diff options
1035 files changed, 38732 insertions, 26140 deletions
diff --git a/.gitignore b/.gitignore index 06b13923f5..25a6352f8d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,7 @@ /phpBB/cache/*.php /phpBB/cache/*.lock /phpBB/composer.phar -/phpBB/config.php -/phpBB/config_dev.php -/phpBB/config_test.php +/phpBB/config*.php /phpBB/ext/* /phpBB/files/* /phpBB/images/avatars/gallery/* @@ -15,5 +13,5 @@ /phpBB/store/* /phpBB/vendor /tests/phpbb_unit_tests.sqlite2 -/tests/test_config.php +/tests/test_config*.php /tests/tmp/* diff --git a/.travis.yml b/.travis.yml index c89ad38661..88c902cd4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,27 +4,41 @@ php: - 5.3 - 5.4 - 5.5 + - 5.6 + - hhvm env: - DB=mysql - - DB=postgres -before_script: - - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi" - - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi" - - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi" - - travis/install-php-extensions.sh +services: + - redis-server + +install: + - sh -c "if [ '$DB' = 'mariadb' ]; then travis/setup-mariadb.sh; fi" + - sh -c "if [ '$TRAVIS_PHP_VERSION' != 'hhvm' ]; then travis/setup-php-extensions.sh; fi" + - sh -c "if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.3.19', '>=');"` = "1" ]; then travis/setup-webserver.sh; fi" - cd phpBB - php ../composer.phar install --dev --no-interaction --prefer-source - cd .. - - sh -c "if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.3.19', '>=');"` = "1" ]; then travis/setup-webserver.sh; fi" + +before_script: + - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi" + - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi" + - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.3' -a '$DB' = 'mysql' ]; then mysql -e 'SET GLOBAL storage_engine=MyISAM;'; fi" + - sh -c "if [ '$DB' = 'mysql' -o '$DB' = 'mariadb' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi" script: + - cd build + - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.5' -a '$DB' = 'mysql' ]; then ../phpBB/vendor/bin/phing sniff; fi" + - cd .. - phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml - -notifications: - email: - recipients: - - dev-team@phpbb.com - on_success: change - on_failure: change + - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.5' -a '$DB' = 'mysql' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..FETCH_HEAD; fi" + +matrix: + include: + - php: 5.4 + env: DB=mariadb + - php: 5.4 + env: DB=postgres + allow_failures: + - php: hhvm @@ -25,9 +25,11 @@ To be able to run an installation from the repo (and not from a pre-built packag ## AUTOMATED TESTING -We have unit and functional tests in order to prevent regressions. You can view the bamboo continuous integration [here](http://bamboo.phpbb.com) or check our travis build below. -develop - [](http://travis-ci.org/phpbb/phpbb3) -develop-olympus - [](http://travis-ci.org/phpbb/phpbb3) +We have unit and functional tests in order to prevent regressions. You can view the bamboo continuous integration [here](http://bamboo.phpbb.com) or check our travis build below: + +* develop [](http://travis-ci.org/phpbb/phpbb) +* develop-ascraeus [](http://travis-ci.org/phpbb/phpbb) +* develop-olympus [](http://travis-ci.org/phpbb/phpbb) ## LICENSE diff --git a/build/build.xml b/build/build.xml index 31782e6821..c1f81fb947 100644 --- a/build/build.xml +++ b/build/build.xml @@ -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="3.1.0-dev" /> - <property name="prevversion" value="3.0.12" /> - <property name="olderversions" value="3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.0.6, 3.0.7, 3.0.7-PL1, 3.0.8, 3.0.9, 3.0.10, 3.0.11" /> + <property name="newversion" value="3.1.0-b3-dev" /> + <property name="prevversion" value="3.1.0-b2" /> + <property name="olderversions" value="3.0.12, 3.1.0-a1, 3.1.0-a2, 3.1.0-a3, 3.1.0-b1" /> <!-- no configuration should be needed beyond this point --> <property name="oldversions" value="${olderversions}, ${prevversion}" /> @@ -74,6 +74,40 @@ passthru="true" /> </target> + <target name="sniff"> + <exec command="phpBB/vendor/bin/phpcs + -s + --extensions=php + --standard=build/code_sniffer/ruleset-php-strict.xml + --ignore=phpBB/phpbb/db/migration/data/v30x/* + phpBB/phpbb" + dir="." returnProperty="retval-php-strict" passthru="true" /> + <exec command="phpBB/vendor/bin/phpcs + -s + --extensions=php + --standard=build/code_sniffer/ruleset-php-legacy.xml + --ignore=phpBB/cache/* + --ignore=phpBB/develop/* + --ignore=phpBB/includes/diff/*.php + --ignore=phpBB/includes/sphinxapi.php + --ignore=phpBB/includes/utf/data/* + --ignore=phpBB/install/data/* + --ignore=phpBB/install/database_update.php + --ignore=phpBB/phpbb/* + --ignore=phpBB/vendor/* + phpBB" + dir="." returnProperty="retval-php-legacy" passthru="true" /> + <if> + <or> + <not><equals arg1="${retval-php-strict}" arg2="0" /></not> + <not><equals arg1="${retval-php-legacy}" arg2="0" /></not> + </or> + <then> + <fail message="PHP Code Sniffer failed." /> + </then> + </if> + </target> + <target name="docs"> <!-- only works if you setup phpdoctor: git clone https://github.com/peej/phpdoctor.git @@ -105,7 +139,7 @@ <property name="dir" value="build/old_versions/release-${version}" /> </phingcall> - <exec dir="build/old_versions" command="diff -crNEBwd release-${version} release-${newversion} > + <exec dir="build/old_versions" command="LC_ALL=C diff -crNEBwd release-${version} release-${newversion} > ../new_version/patches/phpBB-${version}_to_${newversion}.patch" escape="false" /> </target> @@ -131,24 +165,22 @@ <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" command="php -f build_diff.php '${prevversion}' '${newversion}' > logs/build_diff.log" escape="false" /> - <exec dir="build" escape="false" command="diff -crNEBwd old_versions/release-${prevversion}/language new_version/phpBB3/language > - save/save_${prevversion}_to_${newversion}/language/phpbb-${prevversion}_to_${newversion}_language.patch" /> + save/phpbb-${prevversion}_to_${newversion}_language.patch" /> <exec dir="build" escape="false" command="diff -crNEBwd old_versions/release-${prevversion}/styles/prosilver new_version/phpBB3/styles/prosilver > - save/save_${prevversion}_to_${newversion}/prosilver/phpbb-${prevversion}_to_${newversion}_prosilver.patch" /> + save/phpbb-${prevversion}_to_${newversion}_prosilver.patch" /> <exec dir="build" escape="false" command="diff -crNEBwd old_versions/release-${prevversion}/styles/subsilver2 new_version/phpBB3/styles/subsilver2 > - save/save_${prevversion}_to_${newversion}/subsilver2/phpbb-${prevversion}_to_${newversion}_subsilver2.patch" /> + save/phpbb-${prevversion}_to_${newversion}_subsilver2.patch" /> <exec dir="build" escape="false" command="git shortlog --summary --numbered release-${prevversion}...HEAD > - save/save_${prevversion}_to_${newversion}/phpbb-${prevversion}_to_${newversion}_git_shortlog.txt" /> + save/phpbb-${prevversion}_to_${newversion}_git_shortlog.txt" /> <exec dir="build" escape="false" command="git diff --stat release-${prevversion}...HEAD > - save/save_${prevversion}_to_${newversion}/phpbb-${prevversion}_to_${newversion}_git_diffstat.txt" /> + save/phpbb-${prevversion}_to_${newversion}_git_diffstat.txt" /> <phingcall target="checksum-dir"> <property name="dir" value="build/new_version/release_files" /> @@ -169,6 +201,18 @@ <exec dir="${dir}" command="sha256sum ${filename} > ${filename}.sha256" /> </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" + command="php -f build_announcement.php email '${newversion}' 'new_version/release_files' sha256 > + save/announcement_email_${newversion}.txt" /> + + <echo msg="Writing download links and checksums for bbcode announcement to save/announcement_bbcode_${newversion}.txt" /> + <exec dir="build" escape="false" + command="php -f build_announcement.php bbcode '${newversion}' 'new_version/release_files' sha256 > + save/announcement_bbcode_${newversion}.txt" /> + </target> + <target name="changelog" depends="prepare"> <exec dir="build" escape="false" command="php -f build_changelog.php '${newversion}' > @@ -211,7 +255,7 @@ command="git archive ${revision} composer.phar | tar -xf - -C ${dir}" checkreturn="true" /> <exec dir="${dir}" - command="php composer.phar install" + command="php composer.phar install --no-dev" checkreturn="true" passthru="true" /> <delete file="${dir}/composer.phar" /> @@ -229,6 +273,10 @@ <delete dir="${dir}/develop" /> <delete dir="${dir}/install/data" /> + <phingcall target="clean-vendor-dir"> + <property name="dir" value="${dir}" /> + </phingcall> + <echo msg="Setting permissions for checkout of ${revision} in ${dir}" /> <!-- set permissions of all files to 644, directories to 755 --> <exec dir="${dir}" command="find . -type f|xargs chmod 644" escape="false" /> @@ -240,6 +288,91 @@ <chmod mode="0777" file="${dir}/images/avatars/upload" /> </target> + <target name="clean-vendor-dir"> + <!-- Delete unrelated files from vendor/, see PHPBB3-12390 --> + <delete dir="${dir}/vendor/lusitanian/oauth/examples" /> + <delete dir="${dir}/vendor/lusitanian/oauth/tests" /> + <delete file="${dir}/vendor/lusitanian/oauth/.gitignore" /> + <delete file="${dir}/vendor/lusitanian/oauth/.travis.yml" /> + <delete file="${dir}/vendor/lusitanian/oauth/phpunit.xml.dist" /> + <delete file="${dir}/vendor/lusitanian/oauth/README.md" /> + + <delete dir="${dir}/vendor/psr/log/Psr/Log/Test" /> + <delete file="${dir}/vendor/psr/log/.gitignore" /> + <delete file="${dir}/vendor/psr/log/README.md" /> + + <delete dir="${dir}/vendor/symfony/config/Symfony/Component/Config/Tests" /> + <delete file="${dir}/vendor/symfony/config/Symfony/Component/Config/.gitignore" /> + <delete file="${dir}/vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md" /> + <delete file="${dir}/vendor/symfony/config/Symfony/Component/Config/README.md" /> + <delete file="${dir}/vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist" /> + + <delete dir="${dir}/vendor/symfony/console/Symfony/Component/Console/Tests" /> + <delete file="${dir}/vendor/symfony/console/Symfony/Component/Console/.gitignore" /> + <delete file="${dir}/vendor/symfony/console/Symfony/Component/Console/CHANGELOG.md" /> + <delete file="${dir}/vendor/symfony/console/Symfony/Component/Console/README.md" /> + <delete file="${dir}/vendor/symfony/console/Symfony/Component/Console/phpunit.xml.dist" /> + + <delete dir="${dir}/vendor/symfony/debug/Symfony/Component/Debug/Tests" /> + <delete file="${dir}/vendor/symfony/debug/Symfony/Component/Debug/.gitignore" /> + <delete file="${dir}/vendor/symfony/debug/Symfony/Component/Debug/CHANGELOG.md" /> + <delete file="${dir}/vendor/symfony/debug/Symfony/Component/Debug/README.md" /> + <delete file="${dir}/vendor/symfony/debug/Symfony/Component/Debug/phpunit.xml.dist" /> + + <delete dir="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests" /> + <delete file="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/.gitignore" /> + <delete file="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/CHANGELOG.md" /> + <delete file="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/README.md" /> + <delete file="${dir}/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/phpunit.xml.dist" /> + + <delete dir="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/Tests" /> + <delete file="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/.gitignore" /> + <delete file="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/CHANGELOG.md" /> + <delete file="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/README.md" /> + <delete file="${dir}/vendor/symfony/event-dispatcher/Symfony/Component/EventDispatcher/phpunit.xml.dist" /> + + <delete dir="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests" /> + <delete file="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore" /> + <delete file="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md" /> + <delete file="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md" /> + <delete file="${dir}/vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist" /> + + <delete dir="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests" /> + <delete file="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/.gitignore" /> + <delete file="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/CHANGELOG.md" /> + <delete file="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/README.md" /> + <delete file="${dir}/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/phpunit.xml.dist" /> + + <delete dir="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Tests" /> + <delete file="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/.gitignore" /> + <delete file="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CHANGELOG.md" /> + <delete file="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/README.md" /> + <delete file="${dir}/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/phpunit.xml.dist" /> + + <delete dir="${dir}/vendor/symfony/routing/Symfony/Component/Routing/Tests" /> + <delete file="${dir}/vendor/symfony/routing/Symfony/Component/Routing/.gitignore" /> + <delete file="${dir}/vendor/symfony/routing/Symfony/Component/Routing/CHANGELOG.md" /> + <delete file="${dir}/vendor/symfony/routing/Symfony/Component/Routing/README.md" /> + <delete file="${dir}/vendor/symfony/routing/Symfony/Component/Routing/phpunit.xml.dist" /> + + <delete dir="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/Tests" /> + <delete file="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/.gitignore" /> + <delete file="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/CHANGELOG.md" /> + <delete file="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/README.md" /> + <delete file="${dir}/vendor/symfony/yaml/Symfony/Component/Yaml/phpunit.xml.dist" /> + + <delete dir="${dir}/vendor/twig/twig/doc" /> + <delete dir="${dir}/vendor/twig/twig/ext" /> + <delete dir="${dir}/vendor/twig/twig/test" /> + <delete file="${dir}/vendor/twig/twig/.editorconfig" /> + <delete file="${dir}/vendor/twig/twig/.gitignore" /> + <delete file="${dir}/vendor/twig/twig/.travis.yml" /> + <delete file="${dir}/vendor/twig/twig/AUTHORS" /> + <delete file="${dir}/vendor/twig/twig/CHANGELOG" /> + <delete file="${dir}/vendor/twig/twig/phpunit.xml.dist" /> + <delete file="${dir}/vendor/twig/twig/README.markdown" /> + </target> + <target name="clean-diff-dir"> <delete dir="${dir}/cache" /> <delete dir="${dir}/docs" /> diff --git a/build/build_announcement.php b/build/build_announcement.php new file mode 100755 index 0000000000..a1a496fd68 --- /dev/null +++ b/build/build_announcement.php @@ -0,0 +1,80 @@ +#!/usr/bin/env php +<?php +/** +* +* @package build +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +if (php_sapi_name() !== 'cli' || $_SERVER['argc'] != 5) +{ + echo "Usage (CLI only): build_announcement.php email|bbcode new_version release_files_dir checksum_algorithm\n"; + exit(1); +} + +$mode = $_SERVER['argv'][1]; +$version = $_SERVER['argv'][2]; +$root = $_SERVER['argv'][3]; +$checksum_algorithm = $_SERVER['argv'][4]; + +$series_version = substr($version, 0, 3); +$base_url = "https://download.phpbb.com/pub/release/$series_version"; + +if (version_compare($version, "$series_version.0", '<')) +{ + // Everything before 3.x.0, i.e. unstable (e.g. alpha, beta, rc) + $url = "$base_url/unstable/$version"; +} +else if (strpos($version, 'RC') !== false) +{ + // Release candidate of stable release + $url = "$base_url/qa/$version"; +} +else +{ + // Stable release (e.g. 3.x.0, 3.x.1, 3.x.2, 3.x.3-PL1) + $url = "$base_url/$version"; +} + +if ($mode === 'bbcode') +{ + $template = "[url=%1\$s/%2\$s]%2\$s[/url]\n{$checksum_algorithm}sum: %3\$s\n"; +} +else +{ + $template = "%s/%s\n{$checksum_algorithm}sum: %s\n"; +} + +function phpbb_rnatsort($array) +{ + $strrnatcmp = function($a, $b) + { + return strnatcmp($b, $a); + }; + usort($array, $strrnatcmp); + return $array; +} + +function phpbb_string_ends_with($haystack, $needle) +{ + return substr($haystack, -strlen($needle)) === $needle; +} + +function phpbb_get_checksum($checksum_file) +{ + return array_shift(explode(' ', file_get_contents($checksum_file))); +} + +foreach (phpbb_rnatsort(array_diff(scandir($root), array('.', '..'))) as $filename) +{ + if (phpbb_string_ends_with($filename, $checksum_algorithm)) + { + continue; + } + else + { + printf($template, $url, $filename, phpbb_get_checksum("$root/$filename.$checksum_algorithm")); + } +} diff --git a/build/build_diff.php b/build/build_diff.php deleted file mode 100755 index 68bac65a66..0000000000 --- a/build/build_diff.php +++ /dev/null @@ -1,409 +0,0 @@ -#!/usr/bin/env php -<?php -/** -* -* @package build -* @copyright (c) 2010 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -if ($_SERVER['argc'] != 3) -{ - die("Please specify the previous and current version as arguments (e.g. build_diff.php '1.0.2' '1.0.3')."); -} - -$old_version = trim($_SERVER['argv'][1]); -$new_version = trim($_SERVER['argv'][2]); - -$substitute_old = $old_version; -$substitute_new = $new_version; -$simple_name_old = 'release-' . $old_version; -$simple_name_new = 'release-' . $new_version; -$echo_changes = false; - -// DO NOT EVER USE THE FOLLOWING! Fix the script to generate proper changes, -// do NOT manually create them. - -// Set this to true to just compress the changes and do not build them again -// This should be used for building custom modified txt file. ;) -$package_changed_files = false; - -//$debug_file = 'includes/functions_user.php'; //'styles/prosilver/style.cfg'; -$debug_file = false; - -if ($debug_file !== false) -{ - $echo_changes = false; -} - -$s_name = 'save_' . $substitute_old . '_to_' . $substitute_new; - -$location = dirname(__FILE__); - -if (!$package_changed_files) -{ - if (!$echo_changes) - { - // Create directory... - run_command("mkdir $location/save/{$s_name}"); - run_command("mkdir $location/save/{$s_name}/language"); - run_command("mkdir $location/save/{$s_name}/prosilver"); - run_command("mkdir $location/save/{$s_name}/subsilver2"); - } -} - -// Build code changes and place them into 'save' -if (!$package_changed_files) -{ - build_code_changes('language'); - build_code_changes('prosilver'); - build_code_changes('subsilver2'); -} - -// Package code changes -$code_changes_filename = 'phpBB-' . $substitute_old . '_to_' . $substitute_new . '-codechanges'; - -if (!$echo_changes) -{ - // Now compress the files... - // Build Main phpBB Release - $compress_programs = array( -// 'tar.gz' => 'tar -czf', - 'tar.bz2' => 'tar -cjf', - 'zip' => 'zip -r' - ); - - chdir($location . '/save/' . $s_name); - foreach ($compress_programs as $extension => $compress_command) - { - echo "Packaging code changes for $extension\n"; - run_command("rm ./../../new_version/release_files/{$code_changes_filename}.{$extension}"); - flush(); - - // Build Package - run_command("$compress_command ./../../new_version/release_files/{$code_changes_filename}.{$extension} *"); - flush(); - } -} - -/** -* $output_format can be: language, prosilver and subsilver2 -*/ -function build_code_changes($output_format) -{ - global $substitute_new, $substitute_old, $simple_name_old, $simple_name_new, $echo_changes, $package_changed_files, $location, $debug_file, $s_name; - - // Global array holding the data entries - $data = array( - 'header' => array(), - 'diff' => array(), - ); - - // Read diff file and prepare the output filedata... - //$patch_filename = '../new_version/patches/phpBB-' . $substitute_old . '_to_' . $substitute_new . '.patch'; - $release_filename = 'phpbb-' . $substitute_old . '_to_' . $substitute_new . '_' . $output_format . '.txt'; - - if (!$package_changed_files) - { - if (!$echo_changes) - { - $fp = fopen('save/' . $s_name . '/' . $output_format . '/' . $release_filename, 'wb'); - - if (!$fp) - { - die('Unable to create ' . $release_filename); - } - } - } - - include_once($location . '/build_helper.php'); - $package = new build_package(array($substitute_old, $substitute_new), false); - - $titles = array( - 'language' => 'phpBB ' . $substitute_old . ' to phpBB ' . $substitute_new . ' Language Pack Changes', - 'prosilver' => 'phpBB ' . $substitute_old . ' to phpBB ' . $substitute_new . ' prosilver Changes', - 'subsilver2' => 'phpBB ' . $substitute_old . ' to phpBB ' . $substitute_new . ' subsilver2 Changes', - ); - - $data['header'] = array( - 'title' => $titles[$output_format], - 'intro' => ' - -These are the ' . $titles[$output_format] . ' summed up into a little Mod. These changes are only partial and do not include any code changes, therefore not meant for updating phpBB. - - ', - 'included_files' => array(), - ); - - // We collect the files we want to diff first (ironically we grab this from a diff file) - if (!$echo_changes) - { - echo "\n\nCollecting Filenames:"; - } - - // We re-create the patch file - foreach ($package->old_packages as $_package_name => $dest_package_filename) - { - chdir($package->locations['old_versions']); - - if (!$echo_changes) - { - echo "\n\n" . 'Creating patch/diff files for phpBB-' . $dest_package_filename . $package->get('new_version_number'); - } - - $dest_package_filename = $location . '/save/' . $s_name . '/phpBB-' . $dest_package_filename . $package->get('new_version_number') . '.patch'; - $package->run_command('diff ' . $package->diff_options . ' ' . $_package_name . ' ' . $package->get('simple_name') . ' > ' . $dest_package_filename); - - // Parse this diff to determine file changes from the checked versions and save them - $result = $package->collect_diff_files($dest_package_filename, $_package_name); - $package->run_command('rm ' . $dest_package_filename); - } - - chdir($location); - - $filenames = array(); - foreach ($result['files'] as $filename) - { - if ($debug_file !== false && $filename != $debug_file) - { - continue; - } - - // Decide which files to compare... - switch ($output_format) - { - case 'language': - if (strpos($filename, 'language/en/') !== 0) - { - continue 2; - } - break; - - case 'prosilver': - if (strpos($filename, 'styles/prosilver/') !== 0) - { - continue 2; - } - break; - - case 'subsilver2': - if (strpos($filename, 'styles/subsilver2/') !== 0) - { - continue 2; - } - break; - } - - if (!file_exists($location . '/old_versions/' . $simple_name_old . '/' . $filename)) - { - // New file... include it - $data['header']['included_files'][] = array( - 'old' => $location . '/old_versions/' . $simple_name_old . '/' . $filename, - 'new' => $location . '/old_versions/' . $simple_name_new . '/' . $filename, - 'phpbb_filename' => $filename, - ); - continue; - } - - $filenames[] = array( - 'old' => $location . '/old_versions/' . $simple_name_old . '/' . $filename, - 'new' => $location . '/old_versions/' . $simple_name_new . '/' . $filename, - 'phpbb_filename' => $filename, - ); - } - - // Now let us go through the filenames list and create a more comprehensive diff - if (!$echo_changes) - { - fwrite($fp, build_header($output_format, $filenames, $data['header'])); - } - else - { - //echo build_header('text', $filenames, $data['header']); - } - - // Copy files... - $files_to_copy = array(); - - foreach ($data['header']['included_files'] as $filename) - { - $files_to_copy[] = $filename['phpbb_filename']; - } - - // First step is to copy the new version over (clean structure) - if (!$echo_changes && sizeof($files_to_copy)) - { - foreach ($files_to_copy as $file) - { - // Create directory? - $dirname = dirname($file); - - if ($dirname) - { - $dirname = explode('/', $dirname); - $__dir = array(); - - foreach ($dirname as $i => $dir) - { - $__dir[] = $dir; - run_command("mkdir -p $location/save/" . $s_name . '/' . $output_format . '/' . implode('/', $__dir)); - } - } - - $source_file = $location . '/new_version/phpBB3/' . $file; - $dest_file = $location . '/save/' . $s_name . '/' . $output_format . '/'; - $dest_file .= $file; - - $command = "cp -p $source_file $dest_file"; - $result = trim(`$command`); - echo "- Copied File: " . $source_file . " -> " . $dest_file . "\n"; - } - } - - include_once('diff_class.php'); - - if (!$echo_changes) - { - echo "\n\nDiffing Codebases:"; - } - - foreach ($filenames as $file_ary) - { - if (!file_exists($file_ary['old'])) - { - $lines1 = array(); - } - else - { - $lines1 = file($file_ary['old']); - } - $lines2 = file($file_ary['new']); - - if (!sizeof($lines1)) - { - // New File - } - else - { - $diff = new Diff($lines1, $lines2); - $fmt = new BBCodeDiffFormatter(false, 5, $debug_file); - - if (!$echo_changes) - { - fwrite($fp, $fmt->format_open($file_ary['phpbb_filename'])); - fwrite($fp, $fmt->format($diff, $lines1)); - fwrite($fp, $fmt->format_close($file_ary['phpbb_filename'])); - } - else - { - echo $fmt->format_open($file_ary['phpbb_filename']); - echo $fmt->format($diff, $lines1); - echo $fmt->format_close($file_ary['phpbb_filename']); - } - - if ($debug_file !== false) - { - echo $fmt->format_open($file_ary['phpbb_filename']); - echo $fmt->format($diff, $lines1); - echo $fmt->format_close($file_ary['phpbb_filename']); - exit; - } - } - } - - if (!$echo_changes) - { - fwrite($fp, build_footer($output_format)); - - // Close file - fclose($fp); - - chmod('save/' . $s_name . '/' . $output_format . '/' . $release_filename, 0666); - } - else - { - echo build_footer($output_format); - } -} - -/** -* Build Footer -*/ -function build_footer($mode) -{ - $html = ''; - - $html .= "# \n"; - $html .= "#-----[ SAVE/CLOSE ALL FILES ]------------------------------------------ \n"; - $html .= "# \n"; - $html .= "# EoM"; - - return $html; -} - -/** -* Build Header -*/ -function build_header($mode, $filenames, $header) -{ - global $substitute_old; - - $html = ''; - - $html .= "############################################################## \n"; - $html .= "## Title: " . $header['title'] . "\n"; - $html .= "## Author: naderman < naderman@phpbb.com > (Nils Adermann) http://www.phpbb.com \n"; - $html .= "## Description: \n"; - - $intr = explode("\n", $header['intro']); - $introduction = ''; - foreach ($intr as $_line) - { - $introduction .= wordwrap($_line, 80) . "\n"; - } - $intr = explode("\n", $introduction); - - foreach ($intr as $_line) - { - $html .= "## " . $_line . "\n"; - } - $html .= "## \n"; - $html .= "## Files To Edit: \n"; - - foreach ($filenames as $file_ary) - { - $html .= "## " . $file_ary['phpbb_filename'] . "\n"; - } - $html .= "##\n"; - if (sizeof($header['included_files'])) - { - $html .= "## Included Files: \n"; - foreach ($header['included_files'] as $filename) - { - $html .= "## {$filename['phpbb_filename']}\n"; - } - } - $html .= "## License: http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 \n"; - $html .= "############################################################## \n"; - $html .= "\n"; - - // COPY Statement? - if (sizeof($header['included_files'])) - { - $html .= "#\n#-----[ COPY ]------------------------------------------\n#\n"; - foreach ($header['included_files'] as $filename) - { - $html .= "copy {$filename['phpbb_filename']} to {$filename['phpbb_filename']}\n"; - } - $html .= "\n"; - } - - return $html; -} - -function run_command($command) -{ - $result = trim(`$command`); - echo "\n- Command Run: " . $command . "\n"; -} diff --git a/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php b/build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php index 68e9e6bb86..231e77734e 100644 --- a/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php +++ b/build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php @@ -193,7 +193,7 @@ class phpbb_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff */ protected function processLicense(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) { - $license = 'http://opensource.org/licenses/gpl-license.php GNU Public License'; + $license = 'http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2'; if (!isset($tags['license'])) { diff --git a/code_sniffer/phpbb/Tests/Commenting/FileCommentUnitTest.inc b/build/code_sniffer/phpbb/Tests/Commenting/FileCommentUnitTest.inc index 0ace1c1bda..0ace1c1bda 100644 --- a/code_sniffer/phpbb/Tests/Commenting/FileCommentUnitTest.inc +++ b/build/code_sniffer/phpbb/Tests/Commenting/FileCommentUnitTest.inc diff --git a/code_sniffer/phpbb/Tests/Commenting/FileCommentUnitTest.php b/build/code_sniffer/phpbb/Tests/Commenting/FileCommentUnitTest.php index affa27b56c..affa27b56c 100644 --- a/code_sniffer/phpbb/Tests/Commenting/FileCommentUnitTest.php +++ b/build/code_sniffer/phpbb/Tests/Commenting/FileCommentUnitTest.php diff --git a/code_sniffer/phpbb/build.xml b/build/code_sniffer/phpbb/build.xml index b6d3bf6451..b6d3bf6451 100644 --- a/code_sniffer/phpbb/build.xml +++ b/build/code_sniffer/phpbb/build.xml diff --git a/code_sniffer/phpbb/phpbbCodingStandard.php b/build/code_sniffer/phpbb/phpbbCodingStandard.php index adbba9d915..adbba9d915 100644 --- a/code_sniffer/phpbb/phpbbCodingStandard.php +++ b/build/code_sniffer/phpbb/phpbbCodingStandard.php diff --git a/build/code_sniffer/ruleset-minimum.xml b/build/code_sniffer/ruleset-minimum.xml new file mode 100644 index 0000000000..33d0177390 --- /dev/null +++ b/build/code_sniffer/ruleset-minimum.xml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<ruleset name="phpBB Minimum Standard"> + + <description>phpBB minimum coding standard</description> + + <!-- All code files MUST use only UTF-8 without BOM. --> + <rule ref="Generic.Files.ByteOrderMark" /> + + <!-- All code files MUST use the Unix LF (linefeed) line ending. --> + <rule ref="Generic.Files.LineEndings" /> + + <!-- Tabs MUST be used for indentation --> + <rule ref="Generic.WhiteSpace.DisallowSpaceIndent" /> + +</ruleset> diff --git a/build/code_sniffer/ruleset-php-legacy.xml b/build/code_sniffer/ruleset-php-legacy.xml new file mode 100644 index 0000000000..65eb0a8622 --- /dev/null +++ b/build/code_sniffer/ruleset-php-legacy.xml @@ -0,0 +1,59 @@ +<?xml version="1.0"?> +<ruleset name="phpBB PHP Legacy Standard"> + + <description>phpBB legacy coding standard for PHP files</description> + + <rule ref="./ruleset-minimum.xml" /> + + <!-- "for (; bar; )" should be "while (bar)" instead --> + <rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop" /> + + <!-- A method MUST not only call its parent --> + <rule ref="Generic.CodeAnalysis.UselessOverridingMethod" /> + + <!-- The body of each structure MUST be enclosed by braces. --> + <rule ref="Generic.ControlStructures.InlineControlStructure" /> + + <!-- 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" /> + + <!-- Class constants MUST be declared in all upper case with underscore separators. --> + <rule ref="Generic.NamingConventions.UpperCaseConstantName" /> + + <!-- Only <?php, no short tags. --> + <rule ref="Generic.PHP.DisallowShortOpenTag.EchoFound" /> + + <!-- Method arguments with default values MUST go at the end of the argument list. --> + <rule ref="PEAR.Functions.ValidDefaultValue" /> + + <!-- Each file MUST end with exactly one newline character --> + <rule ref="PSR2.Files.EndFileNewline" /> + + <!-- In the argument list, there MUST NOT be a space before each comma, + and there MUST be one space after each comma. --> + <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing"> + <properties> + <property name="equalsSpacing" value="1"/> + </properties> + </rule> + <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint" /> + + <!-- There MUST NOT be trailing whitespace at the end of lines. --> + <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace" /> + + <!-- There MUST NOT be whitespace before the first content of a file --> + <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.StartFile" /> + + <!-- There MUST NOT be whitespace after the last content of a file --> + <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EndFile" /> + + <!-- Functions MUST NOT contain multiple empty lines in a row --> + <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines" /> + + <!-- The ?> closing tag MUST be omitted from files containing only PHP. --> + <rule ref="Zend.Files.ClosingTag" /> + +</ruleset> diff --git a/build/code_sniffer/ruleset-php-strict.xml b/build/code_sniffer/ruleset-php-strict.xml new file mode 100644 index 0000000000..f2d5b86dd1 --- /dev/null +++ b/build/code_sniffer/ruleset-php-strict.xml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<ruleset name="phpBB PHP Strict Standard"> + + <description>phpBB coding standard for PHP files</description> + + <rule ref="./ruleset-php-legacy.xml" /> + + <!-- There SHOULD NOT be more than 80 characters per line + There MUST NOT be more than 120 characters per line --> + <!-- + <rule ref="Generic.Files.LineLength"> + <properties> + <property name="lineLimit" value="80"/> + <property name="absoluteLineLimit" value="120"/> + </properties> + </rule> + --> + + <!-- The PHP constants true, false, and null MUST be in lower case. --> + <rule ref="Generic.PHP.LowerCaseConstant" /> + + <!-- PHP keywords MUST be in lower case. --> + <rule ref="Generic.PHP.LowerCaseKeyword" /> + + <!-- Classes etc. MUST be namespaced --> + <rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace" /> + + <!-- A file MUST not contain more than one class/interface --> + <rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses" /> + + <!-- Files containing classes MUST not have any side-effects --> + <rule ref="PSR1.Files.SideEffects.FoundWithSymbols" /> + + <!-- When present, all use declarations MUST go after the namespace declaration. + There MUST be one use keyword per declaration. + There MUST be one blank line after the use block. --> + <rule ref="PSR2.Namespaces.UseDeclaration" /> + +</ruleset> diff --git a/build/diff_class.php b/build/diff_class.php deleted file mode 100644 index 2d8555400d..0000000000 --- a/build/diff_class.php +++ /dev/null @@ -1,1710 +0,0 @@ -<?php -/** -* -* @package build -* @copyright (c) 2000 Geoffrey T. Dairiki <dairiki@dairiki.org> -* @copyright (c) 2010 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* Class used internally by WikiDiff to actually compute the diffs. -* -* The algorithm used here is mostly lifted from the perl module -* Algorithm::Diff (version 1.06) by Ned Konz, which is available at: -* http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip -* -* More ideas are taken from: -* http://www.ics.uci.edu/~eppstein/161/960229.html -* -* Some ideas are (and a bit of code) are from from analyze.c, from GNU -* diffutils-2.7, which can be found at: -* ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz -* -* Finally, some ideas (subdivision by NCHUNKS > 2, and some optimizations) -* are my own. -*/ -class _WikiDiffEngine -{ - var $edits; // List of editing operation to convert XV to YV. - var $xv = array(), $yv = array(); - - function _WikiDiffEngine($from_lines, $to_lines) - { - $n_from = sizeof($from_lines); - $n_to = sizeof($to_lines); - - $endskip = 0; - // Ignore trailing and leading matching lines. - while ($n_from > 0 && $n_to > 0) - { - if ($from_lines[$n_from - 1] != $to_lines[$n_to - 1]) - { - break; - } - - $n_from--; - $n_to--; - $endskip++; - } - - for ($skip = 0; $skip < min($n_from, $n_to); $skip++) - { - if ($from_lines[$skip] != $to_lines[$skip]) - { - break; - } - } - $n_from -= $skip; - $n_to -= $skip; - - $xlines = array(); - $ylines = array(); - - // Ignore lines which do not exist in both files. - for ($x = 0; $x < $n_from; $x++) - { - $xhash[$from_lines[$x + $skip]] = 1; - } - - for ($y = 0; $y < $n_to; $y++) - { - $line = $to_lines[$y + $skip]; - $ylines[] = $line; - - if (($this->ychanged[$y] = empty($xhash[$line]))) - { - continue; - } - $yhash[$line] = 1; - $this->yv[] = $line; - $this->yind[] = $y; - } - - for ($x = 0; $x < $n_from; $x++) - { - $line = $from_lines[$x + $skip]; - $xlines[] = $line; - - if (($this->xchanged[$x] = empty($yhash[$line]))) - { - continue; // fixme? what happens to yhash/xhash when - // there are two identical lines?? - } - $this->xv[] = $line; - $this->xind[] = $x; - } - - // Find the LCS. - $this->_compareseq(0, sizeof($this->xv), 0, sizeof($this->yv)); - - // Merge edits when possible - $this->_shift_boundaries($xlines, $this->xchanged, $this->ychanged); - $this->_shift_boundaries($ylines, $this->ychanged, $this->xchanged); - - // Compute the edit operations. - $this->edits = array(); - - if ($skip) - { - $this->edits[] = $skip; - } - - $x = 0; - $y = 0; - - while ($x < $n_from || $y < $n_to) - { - // Skip matching "snake". - $x0 = $x; - $ncopy = 0; - while ($x < $n_from && $y < $n_to && !$this->xchanged[$x] && !$this->ychanged[$y]) - { - ++$x; - ++$y; - ++$ncopy; - } - - if ($x > $x0) - { - $this->edits[] = $x - $x0; - } - - // Find deletes. - $x0 = $x; - $ndelete = 0; - - while ($x < $n_from && $this->xchanged[$x]) - { - ++$x; - ++$ndelete; - } - - if ($x > $x0) - { - $this->edits[] = -($x - $x0); - } - - // Find adds. - if (isset($this->ychanged[$y]) && $this->ychanged[$y]) - { - $adds = array(); - while ($y < $n_to && $this->ychanged[$y]) - { - $adds[] = $ylines[$y++]; - } - $this->edits[] = $adds; - } - } - - if (!empty($endskip)) - { - $this->edits[] = $endskip; - } - } - - /* Divide the Largest Common Subsequence (LCS) of the sequences - * [XOFF, XLIM) and [YOFF, YLIM) into NCHUNKS approximately equally - * sized segments. - * - * Returns (LCS, PTS). LCS is the length of the LCS. PTS is an - * array of NCHUNKS+1 (X, Y) indexes giving the diving points between - * sub sequences. The first sub-sequence is contained in [X0, X1), - * [Y0, Y1), the second in [X1, X2), [Y1, Y2) and so on. Note - * that (X0, Y0) == (XOFF, YOFF) and - * (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM). - * - * This function assumes that the first lines of the specified portions - * of the two files do not match, and likewise that the last lines do not - * match. The caller must trim matching lines from the beginning and end - * of the portions it is going to specify. - */ - function _diag ($xoff, $xlim, $yoff, $ylim, $nchunks) - { - $flip = false; - - if ($xlim - $xoff > $ylim - $yoff) - { - // Things seems faster (I'm not sure I understand why) - // when the shortest sequence in X. - $flip = true; - list ($xoff, $xlim, $yoff, $ylim) = array( $yoff, $ylim, $xoff, $xlim); - } - - if ($flip) - { - for ($i = $ylim - 1; $i >= $yoff; $i--) - { - $ymatches[$this->xv[$i]][] = $i; - } - } - else - { - for ($i = $ylim - 1; $i >= $yoff; $i--) - { - $ymatches[$this->yv[$i]][] = $i; - } - } - - $this->lcs = 0; - $this->seq[0]= $yoff - 1; - $this->in_seq = array(); - $ymids[0] = array(); - - $numer = $xlim - $xoff + $nchunks - 1; - $x = $xoff; - - for ($chunk = 0; $chunk < $nchunks; $chunk++) - { - if ($chunk > 0) - { - for ($i = 0; $i <= $this->lcs; $i++) - { - $ymids[$i][$chunk-1] = $this->seq[$i]; - } - } - - $x1 = $xoff + (int)(($numer + ($xlim-$xoff)*$chunk) / $nchunks); - - for ( ; $x < $x1; $x++) - { - $_index = $flip ? $this->yv[$x] : $this->xv[$x]; - $matches = (isset($ymatches[$_index])) ? $ymatches[$_index] : array(); - - if (!$matches) - { - continue; - } - reset($matches); - - while (list ($junk, $y) = each($matches)) - { - if (!isset($this->in_seq[$y]) || !$this->in_seq[$y]) - { - $k = $this->_lcs_pos($y); - //if (!$k) die('assertion "!$k" failed'); - $ymids[$k] = $ymids[$k-1]; - break; - } - } - - while (list ($junk, $y) = each($matches)) - { - if ($y > $this->seq[$k-1]) - { - //if ($y >= $this->seq[$k]) die('assertion failed'); - // Optimization: this is a common case: - // next match is just replacing previous match. - $this->in_seq[$this->seq[$k]] = false; - $this->seq[$k] = $y; - $this->in_seq[$y] = 1; - } - else if (!isset($this->in_seq[$y]) || !$this->in_seq[$y]) - { - $k = $this->_lcs_pos($y); - //if (!$k) die('assertion "!$k" failed'); - $ymids[$k] = $ymids[$k-1]; - } - } - } - } - - $seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff); - $ymid = $ymids[$this->lcs]; - - for ($n = 0; $n < $nchunks - 1; $n++) - { - $x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks); - $y1 = $ymid[$n] + 1; - $seps[] = $flip ? array($y1, $x1) : array($x1, $y1); - } - $seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim); - - return array($this->lcs, $seps); - } - - function _lcs_pos ($ypos) - { - $end = $this->lcs; - if ($end == 0 || $ypos > $this->seq[$end]) - { - $this->seq[++$this->lcs] = $ypos; - $this->in_seq[$ypos] = 1; - return $this->lcs; - } - - $beg = 1; - while ($beg < $end) - { - $mid = (int)(($beg + $end) / 2); - - if ($ypos > $this->seq[$mid]) - { - $beg = $mid + 1; - } - else - { - $end = $mid; - } - } - - //if ($ypos == $this->seq[$end]) die("assertion failure"); - - $this->in_seq[$this->seq[$end]] = false; - $this->seq[$end] = $ypos; - $this->in_seq[$ypos] = 1; - return $end; - } - - /* Find LCS of two sequences. - * - * The results are recorded in the vectors $this->{x,y}changed[], by - * storing a 1 in the element for each line that is an insertion - * or deletion (ie. is not in the LCS). - * - * The subsequence of file 0 is [XOFF, XLIM) and likewise for file 1. - * - * Note that XLIM, YLIM are exclusive bounds. - * All line numbers are origin-0 and discarded lines are not counted. - */ - function _compareseq ($xoff, $xlim, $yoff, $ylim) - { - // Slide down the bottom initial diagonal. - while ($xoff < $xlim && $yoff < $ylim && $this->xv[$xoff] == $this->yv[$yoff]) - { - ++$xoff; - ++$yoff; - } - - // Slide up the top initial diagonal. - while ($xlim > $xoff && $ylim > $yoff && $this->xv[$xlim - 1] == $this->yv[$ylim - 1]) - { - --$xlim; - --$ylim; - } - - if ($xoff == $xlim || $yoff == $ylim) - { - $lcs = 0; - } - else - { - // This is ad hoc but seems to work well. - //$nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5); - //$nchunks = max(2,min(8,(int)$nchunks)); - $nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1; - list ($lcs, $seps) = $this->_diag($xoff, $xlim, $yoff, $ylim, $nchunks); - } - - if ($lcs == 0) - { - // X and Y sequences have no common subsequence: - // mark all changed. - while ($yoff < $ylim) - { - $this->ychanged[$this->yind[$yoff++]] = 1; - } - - while ($xoff < $xlim) - { - $this->xchanged[$this->xind[$xoff++]] = 1; - } - } - else - { - // Use the partitions to split this problem into subproblems. - reset($seps); - - $pt1 = $seps[0]; - - while ($pt2 = next($seps)) - { - $this->_compareseq ($pt1[0], $pt2[0], $pt1[1], $pt2[1]); - $pt1 = $pt2; - } - } - } - - /* Adjust inserts/deletes of identical lines to join changes - * as much as possible. - * - * We do something when a run of changed lines include a - * line at one end and have an excluded, identical line at the other. - * We are free to choose which identical line is included. - * `compareseq' usually chooses the one at the beginning, - * but usually it is cleaner to consider the following identical line - * to be the "change". - * - * This is extracted verbatim from analyze.c (GNU diffutils-2.7). - */ - function _shift_boundaries ($lines, &$changed, $other_changed) - { - $i = 0; - $j = 0; - $len = sizeof($lines); - - while (1) - { - /* - * Scan forwards to find beginning of another run of changes. - * Also keep track of the corresponding point in the other file. - */ - - while ($i < $len && $changed[$i] == 0) - { - while ($other_changed[$j++]) - { - continue; - } - $i++; - } - - if ($i == $len) - { - break; - } - - $start = $i; - - // Find the end of this run of changes. - while (isset($changed[++$i])) - { - continue; - } - - while (isset($other_changed[$j]) && $other_changed[$j]) - { - $j++; - } - - do - { - /* - * Record the length of this run of changes, so that - * we can later determine whether the run has grown. - */ - $runlength = $i - $start; - - /* - * Move the changed region back, so long as the - * previous unchanged line matches the last changed one. - * This merges with previous changed regions. - */ - while ($start && $lines[$start - 1] == $lines[$i - 1]) - { - $changed[--$start] = 1; - $changed[--$i] = false; - - while ($changed[$start - 1]) - { - $start--; - } - - while ($other_changed[--$j]) - { - continue; - } - } - - /* - * Set CORRESPONDING to the end of the changed run, at the last - * point where it corresponds to a changed run in the other file. - * CORRESPONDING == LEN means no such point has been found. - */ - $corresponding = empty($other_changed[$j - 1]) ? $len : $i; - - /* - * Move the changed region forward, so long as the - * first changed line matches the following unchanged one. - * This merges with following changed regions. - * Do this second, so that if there are no merges, - * the changed region is moved forward as far as possible. - */ - while ($i != $len && $lines[$start] == $lines[$i]) - { - $changed[$start++] = false; - $changed[$i++] = 1; - - while ($changed[$i]) - { - $i++; - } - - while ($other_changed[++$j]) - { - $corresponding = $i; - } - } - } while ($runlength != $i - $start); - - /* - * If possible, move the fully-merged run of changes - * back to a corresponding run in the other file. - */ - while ($corresponding < $i) - { - $changed[--$start] = 1; - $changed[--$i] = 0; - - while ($other_changed[--$j]) - { - continue; - } - } - } - } -} - -/** -* Class representing a diff between two files. -*/ -class Diff -{ - var $edits; - - /** - * Compute diff between files (or deserialize serialized WikiDiff.) - */ - function Diff($from_lines = false, $to_lines = false) - { - if ($from_lines && $to_lines) - { - $compute = new _WikiDiffEngine($from_lines, $to_lines); - $this->edits = $compute->edits; - } - else if ($from_lines) - { - // $from_lines is not really from_lines, but rather - // a serialized Diff. - $this->edits = unserialize($from_lines); - } - else - { - $this->edits = array(); - } - } - - /** - * Compute reversed Diff. - * - * SYNOPSIS: - * - * $diff = new Diff($lines1, $lines2); - * $rev = $diff->reverse($lines1); - * - * // reconstruct $lines1 from $lines2: - * $out = $rev->apply($lines2); - */ - function reverse ($from_lines) - { - $x = 0; - $rev = new Diff; - - for (reset($this->edits); $edit = current($this->edits); next($this->edits)) - { - if (is_array($edit)) - { // Was an add, turn it into a delete. - $nadd = sizeof($edit); - if ($nadd == 0) - { - die("assertion error"); - } - $edit = -$nadd; - } - else if ($edit > 0) - { - // Was a copy --- just pass it through. } - $x += $edit; - } - else if ($edit < 0) - { // Was a delete, turn it into an add. - $ndelete = -$edit; - $edit = array(); - - while ($ndelete-- > 0) - { - $edit[] = $from_lines[$x++]; - } - } - else - { - die("assertion error"); - } - - $rev->edits[] = $edit; - } - - return $rev; - } - - /** - * Compose (concatenate) Diffs. - * - * SYNOPSIS: - * - * $diff1 = new Diff($lines1, $lines2); - * $diff2 = new Diff($lines2, $lines3); - * $comp = $diff1->compose($diff2); - * - * // reconstruct $lines3 from $lines1: - * $out = $comp->apply($lines1); - */ - function compose ($that) - { - reset($this->edits); - reset($that->edits); - - $comp = new Diff; - $left = current($this->edits); - $right = current($that->edits); - - while ($left || $right) - { - if (!is_array($left) && $left < 0) - { // Left op is a delete. - $newop = $left; - $left = next($this->edits); - } - else if (is_array($right)) - { // Right op is an add. - $newop = $right; - $right = next($that->edits); - } - else if (!$left || !$right) - { - die ("assertion error"); - } - else if (!is_array($left) && $left > 0) - { // Left op is a copy. - if ($left <= abs($right)) - { - $newop = $right > 0 ? $left : -$left; - $right -= $newop; - - if ($right == 0) - { - $right = next($that->edits); - } - $left = next($this->edits); - } - else - { - $newop = $right; - $left -= abs($right); - $right = next($that->edits); - } - } - else - { // Left op is an add. - if (!is_array($left)) - { - die('assertion error'); - } - $nleft = sizeof($left); - - if ($nleft <= abs($right)) - { - if ($right > 0) - { // Right op is copy - $newop = $left; - $right -= $nleft; - } - else // Right op is delete - { - $newop = false; - $right += $nleft; - } - - if ($right == 0) - { - $right = next($that->edits); - } - $left = next($this->edits); - } - else - { - unset($newop); - - if ($right > 0) - { - for ($i = 0; $i < $right; $i++) - { - $newop[] = $left[$i]; - } - } - - $tmp = array(); - for ($i = abs($right); $i < $nleft; $i++) - { - $tmp[] = $left[$i]; - } - $left = $tmp; - $right = next($that->edits); - } - } - - if (!$op) - { - $op = $newop; - continue; - } - - if (!$newop) - { - continue; - } - - if (is_array($op) && is_array($newop)) - { - // Both $op and $newop are adds. - for ($i = 0; $i < sizeof($newop); $i++) - { - $op[] = $newop[$i]; - } - } - else if (($op > 0 && $newop > 0) || ($op < 0 && $newop < 0)) - { // $op and $newop are both either deletes or copies. - $op += $newop; - } - else - { - $comp->edits[] = $op; - $op = $newop; - } - } - - if ($op) - { - $comp->edits[] = $op; - } - - return $comp; - } - - /* Debugging only: - function _dump () - { - echo "<ol>"; - for (reset($this->edits); - { - $edit = current($this->edits); - } - next($this->edits)) - { - echo "<li>"; - if ($edit > 0) - echo "Copy $edit"; - else if ($edit < 0) - echo "Delete " . -$edit; - else if (is_array($edit)) - { - echo "Add " . sizeof($edit) . "<ul>"; - for ($i = 0; $i < sizeof($edit); $i++) - echo "<li>" . htmlspecialchars($edit[$i]); - echo "</ul>"; - } - else - die("assertion error"); - } - echo "</ol>"; - } - */ - - /** - * Apply a Diff to a set of lines. - * - * SYNOPSIS: - * - * $diff = new Diff($lines1, $lines2); - * - * // reconstruct $lines2 from $lines1: - * $out = $diff->apply($lines1); - */ - function apply ($from_lines) - { - $x = 0; - $xlim = sizeof($from_lines); - - for (reset($this->edits); $edit = current($this->edits); next($this->edits)) - { - if (is_array($edit)) - { - reset($edit); - while (list ($junk, $line) = each($edit)) - { - $output[] = $line; - } - } - else if ($edit > 0) - { - while ($edit--) - { - $output[] = $from_lines[$x++]; - } - } - else - { - $x += -$edit; - } - } - - if ($x != $xlim) - { - die(sprintf("Diff::apply: line count mismatch: %s != %s", $x, $xlim)); - } - - return $output; - } - - /** - * Serialize a Diff. - * - * SYNOPSIS: - * - * $diff = new Diff($lines1, $lines2); - * $string = $diff->serialize; - * - * // recover Diff from serialized version: - * $diff2 = new Diff($string); - */ - function serialize () - { - return serialize($this->edits); - } - - /** - * Return true if two files were equal. - */ - function isEmpty() - { - if (sizeof($this->edits) > 1) - { - return false; - } - - if (sizeof($this->edits) == 0) - { - return true; - } - - // Test for: only edit is a copy. - return !is_array($this->edits[0]) && $this->edits[0] > 0; - } - - /** - * Compute the length of the Longest Common Subsequence (LCS). - * - * This is mostly for diagnostic purposed. - */ - function lcs() - { - $lcs = 0; - for (reset($this->edits); $edit = current($this->edits); next($this->edits)) - { - if (!is_array($edit) && $edit > 0) - { - $lcs += $edit; - } - } - - return $lcs; - } - - /** - * Check a Diff for validity. - * - * This is here only for debugging purposes. - */ - function _check ($from_lines, $to_lines) - { - $test = $this->apply($from_lines); - if (serialize($test) != serialize($to_lines)) - { - die("Diff::_check: failed"); - } - - reset($this->edits); - $prev = current($this->edits); - $prevtype = is_array($prev) ? 'a' : ($prev > 0 ? 'c' : 'd'); - - while ($edit = next($this->edits)) - { - $type = is_array($edit) ? 'a' : ($edit > 0 ? 'c' : 'd'); - if ($prevtype == $type) - { - die("Diff::_check: edit sequence is non-optimal"); - } - $prevtype = $type; - } - $lcs = $this->lcs(); - echo "<strong>Diff Okay: LCS = $lcs</strong>\n"; - } -} - -/** -* A class to format a Diff as HTML. -* -* Usage: -* -* $diff = new Diff($lines1, $lines2); // compute diff. -* -* $fmt = new DiffFormatter; -* echo $fmt->format($diff, $lines1); // Output HTMLified standard diff. -* -* or to output reverse diff (diff's that would take $lines2 to $lines1): -* -* $fmt = new DiffFormatter(true); -* echo $fmt->format($diff, $lines1); -*/ -class DiffFormatter -{ - var $context_lines; - var $do_reverse_diff; - var $context_prefix, $deletes_prefix, $adds_prefix; - - function DiffFormatter ($reverse = false) - { - $this->do_reverse_diff = $reverse; - $this->context_lines = 0; - $this->context_prefix = ' '; - $this->deletes_prefix = '< '; - $this->adds_prefix = '> '; - } - - function format ($diff, $from_lines) - { - $html = '<table width="100%" bgcolor="black" cellspacing=2 cellpadding=2 border=0>' . "\n"; - $html .= $this->_format($diff->edits, $from_lines); - $html .= "</table>\n"; - - return $html; - } - - function _format ($edits, $from_lines) - { - $html = ''; - $x = 0; $y = 0; - $xlim = sizeof($from_lines); - - reset($edits); - while ($edit = current($edits)) - { - if (!is_array($edit) && $edit >= 0) - { // Edit op is a copy. - $ncopy = $edit; - } - else - { - $ncopy = 0; - - if (empty($hunk)) - { - // Start of an output hunk. - $xoff = max(0, $x - $this->context_lines); - $yoff = $xoff + $y - $x; - - if ($xoff < $x) - { - // Get leading context. - $context = array(); - - for ($i = $xoff; $i < $x; $i++) - { - $context[] = $from_lines[$i]; - } - $hunk['c'] = $context; - } - } - - if (is_array($edit)) - { - // Edit op is an add. - $y += sizeof($edit); - $hunk[$this->do_reverse_diff ? 'd' : 'a'] = $edit; - } - else - { - // Edit op is a delete - $deletes = array(); - - while ($edit++ < 0) - { - $deletes[] = $from_lines[$x++]; - } - - $hunk[$this->do_reverse_diff ? 'a' : 'd'] = $deletes; - } - } - - $next = next($edits); - - if (!empty($hunk)) - { - // Originally $ncopy > 2 * $this->context_lines, but we need to split as early as we can for creating MOD Text Templates. ;) - if (!$next || $ncopy > $this->context_lines) - { - // End of an output hunk. - $hunks[] = $hunk; - unset($hunk); - - $xend = min($x + $this->context_lines, $xlim); - - if ($x < $xend) - { - // Get trailing context. - $context = array(); - for ($i = $x; $i < $xend; $i++) - { - $context[] = $from_lines[$i]; - } - $hunks[] = array('c' => $context); - } - - $xlen = $xend - $xoff; - $ylen = $xend + $y - $x - $yoff; - $xbeg = $xlen ? $xoff + 1 : $xoff; - $ybeg = $ylen ? $yoff + 1 : $yoff; - - if ($this->do_reverse_diff) - { - list ($xbeg, $xlen, $ybeg, $ylen) = array($ybeg, $ylen, $xbeg, $xlen); - } - - $html .= $this->_emit_diff($xbeg, $xlen, $ybeg, $ylen, $hunks); - unset($hunks); - } - else if ($ncopy) - { - $hunks[] = $hunk; - - // Copy context. - $context = array(); - for ($i = $x; $i < $x + $ncopy; $i++) - { - $context[] = $from_lines[$i]; - } - $hunk = array('c' => $context); - } - } - - $x += $ncopy; - $y += $ncopy; - } - - return $html; - } - - function _emit_lines($lines, $prefix, $color) - { - $html = ''; - reset($lines); - while (list ($junk, $line) = each($lines)) - { - $html .= "<tr bgcolor=\"$color\"><td><tt>$prefix</tt>"; - $html .= "<tt>" . htmlspecialchars($line) . "</tt></td></tr>\n"; - } - return $html; - } - - function _emit_diff ($xbeg,$xlen,$ybeg,$ylen,$hunks) - { - // Save hunk... - $this->diff_hunks[] = $hunks; - - $html = '<tr><td><table width="100%" bgcolor="white" cellspacing="0" border="0" cellpadding="4"> - <tr bgcolor="#cccccc"><td><tt>' . - $this->_diff_header($xbeg, $xlen, $ybeg, $ylen) . ' - </tt></td></tr>\n<tr><td> - <table width="100%" cellspacing="0" border="0" cellpadding="2"> - '; - - $prefix = array('c' => $this->context_prefix, 'a' => $this->adds_prefix, 'd' => $this->deletes_prefix); - $color = array('c' => '#ffffff', 'a' => '#ffcccc', 'd' => '#ccffcc'); - - for (reset($hunks); $hunk = current($hunks); next($hunks)) - { - if (!empty($hunk['c'])) - { - $html .= $this->_emit_lines($hunk['c'], $this->context_prefix, '#ffffff'); - } - - if (!empty($hunk['d'])) - { - $html .= $this->_emit_lines($hunk['d'], $this->deletes_prefix, '#ccffcc'); - } - - if (!empty($hunk['a'])) - { - $html .= $this->_emit_lines($hunk['a'], $this->adds_prefix, '#ffcccc'); - } - } - - $html .= "</table></td></tr></table></td></tr>\n"; - return $html; - } - - function _diff_header ($xbeg,$xlen,$ybeg,$ylen) - { - $what = $xlen ? ($ylen ? 'c' : 'd') : 'a'; - $xlen = $xlen > 1 ? "," . ($xbeg + $xlen - 1) : ''; - $ylen = $ylen > 1 ? "," . ($ybeg + $ylen - 1) : ''; - - return "$xbeg$xlen$what$ybeg$ylen"; - } -} - -/** -* A class to format a Diff as a pretty HTML unified diff. -* -* Usage: -* -* $diff = new Diff($lines1, $lines2); // compute diff. -* -* $fmt = new UnifiedDiffFormatter; -* echo $fmt->format($diff, $lines1); // Output HTMLified unified diff. -*/ -class UnifiedDiffFormatter extends DiffFormatter -{ - function UnifiedDiffFormatter ($reverse = false, $context_lines = 3) - { - $this->do_reverse_diff = $reverse; - $this->context_lines = $context_lines; - $this->context_prefix = ' '; - $this->deletes_prefix = '-'; - $this->adds_prefix = '+'; - } - - function _diff_header ($xbeg,$xlen,$ybeg,$ylen) - { - $xlen = $xlen == 1 ? '' : ",$xlen"; - $ylen = $ylen == 1 ? '' : ",$ylen"; - - return "@@ -$xbeg$xlen +$ybeg$ylen @@"; - } -} - -/** -* A class to format a Diff as MOD Template instuctions. -* -* Usage: -* -* $diff = new Diff($lines1, $lines2); // compute diff. -* -* $fmt = new BBCodeDiffFormatter; -* echo $fmt->format($diff, $lines1); // Output MOD Actions. -*/ -class BBCodeDiffFormatter extends DiffFormatter -{ - function BBCodeDiffFormatter ($reverse = false, $context_lines = 3, $debug = false) - { - $this->do_reverse_diff = $reverse; - $this->context_lines = $context_lines; - $this->context_prefix = ' '; - $this->deletes_prefix = '-'; - $this->adds_prefix = '+'; - $this->debug = $debug; - } - - function format ($diff, $from_lines) - { - $html = $this->_format($diff->edits, $from_lines); - - return $html; - } - - function skip_lines(&$order_array, &$ordering) - { - if (sizeof($order_array['find_c'])) - { - $text = implode('', $order_array['find_c']); - if ($text === "\n" || $text === "\t" || $text === '') - { - if (isset($order_array['first_find_c'][0]) && - is_array($order_array['first_find_c'][0]) && - trim(implode('', $order_array['first_find_c'][0])) != '' && - isset($order_array['replace'])) - { - $order_array['add'] = $order_array['replace']; - unset($order_array['replace']); - // this is actually an after add - } - else - { - return true; - } - } - } - - if (isset($order_array['add']) && sizeof($order_array['add'])) - { - $text = implode('', $order_array['add']); - if ($text === "\n" || $text === "\t" || $text === '') - { - return true; - } - } - - if (isset($order_array['replace']) && sizeof($order_array['replace'])) - { - $text = implode('', $order_array['replace']); - if ($text === "\n" || $text === "\t" || $text === '') - { - return true; - } - } - } - - function _emit_lines_bb($ybeg, &$ordering) - { - $html = ''; - - // Now adjust for bbcode display... - foreach ($ordering as $order_array) - { - // Skip useless empty lines... - if ($this->skip_lines($order_array, $ordering)) - { - continue; - } - - // Only include double-finds if the last find has very few code location indications... - if (isset($order_array['first_find_c']) && sizeof($order_array['first_find_c'])) - { - $text = implode('', $order_array['find_c']); - if ($text === "\n" || $text === "\t" || $text === '') - { - // no real find, use first_find_c if possible! - //var_dump($order_array); - if (is_array($order_array['first_find_c'][0])) - { - $order_array['find_c'] = $order_array['first_find_c'][0]; - } - else - { - if (isset($order_array['replace']) || isset($order_array['add']) || isset($order_array['delete'])) - { - echo "skipped an edit!\n"; - var_dump($order_array); - } - continue; - } - } - else - { - if (strlen(implode('', $order_array['find_c'])) < 50 && is_array($order_array['first_find_c'][0])) - { - $html .= "#\n#-----[ FIND ]---------------------------------------------\n# Around Line {$ybeg}\n"; - $html .= implode("", $order_array['first_find_c'][0]); - $html .= "\n"; - $ybeg += sizeof($order_array['first_find_c'][0]); - } - } - } - - // still here but nothing to do? what the heck? - if (!isset($order_array['replace']) && !isset($order_array['add']) && !isset($order_array['delete'])) - { - echo "skipped an edit!\n"; - var_dump($order_array); - continue; - } - - if (sizeof($order_array['find_c'])) - { - $html .= "#\n#-----[ FIND ]---------------------------------------------\n# Around Line {$ybeg}\n"; - $html .= implode("", $order_array['find_c']); - $html .= "\n"; - } - - if (isset($order_array['replace'])) - { - $html .= "#\n#-----[ REPLACE WITH ]---------------------------------------------\n#\n"; - $html .= implode("", $order_array['replace']); - $html .= "\n"; - } - - if (isset($order_array['add'])) - { - $html .= "#\n#-----[ AFTER, ADD ]---------------------------------------------\n#\n"; - $html .= implode("", $order_array['add']); - $html .= "\n"; - } - - // There is no DELETE. :o - // Let's try to adjust it then... - if (isset($order_array['delete'])) - { - $text = implode('', $order_array['delete']); - if ($text === "\n" || $text === "\t" || $text === '') - { - continue; - } - - $ybeg += sizeof($order_array['find_c']); - - $html .= "#\n#-----[ FIND ]---------------------------------------------\n# Around Line {$ybeg}\n"; - $html .= implode("", $order_array['delete']); - $html .= "\n"; - - $html .= "#\n#-----[ REPLACE WITH ]---------------------------------------------\n# Just remove/delete the lines (replacing with an empty line)\n"; - $html .= "\n"; - $html .= "\n"; - } - } - - return $html; - } - - function format_open($filename) - { - $html = ''; - $html .= "#\n#-----[ OPEN ]--------------------------------------------- \n#\n{$filename}\n\n"; - - return $html; - } - - function format_close($filename) - { - return ''; - } - - function _emit_diff ($xbeg, $xlen, $ybeg, $ylen, $hunks) - { - - // Go through the hunks to determine which method we are using (AFTER, ADD; REPLACE WITH or DELETE) - - // Remove the header... - if (sizeof($hunks) <= 2 && !isset($hunks[1]['a']) && !isset($hunks[1]['d'])) - { - $reorder = false; - $orig_hunks = $hunks; - - foreach ($hunks as $key => $hunk) - { - if (isset($hunk['a']) && isset($hunk['d'])) - { - /**/ if (sizeof($hunk['a']) == 1 && sizeof($hunk['d']) == 1) - { - if (preg_match('/\* @version \$Id:.+\$$/', $hunk['a'][0]) && preg_match('/\* @version \$Id:.+\$$/', $hunk['d'][0])) - { - // Only remove this sole hunk... - unset($hunks[$key]); - $reorder = true; - continue; - } - }/**/ - - // Compare the add and replace one... - $string_1 = rtrim(trim(implode('', $hunk['a']))); - $string_2 = rtrim(trim(implode('', $hunk['d']))); - - if (strcmp($string_1, $string_2) === 0) - { - // Only remove this sole hunk... - unset($hunks[$key]); - $reorder = true; - continue; - } - } - } - - if ($reorder) - { - // Now check if we have no more 'a' and 'd's - $hunks = array_merge($hunks, array()); - } - } - else - { - $reorder = false; - $orig_hunks = $hunks; - - foreach ($hunks as $key => $hunk) - { - if (isset($hunk['a']) && isset($hunk['d'])) - { - /**/ if (sizeof($hunk['a']) == 1 && sizeof($hunk['d']) == 1) - { - if (preg_match('/\* @version \$Id:.+\$$/', $hunk['a'][0]) && preg_match('/\* @version \$Id:.+\$$/', $hunk['d'][0])) - { - // Only remove this sole hunk... - unset($hunks[$key]); - $reorder = true; - continue; - } - }/**/ - - // Compare the add and replace one... - $string_1 = rtrim(trim(implode('', $hunk['a']))); - $string_2 = rtrim(trim(implode('', $hunk['d']))); - - if (strcmp($string_1, $string_2) === 0) - { - // Only remove this sole hunk... - unset($hunks[$key]); - $reorder = true; - continue; - } - } - } - - if ($reorder) - { - $hunks = array_merge($hunks, array()); - - if (sizeof($hunks) == 1 && sizeof($hunks[0]) == 1 && isset($hunks[0]['c'])) - { - return; - } - else - { - $hunks = $orig_hunks; - } - } - } - - if (sizeof($hunks) == 1 && sizeof($hunks[0]) == 1 && isset($hunks[0]['c'])) - { - return; - } - - $replace = false; - foreach ($hunks as $key => $hunk) - { - if (isset($hunk['d']) && isset($hunk['a'])) - { - $replace = true; - break; - } - } - - $ordering = array(); - $cur_pos = 0; - - // Replace-block - if ($replace) - { - foreach ($hunks as $hunk) - { - if (!isset($hunk['a']) && !isset($hunk['d'])) - { - continue; - } - - if (!empty($hunk['c'])) - { - if (!isset($ordering[$cur_pos]['find_c'])) - { - $ordering[$cur_pos]['find_c'] = $hunk['c']; - } - else - { - $ordering[$cur_pos]['end_c'] = $hunk['c']; - } - } - - // Make sure we begin fresh... - if (!isset($ordering[$cur_pos]['replace'])) - { - $ordering[$cur_pos]['first_find_c'][] = $ordering[$cur_pos]['find_c']; - $ordering[$cur_pos]['find_c'] = array(); - $ordering[$cur_pos]['replace'] = array(); - } - - // Add the middle part if one exist... - if (isset($ordering[$cur_pos]['end_c'])) - { - $ordering[$cur_pos]['find_c'] = array_merge($ordering[$cur_pos]['find_c'], $ordering[$cur_pos]['end_c']); - $ordering[$cur_pos]['replace'] = array_merge($ordering[$cur_pos]['replace'], $ordering[$cur_pos]['end_c']); - unset($ordering[$cur_pos]['end_c']); - } - - if (isset($hunk['d'])) - { - $ordering[$cur_pos]['find_c'] = array_merge($ordering[$cur_pos]['find_c'], $hunk['d']); - } - - if (isset($hunk['a'])) - { - $ordering[$cur_pos]['replace'] = array_merge($ordering[$cur_pos]['replace'], $hunk['a']); - } - } - } - else - { - foreach ($hunks as $hunk) - { - if (!empty($hunk['c'])) - { - if (!isset($ordering[$cur_pos]['find_c'])) - { - $ordering[$cur_pos]['find_c'] = $hunk['c']; - } - else - { - $ordering[$cur_pos]['end_c'] = $hunk['c']; - } - } - - if (!empty($hunk['a'])) - { - if (isset($ordering[$cur_pos]['delete'])) - { - // If ordering is set with an delete entry, we will actually begin a new ordering array (to seperate delete from add) - $cur_pos++; - $ordering[$cur_pos]['find_c'] = $ordering[($cur_pos - 1)]['end_c']; - $ordering[$cur_pos]['add'] = $hunk['a']; - } - else - { - if (isset($ordering[$cur_pos]['add'])) - { - // Now, we really need to be quite careful here... - if (isset($ordering[$cur_pos]['end_c']) && isset($hunk['c']) && isset($hunk['a']) && sizeof($hunk) == 2) - { - // There is a new find/add entry we did not catch... let's try to add a new entry then... but first check the hunk[a] contents... - $text = trim(implode("\n", $hunk['c'])); - if ($text == "\n" || !$text) - { - $ordering[$cur_pos]['add'] = array_merge($ordering[$cur_pos]['add'], array("\n"), $hunk['a']); - } - else if (sizeof($hunk['c']) > 2 || strlen(implode('', $hunk['c'])) > 20) - { - $cur_pos++; - $ordering[$cur_pos]['find_c'] = $ordering[($cur_pos - 1)]['end_c']; - $ordering[$cur_pos]['add'] = $hunk['a']; - } - else - { - $cur_pos++; - $ordering[$cur_pos]['find_c'] = $ordering[($cur_pos - 1)]['end_c']; - $ordering[$cur_pos]['add'] = $hunk['a']; -/* echo 'FIND STATEMENT TOO TINY'; - echo ";".rawurlencode($text).";"; - var_dump($hunk); - exit;*/ - } - } - else - { - echo 'UNCATCHED ENTRY'; - var_dump($hunks); - exit; - } - } - else - { - $ordering[$cur_pos]['add'] = $hunk['a']; - } - } - } - else if (!empty($hunk['d'])) - { - if (isset($ordering[$cur_pos]['add'])) - { - // If ordering is set with an add entry, we will actually begin a new ordering array (to seperate delete from add) - $cur_pos++; - $ordering[$cur_pos]['find_c'] = $ordering[($cur_pos - 1)]['end_c']; - $ordering[$cur_pos]['delete'] = $hunk['d']; - } - else - { - $ordering[$cur_pos]['delete'] = $hunk['d']; - } - } - } - } - - $html = ''; - - return $this->_emit_lines_bb($ybeg, $ordering); - } - - function _diff_header($xbeg, $xlen, $ybeg, $ylen) - { - } -} - - -/** -* A class to format a Diff as MOD Template instuctions. -* -* Usage: -* -* $diff = new Diff($lines1, $lines2); // compute diff. -* -* $fmt = new BBCodeDiffFormatter; -* echo $fmt->format($diff, $lines1); // Output MOD Actions. -*/ -class MODXDiffFormatter extends BBCodeDiffFormatter -{ - function MODXDiffFormatter ($reverse = false, $context_lines = 3, $debug = false) - { - $this->do_reverse_diff = $reverse; - $this->context_lines = $context_lines; - $this->context_prefix = ' '; - $this->deletes_prefix = '-'; - $this->adds_prefix = '+'; - $this->debug = $debug; - } - - function _emit_lines_bb($ybeg, &$ordering) - { - $html = ''; - - // Now adjust for bbcode display... - foreach ($ordering as $order_array) - { - // Skip useless empty lines... - if ($this->skip_lines($order_array, $ordering)) - { - continue; - } - - // Only include double-finds if the last find has very few code location indications... - if (sizeof($order_array['first_find_c'])) - { - $text = implode('', $order_array['find_c']); - if ($text === "\n" || $text === "\t" || $text === '') - { - continue; - } - - if (strlen(implode('', $order_array['find_c'])) < 50) - { - if (substr($html, -8) !== '</find>' . "\n") - { - $html .= ' <edit>' . "\n"; - } - - $html .= ' <comment lang="en">Around Line ' . $ybeg . '</comment>' . "\n"; - $html .= ' <find>' . htmlspecialchars(implode('', $order_array['first_find_c'][0])) . '</find>' . "\n"; - $ybeg += sizeof($order_array['first_find_c'][0]); - } - } - - if (sizeof($order_array['find_c'])) - { - if (substr($html, -8) !== '</find>' . "\n") - { - $html .= ' <edit>' . "\n"; - } - -// $html .= ' <edit>' . "\n"; - $html .= ' <comment lang="en">Around Line ' . $ybeg . '</comment>' . "\n"; - $html .= ' <find>' . htmlspecialchars(implode('', $order_array['find_c'])) . '</find>' . "\n"; - } - - if (isset($order_array['replace'])) - { - $html .= ' <action type="replace-with">' . htmlspecialchars(implode('', $order_array['replace'])) . '</action>' . "\n"; - $html .= ' </edit>' . "\n"; - } - - if (isset($order_array['add'])) - { - $html .= ' <action type="after-add">' . htmlspecialchars(implode('', $order_array['add'])) . '</action>' . "\n"; - $html .= ' </edit>' . "\n"; - } - - // There is no DELETE. :o - // Let's try to adjust it then... - if (isset($order_array['delete'])) - { - $text = implode('', $order_array['delete']); - if ($text === "\n" || $text === "\t" || $text === '') - { - continue; - } - - $ybeg += sizeof($order_array['find_c']); - - if (substr($html, -8) !== '</find>' . "\n") - { - $html .= ' <edit>' . "\n"; - } - $html .= ' <comment lang="en">Around Line ' . $ybeg . ' / Just remove/delete the lines (replacing with an empty line)</comment>' . "\n"; - $html .= ' <find>' . htmlspecialchars(implode('', $order_array['delete'])) . '</find>' . "\n"; - $html .= ' <action type="replace-with"></action>' . "\n"; - $html .= ' </edit>'; - } - } - - return $html; - } - - function format_open($filename) - { - return '<open src="' . $filename . '">' . "\n"; - } - - function format_close($filename) - { - return '</open>' . "\n"; - } - - function _diff_header($xbeg, $xlen, $ybeg, $ylen) - { - } -} diff --git a/build/package.php b/build/package.php index d05448dfb4..00930abe65 100755 --- a/build/package.php +++ b/build/package.php @@ -139,6 +139,12 @@ if (sizeof($package->old_packages)) { unset($file_contents['all'][$index]); } + + $source_filename = $package->locations['old_versions'] . $package->get('simple_name') . '/' . $file; + if (!file_exists($source_filename)) + { + unset($file_contents['all'][$index]); + } } // First of all, fill the 'old' directory @@ -174,16 +180,33 @@ if (sizeof($package->old_packages)) $package->run_command('cp ' . $source_filename . ' ' . $dest_filename); } + /** + * We try to keep the update packages as small as possible while creating them. + * However, we sometimes need to include additional files that are not included + * in the diff in order to be able to correctly include the relatively + * referenced files from the same or subsequent directories. + */ + $copy_relative_directories = array( + 'adm/style/admin.css' => array( + 'copied' => false, + 'copy' => array( + 'adm/images/*' => 'adm/images', + ), + ), + 'config/' => array( + 'copied' => false, + 'copy' => array( + 'config/*.yml' => 'config', + ), + ), + ); + // Then fill the 'new' directory foreach ($file_contents['all'] as $file) { $source_filename = $package->locations['old_versions'] . $package->get('simple_name') . '/' . $file; $dest_filename = $dest_filename_dir . '/install/update/new/' . $file; - - if (!file_exists($source_filename)) - { - continue; - } + $filename = $file; // Create Directories along the way? $file = explode('/', $file); @@ -205,6 +228,37 @@ if (sizeof($package->old_packages)) } $package->run_command('cp ' . $source_filename . ' ' . $dest_filename); + + foreach ($copy_relative_directories as $reference => $data) + { + // Copy all relative referenced files if needed + if (strpos($filename, $reference) === 0 && !$data['copied']) + { + foreach ($data['copy'] as $source_dir_files => $destination_dir) + { + // Create directories along the way? + $directories = explode('/', $destination_dir); + + chdir($dest_filename_dir . '/install/update/new'); + foreach ($directories as $dir) + { + $dir = trim($dir); + if ($dir) + { + if (!file_exists('./' . $dir)) + { + $package->run_command('mkdir ' . $dir); + } + chdir('./' . $dir); + } + } + $source_dir_files = $package->locations['old_versions'] . $package->get('simple_name') . '/' . $source_dir_files; + $destination_dir = $dest_filename_dir . '/install/update/new/' . $destination_dir; + $package->run_command('cp ' . $source_dir_files . ' ' . $destination_dir); + } + $copy_relative_directories[$reference]['copied'] = true; + } + } } // Build index.php file for holding the file structure @@ -222,29 +276,23 @@ $update_info = array( if (sizeof($file_contents['all'])) { - $index_contents .= '\'files\' => array(\'' . implode("',\n\t'", $file_contents['all']) . '\'), -'; + $index_contents .= "\t'files' => array(\n\t\t'" . implode("',\n\t\t'", $file_contents['all']) . "',\n\t),\n"; } else { - $index_contents .= '\'files\' => array(), -'; + $index_contents .= "\t'files' => array(),\n"; } if (sizeof($file_contents['binary'])) { - $index_contents .= '\'binary\' => array(\'' . implode("',\n\t'", $file_contents['binary']) . '\'), -'; + $index_contents .= "\t'binary' => array(\n\t\t'" . implode("',\n\t\t'", $file_contents['binary']) . "',\n\t),\n"; } else { - $index_contents .= '\'binary\' => array(), -'; + $index_contents .= "\t'binary' => array(),\n"; } - $index_contents .= '); - -?' . '>'; + $index_contents .= ");\n"; $fp = fopen($dest_filename_dir . '/install/update/index.php', 'wt'); fwrite($fp, $index_contents); @@ -374,14 +422,22 @@ chdir($package->get('dest_dir') . '/install'); // $package->run_command('rm -v database_update.php'); $package->run_command('rm -v install_update.php'); +chdir($package->get('dest_dir')); +$package->run_command('mv -v styles/subsilver2 ../subsilver2'); +$package->run_command('cp -p docs/COPYING ../subsilver2/license.txt'); + chdir($package->locations['package_dir']); foreach ($compress_programs as $extension => $compress_command) { $package->begin_status('Packaging phpBB for ' . $extension); $package->run_command('rm -v ./release_files/' . $package->get('release_filename') . ".{$extension}"); + $package->run_command('rm -v ./release_files/subsilver2_' . $package->get('new_version_number') . ".{$extension}"); // Build Package $package->run_command("$compress_command ./release_files/" . $package->get('release_filename') . '.' . $extension . ' ' . $package->get('package_name')); + + // Build subSilver2 Package + $package->run_command("$compress_command ./release_files/subsilver2_" . $package->get('new_version_number') . '.' . $extension . ' subsilver2'); } // Microsoft Web PI packaging diff --git a/composer.phar b/composer.phar Binary files differindex a035fdc911..1e9ca731cd 100755 --- a/composer.phar +++ b/composer.phar diff --git a/git-tools/commit-msg-hook-range.sh b/git-tools/commit-msg-hook-range.sh new file mode 100755 index 0000000000..2b408c3e79 --- /dev/null +++ b/git-tools/commit-msg-hook-range.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# @copyright (c) 2014 phpBB Group +# @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +# +# Calls the git commit-msg hook on all non-merge commits in a given commit range. +# + +if [ "$#" -ne 1 ]; +then + echo "Expected one argument (commit range, e.g. phpbb/develop..ticket/12345)." + exit +fi + +DIR=$(dirname "$0") +COMMIT_RANGE="$1" +COMMIT_MSG_HOOK_PATH="$DIR/hooks/commit-msg" +COMMIT_MSG_HOOK_FATAL=$(git config --bool phpbb.hooks.commit-msg.fatal 2> /dev/null) +git config phpbb.hooks.commit-msg.fatal true + +EXIT_STATUS=0 +for COMMIT_HASH in $(git rev-list --no-merges "$COMMIT_RANGE") +do + echo "Inspecting commit message of commit $COMMIT_HASH" + + # The git commit-msg hook takes a path to a file containing a commit + # message. So we have to extract the commit message into a file first, + # which then also needs to be deleted after our work is done. + COMMIT_MESSAGE_PATH="$DIR/commit_msg.$COMMIT_HASH" + git log -n 1 --pretty=format:%B "$COMMIT_HASH" > "$COMMIT_MESSAGE_PATH" + + # Invoke hook on commit message file. + "$COMMIT_MSG_HOOK_PATH" "$COMMIT_MESSAGE_PATH" + + # If any commit message hook complains with a non-zero exit status, we + # will send a non-zero exit status upstream. + if [ $? -ne 0 ] + then + EXIT_STATUS=1 + fi + + rm "$COMMIT_MESSAGE_PATH" +done + +# Restore phpbb.hooks.commit-msg.fatal config +if [ -n "$COMMIT_MSG_HOOK_FATAL" ] +then + git config phpbb.hooks.commit-msg.fatal "$COMMIT_MSG_HOOK_FATAL" +fi + +exit $EXIT_STATUS diff --git a/phpBB/adm/images/corners_left.gif b/phpBB/adm/images/corners_left.gif Binary files differdeleted file mode 100644 index bacd276495..0000000000 --- a/phpBB/adm/images/corners_left.gif +++ /dev/null diff --git a/phpBB/adm/images/corners_left2.gif b/phpBB/adm/images/corners_left2.gif Binary files differdeleted file mode 100644 index 206e50368d..0000000000 --- a/phpBB/adm/images/corners_left2.gif +++ /dev/null diff --git a/phpBB/adm/images/corners_right.gif b/phpBB/adm/images/corners_right.gif Binary files differdeleted file mode 100644 index bcb5bd7d14..0000000000 --- a/phpBB/adm/images/corners_right.gif +++ /dev/null diff --git a/phpBB/adm/images/corners_right2.gif b/phpBB/adm/images/corners_right2.gif Binary files differdeleted file mode 100644 index 0ba66d50b2..0000000000 --- a/phpBB/adm/images/corners_right2.gif +++ /dev/null diff --git a/phpBB/adm/images/loading.gif b/phpBB/adm/images/loading.gif Binary files differnew file mode 100644 index 0000000000..e1ed0883e0 --- /dev/null +++ b/phpBB/adm/images/loading.gif diff --git a/phpBB/adm/images/no_avatar.gif b/phpBB/adm/images/no_avatar.gif Binary files differindex 80539c8c71..ad73330e71 100644 --- a/phpBB/adm/images/no_avatar.gif +++ b/phpBB/adm/images/no_avatar.gif diff --git a/phpBB/adm/images/toggle.gif b/phpBB/adm/images/toggle.gif Binary files differdeleted file mode 100644 index 8af6861bd1..0000000000 --- a/phpBB/adm/images/toggle.gif +++ /dev/null diff --git a/phpBB/adm/style/acp_attachments.html b/phpBB/adm/style/acp_attachments.html index c7b451e68b..5d35666fdd 100644 --- a/phpBB/adm/style/acp_attachments.html +++ b/phpBB/adm/style/acp_attachments.html @@ -122,11 +122,11 @@ { if (newimage == 'no_image') { - document.getElementById('image_upload_icon').src = "{PHPBB_ROOT_PATH}images/spacer.gif"; + document.getElementById('image_upload_icon').src = "{ROOT_PATH}images/spacer.gif"; } else { - document.getElementById('image_upload_icon').src = "{PHPBB_ROOT_PATH}{IMG_PATH}/" + newimage; + document.getElementById('image_upload_icon').src = "{ROOT_PATH}{IMG_PATH}/" + newimage; } } @@ -192,7 +192,7 @@ <dd><select name="upload_icon" id="upload_icon" onchange="update_image(this.options[selectedIndex].value);"> <option value="no_image"<!-- IF S_NO_IMAGE --> selected="selected"<!-- ENDIF -->>{L_NO_IMAGE}</option>{S_FILENAME_LIST} </select></dd> - <dd> <img <!-- IF S_NO_IMAGE -->src="{PHPBB_ROOT_PATH}images/spacer.gif"<!-- ELSE -->src="{UPLOAD_ICON_SRC}"<!-- ENDIF --> id="image_upload_icon" alt="" title="" /> </dd> + <dd> <img <!-- IF S_NO_IMAGE -->src="{ROOT_PATH}images/spacer.gif"<!-- ELSE -->src="{UPLOAD_ICON_SRC}"<!-- ENDIF --> id="image_upload_icon" alt="" title="" /> </dd> </dl> <dl> <dt><label for="extgroup_filesize">{L_MAX_EXTGROUP_FILESIZE}{L_COLON}</label></dt> @@ -224,7 +224,7 @@ <fieldset class="tabulated"> <legend>{L_TITLE}</legend> - <table cellspacing="1"> + <table class="table1"> <col class="row1" /><col class="row1" /><col class="row2" /> <thead> <tr> @@ -291,7 +291,7 @@ <fieldset class="tabulated"> <legend>{L_TITLE}</legend> - <table cellspacing="1"> + <table class="table1"> <col class="row1" /><col class="row1" /><col class="row2" /> <thead> <tr> @@ -331,7 +331,7 @@ <fieldset class="tabulated"> <legend>{L_TITLE}</legend> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_FILENAME}</th> @@ -344,7 +344,7 @@ </thead> <tbody> <!-- BEGIN orphan --> - <!-- IF orphan.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td><a href="{orphan.U_FILE}">{orphan.REAL_FILENAME}</a></td> <td>{orphan.FILETIME}</td> <td>{orphan.FILESIZE}</td> @@ -378,67 +378,74 @@ <fieldset class="tabulated"> <legend>{L_TITLE}</legend> - <div class="pagination"> + <div class="pagination top-pagination"> <!-- IF .pagination or TOTAL_FILES --> {L_NUMBER_FILES}{L_COLON} {TOTAL_FILES} • {L_TOTAL_SIZE}{L_COLON} {TOTAL_SIZE} <!-- IF .pagination --> • <!-- INCLUDE pagination.html --> <!-- ELSE --> - • {S_ON_PAGE} + • {PAGE_NUMBER} <!-- ENDIF --> <!-- ENDIF --> </div> - <table cellspacing="1"> +<!-- IF .attachments --> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_FILENAME}</th> <th>{L_POSTED}</th> - <th>{L_FILESIZE}</th> - <th>{L_DELETE}</th> + <th class="centered-text">{L_FILESIZE}</th> + <th class="centered-text">{L_MARK}</th> </tr> </thead> <tbody> <!-- BEGIN attachments --> - <!-- IF attachments.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td> <!-- IF attachments.S_IN_MESSAGE -->{L_EXTENSION_GROUP}{L_COLON} <strong><!-- IF attachments.EXT_GROUP_NAME -->{attachments.EXT_GROUP_NAME}<!-- ELSE -->{L_NO_EXT_GROUP}<!-- ENDIF --></strong><br />{attachments.L_DOWNLOAD_COUNT}<br />{L_IN} {L_PRIVATE_MESSAGE} <!-- ELSE --><a href="{attachments.U_FILE}" style="font-weight: bold;">{attachments.REAL_FILENAME}</a><br /><!-- IF attachments.COMMENT -->{attachments.COMMENT}<br /><!-- ENDIF -->{attachments.L_DOWNLOAD_COUNT}<br />{L_TOPIC}{L_COLON} <a href="{attachments.U_VIEW_TOPIC}">{attachments.TOPIC_TITLE}</a><!-- ENDIF --> </td> <td>{attachments.FILETIME}<br />{L_POST_BY_AUTHOR} {attachments.ATTACHMENT_POSTER}</td> - <td>{attachments.FILESIZE}</td> - <td><input type="checkbox" class="radio" name="delete[{attachments.ATTACH_ID}]" /></td> + <td class="centered-text">{attachments.FILESIZE}</td> + <td class="centered-text"><input type="checkbox" class="radio" name="delete[{attachments.ATTACH_ID}]" /></td> </tr> <!-- END attachments --> - <tr class="row4"> - <td colspan="3"> </td> - <td class="small"><a href="#" onclick="marklist('attachments', 'delete', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('attachments', 'delete', false); return false;">{L_UNMARK_ALL}</a></td> - </tr> </tbody> </table> +<!-- ELSE --> + <div class="errorbox"> + <p>{L_NO_ATTACHMENTS}</p> + </div> +<!-- ENDIF --> <!-- IF TOTAL_FILES --> - <fieldset class="display-options"> - {L_DISPLAY_LOG}{L_COLON} {S_LIMIT_DAYS} {L_SORT_BY}{L_COLON} {S_SORT_KEY} {S_SORT_DIR} - <input class="button2" type="submit" value="{L_GO}" name="sort" /> - </fieldset> - - <hr /> - <div class="pagination"> {L_NUMBER_FILES}{L_COLON} {TOTAL_FILES} • {L_TOTAL_SIZE}{L_COLON} {TOTAL_SIZE} <!-- IF .pagination --> • <!-- INCLUDE pagination.html --> <!-- ELSE --> - • {S_ON_PAGE} + • {PAGE_NUMBER} <!-- ENDIF --> </div> <!-- ENDIF --> - <p class="submit-buttons"> - <input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" /> - <input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" /> - </p> + <fieldset class="display-options"> + {L_DISPLAY_LOG}{L_COLON} {S_LIMIT_DAYS} {L_SORT_BY}{L_COLON} {S_SORT_KEY} {S_SORT_DIR} + <input class="button2" type="submit" value="{L_GO}" name="sort" /> + </fieldset> + + <hr /> + +<!-- IF .attachments --> + <fieldset class="quick"> + <input class="button2" type="submit" name="submit" value="{L_DELETE_MARKED}" /><br /> + <p class="small"> + <a href="#" onclick="marklist('attachments', 'delete', true); return false;">{L_MARK_ALL}</a> • + <a href="#" onclick="marklist('attachments', 'delete', false); return false;">{L_UNMARK_ALL}</a> + </p> + </fieldset> +<!-- ENDIF --> {S_FORM_TOKEN} </fieldset> </form> diff --git a/phpBB/adm/style/acp_avatar_options_local.html b/phpBB/adm/style/acp_avatar_options_local.html index 148efd051b..0cdb3644d7 100644 --- a/phpBB/adm/style/acp_avatar_options_local.html +++ b/phpBB/adm/style/acp_avatar_options_local.html @@ -8,18 +8,14 @@ </select> <input type="submit" value="{L_GO}" name="avatar_local_go" class="button2" /></dd> </dl> <!-- IF AVATAR_LOCAL_SHOW --> - <table> + <ul id="gallery"> <!-- BEGIN avatar_local_row --> - <tr> - <!-- BEGIN avatar_local_col --> - <td class="row1" style="text-align: center;"><img src="{avatar_local_row.avatar_local_col.AVATAR_IMAGE}" alt="{avatar_local_row.avatar_local_col.AVATAR_NAME}" title="{avatar_local_row.avatar_local_col.AVATAR_NAME}"/></td> - <!-- END avatar_local_col --> - </tr> - <tr> - <!-- BEGIN avatar_local_option --> - <td class="row2" style="text-align: center;"><input type="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_option.S_ROW_COUNT}" value="{avatar_local_row.avatar_local_option.AVATAR_FILE}" /></td> - <!-- END avatar_local_option --> - </tr> + <!-- BEGIN avatar_local_col --> + <li> + <label for="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}"><img src="{avatar_local_row.avatar_local_col.AVATAR_IMAGE}" alt="" /><br /> + <input type="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}" value="{avatar_local_row.avatar_local_col.AVATAR_FILE}" /></label> + </li> + <!-- END avatar_local_col --> <!-- END avatar_local_row --> - </table> + </ul> <!-- ENDIF --> diff --git a/phpBB/adm/style/acp_bbcodes.html b/phpBB/adm/style/acp_bbcodes.html index 5939af24ae..8c8b805975 100644 --- a/phpBB/adm/style/acp_bbcodes.html +++ b/phpBB/adm/style/acp_bbcodes.html @@ -47,6 +47,8 @@ </dl> </fieldset> + <!-- EVENT acp_bbcodes_edit_fieldsets_after --> + <fieldset class="submit-buttons"> <legend>{L_SUBMIT}</legend> <input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" /> @@ -56,7 +58,7 @@ <br /> - <table cellspacing="1" id="down"> + <table class="table1" id="down"> <thead> <tr> <th colspan="2">{L_TOKENS}</th> @@ -71,7 +73,7 @@ </thead> <tbody> <!-- BEGIN token --> - <tr valign="top"> + <tr style="vertical-align: top;"> <td class="row1">{token.TOKEN}</td> <td class="row2">{token.EXPLAIN}</td> </tr> @@ -90,7 +92,7 @@ <fieldset class="tabulated"> <legend>{L_ACP_BBCODES}</legend> - <table cellspacing="1" id="down"> + <table class="table1 zebra-table" id="down"> <thead> <tr> <th>{L_BBCODE_TAG}</th> @@ -99,9 +101,9 @@ </thead> <tbody> <!-- BEGIN bbcodes --> - <!-- IF bbcodes.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td style="text-align: center;">{bbcodes.BBCODE_TAG}</td> - <td style="text-align: right; width: 40px;"><a href="{bbcodes.U_EDIT}">{ICON_EDIT}</a> <a href="{bbcodes.U_DELETE}" data-ajax="row_delete">{ICON_DELETE}</a></td> + <td class="actions"><!-- EVENT acp_bbcodes_actions_prepend --> <a href="{bbcodes.U_EDIT}">{ICON_EDIT}</a> <a href="{bbcodes.U_DELETE}" data-ajax="row_delete">{ICON_DELETE}</a> <!-- EVENT acp_bbcodes_actions_append --></td> </tr> <!-- BEGINELSE --> <tr class="row3"> diff --git a/phpBB/adm/style/acp_bots.html b/phpBB/adm/style/acp_bots.html index cdd0fd4a93..b0e61015b6 100644 --- a/phpBB/adm/style/acp_bots.html +++ b/phpBB/adm/style/acp_bots.html @@ -62,7 +62,7 @@ <form id="acp_bots" method="post" action="{U_ACTION}"> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_BOT_NAME}</th> @@ -73,7 +73,7 @@ </thead> <tbody> <!-- BEGIN bots --> - <!-- IF bots.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td style="width: 50%;">{bots.BOT_NAME}</td> <td style="width: 15%; white-space: nowrap;" align="center"> {bots.LAST_VISIT} </td> <td style="text-align: center;"> <a href="{bots.U_ACTIVATE_DEACTIVATE}" data-ajax="activate_deactivate">{bots.L_ACTIVATE_DEACTIVATE}</a> </td> diff --git a/phpBB/adm/style/acp_ext_purge.html b/phpBB/adm/style/acp_ext_delete_data.html index 94bef82ca5..0f3adb7cfe 100644 --- a/phpBB/adm/style/acp_ext_purge.html +++ b/phpBB/adm/style/acp_ext_delete_data.html @@ -1,39 +1,39 @@ <!-- INCLUDE overall_header.html --> - <a name="maincontent"></a> + <a id="maincontent"></a> <h1>{L_EXTENSIONS_ADMIN}</h1> <p>{L_EXTENSIONS_EXPLAIN}</p> - <p>{L_PURGE_EXPLAIN}</p> + <p>{L_EXTENSION_DELETE_DATA_EXPLAIN}</p> <!-- IF MIGRATOR_ERROR --> <div class="errorbox"> <p><strong>{L_MIGRATION_EXCEPTION_ERROR}</strong></p> <p>{MIGRATOR_ERROR}</p> - <p><a href="{U_RETURN}">{L_RETURN}</a></p> + <p><a href="{U_RETURN}">{L_RETURN_TO_EXTENSION_LIST}</a></p> </div> <!-- ELSEIF PRE --> <div class="errorbox"> - <p>{L_PURGE_CONFIRM}</p> + <p>{L_CONFIRM_MESSAGE}</p> </div> <form id="acp_extensions" method="post" action="{U_PURGE}"> <fieldset class="submit-buttons"> - <legend>{L_PURGE}</legend> - <input class="button1" type="submit" name="purge" value="{L_PURGE}" /> + <legend>{L_EXTENSION_DELETE_DATA}</legend> + <input class="button1" type="submit" name="delete_data" value="{L_EXTENSION_DELETE_DATA}" /> <input class="button2" type="submit" name="cancel" value="{L_CANCEL}" /> </fieldset> </form> <!-- ELSEIF S_NEXT_STEP --> <div class="errorbox"> - <p>{L_PURGE_IN_PROGRESS}</p> + <p>{L_EXTENSION_DELETE_DATA_IN_PROGRESS}</p> </div> <!-- ELSE --> <div class="successbox"> - <p>{L_PURGE_SUCCESS}</p> + <p>{L_EXTENSION_DELETE_DATA_SUCCESS}</p> <br /> - <p><a href="{U_RETURN}">{L_RETURN}</a></p> + <p><a href="{U_RETURN}">{L_RETURN_TO_EXTENSION_LIST}</a></p> </div> <!-- ENDIF --> diff --git a/phpBB/adm/style/acp_ext_details.html b/phpBB/adm/style/acp_ext_details.html index 18786d80f9..6aff4b29cc 100644 --- a/phpBB/adm/style/acp_ext_details.html +++ b/phpBB/adm/style/acp_ext_details.html @@ -1,6 +1,6 @@ <!-- INCLUDE overall_header.html --> -<a name="maincontent"></a> +<a id="maincontent"></a> <a href="{U_BACK}" style="float: {S_CONTENT_FLOW_END};">« {L_BACK}</a> @@ -10,39 +10,39 @@ <legend>{L_EXT_DETAILS}</legend> <!-- IF META_DISPLAY_NAME --> <dl> - <dt><label for="meta_display_name">{L_DISPLAY_NAME}{L_COLON}</label></dt> + <dt><label>{L_DISPLAY_NAME}{L_COLON}</label></dt> <dd><strong id="meta_display_name">{META_DISPLAY_NAME}</strong></dd> </dl> <!-- ENDIF --> <dl> - <dt><label for="meta_name">{L_CLEAN_NAME}{L_COLON}</label></dt> + <dt><label>{L_CLEAN_NAME}{L_COLON}</label></dt> <dd><strong id="meta_name">{META_NAME}</strong></dd> </dl> <!-- IF META_DESCRIPTION --> <dl> - <dt><label for="meta_description">{L_DESCRIPTION}{L_COLON}</label></dt> - <dd><p id="meta_description">{META_DESCRIPTION}</p></dd> + <dt><label>{L_DESCRIPTION}{L_COLON}</label></dt> + <dd><span id="meta_description">{META_DESCRIPTION}</span></dd> </dl> <!-- ENDIF --> <dl> - <dt><label for="meta_version">{L_VERSION}{L_COLON}</label></dt> - <dd><p id="meta_version">{META_VERSION}</p></dd> + <dt><label>{L_VERSION}{L_COLON}</label></dt> + <dd><span id="meta_version">{META_VERSION}</span></dd> </dl> <!-- IF META_HOMEPAGE --> <dl> - <dt><label for="meta_homepage">{L_HOMEPAGE}{L_COLON}</label></dt> - <dd><p id="meta_homepage">{META_HOMEPAGE}</p></dd> + <dt><label>{L_HOMEPAGE}{L_COLON}</label></dt> + <dd><strong id="meta_homepage"><a href="{META_HOMEPAGE}">{META_HOMEPAGE}</a></strong></dd> </dl> <!-- ENDIF --> <!-- IF META_TIME --> <dl> - <dt><label for="meta_time">{L_TIME}{L_COLON}</label></dt> - <dd><p id="meta_time">{META_TIME}</p></dd> + <dt><label>{L_TIME}{L_COLON}</label></dt> + <dd><span id="meta_time">{META_TIME}</span></dd> </dl> <!-- ENDIF --> <dl> - <dt><label for="meta_license">{L_LICENCE}{L_COLON}</label></dt> - <dd><p id="meta_license">{META_LICENCE}</p></dd> + <dt><label>{L_LICENSE}{L_COLON}</label></dt> + <dd><span id="meta_license">{META_LICENSE}</span></dd> </dl> </fieldset> @@ -51,14 +51,14 @@ <legend>{L_REQUIREMENTS}</legend> <!-- IF META_REQUIRE_PHPBB --> <dl<!-- IF META_REQUIRE_PHPBB_FAIL --> class="requirements_not_met"<!-- ENDIF -->> - <dt><label for="require_phpbb">{L_PHPBB_VERSION}{L_COLON}</label></dt> - <dd><p id="require_phpbb">{META_REQUIRE_PHPBB}</p></dd> + <dt><label>{L_PHPBB_VERSION}{L_COLON}</label></dt> + <dd><span id="require_phpbb">{META_REQUIRE_PHPBB}</span></dd> </dl> <!-- ENDIF --> <!-- IF META_REQUIRE_PHP --> <dl<!-- IF META_REQUIRE_PHP_FAIL --> class="requirements_not_met"<!-- ENDIF -->> - <dt><label for="require_php">{L_PHP_VERSION}{L_COLON}</label></dt> - <dd><p id="require_php">{META_REQUIRE_PHP}</p></dd> + <dt><label>{L_PHP_VERSION}{L_COLON}</label></dt> + <dd><span id="require_php">{META_REQUIRE_PHP}</span></dd> </dl> <!-- ENDIF --> </fieldset> @@ -69,25 +69,25 @@ <!-- BEGIN meta_authors --> <fieldset> <dl> - <dt><label for="meta_author_name">{L_AUTHOR_NAME}{L_COLON}</label></dt> - <dd><strong id="meta_author_name">{meta_authors.AUTHOR_NAME}</strong></dd> + <dt><label>{L_AUTHOR_NAME}{L_COLON}</label></dt> + <dd><strong>{meta_authors.AUTHOR_NAME}</strong></dd> </dl> <!-- IF meta_authors.AUTHOR_EMAIL --> <dl> - <dt><label for="meta_author_email">{L_AUTHOR_EMAIL}{L_COLON}</label></dt> - <dd><strong id="meta_author_email"><a href="mailto:{meta_authors.AUTHOR_EMAIL}">{meta_authors.AUTHOR_EMAIL}</a></strong></dd> + <dt><label>{L_AUTHOR_EMAIL}{L_COLON}</label></dt> + <dd><strong><a href="mailto:{meta_authors.AUTHOR_EMAIL}">{meta_authors.AUTHOR_EMAIL}</a></strong></dd> </dl> <!-- ENDIF --> <!-- IF meta_authors.AUTHOR_HOMEPAGE --> <dl> - <dt><label for="meta_author_url">{L_AUTHOR_HOMEPAGE}{L_COLON}</label></dt> - <dd><strong id="meta_author_url"><a href="{meta_authors.AUTHOR_HOMEPAGE}">{meta_authors.AUTHOR_HOMEPAGE}</a></strong></dd> + <dt><label>{L_AUTHOR_HOMEPAGE}{L_COLON}</label></dt> + <dd><strong><a href="{meta_authors.AUTHOR_HOMEPAGE}">{meta_authors.AUTHOR_HOMEPAGE}</a></strong></dd> </dl> <!-- ENDIF --> <!-- IF meta_authors.AUTHOR_ROLE --> <dl> - <dt><label for="author_role">{L_AUTHOR_ROLE}{L_COLON}</label></dt> - <dd><strong id="meta_author_role">{meta_authors.AUTHOR_ROLE}</strong></dd> + <dt><label>{L_AUTHOR_ROLE}{L_COLON}</label></dt> + <dd><strong>{meta_authors.AUTHOR_ROLE}</strong></dd> </dl> <!-- ENDIF --> </fieldset> diff --git a/phpBB/adm/style/acp_ext_disable.html b/phpBB/adm/style/acp_ext_disable.html index 7dc3f6ec97..d650544ff7 100644 --- a/phpBB/adm/style/acp_ext_disable.html +++ b/phpBB/adm/style/acp_ext_disable.html @@ -1,33 +1,33 @@ <!-- INCLUDE overall_header.html --> - <a name="maincontent"></a> + <a id="maincontent"></a> <h1>{L_EXTENSIONS_ADMIN}</h1> <p>{L_EXTENSIONS_EXPLAIN}</p> - <p>{L_DISABLE_EXPLAIN}</p> + <p>{L_EXTENSION_DISABLE_EXPLAIN}</p> <!-- IF PRE --> <div class="errorbox"> - <p>{L_DISABLE_CONFIRM}</p> + <p>{L_CONFIRM_MESSAGE}</p> </div> <form id="acp_extensions" method="post" action="{U_DISABLE}"> <fieldset class="submit-buttons"> - <legend>{L_DISABLE}</legend> - <input class="button1" type="submit" name="disable" value="{L_DISABLE}" /> + <legend>{L_EXTENSION_DISABLE}</legend> + <input class="button1" type="submit" name="disable" value="{L_EXTENSION_DISABLE}" /> <input class="button2" type="submit" name="cancel" value="{L_CANCEL}" /> </fieldset> </form> <!-- ELSEIF S_NEXT_STEP --> <div class="errorbox"> - <p>{L_DISABLE_IN_PROGRESS}</p> + <p>{L_EXTENSION_DISABLE_IN_PROGRESS}</p> </div> <!-- ELSE --> <div class="successbox"> - <p>{L_DISABLE_SUCCESS}</p> + <p>{L_EXTENSION_DISABLE_SUCCESS}</p> <br /> - <p><a href="{U_RETURN}">{L_RETURN}</a></p> + <p><a href="{U_RETURN}">{L_RETURN_TO_EXTENSION_LIST}</a></p> </div> <!-- ENDIF --> diff --git a/phpBB/adm/style/acp_ext_enable.html b/phpBB/adm/style/acp_ext_enable.html index 35585207eb..42523f1f58 100644 --- a/phpBB/adm/style/acp_ext_enable.html +++ b/phpBB/adm/style/acp_ext_enable.html @@ -1,39 +1,39 @@ <!-- INCLUDE overall_header.html --> - <a name="maincontent"></a> + <a id="maincontent"></a> <h1>{L_EXTENSIONS_ADMIN}</h1> <p>{L_EXTENSIONS_EXPLAIN}</p> - <p>{L_ENABLE_EXPLAIN}</p> + <p>{L_EXTENSION_ENABLE_EXPLAIN}</p> <!-- IF MIGRATOR_ERROR --> <div class="errorbox"> <p><strong>{L_MIGRATION_EXCEPTION_ERROR}</strong></p> <p>{MIGRATOR_ERROR}</p> - <p><a href="{U_RETURN}">{L_RETURN}</a></p> + <p><a href="{U_RETURN}">{L_RETURN_TO_EXTENSION_LIST}</a></p> </div> <!-- ELSEIF PRE --> <div class="errorbox"> - <p>{L_ENABLE_CONFIRM}</p> + <p>{L_CONFIRM_MESSAGE}</p> </div> <form id="acp_extensions" method="post" action="{U_ENABLE}"> <fieldset class="submit-buttons"> - <legend>{L_ENABLE}</legend> - <input class="button1" type="submit" name="enable" value="{L_ENABLE}" /> + <legend>{L_EXTENSION_ENABLE}</legend> + <input class="button1" type="submit" name="enable" value="{L_EXTENSION_ENABLE}" /> <input class="button2" type="submit" name="cancel" value="{L_CANCEL}" /> </fieldset> </form> <!-- ELSEIF S_NEXT_STEP --> <div class="errorbox"> - <p>{L_ENABLE_IN_PROGRESS}</p> + <p>{L_EXTENSION_ENABLE_IN_PROGRESS}</p> </div> <!-- ELSE --> <div class="successbox"> - <p>{L_ENABLE_SUCCESS}</p> + <p>{L_EXTENSION_ENABLE_SUCCESS}</p> <br /> - <p><a href="{U_RETURN}">{L_RETURN}</a></p> + <p><a href="{U_RETURN}">{L_RETURN_TO_EXTENSION_LIST}</a></p> </div> <!-- ENDIF --> diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html index 53de0b4d12..2fcc6eab31 100644 --- a/phpBB/adm/style/acp_ext_list.html +++ b/phpBB/adm/style/acp_ext_list.html @@ -1,12 +1,12 @@ <!-- INCLUDE overall_header.html --> -<a name="maincontent"></a> +<a id="maincontent"></a> <h1>{L_EXTENSIONS_ADMIN}</h1> <p>{L_EXTENSIONS_EXPLAIN}</p> - <table cellspacing="1"> + <table class="table1"> <col class="row1" ><col class="row2" ><col class="row2" > <thead> <tr> @@ -18,17 +18,15 @@ <tbody> <!-- IF .enabled --> <tr> - <td class="row3" colspan="3"> - <strong>{L_ENABLED} {L_EXTENSIONS}</strong> - </td> + <td class="row3" colspan="3"><strong>{L_EXTENSIONS_ENABLED}</strong></td> </tr> <!-- BEGIN enabled --> <tr class="ext_enabled"> - <td><strong>{enabled.META_DISPLAY_NAME}</strong></a></td> + <td><strong>{enabled.META_DISPLAY_NAME}</strong></td> <td style="text-align: center;"><a href="{enabled.U_DETAILS}">{L_DETAILS}</a></td> <td style="text-align: center;"> <!-- BEGIN actions --> - <a href="{enabled.actions.U_ACTION}" alt="{enabled.actions.L_ACTION}">{enabled.actions.L_ACTION}</a> + <a href="{enabled.actions.U_ACTION}"<!-- IF enabled.actions.L_ACTION_EXPLAIN --> title="{enabled.actions.L_ACTION_EXPLAIN}"<!-- ENDIF -->>{enabled.actions.L_ACTION}</a> <!-- IF not enabled.actions.S_LAST_ROW --> | <!-- ENDIF --> <!-- END actions --> </td> @@ -38,17 +36,17 @@ <!-- IF .disabled --> <tr> - <td class="row3" colspan="3"><strong>{L_DISABLED} {L_EXTENSIONS}</strong></td> + <td class="row3" colspan="3"><strong>{L_EXTENSIONS_DISABLED}</strong></td> </tr> <!-- BEGIN disabled --> <tr class="ext_disabled"> - <td><strong>{disabled.META_DISPLAY_NAME}</strong></a></td> + <td><strong>{disabled.META_DISPLAY_NAME}</strong></td> <td style="text-align: center;"> <!-- IF disabled.U_DETAILS --><a href="{disabled.U_DETAILS}">{L_DETAILS}</a><!-- ENDIF --> </td> <td style="text-align: center;"> <!-- BEGIN actions --> - <a href="{disabled.actions.U_ACTION}" alt="{disabled.actions.L_ACTION}">{disabled.actions.L_ACTION}</a> + <a href="{disabled.actions.U_ACTION}"<!-- IF disabled.actions.L_ACTION_EXPLAIN --> title="{disabled.actions.L_ACTION_EXPLAIN}"<!-- ENDIF -->>{disabled.actions.L_ACTION}</a> <!-- IF not disabled.actions.S_LAST_ROW --> | <!-- ENDIF --> <!-- END actions --> </td> @@ -57,5 +55,22 @@ <!-- ENDIF --> </tbody> </table> + <br /> + + <table class="table1"> + <tr> + <th>{L_EXTENSION_UPDATE_HEADLINE}</th> + </tr> + <tr> + <td class="row3">{L_EXTENSION_UPDATE_EXPLAIN}</td> + </tr> + <tr> + <th>{L_EXTENSION_REMOVE_HEADLINE}</th> + </tr> + <tr> + <td class="row3">{L_EXTENSION_REMOVE_EXPLAIN}</td> + </tr> + </tbody> + </table> <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html index 7b1466cfbd..f8ea284acb 100644 --- a/phpBB/adm/style/acp_forums.html +++ b/phpBB/adm/style/acp_forums.html @@ -14,45 +14,45 @@ <!-- IF not S_ADD_ACTION and S_FORUM_ORIG_POST --> if (value == {FORUM_POST}) { - dE('type_actions', -1); + phpbb.toggleDisplay('type_actions', -1); } else { - dE('type_actions', 1); + phpbb.toggleDisplay('type_actions', 1); } <!-- ENDIF --> <!-- IF not S_ADD_ACTION and S_FORUM_ORIG_CAT and S_HAS_SUBFORUMS --> if (value == {FORUM_LINK}) { - dE('cat_to_link_actions', 1); + phpbb.toggleDisplay('cat_to_link_actions', 1); } else { - dE('cat_to_link_actions', -1); + phpbb.toggleDisplay('cat_to_link_actions', -1); } <!-- ENDIF --> if (value == {FORUM_POST}) { - dE('forum_post_options', 1); - dE('forum_link_options', -1); - dE('forum_rules_options', 1); - dE('forum_cat_options', -1); + phpbb.toggleDisplay('forum_post_options', 1); + phpbb.toggleDisplay('forum_link_options', -1); + phpbb.toggleDisplay('forum_rules_options', 1); + phpbb.toggleDisplay('forum_cat_options', -1); } else if (value == {FORUM_LINK}) { - dE('forum_post_options', -1); - dE('forum_link_options', 1); - dE('forum_rules_options', -1); - dE('forum_cat_options', -1); + phpbb.toggleDisplay('forum_post_options', -1); + phpbb.toggleDisplay('forum_link_options', 1); + phpbb.toggleDisplay('forum_rules_options', -1); + phpbb.toggleDisplay('forum_cat_options', -1); } else if (value == {FORUM_CAT}) { - dE('forum_post_options', -1); - dE('forum_link_options', -1); - dE('forum_rules_options', 1); - dE('forum_cat_options', 1); + phpbb.toggleDisplay('forum_post_options', -1); + phpbb.toggleDisplay('forum_link_options', -1); + phpbb.toggleDisplay('forum_rules_options', 1); + phpbb.toggleDisplay('forum_cat_options', 1); } } @@ -64,30 +64,30 @@ { <!-- IF not S_ADD_ACTION and S_FORUM_ORIG_POST --> <!-- IF S_FORUM_POST --> - dE('type_actions', -1); + phpbb.toggleDisplay('type_actions', -1); <!-- ENDIF --> <!-- ENDIF --> <!-- IF not S_ADD_ACTION and S_FORUM_ORIG_CAT and S_HAS_SUBFORUMS --> <!-- IF S_FORUM_CAT --> - dE('cat_to_link_actions', -1); + phpbb.toggleDisplay('cat_to_link_actions', -1); <!-- ENDIF --> <!-- ENDIF --> <!-- IF not S_FORUM_POST --> - dE('forum_post_options', -1); + phpbb.toggleDisplay('forum_post_options', -1); <!-- ENDIF --> <!-- IF not S_FORUM_CAT --> - dE('forum_cat_options', -1); + phpbb.toggleDisplay('forum_cat_options', -1); <!-- ENDIF --> <!-- IF not S_FORUM_LINK --> - dE('forum_link_options', -1); + phpbb.toggleDisplay('forum_link_options', -1); <!-- ENDIF --> <!-- IF S_FORUM_LINK --> - dE('forum_rules_options', -1); + phpbb.toggleDisplay('forum_rules_options', -1); <!-- ENDIF --> } @@ -278,6 +278,19 @@ <dd><label><input type="radio" class="radio" name="prune_sticky" value="1"<!-- IF S_PRUNE_STICKY --> id="prune_sticky" checked="checked"<!-- ENDIF --> /> {L_YES}</label> <label><input type="radio" class="radio" name="prune_sticky" value="0"<!-- IF not S_PRUNE_STICKY --> id="prune_sticky" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> </dl> + <dl> + <dt><label for="enable_shadow_prune">{L_FORUM_PRUNE_SHADOW}{L_COLON}</label><br /><span>{L_FORUM_PRUNE_SHADOW_EXPLAIN}</span></dt> + <dd><label><input type="radio" class="radio" name="enable_shadow_prune" value="1"<!-- IF S_PRUNE_SHADOW_ENABLE --> id="enable_shadow_prune" checked="checked"<!-- ENDIF --> /> {L_YES}</label> + <label><input type="radio" class="radio" name="enable_shadow_prune" value="0"<!-- IF not S_PRUNE_SHADOW_ENABLE --> id="enable_shadow_prune" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> + </dl> + <dl> + <dt><label for="prune_shadow_freq">{L_AUTO_PRUNE_FREQ}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_FREQ_EXPLAIN}</span></dt> + <dd><input type="number" id="prune_shadow_freq" name="prune_shadow_freq" value="{PRUNE_FREQ}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd> + </dl> + <dl> + <dt><label for="prune_shadow_days">{L_AUTO_PRUNE_DAYS}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_DAYS_EXPLAIN}</span></dt> + <dd><input type="number" id="prune_shadow_days" name="prune_shadow_days" value="{PRUNE_DAYS}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd> + </dl> </fieldset> </div> @@ -440,32 +453,23 @@ <p><strong>{NAVIGATION}<!-- IF S_NO_FORUMS --> [<a href="{U_EDIT}">{L_EDIT}</a> | <a href="{U_DELETE}">{L_DELETE}</a><!-- IF not S_LINK --> | <a href="{U_SYNC}">{L_RESYNC}</a><!-- ENDIF -->]<!-- ENDIF --></strong></p> <!-- IF .forums --> - <table cellspacing="1"> + <table class="table1 forums"> <col class="row1" /><col class="row1" /><col class="row2" /> <tbody> <!-- BEGIN forums --> - <tr data-down="{forums.U_MOVE_DOWN}" data-up="{forums.U_MOVE_UP}"> - <td style="width: 5%; text-align: center;">{forums.FOLDER_IMAGE}</td> - <td> + <tr> + <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> <!-- IF forums.FORUM_DESCRIPTION --><br /><span>{forums.FORUM_DESCRIPTION}</span><!-- ENDIF --> <!-- IF forums.S_FORUM_POST --><br /><br /><span>{L_TOPICS}{L_COLON} <strong>{forums.FORUM_TOPICS}</strong> / {L_POSTS}{L_COLON} <strong>{forums.FORUM_POSTS}</strong></span><!-- ENDIF --> </td> - <td style="vertical-align: top; width: 100px; text-align: right; white-space: nowrap;"> - <!-- IF forums.S_FIRST_ROW && not forums.S_LAST_ROW --> - <span class="up">{ICON_MOVE_UP_DISABLED}</span> - <span class="down"><a href="{forums.U_MOVE_DOWN}" data-ajax="row_down" data-overlay="false">{ICON_MOVE_DOWN}</a></span> - <!-- ELSEIF not forums.S_FIRST_ROW && not forums.S_LAST_ROW --> - <span class="up"><a href="{forums.U_MOVE_UP}" data-ajax="row_up" data-overlay="false">{ICON_MOVE_UP}</a></span> - <span class="down"><a href="{forums.U_MOVE_DOWN}" data-ajax="row_down" data-overlay="false">{ICON_MOVE_DOWN}</a></span> - <!-- ELSEIF forums.S_LAST_ROW && not forums.S_FIRST_ROW --> - <span class="up"><a href="{forums.U_MOVE_UP}" data-ajax="row_up" data-overlay="false">{ICON_MOVE_UP}</a></span> - <span class="down">{ICON_MOVE_DOWN_DISABLED}</span> - <!-- ELSE --> - <span class="up">{ICON_MOVE_UP_DISABLED}</span> - <span class="down">{ICON_MOVE_DOWN_DISABLED}</span> - <!-- ENDIF --> + <td class="actions"> + <span class="up-disabled" style="display:none;">{ICON_MOVE_UP_DISABLED}</span> + <span class="up"><a href="{forums.U_MOVE_UP}" data-ajax="row_up">{ICON_MOVE_UP}</a></span> + <span class="down-disabled" style="display:none;">{ICON_MOVE_DOWN_DISABLED}</span> + <span class="down"><a href="{forums.U_MOVE_DOWN}" data-ajax="row_down">{ICON_MOVE_DOWN}</a></span> <a href="{forums.U_EDIT}">{ICON_EDIT}</a> <!-- IF not forums.S_FORUM_LINK --> <a href="{forums.U_SYNC}" onclick="popup_progress_bar();">{ICON_SYNC}</a> @@ -501,14 +505,6 @@ </fieldset> </form> - <div class="hidden"> - <a class="template-up-img" href="#">{ICON_MOVE_UP}</a> - <span class="template-up-img-disabled">{ICON_MOVE_UP_DISABLED}</span> - - <a class="template-down-img" href="#">{ICON_MOVE_DOWN}</a> - <span class="template-down-img-disabled">{ICON_MOVE_DOWN_DISABLED}</span> - </div> - <!-- ENDIF --> <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/adm/style/acp_groups.html b/phpBB/adm/style/acp_groups.html index 2953e85bd9..72f4f2b239 100644 --- a/phpBB/adm/style/acp_groups.html +++ b/phpBB/adm/style/acp_groups.html @@ -92,7 +92,12 @@ </dl> <dl> <dt><label for="group_colour">{L_GROUP_COLOR}{L_COLON}</label><br /><span>{L_GROUP_COLOR_EXPLAIN}</span></dt> - <dd><input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="6" maxlength="6" /><!-- IF GROUP_COLOUR --> <span style="background-color: #{GROUP_COLOUR}"> </span><!-- ENDIF --> <span>[ <a href="{U_SWATCH}" onclick="popup(this.href, 636, 150, '_swatch'); return false">{L_COLOUR_SWATCH}</a> ]</span></dd> + <dd> + <input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="6" maxlength="6" /> + <!-- IF GROUP_COLOUR --> <span style="background-color: #{GROUP_COLOUR}"> </span><!-- ENDIF --> <span> + [ <a href="#" id="color_palette_toggle">{L_COLOUR_SWATCH}</a> ]</span> + <div id="color_palette_placeholder" style="display: none;" data-orientation="h" data-height="12" data-width="15" data-target="#group_colour"></div> + </dd> </dl> <dl> <dt><label for="group_rank">{L_GROUP_RANK}{L_COLON}</label></dt> @@ -150,7 +155,7 @@ <a href="{U_DEFAULT_ALL}">» {L_MAKE_DEFAULT_FOR_ALL}</a> </fieldset> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_USERNAME}</th> @@ -165,7 +170,7 @@ <td class="row3" colspan="5"><strong>{L_GROUP_LEAD}</strong></td> </tr> <!-- BEGIN leader --> - <!-- IF leader.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td><!-- IF leader.USERNAME_COLOUR --><a href="{leader.U_USER_EDIT}" style="color: #{leader.USERNAME_COLOUR};" class="username-coloured">{leader.USERNAME}</a><!-- ELSE --><a href="{leader.U_USER_EDIT}">{leader.USERNAME}</a><!-- ENDIF --></td> <td style="text-align: center;"><!-- IF leader.S_GROUP_DEFAULT -->{L_YES}<!-- ELSE -->{L_NO}<!-- ENDIF --></td> <td style="text-align: center;">{leader.JOINED}</td> @@ -174,7 +179,7 @@ </tr> <!-- BEGINELSE --> <tr> - <td class="row1" colspan="5" style="text-align: center;">{L_GROUPS_NO_MODS}</td> + <td colspan="5" style="text-align: center;">{L_GROUPS_NO_MODS}</td> </tr> <!-- END leader --> <tr> @@ -186,7 +191,7 @@ <td class="row3" colspan="5"><strong>{L_GROUP_PENDING}</strong></td> </tr> <!-- ELSE --> - <!-- IF member.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td><!-- IF member.USERNAME_COLOUR --><a href="{member.U_USER_EDIT}" style="color: #{member.USERNAME_COLOUR};" class="username-coloured">{member.USERNAME}</a><!-- ELSE --><a href="{member.U_USER_EDIT}">{member.USERNAME}</a><!-- ENDIF --></td> <td style="text-align: center;"><!-- IF member.S_GROUP_DEFAULT -->{L_YES}<!-- ELSE -->{L_NO}<!-- ENDIF --></td> <td style="text-align: center;">{member.JOINED}</td> @@ -196,7 +201,7 @@ <!-- ENDIF --> <!-- BEGINELSE --> <tr> - <td class="row1" colspan="5" style="text-align: center;">{L_GROUPS_NO_MEMBERS}</td> + <td colspan="5" style="text-align: center;">{L_GROUPS_NO_MEMBERS}</td> </tr> <!-- END member --> </tbody> @@ -261,7 +266,7 @@ <form id="acp_groups" method="post" action="{U_ACTION}"> - <table cellspacing="1"> + <table class="table1"> <col class="col1" /><col class="col1" /><col class="col2" /><col class="col2" /><col class="col2" /> <thead> <tr> @@ -295,7 +300,7 @@ <p>{L_SPECIAL_GROUPS_EXPLAIN}</p> - <table cellspacing="1"> + <table class="table1"> <col class="col1" /><col class="col1" /><col class="col2" /><col class="col2" /><col class="col2" /> <thead> <tr> diff --git a/phpBB/adm/style/acp_groups_position.html b/phpBB/adm/style/acp_groups_position.html index cf1a7be427..c01f7aeb03 100644 --- a/phpBB/adm/style/acp_groups_position.html +++ b/phpBB/adm/style/acp_groups_position.html @@ -27,7 +27,7 @@ <p>{L_LEGEND_EXPLAIN}</p> - <table cellspacing="1"> + <table class="table1"> <col class="col1" /><col class="col2" /><col class="col2" /> <thead> <tr> @@ -38,23 +38,14 @@ </thead> <tbody> <!-- BEGIN legend --> - <tr data-down="{legend.U_MOVE_DOWN}" data-up="{legend.U_MOVE_UP}"> + <tr> <td><strong<!-- IF legend.GROUP_COLOUR --> style="color: {legend.GROUP_COLOUR}"<!-- ENDIF -->>{legend.GROUP_NAME}</strong></td> <td style="text-align: center;">{legend.GROUP_TYPE}</td> - <td style="vertical-align: top; width: 100px; text-align: right; white-space: nowrap;"> - <!-- IF legend.S_FIRST_ROW && not legend.S_LAST_ROW --> - <span class="up">{ICON_MOVE_UP_DISABLED}</span> - <span class="down"><a href="{legend.U_MOVE_DOWN}" data-ajax="row_down" data-overlay="false">{ICON_MOVE_DOWN}</a></span> - <!-- ELSEIF not legend.S_FIRST_ROW && not legend.S_LAST_ROW --> - <span class="up"><a href="{legend.U_MOVE_UP}" data-ajax="row_up" data-overlay="false">{ICON_MOVE_UP}</a></span> - <span class="down"><a href="{legend.U_MOVE_DOWN}" data-ajax="row_down" data-overlay="false">{ICON_MOVE_DOWN}</a></span> - <!-- ELSEIF legend.S_LAST_ROW && not legend.S_FIRST_ROW --> - <span class="up"><a href="{legend.U_MOVE_UP}" data-ajax="row_up" data-overlay="false">{ICON_MOVE_UP}</a></span> - <span class="down">{ICON_MOVE_DOWN_DISABLED}</span> - <!-- ELSE --> - <span class="up">{ICON_MOVE_UP_DISABLED}</span> - <span class="down">{ICON_MOVE_DOWN_DISABLED}</span> - <!-- ENDIF --> + <td class="actions"> + <span class="up-disabled" style="display: none;">{ICON_MOVE_UP_DISABLED}</span> + <span class="up"><a href="{legend.U_MOVE_UP}" data-ajax="row_up">{ICON_MOVE_UP}</a></span> + <span class="down-disabled" style="display:none;">{ICON_MOVE_DOWN_DISABLED}</span> + <span class="down"><a href="{legend.U_MOVE_DOWN}" data-ajax="row_down">{ICON_MOVE_DOWN}</a></span> <a href="{legend.U_DELETE}">{ICON_DELETE}</a> </td> </tr> @@ -115,7 +106,7 @@ <!-- IF S_TEAMPAGE_CATEGORY and CURRENT_CATEGORY_NAME --><p><strong><a href="{U_ACTION}">{L_TEAMPAGE}</a> » {CURRENT_CATEGORY_NAME}</strong></p><!-- ENDIF --> - <table cellspacing="1"> + <table class="table1"> <col class="col1" /><col class="col2" /><col class="col2" /> <thead> <tr> @@ -126,7 +117,7 @@ </thead> <tbody> <!-- BEGIN teampage --> - <tr data-down="{teampage.U_MOVE_DOWN}" data-up="{teampage.U_MOVE_UP}"> + <tr> <td> <!-- IF teampage.U_CATEGORY --> <a href="{teampage.U_CATEGORY}">{teampage.GROUP_NAME}</a> @@ -136,20 +127,11 @@ </td> <td style="text-align: center;"><!-- IF teampage.GROUP_TYPE -->{teampage.GROUP_TYPE}<!-- ELSE -->-<!-- ENDIF --> </td></td> - <td style="vertical-align: top; width: 100px; text-align: right; white-space: nowrap;"> - <!-- IF teampage.S_FIRST_ROW && not teampage.S_LAST_ROW --> - <span class="up">{ICON_MOVE_UP_DISABLED}</span> - <span class="down"><a href="{teampage.U_MOVE_DOWN}" data-ajax="row_down" data-overlay="false">{ICON_MOVE_DOWN}</a></span> - <!-- ELSEIF not teampage.S_FIRST_ROW && not teampage.S_LAST_ROW --> - <span class="up"><a href="{teampage.U_MOVE_UP}" data-ajax="row_up" data-overlay="false">{ICON_MOVE_UP}</a></span> - <span class="down"><a href="{teampage.U_MOVE_DOWN}" data-ajax="row_down" data-overlay="false">{ICON_MOVE_DOWN}</a></span> - <!-- ELSEIF teampage.S_LAST_ROW && not teampage.S_FIRST_ROW --> - <span class="up"><a href="{teampage.U_MOVE_UP}" data-ajax="row_up" data-overlay="false">{ICON_MOVE_UP}</a></span> - <span class="down">{ICON_MOVE_DOWN_DISABLED}</span> - <!-- ELSE --> - <span class="up">{ICON_MOVE_UP_DISABLED}</span> - <span class="down">{ICON_MOVE_DOWN_DISABLED}</span> - <!-- ENDIF --> + <td class="actions"> + <span class="up-disabled" style="display: none;">{ICON_MOVE_UP_DISABLED}</span> + <span class="up"><a href="{teampage.U_MOVE_UP}" data-ajax="row_up">{ICON_MOVE_UP}</a></span> + <span class="down-disabled" style="display:none;">{ICON_MOVE_DOWN_DISABLED}</span> + <span class="down"><a href="{teampage.U_MOVE_DOWN}" data-ajax="row_down">{ICON_MOVE_DOWN}</a></span> <a href="{teampage.U_DELETE}">{ICON_DELETE}</a> </td> </tr> @@ -186,12 +168,4 @@ </fieldset> </form> - <div class="hidden"> - <a class="template-up-img" href="#">{ICON_MOVE_UP}</a> - <span class="template-up-img-disabled">{ICON_MOVE_UP_DISABLED}</span> - - <a class="template-down-img" href="#">{ICON_MOVE_DOWN}</a> - <span class="template-down-img-disabled">{ICON_MOVE_DOWN_DISABLED}</span> - </div> - <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/adm/style/acp_icons.html b/phpBB/adm/style/acp_icons.html index eca02d2798..9117052d87 100644 --- a/phpBB/adm/style/acp_icons.html +++ b/phpBB/adm/style/acp_icons.html @@ -22,7 +22,7 @@ { var use_element = smiley[newimage]; - document.getElementById('add_image_src').src = '{PHPBB_ROOT_PATH}{IMG_PATH}/' + encodeURI(newimage); + document.getElementById('add_image_src').src = '{ROOT_PATH}{IMG_PATH}/' + encodeURI(newimage); document.getElementById('add_code').value = use_element['code']; document.getElementById('add_emotion').value = use_element['emotion']; document.getElementById('add_width').value = use_element['width']; @@ -74,7 +74,7 @@ <fieldset class="tabulated"> <legend>{L_TITLE}</legend> - <table cellspacing="1" id="smilies"> + <table class="table1 zebra-table" id="smilies"> <thead> <tr> <th colspan="{COLSPAN}">{L_CONFIG}</th> @@ -100,7 +100,7 @@ </thead> <tbody> <!-- BEGIN items --> - <!-- IF items.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td style="text-align: center;"><img src="{items.IMG_SRC}" alt="" title="" /><input type="hidden" name="image[{items.IMG}]" value="1" /></td> <td style="vertical-align: top;">[{items.IMG}]</td> @@ -218,7 +218,7 @@ <legend>{L_TITLE}</legend> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_TITLE}</th> @@ -236,16 +236,18 @@ <td class="row3" colspan="{COLSPAN}" style="text-align: center;">{L_NOT_DISPLAYED}</td> </tr> <!-- ENDIF --> - <!-- IF items.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td style="width: 85%; text-align: center;"><img src="{items.IMG_SRC}" width="{items.WIDTH}" height="{items.HEIGHT}" alt="{items.ALT_TEXT}" title="{items.ALT_TEXT}" /></td> <!-- IF S_SMILIES --> <td style="text-align: center;">{items.CODE}</td> <td style="text-align: center;">{items.EMOTION}</td> <!-- ENDIF --> - <td style="text-align: right; white-space: nowrap;"> - <!-- IF items.S_FIRST_ROW and not U_PREVIOUS_PAGE -->{ICON_MOVE_UP_DISABLED}<!-- ELSE --><a href="{items.U_MOVE_UP}">{ICON_MOVE_UP}</a><!-- ENDIF --> - <!-- IF items.S_LAST_ROW and not U_NEXT_PAGE -->{ICON_MOVE_DOWN_DISABLED}<!-- ELSE --><a href="{items.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a><!-- ENDIF --> - <a href="{items.U_EDIT}">{ICON_EDIT}</a> <a href="{items.U_DELETE}" data-ajax="row_delete">{ICON_DELETE}</a> + <td class="actions" style="text-align: right;"> + <span class="up-disabled" style="display:none;">{ICON_MOVE_UP_DISABLED}</span> + <span class="up"><a href="{items.U_MOVE_UP}" data-ajax="row_up">{ICON_MOVE_UP}</a></span> + <span class="down-disabled" style="display:none;">{ICON_MOVE_DOWN_DISABLED}</span> + <span class="down"><a href="{items.U_MOVE_DOWN}" data-ajax="row_down">{ICON_MOVE_DOWN}</a></span> + <a href="{items.U_EDIT}">{ICON_EDIT}</a> <a href="{items.U_DELETE}" data-ajax="row_delete">{ICON_DELETE}</a> </td> </tr> <!-- BEGINELSE --> diff --git a/phpBB/adm/style/acp_inactive.html b/phpBB/adm/style/acp_inactive.html index 68a168a5d6..1cdc1abe6b 100644 --- a/phpBB/adm/style/acp_inactive.html +++ b/phpBB/adm/style/acp_inactive.html @@ -16,7 +16,7 @@ </div> <!-- ENDIF --> -<table cellspacing="1"> +<table class="table1 zebra-table"> <thead> <tr> <th>{L_USERNAME}</th> @@ -29,8 +29,7 @@ </thead> <tbody> <!-- BEGIN inactive --> - <!-- IF inactive.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> - + <tr> <td style="vertical-align: top;"> {inactive.USERNAME_FULL} <!-- IF inactive.POSTS --><br />{L_POSTS}{L_COLON} <strong>{inactive.POSTS}</strong> [<a href="{inactive.U_SEARCH_USER}">{L_SEARCH_USER_POSTS}</a>]<!-- ENDIF --> @@ -53,7 +52,7 @@ </table> <fieldset class="display-options"> - {L_DISPLAY_LOG}{L_COLON} {S_LIMIT_DAYS} {L_SORT_BY}{L_COLON} {S_SORT_KEY} {S_SORT_DIR}<!-- IF .pagination --> Users per page{L_COLON} <input class="inputbox autowidth" type="number" name="users_per_page" id="users_per_page" size="3" value="{USERS_PER_PAGE}" /><!-- ENDIF --> + {L_DISPLAY_LOG}{L_COLON} {S_LIMIT_DAYS} {L_SORT_BY}{L_COLON} {S_SORT_KEY} {S_SORT_DIR}<!-- IF .pagination --> {L_USERS_PER_PAGE}{L_COLON} <input class="inputbox autowidth" type="number" name="users_per_page" id="users_per_page" size="3" value="{USERS_PER_PAGE}" /><!-- ENDIF --> <input class="button2" type="submit" value="{L_GO}" name="sort" /> </fieldset> diff --git a/phpBB/adm/style/acp_language.html b/phpBB/adm/style/acp_language.html index c400437049..d32f6b7eac 100644 --- a/phpBB/adm/style/acp_language.html +++ b/phpBB/adm/style/acp_language.html @@ -75,7 +75,7 @@ <form id="missing" method="post" action="{U_MISSING_ACTION}"> - <table cellspacing="1"> + <table class="table1"> <thead> <tr> <th>{L_LANGUAGE_KEY}</th> @@ -129,7 +129,7 @@ </style> <![endif]--> - <table cellspacing="1"> + <table class="table1"> <thead> <!-- IF S_EMAIL_FILE --> <tr> @@ -147,7 +147,7 @@ </tr> <tr> <td class="row3" style="text-align: right;"> - <!-- IF ALLOW_UPLOAD --> {L_UPLOAD_METHOD}{L_COLON} <!-- BEGIN buttons--><input type="radio" class="radio"<!-- IF buttons.S_FIRST_ROW --> id="method" checked="checked"<!-- ENDIF --> value="{buttons.VALUE}" name="method" /> {buttons.VALUE} <!-- END buttons --><input type="submit" name="upload_file" class="button2" value="{L_SUBMIT_AND_UPLOAD}" /><!-- ENDIF --></td> + <!-- IF ALLOW_UPLOAD --> {L_UPLOAD_METHOD}{L_COLON} <!-- BEGIN buttons --><input type="radio" class="radio"<!-- IF buttons.S_FIRST_ROW --> id="method" checked="checked"<!-- ENDIF --> value="{buttons.VALUE}" name="method" /> {buttons.VALUE} <!-- END buttons --><input type="submit" name="upload_file" class="button2" value="{L_SUBMIT_AND_UPLOAD}" /><!-- ENDIF --></td> </tr> </thead> <tbody> @@ -211,7 +211,7 @@ <p>{L_ACP_LANGUAGE_PACKS_EXPLAIN}</p> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_LANGUAGE_PACK_NAME}</th> @@ -226,7 +226,7 @@ <td class="row3" colspan="5"><strong>{L_INSTALLED_LANGUAGE_PACKS}</strong></td> </tr> <!-- BEGIN lang --> - <!-- IF lang.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td><a href="{lang.U_DETAILS}">{lang.ENGLISH_NAME}</a> {lang.TAG}</td> <td>{lang.LOCAL_NAME}</td> <td style="text-align: center;"><strong>{lang.ISO}</strong></td> @@ -240,7 +240,7 @@ </tr> <!-- ENDIF --> <!-- BEGIN notinst --> - <!-- IF notinst.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td>{notinst.NAME}</td> <td>{notinst.LOCAL_NAME}</td> <td style="text-align: center;"><strong>{notinst.ISO}</strong></td> diff --git a/phpBB/adm/style/acp_logs.html b/phpBB/adm/style/acp_logs.html index e13196f65d..9343b9b509 100644 --- a/phpBB/adm/style/acp_logs.html +++ b/phpBB/adm/style/acp_logs.html @@ -13,7 +13,7 @@ </fieldset> <!-- IF .pagination --> -<div class="pagination" style="float: right; margin: 15px 0 2px 0"> +<div class="pagination top-pagination"> <!-- INCLUDE pagination.html --> </div> <!-- ENDIF --> @@ -22,7 +22,7 @@ <div><br style="clear: both;" /></div> <!-- IF .log --> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_USERNAME}</th> @@ -36,7 +36,7 @@ </thead> <tbody> <!-- BEGIN log --> - <!-- IF log.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td> {log.USERNAME} <!-- IF log.REPORTEE_USERNAME --> diff --git a/phpBB/adm/style/acp_main.html b/phpBB/adm/style/acp_main.html index b644862ce1..9a9b3ff2b9 100644 --- a/phpBB/adm/style/acp_main.html +++ b/phpBB/adm/style/acp_main.html @@ -17,6 +17,7 @@ <!-- IF S_VERSIONCHECK_FAIL --> <div class="errorbox notice"> <p>{L_VERSIONCHECK_FAIL}</p> + <p>{VERSIONCHECK_FAIL_REASON}</p> <p><a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a> · <a href="{U_VERSIONCHECK}">{L_MORE_INFORMATION}</a></p> </div> <!-- ELSEIF not S_VERSION_UP_TO_DATE --> @@ -26,6 +27,12 @@ </div> <!-- ENDIF --> + <!-- IF S_SEARCH_INDEX_MISSING --> + <div class="errorbox"> + <h3>{L_WARNING}</h3> + <p>{L_NO_SEARCH_INDEX}</p> + </div> + <!-- ENDIF --> <!-- IF S_REMOVE_INSTALL --> <div class="errorbox"> @@ -78,7 +85,7 @@ <!-- EVENT acp_main_notice_after --> - <table cellspacing="1"> + <table class="table1 two-columns no-header" data-no-responsive-header="true"> <caption>{L_FORUM_STATS}</caption> <col class="col1" /><col class="col2" /><col class="col1" /><col class="col2" /> <thead> @@ -168,21 +175,21 @@ </dl> </form> - <form id="action_stats_form" method="post" action="{U_ACTION}" data-ajax="true"> + <form id="action_stats_form" method="post" action="{U_ACTION}"> <dl> <dt><label for="action_stats">{L_RESYNC_STATS}</label><br /><span>{L_RESYNC_STATS_EXPLAIN}</span></dt> <dd><input type="hidden" name="action" value="stats" /><input class="button2" type="submit" id="action_stats" name="action_stats" value="{L_RUN}" /></dd> </dl> </form> - <form id="action_user_form" method="post" action="{U_ACTION}" data-ajax="true"> + <form id="action_user_form" method="post" action="{U_ACTION}"> <dl> <dt><label for="action_user">{L_RESYNC_POSTCOUNTS}</label><br /><span>{L_RESYNC_POSTCOUNTS_EXPLAIN}</span></dt> <dd><input type="hidden" name="action" value="user" /><input class="button2" type="submit" id="action_user" name="action_user" value="{L_RUN}" /></dd> </dl> </form> - <form id="action_db_track_form" method="post" action="{U_ACTION}" data-ajax="true"> + <form id="action_db_track_form" method="post" action="{U_ACTION}"> <dl> <dt><label for="action_db_track">{L_RESYNC_POST_MARKING}</label><br /><span>{L_RESYNC_POST_MARKING_EXPLAIN}</span></dt> <dd><input type="hidden" name="action" value="db_track" /><input class="button2" type="submit" id="action_db_track" name="action_db_track" value="{L_RUN}" /></dd> @@ -216,7 +223,7 @@ <div style="text-align: right;"><a href="{U_ADMIN_LOG}">» {L_VIEW_ADMIN_LOG}</a></div> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_USERNAME}</th> @@ -227,8 +234,7 @@ </thead> <tbody> <!-- BEGIN log --> - <!-- IF log.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> - + <tr> <td>{log.USERNAME}</td> <td style="text-align: center;">{log.IP}</td> <td style="text-align: center;">{log.DATE}</td> @@ -249,7 +255,7 @@ <div style="text-align: right;"><a href="{U_INACTIVE_USERS}">» {L_VIEW_INACTIVE_USERS}</a></div> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_USERNAME}</th> @@ -261,8 +267,7 @@ </thead> <tbody> <!-- BEGIN inactive --> - <!-- IF inactive.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> - + <tr> <td style="vertical-align: top;"> {inactive.USERNAME_FULL} <!-- IF inactive.POSTS --><br />{L_POSTS}{L_COLON} <strong>{inactive.POSTS}</strong> [<a href="{inactive.U_SEARCH_USER}">{L_SEARCH_USER_POSTS}</a>]<!-- ENDIF --> diff --git a/phpBB/adm/style/acp_modules.html b/phpBB/adm/style/acp_modules.html index 1e49198725..3c97706e6a 100644 --- a/phpBB/adm/style/acp_modules.html +++ b/phpBB/adm/style/acp_modules.html @@ -10,11 +10,11 @@ { if (value == 'category') { - dE('modoptions', -1); + phpbb.toggleDisplay('modoptions', -1); } else { - dE('modoptions', 1); + phpbb.toggleDisplay('modoptions', 1); } } @@ -132,7 +132,7 @@ </div> <!-- ENDIF --> - <table cellspacing="1"> + <table class="table1"> <tbody> <tr> <td class="row3">{NAVIGATION}<!-- IF S_NO_MODULES --> [<a href="{U_EDIT}">{L_EDIT}</a> | <a href="{U_DELETE}">{L_DELETE}</a> | <!-- IF MODULE_ENABLED --><a href="{U_DISABLE}">{L_DISABLE}</a><!-- ELSE --><a href="{U_ENABLE}">{L_ENABLE}</a><!-- ENDIF -->]<!-- ENDIF --></td> @@ -141,7 +141,7 @@ </table> <!-- IF .modules --> - <table cellspacing="1"> + <table class="table1"> <col class="row1" /><col class="row1" /><col class="row2" /><col class="row2" /> <tbody> <!-- BEGIN modules --> @@ -149,20 +149,11 @@ <td style="width: 5%; text-align: center;">{modules.MODULE_IMAGE}</td> <td><a href="{modules.U_MODULE}">{modules.MODULE_TITLE}</a><!-- IF not modules.MODULE_DISPLAYED --> <span class="small">[{L_HIDDEN_MODULE}]</span><!-- ENDIF --></td> <td style="width: 15%; white-space: nowrap; text-align: center; vertical-align: middle;"> <!-- IF modules.MODULE_ENABLED --><a href="{modules.U_DISABLE}">{L_DISABLE}</a><!-- ELSE --><a href="{modules.U_ENABLE}">{L_ENABLE}</a><!-- ENDIF --> </td> - <td style="width:90px; white-space: nowrap; text-align: right; vertical-align: middle;"> - <!-- IF modules.S_FIRST_ROW && not modules.S_LAST_ROW --> - {ICON_MOVE_UP_DISABLED} - <a href="{modules.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a> - <!-- ELSEIF not modules.S_FIRST_ROW && not modules.S_LAST_ROW--> - <a href="{modules.U_MOVE_UP}">{ICON_MOVE_UP}</a> - <a href="{modules.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a> - <!-- ELSEIF modules.S_LAST_ROW && not modules.S_FIRST_ROW --> - <a href="{modules.U_MOVE_UP}">{ICON_MOVE_UP}</a> - {ICON_MOVE_DOWN_DISABLED} - <!-- ELSE --> - {ICON_MOVE_UP_DISABLED} - {ICON_MOVE_DOWN_DISABLED} - <!-- ENDIF --> + <td class="actions"> + <span class="up-disabled" style="display:none;">{ICON_MOVE_UP_DISABLED}</span> + <span class="up"><a href="{modules.U_MOVE_UP}" data-ajax="row_up">{ICON_MOVE_UP}</a></span> + <span class="down-disabled" style="display:none;">{ICON_MOVE_DOWN_DISABLED}</span> + <span class="down"><a href="{modules.U_MOVE_DOWN}" data-ajax="row_down">{ICON_MOVE_DOWN}</a></span> <a href="{modules.U_EDIT}">{ICON_EDIT}</a> <a href="{modules.U_DELETE}" data-ajax="row_delete">{ICON_DELETE}</a> </td> diff --git a/phpBB/adm/style/acp_permission_roles.html b/phpBB/adm/style/acp_permission_roles.html index d654c320ca..b3137f134c 100644 --- a/phpBB/adm/style/acp_permission_roles.html +++ b/phpBB/adm/style/acp_permission_roles.html @@ -90,9 +90,8 @@ </div> <!-- BEGIN auth --> <div class="permissions-panel" id="options00{auth.S_ROW_COUNT}"<!-- IF auth.S_FIRST_ROW --><!-- ELSE --> style="display: none;"<!-- ENDIF -->> - <span class="corners-top"><span></span></span> <div class="tablewrap"> - <table id="table00{auth.S_ROW_COUNT}" cellspacing="1"> + <table id="table00{auth.S_ROW_COUNT}" class="table1 not-responsive"> <colgroup> <col class="permissions-name" /> <col class="permissions-yes" /> @@ -120,7 +119,6 @@ </tbody> </table> </div> - <span class="corners-bottom"><span></span></span> </div> <!-- END auth --> </div> @@ -144,7 +142,7 @@ <form id="acp_roles" method="post" action="{U_ACTION}"> - <table cellspacing="1"> + <table class="table1"> <col class="col2" /><col class="col2" /><col class="col1" /><col class="col2" /><col class="col2" /> <thead> <tr> @@ -159,20 +157,11 @@ <!-- IF roles.ROLE_DESCRIPTION --><br /><span>{roles.ROLE_DESCRIPTION}</span><!-- ENDIF --> </td> <td style="width: 30%; text-align: center; vertical-align: top; white-space: nowrap;"><!-- IF roles.U_DISPLAY_ITEMS --><a href="{roles.U_DISPLAY_ITEMS}">{L_VIEW_ASSIGNED_ITEMS}</a><!-- ELSE -->{L_VIEW_ASSIGNED_ITEMS}<!-- ENDIF --></td> - <td style="width: 80px; text-align: right; vertical-align: top; white-space: nowrap;"> - <!-- IF roles.S_FIRST_ROW && not roles.S_LAST_ROW --> - {ICON_MOVE_UP_DISABLED} - <a href="{roles.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a> - <!-- ELSEIF not roles.S_FIRST_ROW && not roles.S_LAST_ROW--> - <a href="{roles.U_MOVE_UP}">{ICON_MOVE_UP}</a> - <a href="{roles.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a> - <!-- ELSEIF roles.S_LAST_ROW && not roles.S_FIRST_ROW --> - <a href="{roles.U_MOVE_UP}">{ICON_MOVE_UP}</a> - {ICON_MOVE_DOWN_DISABLED} - <!-- ELSE --> - {ICON_MOVE_UP_DISABLED} - {ICON_MOVE_DOWN_DISABLED} - <!-- ENDIF --> + <td class="actions"> + <span class="up-disabled" style="display:none;">{ICON_MOVE_UP_DISABLED}</span> + <span class="up"><a href="{roles.U_MOVE_UP}" data-ajax="row_up">{ICON_MOVE_UP}</a></span> + <span class="down-disabled" style="display:none;">{ICON_MOVE_DOWN_DISABLED}</span> + <span class="down"><a href="{roles.U_MOVE_DOWN}" data-ajax="row_down">{ICON_MOVE_DOWN}</a></span> <a href="{roles.U_EDIT}" title="{L_EDIT_ROLE}">{ICON_EDIT}</a> <a href="{roles.U_REMOVE}" title="{L_REMOVE_ROLE}" data-ajax="row_delete">{ICON_DELETE}</a> </td> diff --git a/phpBB/adm/style/acp_permissions.html b/phpBB/adm/style/acp_permissions.html index 88a82532a1..6dc9dca2e7 100644 --- a/phpBB/adm/style/acp_permissions.html +++ b/phpBB/adm/style/acp_permissions.html @@ -110,7 +110,7 @@ <!-- ELSEIF S_SELECT_USERGROUP --> - <div style="float: {S_CONTENT_FLOW_BEGIN}; width: 48%;"> + <div class="column1"> <!-- IF S_CAN_SELECT_USER --> @@ -155,7 +155,7 @@ </div> - <div style="float: {S_CONTENT_FLOW_END}; width: 48%"> + <div class="column2"> <!-- IF S_CAN_SELECT_GROUP --> @@ -200,7 +200,7 @@ <!-- ELSEIF S_SELECT_USERGROUP_VIEW --> - <div style="float: {S_CONTENT_FLOW_BEGIN}; width: 48%;"> + <div class="column1"> <h1>{L_USERS}</h1> @@ -241,7 +241,7 @@ </div> - <div style="float: {S_CONTENT_FLOW_END}; width: 48%"> + <div class="column2"> <h1>{L_USERGROUPS}</h1> @@ -324,7 +324,7 @@ </form> <!-- ENDIF --> - <br /><br /> + <br class="responsive-hide" /><br class="responsive-hide" /> <!-- include tooltip file --> <script type="text/javascript" src="style/tooltip.js"></script> @@ -340,7 +340,7 @@ <!-- INCLUDE permission_mask.html --> - <br /><br /> + <br class="responsive-hide" /><br class="responsive-hide" /> <fieldset class="quick" style="float: {S_CONTENT_FLOW_END};"> <input class="button1" type="submit" name="action[apply_all_permissions]" value="{L_APPLY_ALL_PERMISSIONS}" /> @@ -348,7 +348,7 @@ {S_FORM_TOKEN} </fieldset> - <br /><br /> + <br class="responsive-hide" /><br class="responsive-hide" /> </form> diff --git a/phpBB/adm/style/acp_profile.html b/phpBB/adm/style/acp_profile.html index 13be669f70..64bc3df09b 100644 --- a/phpBB/adm/style/acp_profile.html +++ b/phpBB/adm/style/acp_profile.html @@ -64,6 +64,10 @@ <dd><input type="checkbox" class="radio" id="field_show_on_vt" name="field_show_on_vt" value="1"<!-- IF S_SHOW_ON_VT --> checked="checked"<!-- ENDIF --> /></dd> </dl> <dl> + <dt><label for="field_show_on_ml">{L_DISPLAY_ON_MEMBERLIST}{L_COLON}</label><br /><span>{L_DISPLAY_ON_MEMBERLIST_EXPLAIN}</span></dt> + <dd><input type="checkbox" class="radio" id="field_show_on_ml" name="field_show_on_ml" value="1"<!-- IF S_SHOW_ON_MEMBERLIST --> checked="checked"<!-- ENDIF --> /></dd> + </dl> + <dl> <dt><label for="field_required">{L_REQUIRED_FIELD}{L_COLON}</label><br /><span>{L_REQUIRED_FIELD_EXPLAIN}</span></dt> <dd><input type="checkbox" class="radio" id="field_required" name="field_required" value="1"<!-- IF S_FIELD_REQUIRED --> checked="checked"<!-- ENDIF --> /></dd> </dl> @@ -75,6 +79,12 @@ <dt><label for="field_hide">{L_HIDE_PROFILE_FIELD}{L_COLON}</label><br /><span>{L_HIDE_PROFILE_FIELD_EXPLAIN}</span></dt> <dd><input type="checkbox" class="radio" id="field_hide" name="field_hide" value="1"<!-- IF S_FIELD_HIDE --> checked="checked"<!-- ENDIF --> /></dd> </dl> + <dl> + <dt><label for="field_is_contact">{L_FIELD_IS_CONTACT}{L_COLON}</label><br /><span>{L_FIELD_IS_CONTACT_EXPLAIN}</span></dt> + <dd><input type="checkbox" class="radio" id="field_is_contact" name="field_is_contact" value="1"<!-- IF S_FIELD_CONTACT --> checked="checked"<!-- ENDIF --> /></dd> + <dd><input class="text medium" type="text" name="field_contact_desc" id="field_contact_desc" value="{FIELD_CONTACT_DESC}" /> <label for="field_contact_desc">{L_FIELD_CONTACT_DESC}</label></dd> + <dd><input class="text medium" type="text" name="field_contact_url" id="field_contact_url" value="{FIELD_CONTACT_URL}" /> <label for="field_contact_url">{L_FIELD_CONTACT_URL}</label></dd> + </dl> </fieldset> <!-- IF S_EDIT_MODE --> @@ -185,7 +195,7 @@ </div> <!-- ENDIF --> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_FIELD_IDENT}</th> @@ -195,23 +205,16 @@ </thead> <tbody> <!-- BEGIN fields --> - <!-- IF fields.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> - + <tr> <td>{fields.FIELD_IDENT}</td> <td>{fields.FIELD_TYPE}</td> <td style="text-align: center;"><a href="{fields.U_ACTIVATE_DEACTIVATE}" data-ajax="activate_deactivate">{fields.L_ACTIVATE_DEACTIVATE}</a><!-- IF fields.S_NEED_EDIT --> | <a href="{fields.U_TRANSLATE}" style="color: red;">{L_TRANSLATE}</a><!-- ENDIF --></td> - <td style="width: 80px; text-align: right; white-space: nowrap;"> - <!-- IF fields.S_FIRST_ROW && not fields.S_LAST_ROW --> - {ICON_MOVE_UP_DISABLED} - <a href="{fields.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a> - <!-- ELSEIF not fields.S_FIRST_ROW && not fields.S_LAST_ROW--> - <a href="{fields.U_MOVE_UP}">{ICON_MOVE_UP}</a> - <a href="{fields.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a> - <!-- ELSEIF fields.S_LAST_ROW && not fields.S_FIRST_ROW --> - <a href="{fields.U_MOVE_UP}">{ICON_MOVE_UP}</a> - {ICON_MOVE_DOWN_DISABLED} - <!-- ENDIF --> + <td class="actions" style="width: 80px;"> + <span class="up-disabled" style="display:none;">{ICON_MOVE_UP_DISABLED}</span> + <span class="up"><a href="{fields.U_MOVE_UP}" data-ajax="row_up">{ICON_MOVE_UP}</a></span> + <span class="down-disabled" style="display:none;">{ICON_MOVE_DOWN_DISABLED}</span> + <span class="down"><a href="{fields.U_MOVE_DOWN}" data-ajax="row_down">{ICON_MOVE_DOWN}</a></span> <!-- IF not fields.S_NEED_EDIT --> <a href="{fields.U_EDIT}">{ICON_EDIT}</a> <!-- ELSE --> diff --git a/phpBB/adm/style/acp_prune_forums.html b/phpBB/adm/style/acp_prune_forums.html index 67cdaa784a..4d748f1cce 100644 --- a/phpBB/adm/style/acp_prune_forums.html +++ b/phpBB/adm/style/acp_prune_forums.html @@ -8,7 +8,7 @@ <p>{L_PRUNE_SUCCESS}</p> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_FORUM}</th> @@ -18,7 +18,7 @@ </thead> <tbody> <!-- BEGIN pruned --> - <!-- IF pruned.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td style="text-align: center;">{pruned.FORUM_NAME}</td> <td style="text-align: center;">{pruned.NUM_TOPICS}</td> <td style="text-align: center;">{pruned.NUM_POSTS}</td> diff --git a/phpBB/adm/style/acp_prune_users.html b/phpBB/adm/style/acp_prune_users.html index 1257f3fb3d..b8c271355b 100644 --- a/phpBB/adm/style/acp_prune_users.html +++ b/phpBB/adm/style/acp_prune_users.html @@ -19,11 +19,7 @@ <dd><input type="text" id="email" name="email" /></dd> </dl> <dl> - <dt><label for="email">{L_WEBSITE}{L_COLON}</label></dt> - <dd><input type="text" id="website" name="website" /></dd> -</dl> -<dl> - <dt><label for="joined">{L_JOINED}{L_COLON}</label><br /><span>{L_JOINED_EXPLAIN}</span></dt> + <dt><label for="joined_after">{L_JOINED}{L_COLON}</label><br /><span>{L_JOINED_EXPLAIN}</span></dt> <dd> <strong>{L_AFTER}</strong> <input type="text" id="joined_after" name="joined_after" /> <br /> <br /> <strong>{L_BEFORE}</strong> <input type="text" id="joined_before" name="joined_before" /> @@ -39,12 +35,12 @@ </dl> <dl> <dt><label for="posts_on_queue">{L_POSTS_ON_QUEUE}{L_COLON}</label></dt> - <dd><select name="queue_select">{S_COUNT_OPTIONS}</select> <input type="number" id="posts_on_queue" name="posts_on_queue" /></select> + <dd><select name="queue_select">{S_COUNT_OPTIONS}</select> <input type="number" id="posts_on_queue" name="posts_on_queue" /></dd> </dl> <!-- IF S_GROUP_LIST --> <dl> - <dt><label for="group_id">{L_GROUP}{L_COLON}</label><br /><span>{L_PRUNE_USERS_GROUP_EXPLAIN}</dt> - <dd><select name="group_id">{S_GROUP_LIST}</select></dd> + <dt><label for="group_id">{L_GROUP}{L_COLON}</label><br /><span>{L_PRUNE_USERS_GROUP_EXPLAIN}</span></dt> + <dd><select id="group_id" name="group_id">{S_GROUP_LIST}</select></dd> </dl> <!-- ENDIF --> </fieldset> diff --git a/phpBB/adm/style/acp_ranks.html b/phpBB/adm/style/acp_ranks.html index 4b2e52536f..dd2d07a837 100644 --- a/phpBB/adm/style/acp_ranks.html +++ b/phpBB/adm/style/acp_ranks.html @@ -35,8 +35,8 @@ </dl> <dl> <dt><label for="special_rank">{L_RANK_SPECIAL}{L_COLON}</label></dt> - <dd><label><input onclick="dE('posts', -1)" type="radio" class="radio" name="special_rank" value="1" id="special_rank"<!-- IF S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> /> {L_YES}</label> - <label><input onclick="dE('posts', 1)" type="radio" class="radio" name="special_rank" value="0"<!-- IF not S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> + <dd><label><input onclick="phpbb.toggleDisplay('posts', -1)" type="radio" class="radio" name="special_rank" value="1" id="special_rank"<!-- IF S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> /> {L_YES}</label> + <label><input onclick="phpbb.toggleDisplay('posts', 1)" type="radio" class="radio" name="special_rank" value="0"<!-- IF not S_SPECIAL_RANK --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> </dl> <!-- IF S_SPECIAL_RANK --><div id="posts" style="display: none;"><!-- ELSE --><div id="posts"><!-- ENDIF --> <dl> @@ -65,7 +65,7 @@ <fieldset class="tabulated"> <legend>{L_ACP_MANAGE_RANKS}</legend> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_RANK_IMAGE}</th> @@ -76,7 +76,7 @@ </thead> <tbody> <!-- BEGIN ranks --> - <!-- IF ranks.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td style="text-align: center;"><!-- IF ranks.S_RANK_IMAGE --><img src="{ranks.RANK_IMAGE}" alt="{ranks.RANK_TITLE}" title="{ranks.RANK_TITLE}" /><!-- ELSE --> - <!-- ENDIF --></td> <td style="text-align: center;">{ranks.RANK_TITLE}</td> <td style="text-align: center;"><!-- IF ranks.S_SPECIAL_RANK --> - <!-- ELSE -->{ranks.MIN_POSTS}<!-- ENDIF --></td> diff --git a/phpBB/adm/style/acp_reasons.html b/phpBB/adm/style/acp_reasons.html index 2f39f64614..d629a9553f 100644 --- a/phpBB/adm/style/acp_reasons.html +++ b/phpBB/adm/style/acp_reasons.html @@ -68,7 +68,7 @@ <legend>{L_ACP_REASONS}</legend> <!-- IF .reasons --> - <table cellspacing="1"> + <table class="table1"> <col class="row1" /><col class="row1" /><col class="row2" /> <thead> <tr> @@ -86,17 +86,11 @@ <br /><span>{reasons.REASON_DESCRIPTION}</span> </td> <td style="width: 100px;">{reasons.REASON_COUNT}</td> - <td style="width: 80px; text-align: right; white-space: nowrap;"> - <!-- IF reasons.S_FIRST_ROW && not reasons.S_LAST_ROW --> - {ICON_MOVE_UP_DISABLED} - <a href="{reasons.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a> - <!-- ELSEIF not reasons.S_FIRST_ROW && not reasons.S_LAST_ROW--> - <a href="{reasons.U_MOVE_UP}">{ICON_MOVE_UP}</a> - <a href="{reasons.U_MOVE_DOWN}">{ICON_MOVE_DOWN}</a> - <!-- ELSEIF reasons.S_LAST_ROW && not reasons.S_FIRST_ROW --> - <a href="{reasons.U_MOVE_UP}">{ICON_MOVE_UP}</a> - {ICON_MOVE_DOWN_DISABLED} - <!-- ENDIF --> + <td class="actions" style="width: 80px;"> + <span class="up-disabled" style="display:none;">{ICON_MOVE_UP_DISABLED}</span> + <span class="up"><a href="{reasons.U_MOVE_UP}" data-ajax="row_up">{ICON_MOVE_UP}</a></span> + <span class="down-disabled" style="display:none;">{ICON_MOVE_DOWN_DISABLED}</span> + <span class="down"><a href="{reasons.U_MOVE_DOWN}" data-ajax="row_down">{ICON_MOVE_DOWN}</a></span> <a href="{reasons.U_EDIT}">{ICON_EDIT}</a> <!-- IF reasons.U_DELETE --> <a href="{reasons.U_DELETE}" data-ajax="row_delete">{ICON_DELETE}</a> diff --git a/phpBB/adm/style/acp_search.html b/phpBB/adm/style/acp_search.html index bf353d62f2..496a8b2675 100644 --- a/phpBB/adm/style/acp_search.html +++ b/phpBB/adm/style/acp_search.html @@ -112,7 +112,7 @@ <legend>{L_INDEX_STATS}{L_COLON} {backend.L_NAME} <!-- IF backend.S_ACTIVE -->({L_ACTIVE}) <!-- ENDIF --></legend> - <table cellspacing="1"> + <table class="table1"> <caption>{backend.L_NAME} <!-- IF backend.S_ACTIVE -->({L_ACTIVE}) <!-- ENDIF --></caption> <col class="col1" /><col class="col2" /><col class="col1" /><col class="col2" /> <thead> diff --git a/phpBB/adm/style/acp_send_statistics.html b/phpBB/adm/style/acp_send_statistics.html index 2d6c4837fd..480e438e1f 100644 --- a/phpBB/adm/style/acp_send_statistics.html +++ b/phpBB/adm/style/acp_send_statistics.html @@ -17,8 +17,8 @@ function iframe_updated() return; } - dE('questionnaire-form', -1); - dE('questionnaire-thanks', 1); + phpbb.toggleDisplay('questionnaire-form', -1); + phpbb.toggleDisplay('questionnaire-thanks', 1); } //]]> </script> @@ -31,10 +31,10 @@ function iframe_updated() <p>{L_EXPLAIN_SHOW_STATISTICS}</p> - <p id="show-button"><input type="button" class="button2" onclick="dE('configlist', 1); dE('show-button', -1);" value="{L_SHOW_STATISTICS}" /></p> + <p id="show-button"><input type="button" class="button2" onclick="phpbb.toggleDisplay('configlist', 1); phpbb.toggleDisplay('show-button', -1);" value="{L_SHOW_STATISTICS}" /></p> <div id="configlist"> - <input type="button" class="button2" onclick="dE('show-button', 1); dE('configlist', -1);" value="{L_HIDE_STATISTICS}" /> + <input type="button" class="button2" onclick="phpbb.toggleDisplay('show-button', 1); phpbb.toggleDisplay('configlist', -1);" value="{L_HIDE_STATISTICS}" /> <p class="submit-buttons"> <input class="button1" type="submit" id="submit" name="submit" value="{L_SEND_STATISTICS}" /> </p> @@ -61,11 +61,4 @@ function iframe_updated() <p><strong>{L_THANKS_SEND_STATISTICS}</strong><br /><br /><a href="{U_ACP_MAIN}">« {L_GO_ACP_MAIN}</a></p> </div> -<script type="text/javascript"> -//<![CDATA[ - dE('configlist', -1); - dE('questionnaire-thanks', -1); -//]]> -</script> - <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html index 3dc4c2d616..86e666c4ed 100644 --- a/phpBB/adm/style/acp_styles.html +++ b/phpBB/adm/style/acp_styles.html @@ -2,6 +2,10 @@ <a id="maincontent"></a> +<!-- IF S_STYLE_DETAILS --> + <a href="{U_ACTION}" style="float: {S_CONTENT_FLOW_END};">« {L_BACK}</a> +<!-- ENDIF --> + <!-- IF S_CONFIRM_ACTION --> <form id="confirm" method="post" action="{S_CONFIRM_ACTION}"> @@ -20,7 +24,7 @@ </div> </fieldset> - + </form> <!-- ELSE --> @@ -40,7 +44,7 @@ <dd><input type="text" id="name" name="style_name" value="{STYLE_NAME}" /></dd> </dl> <dl> - <dt><label>{L_STYLE_PATH}</label></dt> + <dt><label>{L_STYLE_PATH}{L_COLON}</label></dt> <dd><strong>{STYLE_PATH}</strong></dd> </dl> <dl> @@ -72,14 +76,14 @@ <fieldset class="submit-buttons"> <legend>{L_SUBMIT}</legend> - <input class="button1" type="submit" name="update" value="{L_SUBMIT}" /> - <a href="{U_ACTION}" class="button2">{L_BACK}</a> + <input class="button1" type="submit" name="update" value="{L_SUBMIT}" /> + <input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" /> {S_FORM_TOKEN} </fieldset> <!-- ENDIF --> <!-- IF .styles_list --> - <table cellspacing="1"> + <table class="table1 styles"> <thead> <tr> <th>{L_STYLE_NAME}</th> @@ -97,9 +101,9 @@ <!-- ELSE --> <!-- IF $ROW_CLASS == 'row2a' --><!-- DEFINE $ROW_CLASS = 'row2b' --><!-- ELSE --><!-- DEFINE $ROW_CLASS = 'row2a' --><!-- ENDIF --> <!-- ENDIF --> - <td class="{$ROW_CLASS}" style="padding-left: {styles_list.PADDING}px;"> + <td class="{$ROW_CLASS}" style="padding-{S_CONTENT_FLOW_BEGIN}: {styles_list.PADDING}px;"> <!-- IF styles_list.STYLE_ID and styles_list.COMMENT == '' and styles_list.STYLE_ACTIVE --> - <div class="default-style" style="display: none; float: right;"> + <div class="default-style" style="display: none; float: {S_CONTENT_FLOW_END};"> <input class="radio" type="radio" name="default" value="{styles_list.STYLE_ID}"<!-- IF styles_list.DEFAULT --> checked="checked"<!-- ELSE --><!-- DEFINE $S_DEFAULT = 1 --><!-- ENDIF --> title="{L_STYLE_DEFAULT}" /> </div> <!-- ENDIF --> @@ -113,13 +117,13 @@ <span class="error"><br />{styles_list.COMMENT}</span> <!-- ENDIF --> <!-- IF not styles_list.STYLE_ID and styles_list.COMMENT == '' --> - <span class="style-path"><br />{L_STYLE_PATH} {styles_list.STYLE_PATH_FULL}</span> + <span class="style-path"><br />{L_STYLE_PATH}{L_COLON} {styles_list.STYLE_PATH_FULL}</span> <!-- ENDIF --> </td> <!-- IF not STYLES_LIST_HIDE_COUNT --> - <td class="{$ROW_CLASS}" style="text-align: center;">{styles_list.USERS}</td> + <td class="{$ROW_CLASS} users">{styles_list.USERS}</td> <!-- ENDIF --> - <td class="{$ROW_CLASS}" style="text-align: center;"> + <td class="{$ROW_CLASS} actions"> <!-- BEGIN actions --> <!-- IF styles_list.actions.S_ROW_COUNT > 0 --> | <!-- ENDIF --> <!-- IF styles_list.actions.U_ACTION --> @@ -129,7 +133,7 @@ <!-- END actions --> </td> {styles_list.EXTRA} - <td class="{$ROW_CLASS}" width="20" style="text-align: center;"> + <td class="{$ROW_CLASS} mark" width="20"> <!-- IF styles_list.STYLE_ID --> <input class="checkbox" type="checkbox" name="ids[]" value="{styles_list.STYLE_ID}" /> <!-- ELSE --> @@ -154,14 +158,6 @@ </fieldset> <!-- ENDIF --> -<!-- IF .extra_links --> - <fieldset class="quick"> - <!-- BEGIN extra_links --> - <a class="button2" href="{extra_links.U_ACTION}">{extra_links.L_ACTION}</a> - <!-- END extra_links --> - </fieldset> -<!-- ENDIF --> - </form> <!-- ENDIF --> diff --git a/phpBB/adm/style/acp_update.html b/phpBB/adm/style/acp_update.html index 00d37515b3..0cc995959b 100644 --- a/phpBB/adm/style/acp_update.html +++ b/phpBB/adm/style/acp_update.html @@ -1,52 +1,46 @@ <!-- INCLUDE overall_header.html --> <a id="maincontent"></a> - -<!-- IF S_VERSION_CHECK --> - <h1>{L_VERSION_CHECK}</h1> +<h1>{L_VERSION_CHECK}</h1> - <p>{L_VERSION_CHECK_EXPLAIN}</p> +<p>{L_VERSION_CHECK_EXPLAIN}</p> - <!-- IF S_UP_TO_DATE and S_UP_TO_DATE_AUTO --> - <div class="successbox"> - <p>{L_VERSION_UP_TO_DATE_ACP} - <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a></p> - </div> - <!-- ELSE --> - <div class="errorbox"> - <p>{L_VERSION_NOT_UP_TO_DATE_ACP} - <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a></p> - </div> - <!-- ENDIF --> - - <!-- IF NEXT_FEATURE_VERSION --> - <div class="errorbox"> - <p>{UPGRADE_INSTRUCTIONS}</p> - </div> - <!-- ENDIF --> +<!-- IF S_UP_TO_DATE --> + <div class="successbox"> + <p>{L_VERSION_UP_TO_DATE_ACP} - <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a></p> + </div> +<!-- ELSE --> + <div class="errorbox"> + <p>{L_VERSION_NOT_UP_TO_DATE_ACP} - <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a></p> + </div> +<!-- ENDIF --> - <fieldset> - <legend></legend> +<fieldset> + <legend></legend> <dl> <dt><label>{L_CURRENT_VERSION}</label></dt> - <dd><strong><!-- IF S_UP_TO_DATE and not S_UP_TO_DATE_AUTO -->{AUTO_VERSION}<!-- ELSE -->{CURRENT_VERSION}<!-- ENDIF --></strong></dd> - </dl> - <dl> - <dt><label>{L_LATEST_VERSION}</label></dt> - <dd><strong>{LATEST_VERSION}</strong></dd> + <dd><strong>{CURRENT_VERSION}</strong></dd> </dl> - </fieldset> +</fieldset> - <!-- IF S_UP_TO_DATE and not S_UP_TO_DATE_AUTO --> - {L_UPDATE_INSTRUCTIONS_INCOMPLETE} - <br /><br /> - {UPDATE_INSTRUCTIONS} - <br /><br /> - <!-- ENDIF --> - <!-- IF not S_UP_TO_DATE --> - {UPDATE_INSTRUCTIONS} - <br /><br /> - <!-- ENDIF --> +<!-- BEGIN updates_available --> + <fieldset> + <legend></legend> + <dl> + <dt><label>{L_LATEST_VERSION}</label></dt> + <dd><strong>{updates_available.current}</strong></dd> + </dl> + <dl> + <dt><label>{L_RELEASE_ANNOUNCEMENT}</label></dt> + <dd><strong><a href="{updates_available.announcement}">{updates_available.announcement}</a></strong></dd> + </dl> + </fieldset> +<!-- END updates_available --> +<!-- IF not S_UP_TO_DATE --> + {UPDATE_INSTRUCTIONS} + <br /><br /> <!-- ENDIF --> <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/adm/style/acp_users.html b/phpBB/adm/style/acp_users.html index 96c9de6ebb..b84e32013f 100644 --- a/phpBB/adm/style/acp_users.html +++ b/phpBB/adm/style/acp_users.html @@ -125,7 +125,7 @@ <form id="user_groups" method="post" action="{U_ACTION}"> - <table cellspacing="1"> + <table class="table1 zebra-table"> <tbody> <!-- BEGIN group --> <!-- IF group.S_NEW_GROUP_TYPE --> @@ -133,7 +133,7 @@ <td class="row3" colspan="4"><strong>{group.GROUP_TYPE}</strong></td> </tr> <!-- ELSE --> - <!-- IF group.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td><a href="{group.U_EDIT_GROUP}">{group.GROUP_NAME}</a></td> <td><!-- IF group.S_IS_MEMBER --><!-- IF group.S_NO_DEFAULT --><a href="{group.U_DEFAULT}">{L_GROUP_DEFAULT}</a><!-- ELSE --><strong>{L_GROUP_DEFAULT}</strong><!-- ENDIF --><!-- ELSEIF not group.S_IS_MEMBER and group.U_APPROVE --><a href="{group.U_APPROVE}">{L_GROUP_APPROVE}</a><!-- ELSE --> <!-- ENDIF --></td> <td><!-- IF group.S_IS_MEMBER and not group.S_SPECIAL_GROUP --><a href="{group.U_DEMOTE_PROMOTE}">{group.L_DEMOTE_PROMOTE}</a><!-- ELSE --> <!-- ENDIF --></td> @@ -164,7 +164,7 @@ </div> <!-- IF .attach --> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_FILENAME}</th> @@ -176,7 +176,7 @@ </thead> <tbody> <!-- BEGIN attach --> - <!-- IF attach.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td><a href="{attach.U_DOWNLOAD}">{attach.REAL_FILENAME}</a><br /><span class="small"><!-- IF attach.S_IN_MESSAGE --><strong>{L_PM}{L_COLON} </strong><!-- ELSE --><strong>{L_POST}{L_COLON} </strong><!-- ENDIF --><a href="{attach.U_VIEW_TOPIC}">{attach.TOPIC_TITLE}</a></span></td> <td style="text-align: center">{attach.POST_TIME}</td> <td style="text-align: center">{attach.SIZE}</td> diff --git a/phpBB/adm/style/acp_users_feedback.html b/phpBB/adm/style/acp_users_feedback.html index d1a4f59445..f251724cd2 100644 --- a/phpBB/adm/style/acp_users_feedback.html +++ b/phpBB/adm/style/acp_users_feedback.html @@ -7,7 +7,7 @@ </div> <!-- IF .log --> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_REPORT_BY}</th> @@ -19,8 +19,7 @@ </thead> <tbody> <!-- BEGIN log --> - <!-- IF log.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> - + <tr> <td>{log.USERNAME}</td> <td style="text-align: center;">{log.IP}</td> <td style="text-align: center;">{log.DATE}</td> diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index 1caa6e5e13..506101c3f7 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -30,7 +30,20 @@ </dl> <dl> <dt><label>{L_POSTS}{L_COLON}</label></dt> - <dd><strong>{USER_POSTS}</strong><!-- IF POSTS_IN_QUEUE and U_MCP_QUEUE --> (<a href="{U_MCP_QUEUE}">{L_POSTS_IN_QUEUE}</a>)<!-- ELSEIF POSTS_IN_QUEUE --> ({L_POSTS_IN_QUEUE})<!-- ENDIF --></dd> + <dd> + <strong> + <!-- IF USER_HAS_POSTS and U_SEARCH_USER --> + <a href="{U_SEARCH_USER}">{USER_POSTS}</a> + <!-- ELSE --> + {USER_POSTS} + <!-- ENDIF --> + </strong> + <!-- IF POSTS_IN_QUEUE and U_MCP_QUEUE --> + (<a href="{U_MCP_QUEUE}">{L_POSTS_IN_QUEUE}</a>) + <!-- ELSEIF POSTS_IN_QUEUE --> + ({L_POSTS_IN_QUEUE}) + <!-- ENDIF --> + </dd> </dl> <dl> <dt><label>{L_WARNINGS}{L_COLON}</label></dt> @@ -73,11 +86,11 @@ { if (option != 'banuser' && option != 'banemail' && option != 'banip') { - dE('reasons', -1); + phpbb.toggleDisplay('reasons', -1); return; } - dE('reasons', 1); + phpbb.toggleDisplay('reasons', 1); element = document.getElementById('user_quick_tools').ban_reason; diff --git a/phpBB/adm/style/acp_users_prefs.html b/phpBB/adm/style/acp_users_prefs.html index f1b9e28a66..14715f59e4 100644 --- a/phpBB/adm/style/acp_users_prefs.html +++ b/phpBB/adm/style/acp_users_prefs.html @@ -5,9 +5,10 @@ </script> <form id="user_prefs" method="post" action="{U_ACTION}"> - + <!-- EVENT acp_users_prefs_prepend --> <fieldset> <legend>{L_UCP_PREFS_PERSONAL}</legend> + <!-- EVENT acp_users_prefs_personal_prepend --> <dl> <dt><label for="viewemail">{L_SHOW_EMAIL}{L_COLON}</label></dt> <dd><label><input type="radio" class="radio" name="viewemail" value="1"<!-- IF VIEW_EMAIL --> id="viewemail" checked="checked"<!-- ENDIF --> /> {L_YES}</label> @@ -40,11 +41,6 @@ <label><input type="radio" class="radio" name="notifypm" value="0"<!-- IF not NOTIFY_PM --> id="notifypm" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> </dl> <dl> - <dt><label for="popuppm">{L_POPUP_ON_PM}{L_COLON}</label></dt> - <dd><label><input type="radio" class="radio" name="popuppm" value="1"<!-- IF POPUP_PM --> id="popuppm" checked="checked"<!-- ENDIF --> /> {L_YES}</label> - <label><input type="radio" class="radio" name="popuppm" value="0"<!-- IF not POPUP_PM --> id="popuppm" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> - </dl> - <dl> <dt><label for="lang">{L_BOARD_LANGUAGE}{L_COLON}</label></dt> <dd><select id="lang" name="lang">{S_LANG_OPTIONS}</select></dd> </dl> @@ -55,13 +51,15 @@ <!-- INCLUDE timezone_option.html --> <dl> <dt><label for="dateoptions">{L_BOARD_DATE_FORMAT}{L_COLON}</label><br /><span>{L_BOARD_DATE_FORMAT_EXPLAIN}</span></dt> - <dd><select name="dateoptions" id="dateoptions" onchange="if(this.value=='custom'){dE('custom_date',1);}else{dE('custom_date',-1);} if (this.value == 'custom') { document.getElementById('dateformat').value = default_dateformat; } else { document.getElementById('dateformat').value = this.value; }">{S_DATEFORMAT_OPTIONS}</select></dd> + <dd><select name="dateoptions" id="dateoptions" onchange="if(this.value=='custom'){phpbb.toggleDisplay('custom_date',1);}else{phpbb.toggleDisplay('custom_date',-1);} if (this.value == 'custom') { document.getElementById('dateformat').value = default_dateformat; } else { document.getElementById('dateformat').value = this.value; }">{S_DATEFORMAT_OPTIONS}</select></dd> <dd><div id="custom_date"<!-- IF not S_CUSTOM_DATEFORMAT --> style="display:none;"<!-- ENDIF -->><input type="text" name="dateformat" id="dateformat" value="{DATE_FORMAT}" maxlength="30" /></div></dd> </dl> + <!-- EVENT acp_users_prefs_personal_append --> </fieldset> <fieldset> <legend>{L_UCP_PREFS_POST}</legend> + <!-- EVENT acp_users_prefs_post_prepend --> <dl> <dt><label for="bbcode">{L_DEFAULT_BBCODE}{L_COLON}</label></dt> <dd><label><input type="radio" class="radio" name="bbcode" value="1"<!-- IF BBCODE --> id="bbcode" checked="checked"<!-- ENDIF --> /> {L_YES}</label> @@ -82,10 +80,12 @@ <dd><label><input type="radio" class="radio" name="notify" value="1"<!-- IF NOTIFY --> id="notify" checked="checked"<!-- ENDIF --> /> {L_YES}</label> <label><input type="radio" class="radio" name="notify" value="0"<!-- IF not NOTIFY --> id="notify" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> </dl> + <!-- EVENT acp_users_prefs_post_append --> </fieldset> <fieldset> <legend>{L_UCP_PREFS_VIEW}</legend> + <!-- EVENT acp_users_prefs_view_prepend --> <dl> <dt><label for="view_images">{L_VIEW_IMAGES}{L_COLON}</label></dt> <dd><label><input type="radio" class="radio" name="view_images" value="1"<!-- IF VIEW_IMAGES --> id="view_images" checked="checked"<!-- ENDIF --> /> {L_YES}</label> @@ -140,8 +140,9 @@ <dt><label>{L_VIEW_POSTS_DIR}{L_COLON}</label></dt> <dd>{S_POST_SORT_DIR}</dd> </dl> + <!-- EVENT acp_users_prefs_view_append --> </fieldset> - + <!-- EVENT acp_users_prefs_append --> <fieldset class="quick"> <input class="button1" type="submit" name="update" value="{L_SUBMIT}" /> {S_FORM_TOKEN} diff --git a/phpBB/adm/style/acp_users_profile.html b/phpBB/adm/style/acp_users_profile.html index cad1dca9d8..d32348ff1c 100644 --- a/phpBB/adm/style/acp_users_profile.html +++ b/phpBB/adm/style/acp_users_profile.html @@ -3,42 +3,10 @@ <fieldset> <legend>{L_USER_PROFILE}</legend> <dl> - <dt><label for="icq">{L_UCP_ICQ}{L_COLON}</label></dt> - <dd><input type="text" id="icq" name="icq" value="{ICQ}" /></dd> - </dl> - <dl> - <dt><label for="aim">{L_UCP_AIM}{L_COLON}</label></dt> - <dd><input type="text" id="aim" name="aim" value="{AIM}" /></dd> - </dl> - <dl> - <dt><label for="msn">{L_UCP_MSNM}{L_COLON}</label></dt> - <dd><input type="email" id="msn" name="msn" value="{MSN}" /></dd> - </dl> - <dl> - <dt><label for="yim">{L_UCP_YIM}{L_COLON}</label></dt> - <dd><input type="text" id="yim" name="yim" value="{YIM}" /></dd> - </dl> - <dl> <dt><label for="jabber">{L_UCP_JABBER}{L_COLON}</label></dt> <dd><input type="email" id="jabber" name="jabber" value="{JABBER}" /></dd> </dl> <dl> - <dt><label for="website">{L_WEBSITE}{L_COLON}</label></dt> - <dd><input type="url" id="website" name="website" value="{WEBSITE}" /></dd> - </dl> - <dl> - <dt><label for="location">{L_LOCATION}{L_COLON}</label></dt> - <dd><input type="text" id="location" name="location" value="{LOCATION}" /></dd> - </dl> - <dl> - <dt><label for="occupation">{L_OCCUPATION}{L_COLON}</label></dt> - <dd><textarea id="occupation" name="occupation" rows="3" cols="30">{OCCUPATION}</textarea></dd> - </dl> - <dl> - <dt><label for="interests">{L_INTERESTS}{L_COLON}</label></dt> - <dd><textarea id="interests" name="interests" rows="3" cols="30">{INTERESTS}</textarea></dd> - </dl> - <dl> <dt><label for="birthday">{L_BIRTHDAY}{L_COLON}</label><br /><span>{L_BIRTHDAY_EXPLAIN}</span></dt> <dd>{L_DAY}{L_COLON} <select id="birthday" name="bday_day">{S_BIRTHDAY_DAY_OPTIONS}</select> {L_MONTH}{L_COLON} <select name="bday_month">{S_BIRTHDAY_MONTH_OPTIONS}</select> {L_YEAR}{L_COLON} <select name="bday_year">{S_BIRTHDAY_YEAR_OPTIONS}</select></dd> </dl> diff --git a/phpBB/adm/style/acp_users_signature.html b/phpBB/adm/style/acp_users_signature.html index 2b4964803e..5b5c3ecf7f 100644 --- a/phpBB/adm/style/acp_users_signature.html +++ b/phpBB/adm/style/acp_users_signature.html @@ -3,6 +3,8 @@ var form_name = 'user_signature'; var text_name = 'signature'; + var load_draft = false; + var upload = false; // Define the bbCode tags var bbcode = new Array(); @@ -20,11 +22,11 @@ o: '{LA_BBCODE_O_HELP}', p: '{LA_BBCODE_P_HELP}', w: '{LA_BBCODE_W_HELP}', + a: '{LA_BBCODE_A_HELP}', s: '{LA_BBCODE_S_HELP}', f: '{LA_BBCODE_F_HELP}', y: '{LA_BBCODE_Y_HELP}', - d: '{LA_BBCODE_D_HELP}', - tip: '{L_STYLES_TIP}' + d: '{LA_BBCODE_D_HELP}' <!-- BEGIN custom_tags --> ,cb_{custom_tags.BBCODE_ID}{L_COLON} '{custom_tags.A_BBCODE_HELPLINE}' <!-- END custom_tags --> @@ -32,7 +34,7 @@ // ]]> </script> -<script type="text/javascript" src="{T_TEMPLATE_PATH}/editor.js"></script> +<!-- INCLUDEJS {T_ASSETS_PATH}/javascript/editor.js --> <form id="user_signature" method="post" action="{U_ACTION}"> @@ -47,53 +49,49 @@ <legend>{L_SIGNATURE}</legend> <p>{L_SIGNATURE_EXPLAIN}</p> + <!-- EVENT acp_users_signature_editor_buttons_before --> <div id="format-buttons"> - <input type="button" class="button2" accesskey="b" name="addbbcode0" value=" B " style="font-weight:bold; width: 30px;" onclick="bbstyle(0)" onmouseover="helpline('b')" onmouseout="helpline('tip')" /> - <input type="button" class="button2" accesskey="i" name="addbbcode2" value=" i " style="font-style:italic; width: 30px;" onclick="bbstyle(2)" onmouseover="helpline('i')" onmouseout="helpline('tip')" /> - <input type="button" class="button2" accesskey="u" name="addbbcode4" value=" u " style="text-decoration: underline; width: 30px;" onclick="bbstyle(4)" onmouseover="helpline('u')" onmouseout="helpline('tip')" /> - <input type="button" class="button2" accesskey="q" name="addbbcode6" value="Quote" style="width: 50px" onclick="bbstyle(6)" onmouseover="helpline('q')" onmouseout="helpline('tip')" /> - <input type="button" class="button2" accesskey="c" name="addbbcode8" value="Code" style="width: 40px" onclick="bbstyle(8)" onmouseover="helpline('c')" onmouseout="helpline('tip')" /> - <input type="button" class="button2" accesskey="l" name="addbbcode10" value="List" style="width: 40px" onclick="bbstyle(10)" onmouseover="helpline('l')" onmouseout="helpline('tip')" /> - <input type="button" class="button2" accesskey="o" name="addbbcode12" value="List=" style="width: 40px" onclick="bbstyle(12)" onmouseover="helpline('o')" onmouseout="helpline('tip')" /> - <input type="button" class="button2" accesskey="y" name="addlistitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" onmouseover="helpline('y')" onmouseout="helpline('tip')" /> + <input type="button" class="button2" accesskey="b" name="addbbcode0" value=" B " style="font-weight:bold; width: 30px" onclick="bbstyle(0)" title="{L_BBCODE_B_HELP}" /> + <input type="button" class="button2" accesskey="i" name="addbbcode2" value=" i " style="font-style:italic; width: 30px" onclick="bbstyle(2)" title="{L_BBCODE_I_HELP}" /> + <input type="button" class="button2" accesskey="u" name="addbbcode4" value=" u " style="text-decoration: underline; width: 30px" onclick="bbstyle(4)" title="{L_BBCODE_U_HELP}" /> + <!-- IF S_BBCODE_QUOTE --> + <input type="button" class="button2" accesskey="q" name="addbbcode6" value="Quote" style="width: 50px" onclick="bbstyle(6)" title="{L_BBCODE_Q_HELP}" /> + <!-- ENDIF --> + <input type="button" class="button2" accesskey="c" name="addbbcode8" value="Code" style="width: 40px" onclick="bbstyle(8)" title="{L_BBCODE_C_HELP}" /> + <input type="button" class="button2" accesskey="l" name="addbbcode10" value="List" style="width: 40px" onclick="bbstyle(10)" title="{L_BBCODE_L_HELP}" /> + <input type="button" class="button2" accesskey="o" name="addbbcode12" value="List=" style="width: 40px" onclick="bbstyle(12)" title="{L_BBCODE_O_HELP}" /> + <input type="button" class="button2" accesskey="y" name="addlistitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" title="{L_BBCODE_LISTITEM_HELP}" /> <!-- IF S_BBCODE_IMG --> - <input type="button" class="button2" accesskey="p" name="addbbcode14" value="Img" style="width: 40px" onclick="bbstyle(14)" onmouseover="helpline('p')" onmouseout="helpline('tip')" /> + <input type="button" class="button2" accesskey="p" name="addbbcode14" value="Img" style="width: 40px" onclick="bbstyle(14)" title="{L_BBCODE_P_HELP}" /> <!-- ENDIF --> <!-- IF S_LINKS_ALLOWED --> - <input type="button" class="button2" accesskey="w" name="addbbcode16" value="URL" style="text-decoration: underline; width: 40px" onclick="bbstyle(16)" onmouseover="helpline('w')" onmouseout="helpline('tip')" /> + <input type="button" class="button2" accesskey="w" name="addbbcode16" value="URL" style="text-decoration: underline; width: 40px" onclick="bbstyle(16)" title="{L_BBCODE_W_HELP}" /> <!-- ENDIF --> <!-- IF S_BBCODE_FLASH --> - <input type="button" class="button2" accesskey="d" name="addbbcode18" value="Flash" onclick="bbstyle(18)" onmouseover="helpline('d')" onmouseout="helpline('tip')" /> + <input type="button" class="button2" accesskey="d" name="addbbcode18" value="Flash" onclick="bbstyle(18)" title="{L_BBCODE_D_HELP}" /> <!-- ENDIF --> - - {L_FONT_SIZE}{L_COLON} <select name="addbbcode20" onchange="bbfontstyle('[size=' + this.form.addbbcode20.options[this.form.addbbcode20.selectedIndex].value + ']', '[/size]');this.form.addbbcode20.selectedIndex = 2;" title="{L_FONT_SIZE}" onmouseover="helpline('f')" onmouseout="helpline('tip')"> + <select name="addbbcode20" onchange="bbfontstyle('[size=' + this.form.addbbcode20.options[this.form.addbbcode20.selectedIndex].value + ']', '[/size]');this.form.addbbcode20.selectedIndex = 2;" title="{L_BBCODE_F_HELP}"> <option value="50">{L_FONT_TINY}</option> <option value="85">{L_FONT_SMALL}</option> <option value="100" selected="selected">{L_FONT_NORMAL}</option> - <option value="150">{L_FONT_LARGE}</option> - <option value="200">{L_FONT_HUGE}</option> + <!-- IF not MAX_FONT_SIZE or MAX_FONT_SIZE >= 150 --> + <option value="150">{L_FONT_LARGE}</option> + <!-- IF not MAX_FONT_SIZE or MAX_FONT_SIZE >= 200 --> + <option value="200">{L_FONT_HUGE}</option> + <!-- ENDIF --> + <!-- ENDIF --> </select> - <!-- IF .custom_tags --> - <br /><br /> <!-- BEGIN custom_tags --> - <input type="button" class="button2" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})"<!-- IF custom_tags.BBCODE_HELPLINE !== '' --> onmouseover="helpline('cb_{custom_tags.BBCODE_ID}')" onmouseout="helpline('tip')"<!-- ENDIF --> /> + <input type="button" class="button2" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})" title="{custom_tags.BBCODE_HELPLINE}" /> <!-- END custom_tags --> - <!-- ENDIF --> - </div> + <!-- EVENT acp_users_signature_editor_buttons_after --> - <p><input type="text" class="text full" style="border: 0; background: none;" name="helpbox" value="{L_STYLES_TIP}" /></p> - - <dl> - <dt style="width: 90px;"> - <script type="text/javascript"> - // <![CDATA[ - colorPalette('v', 12, 10); - // ]]> - </script> + <dl class="responsive-columns"> + <dt style="width: 90px;" id="color_palette_placeholder" data-orientation="v" data-height="12" data-width="15" data-bbcode="true"> </dt> - <dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 90px;"><textarea name="signature" rows="10" cols="60" style="width: 95%;" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();" data-bbcode="true">{SIGNATURE}</textarea></dd> - <dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 90px; margin-top: 5px;"> + <dd style="margin-{S_CONTENT_FLOW_BEGIN}: 90px;"><textarea name="signature" rows="10" cols="60" style="width: 95%;" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();" data-bbcode="true">{SIGNATURE}</textarea></dd> + <dd style="margin-{S_CONTENT_FLOW_BEGIN}: 90px; margin-top: 5px;"> <!-- IF S_BBCODE_ALLOWED --> <label><input type="checkbox" class="radio" name="disable_bbcode"{S_BBCODE_CHECKED} /> {L_DISABLE_BBCODE}</label> <!-- ENDIF --> @@ -104,7 +102,7 @@ <label><input type="checkbox" class="radio" name="disable_magic_url"{S_MAGIC_URL_CHECKED} /> {L_DISABLE_MAGIC_URL}</label> <!-- ENDIF --> </dd> - <dd style="margin-{S_CONTENT_FLOW_BEGIN}{L_COLON} 90px; margin-top: 10px;"><strong>{L_OPTIONS}{L_COLON} </strong>{BBCODE_STATUS} :: {IMG_STATUS} :: {FLASH_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> diff --git a/phpBB/adm/style/acp_users_warnings.html b/phpBB/adm/style/acp_users_warnings.html index d27f3800fc..6e7f521415 100644 --- a/phpBB/adm/style/acp_users_warnings.html +++ b/phpBB/adm/style/acp_users_warnings.html @@ -1,7 +1,7 @@ <form id="list" method="post" action="{U_ACTION}"> <!-- IF .warn --> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_REPORT_BY}</th> @@ -12,7 +12,7 @@ </thead> <tbody> <!-- BEGIN warn --> - <!-- IF warn.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td>{warn.USERNAME}</td> <td style="text-align: center; nowrap: nowrap;">{warn.DATE}</td> <td>{warn.ACTION}</td> diff --git a/phpBB/adm/style/acp_words.html b/phpBB/adm/style/acp_words.html index 4acd75f933..6038fc6161 100644 --- a/phpBB/adm/style/acp_words.html +++ b/phpBB/adm/style/acp_words.html @@ -47,7 +47,7 @@ <input class="button2" name="add" type="submit" value="{L_ADD_WORD}" /> </p> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th>{L_WORD}</th> @@ -57,7 +57,7 @@ </thead> <tbody> <!-- BEGIN words --> - <!-- IF words.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> + <tr> <td style="text-align: center;">{words.WORD}</td> <td style="text-align: center;">{words.REPLACEMENT}</td> <td> <a href="{words.U_EDIT}">{ICON_EDIT}</a> <a href="{words.U_DELETE}" data-ajax="row_delete">{ICON_DELETE}</a> </td> diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css index ca15338133..6f2d65afc0 100644 --- a/phpBB/adm/style/admin.css +++ b/phpBB/adm/style/admin.css @@ -18,11 +18,11 @@ body, div, p, th, td, li, dd { font-size: x-small; voice-family: "\"}\""; voice-family: inherit; - font-size: small + font-size: small; } html>body, html>div, html>p, html>th, html>td, html>li, html>dd { - font-size: small + font-size: small; } html { @@ -31,6 +31,7 @@ html { /* Always show a scrollbar for short pages - stops the jump when the scrollbar appears. non-ie browsers */ height: 100%; margin-bottom: 1px; + word-wrap: break-word; } body { @@ -42,6 +43,10 @@ body { margin: 10px 15px; } +code, samp { + font-size: 1.2em; +} + img { border: 0; } @@ -97,6 +102,10 @@ hr { height: 1px; } +.centered-text { + text-align: center; +} + .small { font-size: 0.85em; } @@ -105,6 +114,23 @@ hr { display: none; } +@media only screen and (max-width: 800px), only screen and (max-device-width: 800px) +{ + body { + margin: 5px 5px 0; + } +} + +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + html, body { + height: auto; + margin: 0; + padding: 0; + } +} + + /* General links */ a:link, a:visited { color: #105289; @@ -136,6 +162,7 @@ li { list-style-type: inherit; } + /* Main blocks ---------------------------------------- */ #wrap { @@ -174,7 +201,7 @@ li { #page-body { clear: both; - min-width: 700px; + min-width: 650px; } #page-footer { @@ -195,19 +222,23 @@ li { } #main { - float: left; - width: 76%; - margin: 0 0 0 3%; - min-height: 350px; + float: right; + width: 100%; + margin: 0 0 0 -210px; } .rtl #main { - float: right; - margin: 0 3% 0 0; + float: left; + margin: 0 -210px 0 0; +} + +.main { + margin-left: 210px; } -* html #main { - height: 350px; +.rtl .main { + margin-left: 0; + margin-right: 210px; } #page-body.simple-page-body { @@ -216,17 +247,81 @@ li { min-width: 0; } +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + #wrap, #page-body, #page-body.simple-page-body { + padding: 0; + min-width: 300px; + } + + #page-header { + margin: 5px; + padding-left: 160px; + height: auto; + min-height: 54px; + overflow: hidden; + } + + .rtl #page-header { + padding-right: 160px; + padding-left: 0; + } + + #page-header h1 { + font-size: 1.2em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + #page-header fieldset { + margin-top: 5px; + } + + #main, .rtl #main, .main, .rtl .main { + float: none; + width: auto; + margin: 0; + } + + #content { + background: #F3F3F3 url("../images/innerbox_bg.gif") repeat-x top; + padding: 5px; + } + + #page-footer { + padding: 0 5px 5px; + } +} + +@media only screen and (max-width: 400px), only screen and (max-device-width: 400px) +{ + #page-header { + background-size: 76px 26.5px; + padding-left: 80px; + min-height: 30px; + } + + .rtl #page-header { + padding-right: 80px; + } + + #page-header h1 { + padding-top: 0; + font-size: 1.1em; + } +} + + /* Tabbed menu Based on: http://www.alistapart.com/articles/slidingdoors2/ ----------------------------------------*/ #tabs { line-height: normal; - margin: 0 0 -6px 7px; + margin: 0 7px; min-width: 600px; -} - -.rtl #tabs { - margin: 0 7px -6px 0; + position: relative; + z-index: 2; } #tabs ul { @@ -235,14 +330,27 @@ li { list-style: none; } +#tabs ul:after { + content: ''; + display: block; + clear: both; +} + #tabs li { - display: inline; + display: block; + float: left; margin: 0; padding: 0; font-size: 0.85em; font-weight: bold; } +#tabs li:after { + content: ''; + display: block; + clear: both; +} + #tabs a { float: left; background:url("../images/bg_tabs1.gif") no-repeat 0% -34px; @@ -252,7 +360,7 @@ li { position: relative; } -.rtl #tabs a { +.rtl #tabs li { float: right; } @@ -261,6 +369,7 @@ li { display: block; background: url("../images/bg_tabs2.gif") no-repeat 100% -34px; padding: 7px 10px 4px 4px; + min-height: 14px; color: #767676; white-space: nowrap; font-family: Arial, Helvetica, sans-serif; @@ -280,122 +389,154 @@ li { color: #BC2A4D; } -#tabs #activetab a { +#tabs a:hover { + background-position: 0 -69px; +} + +#tabs a:hover span { + background-position: 100% -69px; +} + +#tabs .activetab a { background-position: 0 0; border-bottom: 1px solid #DCDEE2; } -#tabs #activetab a span { +#tabs .activetab a span { background-position: 100% 0; padding-bottom: 5px; color: #23649F; } -#tabs a:hover { - background-position: 0 -69px; +#tabs .activetab a:hover span { + color: #115098; } -#tabs a:hover span { - background-position: 100% -69px; +.responsive-tab { + position: relative; } -#tabs #activetab a:hover span { - color: #115098; +.responsive-tab .responsive-tab-link span { + display: inline-block; + font-size: 16px; + position: relative; + width: 16px; + line-height: 14px; + text-decoration: none; } +.responsive-tab .responsive-tab-link span:before { + content: ''; + position: absolute; + left: 5px; + top: 8px; + height: .125em; + width: 14px; + border-bottom: 0.125em solid #767676; + border-top: 0.375em double #767676; +} -/* Main Panel ----------------------------------------- */ -#acp { - margin: 4px 0; - padding: 3px 1px; - min-width: 550px; - background-color: #FFFFFF; - border: 1px #999999 solid; +.responsive-tab .responsive-tab-link:hover span:before { + border-color: #BC2A4D; } -.panel { - background: #F3F3F3 url("../images/innerbox_bg.gif") repeat-x top; - padding: 0; +.responsive-tab.activetab .responsive-tab-link span:before { + border-color: #23649F; } -span.corners-top, span.corners-bottom, -span.corners-top span, span.corners-bottom span { - font-size: 1px; - line-height: 1px; - display: block; - height: 5px; - background-repeat: no-repeat; +.responsive-tab.activetab .responsive-tab-link:hover span:before { + border-color: #115098; } -span.corners-top { - background-image: url("../images/corners_left.gif"); - background-position: 0 0; - margin: -4px -2px 0; +#tabs .dropdown { + top: 18px; + margin-right: -1px; } -span.corners-top span { - background-image: url("../images/corners_right.gif"); - background-position: 100% 0; +#tabs .dropdown-right .dropdown { + margin-left: -2px; } -span.corners-bottom { - background-image: url("../images/corners_left.gif"); - background-position: 0 100%; - margin: 0 -2px -4px; - clear: both; +#tabs .dropdown li { + display: block !important; + float: none; + background: transparent none; + padding: 0; } -span.corners-bottom span { - background-image: url("../images/corners_right.gif"); - background-position: 100% 100%; +#tabs .dropdown a, #tabs .dropdown a span { + background: transparent; + display: block; + border-width: 0; + float: none; + margin: 0; + padding: 0; + text-align: right; } -/* WinIE tweaks \*/ -* html span.corners-top, * html span.corners-bottom { background-image: url("../images/corners_left.gif"); } -* html span.corners-top span, * html span.corners-bottom span { background-image: url("../images/corners_right.gif"); } -/* End tweaks */ +#tabs .dropdown a span { + padding: 4px 8px; + color: inherit !important; +} -/* Sub-navigation Menu ----------------------------------------- */ +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + #tabs { + min-width: 0; + } +} -/* Toggle */ -#toggle { - padding: 5px; - width: 5%; - height: 100px; - position: absolute; - left: 15%; - top: 28px; - margin-left: 2px; +/* Main Panel +---------------------------------------- */ +#acp { + clear: both; + position: relative; + top: -2px; + margin: 0 0 2px; + padding: 3px 1px; + min-width: 550px; + background: #F3F3F3 url("../images/innerbox_bg.gif") repeat-x top; + border: 1px #999999 solid; + border-radius: 5px; + box-shadow: #FFF 0 0 0 1px inset; } -.rtl #toggle { - left: 75%; - margin-right: 0; - margin-left: 6px; +#acp:first-child { + top: 0; } -#toggle-handle { - display: block; - width: 18px; - height: 19px; - float: right; - background-image: url(../images/toggle.gif); +.panel { + background: #F3F3F3 url("../images/innerbox_bg.gif") repeat-x top; + padding: 5px 0; + border-radius: 5px; + overflow: hidden; } -.rtl #toggle-handle { - background-image: url(../images/toggle.gif); - background-position: 100% 50%; +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + #acp { + min-width: 0; + min-height: 0; + border-radius: 0; + border-width: 1px 0; + background: #fff; + padding: 1px 0; + box-shadow: none; + } } +/* Sub-navigation Menu +---------------------------------------- */ + /* Menu */ #menu { float: left; - width: 20%; + width: 200px; font-size: 1.00em; padding: 0; border-right: 1px solid #CCCFD3; + position: relative; + z-index: 1; } .rtl #menu { @@ -412,15 +553,16 @@ span.corners-bottom span { list-style: none; margin: 0; padding: 0; + word-wrap: normal; } /* Default list state */ -#menu li { +#menu li, #menu .header { padding: 0; margin: 0; font-size: 0.85em; font-weight: bold; - display: inline; + display: block; } /* Link styles for the sub-section links */ @@ -485,7 +627,7 @@ span.corners-bottom span { background: url("../images/arrow_down.gif") 99% 50% no-repeat; } -#menu li.header { +#menu .header { font-family: Tahoma, Helvetica, sans-serif; display: block; font-weight: bold; @@ -495,8 +637,71 @@ span.corners-bottom span { margin-top: 15px; text-transform: uppercase; font-size: 0.75em; + text-decoration: none; + cursor: inherit; + outline-style: none; } +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + #menu, .rtl #menu { + float: none; + width: auto; + border-width: 0; + max-width: 200px; + margin: 0 auto 10px; + } + + #menu p { + text-align: center; + } + + #menu .menu-block.active { + margin: 0 -5px; + padding: 0 5px 3px; + background: rgba(255, 255, 255, .5); + border-radius: 5px; + } + + #menu .menu-block.no-header.active { + padding-top: 3px; + } + + #menu .menu-block .header { + margin-top: 5px; + cursor: pointer; + border-bottom-width: 0; + position: relative; + text-decoration: underline; + } + + #menu .menu-block .header:focus, #menu .menu-block.active .header { + color: #D31141; + text-decoration: none; + } + + #menu .menu-block ul { + display: none; + } + + .nojs #menu .menu-block:hover ul, #menu .menu-block.active ul, #menu .menu-block.no-header ul { + display: block; + } + + #menu .menu-block li:last-child { + border-bottom: 1px solid #327AA5; + } + + #menu .menu-block:last-child li:last-child, #menu .menu-block.active li:last-child { + border-bottom-width: 0; + } + + #menu .menu-block li a span { + border-radius: 2px; + } +} + + /* Table styles ---------------------------------------- */ @@ -529,6 +734,20 @@ td { text-align: right; } +.table1 { + border-collapse: separate; + border-spacing: 1px; +} + +dt#color_palette_placeholder table { + margin-right: 5px; + width: 80px; +} + +#color_palette_placeholder td { + padding: 0; +} + table.type2 { border: none; background: none; @@ -623,8 +842,22 @@ td.name { text-align: right; } -.row1 { background-color: #F9F9F9; } -.row2 { background-color: #DCEBFE; } +.row1 { + background-color: #F9F9F9; +} + +table.zebra-table tbody tr:nth-child(odd) { + background-color: #F9F9F9; +} + +.row2 { + background-color: #DCEBFE; +} + +table.zebra-table tbody tr:nth-child(even) { + background-color: #DCEBFE; +} + .row3 { background-color: #DBDFE2; } .row4 { background-color: #E4E8EB; } .col1 { background-color: #DCEBFE; } @@ -653,6 +886,177 @@ td.name { color: #BC2A4D; } +/* Specific tables */ +table.forums td.folder { + width: 27px; + text-align: center; +} + +table td.actions { + vertical-align: middle; + width: 100px; + text-align: center; + white-space: nowrap; +} + +table tr:first-child td.actions .up, table tr:last-child td.actions .down { + display: none; +} + +table tr:first-child td.actions .up-disabled, table tr:last-child td.actions .down-disabled { + display: inline !important; +} + +table.styles td.users, table td.mark { + text-align: center; +} + +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + table.responsive, table.responsive tbody, table.responsive tr, table.responsive td { + display: block; + } + + table.responsive thead, table.responsive th, table.responsive colgroup { + display: none; + } + + table.responsive.show-header thead, table.responsive.show-header th:first-child, table.responsive caption { + display: block; + width: auto !important; + text-align: left !important; + margin: 0; + } + + table.responsive { + background: transparent none; + border-width: 0; + padding: 0; + } + + table.responsive caption { + padding: 3px 4px; + color: #FFFFFF; + background: #70AED3 url("../images/gradient2b.gif") bottom left repeat-x; + border-top: 1px solid #6DACD2; + border-bottom: 1px solid #327AA5; + text-align: left; + font-size: 0.75em; + font-weight: bold; + text-transform: uppercase; + } + + table.responsive.show-header th:first-child span.rank-img, table.responsive.no-caption caption, table.responsive.no-header thead { + display: none; + } + + table.responsive tr { + margin: 2px 0; + border: 1px solid #CCCFD3; + background-color: #FFFFFF; + padding: 1px 1px 0; + overflow: hidden; + } + + table.responsive tr.row1 td { background-color: #F9F9F9; } + table.responsive tr.row2 td { background-color: #DCEBFE; } + table.responsive tr.row3 td { background-color: #DBDFE2; } + table.responsive tr.row4 td { background-color: #E4E8EB; } + table.responsive tr.col1 td { background-color: #DCEBFE; } + table.responsive tr.col2 td { background-color: #F9F9F9; } + table.responsive tr.row1a td { background-color: #F9F9F9; } + table.responsive tr.row1b td { background-color: #F6F6F6; } + table.responsive tr.row2a td { background-color: #E7EEF4; } + table.responsive tr.row2b td { background-color: #E3EBF2; } + + table.responsive td { + width: auto !important; + text-align: left !important; + padding: 4px; + margin-bottom: 1px; + } + + table.responsive td.empty { + display: none !important; + } + + table.responsive td > dfn { + display: inline-block !important; + } + + table.responsive td > dfn:after { + content: ':'; + padding-right: 5px; + } + + table.responsive.two-columns td { + width: 50% !important; + float: left; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + + table.responsive.two-columns td:nth-child(2n+1) { + clear: left; + } + + table.responsive span.rank-img { + float: none; + padding-right: 5px; + } + + table.responsive#memberlist td:first-child input[type="checkbox"] { + float: right; + } + + /* Specific tables */ + table.responsive.forums td.folder { + float: left; + width: 27px; + background: transparent; + } + .rtl table.responsive.forums td.folder { + float: right; + } + + table.responsive.forums td.forum-desc { + margin-left: 35px; + min-height: 27px; + background: transparent; + } + + .rtl table.responsive.forums td.forum-desc { + margin-left: 0; + margin-right: 35px; + } + + table.responsive td.actions { + clear: both; + text-align: right !important; + } + + .rtl table.responsive td.actions { + text-align: left !important; + } + + table.responsive.styles tr.responsive-style-row td:first-child { + padding-left: 4px !important; + padding-right: 4px !important; + } + + table.responsive.styles td:first-child > dfn, table.responsive td.actions > dfn { + display: none !important; + } + + .horizontal-palette td:nth-child(2n), .vertical-palette tr:nth-child(2n) { + display: none; + } + + .colour-palette a { + display: inline-block !important; + } +} + /* General form styles ----------------------------------------*/ fieldset { @@ -664,6 +1068,7 @@ fieldset { border-left: 1px solid #D7D7D7; background-color: #FFFFFF; position: relative; + border-radius: 3px; } .rtl fieldset { @@ -673,10 +1078,6 @@ fieldset { border-left: 1px solid #CCCCCC; } -* html fieldset { - padding: 0 10px 5px 10px; -} - fieldset p { font-size: 0.85em; } @@ -695,23 +1096,10 @@ legend { vertical-align: middle; } -* html legend { - margin: 0 0 -10px -7px; - line-height: 1em; - font-size: .85em; -} - -/* Holly hack, .rtl comes after html */ -* html .rtl legend { - margin: 0; - margin-right: -7px; -} - input, textarea { font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 0.90em; font-weight: normal; - cursor: text; vertical-align: middle; padding: 2px; color: #111111; @@ -742,11 +1130,14 @@ input.langvalue, textarea.langvalue { } optgroup, select { + background-color: #FAFAFA; + border: 1px solid #666666; font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 0.85em; font-weight: normal; font-style: normal; cursor: pointer; + padding: 1px; vertical-align: middle; width: auto; color: #000; @@ -854,7 +1245,7 @@ fieldset.display-options { border: none; background-color: transparent; text-align: center; - font-size: 0.75em; + font-size: 0.85em; } fieldset.display-options select, fieldset.display-options input, fieldset.display-options label { @@ -873,6 +1264,22 @@ select#full_folder_action { width: 95%; } +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + fieldset { + padding: 5px; + } + + fieldset.quick, p.quick { + float: none !important; + text-align: center; + } + + fieldset.display-options { + clear: both; + } +} + /* Definition list layout for forms Other general def. list properties defined in prosilver_main.css ---------------------------------------- */ @@ -959,6 +1366,10 @@ fieldset dt { border-left: 1px solid #CCCCCC; } +fieldset #color_palette_placeholder { + padding-top: 0; +} + fieldset dd { margin: 0 0 0 45%; padding: 0 0 0 5px; @@ -1004,6 +1415,55 @@ input:focus, textarea:focus { outline-style: none; } +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + fieldset dl { + margin-bottom: 5px; + padding-bottom: 5px; + border-bottom: 1px solid #e8e8e8; + } + + fieldset > dl:last-child, fieldset > form:last-child > dl:last-child { + border-bottom-width: 0; + margin-bottom: 0; + } + + fieldset dt, .rtl fieldset dt, fieldset dd, .rtl fieldset dd { + border-width: 0; + margin-left: 0; + margin-right: 0; + float: none; + width: auto; + } + + fieldset .responsive-columns dt { + float: left; + } + + .ltr fieldset dd { + padding-left: 20px; + } + + .rtl fieldset dd { + padding-right: 20px; + } + + select, dd select, dd input { + max-width: 300px; + } + + input[type="number"], dd input[type="number"] { + max-width: 70px; + } +} + +@media only screen and (max-width: 400px), only screen and (max-device-width: 400px) +{ + select, dd select, dd input { + max-width: 240px; + } +} + /* Submit button fieldset or paragraph ---------------------------------------- */ fieldset.submit-buttons { @@ -1030,6 +1490,13 @@ fieldset.submit-buttons legend { display: none; } +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + p.submit-buttons { + margin-top: 0; + } +} + /* Input field styles ---------------------------------------- */ @@ -1045,7 +1512,6 @@ textarea.full { width: 99%; } -* html input.full, * html textarea.full { width: 95%;} input.medium { width: 50%;} input.narrow { width: 25%;} input.tiny { width: 10%;} @@ -1054,7 +1520,7 @@ input.autowidth { width: auto !important;} /* Form button styles ---------------------------------------- */ -a.button1, input.button1, input.button3, +a.button1, input.button1, a.button2, input.button2 { width: auto !important; padding: 1px 3px 0 3px; @@ -1097,7 +1563,7 @@ input.disabled { } /* Focus states */ -input.button1:focus, input.button2:focus, input.button3:focus { +input.button1:focus, input.button2:focus { outline-style: none; } @@ -1109,8 +1575,10 @@ input.button1:focus, input.button2:focus, input.button3:focus { position: fixed; display: none; top: 150px; - left: 25%; - width: 50%; + left: 0; + right: 0; + width: 620px; + margin: 0 auto; z-index: 50; padding: 25px; padding: 0 25px 20px 25px; @@ -1154,6 +1622,8 @@ input.button1:focus, input.button2:focus, input.button3:focus { #darkenwrapper { display: none; + position: relative; + z-index: 44; } #darken { @@ -1164,16 +1634,52 @@ input.button1:focus, input.button2:focus, input.button3:focus { height: 100%; background-color: #000000; opacity: 0.5; + z-index: 45; +} + +@media only screen and (max-height: 500px), only screen and (max-device-width: 500px) +{ + .phpbb_alert { + top: 25px; + } +} + +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + .phpbb_alert { + width: auto; + margin: 0 25px; + } +} + +#loading_indicator { + background: #000000 url("../images/loading.gif") center center no-repeat; + border-radius: 5px; + display: none; + opacity: 0.8; + margin-top: -50px; + margin-left: -50px; + height: 50px; + width: 50px; + position: fixed; + left: 50%; + top: 50%; + z-index: 51; } /* Pagination ---------------------------------------- */ .pagination { + font-size: .85em; height: 1%; /* IE tweak (holly hack) */ width: auto; text-align: right; margin-top: 5px; +} + +.top-pagination { float: right; + margin: 15px 0 2px 0; } .rtl .pagination { @@ -1247,6 +1753,20 @@ li.pagination ul { border-color: #B4BAC0; } +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + .pagination, .rtl .pagination { + float: none; + text-align: center; + margin: 5px 0; + } + + .pagination li a, .pagination li span { + display: inline-block; + min-width: 10px; + } +} + /* Action Highlighting ---------------------------------------- */ .successbox, .errorbox { @@ -1272,8 +1792,6 @@ li.pagination ul { background-color: #BC2A4D; } -* html .errorbox, * html .successbox { height: 1%; } /* Pixel shift fix for IE */ - .successbox h3, .errorbox h3 { color: #FFFFFF; margin: 0 0 0.5em; @@ -1367,8 +1885,7 @@ li.pagination ul { visibility: hidden; }*/ -.clearfix, #tabs, .row, #content, fieldset dl, #page-body { - height: 1%; +.clearfix, .row, #content, fieldset dl, #page-body { overflow: hidden; } @@ -1422,6 +1939,15 @@ li.pagination ul { /* Permission interface ---------------------------------------- */ +.column1, .column2 { + width: 48%; + float: left; +} + +.ltr .column2, .rtl .column1 { + float: right; +} + fieldset.permissions legend { text-transform: none; } @@ -1619,60 +2145,15 @@ fieldset.permissions .padding { float: left; background-color: #CADCEB; width: 100%; + border-radius: 5px; + overflow: hidden; + padding: 5px 0; } .rtl .permissions-panel { float: right; } -.permissions-panel span.corners-top { - background-image: url("../images/corners_left2.gif"); -} - -.permissions-panel span.corners-top span { - background-image: url("../images/corners_right2.gif"); -} - -.permissions-panel span.corners-bottom { - background-image: url("../images/corners_left2.gif"); -} - -.permissions-panel span.corners-bottom span { - background-image: url("../images/corners_right2.gif"); -} - -.permissions-panel span.corners-top, .permissions-panel span.corners-bottom, -.permissions-panel span.corners-top span, .permissions-panel span.corners-bottom span { - font-size: 1px; - line-height: 1px; - display: block; - height: 5px; - background-repeat: no-repeat; -} - -.permissions-panel span.corners-top { - background-image: url("../images/corners_left2.gif"); - background-position: 0 0; - margin: 0 0; -} - -.permissions-panel span.corners-top span { - background-image: url("../images/corners_right2.gif"); - background-position: 100% 0; -} - -.permissions-panel span.corners-bottom { - background-image: url("../images/corners_left2.gif"); - background-position: 0 100%; - margin: 0 0; - clear: both; -} - -.permissions-panel span.corners-bottom span { - background-image: url("../images/corners_right2.gif"); - background-position: 100% 100%; -} - /* Permission table ---------------------------------------- */ .permissions-panel .tablewrap { @@ -1755,6 +2236,208 @@ fieldset.permissions .padding { padding: 0; } +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + .column1, .column2 { + float: none !important; + width: auto; + } + + .permissions-simple { + clear: both; + } + + .permissions-simple td, .permissions-simple dd { + width: auto !important; + margin-left: 0 !important; + margin-right: 0 !important; + } + + .permissions-simple dd { + margin-top: 5px; + } + + .permissions-panel .tablewrap { + margin: 0 5px; + } + + .permissions-category { + min-width: 0; + margin: 0 !important; + } + + .permissions-category a, .permissions-category a span.tabbg { + display: block; + float: none !important; + background: transparent none; + } + + .permissions-category a { + background: #d9e5ee; + margin: 5px 0; + padding: 0 !important; + border-radius: 3px; + text-decoration: underline; + } + + .permissions-category .activetab a { + background-color: #dd6900; + color: #fff; + } + + .permissions-category a span.tabbg { + color: inherit !important; + padding-top: 6px !important; + padding-bottom: 6px !important; + } + + .permissions-category .activetab span.colour { + border-color: #fff; + } +} + +/* Avatars gallery +---------------------------------------- */ +#gallery { + display: block; + margin: 0 -5px; + padding: 0; + overflow: hidden; +} + +#gallery li { + display: block; + float: left; + border: 1px solid #ccc; + border-radius: 2px; + background: #fff; + padding: 5px; + margin: 5px; +} + +#gallery li:hover { + background-color: #eee; +} + +#gallery li label { + display: block; + text-align: center; + padding: 0; +} + +/* Dropdown menu +----------------------------------------*/ +.dropdown { + position: absolute; + left: 0; + top: 22px; + z-index: 2; + border: 1px solid transparent; + border-radius: 5px; + padding: 9px 0 0; +} + +.dropdown-up .dropdown { + top: auto; + bottom: 18px; + padding: 0 0 9px; +} + +.dropdown-left .dropdown { + left: auto; + right: 0; +} + +.dropdown .pointer, .dropdown .pointer-inner { + position: absolute; + width: 0; + height: 0; + border-top-width: 0; + border-bottom: 10px solid transparent; + border-left: 10px dashed transparent; + border-right: 10px dashed transparent; + -webkit-transform: rotate(360deg); /* better anti-aliasing in webkit */ + display: block; +} + +.dropdown-up .pointer, .dropdown-up .pointer-inner { + border-bottom-width: 0; + border-top: 10px solid transparent; +} + +.dropdown .pointer { + right: auto; + left: 10px; + top: 0; + z-index: 3; +} + +.dropdown-up .pointer { + bottom: 0; + top: auto; +} + +.dropdown-left .dropdown .pointer { + left: auto; + right: 10px; +} + +.dropdown .pointer-inner { + top: auto; + bottom: -11px; + left: -10px; +} + +.dropdown-up .pointer-inner { + bottom: auto; + top: -11px; +} + +.dropdown .pointer { + border-color: #B9B9B9 transparent; +} + +.dropdown .pointer-inner { + border-color: #FFF transparent; +} + +.dropdown .dropdown-contents { + z-index: 2; + overflow: hidden; + overflow-y: auto; + background: #fff; + border: 1px solid #b9b9b9; + border-radius: 5px; + padding: 5px; + position: relative; + min-width: 40px; + max-height: 200px; + box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.2); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.dropdown-up .dropdown-contents { + box-shadow: 1px 0 5px rgba(0, 0, 0, 0.2); +} + +.dropdown li { + float: none; + margin: 0; + white-space: nowrap; + text-align: left; +} + +.wrap .dropdown li, .dropdown.wrap li { + white-space: normal; +} + +.dropdown li:before, .dropdown li:after { + display: none !important; +} + + /* Classes for additional tasks ---------------------------------------- */ @@ -1777,3 +2460,11 @@ fieldset.permissions .padding { color: #FFFFFF; font-size: 1.4em; } + +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + .responsive-hide { display: none !important; } + .responsive-show { display: block !important; } + .responsive-show-inline { display: inline !important; } + .responsive-show-inline-block { display: inline-block !important; } +} diff --git a/phpBB/adm/style/admin.js b/phpBB/adm/style/admin.js new file mode 100644 index 0000000000..7bda86e1e3 --- /dev/null +++ b/phpBB/adm/style/admin.js @@ -0,0 +1,250 @@ +/** +* phpBB3 ACP functions +*/ + +/** +* Parse document block +*/ +function parse_document(container) +{ + var test = document.createElement('div'), + oldBrowser = (typeof test.style.borderRadius == 'undefined'); + + delete test; + + /** + * Navigation + */ + container.find('#menu').each(function() { + var menu = $(this), + blocks = menu.children('.menu-block'); + + if (!blocks.length) { + return; + } + + // Set onclick event + blocks.children('a.header').click(function() { + var parent = $(this).parent(); + if (!parent.hasClass('active')) { + parent.siblings().removeClass('active'); + } + parent.toggleClass('active'); + }); + + // Set active menu + menu.find('#activemenu').parents('.menu-block').addClass('active'); + + // Check if there is active menu + if (!blocks.filter('.active').length) { + blocks.filter(':first').addClass('active'); + } + }); + + /** + * Responsive tables + */ + container.find('table').not('.not-responsive').each(function() { + var $this = $(this), + th = $this.find('thead > tr > th'), + columns = th.length, + headers = [], + totalHeaders = 0, + i, headersLength; + + // Find columns + $this.find('colgroup:first').children().each(function(i) { + var column = $(this); + $this.find('td:nth-child(' + (i + 1) + ')').addClass(column.prop('className')); + }); + + // Styles table + if ($this.hasClass('styles')) { + $this.find('td:first-child[style]').each(function() { + var style = $(this).attr('style'); + if (style.length) { + $(this).parent('tr').attr('style', style.toLowerCase().replace('padding', 'margin')).addClass('responsive-style-row'); + } + }); + } + + // Find each header + if (!$this.data('no-responsive-header')) + { + th.each(function(column) { + var cell = $(this), + colspan = parseInt(cell.attr('colspan')), + dfn = cell.attr('data-dfn'), + text = dfn ? dfn : cell.text().trim(); + + if (text == ' ') text = ''; + colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan; + + for (i=0; i<colspan; i++) { + headers.push(text); + } + totalHeaders ++; + + if (dfn && !column) { + $this.addClass('show-header'); + } + }); + } + + headersLength = headers.length; + + // Add header text to each cell as <dfn> + $this.addClass('responsive'); + + if (totalHeaders < 2) { + $this.addClass('show-header'); + return; + } + + $this.find('tbody > tr').each(function() { + var row = $(this), + cells = row.children('td'), + column = 0; + + if (cells.length == 1) { + row.addClass('big-column'); + return; + } + + cells.each(function() { + var cell = $(this), + colspan = parseInt(cell.attr('colspan')), + text = cell.text().trim(); + + if (headersLength <= column) { + return; + } + + if ((text.length && text !== '-') || cell.children().length) { + if (headers[column] != '') { + cell.prepend('<dfn style="display: none;">' + headers[column] + '</dfn>'); + } + } + else { + cell.addClass('empty'); + } + + colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan; + column += colspan; + }); + }); + + // Remove <dfn> in disabled extensions list + $this.find('tr.ext_disabled > .empty:nth-child(2) + .empty').siblings(':first-child').children('dfn').remove(); + }); + + /** + * Hide empty responsive tables + */ + container.find('table.responsive > tbody').each(function() { + var items = $(this).children('tr'); + if (items.length == 0) + { + $(this).parent('table:first').addClass('responsive-hide'); + } + }); + + /** + * Fieldsets with empty <span> + */ + container.find('fieldset dt > span:last-child').each(function() { + var $this = $(this); + if ($this.html() == ' ') { + $this.addClass('responsive-hide'); + } + + }); + + /** + * Responsive tabs + */ + container.find('#tabs').not('[data-skip-responsive]').each(function() { + var $this = $(this), + $body = $('body'), + ul = $this.children(), + tabs = ul.children().not('[data-skip-responsive]'), + links = tabs.children('a'), + item = ul.append('<li class="responsive-tab" style="display:none;"><a href="javascript:void(0);" class="responsive-tab-link"><span> </span></a><div class="dropdown tab-dropdown" style="display: none;"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>').find('li.responsive-tab'), + menu = item.find('.dropdown-contents'), + maxHeight = 0, + lastWidth = false, + responsive = false; + + links.each(function() { + var link = $(this); + maxHeight = Math.max(maxHeight, Math.max(link.outerHeight(true), link.parent().outerHeight(true))); + }) + + function check() { + var width = $body.width(), + height = $this.height(); + + if (arguments.length == 0 && (!responsive || width <= lastWidth) && height <= maxHeight) { + return; + } + + tabs.show(); + item.hide(); + + lastWidth = width; + height = $this.height(); + if (height <= maxHeight) { + responsive = false; + if (item.hasClass('dropdown-visible')) { + phpbb.toggleDropdown.call(item.find('a.responsive-tab-link').get(0)); + } + return; + } + + responsive = true; + item.show(); + menu.html(''); + + var availableTabs = tabs.filter(':not(.activetab, .responsive-tab)'), + total = availableTabs.length, + i, tab; + + for (i = total - 1; i >= 0; i --) { + tab = availableTabs.eq(i); + menu.prepend(tab.clone(true)); + tab.hide(); + if ($this.height() <= maxHeight) { + menu.find('a').click(function() { check(true); }); + return; + } + } + menu.find('a').click(function() { check(true); }); + } + + phpbb.registerDropdown(item.find('a.responsive-tab-link'), item.find('.dropdown'), {visibleClass: 'activetab', verticalDirection: 'down'}); + + check(true); + $(window).resize(check); + }); +} + +/** +* Run onload functions +*/ +(function($) { + $(document).ready(function() { + // Swap .nojs and .hasjs + $('body.nojs').toggleClass('nojs hasjs'); + + // Focus forms + $('form[data-focus]:first').each(function() { + $('#' + this.getAttribute('data-focus')).focus(); + }); + + parse_document($('body')); + + // Hide configlist and success message in send statistics page + phpbb.toggleDisplay('configlist', -1); + phpbb.toggleDisplay('questionnaire-thanks', -1); + }); +})(jQuery); diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index efb0639f1b..959580d6c2 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -2,105 +2,34 @@ "use strict"; -var imgTemplates = { - up: $('.template-up-img'), - upDisabled: $('.template-up-img-disabled'), - down: $('.template-down-img'), - downDisabled: $('.template-down-img-disabled') -}; - /** * The following callbacks are for reording items. row_down * is triggered when an item is moved down, and row_up is triggered when * an item is moved up. It moves the row up or down, and deactivates / * activates any up / down icons that require it (the ones at the top or bottom). */ -phpbb.addAjaxCallback('row_down', function() { +phpbb.addAjaxCallback('row_down', function(res) { + if (typeof res.success === 'undefined' || !res.success) { + return; + } + var el = $(this), tr = el.parents('tr'), trSwap = tr.next(); - /* - * If the element was the first one, we have to: - * - Add the up-link to the row we moved - * - Remove the up-link on the next row - */ - if (tr.is(':first-child')) { - var upImg = imgTemplates.up.clone().attr('href', tr.attr('data-up')); - tr.find('.up').html(upImg); - - phpbb.ajaxify({ - selector: tr.find('.up').children('a'), - callback: 'row_up', - overlay: false - }); - - trSwap.find('.up').html(imgTemplates.upDisabled.clone()); - } - tr.insertAfter(trSwap); +}); - /* - * As well as: - * - Remove the down-link on the moved row, if it is now the last row - * - Add the down-link to the next row, if it was the last row - */ - if (tr.is(':last-child')) { - tr.find('.down').html(imgTemplates.downDisabled.clone()); - - var downImg = imgTemplates.down.clone().attr('href', trSwap.attr('data-down')); - trSwap.find('.down').html(downImg); - - phpbb.ajaxify({ - selector: trSwap.find('.down').children('a'), - callback: 'row_down', - overlay: false - }); +phpbb.addAjaxCallback('row_up', function(res) { + if (typeof res.success === 'undefined' || !res.success) { + return; } -}); -phpbb.addAjaxCallback('row_up', function() { var el = $(this), tr = el.parents('tr'), trSwap = tr.prev(); - /* - * If the element was the last one, we have to: - * - Add the down-link to the row we moved - * - Remove the down-link on the next row - */ - if (tr.is(':last-child')) { - var downImg = imgTemplates.down.clone().attr('href', tr.attr('data-down')); - tr.find('.down').html(downImg); - - phpbb.ajaxify({ - selector: tr.find('.down').children('a'), - callback: 'row_down', - overlay: false - }); - - trSwap.find('.down').html(imgTemplates.downDisabled.clone()); - } - tr.insertBefore(trSwap); - - /* - * As well as: - * - Remove the up-link on the moved row, if it is now the first row - * - Add the up-link to the previous row, if it was the first row - */ - if (tr.is(':first-child')) { - tr.find('.up').html(imgTemplates.upDisabled.clone()); - - var upImg = imgTemplates.up.clone().attr('href', trSwap.attr('data-up')); - trSwap.find('.up').html(upImg); - - phpbb.ajaxify({ - selector: trSwap.find('.up').children('a'), - callback: 'row_up', - overlay: false - }); - } }); /** diff --git a/phpBB/adm/style/captcha_qa_acp.html b/phpBB/adm/style/captcha_qa_acp.html index 99f3f24f70..6235f9a104 100644 --- a/phpBB/adm/style/captcha_qa_acp.html +++ b/phpBB/adm/style/captcha_qa_acp.html @@ -14,7 +14,7 @@ <fieldset class="tabulated"> <legend>{L_QUESTIONS}</legend> - <table cellspacing="1"> + <table class="table1 zebra-table"> <thead> <tr> <th colspan="3">{L_QUESTIONS}</th> @@ -27,14 +27,12 @@ </thead> <tbody> <!-- BEGIN questions --> - - <!-- IF questions.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> - + <tr> <td style="text-align: left;">{questions.QUESTION_TEXT}</td> <td style="text-align: center;">{questions.QUESTION_LANG}</td> <td style="text-align: center;"><a href="{questions.U_EDIT}">{ICON_EDIT}</a> <a href="{questions.U_DELETE}">{ICON_DELETE}</a></td> - </tr> - <!-- END questions --> + </tr> + <!-- END questions --> </tbody> </table> <fieldset class="quick"> diff --git a/phpBB/adm/style/colour_swatch.html b/phpBB/adm/style/colour_swatch.html deleted file mode 100644 index e731620bd3..0000000000 --- a/phpBB/adm/style/colour_swatch.html +++ /dev/null @@ -1,75 +0,0 @@ -<!DOCTYPE html> -<html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> -<head> -<meta charset="utf-8"> -<title>{L_COLOUR_SWATCH}</title> - -<style type="text/css"> -/* <![CDATA[ */ - body { - background-color: #404040; - color: #fff; - } - - td { - border: solid 1px #333; - } - - .over { - border-color: white; - } - - .out { - border-color: #333333; - } - - img { - border: 0; - } -/* ]]> */ -</style> -</head> - -<body> - -<script type="text/javascript"> -// <![CDATA[ - var r = 0, g = 0, b = 0; - - var numberList = new Array(6); - numberList[0] = '00'; - numberList[1] = '33'; - numberList[2] = '66'; - numberList[3] = '99'; - numberList[4] = 'CC'; - numberList[5] = 'FF'; - - document.writeln('<table cellspacing="0" cellpadding="0" border="0">'); - - for (r = 0; r < 6; r++) - { - document.writeln('<tr>'); - - for (g = 0; g < 6; g++) - { - for (b = 0; b < 6; b++) - { - color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); - document.write('<td style="background-color: #' + color + ';" onmouseover="this.className=\'over\'" onmouseout="this.className=\'out\'">'); - document.write('<a href="#" onclick="cell(\'' + color + '\'); return false;"><img src="{T_IMAGES_PATH}spacer.gif" width="15" height="12" alt="#' + color + '" title="#' + color + '" \/><\/a>'); - document.writeln('<\/td>'); - } - } - document.writeln('<\/tr>'); - } - document.writeln('<\/table>'); - - function cell(color) - { - opener.document.forms["{OPENER}"].{NAME}.value = color; - } -// ]]> -</script> - -</body> -</html> diff --git a/phpBB/adm/style/custom_profile_fields.html b/phpBB/adm/style/custom_profile_fields.html deleted file mode 100644 index 982356bfa7..0000000000 --- a/phpBB/adm/style/custom_profile_fields.html +++ /dev/null @@ -1,32 +0,0 @@ - -<!-- BEGIN dropdown --> - <select name="{dropdown.FIELD_IDENT}" id="{dropdown.FIELD_IDENT}"> - <!-- BEGIN options --><option value="{dropdown.options.OPTION_ID}"{dropdown.options.SELECTED}>{dropdown.options.VALUE}</option><!-- END options --> - </select> -<!-- END dropdown --> - -<!-- BEGIN text --> - <textarea name="{text.FIELD_IDENT}" id="{text.FIELD_IDENT}" rows="{text.FIELD_ROWS}" cols="{text.FIELD_COLS}">{text.FIELD_VALUE}</textarea> -<!-- END text --> - -<!-- BEGIN string --> - <input type="text" name="{string.FIELD_IDENT}" id="{string.FIELD_IDENT}" size="{string.FIELD_LENGTH}" maxlength="{string.FIELD_MAXLEN}" value="{string.FIELD_VALUE}" /> -<!-- END string --> - -<!-- BEGIN bool --> - <!-- IF bool.FIELD_LENGTH eq 1 --> - <!-- BEGIN options --><label for="{bool.FIELD_IDENT}_{bool.options.OPTION_ID}"><input type="radio" class="radio" name="{bool.FIELD_IDENT}" id="{bool.FIELD_IDENT}_{bool.options.OPTION_ID}" value="{bool.options.OPTION_ID}"{bool.options.CHECKED} /> {bool.options.VALUE}</label> <!-- END options --> - <!-- ELSE --> - <input type="checkbox" class="radio" name="{bool.FIELD_IDENT}" id="{bool.FIELD_IDENT}" value="1"<!-- IF bool.FIELD_VALUE --> checked="checked"<!-- ENDIF --> /> - <!-- ENDIF --> -<!-- END bool --> - -<!-- BEGIN int --> - <input type="text" name="{int.FIELD_IDENT}" id="{int.FIELD_IDENT}" size="{int.FIELD_LENGTH}" value="{int.FIELD_VALUE}" /> -<!-- END int --> - -<!-- BEGIN date --> - <span>{L_DAY}{L_COLON}</span> <select name="{date.FIELD_IDENT}_day" id="{date.FIELD_IDENT}_day">{date.S_DAY_OPTIONS}</select> - <span>{L_MONTH}{L_COLON}</span> <select name="{date.FIELD_IDENT}_month" id="{date.FIELD_IDENT}_month">{date.S_MONTH_OPTIONS}</select> - <span>{L_YEAR}{L_COLON}</span> <select name="{date.FIELD_IDENT}_year" id="{date.FIELD_IDENT}_year">{date.S_YEAR_OPTIONS}</select> -<!-- END date --> diff --git a/phpBB/adm/style/editor.js b/phpBB/adm/style/editor.js deleted file mode 100644 index 9938ff5d0b..0000000000 --- a/phpBB/adm/style/editor.js +++ /dev/null @@ -1,336 +0,0 @@ -/** -* bbCode control by subBlue design [ www.subBlue.com ] -* Includes unixsafe colour palette selector by SHS` -*/ - -// Startup variables -var imageTag = false; -var theSelection = false; - -// Check for Browser & Platform for PC & IE specific bits -// More details from: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html -var clientPC = navigator.userAgent.toLowerCase(); // Get client info -var clientVer = parseInt(navigator.appVersion, 10); // Get browser version - -var is_ie = ((clientPC.indexOf('msie') !== -1) && (clientPC.indexOf('opera') === -1)); -var is_win = ((clientPC.indexOf('win') !== -1) || (clientPC.indexOf('16bit') !== -1)); -var baseHeight; - -/** -* Shows the help messages in the helpline window -*/ -function helpline(help) { - document.forms[form_name].helpbox.value = help_line[help]; -} - -/** -* Fix a bug involving the TextRange object. From -* http://www.frostjedi.com/terra/scripts/demo/caretBug.html -*/ -function initInsertions() { - var doc; - - if (document.forms[form_name]) { - doc = document; - } else { - doc = opener.document; - } - - var textarea = doc.forms[form_name].elements[text_name]; - - if (is_ie && typeof(baseHeight) !== 'number') { - textarea.focus(); - baseHeight = doc.selection.createRange().duplicate().boundingHeight; - - if (!document.forms[form_name]) { - document.body.focus(); - } - } -} - -/** -* bbstyle -*/ -function bbstyle(bbnumber) { - if (bbnumber !== -1) { - bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]); - } else { - insert_text('[*]'); - document.forms[form_name].elements[text_name].focus(); - } -} - -/** -* Apply bbcodes -*/ -function bbfontstyle(bbopen, bbclose) { - theSelection = false; - - var textarea = document.forms[form_name].elements[text_name]; - - textarea.focus(); - - if ((clientVer >= 4) && is_ie && is_win) { - // Get text selection - theSelection = document.selection.createRange().text; - - if (theSelection) { - // Add tags around selection - document.selection.createRange().text = bbopen + theSelection + bbclose; - document.forms[form_name].elements[text_name].focus(); - theSelection = ''; - return; - } - } else if (document.forms[form_name].elements[text_name].selectionEnd - && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) { - mozWrap(document.forms[form_name].elements[text_name], bbopen, bbclose); - document.forms[form_name].elements[text_name].focus(); - theSelection = ''; - return; - } - - //The new position for the cursor after adding the bbcode - var caret_pos = getCaretPosition(textarea).start; - var new_pos = caret_pos + bbopen.length; - - // Open tag - insert_text(bbopen + bbclose); - - // Center the cursor when we don't have a selection - // Gecko and proper browsers - if (!isNaN(textarea.selectionStart)) { - textarea.selectionStart = new_pos; - textarea.selectionEnd = new_pos; - } - // IE - else if (document.selection) { - var range = textarea.createTextRange(); - range.move("character", new_pos); - range.select(); - storeCaret(textarea); - } - - textarea.focus(); - return; -} - -/** -* Insert text at position -*/ -function insert_text(text, spaces, popup) { - var textarea; - - if (!popup) { - textarea = document.forms[form_name].elements[text_name]; - } else { - textarea = opener.document.forms[form_name].elements[text_name]; - } - - if (spaces) { - text = ' ' + text + ' '; - } - - if (!isNaN(textarea.selectionStart)) { - var sel_start = textarea.selectionStart; - var sel_end = textarea.selectionEnd; - - mozWrap(textarea, text, ''); - textarea.selectionStart = sel_start + text.length; - textarea.selectionEnd = sel_end + text.length; - } else if (textarea.createTextRange && textarea.caretPos) { - if (baseHeight !== textarea.caretPos.boundingHeight) { - textarea.focus(); - storeCaret(textarea); - } - - var caret_pos = textarea.caretPos; - caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; - } else { - textarea.value = textarea.value + text; - } - - if (!popup) { - textarea.focus(); - } -} - -/** -* Add inline attachment at position -*/ -function attach_inline(index, filename) { - insert_text('[attachment=' + index + ']' + filename + '[/attachment]'); - document.forms[form_name].elements[text_name].focus(); -} - -/** -* Add quote text to message -*/ -function addquote(post_id, username) -{ - var message_name = 'message_' + post_id; - var theSelection = ''; - var divarea = false; - - if (document.all) { - divarea = document.all[message_name]; - } else { - divarea = document.getElementById(message_name); - } - - // Get text selection - not only the post content :( - if (window.getSelection) { - theSelection = window.getSelection().toString(); - } else if (document.getSelection) { - theSelection = document.getSelection(); - } else if (document.selection) { - theSelection = document.selection.createRange().text; - } - - if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) { - if (divarea.innerHTML) { - theSelection = divarea.innerHTML.replace(/<br>/ig, '\n'); - theSelection = theSelection.replace(/<br\/>/ig, '\n'); - theSelection = theSelection.replace(/<\;/ig, '<'); - theSelection = theSelection.replace(/>\;/ig, '>'); - theSelection = theSelection.replace(/&\;/ig, '&'); - theSelection = theSelection.replace(/ \;/ig, ' '); - } else if (document.all) { - theSelection = divarea.innerText; - } else if (divarea.textContent) { - theSelection = divarea.textContent; - } else if (divarea.firstChild.nodeValue) { - theSelection = divarea.firstChild.nodeValue; - } - } - - if (theSelection) { - insert_text('[quote="' + username + '"]' + theSelection + '[/quote]'); - } - - return; -} - -/** -* From http://www.massless.org/mozedit/ -*/ -function mozWrap(txtarea, open, close) { - var selLength = (typeof(txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength; - var selStart = txtarea.selectionStart; - var selEnd = txtarea.selectionEnd; - var scrollTop = txtarea.scrollTop; - - if (selEnd === 1 || selEnd === 2) { - selEnd = selLength; - } - - var s1 = (txtarea.value).substring(0,selStart); - var s2 = (txtarea.value).substring(selStart, selEnd); - var s3 = (txtarea.value).substring(selEnd, selLength); - - txtarea.value = s1 + open + s2 + close + s3; - txtarea.selectionStart = selStart + open.length; - txtarea.selectionEnd = selEnd + open.length; - txtarea.focus(); - txtarea.scrollTop = scrollTop; - - return; -} - -/** -* Insert at Caret position. Code from -* http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130 -*/ -function storeCaret(textEl) { - if (textEl.createTextRange) { - textEl.caretPos = document.selection.createRange().duplicate(); - } -} - -/** -* Color pallette -*/ -function colorPalette(dir, width, height) { - var r = 0, g = 0, b = 0; - var numberList = new Array(6); - var color = ''; - - numberList[0] = '00'; - numberList[1] = '40'; - numberList[2] = '80'; - numberList[3] = 'BF'; - numberList[4] = 'FF'; - - document.writeln('<table class="type2">'); - - for (r = 0; r < 5; r++) { - if (dir === 'h') { - document.writeln('<tr>'); - } - - for (g = 0; g < 5; g++) { - if (dir === 'v') { - document.writeln('<tr>'); - } - - for (b = 0; b < 5; b++) { - color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); - document.write('<td bgcolor="#' + color + '" style="width: ' + width + 'px; height: ' + height + 'px;">'); - document.write('<a href="#" onclick="bbfontstyle(\'[color=#' + color + ']\', \'[/color]\'); return false;"><img src="images/spacer.gif" width="' + width + '" height="' + height + '" alt="#' + color + '" title="#' + color + '" /></a>'); - document.writeln('</td>'); - } - - if (dir === 'v') { - document.writeln('</tr>'); - } - } - - if (dir === 'h') { - document.writeln('</tr>'); - } - } - document.writeln('</table>'); -} - -/** -* Caret Position object -*/ -function caretPosition() { - var start = null; - var end = null; -} - -/** -* Get the caret position in an textarea -*/ -function getCaretPosition(txtarea) { - var caretPos = new caretPosition(); - - // simple Gecko/Opera way - if (txtarea.selectionStart || txtarea.selectionStart === 0) { - caretPos.start = txtarea.selectionStart; - caretPos.end = txtarea.selectionEnd; - } - // dirty and slow IE way - else if (document.selection) { - // get current selection - var range = document.selection.createRange(); - - // a new selection of the whole textarea - var range_all = document.body.createTextRange(); - range_all.moveToElementText(txtarea); - - // calculate selection start point by moving beginning of range_all to beginning of range - var sel_start; - for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) { - range_all.moveStart('character', 1); - } - - txtarea.sel_start = sel_start; - - // we ignore the end value for IE, this is already dirty enough and we don't need it - caretPos.start = txtarea.sel_start; - caretPos.end = txtarea.sel_start; - } - - return caretPos; -} diff --git a/phpBB/adm/style/install_convert.html b/phpBB/adm/style/install_convert.html index 5fec8c4789..7e22404f56 100644 --- a/phpBB/adm/style/install_convert.html +++ b/phpBB/adm/style/install_convert.html @@ -22,7 +22,7 @@ <!-- ENDIF --> <!-- IF S_LIST --> - <table cellspacing="1"> + <table class="table1"> <caption>{L_AVAILABLE_CONVERTORS}</caption> <col class="col1" /><col class="col2" /><col class="col1" /><col class="col2" /> <thead> diff --git a/phpBB/adm/style/install_footer.html b/phpBB/adm/style/install_footer.html index 73c3f5a6b9..822ab76313 100644 --- a/phpBB/adm/style/install_footer.html +++ b/phpBB/adm/style/install_footer.html @@ -1,10 +1,7 @@ - - </div> + </div> + </div><!-- /#main --> </div> - <span class="corners-bottom"><span></span></span> - <div class="clear"></div> - </div> - </div> + </div><!-- /#acp --> </div> <div id="page-footer"> @@ -13,7 +10,10 @@ </div> <script type="text/javascript" src="{T_JQUERY_LINK}"></script> -<!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> +<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> +<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script> +<!-- INCLUDEJS admin.js --> +{$SCRIPTS} </body> </html> diff --git a/phpBB/adm/style/install_header.html b/phpBB/adm/style/install_header.html index 5631b83e17..a8f7009e4b 100644 --- a/phpBB/adm/style/install_header.html +++ b/phpBB/adm/style/install_header.html @@ -2,45 +2,20 @@ <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> <meta charset="utf-8"> +<meta name="viewport" content="width=device-width" /> <!-- IF META -->{META}<!-- ENDIF --> <title>{PAGE_TITLE}</title> <link href="{T_TEMPLATE_PATH}/admin.css" rel="stylesheet" type="text/css" media="screen" /> - -<script type="text/javascript"> -// <![CDATA[ - -/** -* Set display of page element -* s[-1,0,1] = hide,toggle display,show -*/ -function dE(n, s, type) -{ - if (!type) - { - type = 'block'; - } - - var e = document.getElementById(n); - if (!s) - { - s = (e.style.display == '' || e.style.display == 'block') ? -1 : 1; - } - e.style.display = (s == 1) ? type : 'none'; -} - -// ]]> -</script> - </head> -<body class="{S_CONTENT_DIRECTION}"> +<body class="{S_CONTENT_DIRECTION} nojs"> <div id="wrap"> <div id="page-header"> <h1>{L_INSTALL_PANEL}</h1> <p id="skip"><a href="#acp">{L_SKIP}</a></p> <!-- IF S_LANG_SELECT --> - <form method="post" action=""> + <form method="post" action="#"> <fieldset class="nobg"> <label for="language">{L_SELECT_LANG}{L_COLON}</label> {S_LANG_SELECT} @@ -54,16 +29,15 @@ function dE(n, s, type) <div id="tabs"> <ul> <!-- BEGIN t_block1 --> - <li<!-- IF t_block1.S_SELECTED --> id="activetab"<!-- ENDIF -->><a href="{t_block1.U_TITLE}"><span>{t_block1.L_TITLE}</span></a></li> + <li<!-- IF t_block1.S_SELECTED --> class="activetab"<!-- ENDIF -->><a href="{t_block1.U_TITLE}"><span>{t_block1.L_TITLE}</span></a></li> <!-- END t_block1 --> </ul> </div> <div id="acp"> - <div class="panel"> - <span class="corners-top"><span></span></span> <div id="content"> <div id="menu"> + <div class="menu-block no-header"> <ul> <!-- BEGIN l_block1 --> <li<!-- IF l_block1.S_SELECTED --> id="activemenu"<!-- ENDIF -->><a href="{l_block1.U_TITLE}"><span>{l_block1.L_TITLE}</span></a></li> @@ -72,6 +46,8 @@ function dE(n, s, type) <li<!-- IF l_block2.S_SELECTED --> id="activemenu"<!-- ENDIF -->><span<!-- IF l_block2.S_COMPLETE --> class="completed"<!-- ENDIF -->>{l_block2.L_TITLE}</span></li> <!-- END l_block2 --> </ul> + </div> </div> <div id="main" class="install-body"> + <div class="main"> diff --git a/phpBB/adm/style/install_update.html b/phpBB/adm/style/install_update.html index 57e2c8ffea..f0df138641 100644 --- a/phpBB/adm/style/install_update.html +++ b/phpBB/adm/style/install_update.html @@ -224,7 +224,7 @@ <!-- IF .not_modified --> <h2>{L_FILES_NOT_MODIFIED}</h2> - <div style="float: {S_CONTENT_FLOW_END};">» <a href="#" onclick="dE('not_modified', 0); return false;">{L_TOGGLE_DISPLAY}</a></div> + <div style="float: {S_CONTENT_FLOW_END};">» <a href="#" onclick="phpbb.toggleDisplay('not_modified', 0); return false;">{L_TOGGLE_DISPLAY}</a></div> <p>{L_FILES_NOT_MODIFIED_EXPLAIN}</p> <fieldset id="not_modified" style="display: none;"> @@ -395,7 +395,7 @@ <p>{L_MAPPING_FILE_STRUCTURE}</p> - <table cellspacing="1"> + <table class="table1"> <col class="row1" /><col class="row2" /><col class="row1" /> <thead> <tr> diff --git a/phpBB/adm/style/install_update_diff.html b/phpBB/adm/style/install_update_diff.html index 1f30fe4d13..150ef37e0e 100644 --- a/phpBB/adm/style/install_update_diff.html +++ b/phpBB/adm/style/install_update_diff.html @@ -2,6 +2,7 @@ <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> <meta charset="utf-8"> +<meta name="viewport" content="width=device-width" /> <!-- IF META -->{META}<!-- ENDIF --> <title>{PAGE_TITLE}</title> @@ -33,7 +34,7 @@ window.onresize = resize_panel; <style type="text/css"> /* <![CDATA[ */ -#main { +#main, .rtl #main { font-size: 1em; line-height: 0.7em; margin: 0; @@ -43,6 +44,7 @@ window.onresize = resize_panel; #diff_content { padding: 30px 10px 10px; + overflow: hidden; } <!-- IF DIFF_MODE neq 'side_by_side' and DIFF_MODE neq 'raw' --> @@ -221,7 +223,7 @@ table.hrdiff caption span { <!-- ENDIF --> <!-- IF not S_DIFF_NEW_FILE --> <p id="skip"><a href="#acp">{L_SKIP}</a></p> - <form method="post" action=""> + <form method="post" action="#"> <fieldset class="quick"> <label for="diff_mode">{L_SELECT_DIFF_MODE}{L_COLON}</label> <select name="diff_mode" id="diff_mode">{S_DIFF_MODE_OPTIONS}</select> @@ -238,15 +240,13 @@ table.hrdiff caption span { <div id="page-body"> <div id="acp"> - <div class="panel" id="codepanel"> - <span class="corners-top"><span></span></span> + <div id="codepanel"> <div id="diff_content"> <div id="main"> {DIFF_CONTENT} </div> </div> - <span class="corners-bottom"><span></span></span> - </div> + </div> </div> </div> diff --git a/phpBB/adm/style/overall_footer.html b/phpBB/adm/style/overall_footer.html index 9202cec06b..8810414fc2 100644 --- a/phpBB/adm/style/overall_footer.html +++ b/phpBB/adm/style/overall_footer.html @@ -1,10 +1,7 @@ - - </div> + </div> + </div><!-- /#main --> </div> - <span class="corners-bottom"><span></span></span> - <div class="clear"></div> - </div> - </div> + </div><!-- /#acp --> </div> <div id="page-footer"> @@ -20,8 +17,8 @@ <div id="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}" data-ajax-error-text-abort="{L_AJAX_ERROR_TEXT_ABORT}" data-ajax-error-text-timeout="{L_AJAX_ERROR_TEXT_TIMEOUT}" data-ajax-error-text-parsererror="{L_AJAX_ERROR_TEXT_PARSERERROR}"> <div id="darken"> </div> - <div class="jalert" id="loadingalert"><h3>{L_LOADING}</h3><p>{L_PLEASE_WAIT}</p></div> </div> + <div id="loading_indicator"></div> <div id="phpbb_alert" class="phpbb_alert" data-l-err="{L_ERROR}" data-l-timeout-processing-req="{L_TIMEOUT_PROCESSING_REQ}"> <a href="#" class="alert_close"></a> @@ -35,12 +32,13 @@ </div> <script type="text/javascript" src="{T_JQUERY_LINK}"></script> -<!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> +<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> <script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script> <!-- INCLUDEJS ajax.js --> -{$SCRIPTS} +<!-- INCLUDEJS admin.js --> <!-- EVENT acp_overall_footer_after --> +{$SCRIPTS} </body> </html> diff --git a/phpBB/adm/style/overall_header.html b/phpBB/adm/style/overall_header.html index 3a9b6db2a3..25a82a5faa 100644 --- a/phpBB/adm/style/overall_header.html +++ b/phpBB/adm/style/overall_header.html @@ -2,6 +2,7 @@ <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> <meta charset="utf-8"> +<meta name="viewport" content="width=device-width" /> <!-- IF META -->{META}<!-- ENDIF --> <title>{PAGE_TITLE}</title> @@ -10,13 +11,10 @@ <script type="text/javascript"> // <![CDATA[ var jump_page = '{LA_JUMP_PAGE}{L_COLON}'; -var on_page = '{ON_PAGE}'; +var on_page = '{CURRENT_PAGE}'; var per_page = '{PER_PAGE}'; var base_url = '{BASE_URL|e('js')}'; -var menu_state = 'shown'; - - /** * Jump to page */ @@ -38,25 +36,6 @@ function jumpto() } /** -* Set display of page element -* s[-1,0,1] = hide,toggle display,show -*/ -function dE(n, s, type) -{ - if (!type) - { - type = 'block'; - } - - var e = document.getElementById(n); - if (!s) - { - s = (e.style.display == '') ? -1 : 1; - } - e.style.display = (s == 1) ? type : 'none'; -} - -/** * Mark/unmark checkboxes * id = ID of parent container, name = name prefix, state = state [true/false] */ @@ -103,62 +82,18 @@ function popup(url, width, height, name) return false; } -/** -* Hiding/Showing the side menu -*/ -function switch_menu() -{ - var menu = document.getElementById('menu'); - var main = document.getElementById('main'); - var toggle = document.getElementById('toggle'); - var handle = document.getElementById('toggle-handle'); - - switch (menu_state) - { - // hide - case 'shown': - main.style.width = '93%'; - menu_state = 'hidden'; - menu.style.display = 'none'; - toggle.style.width = '20px'; - handle.style.backgroundImage = 'url(images/toggle.gif)'; - handle.style.backgroundRepeat = 'no-repeat'; - - <!-- IF S_CONTENT_DIRECTION eq 'rtl' --> - handle.style.backgroundPosition = '0% 50%'; - toggle.style.left = '96%'; - <!-- ELSE --> - handle.style.backgroundPosition = '100% 50%'; - toggle.style.left = '0'; - <!-- ENDIF --> - break; - - // show - case 'hidden': - main.style.width = '76%'; - menu_state = 'shown'; - menu.style.display = 'block'; - toggle.style.width = '5%'; - handle.style.backgroundImage = 'url(images/toggle.gif)'; - handle.style.backgroundRepeat = 'no-repeat'; - - <!-- IF S_CONTENT_DIRECTION eq 'rtl' --> - handle.style.backgroundPosition = '100% 50%'; - toggle.style.left = '75%'; - <!-- ELSE --> - handle.style.backgroundPosition = '0% 50%'; - toggle.style.left = '15%'; - <!-- ENDIF --> - break; - } -} - // ]]> </script> + <!-- EVENT acp_overall_header_head_append --> + +{$STYLESHEETS} + </head> -<body class="{S_CONTENT_DIRECTION}"> +<body class="{S_CONTENT_DIRECTION} {BODY_CLASS} nojs"> + +<!-- EVENT acp_overall_header_body_before --> <div id="wrap"> <div id="page-header"> @@ -171,29 +106,25 @@ function switch_menu() <div id="tabs"> <ul> <!-- BEGIN t_block1 --> - <li<!-- IF t_block1.S_SELECTED --> id="activetab"<!-- ENDIF -->><a href="{t_block1.U_TITLE}"><span>{t_block1.L_TITLE}</span></a></li> + <li<!-- IF t_block1.S_SELECTED --> class="activetab"<!-- ENDIF -->><a href="{t_block1.U_TITLE}"><span>{t_block1.L_TITLE}</span></a></li> <!-- END t_block1 --> </ul> </div> <div id="acp"> - <div class="panel"> - <span class="corners-top"><span></span></span> <div id="content"> - <!-- IF not S_USER_NOTICE --> - <div id="toggle"> - <a id="toggle-handle" accesskey="m" title="{L_MENU_TOGGLE}" onclick="switch_menu(); return false;" href="#"></a></div> - <!-- ENDIF --> <div id="menu"> <p>{L_LOGGED_IN_AS}<br /><strong>{USERNAME}</strong> [ <a href="{U_LOGOUT}">{L_LOGOUT}</a> ][ <a href="{U_ADM_LOGOUT}">{L_ADM_LOGOUT}</a> ] </p> - <ul> <!-- DEFINE $LI_USED = 0 --> <!-- BEGIN l_block1 --> <!-- IF l_block1.S_SELECTED --> <!-- BEGIN l_block2 --> <!-- IF .l_block1.l_block2.l_block3 --> - <li class="header">{l_block1.l_block2.L_TITLE}</li> + <!-- IF $LI_USED --></ul></div><!-- ENDIF --> + <div class="menu-block"> + <a class="header" href="javascript:void(0);">{l_block1.l_block2.L_TITLE}</a> + <ul> <!-- DEFINE $LI_USED = 1 --> <!-- ENDIF --> @@ -205,10 +136,11 @@ function switch_menu() <!-- ENDIF --> <!-- END l_block1 --> - <!-- IF not $LI_USED --> - <li></li> + <!-- IF $LI_USED --> + </ul> + </div> <!-- ENDIF --> - </ul> </div> <div id="main"> + <div class="main"> diff --git a/phpBB/adm/style/pagination.html b/phpBB/adm/style/pagination.html index d62d0b6a81..7158f83fbc 100644 --- a/phpBB/adm/style/pagination.html +++ b/phpBB/adm/style/pagination.html @@ -1,5 +1,5 @@ - <a href="#" onclick="jumpto(); return false;" title="{L_JUMP_TO_PAGE}">{S_ON_PAGE}</a> • + <a href="#" onclick="jumpto(); return false;" title="{L_JUMP_TO_PAGE}">{PAGE_NUMBER}</a> • <ul> <!-- BEGIN pagination --> <!-- IF pagination.S_IS_PREV --><li><a href="{pagination.PAGE_URL}">{L_PREVIOUS}</a></li> diff --git a/phpBB/adm/style/permission_mask.html b/phpBB/adm/style/permission_mask.html index 4d52b901c3..7b5c071693 100644 --- a/phpBB/adm/style/permission_mask.html +++ b/phpBB/adm/style/permission_mask.html @@ -75,9 +75,8 @@ <!-- BEGIN category --> <div class="permissions-panel" id="options{p_mask.S_ROW_COUNT}{p_mask.f_mask.S_ROW_COUNT}{p_mask.f_mask.category.S_ROW_COUNT}" <!-- IF p_mask.S_FIRST_ROW and p_mask.f_mask.S_FIRST_ROW and p_mask.f_mask.category.S_FIRST_ROW --><!-- ELSE --> style="display: none;"<!-- ENDIF -->> - <span class="corners-top"><span></span></span> <div class="tablewrap"> - <table id="table{p_mask.S_ROW_COUNT}{p_mask.f_mask.S_ROW_COUNT}{p_mask.f_mask.category.S_ROW_COUNT}" cellspacing="1"> + <table id="table{p_mask.S_ROW_COUNT}{p_mask.f_mask.S_ROW_COUNT}{p_mask.f_mask.category.S_ROW_COUNT}" class="table1 not-responsive"> <colgroup> <col class="permissions-name" /> <col class="permissions-yes" /> @@ -128,7 +127,6 @@ <!-- ENDIF --> - <span class="corners-bottom"><span></span></span> </div> <!-- END category --> <div class="clearfix"></div> diff --git a/phpBB/adm/style/permission_roles_mask.html b/phpBB/adm/style/permission_roles_mask.html index 42a7fc3e4e..3a14e65004 100644 --- a/phpBB/adm/style/permission_roles_mask.html +++ b/phpBB/adm/style/permission_roles_mask.html @@ -1,7 +1,7 @@ <!-- BEGIN role_mask --> - <table cellspacing="1"> + <table class="table1"> <caption><!-- IF role_mask.FORUM_ID -->{L_FORUM}{L_COLON} <!-- ENDIF -->{role_mask.NAME}</caption> <tbody> <tr> diff --git a/phpBB/adm/style/permission_trace.html b/phpBB/adm/style/permission_trace.html index 744ad3293e..7330ffee41 100644 --- a/phpBB/adm/style/permission_trace.html +++ b/phpBB/adm/style/permission_trace.html @@ -8,7 +8,7 @@ <br /> - <table cellspacing="1" class="type1"> + <table class="table1"> <thead> <tr> <th>{L_TRACE_WHO}</th> diff --git a/phpBB/adm/style/permissions.js b/phpBB/adm/style/permissions.js index 1c85fbd9ef..9178adab50 100644 --- a/phpBB/adm/style/permissions.js +++ b/phpBB/adm/style/permissions.js @@ -177,7 +177,7 @@ function swap_options(pmask, fmask, cat, adv, view) { var adv_block = document.getElementById('advanced' + pmask + fmask); if (adv_block.style.display === 'block' && adv === true) { - dE('advanced' + pmask + fmask, -1); + phpbb.toggleDisplay('advanced' + pmask + fmask, -1); reset_opacity(1); display_checkboxes(false); return; @@ -207,11 +207,11 @@ function swap_options(pmask, fmask, cat, adv, view) { return; } - dE('options' + active_option, -1); + phpbb.toggleDisplay('options' + active_option, -1); //hiding and showing the checkbox if (document.getElementById('checkbox' + active_pmask + active_fmask)) { - dE('checkbox' + pmask + fmask, -1); + phpbb.toggleDisplay('checkbox' + pmask + fmask, -1); if ((pmask + fmask) !== (active_pmask + active_fmask)) { document.getElementById('checkbox' + active_pmask + active_fmask).style.display = 'inline'; @@ -219,13 +219,13 @@ function swap_options(pmask, fmask, cat, adv, view) { } if (!view) { - dE('advanced' + active_pmask + active_fmask, -1); + phpbb.toggleDisplay('advanced' + active_pmask + active_fmask, -1); } if (!view) { - dE('advanced' + pmask + fmask, 1); + phpbb.toggleDisplay('advanced' + pmask + fmask, 1); } - dE('options' + id, 1); + phpbb.toggleDisplay('options' + id, 1); active_pmask = pmask; active_fmask = fmask; diff --git a/phpBB/adm/style/profilefields/bool.html b/phpBB/adm/style/profilefields/bool.html new file mode 100644 index 0000000000..f1d7ba75f4 --- /dev/null +++ b/phpBB/adm/style/profilefields/bool.html @@ -0,0 +1,7 @@ +<!-- BEGIN bool --> +<!-- IF bool.FIELD_LENGTH eq 1 --> + <!-- BEGIN options --><label for="{bool.FIELD_IDENT}_{bool.options.OPTION_ID}"><input type="radio" class="radio" name="{bool.FIELD_IDENT}" id="{bool.FIELD_IDENT}_{bool.options.OPTION_ID}" value="{bool.options.OPTION_ID}"{bool.options.CHECKED} /> {bool.options.VALUE}</label> <!-- END options --> +<!-- ELSE --> + <input type="checkbox" class="radio" name="{bool.FIELD_IDENT}" id="{bool.FIELD_IDENT}"<!-- IF bool.FIELD_VALUE --> checked="checked"<!-- ENDIF --> /> +<!-- ENDIF --> +<!-- END bool --> diff --git a/phpBB/adm/style/profilefields/date.html b/phpBB/adm/style/profilefields/date.html new file mode 100644 index 0000000000..5d5bc04ed6 --- /dev/null +++ b/phpBB/adm/style/profilefields/date.html @@ -0,0 +1,5 @@ +<!-- BEGIN date --> +<label for="{date.FIELD_IDENT}_day">{L_DAY}{L_COLON} <select name="{date.FIELD_IDENT}_day" id="{date.FIELD_IDENT}_day">{date.S_DAY_OPTIONS}</select></label> +<label for="{date.FIELD_IDENT}_month">{L_MONTH}{L_COLON} <select name="{date.FIELD_IDENT}_month" id="{date.FIELD_IDENT}_month">{date.S_MONTH_OPTIONS}</select></label> +<label for="{date.FIELD_IDENT}_year">{L_YEAR}{L_COLON} <select name="{date.FIELD_IDENT}_year" id="{date.FIELD_IDENT}_year">{date.S_YEAR_OPTIONS}</select></label> +<!-- END date --> diff --git a/phpBB/adm/style/profilefields/dropdown.html b/phpBB/adm/style/profilefields/dropdown.html new file mode 100644 index 0000000000..243b7039da --- /dev/null +++ b/phpBB/adm/style/profilefields/dropdown.html @@ -0,0 +1,5 @@ +<!-- BEGIN dropdown --> +<select name="{dropdown.FIELD_IDENT}" id="{dropdown.FIELD_IDENT}"> + <!-- BEGIN options --><option value="{dropdown.options.OPTION_ID}"{dropdown.options.SELECTED}>{dropdown.options.VALUE}</option><!-- END options --> +</select> +<!-- END dropdown --> diff --git a/phpBB/adm/style/profilefields/int.html b/phpBB/adm/style/profilefields/int.html new file mode 100644 index 0000000000..d047c254d8 --- /dev/null +++ b/phpBB/adm/style/profilefields/int.html @@ -0,0 +1,3 @@ +<!-- BEGIN int --> +<input type="number" min="{int.FIELD_MINLEN}" max="{int.FIELD_MAXLEN}" class="autowidth" name="{int.FIELD_IDENT}" id="{int.FIELD_IDENT}" size="{int.FIELD_LENGTH}" value="{int.FIELD_VALUE}" /> +<!-- END int --> diff --git a/phpBB/adm/style/profilefields/string.html b/phpBB/adm/style/profilefields/string.html new file mode 100644 index 0000000000..a8855f50d8 --- /dev/null +++ b/phpBB/adm/style/profilefields/string.html @@ -0,0 +1,3 @@ +<!-- BEGIN string --> +<input type="text" class="autowidth" name="{string.FIELD_IDENT}" id="{string.FIELD_IDENT}" size="{string.FIELD_LENGTH}" maxlength="{string.FIELD_MAXLEN}" value="{string.FIELD_VALUE}" /> +<!-- END string --> diff --git a/phpBB/adm/style/profilefields/text.html b/phpBB/adm/style/profilefields/text.html new file mode 100644 index 0000000000..6334b61926 --- /dev/null +++ b/phpBB/adm/style/profilefields/text.html @@ -0,0 +1,3 @@ +<!-- BEGIN text --> +<textarea name="{text.FIELD_IDENT}" id="{text.FIELD_IDENT}" rows="{text.FIELD_ROWS}" cols="{text.FIELD_COLS}">{text.FIELD_VALUE}</textarea> +<!-- END text --> diff --git a/phpBB/adm/style/profilefields/url.html b/phpBB/adm/style/profilefields/url.html new file mode 100644 index 0000000000..8dd3a90de1 --- /dev/null +++ b/phpBB/adm/style/profilefields/url.html @@ -0,0 +1,3 @@ +<!-- BEGIN url --> +<input type="url" class="inputbox autowidth" name="{url.FIELD_IDENT}" id="{url.FIELD_IDENT}" size="{url.FIELD_LENGTH}" maxlength="{url.FIELD_MAXLEN}" value="{url.FIELD_VALUE}" /> +<!-- END url --> diff --git a/phpBB/adm/style/simple_footer.html b/phpBB/adm/style/simple_footer.html index 906a9bebed..c549a2df4e 100644 --- a/phpBB/adm/style/simple_footer.html +++ b/phpBB/adm/style/simple_footer.html @@ -17,7 +17,9 @@ </div> <script type="text/javascript" src="{T_JQUERY_LINK}"></script> -<!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> +<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> +<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script> + <!-- EVENT acp_simple_footer_after --> </body> diff --git a/phpBB/adm/style/simple_header.html b/phpBB/adm/style/simple_header.html index 9c4c8a2960..ae25f28d32 100644 --- a/phpBB/adm/style/simple_header.html +++ b/phpBB/adm/style/simple_header.html @@ -10,7 +10,7 @@ <script type="text/javascript"> // <![CDATA[ var jump_page = '{LA_JUMP_PAGE}{L_COLON}'; -var on_page = '{ON_PAGE}'; +var on_page = '{CURRENT_PAGE}'; var per_page = '{PER_PAGE}'; var base_url = '{BASE_URL|e('js')}'; @@ -49,25 +49,6 @@ function jumpto() } /** -* Set display of page element -* s[-1,0,1] = hide,toggle display,show -*/ -function dE(n, s, type) -{ - if (!type) - { - type = 'block'; - } - - var e = document.getElementById(n); - if (!s) - { - s = (e.style.display == '') ? -1 : 1; - } - e.style.display = (s == 1) ? type : 'none'; -} - -/** * Mark/unmark checkboxes * id = ID of parent container, name = name prefix, state = state [true/false] */ @@ -104,6 +85,8 @@ function find_username(url) <!-- EVENT acp_simple_header_head_append --> </head> -<body class="{S_CONTENT_DIRECTION}"> +<body class="{S_CONTENT_DIRECTION} {BODY_CLASS}"> + +<!-- EVENT acp_simple_header_body_before --> <div id="page-body" class="simple-page-body"> diff --git a/phpBB/adm/style/viewsource.html b/phpBB/adm/style/viewsource.html deleted file mode 100644 index 03e9ff50e5..0000000000 --- a/phpBB/adm/style/viewsource.html +++ /dev/null @@ -1,21 +0,0 @@ -<!-- INCLUDE simple_header.html --> -<div id="acp" style="padding: 0;"> -<div class="panel" style="padding: 10px;"> -<div style="overflow: auto;"> - <h1>{FILENAME}</h1> - - <table class="type2"> - <tbody> - <!-- BEGIN source --> - <tr valign="top"> - <td class="sourcenum">{source.LINENUM} </td> - <td class="source">{source.LINE}</td> - </tr> - <!-- END source --> - </tbody> - </table> - -</div> -</div> -</div> -<!-- INCLUDE simple_footer.html --> diff --git a/phpBB/adm/swatch.php b/phpBB/adm/swatch.php deleted file mode 100644 index e9d46d65b5..0000000000 --- a/phpBB/adm/swatch.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -define('IN_PHPBB', true); -define('ADMIN_START', true); -$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; -$phpEx = substr(strrchr(__FILE__, '.'), 1); -include($phpbb_root_path . 'common.' . $phpEx); - -// Start session management -$user->session_begin(false); -$auth->acl($user->data); -$user->setup(); - -// Set custom template for admin area -$template->set_custom_style('adm', $phpbb_admin_path . 'style'); - -$template->set_filenames(array( - 'body' => 'colour_swatch.html') -); - -$form = request_var('form', ''); -$name = request_var('name', ''); - -// We validate form and name here, only id/class allowed -$form = (!preg_match('/^[a-z0-9_-]+$/i', $form)) ? '' : $form; -$name = (!preg_match('/^[a-z0-9_-]+$/i', $name)) ? '' : $name; - -$template->assign_vars(array( - 'OPENER' => $form, - 'NAME' => $name, - 'T_IMAGES_PATH' => "{$phpbb_root_path}images/", - - 'S_USER_LANG' => $user->lang['USER_LANG'], - 'S_CONTENT_DIRECTION' => $user->lang['DIRECTION'], - 'S_CONTENT_ENCODING' => 'UTF-8', -)); - -$template->display('body'); - -garbage_collection(); diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index cdba6f9d26..4920a1167f 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -12,31 +12,29 @@ var keymap = { }; var dark = $('#darkenwrapper'); -var loadingAlert = $('#loadingalert'); +var loadingIndicator = $('#loading_indicator'); var phpbbAlertTimer = null; +var isTouch = (window && typeof window.ontouchstart !== 'undefined'); /** * Display a loading screen * - * @returns object Returns loadingAlert. + * @returns object Returns loadingIndicator. */ -phpbb.loadingAlert = function() { - if (dark.is(':visible')) { - loadingAlert.fadeIn(phpbb.alertTime); - } else { - loadingAlert.show(); - dark.fadeIn(phpbb.alertTime, function() { - // Wait five seconds and display an error if nothing has been returned by then. - phpbbAlertTimer = setTimeout(function() { - if (loadingAlert.is(':visible')) { - phpbb.alert($('#phpbb_alert').attr('data-l-err'), $('#phpbb_alert').attr('data-l-timeout-processing-req')); - } - }, 5000); - }); +phpbb.loadingIndicator = function() { + if (!loadingIndicator.is(':visible')) { + loadingIndicator.fadeIn(phpbb.alertTime); + // Wait fifteen seconds and display an error if nothing has been returned by then. + phpbb.clearLoadingTimeout(); + phpbbAlertTimer = setTimeout(function() { + if (loadingIndicator.is(':visible')) { + phpbb.alert($('#phpbb_alert').attr('data-l-err'), $('#phpbb_alert').attr('data-l-timeout-processing-req')); + } + }, 15000); } - return loadingAlert; + return loadingIndicator; }; /** @@ -66,6 +64,10 @@ phpbb.alert = function(title, msg, fadedark) { div.find('.alert_title').html(title); div.find('.alert_text').html(msg); + if (!dark.is(':visible')) { + dark.fadeIn(phpbb.alertTime); + } + div.bind('click', function(e) { e.stopPropagation(); }); @@ -97,8 +99,8 @@ phpbb.alert = function(title, msg, fadedark) { e.preventDefault(); }); - if (loadingAlert.is(':visible')) { - loadingAlert.fadeOut(phpbb.alertTime, function() { + if (loadingIndicator.is(':visible')) { + loadingIndicator.fadeOut(phpbb.alertTime, function() { dark.append(div); div.fadeIn(phpbb.alertTime); }); @@ -131,6 +133,10 @@ phpbb.confirm = function(msg, callback, fadedark) { var div = $('#phpbb_confirm'); div.find('.alert_text').html(msg); + if (!dark.is(':visible')) { + dark.fadeIn(phpbb.alertTime); + } + div.bind('click', function(e) { e.stopPropagation(); }); @@ -184,8 +190,8 @@ phpbb.confirm = function(msg, callback, fadedark) { e.preventDefault(); }); - if (loadingAlert.is(':visible')) { - loadingAlert.fadeOut(phpbb.alertTime, function() { + if (loadingIndicator.is(':visible')) { + loadingIndicator.fadeOut(phpbb.alertTime, function() { dark.append(div); div.fadeIn(phpbb.alertTime); }); @@ -310,7 +316,7 @@ phpbb.ajaxify = function(options) { refresh = false; } - setTimeout(function() { + phpbbAlertTimer = setTimeout(function() { if (refresh) { window.location = res.REFRESH_DATA.url; } @@ -326,12 +332,12 @@ phpbb.ajaxify = function(options) { // If confirmation is required, display a dialog to the user. phpbb.confirm(res.MESSAGE_BODY, function(del) { if (del) { - phpbb.loadingAlert(); + phpbb.loadingIndicator(); data = $('<form>' + res.S_HIDDEN_FIELDS + '</form>').serialize(); $.ajax({ url: res.S_CONFIRM_ACTION, type: 'POST', - data: data + '&confirm=' + res.YES_VALUE, + data: data + '&confirm=' + res.YES_VALUE + '&' + $('#phpbb_confirm form').serialize(), success: returnHandler, error: errorHandler }); @@ -369,16 +375,19 @@ phpbb.ajaxify = function(options) { } if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) { - phpbb.loadingAlert(); + phpbb.loadingIndicator(); } - $.ajax({ + var request = $.ajax({ url: action, type: method, data: data, success: returnHandler, error: errorHandler }); + request.always(function() { + loadingIndicator.fadeOut(phpbb.alertTime); + }); event.preventDefault(); }); @@ -423,14 +432,14 @@ phpbb.timezoneSwitchDate = function(keepSelection) { if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() === 1) { // If there is only one timezone for the selected date, we just select that automatically. - $("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").attr('selected', true); + $("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").prop('selected', true); keepSelection = true; } if (typeof keepSelection !== 'undefined' && !keepSelection) { var timezoneOptions = $('#timezone > optgroup option'); if (timezoneOptions.filter(':selected').length <= 0) { - timezoneOptions.filter(':first').attr('selected', true); + timezoneOptions.filter(':first').prop('selected', true); } } }; @@ -510,11 +519,11 @@ $('#notification_list_button').click(function(e) { e.preventDefault(); }); $('#phpbb').click(function(e) { - var target = $(e.target); + var target = $(e.target); - if (!target.is('#notification_list') && !target.is('#notification_list_button') && !target.parents().is('#notification_list')) { - $('#notification_list').hide(); - } + if (!target.is('#notification_list, #notification_list_button') && !target.parents().is('#notification_list, #notification_list_button')) { + $('#notification_list').hide(); + } }); phpbb.ajaxCallbacks = {}; @@ -541,13 +550,23 @@ phpbb.addAjaxCallback = function(id, callback) { * current text so that the process can be repeated. */ phpbb.addAjaxCallback('alt_text', function() { - var el = $(this), + var el, + updateAll = $(this).data('update-all'), altText; - altText = el.attr('data-alt-text'); - el.attr('data-alt-text', el.text()); - el.attr('title', altText); - el.text(altText); + if (updateAll !== undefined && updateAll.length) { + el = $(updateAll); + } else { + el = $(this); + } + + el.each(function() { + var el = $(this); + altText = el.attr('data-alt-text'); + el.attr('data-alt-text', el.text()); + el.attr('title', $.trim(altText)); + el.text(altText); + }); }); /** @@ -560,27 +579,37 @@ phpbb.addAjaxCallback('alt_text', function() { * and changes the link itself. */ phpbb.addAjaxCallback('toggle_link', function() { - var el = $(this), + var el, + updateAll = $(this).data('update-all') , toggleText, toggleUrl, toggleClass; - // Toggle link text + if (updateAll !== undefined && updateAll.length) { + el = $(updateAll); + } else { + el = $(this); + } + + el.each(function() { + var el = $(this); - toggleText = el.attr('data-toggle-text'); - el.attr('data-toggle-text', el.text()); - el.attr('title', toggleText); - el.text(toggleText); + // Toggle link text + toggleText = el.attr('data-toggle-text'); + el.attr('data-toggle-text', el.text()); + el.attr('title', $.trim(toggleText)); + el.text(toggleText); - // Toggle link url - toggleUrl = el.attr('data-toggle-url'); - el.attr('data-toggle-url', el.attr('href')); - el.attr('href', toggleUrl); + // Toggle link url + toggleUrl = el.attr('data-toggle-url'); + el.attr('data-toggle-url', el.attr('href')); + el.attr('href', toggleUrl); - // Toggle class of link parent - toggleClass = el.attr('data-toggle-class'); - el.attr('data-toggle-class', el.parent().attr('class')); - el.parent().attr('class', toggleClass); + // Toggle class of link parent + toggleClass = el.attr('data-toggle-class'); + el.attr('data-toggle-class', el.parent().attr('class')); + el.parent().attr('class', toggleClass); + }); }); /** @@ -616,16 +645,16 @@ phpbb.resizeTextArea = function(items, options) { resetCallback: function(item) { } }; - if (arguments.length > 1) - { + if (isTouch) return; + + if (arguments.length > 1) { configuration = $.extend(configuration, options); } function resetAutoResize(item) { var $item = $(item); - if ($item.hasClass('auto-resized')) - { + if ($item.hasClass('auto-resized')) { $(item).css({height: '', resize: ''}).removeClass('auto-resized'); configuration.resetCallback.call(item, $item); } @@ -635,14 +664,14 @@ phpbb.resizeTextArea = function(items, options) { { function setHeight(height) { + height += parseInt($item.css('height')) - $item.height(); $item.css({height: height + 'px', resize: 'none'}).addClass('auto-resized'); configuration.resizeCallback.call(item, $item); } var windowHeight = $(window).height(); - if (windowHeight < configuration.minWindowHeight) - { + if (windowHeight < configuration.minWindowHeight) { resetAutoResize(item); return; } @@ -652,12 +681,14 @@ phpbb.resizeTextArea = function(items, options) { height = parseInt($item.height()), scrollHeight = (item.scrollHeight) ? item.scrollHeight : 0; - if (height > maxHeight) - { + if (height < 0) { + return; + } + + if (height > maxHeight) { setHeight(maxHeight); } - else if (scrollHeight > (height + 5)) - { + else if (scrollHeight > (height + 5)) { setHeight(Math.min(maxHeight, scrollHeight)); } } @@ -670,8 +701,7 @@ phpbb.resizeTextArea = function(items, options) { $(window).resize(function() { items.each(function() { - if ($(this).hasClass('auto-resized')) - { + if ($(this).hasClass('auto-resized')) { autoResize(this); } }); @@ -830,12 +860,268 @@ phpbb.applyCodeEditor = function(textarea) { }; /** +* List of classes that toggle dropdown menu, +* list of classes that contain visible dropdown menu +* +* Add your own classes to strings with comma (probably you +* will never need to do that) +*/ +phpbb.dropdownHandles = '.dropdown-container.dropdown-visible .dropdown-toggle'; +phpbb.dropdownVisibleContainers = '.dropdown-container.dropdown-visible'; + +/** +* Dropdown toggle event handler +* This handler is used by phpBB.registerDropdown() and other functions +*/ +phpbb.toggleDropdown = function() { + var $this = $(this), + options = $this.data('dropdown-options'), + parent = options.parent, + visible = parent.hasClass('dropdown-visible'); + + if (!visible) { + // Hide other dropdown menus + $(phpbb.dropdownHandles).each(phpbb.toggleDropdown); + + // Figure out direction of dropdown + var direction = options.direction, + verticalDirection = options.verticalDirection, + offset = $this.offset(); + + if (direction == 'auto') { + if (($(window).width() - $this.outerWidth(true)) / 2 > offset.left) { + direction = 'right'; + } + else { + direction = 'left'; + } + } + parent.toggleClass(options.leftClass, direction == 'left').toggleClass(options.rightClass, direction == 'right'); + + if (verticalDirection == 'auto') { + var height = $(window).height(), + top = offset.top - $(window).scrollTop(); + + if (top < height * 0.7) { + verticalDirection = 'down'; + } + else { + verticalDirection = 'up'; + } + } + parent.toggleClass(options.upClass, verticalDirection == 'up').toggleClass(options.downClass, verticalDirection == 'down'); + } + + options.dropdown.toggle(); + parent.toggleClass(options.visibleClass, !visible).toggleClass('dropdown-visible', !visible); + + // Check dimensions when showing dropdown + // !visible because variable shows state of dropdown before it was toggled + if (!visible) { + options.dropdown.find('.dropdown-contents').each(function() { + var $this = $(this), + windowWidth = $(window).width(); + + $this.css({ + marginLeft: 0, + left: 0, + maxWidth: (windowWidth - 4) + 'px' + }); + + var offset = $this.offset().left, + width = $this.outerWidth(true); + + if (offset < 2) { + $this.css('left', (2 - offset) + 'px'); + } + else if ((offset + width + 2) > windowWidth) { + $this.css('margin-left', (windowWidth - offset - width - 2) + 'px'); + } + }); + } + + // Prevent event propagation + if (arguments.length > 0) { + try { + var e = arguments[0]; + e.preventDefault(); + e.stopPropagation(); + } + catch (error) { } + } + return false; +}; + +/** +* Toggle dropdown submenu +*/ +phpbb.toggleSubmenu = function(e) { + $(this).siblings('.dropdown-submenu').toggle(); + e.preventDefault(); +} + +/** +* Register dropdown menu +* Shows/hides dropdown, decides which side to open to +* +* @param {jQuery} toggle Link that toggles dropdown. +* @param {jQuery} dropdown Dropdown menu. +* @param {Object} options List of options. Optional. +*/ +phpbb.registerDropdown = function(toggle, dropdown, options) +{ + var ops = { + parent: toggle.parent(), // Parent item to add classes to + direction: 'auto', // Direction of dropdown menu. Possible values: auto, left, right + verticalDirection: 'auto', // Vertical direction. Possible values: auto, up, down + visibleClass: 'visible', // Class to add to parent item when dropdown is visible + leftClass: 'dropdown-left', // Class to add to parent item when dropdown opens to left side + rightClass: 'dropdown-right', // Class to add to parent item when dropdown opens to right side + upClass: 'dropdown-up', // Class to add to parent item when dropdown opens above menu item + downClass: 'dropdown-down' // Class to add to parent item when dropdown opens below menu item + }; + if (options) { + ops = $.extend(ops, options); + } + ops.dropdown = dropdown; + + ops.parent.addClass('dropdown-container'); + toggle.addClass('dropdown-toggle'); + + toggle.data('dropdown-options', ops); + + toggle.click(phpbb.toggleDropdown); + $('.dropdown-toggle-submenu', ops.parent).click(phpbb.toggleSubmenu); +}; + +/** +* Get the HTML for a color palette table. +* +* @param string dir Palette direction - either v or h +* @param int width Palette cell width. +* @param int height Palette cell height. +*/ +phpbb.colorPalette = function(dir, width, height) { + var r = 0, + g = 0, + b = 0, + numberList = new Array(6), + color = '', + html = ''; + + numberList[0] = '00'; + numberList[1] = '40'; + numberList[2] = '80'; + numberList[3] = 'BF'; + numberList[4] = 'FF'; + + var table_class = (dir == 'h') ? 'horizontal-palette' : 'vertical-palette'; + html += '<table class="not-responsive colour-palette ' + table_class + '" style="width: auto;">'; + + for (r = 0; r < 5; r++) { + if (dir == 'h') { + html += '<tr>'; + } + + for (g = 0; g < 5; g++) { + if (dir == 'v') { + html += '<tr>'; + } + + for (b = 0; b < 5; b++) { + color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); + html += '<td style="background-color: #' + color + '; width: ' + width + 'px; height: ' + height + 'px;">'; + html += '<a href="#" data-color="' + color + '" style="display: block; width: ' + width + 'px; height: ' + height + 'px; " alt="#' + color + '" title="#' + color + '"></a>'; + html += '</td>'; + } + + if (dir == 'v') { + html += '</tr>'; + } + } + + if (dir == 'h') { + html += '</tr>'; + } + } + html += '</table>'; + return html; +} + +/** +* Register a color palette. +* +* @param object el jQuery object for the palette container. +*/ +phpbb.registerPalette = function(el) { + var orientation = el.attr('data-orientation'), + height = el.attr('data-height'), + width = el.attr('data-width'), + target = el.attr('data-target'), + bbcode = el.attr('data-bbcode'); + + // Insert the palette HTML into the container. + el.html(phpbb.colorPalette(orientation, width, height)); + + // Add toggle control. + $('#color_palette_toggle').click(function(e) { + el.toggle(); + e.preventDefault(); + }); + + // Attach event handler when a palette cell is clicked. + $(el).on('click', 'a', function(e) { + var color = $(this).attr('data-color'); + + if (bbcode) { + bbfontstyle('[color=#' + color + ']', '[/color]'); + } else { + $(target).val(color); + } + e.preventDefault(); + }); +} + +/** +* Set display of page element +* +* @param string id The ID of the element to change +* @param int action Set to 0 if element display should be toggled, -1 for +* hiding the element, and 1 for showing it. +* @param string type Display type that should be used, e.g. inline, block or +* other CSS "display" types +*/ +phpbb.toggleDisplay = function(id, action, type) { + if (!type) { + type = 'block'; + } + + var display = $('#' + id).css('display'); + if (!action) { + action = (display === '' || display === type) ? -1 : 1; + } + $('#' + id).css('display', ((action === 1) ? type : 'none')); +} + +/** * Apply code editor to all textarea elements with data-bbcode attribute */ $(document).ready(function() { $('textarea[data-bbcode]').each(function() { phpbb.applyCodeEditor(this); }); + + // Hide active dropdowns when click event happens outside + $('body').click(function(e) { + var parents = $(e.target).parents(); + if (!parents.is(phpbb.dropdownVisibleContainers)) { + $(phpbb.dropdownHandles).each(phpbb.toggleDropdown); + } + }); + + $('#color_palette_placeholder').each(function() { + phpbb.registerPalette($(this)); + }); }); })(jQuery); // Avoid conflicts with other libraries diff --git a/phpBB/styles/subsilver2/template/editor.js b/phpBB/assets/javascript/editor.js index 6cf616e180..dfc7dab525 100644 --- a/phpBB/styles/subsilver2/template/editor.js +++ b/phpBB/assets/javascript/editor.js @@ -38,7 +38,6 @@ function initInsertions() { } var textarea = doc.forms[form_name].elements[text_name]; - phpbb.applyCodeEditor(textarea); if (is_ie && typeof(baseHeight) !== 'number') { textarea.focus(); @@ -79,14 +78,13 @@ function bbfontstyle(bbopen, bbclose) { if (theSelection) { // Add tags around selection document.selection.createRange().text = bbopen + theSelection + bbclose; - document.forms[form_name].elements[text_name].focus(); + textarea.focus(); theSelection = ''; return; } - } else if (document.forms[form_name].elements[text_name].selectionEnd - && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) { - mozWrap(document.forms[form_name].elements[text_name], bbopen, bbclose); - document.forms[form_name].elements[text_name].focus(); + } else if (textarea.selectionEnd && (textarea.selectionEnd - textarea.selectionStart > 0)) { + mozWrap(textarea, bbopen, bbclose); + textarea.focus(); theSelection = ''; return; } @@ -290,57 +288,12 @@ function mozWrap(txtarea, open, close) { * http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130 */ function storeCaret(textEl) { - if (textEl.createTextRange) { + if (textEl.createTextRange && document.selection) { textEl.caretPos = document.selection.createRange().duplicate(); } } /** -* Color pallette -*/ -function colorPalette(dir, width, height) { - var r = 0, g = 0, b = 0; - var numberList = new Array(6); - var color = ''; - - numberList[0] = '00'; - numberList[1] = '40'; - numberList[2] = '80'; - numberList[3] = 'BF'; - numberList[4] = 'FF'; - - document.writeln('<table cellspacing="1" cellpadding="0" border="0">'); - - for (r = 0; r < 5; r++) { - if (dir === 'h') { - document.writeln('<tr>'); - } - - for (g = 0; g < 5; g++) { - if (dir === 'v') { - document.writeln('<tr>'); - } - - for (b = 0; b < 5; b++) { - color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); - document.write('<td bgcolor="#' + color + '" style="width: ' + width + 'px; height: ' + height + 'px;">'); - document.write('<a href="#" onclick="bbfontstyle(\'[color=#' + color + ']\', \'[/color]\'); return false;"><img src="images/spacer.gif" width="' + width + '" height="' + height + '" alt="#' + color + '" title="#' + color + '" /></a>'); - document.writeln('</td>'); - } - - if (dir === 'v') { - document.writeln('</tr>'); - } - } - - if (dir === 'h') { - document.writeln('</tr>'); - } - } - document.writeln('</table>'); -} - -/** * Caret Position object */ function caretPosition() { @@ -383,3 +336,29 @@ function getCaretPosition(txtarea) { return caretPos; } + +/** +* Allow to use tab character when typing code +* Keep indentation of last line of code when typing code +*/ +(function($) { + $(document).ready(function() { + var doc, textarea; + + // find textarea, make sure browser supports necessary functions + if (document.forms[form_name]) { + doc = document; + } else { + doc = opener.document; + } + + if (!doc.forms[form_name]) { + return; + } + + textarea = doc.forms[form_name].elements[text_name]; + + phpbb.applyCodeEditor(textarea); + }); +})(jQuery); + diff --git a/phpBB/assets/javascript/jquery.js b/phpBB/assets/javascript/jquery.js index 83589daa70..73f33fb3aa 100644 --- a/phpBB/assets/javascript/jquery.js +++ b/phpBB/assets/javascript/jquery.js @@ -1,2 +1,4 @@ -/*! jQuery v1.8.3 jquery.com | jquery.org/license */
-(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r<i;r++)v.event.add(t,n,u[n][r])}o.data&&(o.data=v.extend({},o.data))}function Ot(e,t){var n;if(t.nodeType!==1)return;t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),n=t.nodeName.toLowerCase(),n==="object"?(t.parentNode&&(t.outerHTML=e.outerHTML),v.support.html5Clone&&e.innerHTML&&!v.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):n==="input"&&Et.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):n==="option"?t.selected=e.defaultSelected:n==="input"||n==="textarea"?t.defaultValue=e.defaultValue:n==="script"&&t.text!==e.text&&(t.text=e.text),t.removeAttribute(v.expando)}function Mt(e){return typeof e.getElementsByTagName!="undefined"?e.getElementsByTagName("*"):typeof e.querySelectorAll!="undefined"?e.querySelectorAll("*"):[]}function _t(e){Et.test(e.type)&&(e.defaultChecked=e.checked)}function Qt(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Jt.length;while(i--){t=Jt[i]+n;if(t in e)return t}return r}function Gt(e,t){return e=t||e,v.css(e,"display")==="none"||!v.contains(e.ownerDocument,e)}function Yt(e,t){var n,r,i=[],s=0,o=e.length;for(;s<o;s++){n=e[s];if(!n.style)continue;i[s]=v._data(n,"olddisplay"),t?(!i[s]&&n.style.display==="none"&&(n.style.display=""),n.style.display===""&&Gt(n)&&(i[s]=v._data(n,"olddisplay",nn(n.nodeName)))):(r=Dt(n,"display"),!i[s]&&r!=="none"&&v._data(n,"olddisplay",r))}for(s=0;s<o;s++){n=e[s];if(!n.style)continue;if(!t||n.style.display==="none"||n.style.display==="")n.style.display=t?i[s]||"":"none"}return e}function Zt(e,t,n){var r=Rt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function en(e,t,n,r){var i=n===(r?"border":"content")?4:t==="width"?1:0,s=0;for(;i<4;i+=2)n==="margin"&&(s+=v.css(e,n+$t[i],!0)),r?(n==="content"&&(s-=parseFloat(Dt(e,"padding"+$t[i]))||0),n!=="margin"&&(s-=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0)):(s+=parseFloat(Dt(e,"padding"+$t[i]))||0,n!=="padding"&&(s+=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0));return s}function tn(e,t,n){var r=t==="width"?e.offsetWidth:e.offsetHeight,i=!0,s=v.support.boxSizing&&v.css(e,"boxSizing")==="border-box";if(r<=0||r==null){r=Dt(e,t);if(r<0||r==null)r=e.style[t];if(Ut.test(r))return r;i=s&&(v.support.boxSizingReliable||r===e.style[t]),r=parseFloat(r)||0}return r+en(e,t,n||(s?"border":"content"),i)+"px"}function nn(e){if(Wt[e])return Wt[e];var t=v("<"+e+">").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write("<!doctype html><html><body>"),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u<a;u++)r=o[u],s=/^\+/.test(r),s&&(r=r.substr(1)||"*"),i=e[r]=e[r]||[],i[s?"unshift":"push"](n)}}function kn(e,n,r,i,s,o){s=s||n.dataTypes[0],o=o||{},o[s]=!0;var u,a=e[s],f=0,l=a?a.length:0,c=e===Sn;for(;f<l&&(c||!u);f++)u=a[f](n,r,i),typeof u=="string"&&(!c||o[u]?u=t:(n.dataTypes.unshift(u),u=kn(e,n,r,i,u,o)));return(c||!u)&&!o["*"]&&(u=kn(e,n,r,i,"*",o)),u}function Ln(e,n){var r,i,s=v.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((s[r]?e:i||(i={}))[r]=n[r]);i&&v.extend(!0,e,i)}function An(e,n,r){var i,s,o,u,a=e.contents,f=e.dataTypes,l=e.responseFields;for(s in l)s in r&&(n[l[s]]=r[s]);while(f[0]==="*")f.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("content-type"));if(i)for(s in a)if(a[s]&&a[s].test(i)){f.unshift(s);break}if(f[0]in r)o=f[0];else{for(s in r){if(!f[0]||e.converters[s+" "+f[0]]){o=s;break}u||(u=s)}o=o||u}if(o)return o!==f[0]&&f.unshift(o),r[o]}function On(e,t){var n,r,i,s,o=e.dataTypes.slice(),u=o[0],a={},f=0;e.dataFilter&&(t=e.dataFilter(t,e.dataType));if(o[1])for(n in e.converters)a[n.toLowerCase()]=e.converters[n];for(;i=o[++f];)if(i!=="*"){if(u!=="*"&&u!==i){n=a[u+" "+i]||a["* "+i];if(!n)for(r in a){s=r.split(" ");if(s[1]===i){n=a[u+" "+s[0]]||a["* "+s[0]];if(n){n===!0?n=a[r]:a[r]!==!0&&(i=s[0],o.splice(f--,0,i));break}}}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(l){return{state:"parsererror",error:n?l:"No conversion from "+u+" to "+i}}}u=i}return{state:"success",data:t}}function Fn(){try{return new e.XMLHttpRequest}catch(t){}}function In(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function $n(){return setTimeout(function(){qn=t},0),qn=v.now()}function Jn(e,t){v.each(t,function(t,n){var r=(Vn[t]||[]).concat(Vn["*"]),i=0,s=r.length;for(;i<s;i++)if(r[i].call(e,t,n))return})}function Kn(e,t,n){var r,i=0,s=0,o=Xn.length,u=v.Deferred().always(function(){delete a.elem}),a=function(){var t=qn||$n(),n=Math.max(0,f.startTime+f.duration-t),r=n/f.duration||0,i=1-r,s=0,o=f.tweens.length;for(;s<o;s++)f.tweens[s].run(i);return u.notifyWith(e,[f,i,n]),i<1&&o?n:(u.resolveWith(e,[f]),!1)},f=u.promise({elem:e,props:v.extend({},t),opts:v.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:qn||$n(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=v.Tween(e,f.opts,t,n,f.opts.specialEasing[t]||f.opts.easing);return f.tweens.push(i),i},stop:function(t){var n=0,r=t?f.tweens.length:0;for(;n<r;n++)f.tweens[n].run(1);return t?u.resolveWith(e,[f,t]):u.rejectWith(e,[f,t]),this}}),l=f.props;Qn(l,f.opts.specialEasing);for(;i<o;i++){r=Xn[i].call(f,e,l,f.opts);if(r)return r}return Jn(f,l),v.isFunction(f.opts.start)&&f.opts.start.call(e,f),v.fx.timer(v.extend(a,{anim:f,queue:f.opts.queue,elem:e})),f.progress(f.opts.progress).done(f.opts.done,f.opts.complete).fail(f.opts.fail).always(f.opts.always)}function Qn(e,t){var n,r,i,s,o;for(n in e){r=v.camelCase(n),i=t[r],s=e[n],v.isArray(s)&&(i=s[1],s=e[n]=s[0]),n!==r&&(e[r]=s,delete e[n]),o=v.cssHooks[r];if(o&&"expand"in o){s=o.expand(s),delete e[r];for(n in s)n in e||(e[n]=s[n],t[n]=i)}else t[r]=i}}function Gn(e,t,n){var r,i,s,o,u,a,f,l,c,h=this,p=e.style,d={},m=[],g=e.nodeType&&Gt(e);n.queue||(l=v._queueHooks(e,"fx"),l.unqueued==null&&(l.unqueued=0,c=l.empty.fire,l.empty.fire=function(){l.unqueued||c()}),l.unqueued++,h.always(function(){h.always(function(){l.unqueued--,v.queue(e,"fx").length||l.empty.fire()})})),e.nodeType===1&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],v.css(e,"display")==="inline"&&v.css(e,"float")==="none"&&(!v.support.inlineBlockNeedsLayout||nn(e.nodeName)==="inline"?p.display="inline-block":p.zoom=1)),n.overflow&&(p.overflow="hidden",v.support.shrinkWrapBlocks||h.done(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t){s=t[r];if(Un.exec(s)){delete t[r],a=a||s==="toggle";if(s===(g?"hide":"show"))continue;m.push(r)}}o=m.length;if(o){u=v._data(e,"fxshow")||v._data(e,"fxshow",{}),"hidden"in u&&(g=u.hidden),a&&(u.hidden=!g),g?v(e).show():h.done(function(){v(e).hide()}),h.done(function(){var t;v.removeData(e,"fxshow",!0);for(t in d)v.style(e,t,d[t])});for(r=0;r<o;r++)i=m[r],f=h.createTween(i,g?u[i]:0),d[i]=u[i]||v.style(e,i),i in u||(u[i]=f.start,g&&(f.end=f.start,f.start=i==="width"||i==="height"?1:0))}}function Yn(e,t,n,r,i){return new Yn.prototype.init(e,t,n,r,i)}function Zn(e,t){var n,r={height:e},i=0;t=t?1:0;for(;i<4;i+=2-t)n=$t[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function tr(e){return v.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:!1}var n,r,i=e.document,s=e.location,o=e.navigator,u=e.jQuery,a=e.$,f=Array.prototype.push,l=Array.prototype.slice,c=Array.prototype.indexOf,h=Object.prototype.toString,p=Object.prototype.hasOwnProperty,d=String.prototype.trim,v=function(e,t){return new v.fn.init(e,t,n)},m=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,g=/\S/,y=/\s+/,b=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,w=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a<f;a++)if((e=arguments[a])!=null)for(n in e){r=u[n],i=e[n];if(u===i)continue;l&&i&&(v.isPlainObject(i)||(s=v.isArray(i)))?(s?(s=!1,o=r&&v.isArray(r)?r:[]):o=r&&v.isPlainObject(r)?r:{},u[n]=v.extend(l,o,i)):i!==t&&(u[n]=i)}return u},v.extend({noConflict:function(t){return e.$===v&&(e.$=a),t&&e.jQuery===v&&(e.jQuery=u),v},isReady:!1,readyWait:1,holdReady:function(e){e?v.readyWait++:v.ready(!0)},ready:function(e){if(e===!0?--v.readyWait:v.isReady)return;if(!i.body)return setTimeout(v.ready,1);v.isReady=!0;if(e!==!0&&--v.readyWait>0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s<o;)if(n.apply(e[s++],r)===!1)break}else if(u){for(i in e)if(n.call(e[i],i,e[i])===!1)break}else for(;s<o;)if(n.call(e[s],s,e[s++])===!1)break;return e},trim:d&&!d.call("\ufeff\u00a0")?function(e){return e==null?"":d.call(e)}:function(e){return e==null?"":(e+"").replace(b,"")},makeArray:function(e,t){var n,r=t||[];return e!=null&&(n=v.type(e),e.length==null||n==="string"||n==="function"||n==="regexp"||v.isWindow(e)?f.call(r,e):v.merge(r,e)),r},inArray:function(e,t,n){var r;if(t){if(c)return c.call(t,e,n);r=t.length,n=n?n<0?Math.max(0,r+n):n:0;for(;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,s=0;if(typeof r=="number")for(;s<r;s++)e[i++]=n[s];else while(n[s]!==t)e[i++]=n[s++];return e.length=i,e},grep:function(e,t,n){var r,i=[],s=0,o=e.length;n=!!n;for(;s<o;s++)r=!!t(e[s],s),n!==r&&i.push(e[s]);return i},map:function(e,n,r){var i,s,o=[],u=0,a=e.length,f=e instanceof v||a!==t&&typeof a=="number"&&(a>0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u<a;u++)i=n(e[u],u,r),i!=null&&(o[o.length]=i);else for(s in e)i=n(e[s],s,r),i!=null&&(o[o.length]=i);return o.concat.apply([],o)},guid:1,proxy:function(e,n){var r,i,s;return typeof n=="string"&&(r=e[n],n=e,e=r),v.isFunction(e)?(i=l.call(arguments,2),s=function(){return e.apply(n,i.concat(l.call(arguments)))},s.guid=e.guid=e.guid||v.guid++,s):t},access:function(e,n,r,i,s,o,u){var a,f=r==null,l=0,c=e.length;if(r&&typeof r=="object"){for(l in r)v.access(e,n,l,r[l],1,o,i);s=1}else if(i!==t){a=u===t&&v.isFunction(i),f&&(a?(a=n,n=function(e,t,n){return a.call(v(e),n)}):(n.call(e,i),n=null));if(n)for(;l<c;l++)n(e[l],r,a?i.call(e[l],l,n(e[l],r)):i,u);s=1}return s?e:f?n.call(e):c?n(e[0],r):o},now:function(){return(new Date).getTime()}}),v.ready.promise=function(t){if(!r){r=v.Deferred();if(i.readyState==="complete")setTimeout(v.ready,1);else if(i.addEventListener)i.addEventListener("DOMContentLoaded",A,!1),e.addEventListener("load",v.ready,!1);else{i.attachEvent("onreadystatechange",A),e.attachEvent("onload",v.ready);var n=!1;try{n=e.frameElement==null&&i.documentElement}catch(s){}n&&n.doScroll&&function o(){if(!v.isReady){try{n.doScroll("left")}catch(e){return setTimeout(o,50)}v.ready()}}()}}return r.promise(t)},v.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){O["[object "+t+"]"]=t.toLowerCase()}),n=v(i);var M={};v.Callbacks=function(e){e=typeof e=="string"?M[e]||_(e):v.extend({},e);var n,r,i,s,o,u,a=[],f=!e.once&&[],l=function(t){n=e.memory&&t,r=!0,u=s||0,s=0,o=a.length,i=!0;for(;a&&u<o;u++)if(a[u].apply(t[0],t[1])===!1&&e.stopOnFalse){n=!1;break}i=!1,a&&(f?f.length&&l(f.shift()):n?a=[]:c.disable())},c={add:function(){if(a){var t=a.length;(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))}return this},remove:function(){return a&&v.each(arguments,function(e,t){var n;while((n=v.inArray(t,a,n))>-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t<r;t++)n[t]&&v.isFunction(n[t].promise)?n[t].promise().done(o(t,f,n)).fail(s.reject).progress(o(t,a,u)):--i}return i||s.resolveWith(f,n),s.promise()}}),v.support=function(){var t,n,r,s,o,u,a,f,l,c,h,p=i.createElement("div");p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="<table><tr><td></td><td>t</td></tr></table>",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="<div></div>",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i<s;i++)delete r[t[i]];if(!(n?B:v.isEmptyObject)(r))return}}if(!n){delete u[a].data;if(!B(u[a]))return}o?v.cleanData([e],!0):v.support.deleteExpando||u!=u.window?delete u[a]:u[a]=null},_data:function(e,t,n){return v.data(e,t,n,!0)},acceptData:function(e){var t=e.nodeName&&v.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),v.fn.extend({data:function(e,n){var r,i,s,o,u,a=this[0],f=0,l=null;if(e===t){if(this.length){l=v.data(a);if(a.nodeType===1&&!v._data(a,"parsedAttrs")){s=a.attributes;for(u=s.length;f<u;f++)o=s[f].name,o.indexOf("data-")||(o=v.camelCase(o.substring(5)),H(a,o,l[o]));v._data(a,"parsedAttrs",!0)}}return l}return typeof e=="object"?this.each(function(){v.data(this,e)}):(r=e.split(".",2),r[1]=r[1]?"."+r[1]:"",i=r[1]+"!",v.access(this,function(n){if(n===t)return l=this.triggerHandler("getData"+i,[r[0]]),l===t&&a&&(l=v.data(a,e),l=H(a,e,l)),l===t&&r[1]?this.data(r[0]):l;r[1]=n,this.each(function(){var t=v(this);t.triggerHandler("setData"+i,r),v.data(this,e,n),t.triggerHandler("changeData"+i,r)})},null,n,arguments.length>1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length<r?v.queue(this[0],e):n===t?this:this.each(function(){var t=v.queue(this,e,n);v._queueHooks(this,e),e==="fx"&&t[0]!=="inprogress"&&v.dequeue(this,e)})},dequeue:function(e){return this.each(function(){v.dequeue(this,e)})},delay:function(e,t){return e=v.fx?v.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,s=v.Deferred(),o=this,u=this.length,a=function(){--i||s.resolveWith(o,[o])};typeof e!="string"&&(n=e,e=t),e=e||"fx";while(u--)r=v._data(o[u],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(a));return a(),s.promise(n)}});var j,F,I,q=/[\t\r\n]/g,R=/\r/g,U=/^(?:button|input)$/i,z=/^(?:button|input|object|select|textarea)$/i,W=/^a(?:rea|)$/i,X=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,V=v.support.getSetAttribute;v.fn.extend({attr:function(e,t){return v.access(this,v.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n<r;n++){i=this[n];if(i.nodeType===1)if(!i.className&&t.length===1)i.className=e;else{s=" "+i.className+" ";for(o=0,u=t.length;o<u;o++)s.indexOf(" "+t[o]+" ")<0&&(s+=t[o]+" ");i.className=v.trim(s)}}}return this},removeClass:function(e){var n,r,i,s,o,u,a;if(v.isFunction(e))return this.each(function(t){v(this).removeClass(e.call(this,t,this.className))});if(e&&typeof e=="string"||e===t){n=(e||"").split(y);for(u=0,a=this.length;u<a;u++){i=this[u];if(i.nodeType===1&&i.className){r=(" "+i.className+" ").replace(q," ");for(s=0,o=n.length;s<o;s++)while(r.indexOf(" "+n[s]+" ")>=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n<r;n++)if(this[n].nodeType===1&&(" "+this[n].className+" ").replace(q," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a<u;a++){n=r[a];if((n.selected||a===i)&&(v.support.optDisabled?!n.disabled:n.getAttribute("disabled")===null)&&(!n.parentNode.disabled||!v.nodeName(n.parentNode,"optgroup"))){t=v(n).val();if(s)return t;o.push(t)}}return o},set:function(e,t){var n=v.makeArray(t);return v(e).find("option").each(function(){this.selected=v.inArray(v(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o<r.length;o++)i=r[o],i&&(n=v.propFix[i]||i,s=X.test(i),s||v.attr(e,i,""),e.removeAttribute(V?i:n),s&&n in e&&(e[n]=!1))}},attrHooks:{type:{set:function(e,t){if(U.test(e.nodeName)&&e.parentNode)v.error("type property can't be changed");else if(!v.support.radioValue&&t==="radio"&&v.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}},value:{get:function(e,t){return j&&v.nodeName(e,"button")?j.get(e,t):t in e?e.value:null},set:function(e,t,n){if(j&&v.nodeName(e,"button"))return j.set(e,t,n);e.value=t}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,s,o,u=e.nodeType;if(!e||u===3||u===8||u===2)return;return o=u!==1||!v.isXMLDoc(e),o&&(n=v.propFix[n]||n,s=v.propHooks[n]),r!==t?s&&"set"in s&&(i=s.set(e,r,n))!==t?i:e[n]=r:s&&"get"in s&&(i=s.get(e,n))!==null?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):z.test(e.nodeName)||W.test(e.nodeName)&&e.href?0:t}}}}),F={get:function(e,n){var r,i=v.prop(e,n);return i===!0||typeof i!="boolean"&&(r=e.getAttributeNode(n))&&r.nodeValue!==!1?n.toLowerCase():t},set:function(e,t,n){var r;return t===!1?v.removeAttr(e,n):(r=v.propFix[n]||n,r in e&&(e[r]=!0),e.setAttribute(n,n.toLowerCase())),n}},V||(I={name:!0,id:!0,coords:!0},j=v.valHooks.button={get:function(e,n){var r;return r=e.getAttributeNode(n),r&&(I[n]?r.value!=="":r.specified)?r.value:t},set:function(e,t,n){var r=e.getAttributeNode(n);return r||(r=i.createAttribute(n),e.setAttributeNode(r)),r.value=t+""}},v.each(["width","height"],function(e,t){v.attrHooks[t]=v.extend(v.attrHooks[t],{set:function(e,n){if(n==="")return e.setAttribute(t,"auto"),n}})}),v.attrHooks.contenteditable={get:j.get,set:function(e,t,n){t===""&&(t="false"),j.set(e,t,n)}}),v.support.hrefNormalized||v.each(["href","src","width","height"],function(e,n){v.attrHooks[n]=v.extend(v.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return r===null?t:r}})}),v.support.style||(v.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=t+""}}),v.support.optSelected||(v.propHooks.selected=v.extend(v.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),v.support.enctype||(v.propFix.enctype="encoding"),v.support.checkOn||v.each(["radio","checkbox"],function(){v.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}}),v.each(["radio","checkbox"],function(){v.valHooks[this]=v.extend(v.valHooks[this],{set:function(e,t){if(v.isArray(t))return e.checked=v.inArray(v(e).val(),t)>=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f<n.length;f++){l=J.exec(n[f])||[],c=l[1],h=(l[2]||"").split(".").sort(),g=v.event.special[c]||{},c=(s?g.delegateType:g.bindType)||c,g=v.event.special[c]||{},p=v.extend({type:c,origType:l[1],data:i,handler:r,guid:r.guid,selector:s,needsContext:s&&v.expr.match.needsContext.test(s),namespace:h.join(".")},d),m=a[c];if(!m){m=a[c]=[],m.delegateCount=0;if(!g.setup||g.setup.call(e,i,h,u)===!1)e.addEventListener?e.addEventListener(c,u,!1):e.attachEvent&&e.attachEvent("on"+c,u)}g.add&&(g.add.call(e,p),p.handler.guid||(p.handler.guid=r.guid)),s?m.splice(m.delegateCount++,0,p):m.push(p),v.event.global[c]=!0}e=null},global:{},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,m,g=v.hasData(e)&&v._data(e);if(!g||!(h=g.events))return;t=v.trim(Z(t||"")).split(" ");for(s=0;s<t.length;s++){o=J.exec(t[s])||[],u=a=o[1],f=o[2];if(!u){for(u in h)v.event.remove(e,u+t[s],n,r,!0);continue}p=v.event.special[u]||{},u=(r?p.delegateType:p.bindType)||u,d=h[u]||[],l=d.length,f=f?new RegExp("(^|\\.)"+f.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(c=0;c<d.length;c++)m=d[c],(i||a===m.origType)&&(!n||n.guid===m.guid)&&(!f||f.test(m.namespace))&&(!r||r===m.selector||r==="**"&&m.selector)&&(d.splice(c--,1),m.selector&&d.delegateCount--,p.remove&&p.remove.call(e,m));d.length===0&&l!==d.length&&((!p.teardown||p.teardown.call(e,f,g.handle)===!1)&&v.removeEvent(e,u,g.handle),delete h[u])}v.isEmptyObject(h)&&(delete g.handle,v.removeData(e,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(n,r,s,o){if(!s||s.nodeType!==3&&s.nodeType!==8){var u,a,f,l,c,h,p,d,m,g,y=n.type||n,b=[];if(Y.test(y+v.event.triggered))return;y.indexOf("!")>=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f<m.length&&!n.isPropagationStopped();f++)l=m[f][0],n.type=m[f][1],d=(v._data(l,"events")||{})[n.type]&&v._data(l,"handle"),d&&d.apply(l,r),d=h&&l[h],d&&v.acceptData(l)&&d.apply&&d.apply(l,r)===!1&&n.preventDefault();return n.type=y,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(s.ownerDocument,r)===!1)&&(y!=="click"||!v.nodeName(s,"a"))&&v.acceptData(s)&&h&&s[y]&&(y!=="focus"&&y!=="blur"||n.target.offsetWidth!==0)&&!v.isWindow(s)&&(c=s[h],c&&(s[h]=null),v.event.triggered=y,s[y](),v.event.triggered=t,c&&(s[h]=c)),n.result}return},dispatch:function(n){n=v.event.fix(n||e.event);var r,i,s,o,u,a,f,c,h,p,d=(v._data(this,"events")||{})[n.type]||[],m=d.delegateCount,g=l.call(arguments),y=!n.exclusive&&!n.namespace,b=v.event.special[n.type]||{},w=[];g[0]=n,n.delegateTarget=this;if(b.preDispatch&&b.preDispatch.call(this,n)===!1)return;if(m&&(!n.button||n.type!=="click"))for(s=n.target;s!=this;s=s.parentNode||this)if(s.disabled!==!0||n.type!=="click"){u={},f=[];for(r=0;r<m;r++)c=d[r],h=c.selector,u[h]===t&&(u[h]=c.needsContext?v(h,this).index(s)>=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r<w.length&&!n.isPropagationStopped();r++){a=w[r],n.currentTarget=a.elem;for(i=0;i<a.matches.length&&!n.isImmediatePropagationStopped();i++){c=a.matches[i];if(y||!n.namespace&&!c.namespace||n.namespace_re&&n.namespace_re.test(c.namespace))n.data=c.data,n.handleObj=c,o=((v.event.special[c.origType]||{}).handle||c.handler).apply(a.elem,g),o!==t&&(n.result=o,o===!1&&(n.preventDefault(),n.stopPropagation()))}}return b.postDispatch&&b.postDispatch.call(this,n),n.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return e.which==null&&(e.which=t.charCode!=null?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,s,o,u=n.button,a=n.fromElement;return e.pageX==null&&n.clientX!=null&&(r=e.target.ownerDocument||i,s=r.documentElement,o=r.body,e.pageX=n.clientX+(s&&s.scrollLeft||o&&o.scrollLeft||0)-(s&&s.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(s&&s.scrollTop||o&&o.scrollTop||0)-(s&&s.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?n.toElement:a),!e.which&&u!==t&&(e.which=u&1?1:u&2?3:u&4?2:0),e}},fix:function(e){if(e[v.expando])return e;var t,n,r=e,s=v.event.fixHooks[e.type]||{},o=s.props?this.props.concat(s.props):this.props;e=v.Event(r);for(t=o.length;t;)n=o[--t],e[n]=r[n];return e.target||(e.target=r.srcElement||i),e.target.nodeType===3&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,r):e},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,n){v.isWindow(this)&&(this.onbeforeunload=n)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,n,r){var i=v.extend(new v.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?v.event.trigger(i,null,t):v.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},v.event.handle=v.event.dispatch,v.removeEvent=i.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]=="undefined"&&(e[r]=null),e.detachEvent(r,n))},v.Event=function(e,t){if(!(this instanceof v.Event))return new v.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?tt:et):this.type=e,t&&v.extend(this,t),this.timeStamp=e&&e.timeStamp||v.now(),this[v.expando]=!0},v.Event.prototype={preventDefault:function(){this.isDefaultPrevented=tt;var e=this.originalEvent;if(!e)return;e.preventDefault?e.preventDefault():e.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=tt;var e=this.originalEvent;if(!e)return;e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=tt,this.stopPropagation()},isDefaultPrevented:et,isPropagationStopped:et,isImmediatePropagationStopped:et},v.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){v.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,s=e.handleObj,o=s.selector;if(!i||i!==r&&!v.contains(r,i))e.type=s.origType,n=s.handler.apply(this,arguments),e.type=t;return n}}}),v.support.submitBubbles||(v.event.special.submit={setup:function(){if(v.nodeName(this,"form"))return!1;v.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=v.nodeName(n,"input")||v.nodeName(n,"button")?n.form:t;r&&!v._data(r,"_submit_attached")&&(v.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),v._data(r,"_submit_attached",!0))})},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&v.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){if(v.nodeName(this,"form"))return!1;v.event.remove(this,"._submit")}}),v.support.changeBubbles||(v.event.special.change={setup:function(){if($.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")v.event.add(this,"propertychange._change",function(e){e.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),v.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),v.event.simulate("change",this,e,!0)});return!1}v.event.add(this,"beforeactivate._change",function(e){var t=e.target;$.test(t.nodeName)&&!v._data(t,"_change_attached")&&(v.event.add(t,"change._change",function(e){this.parentNode&&!e.isSimulated&&!e.isTrigger&&v.event.simulate("change",this.parentNode,e,!0)}),v._data(t,"_change_attached",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||t.type!=="radio"&&t.type!=="checkbox")return e.handleObj.handler.apply(this,arguments)},teardown:function(){return v.event.remove(this,"._change"),!$.test(this.nodeName)}}),v.support.focusinBubbles||v.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){v.event.simulate(t,e.target,v.event.fix(e),!0)};v.event.special[t]={setup:function(){n++===0&&i.addEventListener(e,r,!0)},teardown:function(){--n===0&&i.removeEventListener(e,r,!0)}}}),v.fn.extend({on:function(e,n,r,i,s){var o,u;if(typeof e=="object"){typeof n!="string"&&(r=r||n,n=t);for(u in e)this.on(u,n,r,e[u],s);return this}r==null&&i==null?(i=n,r=n=t):i==null&&(typeof n=="string"?(i=r,r=t):(i=r,r=n,n=t));if(i===!1)i=et;else if(!i)return this;return s===1&&(o=i,i=function(e){return v().off(e),o.apply(this,arguments)},i.guid=o.guid||(o.guid=v.guid++)),this.each(function(){v.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,s;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,v(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if(typeof e=="object"){for(s in e)this.off(s,n,e[s]);return this}if(n===!1||typeof n=="function")r=n,n=t;return r===!1&&(r=et),this.each(function(){v.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,n){return v(this.context).on(e,this.selector,t,n),this},die:function(e,t){return v(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){v.event.trigger(e,t,this)})},triggerHandler:function(e,t){if(this[0])return v.event.trigger(e,t,this[0],!0)},toggle:function(e){var t=arguments,n=e.guid||v.guid++,r=0,i=function(n){var i=(v._data(this,"lastToggle"+e.guid)||0)%r;return v._data(this,"lastToggle"+e.guid,i+1),n.preventDefault(),t[i].apply(this,arguments)||!1};i.guid=n;while(r<t.length)t[r++].guid=n;return this.click(i)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),v.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){v.fn[t]=function(e,n){return n==null&&(n=e,e=null),arguments.length>0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u<a;u++)if(s=e[u])if(!n||n(s,r,i))o.push(s),f&&t.push(u);return o}function ct(e,t,n,r,i,s){return r&&!r[d]&&(r=ct(r)),i&&!i[d]&&(i=ct(i,s)),N(function(s,o,u,a){var f,l,c,h=[],p=[],d=o.length,v=s||dt(t||"*",u.nodeType?[u]:u,[]),m=e&&(s||!t)?lt(v,h,e,u,a):v,g=n?i||(s?e:d||r)?[]:o:m;n&&n(m,g,u,a);if(r){f=lt(g,p),r(f,[],u,a),l=f.length;while(l--)if(c=f[l])g[p[l]]=!(m[p[l]]=c)}if(s){if(i||e){if(i){f=[],l=g.length;while(l--)(c=g[l])&&f.push(m[l]=c);i(null,g=[],f,a)}l=g.length;while(l--)(c=g[l])&&(f=i?T.call(s,c):h[l])>-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a<s;a++)if(n=i.relative[e[a].type])h=[at(ft(h),n)];else{n=i.filter[e[a].type].apply(null,e[a].matches);if(n[d]){r=++a;for(;r<s;r++)if(i.relative[e[r].type])break;return ct(a>1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a<r&&ht(e.slice(a,r)),r<s&&ht(e=e.slice(r)),r<s&&e.join(""))}h.push(n)}return ft(h)}function pt(e,t){var r=t.length>0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r<i;r++)nt(e,t[r],n);return n}function vt(e,t,n,r,s){var o,u,f,l,c,h=ut(e),p=h.length;if(!r&&h.length===1){u=h[0]=h[0].slice(0);if(u.length>2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;t<n;t++)if(this[t]===e)return t;return-1},N=function(e,t){return e[d]=t==null||t,e},C=function(){var e={},t=[];return N(function(n,r){return t.push(n)>i.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="<a name='"+d+"'></a><div name='"+d+"'></div>",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:st(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:st(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},f=y.compareDocumentPosition?function(e,t){return e===t?(l=!0,0):(!e.compareDocumentPosition||!t.compareDocumentPosition?e.compareDocumentPosition:e.compareDocumentPosition(t)&4)?-1:1}:function(e,t){if(e===t)return l=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],s=[],o=e.parentNode,u=t.parentNode,a=o;if(o===u)return ot(e,t);if(!o)return-1;if(!u)return 1;while(a)i.unshift(a),a=a.parentNode;a=u;while(a)s.unshift(a),a=a.parentNode;n=i.length,r=s.length;for(var f=0;f<n&&f<r;f++)if(i[f]!==s[f])return ot(i[f],s[f]);return f===n?ot(e,s[f],-1):ot(i[f],t,1)},[0,0].sort(f),h=!l,nt.uniqueSort=function(e){var t,n=[],r=1,i=0;l=h,e.sort(f);if(l){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e},nt.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},a=nt.compile=function(e,t){var n,r=[],i=[],s=A[d][e+" "];if(!s){t||(t=ut(e)),n=t.length;while(n--)s=ht(t[n]),s[d]?r.push(s):i.push(s);s=A(e,pt(i,r))}return s},g.querySelectorAll&&function(){var e,t=vt,n=/'|\\/g,r=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,i=[":focus"],s=[":active"],u=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector||y.oMatchesSelector||y.msMatchesSelector;K(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="<p test=''></p>",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="<input type='hidden'/>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t<n;t++)if(v.contains(u[t],this))return!0});o=this.pushStack("","find",e);for(t=0,n=this.length;t<n;t++){r=o.length,v.find(e,this[t],o);if(t>0)for(i=r;i<o.length;i++)for(s=0;s<r;s++)if(o[s]===o[i]){o.splice(i--,1);break}}return o},has:function(e){var t,n=v(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(v.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1),"not",e)},filter:function(e){return this.pushStack(ft(this,e,!0),"filter",e)},is:function(e){return!!e&&(typeof e=="string"?st.test(e)?v(e,this.context).index(this[0])>=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r<i;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&n.nodeType!==11){if(o?o.index(n)>-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/<tbody/i,gt=/<|&#?\w+;/,yt=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,wt=new RegExp("<(?:"+ct+")[\\s/>]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,Nt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X<div>","</div>"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1></$2>");try{for(;r<i;r++)n=this[r]||{},n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),n.innerHTML=e);n=0}catch(s){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){return ut(this[0])?this.length?this.pushStack(v(v.isFunction(e)?e():e),"replaceWith",e):this:v.isFunction(e)?this.each(function(t){var n=v(this),r=n.html();n.replaceWith(e.call(this,t,r))}):(typeof e!="string"&&(e=v(e).detach()),this.each(function(){var t=this.nextSibling,n=this.parentNode;v(this).remove(),t?v(t).before(e):v(n).append(e)}))},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=[].concat.apply([],e);var i,s,o,u,a=0,f=e[0],l=[],c=this.length;if(!v.support.checkClone&&c>1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a<c;a++)r.call(n&&v.nodeName(this[a],"table")?Lt(this[a],"tbody"):this[a],a===u?o:v.clone(o,!0,!0))}o=s=null,l.length&&v.each(l,function(e,t){t.src?v.ajax?v.ajax({url:t.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):v.error("no ajax"):v.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Tt,"")),t.parentNode&&t.parentNode.removeChild(t)})}return this}}),v.buildFragment=function(e,n,r){var s,o,u,a=e[0];return n=n||i,n=!n.nodeType&&n[0]||n,n=n.ownerDocument||n,e.length===1&&typeof a=="string"&&a.length<512&&n===i&&a.charAt(0)==="<"&&!bt.test(a)&&(v.support.checkClone||!St.test(a))&&(v.support.html5Clone||!wt.test(a))&&(o=!0,s=v.fragments[a],u=s!==t),s||(s=n.createDocumentFragment(),v.clean(e,n,s,r),o&&(v.fragments[a]=u&&s)),{fragment:s,cacheable:o}},v.fragments={},v.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){v.fn[e]=function(n){var r,i=0,s=[],o=v(n),u=o.length,a=this.length===1&&this[0].parentNode;if((a==null||a&&a.nodeType===11&&a.childNodes.length===1)&&u===1)return o[t](this[0]),this;for(;i<u;i++)r=(i>0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1></$2>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]==="<table>"&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("<div>").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r<i;r++)n=e[r],Vn[n]=Vn[n]||[],Vn[n].unshift(t)},prefilter:function(e,t){t?Xn.unshift(e):Xn.push(e)}}),v.Tween=Yn,Yn.prototype={constructor:Yn,init:function(e,t,n,r,i,s){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=s||(v.cssNumber[n]?"":"px")},cur:function(){var e=Yn.propHooks[this.prop];return e&&e.get?e.get(this):Yn.propHooks._default.get(this)},run:function(e){var t,n=Yn.propHooks[this.prop];return this.options.duration?this.pos=t=v.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Yn.propHooks._default.set(this),this}},Yn.prototype.init.prototype=Yn.prototype,Yn.propHooks={_default:{get:function(e){var t;return e.elem[e.prop]==null||!!e.elem.style&&e.elem.style[e.prop]!=null?(t=v.css(e.elem,e.prop,!1,""),!t||t==="auto"?0:t):e.elem[e.prop]},set:function(e){v.fx.step[e.prop]?v.fx.step[e.prop](e):e.elem.style&&(e.elem.style[v.cssProps[e.prop]]!=null||v.cssHooks[e.prop])?v.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Yn.propHooks.scrollTop=Yn.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},v.each(["toggle","show","hide"],function(e,t){var n=v.fn[t];v.fn[t]=function(r,i,s){return r==null||typeof r=="boolean"||!e&&v.isFunction(r)&&v.isFunction(i)?n.apply(this,arguments):this.animate(Zn(t,!0),r,i,s)}}),v.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Gt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=v.isEmptyObject(e),s=v.speed(t,n,r),o=function(){var t=Kn(this,v.extend({},e),s);i&&t.stop(!0)};return i||s.queue===!1?this.each(o):this.queue(s.queue,o)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return typeof e!="string"&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=e!=null&&e+"queueHooks",s=v.timers,o=v._data(this);if(n)o[n]&&o[n].stop&&i(o[n]);else for(n in o)o[n]&&o[n].stop&&Wn.test(n)&&i(o[n]);for(n=s.length;n--;)s[n].elem===this&&(e==null||s[n].queue===e)&&(s[n].anim.stop(r),t=!1,s.splice(n,1));(t||!r)&&v.dequeue(this,e)})}}),v.each({slideDown:Zn("show"),slideUp:Zn("hide"),slideToggle:Zn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){v.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),v.speed=function(e,t,n){var r=e&&typeof e=="object"?v.extend({},e):{complete:n||!n&&t||v.isFunction(e)&&e,duration:e,easing:n&&t||t&&!v.isFunction(t)&&t};r.duration=v.fx.off?0:typeof r.duration=="number"?r.duration:r.duration in v.fx.speeds?v.fx.speeds[r.duration]:v.fx.speeds._default;if(r.queue==null||r.queue===!0)r.queue="fx";return r.old=r.complete,r.complete=function(){v.isFunction(r.old)&&r.old.call(this),r.queue&&v.dequeue(this,r.queue)},r},v.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},v.timers=[],v.fx=Yn.prototype.init,v.fx.tick=function(){var e,n=v.timers,r=0;qn=v.now();for(;r<n.length;r++)e=n[r],!e()&&n[r]===e&&n.splice(r--,1);n.length||v.fx.stop(),qn=t},v.fx.timer=function(e){e()&&v.timers.push(e)&&!Rn&&(Rn=setInterval(v.fx.tick,v.fx.interval))},v.fx.interval=13,v.fx.stop=function(){clearInterval(Rn),Rn=null},v.fx.speeds={slow:600,fast:200,_default:400},v.fx.step={},v.expr&&v.expr.filters&&(v.expr.filters.animated=function(e){return v.grep(v.timers,function(t){return e===t.elem}).length});var er=/^(?:body|html)$/i;v.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){v.offset.setOffset(this,e,t)});var n,r,i,s,o,u,a,f={top:0,left:0},l=this[0],c=l&&l.ownerDocument;if(!c)return;return(r=c.body)===l?v.offset.bodyOffset(l):(n=c.documentElement,v.contains(n,l)?(typeof l.getBoundingClientRect!="undefined"&&(f=l.getBoundingClientRect()),i=tr(c),s=n.clientTop||r.clientTop||0,o=n.clientLeft||r.clientLeft||0,u=i.pageYOffset||n.scrollTop,a=i.pageXOffset||n.scrollLeft,{top:f.top+u-s,left:f.left+a-o}):f)},v.offset={bodyOffset:function(e){var t=e.offsetTop,n=e.offsetLeft;return v.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(v.css(e,"marginTop"))||0,n+=parseFloat(v.css(e,"marginLeft"))||0),{top:t,left:n}},setOffset:function(e,t,n){var r=v.css(e,"position");r==="static"&&(e.style.position="relative");var i=v(e),s=i.offset(),o=v.css(e,"top"),u=v.css(e,"left"),a=(r==="absolute"||r==="fixed")&&v.inArray("auto",[o,u])>-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window);
\ No newline at end of file +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="<select t=''><option selected=''></option></select>",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=jb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=kb(b);function nb(){}nb.prototype=d.filters=d.pseudos,d.setFilters=new nb;function ob(a,b){var c,e,f,g,h,i,j,k=x[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=Q.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?db.error(a):x(a,i).slice(0)}function pb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},W=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a>",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=$.test(e)?this.mouseHooks:Z.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||z),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||z,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==db()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===db()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=z.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===L&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&(a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault())?bb:cb):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:cb,isPropagationStopped:cb,isImmediatePropagationStopped:cb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=bb,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=bb,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submitBubbles||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?b.form:void 0;c&&!n._data(c,"submitBubbles")&&(n.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),n._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.changeBubbles||(n.event.special.change={setup:function(){return Y.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),n.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),n.event.simulate("change",this,a,!0)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;Y.test(b.nodeName)&&!n._data(b,"changeBubbles")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a,!0)}),n._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!Y.test(this.nodeName)}}),l.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=cb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return n().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=cb),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});function eb(a){var b=fb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var fb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gb=/ jQuery\d+="(?:null|\d+)"/g,hb=new RegExp("<(?:"+fb+")[\\s/>]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/<tbody/i,mb=/<|&#?\w+;/,nb=/<(?:script|style|link)/i,ob=/checked\s*(?:[^=]|=\s*.checked.)/i,pb=/^$|\/(?:java|ecma)script/i,qb=/^true\/(.*)/,rb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,sb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1></$2>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?"<table>"!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Db[0].contentWindow||Db[0].contentDocument).document,b.write(),b.close(),c=Fb(a,b),Db.detach()),Eb[a]=c),c}!function(){var a,b,c=z.createElement("div"),d="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],a.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(a.style.opacity),l.cssFloat=!!a.style.cssFloat,c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===c.style.backgroundClip,a=c=null,l.shrinkWrapBlocks=function(){var a,c,e,f;if(null==b){if(a=z.getElementsByTagName("body")[0],!a)return;f="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",c=z.createElement("div"),e=z.createElement("div"),a.appendChild(c).appendChild(e),b=!1,typeof e.style.zoom!==L&&(e.style.cssText=d+";width:1px;padding:1px;zoom:1",e.innerHTML="<div></div>",e.firstChild.style.width="5px",b=3!==e.offsetWidth),a.removeChild(c),a=c=e=null}return b}}();var Hb=/^margin/,Ib=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Jb,Kb,Lb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Jb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),Ib.test(g)&&Hb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):z.documentElement.currentStyle&&(Jb=function(a){return a.currentStyle},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ib.test(g)&&!Lb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Mb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h=z.createElement("div"),i="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",j="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";h.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",b=h.getElementsByTagName("a")[0],b.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(b.style.opacity),l.cssFloat=!!b.style.cssFloat,h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,b=h=null,n.extend(l,{reliableHiddenOffsets:function(){if(null!=c)return c;var a,b,d,e=z.createElement("div"),f=z.getElementsByTagName("body")[0];if(f)return e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=z.createElement("div"),a.style.cssText=i,f.appendChild(a).appendChild(e),e.innerHTML="<table><tr><td></td><td>t</td></tr></table>",b=e.getElementsByTagName("td"),b[0].style.cssText="padding:0;margin:0;border:0;display:none",d=0===b[0].offsetHeight,b[0].style.display="",b[1].style.display="none",c=d&&0===b[0].offsetHeight,f.removeChild(a),e=f=null,c},boxSizing:function(){return null==d&&k(),d},boxSizingReliable:function(){return null==e&&k(),e},pixelPosition:function(){return null==f&&k(),f},reliableMarginRight:function(){var b,c,d,e;if(null==g&&a.getComputedStyle){if(b=z.getElementsByTagName("body")[0],!b)return;c=z.createElement("div"),d=z.createElement("div"),c.style.cssText=i,b.appendChild(c).appendChild(d),e=d.appendChild(z.createElement("div")),e.style.cssText=d.style.cssText=j,e.style.marginRight=e.style.width="0",d.style.width="1px",g=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight),b.removeChild(c)}return g}});function k(){var b,c,h=z.getElementsByTagName("body")[0];h&&(b=z.createElement("div"),c=z.createElement("div"),b.style.cssText=i,h.appendChild(b).appendChild(c),c.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%",n.swap(h,null!=h.style.zoom?{zoom:1}:{},function(){d=4===c.offsetWidth}),e=!0,f=!1,g=!0,a.getComputedStyle&&(f="1%"!==(a.getComputedStyle(c,null)||{}).top,e="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width),h.removeChild(b),c=h=null)}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Nb=/alpha\([^)]*\)/i,Ob=/opacity\s*=\s*([^)]*)/,Pb=/^(none|table(?!-c[ea]).+)/,Qb=new RegExp("^("+T+")(.*)$","i"),Rb=new RegExp("^([+-])=("+T+")","i"),Sb={position:"absolute",visibility:"hidden",display:"block"},Tb={letterSpacing:0,fontWeight:400},Ub=["Webkit","O","Moz","ms"];function Vb(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ub.length;while(e--)if(b=Ub[e]+c,b in a)return b;return d}function Wb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=n._data(d,"olddisplay",Gb(d.nodeName)))):f[g]||(e=V(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Xb(a,b,c){var d=Qb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Yb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Zb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Jb(a),g=l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Kb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ib.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Yb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Kb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=Vb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Rb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]="",i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Vb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Kb(a,b,d)),"normal"===f&&b in Tb&&(f=Tb[b]),""===c||c?(e=parseFloat(f),c===!0||n.isNumeric(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&Pb.test(n.css(a,"display"))?n.swap(a,Sb,function(){return Zb(a,b,d)}):Zb(a,b,d):void 0},set:function(a,c,d){var e=d&&Jb(a);return Xb(a,c,d?Yb(a,b,d,l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Ob.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Nb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Nb.test(f)?f.replace(Nb,e):f+" "+e)}}),n.cssHooks.marginRight=Mb(l.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},Kb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Hb.test(a)||(n.cssHooks[a+b].set=Xb)}),n.fn.extend({css:function(a,b){return W(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Jb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b) +},a,b,arguments.length>1)},show:function(){return Wb(this,!0)},hide:function(){return Wb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function $b(a,b,c,d,e){return new $b.prototype.init(a,b,c,d,e)}n.Tween=$b,$b.prototype={constructor:$b,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=$b.propHooks[this.prop];return a&&a.get?a.get(this):$b.propHooks._default.get(this)},run:function(a){var b,c=$b.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):$b.propHooks._default.set(this),this}},$b.prototype.init.prototype=$b.prototype,$b.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},$b.propHooks.scrollTop=$b.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=$b.prototype.init,n.fx.step={};var _b,ac,bc=/^(?:toggle|show|hide)$/,cc=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),dc=/queueHooks$/,ec=[jc],fc={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=cc.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&cc.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function gc(){return setTimeout(function(){_b=void 0}),_b=n.now()}function hc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=U[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function ic(a,b,c){for(var d,e=(fc[b]||[]).concat(fc["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function jc(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&V(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k=Gb(a.nodeName),"none"===j&&(j=k),"inline"===j&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==k?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],bc.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}if(!n.isEmptyObject(o)){r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=ic(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function kc(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function lc(a,b,c){var d,e,f=0,g=ec.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=_b||gc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:_b||gc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(kc(k,j.opts.specialEasing);g>f;f++)if(d=ec[f].call(j,a,k,j.opts))return d;return n.map(k,ic,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(lc,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],fc[c]=fc[c]||[],fc[c].unshift(b)},prefilter:function(a,b){b?ec.unshift(a):ec.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=lc(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&dc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(hc(b,!0),a,d,e)}}),n.each({slideDown:hc("show"),slideUp:hc("hide"),slideToggle:hc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(_b=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),_b=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ac||(ac=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(ac),ac=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e=z.createElement("div");e.setAttribute("className","t"),e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=e.getElementsByTagName("a")[0],c=z.createElement("select"),d=c.appendChild(z.createElement("option")),b=e.getElementsByTagName("input")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==e.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=d.selected,l.enctype=!!z.createElement("form").enctype,c.disabled=!0,l.optDisabled=!d.disabled,b=z.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value,a=b=c=d=e=null}();var mc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(mc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.text(a)}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var nc,oc,pc=n.expr.attrHandle,qc=/^(?:checked|selected)$/i,rc=l.getSetAttribute,sc=l.input;n.fn.extend({attr:function(a,b){return W(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===L?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?oc:nc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(F);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?sc&&rc||!qc.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(rc?c:d)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),oc={set:function(a,b,c){return b===!1?n.removeAttr(a,c):sc&&rc||!qc.test(c)?a.setAttribute(!rc&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=pc[b]||n.find.attr;pc[b]=sc&&rc||!qc.test(b)?function(a,b,d){var e,f;return d||(f=pc[b],pc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,pc[b]=f),e}:function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),sc&&rc||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):nc&&nc.set(a,b,c)}}),rc||(nc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},pc.id=pc.name=pc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:nc.set},n.attrHooks.contenteditable={set:function(a,b,c){nc.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var tc=/^(?:input|select|textarea|button|object)$/i,uc=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return W(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):tc.test(a.nodeName)||uc.test(a.nodeName)&&a.href?0:-1}}}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var vc=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(F)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===L||"boolean"===c)&&(this.className&&n._data(this,"__className__",this.className),this.className=this.className||a===!1?"":n._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(vc," ").indexOf(b)>=0)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var wc=n.now(),xc=/\?/,yc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(yc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var zc,Ac,Bc=/#.*$/,Cc=/([?&])_=[^&]*/,Dc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Ec=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Fc=/^(?:GET|HEAD)$/,Gc=/^\/\//,Hc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ic={},Jc={},Kc="*/".concat("*");try{Ac=location.href}catch(Lc){Ac=z.createElement("a"),Ac.href="",Ac=Ac.href}zc=Hc.exec(Ac.toLowerCase())||[];function Mc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(F)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nc(a,b,c,d){var e={},f=a===Jc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Oc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Pc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Qc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ac,type:"GET",isLocal:Ec.test(zc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Oc(Oc(a,n.ajaxSettings),b):Oc(n.ajaxSettings,a)},ajaxPrefilter:Mc(Ic),ajaxTransport:Mc(Jc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Dc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||Ac)+"").replace(Bc,"").replace(Gc,zc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(F)||[""],null==k.crossDomain&&(c=Hc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===zc[1]&&c[2]===zc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(zc[3]||("http:"===zc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),Nc(Ic,k,b,v),2===t)return v;h=k.global,h&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Fc.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(xc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Cc.test(e)?e.replace(Cc,"$1_="+wc++):e+(xc.test(e)?"&":"?")+"_="+wc++)),k.ifModified&&(n.lastModified[e]&&v.setRequestHeader("If-Modified-Since",n.lastModified[e]),n.etag[e]&&v.setRequestHeader("If-None-Match",n.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Kc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Nc(Jc,k,b,v)){v.readyState=1,h&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Pc(k,v,c)),u=Qc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(n.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!l.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||n.css(a,"display"))},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var Rc=/%20/g,Sc=/\[\]$/,Tc=/\r?\n/g,Uc=/^(?:submit|button|image|reset|file)$/i,Vc=/^(?:input|select|textarea|keygen)/i;function Wc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Sc.test(a)?d(a,e):Wc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Wc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Wc(c,a[c],b,e);return d.join("&").replace(Rc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Vc.test(this.nodeName)&&!Uc.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Tc,"\r\n")}}):{name:b.name,value:c.replace(Tc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&$c()||_c()}:$c;var Xc=0,Yc={},Zc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Yc)Yc[a](void 0,!0)}),l.cors=!!Zc&&"withCredentials"in Zc,Zc=l.ajax=!!Zc,Zc&&n.ajaxTransport(function(a){if(!a.crossDomain||l.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Xc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Yc[g],b=void 0,f.onreadystatechange=n.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Yc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function $c(){try{return new a.XMLHttpRequest}catch(b){}}function _c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=z.head||n("head")[0]||z.documentElement;return{send:function(d,e){b=z.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ad=[],bd=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=ad.pop()||n.expando+"_"+wc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(bd.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&bd.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(bd,"$1"+e):b.jsonp!==!1&&(b.url+=(xc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,ad.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||z;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var cd=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&cd)return cd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h,a.length),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&n.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var dd=a.document.documentElement;function ed(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(typeof e.getBoundingClientRect!==L&&(d=e.getBoundingClientRect()),c=ed(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||dd;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||dd})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return W(this,function(a,d,e){var f=ed(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Mb(l.pixelPosition,function(a,c){return c?(c=Kb(a,b),Ib.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return W(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var fd=a.jQuery,gd=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=gd),b&&a.jQuery===n&&(a.jQuery=fd),n},typeof b===L&&(a.jQuery=a.$=n),n}); diff --git a/phpBB/assets/javascript/plupload.js b/phpBB/assets/javascript/plupload.js new file mode 100644 index 0000000000..8ffd452a09 --- /dev/null +++ b/phpBB/assets/javascript/plupload.js @@ -0,0 +1,682 @@ +plupload.addI18n(phpbb.plupload.i18n); +phpbb.plupload.ids = []; + +(function($) { // Avoid conflicts with other libraries + +"use strict"; + +/** + * Set up the uploader. + * + * @return undefined + */ +phpbb.plupload.initialize = function() { + // Initialize the Plupload uploader. + uploader.init(); + + // Set attachment data. + phpbb.plupload.setData(phpbb.plupload.data); + phpbb.plupload.updateMultipartParams(phpbb.plupload.getSerializedData()); + + // Only execute if Plupload initialized successfully. + uploader.bind('Init', function() { + phpbb.plupload.form = $(phpbb.plupload.config.form_hook)[0], + phpbb.plupload.rowTpl = $('#attach-row-tpl')[0].outerHTML; + + // Hide the basic upload panel and remove the attach row template. + $('#attach-row-tpl, #attach-panel-basic').remove(); + // Show multi-file upload options. + $('#attach-panel-multi').show(); + }); + + uploader.bind('PostInit', function() { + // Point out the drag-and-drop zone if it's supported. + if (uploader.features.dragdrop) { + $('#drag-n-drop-message').show(); + } + }); +}; + +/** + * Unsets all elements in the object uploader.settings.multipart_params whose keys + * begin with 'attachment_data[' + * + * @return undefined + */ +phpbb.plupload.clearParams = function() { + var obj = uploader.settings.multipart_params; + for (var key in obj) { + if (!obj.hasOwnProperty(key) || key.indexOf('attachment_data[') !== 0) { + continue; + } + + delete uploader.settings.multipart_params[key]; + } +}; + +/** + * Update uploader.settings.multipart_params object with new data. + * + * @param object obj + * @return undefined + */ +phpbb.plupload.updateMultipartParams = function(obj) { + uploader.settings.multipart_params = $.extend( + uploader.settings.multipart_params, + obj + ); +}; + +/** + * Convert the array of attachment objects into an object that PHP would expect as POST data. + * + * @return object An object in the form 'attachment_data[i][key]': value as + * expected by the server + */ +phpbb.plupload.getSerializedData = function() { + var obj = {}; + for (var i = 0; i < phpbb.plupload.data.length; i++) { + var datum = phpbb.plupload.data[i]; + for (var key in datum) { + if (!datum.hasOwnProperty(key)) { + continue; + } + + obj['attachment_data[' + i + '][' + key + ']'] = datum[key]; + } + } + return obj; +}; + +/** + * Get the index from the phpbb.plupload.data array where the given + * attachment id appears. + * + * @param int attach_id The attachment id of the file. + * @return bool Returns false if the id cannot be found. + * @return int Returns the index of the file if it exists. + */ +phpbb.plupload.getIndex = function(attach_id) { + var index = $.inArray(Number(attach_id), phpbb.plupload.ids); + return (index !== -1) ? index : false; +}; + +/** + * Set the data in phpbb.plupload.data and phpbb.plupload.ids arrays. + * + * @param array data Array containing the new data to use. In the form of + * array(index => object(property: value). Requires attach_id to be one of the object properties. + * + * @return undefined + */ +phpbb.plupload.setData = function(data) { + // Make sure that the array keys are reset. + phpbb.plupload.ids = phpbb.plupload.data = []; + phpbb.plupload.data = data; + + for (var i = 0; i < data.length; i++) { + phpbb.plupload.ids.push(Number(data[i].attach_id)); + } +}; + +/** + * Update the attachment data in the HTML and the phpbb & phpbb.plupload objects. + * + * @param array data Array containing the new data to use. + * @param string action The action that required the update. Used to update the inline attachment bbcodes. + * @param int index The index from phpbb.plupload_ids that was affected by the action. + * @param array downloadUrl Optional array of download urls to update. + * @return undefined + */ +phpbb.plupload.update = function(data, action, index, downloadUrl) { + + phpbb.plupload.updateBbcode(action, index); + phpbb.plupload.setData(data); + phpbb.plupload.updateRows(downloadUrl); + phpbb.plupload.clearParams(); + phpbb.plupload.updateMultipartParams(phpbb.plupload.getSerializedData()); +}; + +/** + * Update the relevant elements and hidden data for all attachments. + * + * @param array downloadUrl Optional array of download urls to update. + * @return undefined + */ +phpbb.plupload.updateRows = function(downloadUrl) { + for (var i = 0; i < phpbb.plupload.ids.length; i++) { + phpbb.plupload.updateRow(i, downloadUrl); + } +}; + +/** + * Insert a row for a new attachment. This expects an HTML snippet in the HTML + * using the id "attach-row-tpl" to be present. This snippet is cloned and the + * data for the file inserted into it. The row is then appended or prepended to + * #file-list based on the attach_order setting. + * + * @param object file Plupload file object for the new attachment. + * @return undefined + */ +phpbb.plupload.insertRow = function(file) { + var row = $(phpbb.plupload.rowTpl); + + row.attr('id', file.id); + row.find('.file-name').html(plupload.xmlEncode(file.name)); + row.find('.file-size').html(plupload.formatSize(file.size)); + + if (phpbb.plupload.order == 'desc') { + $('#file-list').prepend(row); + } else { + $('#file-list').append(row); + } +}; + +/** + * Update the relevant elements and hidden data for an attachment. + * + * @param int index The index from phpbb.plupload.ids of the attachment to edit. + * @param array downloadUrl Optional array of download urls to update. + * @return undefined + */ +phpbb.plupload.updateRow = function(index, downloadUrl) { + var attach = phpbb.plupload.data[index], + row = $('[data-attach-id="' + attach.attach_id + '"]'); + + // Add the link to the file + if (typeof downloadUrl !== 'undefined' && typeof downloadUrl[index] !== 'undefined') { + var url = downloadUrl[index].replace('&', '&'), + link = $('<a></a>'); + + link.attr('href', url).html(attach.real_filename); + row.find('.file-name').html(link) + } + + row.find('textarea').attr('name', 'comment_list[' + index + ']'); + phpbb.plupload.updateHiddenData(row, attach, index); +}; + +/** + * Update hidden input data for an attachment. + * + * @param object row jQuery object for the attachment row. + * @param object attach Attachment data object from phpbb.plupload.data + * @param int index Attachment index from phpbb.plupload.ids + * @return undefined + */ +phpbb.plupload.updateHiddenData = function(row, attach, index) { + row.find('input[type="hidden"]').remove(); + + for (var key in attach) { + var input = $('<input />') + .attr('type', 'hidden') + .attr('name', 'attachment_data[' + index + '][' + key +']') + .attr('value', attach[key]); + $('textarea', row).after(input); + } +}; + +/** + * Deleting a file removes it from the queue and fires an AJAX event to the + * server to tell it to remove the temporary attachment. The server + * responds with the updated attachment data list so that any future + * uploads can maintain state with the server + * + * @param object row jQuery object for the attachment row. + * @param int attachId Attachment id of the file to be removed. + * + * @return undefined + */ +phpbb.plupload.deleteFile = function(row, attachId) { + // If there's no attach id, then the file hasn't been uploaded. Simply delete the row. + if (typeof attachId === 'undefined') { + var file = uploader.getFile(row.attr('id')); + uploader.removeFile(file); + + row.slideUp(100, function() { + row.remove(); + phpbb.plupload.hideEmptyList(); + }); + } + + var index = phpbb.plupload.getIndex(attachId); + row.find('.file-status').toggleClass('file-uploaded file-working'); + + if (index === false) { + return; + } + var fields = {}; + fields['delete_file[' + index + ']'] = 1; + + var always = function() { + row.find('.file-status').removeClass('file-working'); + }; + + var done = function(response) { + if (typeof response !== 'object') { + return; + } + + // trigger_error() was called which likely means a permission error was encountered. + if (typeof response.title !== 'undefined') { + uploader.trigger('Error', {message: response.message}); + // We will have to assume that the deletion failed. So leave the file status as uploaded. + row.find('.file-status').toggleClass('file-uploaded'); + + return; + } + phpbb.plupload.update(response, 'removal', index); + // Check if the user can upload files now if he had reached the max files limit. + phpbb.plupload.handleMaxFilesReached(); + + if (row.attr('id')) { + var file = uploader.getFile(row.attr('id')); + uploader.removeFile(file); + } + row.slideUp(100, function() { + row.remove(); + // Hide the file list if it's empty now. + phpbb.plupload.hideEmptyList(); + }); + uploader.trigger('FilesRemoved'); + }; + + $.ajax(phpbb.plupload.config.url, { + type: 'POST', + data: $.extend(fields, phpbb.plupload.getSerializedData()), + headers: {'X-PHPBB-USING-PLUPLOAD': '1', 'X-Requested-With': 'XMLHttpRequest'} + }) + .always(always) + .done(done); +}; + +/** + * Check the attachment list and hide its container if it's empty. + * + * @return undefined + */ +phpbb.plupload.hideEmptyList = function() { + if (!$('#file-list').children().length) { + $('#file-list-container').slideUp(100); + } +} + +/** + * Update the indices used in inline attachment bbcodes. This ensures that the bbcodes + * correspond to the correct file after a file is added or removed. This should be called + * before the phpbb.plupload,data and phpbb.plupload.ids arrays are updated, otherwise it will + * not work correctly. + * + * @param string action The action that occurred -- either "addition" or "removal" + * @param int index The index of the attachment from phpbb.plupload.ids that was affected. + * + * @return undefined + */ +phpbb.plupload.updateBbcode = function(action, index) { + var textarea = $('#message', phpbb.plupload.form), + text = textarea.val(), + removal = (action === 'removal'); + + // Return if the bbcode isn't used at all. + if (text.indexOf('[attachment=') === -1) { + return; + } + + // Private function used to replace the bbcode. + var updateBbcode = function(match, fileName) { + // Remove the bbcode if the file was removed. + if (removal && index === i) { + return ''; + } + var newIndex = i + ((removal) ? -1 : 1); + return '[attachment=' + newIndex +']' + fileName + '[/attachment]'; + }; + + // Private function used to generate search regexp + var searchRegexp = function(index) { + return new RegExp('\\[attachment=' + index + '\\](.*?)\\[\\/attachment\\]', 'g'); + } + // The update order of the indices is based on the action taken to ensure that we don't corrupt + // the bbcode index by updating it several times as we move through the loop. + // Removal loop starts at the removed index and moves to the end of the array. + // Addition loop starts at the end of the array and moves to the added index at 0. + var searchLoop = function() { + if (typeof i === 'undefined') { + i = (removal) ? index : phpbb.plupload.ids.length - 1; + } + return (removal) ? (i < phpbb.plupload.ids.length): (i >= index); + } + var i; + + while (searchLoop()) { + text = text.replace(searchRegexp(i), updateBbcode); + (removal) ? i++ : i--; + } + textarea.val(text); +}; + +/** + * Get Plupload file objects based on their upload status. + * + * @param int status Plupload status - plupload.DONE, plupload.FAILED, plupload.QUEUED, + * plupload.STARTED, plupload.STOPPED + * + * @return Returns an array of the Plupload file objects matching the status. + */ +phpbb.plupload.getFilesByStatus = function(status) { + var files = []; + + $.each(uploader.files, function(i, file) { + if (file.status === status) { + files.push(file); + } + }); + return files; +} + +/** + * Check whether the user has reached the maximun number of files that he's allowed + * to upload. If so, disables the uploader and marks the queued files as failed. Otherwise + * makes sure that the uploader is enabled. + * + * @return bool Returns true if the limit has been reached. False if otherwise. + */ +phpbb.plupload.handleMaxFilesReached = function() { + // If there is no limit, the user is an admin or moderator. + if (!phpbb.plupload.maxFiles) { + return false; + } + + if (phpbb.plupload.maxFiles <= phpbb.plupload.ids.length) { + // Fail the rest of the queue. + phpbb.plupload.markQueuedFailed(phpbb.plupload.lang.TOO_MANY_ATTACHMENTS); + // Disable the uploader. + phpbb.plupload.disableUploader(); + uploader.trigger('Error', {message: phpbb.plupload.lang.TOO_MANY_ATTACHMENTS}); + + return true; + } else if(phpbb.plupload.maxFiles > phpbb.plupload.ids.length) { + // Enable the uploader if the user is under the limit + phpbb.plupload.enableUploader(); + } + return false; +} + +/** + * Disable the uploader + * + * @return undefined + */ +phpbb.plupload.disableUploader = function() { + $('#add_files').addClass('disabled'); + uploader.disableBrowse(); +} + +/** + * Enable the uploader + * + * @return undefined + */ +phpbb.plupload.enableUploader = function() { + $('#add_files').removeClass('disabled'); + uploader.disableBrowse(false); +} + +/** + * Mark all queued files as failed. + * + * @param string error Error message to present to the user. + * @return undefined + */ +phpbb.plupload.markQueuedFailed = function(error) { + var files = phpbb.plupload.getFilesByStatus(plupload.QUEUED); + + $.each(files, function(i, file) { + $('#' + file.id).find('.file-progress').hide(); + phpbb.plupload.fileError(file, error); + }); +} + +/** + * Marks a file as failed and sets the error message for it. + * + * @param object file Plupload file object that failed. + * @param string error Error message to present to the user. + * @return undefined + */ +phpbb.plupload.fileError = function(file, error) { + file.status = plupload.FAILED; + file.error = error; + $('#' + file.id).find('.file-status').addClass('file-error').attr({'data-error-title': phpbb.plupload.lang.ERROR, 'data-error-message': error}); +} + + + + +/** + * Set up the Plupload object and get some basic data. + */ +var uploader = new plupload.Uploader(phpbb.plupload.config); +phpbb.plupload.initialize(); + + + + +/** + * Insert inline attachment bbcode. + */ + $('#file-list').on('click', '.file-inline-bbcode', function(e) { + var attachId = $(this).parents('.attach-row').attr('data-attach-id'), + index = phpbb.plupload.getIndex(attachId); + + attach_inline(index, phpbb.plupload.data[index].real_filename); + e.preventDefault(); +}); + +/** + * Delete a file. + */ +$('#file-list').on('click', '.file-delete', function(e) { + var row = $(this).parents('.attach-row'), + attachId = row.attr('data-attach-id'); + + phpbb.plupload.deleteFile(row, attachId); + e.preventDefault(); +}); + +/** + * Display the error message for a particular file when the error icon is clicked. + */ +$('#file-list').on('click', '.file-error', function(e) { + phpbb.alert($(this).attr('data-error-title'), $(this).attr('data-error-message')); + e.preventDefault(); +}); + +/** + * Fires when an error occurs. + */ +uploader.bind('Error', function(up, error) { + error.file.name = plupload.xmlEncode(error.file.name); + + // The error message that Plupload provides for these is vague, so we'll be more specific. + if (error.code === plupload.FILE_EXTENSION_ERROR) { + error.message = plupload.translate('Invalid file extension:') + ' ' + error.file.name; + } else if (error.code === plupload.FILE_SIZE_ERROR) { + error.message = plupload.translate('File too large:') + ' ' + error.file.name; + } + phpbb.alert(phpbb.plupload.lang.ERROR, error.message); +}); + +/** + * Fires before a given file is about to be uploaded. This allows us to + * send the real filename along with the chunk. This is necessary because + * for some reason the filename is set to 'blob' whenever a file is chunked + * + * @param object up The plupload.Uploader object + * @param object file The plupload.File object that is about to be + * uploaded + * + * @return undefined + */ +uploader.bind('BeforeUpload', function(up, file) { + if (phpbb.plupload.handleMaxFilesReached()) { + return; + } + + phpbb.plupload.updateMultipartParams({'real_filename': file.name}); +}); + +/** + * Fired when a single chunk of any given file is uploaded. This parses the + * response from the server and checks for an error. If an error occurs it + * is reported to the user and the upload of this particular file is halted + * + * @param object up The plupload.Uploader object + * @param object file The plupload.File object whose chunk has just + * been uploaded + * @param object response The response object from the server + * + * @return undefined + */ +uploader.bind('ChunkUploaded', function(up, file, response) { + if (response.chunk >= response.chunks - 1) { + return; + } + + var json = {}; + try { + json = $.parseJSON(response.response); + } catch (e) { + file.status = plupload.FAILED; + up.trigger('FileUploaded', file, { + response: JSON.stringify({ + error: { + message: 'Error parsing server response.' + } + }) + }); + } + + // If trigger_error() was called, then a permission error likely occurred. + if (typeof json.title !== 'undefined') { + json.error = {message: json.message}; + } + + if (json.error) { + file.status = plupload.FAILED; + up.trigger('FileUploaded', file, { + response: JSON.stringify({ + error: { + message: json.error.message + } + }) + }); + } +}); + +/** + * Fires when files are added to the queue. + * + * @return undefined + */ +uploader.bind('FilesAdded', function(up, files) { + // Prevent unnecessary requests to the server if the user already uploaded + // the maximum number of files allowed. + if (phpbb.plupload.handleMaxFilesReached()) { + return; + } + + // Show the file list if there aren't any files currently. + if (!$('#file-list-container').is(':visible')) { + $('#file-list-container').show(100); + } + + $.each(files, function(i, file) { + phpbb.plupload.insertRow(file); + }); + + up.bind('UploadProgress', function(up, file) { + $('#' + file.id + " .file-progress-bar").css('width', file.percent + '%'); + $('#file-total-progress-bar').css('width', up.total.percent + '%'); + }); + + // Do not allow more files to be added to the running queue. + phpbb.plupload.disableUploader(); + + // Start uploading the files once the user has selected them. + up.start(); +}); + + +/** + * Fires when an entire file has been uploaded. It checks for errors + * returned by the server otherwise parses the list of attachment data and + * appends it to the next file upload so that the server can maintain state + * with regards to the attachments in a given post + * + * @param object up The plupload.Uploader object + * @param object file The plupload.File object that has just been + * uploaded + * @param string response The response string from the server + * + * @return undefined + */ +uploader.bind('FileUploaded', function(up, file, response) { + var json = {}, + row = $('#' + file.id), + error; + + // Hide the progress indicator. + row.find('.file-progress').hide(); + + try { + json = $.parseJSON(response.response); + } catch (e) { + error = 'Error parsing server response.'; + } + + // If trigger_error() was called, then a permission error likely occurred. + if (typeof json.title !== 'undefined') { + error = json.message; + up.trigger('Error', {message: error}); + + // The rest of the queue will fail. + phpbb.plupload.markQueuedFailed(error); + } else if (json.error) { + error = json.error.message; + } + + if (typeof error !== 'undefined') { + phpbb.plupload.fileError(file, error); + } else if (file.status === plupload.DONE) { + file.attachment_data = json['data'][0]; + + row.attr('data-attach-id', file.attachment_data.attach_id); + row.find('.file-inline-bbcode').show(); + row.find('.file-status').addClass('file-uploaded'); + phpbb.plupload.update(json['data'], 'addition', 0, [json['download_url']]); + } +}); + +/** + * Fires when the entire queue of files have been uploaded. + * + * @param object up The plupload.Uploader object + * @param array files An array of plupload.File objects that have just + * been uploaded as part of a queue + * + * @return undefined + */ +uploader.bind('UploadComplete', function(up, files) { + // Hide the progress bar + setTimeout(function() { + $('#file-total-progress-bar').fadeOut(500, function() { + $(this).css('width', 0).show(); + }); + }, 2000); + + // Re-enable the uploader + phpbb.plupload.enableUploader(); +}); + +})(jQuery); // Avoid conflicts with other libraries diff --git a/phpBB/assets/plupload/img/done.gif b/phpBB/assets/plupload/img/done.gif Binary files differnew file mode 100644 index 0000000000..29f3ed7c97 --- /dev/null +++ b/phpBB/assets/plupload/img/done.gif diff --git a/phpBB/assets/plupload/img/error.gif b/phpBB/assets/plupload/img/error.gif Binary files differnew file mode 100644 index 0000000000..4682b63007 --- /dev/null +++ b/phpBB/assets/plupload/img/error.gif diff --git a/phpBB/assets/plupload/img/throbber.gif b/phpBB/assets/plupload/img/throbber.gif Binary files differnew file mode 100644 index 0000000000..4ae8b16a5a --- /dev/null +++ b/phpBB/assets/plupload/img/throbber.gif diff --git a/phpBB/assets/plupload/plupload.full.min.js b/phpBB/assets/plupload/plupload.full.min.js new file mode 100644 index 0000000000..69d6ad120c --- /dev/null +++ b/phpBB/assets/plupload/plupload.full.min.js @@ -0,0 +1,28 @@ +/** + * mOxie - multi-runtime File API & XMLHttpRequest L2 Polyfill + * v1.2.0 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-01-16 + */ +!function(e,t){"use strict";function n(e,t){for(var n,i=[],r=0;r<e.length;++r){if(n=s[e[r]]||o(e[r]),!n)throw"module definition dependecy not found: "+e[r];i.push(n)}t.apply(null,i)}function i(e,i,r){if("string"!=typeof e)throw"invalid module definition, module id must be defined and be a string";if(i===t)throw"invalid module definition, dependencies must be specified";if(r===t)throw"invalid module definition, definition function must be specified";n(i,function(){s[e]=r.apply(null,arguments)})}function r(e){return!!s[e]}function o(t){for(var n=e,i=t.split(/[.\/]/),r=0;r<i.length;++r){if(!n[i[r]])return;n=n[i[r]]}return n}function a(n){for(var i=0;i<n.length;i++){for(var r=e,o=n[i],a=o.split(/[.\/]/),u=0;u<a.length-1;++u)r[a[u]]===t&&(r[a[u]]={}),r=r[a[u]];r[a[a.length-1]]=s[o]}}var s={},u="moxie/core/utils/Basic",c="moxie/core/I18n",l="moxie/core/utils/Mime",d="moxie/core/utils/Env",f="moxie/core/utils/Dom",p="moxie/core/Exceptions",h="moxie/core/EventTarget",m="moxie/core/utils/Encode",g="moxie/runtime/Runtime",v="moxie/runtime/RuntimeClient",y="moxie/file/Blob",w="moxie/file/File",E="moxie/file/FileInput",_="moxie/file/FileDrop",x="moxie/runtime/RuntimeTarget",R="moxie/file/FileReader",b="moxie/core/utils/Url",T="moxie/file/FileReaderSync",S="moxie/xhr/FormData",A="moxie/xhr/XMLHttpRequest",O="moxie/runtime/Transporter",I="moxie/image/Image",D="moxie/runtime/html5/Runtime",N="moxie/runtime/html5/file/Blob",L="moxie/core/utils/Events",M="moxie/runtime/html5/file/FileInput",C="moxie/runtime/html5/file/FileDrop",F="moxie/runtime/html5/file/FileReader",H="moxie/runtime/html5/xhr/XMLHttpRequest",P="moxie/runtime/html5/utils/BinaryReader",k="moxie/runtime/html5/image/JPEGHeaders",U="moxie/runtime/html5/image/ExifParser",B="moxie/runtime/html5/image/JPEG",z="moxie/runtime/html5/image/PNG",G="moxie/runtime/html5/image/ImageInfo",q="moxie/runtime/html5/image/MegaPixel",X="moxie/runtime/html5/image/Image",j="moxie/runtime/flash/Runtime",V="moxie/runtime/flash/file/Blob",W="moxie/runtime/flash/file/FileInput",Y="moxie/runtime/flash/file/FileReader",$="moxie/runtime/flash/file/FileReaderSync",J="moxie/runtime/flash/xhr/XMLHttpRequest",Z="moxie/runtime/flash/runtime/Transporter",K="moxie/runtime/flash/image/Image",Q="moxie/runtime/silverlight/Runtime",et="moxie/runtime/silverlight/file/Blob",tt="moxie/runtime/silverlight/file/FileInput",nt="moxie/runtime/silverlight/file/FileDrop",it="moxie/runtime/silverlight/file/FileReader",rt="moxie/runtime/silverlight/file/FileReaderSync",ot="moxie/runtime/silverlight/xhr/XMLHttpRequest",at="moxie/runtime/silverlight/runtime/Transporter",st="moxie/runtime/silverlight/image/Image",ut="moxie/runtime/html4/Runtime",ct="moxie/runtime/html4/file/FileInput",lt="moxie/runtime/html4/file/FileReader",dt="moxie/runtime/html4/xhr/XMLHttpRequest",ft="moxie/runtime/html4/image/Image";i(u,[],function(){var e=function(e){var t;return e===t?"undefined":null===e?"null":e.nodeType?"node":{}.toString.call(e).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()},t=function(i){var r;return n(arguments,function(o,s){s>0&&n(o,function(n,o){n!==r&&(e(i[o])===e(n)&&~a(e(n),["array","object"])?t(i[o],n):i[o]=n)})}),i},n=function(e,t){var n,i,r,o;if(e){try{n=e.length}catch(a){n=o}if(n===o){for(i in e)if(e.hasOwnProperty(i)&&t(e[i],i)===!1)return}else for(r=0;n>r;r++)if(t(e[r],r)===!1)return}},i=function(t){var n;if(!t||"object"!==e(t))return!0;for(n in t)return!1;return!0},r=function(t,n){function i(r){"function"===e(t[r])&&t[r](function(e){++r<o&&!e?i(r):n(e)})}var r=0,o=t.length;"function"!==e(n)&&(n=function(){}),t&&t.length||n(),i(r)},o=function(e,t){var i=0,r=e.length,o=new Array(r);n(e,function(e,n){e(function(e){if(e)return t(e);var a=[].slice.call(arguments);a.shift(),o[n]=a,i++,i===r&&(o.unshift(null),t.apply(this,o))})})},a=function(e,t){if(t){if(Array.prototype.indexOf)return Array.prototype.indexOf.call(t,e);for(var n=0,i=t.length;i>n;n++)if(t[n]===e)return n}return-1},s=function(t,n){var i=[];"array"!==e(t)&&(t=[t]),"array"!==e(n)&&(n=[n]);for(var r in t)-1===a(t[r],n)&&i.push(t[r]);return i.length?i:!1},u=function(e,t){var i=[];return n(e,function(e){-1!==a(e,t)&&i.push(e)}),i.length?i:null},c=function(e){var t,n=[];for(t=0;t<e.length;t++)n[t]=e[t];return n},l=function(){var e=0;return function(t){var n=(new Date).getTime().toString(32),i;for(i=0;5>i;i++)n+=Math.floor(65535*Math.random()).toString(32);return(t||"o_")+n+(e++).toString(32)}}(),d=function(e){return e?String.prototype.trim?String.prototype.trim.call(e):e.toString().replace(/^\s*/,"").replace(/\s*$/,""):e},f=function(e){if("string"!=typeof e)return e;var t={t:1099511627776,g:1073741824,m:1048576,k:1024},n;return e=/^([0-9]+)([mgk]?)$/.exec(e.toLowerCase().replace(/[^0-9mkg]/g,"")),n=e[2],e=+e[1],t.hasOwnProperty(n)&&(e*=t[n]),e};return{guid:l,typeOf:e,extend:t,each:n,isEmptyObj:i,inSeries:r,inParallel:o,inArray:a,arrayDiff:s,arrayIntersect:u,toArray:c,trim:d,parseSizeStr:f}}),i(c,[u],function(e){var t={};return{addI18n:function(n){return e.extend(t,n)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(t){var n=[].slice.call(arguments,1);return t.replace(/%[a-z]/g,function(){var t=n.shift();return"undefined"!==e.typeOf(t)?t:""})}}}),i(l,[u,c],function(e,t){var n="application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx,application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx,application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx,application/vnd.openxmlformats-officedocument.presentationml.template,potx,application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx,application/x-javascript,js,application/json,json,audio/mpeg,mp3 mpga mpega mp2,audio/x-wav,wav,audio/x-m4a,m4a,audio/ogg,oga ogg,audio/aiff,aiff aif,audio/flac,flac,audio/aac,aac,audio/ac3,ac3,audio/x-ms-wma,wma,image/bmp,bmp,image/gif,gif,image/jpeg,jpg jpeg jpe,image/photoshop,psd,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/plain,asc txt text diff log,text/html,htm html xhtml,text/css,css,text/csv,csv,text/rtf,rtf,video/mpeg,mpeg mpg mpe m2v,video/quicktime,qt mov,video/mp4,mp4,video/x-m4v,m4v,video/x-flv,flv,video/x-ms-wmv,wmv,video/avi,avi,video/webm,webm,video/3gpp,3gpp 3gp,video/3gpp2,3g2,video/vnd.rn-realvideo,rv,video/ogg,ogv,video/x-matroska,mkv,application/vnd.oasis.opendocument.formula-template,otf,application/octet-stream,exe",i={mimes:{},extensions:{},addMimeType:function(e){var t=e.split(/,/),n,i,r;for(n=0;n<t.length;n+=2){for(r=t[n+1].split(/ /),i=0;i<r.length;i++)this.mimes[r[i]]=t[n];this.extensions[t[n]]=r}},extList2mimes:function(t,n){var i=this,r,o,a,s,u=[];for(o=0;o<t.length;o++)for(r=t[o].extensions.split(/\s*,\s*/),a=0;a<r.length;a++){if("*"===r[a])return[];if(s=i.mimes[r[a]])-1===e.inArray(s,u)&&u.push(s);else{if(!n||!/^\w+$/.test(r[a]))return[];u.push("."+r[a])}}return u},mimes2exts:function(t){var n=this,i=[];return e.each(t,function(t){if("*"===t)return i=[],!1;var r=t.match(/^(\w+)\/(\*|\w+)$/);r&&("*"===r[2]?e.each(n.extensions,function(e,t){new RegExp("^"+r[1]+"/").test(t)&&[].push.apply(i,n.extensions[t])}):n.extensions[t]&&[].push.apply(i,n.extensions[t]))}),i},mimes2extList:function(n){var i=[],r=[];return"string"===e.typeOf(n)&&(n=e.trim(n).split(/\s*,\s*/)),r=this.mimes2exts(n),i.push({title:t.translate("Files"),extensions:r.length?r.join(","):"*"}),i.mimes=n,i},getFileExtension:function(e){var t=e&&e.match(/\.([^.]+)$/);return t?t[1].toLowerCase():""},getFileMime:function(e){return this.mimes[this.getFileExtension(e)]||""}};return i.addMimeType(n),i}),i(d,[u],function(e){function t(e,t,n){var i=0,r=0,o=0,a={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1},s=function(e){return e=(""+e).replace(/[_\-+]/g,"."),e=e.replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,"."),e.length?e.split("."):[-8]},u=function(e){return e?isNaN(e)?a[e]||-7:parseInt(e,10):0};for(e=s(e),t=s(t),r=Math.max(e.length,t.length),i=0;r>i;i++)if(e[i]!=t[i]){if(e[i]=u(e[i]),t[i]=u(t[i]),e[i]<t[i]){o=-1;break}if(e[i]>t[i]){o=1;break}}if(!n)return o;switch(n){case">":case"gt":return o>0;case">=":case"ge":return o>=0;case"<=":case"le":return 0>=o;case"==":case"=":case"eq":return 0===o;case"<>":case"!=":case"ne":return 0!==o;case"":case"<":case"lt":return 0>o;default:return null}}var n=function(e){var t="",n="?",i="function",r="undefined",o="object",a="major",s="model",u="name",c="type",l="vendor",d="version",f="architecture",p="console",h="mobile",m="tablet",g={has:function(e,t){return-1!==t.toLowerCase().indexOf(e.toLowerCase())},lowerize:function(e){return e.toLowerCase()}},v={rgx:function(){for(var t,n=0,a,s,u,c,l,d,f=arguments;n<f.length;n+=2){var p=f[n],h=f[n+1];if(typeof t===r){t={};for(u in h)c=h[u],typeof c===o?t[c[0]]=e:t[c]=e}for(a=s=0;a<p.length;a++)if(l=p[a].exec(this.getUA())){for(u=0;u<h.length;u++)d=l[++s],c=h[u],typeof c===o&&c.length>0?2==c.length?t[c[0]]=typeof c[1]==i?c[1].call(this,d):c[1]:3==c.length?t[c[0]]=typeof c[1]!==i||c[1].exec&&c[1].test?d?d.replace(c[1],c[2]):e:d?c[1].call(this,d,c[2]):e:4==c.length&&(t[c[0]]=d?c[3].call(this,d.replace(c[1],c[2])):e):t[c]=d?d:e;break}if(l)break}return t},str:function(t,i){for(var r in i)if(typeof i[r]===o&&i[r].length>0){for(var a=0;a<i[r].length;a++)if(g.has(i[r][a],t))return r===n?e:r}else if(g.has(i[r],t))return r===n?e:r;return t}},y={browser:{oldsafari:{major:{1:["/8","/1","/3"],2:"/4","?":"/"},version:{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}}},device:{sprint:{model:{"Evo Shift 4G":"7373KT"},vendor:{HTC:"APA",Sprint:"Sprint"}}},os:{windows:{version:{ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2000:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",RT:"ARM"}}}},w={browser:[[/(opera\smini)\/((\d+)?[\w\.-]+)/i,/(opera\s[mobiletab]+).+version\/((\d+)?[\w\.-]+)/i,/(opera).+version\/((\d+)?[\w\.]+)/i,/(opera)[\/\s]+((\d+)?[\w\.]+)/i],[u,d,a],[/\s(opr)\/((\d+)?[\w\.]+)/i],[[u,"Opera"],d,a],[/(kindle)\/((\d+)?[\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?((\d+)?[\w\.]+)*/i,/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?((\d+)?[\w\.]*)/i,/(?:ms|\()(ie)\s((\d+)?[\w\.]+)/i,/(rekonq)((?:\/)[\w\.]+)*/i,/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron)\/((\d+)?[\w\.-]+)/i],[u,d,a],[/(trident).+rv[:\s]((\d+)?[\w\.]+).+like\sgecko/i],[[u,"IE"],d,a],[/(yabrowser)\/((\d+)?[\w\.]+)/i],[[u,"Yandex"],d,a],[/(comodo_dragon)\/((\d+)?[\w\.]+)/i],[[u,/_/g," "],d,a],[/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?((\d+)?[\w\.]+)/i],[u,d,a],[/(dolfin)\/((\d+)?[\w\.]+)/i],[[u,"Dolphin"],d,a],[/((?:android.+)crmo|crios)\/((\d+)?[\w\.]+)/i],[[u,"Chrome"],d,a],[/((?:android.+))version\/((\d+)?[\w\.]+)\smobile\ssafari/i],[[u,"Android Browser"],d,a],[/version\/((\d+)?[\w\.]+).+?mobile\/\w+\s(safari)/i],[d,a,[u,"Mobile Safari"]],[/version\/((\d+)?[\w\.]+).+?(mobile\s?safari|safari)/i],[d,a,u],[/webkit.+?(mobile\s?safari|safari)((\/[\w\.]+))/i],[u,[a,v.str,y.browser.oldsafari.major],[d,v.str,y.browser.oldsafari.version]],[/(konqueror)\/((\d+)?[\w\.]+)/i,/(webkit|khtml)\/((\d+)?[\w\.]+)/i],[u,d,a],[/(navigator|netscape)\/((\d+)?[\w\.-]+)/i],[[u,"Netscape"],d,a],[/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?((\d+)?[\w\.\+]+)/i,/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/((\d+)?[\w\.-]+)/i,/(mozilla)\/((\d+)?[\w\.]+).+rv\:.+gecko\/\d+/i,/(uc\s?browser|polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|qqbrowser)[\/\s]?((\d+)?[\w\.]+)/i,/(links)\s\(((\d+)?[\w\.]+)/i,/(gobrowser)\/?((\d+)?[\w\.]+)*/i,/(ice\s?browser)\/v?((\d+)?[\w\._]+)/i,/(mosaic)[\/\s]((\d+)?[\w\.]+)/i],[u,d,a]],engine:[[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,/(icab)[\/\s]([23]\.[\d\.]+)/i],[u,d],[/rv\:([\w\.]+).*(gecko)/i],[d,u]],os:[[/(windows)\snt\s6\.2;\s(arm)/i,/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i],[u,[d,v.str,y.os.windows.version]],[/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i],[[u,"Windows"],[d,v.str,y.os.windows.version]],[/\((bb)(10);/i],[[u,"BlackBerry"],d],[/(blackberry)\w*\/?([\w\.]+)*/i,/(tizen)\/([\w\.]+)/i,/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i],[u,d],[/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i],[[u,"Symbian"],d],[/mozilla.+\(mobile;.+gecko.+firefox/i],[[u,"Firefox OS"],d],[/(nintendo|playstation)\s([wids3portablevu]+)/i,/(mint)[\/\s\(]?(\w+)*/i,/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk)[\/\s-]?([\w\.-]+)*/i,/(hurd|linux)\s?([\w\.]+)*/i,/(gnu)\s?([\w\.]+)*/i],[u,d],[/(cros)\s[\w]+\s([\w\.]+\w)/i],[[u,"Chromium OS"],d],[/(sunos)\s?([\w\.]+\d)*/i],[[u,"Solaris"],d],[/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i],[u,d],[/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i],[[u,"iOS"],[d,/_/g,"."]],[/(mac\sos\sx)\s?([\w\s\.]+\w)*/i],[u,[d,/_/g,"."]],[/(haiku)\s(\w+)/i,/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i,/(macintosh|mac(?=_powerpc)|plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos)/i,/(unix)\s?([\w\.]+)*/i],[u,d]]},E=function(e){var n=e||(window&&window.navigator&&window.navigator.userAgent?window.navigator.userAgent:t);this.getBrowser=function(){return v.rgx.apply(this,w.browser)},this.getEngine=function(){return v.rgx.apply(this,w.engine)},this.getOS=function(){return v.rgx.apply(this,w.os)},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS()}},this.getUA=function(){return n},this.setUA=function(e){return n=e,this},this.setUA(n)};return(new E).getResult()}(),i=function(){var t={define_property:function(){return!1}(),create_canvas:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))}(),return_response_type:function(t){try{if(-1!==e.inArray(t,["","text","document"]))return!0;if(window.XMLHttpRequest){var n=new XMLHttpRequest;if(n.open("get","/"),"responseType"in n)return n.responseType=t,n.responseType!==t?!1:!0}}catch(i){}return!1},use_data_uri:function(){var e=new Image;return e.onload=function(){t.use_data_uri=1===e.width&&1===e.height},setTimeout(function(){e.src="data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="},1),!1}(),use_data_uri_over32kb:function(){return t.use_data_uri&&("IE"!==r.browser||r.version>=9)},use_data_uri_of:function(e){return t.use_data_uri&&33e3>e||t.use_data_uri_over32kb()},use_fileinput:function(){var e=document.createElement("input");return e.setAttribute("type","file"),!e.disabled}};return function(n){var i=[].slice.call(arguments);return i.shift(),"function"===e.typeOf(t[n])?t[n].apply(this,i):!!t[n]}}(),r={can:i,browser:n.browser.name,version:parseFloat(n.browser.major),os:n.os.name,osVersion:n.os.version,verComp:t,swf_url:"../flash/Moxie.swf",xap_url:"../silverlight/Moxie.xap",global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};return r.OS=r.os,r}),i(f,[d],function(e){var t=function(e){return"string"!=typeof e?e:document.getElementById(e)},n=function(e,t){if(!e.className)return!1;var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");return n.test(e.className)},i=function(e,t){n(e,t)||(e.className=e.className?e.className.replace(/\s+$/,"")+" "+t:t)},r=function(e,t){if(e.className){var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");e.className=e.className.replace(n,function(e,t,n){return" "===t&&" "===n?" ":""})}},o=function(e,t){return e.currentStyle?e.currentStyle[t]:window.getComputedStyle?window.getComputedStyle(e,null)[t]:void 0},a=function(t,n){function i(e){var t,n,i=0,r=0;return e&&(n=e.getBoundingClientRect(),t="CSS1Compat"===s.compatMode?s.documentElement:s.body,i=n.left+t.scrollLeft,r=n.top+t.scrollTop),{x:i,y:r}}var r=0,o=0,a,s=document,u,c;if(t=t,n=n||s.body,t&&t.getBoundingClientRect&&"IE"===e.browser&&(!s.documentMode||s.documentMode<8))return u=i(t),c=i(n),{x:u.x-c.x,y:u.y-c.y};for(a=t;a&&a!=n&&a.nodeType;)r+=a.offsetLeft||0,o+=a.offsetTop||0,a=a.offsetParent;for(a=t.parentNode;a&&a!=n&&a.nodeType;)r-=a.scrollLeft||0,o-=a.scrollTop||0,a=a.parentNode;return{x:r,y:o}},s=function(e){return{w:e.offsetWidth||e.clientWidth,h:e.offsetHeight||e.clientHeight}};return{get:t,hasClass:n,addClass:i,removeClass:r,getStyle:o,getPos:a,getSize:s}}),i(p,[u],function(e){function t(e,t){var n;for(n in e)if(e[n]===t)return n;return null}return{RuntimeError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": RuntimeError "+this.code}var i={NOT_INIT_ERR:1,NOT_SUPPORTED_ERR:9,JS_ERR:4};return e.extend(n,i),n.prototype=Error.prototype,n}(),OperationNotAllowedException:function(){function t(e){this.code=e,this.name="OperationNotAllowedException"}return e.extend(t,{NOT_ALLOWED_ERR:1}),t.prototype=Error.prototype,t}(),ImageError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": ImageError "+this.code}var i={WRONG_FORMAT:1,MAX_RESOLUTION_ERR:2};return e.extend(n,i),n.prototype=Error.prototype,n}(),FileException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": FileException "+this.code}var i={NOT_FOUND_ERR:1,SECURITY_ERR:2,ABORT_ERR:3,NOT_READABLE_ERR:4,ENCODING_ERR:5,NO_MODIFICATION_ALLOWED_ERR:6,INVALID_STATE_ERR:7,SYNTAX_ERR:8};return e.extend(n,i),n.prototype=Error.prototype,n}(),DOMException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": DOMException "+this.code}var i={INDEX_SIZE_ERR:1,DOMSTRING_SIZE_ERR:2,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,INVALID_CHARACTER_ERR:5,NO_DATA_ALLOWED_ERR:6,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INUSE_ATTRIBUTE_ERR:10,INVALID_STATE_ERR:11,SYNTAX_ERR:12,INVALID_MODIFICATION_ERR:13,NAMESPACE_ERR:14,INVALID_ACCESS_ERR:15,VALIDATION_ERR:16,TYPE_MISMATCH_ERR:17,SECURITY_ERR:18,NETWORK_ERR:19,ABORT_ERR:20,URL_MISMATCH_ERR:21,QUOTA_EXCEEDED_ERR:22,TIMEOUT_ERR:23,INVALID_NODE_TYPE_ERR:24,DATA_CLONE_ERR:25};return e.extend(n,i),n.prototype=Error.prototype,n}(),EventException:function(){function t(e){this.code=e,this.name="EventException"}return e.extend(t,{UNSPECIFIED_EVENT_TYPE_ERR:0}),t.prototype=Error.prototype,t}()}}),i(h,[p,u],function(e,t){function n(){var n={};t.extend(this,{uid:null,init:function(){this.uid||(this.uid=t.guid("uid_"))},addEventListener:function(e,i,r,o){var a=this,s;return e=t.trim(e),/\s/.test(e)?(t.each(e.split(/\s+/),function(e){a.addEventListener(e,i,r,o)}),void 0):(e=e.toLowerCase(),r=parseInt(r,10)||0,s=n[this.uid]&&n[this.uid][e]||[],s.push({fn:i,priority:r,scope:o||this}),n[this.uid]||(n[this.uid]={}),n[this.uid][e]=s,void 0)},hasEventListener:function(e){return e?!(!n[this.uid]||!n[this.uid][e]):!!n[this.uid]},removeEventListener:function(e,i){e=e.toLowerCase();var r=n[this.uid]&&n[this.uid][e],o;if(r){if(i){for(o=r.length-1;o>=0;o--)if(r[o].fn===i){r.splice(o,1);break}}else r=[];r.length||(delete n[this.uid][e],t.isEmptyObj(n[this.uid])&&delete n[this.uid])}},removeAllEventListeners:function(){n[this.uid]&&delete n[this.uid]},dispatchEvent:function(i){var r,o,a,s,u={},c=!0,l;if("string"!==t.typeOf(i)){if(s=i,"string"!==t.typeOf(s.type))throw new e.EventException(e.EventException.UNSPECIFIED_EVENT_TYPE_ERR);i=s.type,s.total!==l&&s.loaded!==l&&(u.total=s.total,u.loaded=s.loaded),u.async=s.async||!1}if(-1!==i.indexOf("::")?function(e){r=e[0],i=e[1]}(i.split("::")):r=this.uid,i=i.toLowerCase(),o=n[r]&&n[r][i]){o.sort(function(e,t){return t.priority-e.priority}),a=[].slice.call(arguments),a.shift(),u.type=i,a.unshift(u);var d=[];t.each(o,function(e){a[0].target=e.scope,u.async?d.push(function(t){setTimeout(function(){t(e.fn.apply(e.scope,a)===!1)},1)}):d.push(function(t){t(e.fn.apply(e.scope,a)===!1)})}),d.length&&t.inSeries(d,function(e){c=!e})}return c},bind:function(){this.addEventListener.apply(this,arguments)},unbind:function(){this.removeEventListener.apply(this,arguments)},unbindAll:function(){this.removeAllEventListeners.apply(this,arguments)},trigger:function(){return this.dispatchEvent.apply(this,arguments)},convertEventPropsToHandlers:function(e){var n;"array"!==t.typeOf(e)&&(e=[e]);for(var i=0;i<e.length;i++)n="on"+e[i],"function"===t.typeOf(this[n])?this.addEventListener(e[i],this[n]):"undefined"===t.typeOf(this[n])&&(this[n]=null)}})}return n.instance=new n,n}),i(m,[],function(){var e=function(e){return unescape(encodeURIComponent(e))},t=function(e){return decodeURIComponent(escape(e))},n=function(e,n){if("function"==typeof window.atob)return n?t(window.atob(e)):window.atob(e);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,p=0,h="",m=[];if(!e)return e;e+="";do s=i.indexOf(e.charAt(f++)),u=i.indexOf(e.charAt(f++)),c=i.indexOf(e.charAt(f++)),l=i.indexOf(e.charAt(f++)),d=s<<18|u<<12|c<<6|l,r=255&d>>16,o=255&d>>8,a=255&d,m[p++]=64==c?String.fromCharCode(r):64==l?String.fromCharCode(r,o):String.fromCharCode(r,o,a);while(f<e.length);return h=m.join(""),n?t(h):h},i=function(t,n){if(n&&e(t),"function"==typeof window.btoa)return window.btoa(t);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,p=0,h="",m=[];if(!t)return t;do r=t.charCodeAt(f++),o=t.charCodeAt(f++),a=t.charCodeAt(f++),d=r<<16|o<<8|a,s=63&d>>18,u=63&d>>12,c=63&d>>6,l=63&d,m[p++]=i.charAt(s)+i.charAt(u)+i.charAt(c)+i.charAt(l);while(f<t.length);h=m.join("");var g=t.length%3;return(g?h.slice(0,g-3):h)+"===".slice(g||3)};return{utf8_encode:e,utf8_decode:t,atob:n,btoa:i}}),i(g,[u,f,h],function(e,t,n){function i(n,r,a,s,u){var c=this,l,d=e.guid(r+"_"),f=u||"browser";n=n||{},o[d]=this,a=e.extend({access_binary:!1,access_image_binary:!1,display_media:!1,do_cors:!1,drag_and_drop:!1,filter_by_extension:!0,resize_image:!1,report_upload_progress:!1,return_response_headers:!1,return_response_type:!1,return_status_code:!0,send_custom_headers:!1,select_file:!1,select_folder:!1,select_multiple:!0,send_binary_string:!1,send_browser_cookies:!0,send_multipart:!0,slice_blob:!1,stream_upload:!1,summon_file_dialog:!1,upload_filesize:!0,use_http_method:!0},a),n.preferred_caps&&(f=i.getMode(s,n.preferred_caps,f)),l=function(){var t={};return{exec:function(e,n,i,r){return l[n]&&(t[e]||(t[e]={context:this,instance:new l[n]}),t[e].instance[i])?t[e].instance[i].apply(this,r):void 0},removeInstance:function(e){delete t[e]},removeAllInstances:function(){var n=this;e.each(t,function(t,i){"function"===e.typeOf(t.instance.destroy)&&t.instance.destroy.call(t.context),n.removeInstance(i)})}}}(),e.extend(this,{initialized:!1,uid:d,type:r,mode:i.getMode(s,n.required_caps,f),shimid:d+"_container",clients:0,options:n,can:function(t,n){var r=arguments[2]||a;if("string"===e.typeOf(t)&&"undefined"===e.typeOf(n)&&(t=i.parseCaps(t)),"object"===e.typeOf(t)){for(var o in t)if(!this.can(o,t[o],r))return!1;return!0}return"function"===e.typeOf(r[t])?r[t].call(this,n):n===r[t]},getShimContainer:function(){var n,i=t.get(this.shimid);return i||(n=this.options.container?t.get(this.options.container):document.body,i=document.createElement("div"),i.id=this.shimid,i.className="moxie-shim moxie-shim-"+this.type,e.extend(i.style,{position:"absolute",top:"0px",left:"0px",width:"1px",height:"1px",overflow:"hidden"}),n.appendChild(i),n=null),i},getShim:function(){return l},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec.call(this,this.uid,e,t,n)},exec:function(e,t){var n=[].slice.call(arguments,2);return c[e]&&c[e][t]?c[e][t].apply(this,n):c.shimExec.apply(this,arguments)},destroy:function(){if(c){var e=t.get(this.shimid);e&&e.parentNode.removeChild(e),l&&l.removeAllInstances(),this.unbindAll(),delete o[this.uid],this.uid=null,d=c=l=e=null}}}),this.mode&&n.required_caps&&!this.can(n.required_caps)&&(this.mode=!1)}var r={},o={};return i.order="html5,flash,silverlight,html4",i.getRuntime=function(e){return o[e]?o[e]:!1},i.addConstructor=function(e,t){t.prototype=n.instance,r[e]=t},i.getConstructor=function(e){return r[e]||null},i.getInfo=function(e){var t=i.getRuntime(e);return t?{uid:t.uid,type:t.type,mode:t.mode,can:function(){return t.can.apply(t,arguments)}}:null},i.parseCaps=function(t){var n={};return"string"!==e.typeOf(t)?t||{}:(e.each(t.split(","),function(e){n[e]=!0}),n)},i.can=function(e,t){var n,r=i.getConstructor(e),o;return r?(n=new r({required_caps:t}),o=n.mode,n.destroy(),!!o):!1},i.thatCan=function(e,t){var n=(t||i.order).split(/\s*,\s*/);for(var r in n)if(i.can(n[r],e))return n[r];return null},i.getMode=function(t,n,i){var r=null;if("undefined"===e.typeOf(i)&&(i="browser"),n&&!e.isEmptyObj(t)){if(e.each(n,function(n,i){if(t.hasOwnProperty(i)){var o=t[i](n);if("string"==typeof o&&(o=[o]),r){if(!(r=e.arrayIntersect(r,o)))return r=!1}else r=o}}),r)return-1!==e.inArray(i,r)?i:r[0];if(r===!1)return!1}return i},i.capTrue=function(){return!0},i.capFalse=function(){return!1},i.capTest=function(e){return function(){return!!e}},i}),i(v,[p,u,g],function(e,t,n){return function i(){var i;t.extend(this,{connectRuntime:function(r){function o(t){var s,u;return t.length?(s=t.shift(),(u=n.getConstructor(s))?(i=new u(r),i.bind("Init",function(){i.initialized=!0,setTimeout(function(){i.clients++,a.trigger("RuntimeInit",i)},1)}),i.bind("Error",function(){i.destroy(),o(t)}),i.mode?(i.init(),void 0):(i.trigger("Error"),void 0)):(o(t),void 0)):(a.trigger("RuntimeError",new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)),i=null,void 0)}var a=this,s;if("string"===t.typeOf(r)?s=r:"string"===t.typeOf(r.ruid)&&(s=r.ruid),s){if(i=n.getRuntime(s))return i.clients++,i;throw new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)}o((r.runtime_order||n.order).split(/\s*,\s*/))},getRuntime:function(){return i&&i.uid?i:(i=null,null)},disconnectRuntime:function(){i&&--i.clients<=0&&(i.destroy(),i=null)}})}}),i(y,[u,m,v],function(e,t,n){function i(o,a){function s(t,n,o){var a,s=r[this.uid];return"string"===e.typeOf(s)&&s.length?(a=new i(null,{type:o,size:n-t}),a.detach(s.substr(t,a.size)),a):null}n.call(this),o&&this.connectRuntime(o),a?"string"===e.typeOf(a)&&(a={data:a}):a={},e.extend(this,{uid:a.uid||e.guid("uid_"),ruid:o,size:a.size||0,type:a.type||"",slice:function(e,t,n){return this.isDetached()?s.apply(this,arguments):this.getRuntime().exec.call(this,"Blob","slice",this.getSource(),e,t,n)},getSource:function(){return r[this.uid]?r[this.uid]:null},detach:function(e){this.ruid&&(this.getRuntime().exec.call(this,"Blob","destroy",r[this.uid]),this.disconnectRuntime(),this.ruid=null),e=e||"";var n=e.match(/^data:([^;]*);base64,/);n&&(this.type=n[1],e=t.atob(e.substring(e.indexOf("base64,")+7))),this.size=e.length,r[this.uid]=e},isDetached:function(){return!this.ruid&&"string"===e.typeOf(r[this.uid])},destroy:function(){this.detach(),delete r[this.uid]}}),a.data?this.detach(a.data):r[this.uid]=a}var r={};return i}),i(w,[u,l,y],function(e,t,n){function i(i,r){var o,a;if(r||(r={}),a=r.type&&""!==r.type?r.type:t.getFileMime(r.name),r.name)o=r.name.replace(/\\/g,"/"),o=o.substr(o.lastIndexOf("/")+1);else{var s=a.split("/")[0];o=e.guid((""!==s?s:"file")+"_"),t.extensions[a]&&(o+="."+t.extensions[a][0])}n.apply(this,arguments),e.extend(this,{type:a||"",name:o||e.guid("file_"),lastModifiedDate:r.lastModifiedDate||(new Date).toLocaleString()})}return i.prototype=n.prototype,i}),i(E,[u,l,f,p,h,c,w,g,v],function(e,t,n,i,r,o,a,s,u){function c(r){var c=this,d,f,p;if(-1!==e.inArray(e.typeOf(r),["string","node"])&&(r={browse_button:r}),f=n.get(r.browse_button),!f)throw new i.DOMException(i.DOMException.NOT_FOUND_ERR);p={accept:[{title:o.translate("All Files"),extensions:"*"}],name:"file",multiple:!1,required_caps:!1,container:f.parentNode||document.body},r=e.extend({},p,r),"string"==typeof r.required_caps&&(r.required_caps=s.parseCaps(r.required_caps)),"string"==typeof r.accept&&(r.accept=t.mimes2extList(r.accept)),d=n.get(r.container),d||(d=document.body),"static"===n.getStyle(d,"position")&&(d.style.position="relative"),d=f=null,u.call(c),e.extend(c,{uid:e.guid("uid_"),ruid:null,shimid:null,files:null,init:function(){c.convertEventPropsToHandlers(l),c.bind("RuntimeInit",function(t,i){c.ruid=i.uid,c.shimid=i.shimid,c.bind("Ready",function(){c.trigger("Refresh")},999),c.bind("Change",function(){var t=i.exec.call(c,"FileInput","getFiles");c.files=[],e.each(t,function(e){return 0===e.size?!0:(c.files.push(new a(c.ruid,e)),void 0)})},999),c.bind("Refresh",function(){var t,o,a,s;a=n.get(r.browse_button),s=n.get(i.shimid),a&&(t=n.getPos(a,n.get(r.container)),o=n.getSize(a),s&&e.extend(s.style,{top:t.y+"px",left:t.x+"px",width:o.w+"px",height:o.h+"px"})),s=a=null}),i.exec.call(c,"FileInput","init",r)}),c.connectRuntime(e.extend({},r,{required_caps:{select_file:!0}}))},disable:function(t){var n=this.getRuntime();n&&n.exec.call(this,"FileInput","disable","undefined"===e.typeOf(t)?!0:t)},refresh:function(){c.trigger("Refresh")},destroy:function(){var t=this.getRuntime();t&&(t.exec.call(this,"FileInput","destroy"),this.disconnectRuntime()),"array"===e.typeOf(this.files)&&e.each(this.files,function(e){e.destroy()}),this.files=null}})}var l=["ready","change","cancel","mouseenter","mouseleave","mousedown","mouseup"];return c.prototype=r.instance,c}),i(_,[c,f,p,u,w,v,h,l],function(e,t,n,i,r,o,a,s){function u(n){var a=this,u;"string"==typeof n&&(n={drop_zone:n}),u={accept:[{title:e.translate("All Files"),extensions:"*"}],required_caps:{drag_and_drop:!0}},n="object"==typeof n?i.extend({},u,n):u,n.container=t.get(n.drop_zone)||document.body,"static"===t.getStyle(n.container,"position")&&(n.container.style.position="relative"),"string"==typeof n.accept&&(n.accept=s.mimes2extList(n.accept)),o.call(a),i.extend(a,{uid:i.guid("uid_"),ruid:null,files:null,init:function(){a.convertEventPropsToHandlers(c),a.bind("RuntimeInit",function(e,t){a.ruid=t.uid,a.bind("Drop",function(){var e=t.exec.call(a,"FileDrop","getFiles");a.files=[],i.each(e,function(e){a.files.push(new r(a.ruid,e))})},999),t.exec.call(a,"FileDrop","init",n),a.dispatchEvent("ready")}),a.connectRuntime(n)},destroy:function(){var e=this.getRuntime();e&&(e.exec.call(this,"FileDrop","destroy"),this.disconnectRuntime()),this.files=null}})}var c=["ready","dragenter","dragleave","drop","error"];return u.prototype=a.instance,u}),i(x,[u,v,h],function(e,t,n){function i(){this.uid=e.guid("uid_"),t.call(this),this.destroy=function(){this.disconnectRuntime(),this.unbindAll()}}return i.prototype=n.instance,i}),i(R,[u,m,p,h,y,w,x],function(e,t,n,i,r,o,a){function s(){function i(e,i){function l(e){o.readyState=s.DONE,o.error=e,o.trigger("error"),d()}function d(){c.destroy(),c=null,o.trigger("loadend")}function f(t){c.bind("Error",function(e,t){l(t)}),c.bind("Progress",function(e){o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e)}),c.bind("Load",function(e){o.readyState=s.DONE,o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e),d()}),t.exec.call(c,"FileReader","read",e,i)}if(c=new a,this.convertEventPropsToHandlers(u),this.readyState===s.LOADING)return l(new n.DOMException(n.DOMException.INVALID_STATE_ERR));if(this.readyState=s.LOADING,this.trigger("loadstart"),i instanceof r)if(i.isDetached()){var p=i.getSource();switch(e){case"readAsText":case"readAsBinaryString":this.result=p;break;case"readAsDataURL":this.result="data:"+i.type+";base64,"+t.btoa(p)}this.readyState=s.DONE,this.trigger("load"),d()}else f(c.connectRuntime(i.ruid));else l(new n.DOMException(n.DOMException.NOT_FOUND_ERR))}var o=this,c;e.extend(this,{uid:e.guid("uid_"),readyState:s.EMPTY,result:null,error:null,readAsBinaryString:function(e){i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){i.call(this,"readAsDataURL",e)},readAsText:function(e){i.call(this,"readAsText",e) +},abort:function(){this.result=null,-1===e.inArray(this.readyState,[s.EMPTY,s.DONE])&&(this.readyState===s.LOADING&&(this.readyState=s.DONE),c&&c.getRuntime().exec.call(this,"FileReader","abort"),this.trigger("abort"),this.trigger("loadend"))},destroy:function(){this.abort(),c&&(c.getRuntime().exec.call(this,"FileReader","destroy"),c.disconnectRuntime()),o=c=null}})}var u=["loadstart","progress","load","abort","error","loadend"];return s.EMPTY=0,s.LOADING=1,s.DONE=2,s.prototype=i.instance,s}),i(b,[],function(){var e=function(t,n){for(var i=["source","scheme","authority","userInfo","user","pass","host","port","relative","path","directory","file","query","fragment"],r=i.length,o={http:80,https:443},a={},s=/^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/,u=s.exec(t||"");r--;)u[r]&&(a[i[r]]=u[r]);if(!a.scheme){n&&"string"!=typeof n||(n=e(n||document.location.href)),a.scheme=n.scheme,a.host=n.host,a.port=n.port;var c="";/^[^\/]/.test(a.path)&&(c=n.path,/(\/|\/[^\.]+)$/.test(c)?c+="/":c=c.replace(/\/[^\/]+$/,"/")),a.path=c+(a.path||"")}return a.port||(a.port=o[a.scheme]||80),a.port=parseInt(a.port,10),a.path||(a.path="/"),delete a.source,a},t=function(t){var n={http:80,https:443},i=e(t);return i.scheme+"://"+i.host+(i.port!==n[i.scheme]?":"+i.port:"")+i.path+(i.query?i.query:"")},n=function(t){function n(e){return[e.scheme,e.host,e.port].join("/")}return"string"==typeof t&&(t=e(t)),n(e())===n(t)};return{parseUrl:e,resolveUrl:t,hasSameOrigin:n}}),i(T,[u,v,m],function(e,t,n){return function(){function i(e,t){if(!t.isDetached()){var i=this.connectRuntime(t.ruid).exec.call(this,"FileReaderSync","read",e,t);return this.disconnectRuntime(),i}var r=t.getSource();switch(e){case"readAsBinaryString":return r;case"readAsDataURL":return"data:"+t.type+";base64,"+n.btoa(r);case"readAsText":for(var o="",a=0,s=r.length;s>a;a++)o+=String.fromCharCode(r[a]);return o}}t.call(this),e.extend(this,{uid:e.guid("uid_"),readAsBinaryString:function(e){return i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){return i.call(this,"readAsDataURL",e)},readAsText:function(e){return i.call(this,"readAsText",e)}})}}),i(S,[p,u,y],function(e,t,n){function i(){var e,i=[];t.extend(this,{append:function(r,o){var a=this,s=t.typeOf(o);o instanceof n?e={name:r,value:o}:"array"===s?(r+="[]",t.each(o,function(e){a.append(r,e)})):"object"===s?t.each(o,function(e,t){a.append(r+"["+t+"]",e)}):"null"===s||"undefined"===s||"number"===s&&isNaN(o)?a.append(r,"false"):i.push({name:r,value:o.toString()})},hasBlob:function(){return!!this.getBlob()},getBlob:function(){return e&&e.value||null},getBlobName:function(){return e&&e.name||null},each:function(n){t.each(i,function(e){n(e.value,e.name)}),e&&n(e.value,e.name)},destroy:function(){e=null,i=[]}})}return i}),i(A,[u,p,h,m,b,g,x,y,T,S,d,l],function(e,t,n,i,r,o,a,s,u,c,l,d){function f(){this.uid=e.guid("uid_")}function p(){function n(e,t){return y.hasOwnProperty(e)?1===arguments.length?l.can("define_property")?y[e]:v[e]:(l.can("define_property")?y[e]=t:v[e]=t,void 0):void 0}function u(t){function i(){k.destroy(),k=null,s.dispatchEvent("loadend"),s=null}function r(r){k.bind("LoadStart",function(e){n("readyState",p.LOADING),s.dispatchEvent("readystatechange"),s.dispatchEvent(e),I&&s.upload.dispatchEvent(e)}),k.bind("Progress",function(e){n("readyState")!==p.LOADING&&(n("readyState",p.LOADING),s.dispatchEvent("readystatechange")),s.dispatchEvent(e)}),k.bind("UploadProgress",function(e){I&&s.upload.dispatchEvent({type:"progress",lengthComputable:!1,total:e.total,loaded:e.loaded})}),k.bind("Load",function(t){n("readyState",p.DONE),n("status",Number(r.exec.call(k,"XMLHttpRequest","getStatus")||0)),n("statusText",h[n("status")]||""),n("response",r.exec.call(k,"XMLHttpRequest","getResponse",n("responseType"))),~e.inArray(n("responseType"),["text",""])?n("responseText",n("response")):"document"===n("responseType")&&n("responseXML",n("response")),U=r.exec.call(k,"XMLHttpRequest","getAllResponseHeaders"),s.dispatchEvent("readystatechange"),n("status")>0?(I&&s.upload.dispatchEvent(t),s.dispatchEvent(t)):(N=!0,s.dispatchEvent("error")),i()}),k.bind("Abort",function(e){s.dispatchEvent(e),i()}),k.bind("Error",function(e){N=!0,n("readyState",p.DONE),s.dispatchEvent("readystatechange"),D=!0,s.dispatchEvent(e),i()}),r.exec.call(k,"XMLHttpRequest","send",{url:E,method:_,async:w,user:R,password:b,headers:x,mimeType:S,encoding:T,responseType:s.responseType,withCredentials:s.withCredentials,options:P},t)}var s=this;M=(new Date).getTime(),k=new a,"string"==typeof P.required_caps&&(P.required_caps=o.parseCaps(P.required_caps)),P.required_caps=e.extend({},P.required_caps,{return_response_type:s.responseType}),t instanceof c&&(P.required_caps.send_multipart=!0),L||(P.required_caps.do_cors=!0),P.ruid?r(k.connectRuntime(P)):(k.bind("RuntimeInit",function(e,t){r(t)}),k.bind("RuntimeError",function(e,t){s.dispatchEvent("RuntimeError",t)}),k.connectRuntime(P))}function g(){n("responseText",""),n("responseXML",null),n("response",null),n("status",0),n("statusText",""),M=C=null}var v=this,y={timeout:0,readyState:p.UNSENT,withCredentials:!1,status:0,statusText:"",responseType:"",responseXML:null,responseText:null,response:null},w=!0,E,_,x={},R,b,T=null,S=null,A=!1,O=!1,I=!1,D=!1,N=!1,L=!1,M,C,F=null,H=null,P={},k,U="",B;e.extend(this,y,{uid:e.guid("uid_"),upload:new f,open:function(o,a,s,u,c){var l;if(!o||!a)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(/[\u0100-\uffff]/.test(o)||i.utf8_encode(o)!==o)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(~e.inArray(o.toUpperCase(),["CONNECT","DELETE","GET","HEAD","OPTIONS","POST","PUT","TRACE","TRACK"])&&(_=o.toUpperCase()),~e.inArray(_,["CONNECT","TRACE","TRACK"]))throw new t.DOMException(t.DOMException.SECURITY_ERR);if(a=i.utf8_encode(a),l=r.parseUrl(a),L=r.hasSameOrigin(l),E=r.resolveUrl(a),(u||c)&&!L)throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);if(R=u||l.user,b=c||l.pass,w=s||!0,w===!1&&(n("timeout")||n("withCredentials")||""!==n("responseType")))throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);A=!w,O=!1,x={},g.call(this),n("readyState",p.OPENED),this.convertEventPropsToHandlers(["readystatechange"]),this.dispatchEvent("readystatechange")},setRequestHeader:function(r,o){var a=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","content-transfer-encoding","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","user-agent","via"];if(n("readyState")!==p.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(/[\u0100-\uffff]/.test(r)||i.utf8_encode(r)!==r)throw new t.DOMException(t.DOMException.SYNTAX_ERR);return r=e.trim(r).toLowerCase(),~e.inArray(r,a)||/^(proxy\-|sec\-)/.test(r)?!1:(x[r]?x[r]+=", "+o:x[r]=o,!0)},getAllResponseHeaders:function(){return U||""},getResponseHeader:function(t){return t=t.toLowerCase(),N||~e.inArray(t,["set-cookie","set-cookie2"])?null:U&&""!==U&&(B||(B={},e.each(U.split(/\r\n/),function(t){var n=t.split(/:\s+/);2===n.length&&(n[0]=e.trim(n[0]),B[n[0].toLowerCase()]={header:n[0],value:e.trim(n[1])})})),B.hasOwnProperty(t))?B[t].header+": "+B[t].value:null},overrideMimeType:function(i){var r,o;if(~e.inArray(n("readyState"),[p.LOADING,p.DONE]))throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(i=e.trim(i.toLowerCase()),/;/.test(i)&&(r=i.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))&&(i=r[1],r[2]&&(o=r[2])),!d.mimes[i])throw new t.DOMException(t.DOMException.SYNTAX_ERR);F=i,H=o},send:function(n,r){if(P="string"===e.typeOf(r)?{ruid:r}:r?r:{},this.convertEventPropsToHandlers(m),this.upload.convertEventPropsToHandlers(m),this.readyState!==p.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(n instanceof s)P.ruid=n.ruid,S=n.type||"application/octet-stream";else if(n instanceof c){if(n.hasBlob()){var o=n.getBlob();P.ruid=o.ruid,S=o.type||"application/octet-stream"}}else"string"==typeof n&&(T="UTF-8",S="text/plain;charset=UTF-8",n=i.utf8_encode(n));this.withCredentials||(this.withCredentials=P.required_caps&&P.required_caps.send_browser_cookies&&!L),I=!A&&this.upload.hasEventListener(),N=!1,D=!n,A||(O=!0),u.call(this,n)},abort:function(){if(N=!0,A=!1,~e.inArray(n("readyState"),[p.UNSENT,p.OPENED,p.DONE]))n("readyState",p.UNSENT);else{if(n("readyState",p.DONE),O=!1,!k)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);k.getRuntime().exec.call(k,"XMLHttpRequest","abort",D),D=!0}},destroy:function(){k&&("function"===e.typeOf(k.destroy)&&k.destroy(),k=null),this.unbindAll(),this.upload&&(this.upload.unbindAll(),this.upload=null)}})}var h={100:"Continue",101:"Switching Protocols",102:"Processing",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"Reserved",307:"Temporary Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",426:"Upgrade Required",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",510:"Not Extended"};f.prototype=n.instance;var m=["loadstart","progress","abort","error","load","timeout","loadend"],g=1,v=2;return p.UNSENT=0,p.OPENED=1,p.HEADERS_RECEIVED=2,p.LOADING=3,p.DONE=4,p.prototype=n.instance,p}),i(O,[u,m,v,h],function(e,t,n,i){function r(){function i(){l=d=0,c=this.result=null}function o(t,n){var i=this;u=n,i.bind("TransportingProgress",function(t){d=t.loaded,l>d&&-1===e.inArray(i.state,[r.IDLE,r.DONE])&&a.call(i)},999),i.bind("TransportingComplete",function(){d=l,i.state=r.DONE,c=null,i.result=u.exec.call(i,"Transporter","getAsBlob",t||"")},999),i.state=r.BUSY,i.trigger("TransportingStarted"),a.call(i)}function a(){var e=this,n,i=l-d;f>i&&(f=i),n=t.btoa(c.substr(d,f)),u.exec.call(e,"Transporter","receive",n,l)}var s,u,c,l,d,f;n.call(this),e.extend(this,{uid:e.guid("uid_"),state:r.IDLE,result:null,transport:function(t,n,r){var a=this;if(r=e.extend({chunk_size:204798},r),(s=r.chunk_size%3)&&(r.chunk_size+=3-s),f=r.chunk_size,i.call(this),c=t,l=t.length,"string"===e.typeOf(r)||r.ruid)o.call(a,n,this.connectRuntime(r));else{var u=function(e,t){a.unbind("RuntimeInit",u),o.call(a,n,t)};this.bind("RuntimeInit",u),this.connectRuntime(r)}},abort:function(){var e=this;e.state=r.IDLE,u&&(u.exec.call(e,"Transporter","clear"),e.trigger("TransportingAborted")),i.call(e)},destroy:function(){this.unbindAll(),u=null,this.disconnectRuntime(),i.call(this)}})}return r.IDLE=0,r.BUSY=1,r.DONE=2,r.prototype=i.instance,r}),i(I,[u,f,p,T,A,g,v,O,d,h,y,w,m],function(e,t,n,i,r,o,a,s,u,c,l,d,f){function p(){function i(e){e||(e=this.getRuntime().exec.call(this,"Image","getInfo")),this.size=e.size,this.width=e.width,this.height=e.height,this.type=e.type,this.meta=e.meta,""===this.name&&(this.name=e.name)}function c(t){var i=e.typeOf(t);try{if(t instanceof p){if(!t.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);m.apply(this,arguments)}else if(t instanceof l){if(!~e.inArray(t.type,["image/jpeg","image/png"]))throw new n.ImageError(n.ImageError.WRONG_FORMAT);g.apply(this,arguments)}else if(-1!==e.inArray(i,["blob","file"]))c.call(this,new d(null,t),arguments[1]);else if("string"===i)/^data:[^;]*;base64,/.test(t)?c.call(this,new l(null,{data:t}),arguments[1]):v.apply(this,arguments);else{if("node"!==i||"img"!==t.nodeName.toLowerCase())throw new n.DOMException(n.DOMException.TYPE_MISMATCH_ERR);c.call(this,t.src,arguments[1])}}catch(r){this.trigger("error",r)}}function m(t,n){var i=this.connectRuntime(t.ruid);this.ruid=i.uid,i.exec.call(this,"Image","loadFromImage",t,"undefined"===e.typeOf(n)?!0:n)}function g(t,n){function i(e){r.ruid=e.uid,e.exec.call(r,"Image","loadFromBlob",t)}var r=this;r.name=t.name||"",t.isDetached()?(this.bind("RuntimeInit",function(e,t){i(t)}),n&&"string"==typeof n.required_caps&&(n.required_caps=o.parseCaps(n.required_caps)),this.connectRuntime(e.extend({required_caps:{access_image_binary:!0,resize_image:!0}},n))):i(this.connectRuntime(t.ruid))}function v(e,t){var n=this,i;i=new r,i.open("get",e),i.responseType="blob",i.onprogress=function(e){n.trigger(e)},i.onload=function(){g.call(n,i.response,!0)},i.onerror=function(e){n.trigger(e)},i.onloadend=function(){i.destroy()},i.bind("RuntimeError",function(e,t){n.trigger("RuntimeError",t)}),i.send(null,t)}a.call(this),e.extend(this,{uid:e.guid("uid_"),ruid:null,name:"",size:0,width:0,height:0,type:"",meta:{},clone:function(){this.load.apply(this,arguments)},load:function(){this.bind("Load Resize",function(){i.call(this)},999),this.convertEventPropsToHandlers(h),c.apply(this,arguments)},downsize:function(t,i,r,o){try{if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>p.MAX_RESIZE_WIDTH||this.height>p.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);(!t&&!i||"undefined"===e.typeOf(r))&&(r=!1),t=t||this.width,i=i||this.height,o="undefined"===e.typeOf(o)?!0:!!o,this.getRuntime().exec.call(this,"Image","downsize",t,i,r,o)}catch(a){this.trigger("error",a)}},crop:function(e,t,n){this.downsize(e,t,!0,n)},getAsCanvas:function(){if(!u.can("create_canvas"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);var e=this.connectRuntime(this.ruid);return e.exec.call(this,"Image","getAsCanvas")},getAsBlob:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return e||(e="image/jpeg"),"image/jpeg"!==e||t||(t=90),this.getRuntime().exec.call(this,"Image","getAsBlob",e,t)},getAsDataURL:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return this.getRuntime().exec.call(this,"Image","getAsDataURL",e,t)},getAsBinaryString:function(e,t){var n=this.getAsDataURL(e,t);return f.atob(n.substring(n.indexOf("base64,")+7))},embed:function(i){function r(){if(u.can("create_canvas")){var t=a.getAsCanvas();if(t)return i.appendChild(t),t=null,a.destroy(),o.trigger("embedded"),void 0}var r=a.getAsDataURL(c,l);if(!r)throw new n.ImageError(n.ImageError.WRONG_FORMAT);if(u.can("use_data_uri_of",r.length))i.innerHTML='<img src="'+r+'" width="'+a.width+'" height="'+a.height+'" />',a.destroy(),o.trigger("embedded");else{var d=new s;d.bind("TransportingComplete",function(){v=o.connectRuntime(this.result.ruid),o.bind("Embedded",function(){e.extend(v.getShimContainer().style,{top:"0px",left:"0px",width:a.width+"px",height:a.height+"px"}),v=null},999),v.exec.call(o,"ImageView","display",this.result.uid,m,g),a.destroy()}),d.transport(f.atob(r.substring(r.indexOf("base64,")+7)),c,e.extend({},h,{required_caps:{display_media:!0},runtime_order:"flash,silverlight",container:i}))}}var o=this,a,c,l,d,h=arguments[1]||{},m=this.width,g=this.height,v;try{if(!(i=t.get(i)))throw new n.DOMException(n.DOMException.INVALID_NODE_TYPE_ERR);if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>p.MAX_RESIZE_WIDTH||this.height>p.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);if(c=h.type||this.type||"image/jpeg",l=h.quality||90,d="undefined"!==e.typeOf(h.crop)?h.crop:!1,h.width)m=h.width,g=h.height||m;else{var y=t.getSize(i);y.w&&y.h&&(m=y.w,g=y.h)}return a=new p,a.bind("Resize",function(){r.call(o)}),a.bind("Load",function(){a.downsize(m,g,d,!1)}),a.clone(this,!1),a}catch(w){this.trigger("error",w)}},destroy:function(){this.ruid&&(this.getRuntime().exec.call(this,"Image","destroy"),this.disconnectRuntime()),this.unbindAll()}})}var h=["progress","load","error","resize","embedded"];return p.MAX_RESIZE_WIDTH=6500,p.MAX_RESIZE_HEIGHT=6500,p.prototype=c.instance,p}),i(D,[u,p,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue,c=e.extend({access_binary:s(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return r.can("access_binary")&&!!a.Image},display_media:s(i.can("create_canvas")||i.can("use_data_uri_over32kb")),do_cors:s(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:s(function(){var e=document.createElement("div");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&("IE"!==i.browser||i.version>9)}()),filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),return_response_headers:u,return_response_type:function(e){return"json"===e&&window.JSON?!0:i.can("return_response_type",e)},return_status_code:u,report_upload_progress:s(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return r.can("access_binary")&&i.can("create_canvas")},select_file:function(){return i.can("use_fileinput")&&window.File},select_folder:function(){return r.can("select_file")&&"Chrome"===i.browser&&i.version>=21},select_multiple:function(){return!(!r.can("select_file")||"Safari"===i.browser&&"Windows"===i.os||"iOS"===i.os&&i.verComp(i.osVersion,"7.0.4","<"))},send_binary_string:s(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:s(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||r.can("send_binary_string")},slice_blob:s(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return r.can("slice_blob")&&r.can("send_multipart")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||"IE"===i.browser&&i.version>=10||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u},arguments[2]);n.call(this,t,arguments[1]||o,c),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html5",a={};return n.addConstructor(o,r),a}),i(N,[D,y],function(e,t){function n(){function e(e,t,n){var i;if(!window.File.prototype.slice)return(i=window.File.prototype.webkitSlice||window.File.prototype.mozSlice)?i.call(e,t,n):null;try{return e.slice(),e.slice(t,n)}catch(r){return e.slice(t,n-t)}}this.slice=function(){return new t(this.getRuntime().uid,e.apply(this,arguments))}}return e.Blob=n}),i(L,[u],function(e){function t(){this.returnValue=!1}function n(){this.cancelBubble=!0}var i={},r="moxie_"+e.guid(),o=function(o,a,s,u){var c,l;a=a.toLowerCase(),o.addEventListener?(c=s,o.addEventListener(a,c,!1)):o.attachEvent&&(c=function(){var e=window.event;e.target||(e.target=e.srcElement),e.preventDefault=t,e.stopPropagation=n,s(e)},o.attachEvent("on"+a,c)),o[r]||(o[r]=e.guid()),i.hasOwnProperty(o[r])||(i[o[r]]={}),l=i[o[r]],l.hasOwnProperty(a)||(l[a]=[]),l[a].push({func:c,orig:s,key:u})},a=function(t,n,o){var a,s;if(n=n.toLowerCase(),t[r]&&i[t[r]]&&i[t[r]][n]){a=i[t[r]][n];for(var u=a.length-1;u>=0&&(a[u].orig!==o&&a[u].key!==o||(t.removeEventListener?t.removeEventListener(n,a[u].func,!1):t.detachEvent&&t.detachEvent("on"+n,a[u].func),a[u].orig=null,a[u].func=null,a.splice(u,1),o===s));u--);if(a.length||delete i[t[r]][n],e.isEmptyObj(i[t[r]])){delete i[t[r]];try{delete t[r]}catch(c){t[r]=s}}}},s=function(t,n){t&&t[r]&&e.each(i[t[r]],function(e,i){a(t,i,n)})};return{addEvent:o,removeEvent:a,removeAllEvents:s}}),i(M,[D,u,f,L,l,d],function(e,t,n,i,r,o){function a(){var e=[],a;t.extend(this,{init:function(s){var u=this,c=u.getRuntime(),l,d,f,p,h,m;a=s,e=[],f=a.accept.mimes||r.extList2mimes(a.accept,c.can("filter_by_extension")),d=c.getShimContainer(),d.innerHTML='<input id="'+c.uid+'" type="file" style="font-size:999px;opacity:0;"'+(a.multiple&&c.can("select_multiple")?"multiple":"")+(a.directory&&c.can("select_folder")?"webkitdirectory directory":"")+(f?' accept="'+f.join(",")+'"':"")+" />",l=n.get(c.uid),t.extend(l.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),p=n.get(a.browse_button),c.can("summon_file_dialog")&&("static"===n.getStyle(p,"position")&&(p.style.position="relative"),h=parseInt(n.getStyle(p,"z-index"),10)||1,p.style.zIndex=h,d.style.zIndex=h-1,i.addEvent(p,"click",function(e){var t=n.get(c.uid);t&&!t.disabled&&t.click(),e.preventDefault()},u.uid)),m=c.can("summon_file_dialog")?p:d,i.addEvent(m,"mouseover",function(){u.trigger("mouseenter")},u.uid),i.addEvent(m,"mouseout",function(){u.trigger("mouseleave")},u.uid),i.addEvent(m,"mousedown",function(){u.trigger("mousedown")},u.uid),i.addEvent(n.get(a.container),"mouseup",function(){u.trigger("mouseup")},u.uid),l.onchange=function g(){if(e=[],a.directory?t.each(this.files,function(t){"."!==t.name&&e.push(t)}):e=[].slice.call(this.files),"IE"!==o.browser)this.value="";else{var n=this.cloneNode(!0);this.parentNode.replaceChild(n,this),n.onchange=g}u.trigger("change")},u.trigger({type:"ready",async:!0}),d=null},getFiles:function(){return e},disable:function(e){var t=this.getRuntime(),i;(i=n.get(t.uid))&&(i.disabled=!!e)},destroy:function(){var t=this.getRuntime(),r=t.getShim(),o=t.getShimContainer();i.removeAllEvents(o,this.uid),i.removeAllEvents(a&&n.get(a.container),this.uid),i.removeAllEvents(a&&n.get(a.browse_button),this.uid),o&&(o.innerHTML=""),r.removeInstance(this.uid),e=a=o=r=null}})}return e.FileInput=a}),i(C,[D,u,f,L,l],function(e,t,n,i,r){function o(){function e(e){for(var n=[],i=0;i<e.length;i++)[].push.apply(n,e[i].extensions.split(/\s*,\s*/));return-1===t.inArray("*",n)?n:[]}function o(e){var n=r.getFileExtension(e.name);return!n||!d.length||-1!==t.inArray(n,d)}function a(e,n){var i=[];t.each(e,function(e){var t=e.webkitGetAsEntry();if(t)if(t.isFile){var n=e.getAsFile();o(n)&&l.push(n)}else i.push(t)}),i.length?s(i,n):n()}function s(e,n){var i=[];t.each(e,function(e){i.push(function(t){u(e,t)})}),t.inSeries(i,function(){n()})}function u(e,t){e.isFile?e.file(function(e){o(e)&&l.push(e),t()},function(){t()}):e.isDirectory?c(e,t):t()}function c(e,t){function n(e){r.readEntries(function(t){t.length?([].push.apply(i,t),n(e)):e()},e)}var i=[],r=e.createReader();n(function(){s(i,t)})}var l=[],d=[],f;t.extend(this,{init:function(n){var r=this,s;f=n,d=e(f.accept),s=f.container,i.addEvent(s,"dragover",function(e){e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="copy"},r.uid),i.addEvent(s,"drop",function(e){e.preventDefault(),e.stopPropagation(),l=[],e.dataTransfer.items&&e.dataTransfer.items[0].webkitGetAsEntry?a(e.dataTransfer.items,function(){r.trigger("drop")}):(t.each(e.dataTransfer.files,function(e){o(e)&&l.push(e)}),r.trigger("drop"))},r.uid),i.addEvent(s,"dragenter",function(e){e.preventDefault(),e.stopPropagation(),r.trigger("dragenter")},r.uid),i.addEvent(s,"dragleave",function(e){e.preventDefault(),e.stopPropagation(),r.trigger("dragleave")},r.uid)},getFiles:function(){return l},destroy:function(){i.removeAllEvents(f&&n.get(f.container),this.uid),l=d=f=null}})}return e.FileDrop=o}),i(F,[D,m,u],function(e,t,n){function i(){function e(e){return t.atob(e.substring(e.indexOf("base64,")+7))}var i,r=!1;n.extend(this,{read:function(e,t){var o=this;i=new window.FileReader,i.addEventListener("progress",function(e){o.trigger(e)}),i.addEventListener("load",function(e){o.trigger(e)}),i.addEventListener("error",function(e){o.trigger(e,i.error)}),i.addEventListener("loadend",function(){i=null}),"function"===n.typeOf(i[e])?(r=!1,i[e](t.getSource())):"readAsBinaryString"===e&&(r=!0,i.readAsDataURL(t.getSource()))},getResult:function(){return i&&i.result?r?e(i.result):i.result:null},abort:function(){i&&i.abort()},destroy:function(){i=null}})}return e.FileReader=i}),i(H,[D,u,l,b,w,y,S,p,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(e,t){var n=this,i,r;i=t.getBlob().getSource(),r=new window.FileReader,r.onload=function(){t.append(t.getBlobName(),new o(null,{type:i.type,data:r.result})),f.send.call(n,e,t)},r.readAsBinaryString(i)}function c(){return!window.XMLHttpRequest||"IE"===u.browser&&u.version<8?function(){for(var e=["Msxml2.XMLHTTP.6.0","Microsoft.XMLHTTP"],t=0;t<e.length;t++)try{return new ActiveXObject(e[t])}catch(n){}}():new window.XMLHttpRequest}function l(e){var t=e.responseXML,n=e.responseText;return"IE"===u.browser&&n&&t&&!t.documentElement&&/[^\/]+\/[^\+]+\+xml/.test(e.getResponseHeader("Content-Type"))&&(t=new window.ActiveXObject("Microsoft.XMLDOM"),t.async=!1,t.validateOnParse=!1,t.loadXML(n)),t&&("IE"===u.browser&&0!==t.parseError||!t.documentElement||"parsererror"===t.documentElement.tagName)?null:t}function d(e){var t="----moxieboundary"+(new Date).getTime(),n="--",i="\r\n",r="",a=this.getRuntime();if(!a.can("send_binary_string"))throw new s.RuntimeError(s.RuntimeError.NOT_SUPPORTED_ERR);return p.setRequestHeader("Content-Type","multipart/form-data; boundary="+t),e.each(function(e,a){r+=e instanceof o?n+t+i+'Content-Disposition: form-data; name="'+a+'"; filename="'+unescape(encodeURIComponent(e.name||"blob"))+'"'+i+"Content-Type: "+(e.type||"application/octet-stream")+i+i+e.getSource()+i:n+t+i+'Content-Disposition: form-data; name="'+a+'"'+i+i+unescape(encodeURIComponent(e))+i}),r+=n+t+n+i}var f=this,p,h;t.extend(this,{send:function(n,r){var s=this,l="Mozilla"===u.browser&&u.version>=4&&u.version<7,f="Android Browser"===u.browser,m=!1;if(h=n.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase(),p=c(),p.open(n.method,n.url,n.async,n.user,n.password),r instanceof o)r.isDetached()&&(m=!0),r=r.getSource();else if(r instanceof a){if(r.hasBlob())if(r.getBlob().isDetached())r=d.call(s,r),m=!0;else if((l||f)&&"blob"===t.typeOf(r.getBlob().getSource())&&window.FileReader)return e.call(s,n,r),void 0;if(r instanceof a){var g=new window.FormData;r.each(function(e,t){e instanceof o?g.append(t,e.getSource()):g.append(t,e)}),r=g}}p.upload?(n.withCredentials&&(p.withCredentials=!0),p.addEventListener("load",function(e){s.trigger(e)}),p.addEventListener("error",function(e){s.trigger(e)}),p.addEventListener("progress",function(e){s.trigger(e)}),p.upload.addEventListener("progress",function(e){s.trigger({type:"UploadProgress",loaded:e.loaded,total:e.total})})):p.onreadystatechange=function v(){switch(p.readyState){case 1:break;case 2:break;case 3:var e,t;try{i.hasSameOrigin(n.url)&&(e=p.getResponseHeader("Content-Length")||0),p.responseText&&(t=p.responseText.length)}catch(r){e=t=0}s.trigger({type:"progress",lengthComputable:!!e,total:parseInt(e,10),loaded:t});break;case 4:p.onreadystatechange=function(){},0===p.status?s.trigger("error"):s.trigger("load")}},t.isEmptyObj(n.headers)||t.each(n.headers,function(e,t){p.setRequestHeader(t,e)}),""!==n.responseType&&"responseType"in p&&(p.responseType="json"!==n.responseType||u.can("return_response_type","json")?n.responseType:"text"),m?p.sendAsBinary?p.sendAsBinary(r):function(){for(var e=new Uint8Array(r.length),t=0;t<r.length;t++)e[t]=255&r.charCodeAt(t);p.send(e.buffer)}():p.send(r),s.trigger("loadstart")},getStatus:function(){try{if(p)return p.status}catch(e){}return 0},getResponse:function(e){var t=this.getRuntime();try{switch(e){case"blob":var i=new r(t.uid,p.response),o=p.getResponseHeader("Content-Disposition");if(o){var a=o.match(/filename=([\'\"'])([^\1]+)\1/);a&&(h=a[2])}return i.name=h,i.type||(i.type=n.getFileMime(h)),i;case"json":return u.can("return_response_type","json")?p.response:200===p.status&&window.JSON?JSON.parse(p.responseText):null;case"document":return l(p);default:return""!==p.responseText?p.responseText:null}}catch(s){return null}},getAllResponseHeaders:function(){try{return p.getAllResponseHeaders()}catch(e){}return""},abort:function(){p&&p.abort()},destroy:function(){f=h=null}})}return e.XMLHttpRequest=c}),i(P,[],function(){return function(){function e(e,t){var n=r?0:-8*(t-1),i=0,a;for(a=0;t>a;a++)i|=o.charCodeAt(e+a)<<Math.abs(n+8*a);return i}function n(e,t,n){n=3===arguments.length?n:o.length-t-1,o=o.substr(0,t)+e+o.substr(n+t)}function i(e,t,i){var o="",a=r?0:-8*(i-1),s;for(s=0;i>s;s++)o+=String.fromCharCode(255&t>>Math.abs(a+8*s));n(o,e,i)}var r=!1,o;return{II:function(e){return e===t?r:(r=e,void 0)},init:function(e){r=!1,o=e},SEGMENT:function(e,t,i){switch(arguments.length){case 1:return o.substr(e,o.length-e-1);case 2:return o.substr(e,t);case 3:n(i,e,t);break;default:return o}},BYTE:function(t){return e(t,1)},SHORT:function(t){return e(t,2)},LONG:function(n,r){return r===t?e(n,4):(i(n,r,4),void 0)},SLONG:function(t){var n=e(t,4);return n>2147483647?n-4294967296:n},STRING:function(t,n){var i="";for(n+=t;n>t;t++)i+=String.fromCharCode(e(t,1));return i}}}}),i(k,[P],function(e){return function t(n){var i=[],r,o,a,s=0;if(r=new e,r.init(n),65496===r.SHORT(0)){for(o=2;o<=n.length;)if(a=r.SHORT(o),a>=65488&&65495>=a)o+=2;else{if(65498===a||65497===a)break;s=r.SHORT(o+2)+2,a>=65505&&65519>=a&&i.push({hex:a,name:"APP"+(15&a),start:o,length:s,segment:r.SEGMENT(o,s)}),o+=s}return r.init(null),{headers:i,restore:function(e){var t,n;for(r.init(e),o=65504==r.SHORT(2)?4+r.SHORT(4):2,n=0,t=i.length;t>n;n++)r.SEGMENT(o,0,i[n].segment),o+=i[n].length;return e=r.SEGMENT(),r.init(null),e},strip:function(e){var n,i,o;for(i=new t(e),n=i.headers,i.purge(),r.init(e),o=n.length;o--;)r.SEGMENT(n[o].start,n[o].length,"");return e=r.SEGMENT(),r.init(null),e},get:function(e){for(var t=[],n=0,r=i.length;r>n;n++)i[n].name===e.toUpperCase()&&t.push(i[n].segment);return t},set:function(e,t){var n=[],r,o,a;for("string"==typeof t?n.push(t):n=t,r=o=0,a=i.length;a>r&&(i[r].name===e.toUpperCase()&&(i[r].segment=n[o],i[r].length=n[o].length,o++),!(o>=n.length));r++);},purge:function(){i=[],r.init(null),r=null}}}}}),i(U,[u,P],function(e,n){return function i(){function i(e,n){var i=a.SHORT(e),r,o,s,u,d,f,p,h,m=[],g={};for(r=0;i>r;r++)if(p=f=e+12*r+2,s=n[a.SHORT(p)],s!==t){switch(u=a.SHORT(p+=2),d=a.LONG(p+=2),p+=4,m=[],u){case 1:case 7:for(d>4&&(p=a.LONG(p)+c.tiffHeader),o=0;d>o;o++)m[o]=a.BYTE(p+o);break;case 2:d>4&&(p=a.LONG(p)+c.tiffHeader),g[s]=a.STRING(p,d-1);continue;case 3:for(d>2&&(p=a.LONG(p)+c.tiffHeader),o=0;d>o;o++)m[o]=a.SHORT(p+2*o);break;case 4:for(d>1&&(p=a.LONG(p)+c.tiffHeader),o=0;d>o;o++)m[o]=a.LONG(p+4*o);break;case 5:for(p=a.LONG(p)+c.tiffHeader,o=0;d>o;o++)m[o]=a.LONG(p+4*o)/a.LONG(p+4*o+4);break;case 9:for(p=a.LONG(p)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(p+4*o);break;case 10:for(p=a.LONG(p)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(p+4*o)/a.SLONG(p+4*o+4);break;default:continue}h=1==d?m[0]:m,g[s]=l.hasOwnProperty(s)&&"object"!=typeof h?l[s][h]:h}return g}function r(){var e=c.tiffHeader;return a.II(18761==a.SHORT(e)),42!==a.SHORT(e+=2)?!1:(c.IFD0=c.tiffHeader+a.LONG(e+=2),u=i(c.IFD0,s.tiff),"ExifIFDPointer"in u&&(c.exifIFD=c.tiffHeader+u.ExifIFDPointer,delete u.ExifIFDPointer),"GPSInfoIFDPointer"in u&&(c.gpsIFD=c.tiffHeader+u.GPSInfoIFDPointer,delete u.GPSInfoIFDPointer),!0)}function o(e,t,n){var i,r,o,u=0;if("string"==typeof t){var l=s[e.toLowerCase()];for(var d in l)if(l[d]===t){t=d;break}}i=c[e.toLowerCase()+"IFD"],r=a.SHORT(i);for(var f=0;r>f;f++)if(o=i+12*f+2,a.SHORT(o)==t){u=o+8;break}return u?(a.LONG(u,n),!0):!1}var a,s,u,c={},l;return a=new n,s={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"}},l={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire.",1:"Flash fired.",5:"Strobe return light not detected.",7:"Strobe return light detected.",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}},{init:function(e){return c={tiffHeader:10},e!==t&&e.length?(a.init(e),65505===a.SHORT(0)&&"EXIF\0"===a.STRING(4,5).toUpperCase()?r():!1):!1 +},TIFF:function(){return u},EXIF:function(){var t;if(t=i(c.exifIFD,s.exif),t.ExifVersion&&"array"===e.typeOf(t.ExifVersion)){for(var n=0,r="";n<t.ExifVersion.length;n++)r+=String.fromCharCode(t.ExifVersion[n]);t.ExifVersion=r}return t},GPS:function(){var t;return t=i(c.gpsIFD,s.gps),t.GPSVersionID&&"array"===e.typeOf(t.GPSVersionID)&&(t.GPSVersionID=t.GPSVersionID.join(".")),t},setExif:function(e,t){return"PixelXDimension"!==e&&"PixelYDimension"!==e?!1:o("exif",e,t)},getBinary:function(){return a.SEGMENT()},purge:function(){a.init(null),a=u=null,c={}}}}}),i(B,[u,p,k,P,U],function(e,t,n,i,r){function o(o){function a(){for(var e=0,t,n;e<=u.length;){if(t=c.SHORT(e+=2),t>=65472&&65475>=t)return e+=5,{height:c.SHORT(e),width:c.SHORT(e+=2)};n=c.SHORT(e+=2),e+=n-2}return null}function s(){d&&l&&c&&(d.purge(),l.purge(),c.init(null),u=f=l=d=c=null)}var u,c,l,d,f,p;if(u=o,c=new i,c.init(u),65496!==c.SHORT(0))throw new t.ImageError(t.ImageError.WRONG_FORMAT);l=new n(o),d=new r,p=!!d.init(l.get("app1")[0]),f=a.call(this),e.extend(this,{type:"image/jpeg",size:u.length,width:f&&f.width||0,height:f&&f.height||0,setExif:function(t,n){return p?("object"===e.typeOf(t)?e.each(t,function(e,t){d.setExif(t,e)}):d.setExif(t,n),l.set("app1",d.getBinary()),void 0):!1},writeHeaders:function(){return arguments.length?l.restore(arguments[0]):u=l.restore(u)},stripHeaders:function(e){return l.strip(e)},purge:function(){s.call(this)}}),p&&(this.meta={tiff:d.TIFF(),exif:d.EXIF(),gps:d.GPS()})}return o}),i(z,[p,u,P],function(e,t,n){function i(i){function r(){var e,t;return e=a.call(this,8),"IHDR"==e.type?(t=e.start,{width:u.LONG(t),height:u.LONG(t+=4)}):null}function o(){u&&(u.init(null),s=d=c=l=u=null)}function a(e){var t,n,i,r;return t=u.LONG(e),n=u.STRING(e+=4,4),i=e+=4,r=u.LONG(e+t),{length:t,type:n,start:i,CRC:r}}var s,u,c,l,d;s=i,u=new n,u.init(s),function(){var t=0,n=0,i=[35152,20039,3338,6666];for(n=0;n<i.length;n++,t+=2)if(i[n]!=u.SHORT(t))throw new e.ImageError(e.ImageError.WRONG_FORMAT)}(),d=r.call(this),t.extend(this,{type:"image/png",size:s.length,width:d.width,height:d.height,purge:function(){o.call(this)}}),o.call(this)}return i}),i(G,[u,p,B,z],function(e,t,n,i){return function(r){var o=[n,i],a;a=function(){for(var e=0;e<o.length;e++)try{return new o[e](r)}catch(n){}throw new t.ImageError(t.ImageError.WRONG_FORMAT)}(),e.extend(this,{type:"",size:0,width:0,height:0,setExif:function(){},writeHeaders:function(e){return e},stripHeaders:function(e){return e},purge:function(){}}),e.extend(this,a),this.purge=function(){a.purge(),a=null}}}),i(q,[],function(){function e(e,i,r){var o=e.naturalWidth,a=e.naturalHeight,s=r.width,u=r.height,c=r.x||0,l=r.y||0,d=i.getContext("2d");t(e)&&(o/=2,a/=2);var f=1024,p=document.createElement("canvas");p.width=p.height=f;for(var h=p.getContext("2d"),m=n(e,o,a),g=0;a>g;){for(var v=g+f>a?a-g:f,y=0;o>y;){var w=y+f>o?o-y:f;h.clearRect(0,0,f,f),h.drawImage(e,-y,-g);var E=y*s/o+c<<0,_=Math.ceil(w*s/o),x=g*u/a/m+l<<0,R=Math.ceil(v*u/a/m);d.drawImage(p,0,0,w,v,E,x,_,R),y+=f}g+=f}p=h=null}function t(e){var t=e.naturalWidth,n=e.naturalHeight;if(t*n>1048576){var i=document.createElement("canvas");i.width=i.height=1;var r=i.getContext("2d");return r.drawImage(e,-t+1,0),0===r.getImageData(0,0,1,1).data[3]}return!1}function n(e,t,n){var i=document.createElement("canvas");i.width=1,i.height=n;var r=i.getContext("2d");r.drawImage(e,0,0);for(var o=r.getImageData(0,0,1,n).data,a=0,s=n,u=n;u>a;){var c=o[4*(u-1)+3];0===c?s=u:a=u,u=s+a>>1}i=null;var l=u/n;return 0===l?1:l}return{isSubsampled:t,renderTo:e}}),i(X,[D,u,p,m,w,G,q,l,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(){if(!E&&!y)throw new n.ImageError(n.DOMException.INVALID_STATE_ERR);return E||y}function c(e){return i.atob(e.substring(e.indexOf("base64,")+7))}function l(e,t){return"data:"+(t||"")+";base64,"+i.btoa(e)}function d(e){var t=this;y=new Image,y.onerror=function(){g.call(this),t.trigger("error",new n.ImageError(n.ImageError.WRONG_FORMAT))},y.onload=function(){t.trigger("load")},y.src=/^data:[^;]*;base64,/.test(e)?e:l(e,x.type)}function f(e,t){var i=this,r;return window.FileReader?(r=new FileReader,r.onload=function(){t(this.result)},r.onerror=function(){i.trigger("error",new n.FileException(n.FileException.NOT_READABLE_ERR))},r.readAsDataURL(e),void 0):t(e.getAsDataURL())}function p(n,i,r,o){var a=this,s,u,c=0,l=0,d,f,p,g;if(b=o,g=this.meta&&this.meta.tiff&&this.meta.tiff.Orientation||1,-1!==t.inArray(g,[5,6,7,8])){var v=n;n=i,i=v}return d=e(),u=r?Math.max:Math.min,s=u(n/d.width,i/d.height),s>1&&(!r||o)?(this.trigger("Resize"),void 0):(E||(E=document.createElement("canvas")),f=Math.round(d.width*s),p=Math.round(d.height*s),r?(E.width=n,E.height=i,f>n&&(c=Math.round((f-n)/2)),p>i&&(l=Math.round((p-i)/2))):(E.width=f,E.height=p),b||m(E.width,E.height,g),h.call(this,d,E,-c,-l,f,p),this.width=E.width,this.height=E.height,R=!0,a.trigger("Resize"),void 0)}function h(e,t,n,i,r,o){if("iOS"===u.OS)a.renderTo(e,t,{width:r,height:o,x:n,y:i});else{var s=t.getContext("2d");s.drawImage(e,n,i,r,o)}}function m(e,t,n){switch(n){case 5:case 6:case 7:case 8:E.width=t,E.height=e;break;default:E.width=e,E.height=t}var i=E.getContext("2d");switch(n){case 2:i.translate(e,0),i.scale(-1,1);break;case 3:i.translate(e,t),i.rotate(Math.PI);break;case 4:i.translate(0,t),i.scale(1,-1);break;case 5:i.rotate(.5*Math.PI),i.scale(1,-1);break;case 6:i.rotate(.5*Math.PI),i.translate(0,-t);break;case 7:i.rotate(.5*Math.PI),i.translate(e,-t),i.scale(-1,1);break;case 8:i.rotate(-.5*Math.PI),i.translate(-e,0)}}function g(){w&&(w.purge(),w=null),_=y=E=x=null,R=!1}var v=this,y,w,E,_,x,R=!1,b=!0;t.extend(this,{loadFromBlob:function(e){var t=this,i=t.getRuntime(),r=arguments.length>1?arguments[1]:!0;if(!i.can("access_binary"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);return x=e,e.isDetached()?(_=e.getSource(),d.call(this,_),void 0):(f.call(this,e.getSource(),function(e){r&&(_=c(e)),d.call(t,e)}),void 0)},loadFromImage:function(e,t){this.meta=e.meta,x=new r(null,{name:e.name,size:e.size,type:e.type}),d.call(this,t?_=e.getAsBinaryString():e.getAsDataURL())},getInfo:function(){var t=this.getRuntime(),n;return!w&&_&&t.can("access_image_binary")&&(w=new o(_)),n={width:e().width||0,height:e().height||0,type:x.type||s.getFileMime(x.name),size:_&&_.length||x.size||0,name:x.name||"",meta:w&&w.meta||this.meta||{}}},downsize:function(){p.apply(this,arguments)},getAsCanvas:function(){return E&&(E.id=this.uid+"_canvas"),E},getAsBlob:function(e,t){return e!==this.type&&p.call(this,this.width,this.height,!1),new r(null,{name:x.name||"",type:e,data:v.getAsBinaryString.call(this,e,t)})},getAsDataURL:function(e){var t=arguments[1]||90;if(!R)return y.src;if("image/jpeg"!==e)return E.toDataURL("image/png");try{return E.toDataURL("image/jpeg",t/100)}catch(n){return E.toDataURL("image/jpeg")}},getAsBinaryString:function(e,t){if(!R)return _||(_=c(v.getAsDataURL(e,t))),_;if("image/jpeg"!==e)_=c(v.getAsDataURL(e,t));else{var n;t||(t=90);try{n=E.toDataURL("image/jpeg",t/100)}catch(i){n=E.toDataURL("image/jpeg")}_=c(n),w&&(_=w.stripHeaders(_),b&&(w.meta&&w.meta.exif&&w.setExif({PixelXDimension:this.width,PixelYDimension:this.height}),_=w.writeHeaders(_)),w.purge(),w=null)}return R=!1,_},destroy:function(){v=null,g.call(this),this.getRuntime().getShim().removeInstance(this.uid)}})}return e.Image=c}),i(j,[u,d,f,p,g],function(e,t,n,i,r){function o(){var e;try{e=navigator.plugins["Shockwave Flash"],e=e.description}catch(t){try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(n){e="0.0"}}return e=e.match(/\d+/g),parseFloat(e[0]+"."+e[1])}function a(a){var c=this,l;a=e.extend({swf_url:t.swf_url},a),r.call(this,a,s,{access_binary:function(e){return e&&"browser"===c.mode},access_image_binary:function(e){return e&&"browser"===c.mode},display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:function(){return"client"===c.mode},resize_image:r.capTrue,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!e.arrayDiff(t,["","text","document"])||"browser"===c.mode},return_status_code:function(t){return"browser"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:function(e){return e&&"browser"===c.mode},send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"browser"===c.mode},send_multipart:r.capTrue,slice_blob:r.capTrue,stream_upload:function(e){return e&&"browser"===c.mode},summon_file_dialog:!1,upload_filesize:function(t){return e.parseSizeStr(t)<=2097152||"client"===c.mode},use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}},{access_binary:function(e){return e?"browser":"client"},access_image_binary:function(e){return e?"browser":"client"},report_upload_progress:function(e){return e?"browser":"client"},return_response_type:function(t){return e.arrayDiff(t,["","text","json","document"])?"browser":["client","browser"]},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"browser":["client","browser"]},send_binary_string:function(e){return e?"browser":"client"},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"browser":"client"},stream_upload:function(e){return e?"client":"browser"},upload_filesize:function(t){return e.parseSizeStr(t)>=2097152?"client":"browser"}},"client"),o()<10&&(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid)},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var n,r,o;o=this.getShimContainer(),e.extend(o.style,{position:"absolute",top:"-8px",left:"-8px",width:"9px",height:"9px",overflow:"hidden"}),n='<object id="'+this.uid+'" type="application/x-shockwave-flash" data="'+a.swf_url+'" ',"IE"===t.browser&&(n+='classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '),n+='width="100%" height="100%" style="outline:0"><param name="movie" value="'+a.swf_url+'" />'+'<param name="flashvars" value="uid='+escape(this.uid)+"&target="+t.global_event_dispatcher+'" />'+'<param name="wmode" value="transparent" />'+'<param name="allowscriptaccess" value="always" />'+"</object>","IE"===t.browser?(r=document.createElement("div"),o.appendChild(r),r.outerHTML=n,r=o=null):o.innerHTML=n,l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="flash",u={};return r.addConstructor(s,a),u}),i(V,[j,y],function(e,t){var n={slice:function(e,n,i,r){var o=this.getRuntime();return 0>n?n=Math.max(e.size+n,0):n>0&&(n=Math.min(n,e.size)),0>i?i=Math.max(e.size+i,0):i>0&&(i=Math.min(i,e.size)),e=o.shimExec.call(this,"Blob","slice",n,i,r||""),e&&(e=new t(o.uid,e)),e}};return e.Blob=n}),i(W,[j],function(e){var t={init:function(e){this.getRuntime().shimExec.call(this,"FileInput","init",{name:e.name,accept:e.accept,multiple:e.multiple}),this.trigger("ready")}};return e.FileInput=t}),i(Y,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i="",r={read:function(e,t){var r=this,o=r.getRuntime();return"readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"),r.bind("Progress",function(t,r){r&&(i+=n(r,e))}),o.shimExec.call(this,"FileReader","readAsBase64",t.uid)},getResult:function(){return i},destroy:function(){i=null}};return e.FileReader=r}),i($,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i={read:function(e,t){var i,r=this.getRuntime();return(i=r.shimExec.call(this,"FileReaderSync","readAsBase64",t.uid))?("readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"+i),n(i,e,t.type)):null}};return e.FileReaderSync=i}),i(J,[j,u,y,w,T,S,O],function(e,t,n,i,r,o,a){var s={send:function(e,i){function r(){e.transport=l.mode,l.shimExec.call(c,"XMLHttpRequest","send",e,i)}function s(e,t){l.shimExec.call(c,"XMLHttpRequest","appendBlob",e,t.uid),i=null,r()}function u(e,t){var n=new a;n.bind("TransportingComplete",function(){t(this.result)}),n.transport(e.getSource(),e.type,{ruid:l.uid})}var c=this,l=c.getRuntime();if(t.isEmptyObj(e.headers)||t.each(e.headers,function(e,t){l.shimExec.call(c,"XMLHttpRequest","setRequestHeader",t,e.toString())}),i instanceof o){var d;if(i.each(function(e,t){e instanceof n?d=t:l.shimExec.call(c,"XMLHttpRequest","append",t,e)}),i.hasBlob()){var f=i.getBlob();f.isDetached()?u(f,function(e){f.destroy(),s(d,e)}):s(d,f)}else i=null,r()}else i instanceof n?i.isDetached()?u(i,function(e){i.destroy(),i=e.uid,r()}):(i=i.uid,r()):r()},getResponse:function(e){var n,o,a=this.getRuntime();if(o=a.shimExec.call(this,"XMLHttpRequest","getResponseAsBlob")){if(o=new i(a.uid,o),"blob"===e)return o;try{if(n=new r,~t.inArray(e,["","text"]))return n.readAsText(o);if("json"===e&&window.JSON)return JSON.parse(n.readAsText(o))}finally{o.destroy()}}return null},abort:function(e){var t=this.getRuntime();t.shimExec.call(this,"XMLHttpRequest","abort"),this.dispatchEvent("readystatechange"),this.dispatchEvent("abort")}};return e.XMLHttpRequest=s}),i(Z,[j,y],function(e,t){var n={getAsBlob:function(e){var n=this.getRuntime(),i=n.shimExec.call(this,"Transporter","getAsBlob",e);return i?new t(n.uid,i):null}};return e.Transporter=n}),i(K,[j,u,O,y,T],function(e,t,n,i,r){var o={loadFromBlob:function(e){function t(e){r.shimExec.call(i,"Image","loadFromBlob",e.uid),i=r=null}var i=this,r=i.getRuntime();if(e.isDetached()){var o=new n;o.bind("TransportingComplete",function(){t(o.result.getSource())}),o.transport(e.getSource(),e.type,{ruid:r.uid})}else t(e.getSource())},loadFromImage:function(e){var t=this.getRuntime();return t.shimExec.call(this,"Image","loadFromImage",e.uid)},getAsBlob:function(e,t){var n=this.getRuntime(),r=n.shimExec.call(this,"Image","getAsBlob",e,t);return r?new i(n.uid,r):null},getAsDataURL:function(){var e=this.getRuntime(),t=e.Image.getAsBlob.apply(this,arguments),n;return t?(n=new r,n.readAsDataURL(t)):null}};return e.Image=o}),i(Q,[u,d,f,p,g],function(e,t,n,i,r){function o(e){var t=!1,n=null,i,r,o,a,s,u=0;try{try{n=new ActiveXObject("AgControl.AgControl"),n.IsVersionSupported(e)&&(t=!0),n=null}catch(c){var l=navigator.plugins["Silverlight Plug-In"];if(l){for(i=l.description,"1.0.30226.2"===i&&(i="2.0.30226.2"),r=i.split(".");r.length>3;)r.pop();for(;r.length<4;)r.push(0);for(o=e.split(".");o.length>4;)o.pop();do a=parseInt(o[u],10),s=parseInt(r[u],10),u++;while(u<o.length&&a===s);s>=a&&!isNaN(a)&&(t=!0)}}}catch(d){t=!1}return t}function a(a){var c=this,l;a=e.extend({xap_url:t.xap_url},a),r.call(this,a,s,{access_binary:r.capTrue,access_image_binary:r.capTrue,display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:r.capTrue,resize_image:r.capTrue,return_response_headers:function(e){return e&&"client"===c.mode},return_response_type:function(e){return"json"!==e?!0:!!window.JSON},return_status_code:function(t){return"client"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:r.capTrue,send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"client"===c.mode},send_multipart:r.capTrue,slice_blob:r.capTrue,stream_upload:!0,summon_file_dialog:!1,upload_filesize:r.capTrue,use_http_method:function(t){return"client"===c.mode||!e.arrayDiff(t,["GET","POST"])}},{return_response_headers:function(e){return e?"client":"browser"},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"client":["client","browser"]},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"client":"browser"},use_http_method:function(t){return e.arrayDiff(t,["GET","POST"])?"client":["client","browser"]}}),o("2.0.31005.0")&&"Opera"!==t.browser||(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid).content.Moxie},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var e;e=this.getShimContainer(),e.innerHTML='<object id="'+this.uid+'" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%" style="outline:none;">'+'<param name="source" value="'+a.xap_url+'"/>'+'<param name="background" value="Transparent"/>'+'<param name="windowless" value="true"/>'+'<param name="enablehtmlaccess" value="true"/>'+'<param name="initParams" value="uid='+this.uid+",target="+t.global_event_dispatcher+'"/>'+"</object>",l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},"Windows"!==t.OS?1e4:5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="silverlight",u={};return r.addConstructor(s,a),u}),i(et,[Q,u,V],function(e,t,n){return e.Blob=t.extend({},n)}),i(tt,[Q],function(e){var t={init:function(e){function t(e){for(var t="",n=0;n<e.length;n++)t+=(""!==t?"|":"")+e[n].title+" | *."+e[n].extensions.replace(/,/g,";*.");return t}this.getRuntime().shimExec.call(this,"FileInput","init",t(e.accept),e.name,e.multiple),this.trigger("ready")}};return e.FileInput=t}),i(nt,[Q,f,L],function(e,t,n){var i={init:function(){var e=this,i=e.getRuntime(),r;return r=i.getShimContainer(),n.addEvent(r,"dragover",function(e){e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="copy"},e.uid),n.addEvent(r,"dragenter",function(e){e.preventDefault();var n=t.get(i.uid).dragEnter(e);n&&e.stopPropagation()},e.uid),n.addEvent(r,"drop",function(e){e.preventDefault();var n=t.get(i.uid).dragDrop(e);n&&e.stopPropagation()},e.uid),i.shimExec.call(this,"FileDrop","init")}};return e.FileDrop=i}),i(it,[Q,u,Y],function(e,t,n){return e.FileReader=t.extend({},n)}),i(rt,[Q,u,$],function(e,t,n){return e.FileReaderSync=t.extend({},n)}),i(ot,[Q,u,J],function(e,t,n){return e.XMLHttpRequest=t.extend({},n)}),i(at,[Q,u,Z],function(e,t,n){return e.Transporter=t.extend({},n)}),i(st,[Q,u,K],function(e,t,n){return e.Image=t.extend({},n,{getInfo:function(){var e=this.getRuntime(),n=["tiff","exif","gps"],i={meta:{}},r=e.shimExec.call(this,"Image","getInfo");return r.meta&&t.each(n,function(e){var t=r.meta[e],n,o,a,s;if(t&&t.keys)for(i.meta[e]={},o=0,a=t.keys.length;a>o;o++)n=t.keys[o],s=t[n],s&&(/^(\d|[1-9]\d+)$/.test(s)?s=parseInt(s,10):/^\d*\.\d+$/.test(s)&&(s=parseFloat(s)),i.meta[e][n]=s)}),i.width=parseInt(r.width,10),i.height=parseInt(r.height,10),i.size=parseInt(r.size,10),i.type=r.type,i.name=r.name,i}})}),i(ut,[u,p,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue;n.call(this,t,o,{access_binary:s(window.FileReader||window.File&&File.getAsDataURL),access_image_binary:!1,display_media:s(a.Image&&(i.can("create_canvas")||i.can("use_data_uri_over32kb"))),do_cors:!1,drag_and_drop:!1,filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),resize_image:function(){return a.Image&&r.can("access_binary")&&i.can("create_canvas")},report_upload_progress:!1,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!!~e.inArray(t,["text","document",""])},return_status_code:function(t){return!e.arrayDiff(t,[200,404])},select_file:function(){return i.can("use_fileinput")},select_multiple:!1,send_binary_string:!1,send_custom_headers:!1,send_multipart:!0,slice_blob:!1,stream_upload:function(){return r.can("select_file")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u,use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}}),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html4",a={};return n.addConstructor(o,r),a}),i(ct,[ut,u,f,L,l,d],function(e,t,n,i,r,o){function a(){function e(){var r=this,l=r.getRuntime(),d,f,p,h,m,g;g=t.guid("uid_"),d=l.getShimContainer(),a&&(p=n.get(a+"_form"),p&&t.extend(p.style,{top:"100%"})),h=document.createElement("form"),h.setAttribute("id",g+"_form"),h.setAttribute("method","post"),h.setAttribute("enctype","multipart/form-data"),h.setAttribute("encoding","multipart/form-data"),t.extend(h.style,{overflow:"hidden",position:"absolute",top:0,left:0,width:"100%",height:"100%"}),m=document.createElement("input"),m.setAttribute("id",g),m.setAttribute("type","file"),m.setAttribute("name",c.name||"Filedata"),m.setAttribute("accept",u.join(",")),t.extend(m.style,{fontSize:"999px",opacity:0}),h.appendChild(m),d.appendChild(h),t.extend(m.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),"IE"===o.browser&&o.version<10&&t.extend(m.style,{filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}),m.onchange=function(){var t;this.value&&(t=this.files?this.files[0]:{name:this.value},s=[t],this.onchange=function(){},e.call(r),r.bind("change",function i(){var e=n.get(g),t=n.get(g+"_form"),o;r.unbind("change",i),r.files.length&&e&&t&&(o=r.files[0],e.setAttribute("id",o.uid),t.setAttribute("id",o.uid+"_form"),t.setAttribute("target",o.uid+"_iframe")),e=t=null},998),m=h=null,r.trigger("change"))},l.can("summon_file_dialog")&&(f=n.get(c.browse_button),i.removeEvent(f,"click",r.uid),i.addEvent(f,"click",function(e){m&&!m.disabled&&m.click(),e.preventDefault()},r.uid)),a=g,d=p=f=null}var a,s=[],u=[],c;t.extend(this,{init:function(t){var o=this,a=o.getRuntime(),s;c=t,u=t.accept.mimes||r.extList2mimes(t.accept,a.can("filter_by_extension")),s=a.getShimContainer(),function(){var e,r,u;e=n.get(t.browse_button),a.can("summon_file_dialog")&&("static"===n.getStyle(e,"position")&&(e.style.position="relative"),r=parseInt(n.getStyle(e,"z-index"),10)||1,e.style.zIndex=r,s.style.zIndex=r-1),u=a.can("summon_file_dialog")?e:s,i.addEvent(u,"mouseover",function(){o.trigger("mouseenter")},o.uid),i.addEvent(u,"mouseout",function(){o.trigger("mouseleave")},o.uid),i.addEvent(u,"mousedown",function(){o.trigger("mousedown")},o.uid),i.addEvent(n.get(t.container),"mouseup",function(){o.trigger("mouseup")},o.uid),e=null}(),e.call(this),s=null,o.trigger({type:"ready",async:!0})},getFiles:function(){return s},disable:function(e){var t;(t=n.get(a))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),r=e.getShimContainer();i.removeAllEvents(r,this.uid),i.removeAllEvents(c&&n.get(c.container),this.uid),i.removeAllEvents(c&&n.get(c.browse_button),this.uid),r&&(r.innerHTML=""),t.removeInstance(this.uid),a=s=u=c=r=t=null}})}return e.FileInput=a}),i(lt,[ut,F],function(e,t){return e.FileReader=t}),i(dt,[ut,u,f,b,p,L,y,S],function(e,t,n,i,r,o,a,s){function u(){function e(e){var t=this,i,r,a,s,u=!1;if(l){if(i=l.id.replace(/_iframe$/,""),r=n.get(i+"_form")){for(a=r.getElementsByTagName("input"),s=a.length;s--;)switch(a[s].getAttribute("type")){case"hidden":a[s].parentNode.removeChild(a[s]);break;case"file":u=!0}a=[],u||r.parentNode.removeChild(r),r=null}setTimeout(function(){o.removeEvent(l,"load",t.uid),l.parentNode&&l.parentNode.removeChild(l);var n=t.getRuntime().getShimContainer();n.children.length||n.parentNode.removeChild(n),n=l=null,e()},1)}}var u,c,l;t.extend(this,{send:function(d,f){function p(){var n=m.getShimContainer()||document.body,r=document.createElement("div");r.innerHTML='<iframe id="'+g+'_iframe" name="'+g+'_iframe" src="javascript:""" style="display:none"></iframe>',l=r.firstChild,n.appendChild(l),o.addEvent(l,"load",function(){var n;try{n=l.contentWindow.document||l.contentDocument||window.frames[l.id].document,/^4(0[0-9]|1[0-7]|2[2346])\s/.test(n.title)?u=n.title.replace(/^(\d+).*$/,"$1"):(u=200,c=t.trim(n.body.innerHTML),h.trigger({type:"progress",loaded:c.length,total:c.length}),w&&h.trigger({type:"uploadprogress",loaded:w.size||1025,total:w.size||1025}))}catch(r){if(!i.hasSameOrigin(d.url))return e.call(h,function(){h.trigger("error")}),void 0;u=404}e.call(h,function(){h.trigger("load")})},h.uid)}var h=this,m=h.getRuntime(),g,v,y,w;if(u=c=null,f instanceof s&&f.hasBlob()){if(w=f.getBlob(),g=w.uid,y=n.get(g),v=n.get(g+"_form"),!v)throw new r.DOMException(r.DOMException.NOT_FOUND_ERR)}else g=t.guid("uid_"),v=document.createElement("form"),v.setAttribute("id",g+"_form"),v.setAttribute("method",d.method),v.setAttribute("enctype","multipart/form-data"),v.setAttribute("encoding","multipart/form-data"),v.setAttribute("target",g+"_iframe"),m.getShimContainer().appendChild(v);f instanceof s&&f.each(function(e,n){if(e instanceof a)y&&y.setAttribute("name",n);else{var i=document.createElement("input");t.extend(i,{type:"hidden",name:n,value:e}),y?v.insertBefore(i,y):v.appendChild(i)}}),v.setAttribute("action",d.url),p(),v.submit(),h.trigger("loadstart")},getStatus:function(){return u},getResponse:function(e){if("json"===e&&"string"===t.typeOf(c)&&window.JSON)try{return JSON.parse(c.replace(/^\s*<pre[^>]*>/,"").replace(/<\/pre>\s*$/,""))}catch(n){return null}return c},abort:function(){var t=this;l&&l.contentWindow&&(l.contentWindow.stop?l.contentWindow.stop():l.contentWindow.document.execCommand?l.contentWindow.document.execCommand("Stop"):l.src="about:blank"),e.call(this,function(){t.dispatchEvent("abort")})}})}return e.XMLHttpRequest=u}),i(ft,[ut,X],function(e,t){return e.Image=t}),a([u,c,l,d,f,p,h,m,g,v,y,w,E,_,x,R,b,T,S,A,O,I,L])}(this);;(function(){"use strict";var e={},t=moxie.core.utils.Basic.inArray;return function n(r){var i,s;for(i in r)s=typeof r[i],s==="object"&&!~t(i,["Exceptions","Env","Mime"])?n(r[i]):s==="function"&&(e[i]=r[i])}(window.moxie),e.Env=window.moxie.core.utils.Env,e.Mime=window.moxie.core.utils.Mime,e.Exceptions=window.moxie.core.Exceptions,window.mOxie=e,window.o||(window.o=e),e})(); +/** + * Plupload - multi-runtime File Uploader + * v2.1.1 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-01-16 + */ +;(function(e,t,n){function s(e){function r(e,t,r){var i={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};i[e]?n[i[e]]=t:r||(n[e]=t)}var t=e.required_features,n={};return typeof t=="string"?o.each(t.split(/\s*,\s*/),function(e){r(e,!0)}):typeof t=="object"?o.each(t,function(e,t){r(t,e)}):t===!0&&(e.multipart||(n.send_binary_string=!0),e.chunk_size>0&&(n.slice_blob=!0),e.resize.enabled&&(n.send_binary_string=!0),o.each(e,function(e,t){r(t,!!e,!0)})),n}var r=e.setTimeout,i={},o={VERSION:"2.1.1",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,IMAGE_MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,mimeTypes:t.mimes,ua:t.ua,typeOf:t.typeOf,extend:t.extend,guid:t.guid,get:function(n){var r=[],i;t.typeOf(n)!=="array"&&(n=[n]);var s=n.length;while(s--)i=t.get(n[s]),i&&r.push(i);return r.length?r:null},each:t.each,getPos:t.getPos,getSize:t.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},n=/[<>&\"\']/g;return e?(""+e).replace(n,function(e){return t[e]?"&"+t[e]+";":e}):e},toArray:t.toArray,inArray:t.inArray,addI18n:t.addI18n,translate:t.translate,isEmptyObj:t.isEmptyObj,hasClass:t.hasClass,addClass:t.addClass,removeClass:t.removeClass,getStyle:t.getStyle,addEvent:t.addEvent,removeEvent:t.removeEvent,removeAllEvents:t.removeAllEvents,cleanName:function(e){var t,n;n=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(t=0;t<n.length;t+=2)e=e.replace(n[t],n[t+1]);return e=e.replace(/\s+/g,"_"),e=e.replace(/[^a-z0-9_\-\.]+/gi,""),e},buildUrl:function(e,t){var n="";return o.each(t,function(e,t){n+=(n?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(e)}),n&&(e+=(e.indexOf("?")>0?"&":"?")+n),e},formatSize:function(e){function t(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}if(e===n||/\D/.test(e))return o.translate("N/A");var r=Math.pow(1024,4);return e>r?t(e/r,1)+" "+o.translate("tb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("gb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("mb"):e>1024?Math.round(e/1024)+" "+o.translate("kb"):e+" "+o.translate("b")},parseSize:t.parseSizeStr,predictRuntime:function(e,n){var r,i;return r=new o.Uploader(e),i=t.Runtime.thatCan(r.getOption().required_features,n||e.runtimes),r.destroy(),i},addFileFilter:function(e,t){i[e]=t}};o.addFileFilter("mime_types",function(e,t,n){e.length&&!e.regexp.test(t.name)?(this.trigger("Error",{code:o.FILE_EXTENSION_ERROR,message:o.translate("File extension error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("max_file_size",function(e,t,n){var r;e=o.parseSize(e),t.size!==r&&e&&t.size>e?(this.trigger("Error",{code:o.FILE_SIZE_ERROR,message:o.translate("File size error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("prevent_duplicates",function(e,t,n){if(e){var r=this.files.length;while(r--)if(t.name===this.files[r].name&&t.size===this.files[r].size){this.trigger("Error",{code:o.FILE_DUPLICATE_ERROR,message:o.translate("Duplicate file error."),file:t}),n(!1);return}}n(!0)}),o.Uploader=function(e){function g(){var e,t=0,n;if(this.state==o.STARTED){for(n=0;n<f.length;n++)!e&&f[n].status==o.QUEUED?(e=f[n],this.trigger("BeforeUpload",e)&&(e.status=o.UPLOADING,this.trigger("UploadFile",e))):t++;t==f.length&&(this.state!==o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged")),this.trigger("UploadComplete",f))}}function y(e){e.percent=e.size>0?Math.ceil(e.loaded/e.size*100):100,b()}function b(){var e,t;d.reset();for(e=0;e<f.length;e++)t=f[e],t.size!==n?(d.size+=t.origSize,d.loaded+=t.loaded*t.origSize/t.size):d.size=n,t.status==o.DONE?d.uploaded++:t.status==o.FAILED?d.failed++:d.queued++;d.size===n?d.percent=f.length>0?Math.ceil(d.uploaded/f.length*100):0:(d.bytesPerSec=Math.ceil(d.loaded/((+(new Date)-p||1)/1e3)),d.percent=d.size>0?Math.ceil(d.loaded/d.size*100):0)}function w(){var e=c[0]||h[0];return e?e.getRuntime().uid:!1}function E(e,n){if(e.ruid){var r=t.Runtime.getInfo(e.ruid);if(r)return r.can(n)}return!1}function S(){this.bind("FilesAdded",C),this.bind("CancelUpload",M),this.bind("BeforeUpload",k),this.bind("UploadFile",L),this.bind("UploadProgress",A),this.bind("StateChanged",O),this.bind("QueueChanged",b),this.bind("Error",D),this.bind("FileUploaded",_),this.bind("Destroy",P)}function x(e,n){var r=this,i=0,s=[],u={accept:e.filters.mime_types,runtime_order:e.runtimes,required_caps:e.required_features,preferred_caps:l,swf_url:e.flash_swf_url,xap_url:e.silverlight_xap_url};o.each(e.runtimes.split(/\s*,\s*/),function(t){e[t]&&(u[t]=e[t])}),e.browse_button&&o.each(e.browse_button,function(n){s.push(function(s){var a=new t.FileInput(o.extend({},u,{name:e.file_data_name,multiple:e.multi_selection,container:e.container,browse_button:n}));a.onready=function(){var e=t.Runtime.getInfo(this.ruid);t.extend(r.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")}),i++,c.push(this),s()},a.onchange=function(){r.addFile(this.files)},a.bind("mouseenter mouseleave mousedown mouseup",function(r){v||(e.browse_button_hover&&("mouseenter"===r.type?t.addClass(n,e.browse_button_hover):"mouseleave"===r.type&&t.removeClass(n,e.browse_button_hover)),e.browse_button_active&&("mousedown"===r.type?t.addClass(n,e.browse_button_active):"mouseup"===r.type&&t.removeClass(n,e.browse_button_active)))}),a.bind("error runtimeerror",function(){a=null,s()}),a.init()})}),e.drop_element&&o.each(e.drop_element,function(e){s.push(function(n){var s=new t.FileDrop(o.extend({},u,{drop_zone:e}));s.onready=function(){var e=t.Runtime.getInfo(this.ruid);r.features.dragdrop=e.can("drag_and_drop"),i++,h.push(this),n()},s.ondrop=function(){r.addFile(this.files)},s.bind("error runtimeerror",function(){s=null,n()}),s.init()})}),t.inSeries(s,function(){typeof n=="function"&&n(i)})}function T(e,n,r){var i=new t.Image;try{i.onload=function(){i.downsize(n.width,n.height,n.crop,n.preserve_headers)},i.onresize=function(){r(this.getAsBlob(e.type,n.quality)),this.destroy()},i.onerror=function(){r(e)},i.load(e)}catch(s){r(e)}}function N(e,n,r){function f(e,t,n){var r=a[e];switch(e){case"max_file_size":e==="max_file_size"&&(a.max_file_size=a.filters.max_file_size=t);break;case"chunk_size":if(t=o.parseSize(t))a[e]=t;break;case"filters":o.typeOf(t)==="array"&&(t={mime_types:t}),n?o.extend(a.filters,t):a.filters=t,t.mime_types&&(a.filters.mime_types.regexp=function(e){var t=[];return o.each(e,function(e){o.each(e.extensions.split(/,/),function(e){/^\s*\*\s*$/.test(e)?t.push("\\.*"):t.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))})}),new RegExp("("+t.join("|")+")$","i")}(a.filters.mime_types));break;case"resize":n?o.extend(a.resize,t,{enabled:!0}):a.resize=t;break;case"prevent_duplicates":a.prevent_duplicates=a.filters.prevent_duplicates=!!t;break;case"browse_button":case"drop_element":t=o.get(t);case"container":case"runtimes":case"multi_selection":case"flash_swf_url":case"silverlight_xap_url":a[e]=t,n||(u=!0);break;default:a[e]=t}n||i.trigger("OptionChanged",e,t,r)}var i=this,u=!1;typeof e=="object"?o.each(e,function(e,t){f(t,e,r)}):f(e,n,r),r?(a.required_features=s(o.extend({},a)),l=s(o.extend({},a,{required_features:!0}))):u&&(i.trigger("Destroy"),x.call(i,a,function(e){e?(i.runtime=t.Runtime.getInfo(w()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})}))}function C(e,t){[].push.apply(f,t),e.trigger("QueueChanged"),e.refresh()}function k(e,t){if(a.unique_names){var n=t.name.match(/\.([^.]+)$/),r="part";n&&(r=n[1]),t.target_name=t.id+"."+r}}function L(e,n){function h(){u-->0?r(p,1e3):(n.loaded=f,e.trigger("Error",{code:o.HTTP_ERROR,message:o.translate("HTTP Error."),file:n,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}))}function p(){var d,v,g,y;if(n.status==o.DONE||n.status==o.FAILED||e.state==o.STOPPED)return;g={name:n.target_name||n.name},s&&a.chunks&&c.size>s?(y=Math.min(s,c.size-f),d=c.slice(f,f+y)):(y=c.size,d=c),s&&a.chunks&&(e.settings.send_chunk_number?(g.chunk=Math.ceil(f/s),g.chunks=Math.ceil(c.size/s)):(g.offset=f,g.total=c.size)),m=new t.XMLHttpRequest,m.upload&&(m.upload.onprogress=function(t){n.loaded=Math.min(n.size,f+t.loaded),e.trigger("UploadProgress",n)}),m.onload=function(){if(m.status>=400){h();return}u=e.settings.max_retries,y<c.size?(d.destroy(),f+=y,n.loaded=Math.min(f,c.size),e.trigger("ChunkUploaded",n,{offset:n.loaded,total:c.size,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}),t.Env.browser==="Android Browser"&&e.trigger("UploadProgress",n)):n.loaded=n.size,d=v=null,!f||f>=c.size?(n.size!=n.origSize&&(c.destroy(),c=null),e.trigger("UploadProgress",n),n.status=o.DONE,e.trigger("FileUploaded",n,{response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()})):r(p,1)},m.onerror=function(){h()},m.onloadend=function(){this.destroy(),m=null},e.settings.multipart&&a.multipart?(g.name=n.target_name||n.name,m.open("post",i,!0),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),v=new t.FormData,o.each(o.extend(g,e.settings.multipart_params),function(e,t){v.append(t,e)}),v.append(e.settings.file_data_name,d),m.send(v,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url})):(i=o.buildUrl(e.settings.url,o.extend(g,e.settings.multipart_params)),m.open("post",i,!0),m.setRequestHeader("Content-Type","application/octet-stream"),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),m.send(d,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url}))}var i=e.settings.url,s=e.settings.chunk_size,u=e.settings.max_retries,a=e.features,f=0,c;n.loaded&&(f=n.loaded=s*Math.floor(n.loaded/s)),c=n.getSource(),e.settings.resize.enabled&&E(c,"send_binary_string")&&!!~t.inArray(c.type,["image/jpeg","image/png"])?T.call(this,c,e.settings.resize,function(e){c=e,n.size=e.size,p()}):p()}function A(e,t){y(t)}function O(e){if(e.state==o.STARTED)p=+(new Date);else if(e.state==o.STOPPED)for(var t=e.files.length-1;t>=0;t--)e.files[t].status==o.UPLOADING&&(e.files[t].status=o.QUEUED,b())}function M(){m&&m.abort()}function _(e){b(),r(function(){g.call(e)},1)}function D(e,t){t.file&&(t.file.status=o.FAILED,y(t.file),e.state==o.STARTED&&(e.trigger("CancelUpload"),r(function(){g.call(e)},1)))}function P(e){e.stop(),o.each(f,function(e){e.destroy()}),f=[],c.length&&(o.each(c,function(e){e.destroy()}),c=[]),h.length&&(o.each(h,function(e){e.destroy()}),h=[]),l={},v=!1,p=m=null,d.reset()}var u=o.guid(),a,f=[],l={},c=[],h=[],p,d,v=!1,m;a={runtimes:t.Runtime.order,max_retries:0,chunk_size:0,multipart:!0,multi_selection:!0,file_data_name:"file",flash_swf_url:"js/Moxie.swf",silverlight_xap_url:"js/Moxie.xap",filters:{mime_types:[],prevent_duplicates:!1,max_file_size:0},resize:{enabled:!1,preserve_headers:!0,crop:!1},send_chunk_number:!0},N.call(this,e,null,!0),d=new o.QueueProgress,o.extend(this,{id:u,uid:u,state:o.STOPPED,features:{},runtime:null,files:f,settings:a,total:d,init:function(){var e=this;typeof a.preinit=="function"?a.preinit(e):o.each(a.preinit,function(t,n){e.bind(n,t)});if(!a.browse_button||!a.url){this.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")});return}S.call(this),x.call(this,a,function(n){typeof a.init=="function"?a.init(e):o.each(a.init,function(t,n){e.bind(n,t)}),n?(e.runtime=t.Runtime.getInfo(w()).type,e.trigger("Init",{runtime:e.runtime}),e.trigger("PostInit")):e.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})})},setOption:function(e,t){N.call(this,e,t,!this.runtime)},getOption:function(e){return e?a[e]:a},refresh:function(){c.length&&o.each(c,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=o.STARTED&&(this.state=o.STARTED,this.trigger("StateChanged"),g.call(this))},stop:function(){this.state!=o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){v=arguments[0]!==n?arguments[0]:!0,c.length&&o.each(c,function(e){e.disable(v)}),this.trigger("DisableBrowse",v)},getFile:function(e){var t;for(t=f.length-1;t>=0;t--)if(f[t].id===e)return f[t]},addFile:function(e,n){function l(e,n){var r=[];t.each(s.settings.filters,function(t,n){i[n]&&r.push(function(r){i[n].call(s,t,e,function(e){r(!e)})})}),t.inSeries(r,n)}function c(e){var i=t.typeOf(e);if(e instanceof t.File){if(!e.ruid&&!e.isDetached()){if(!f)return!1;e.ruid=f,e.connectRuntime(f)}c(new o.File(e))}else e instanceof t.Blob?(c(e.getSource()),e.destroy()):e instanceof o.File?(n&&(e.name=n),u.push(function(t){l(e,function(n){n||(a.push(e),s.trigger("FileFiltered",e)),r(t,1)})})):t.inArray(i,["file","blob"])!==-1?c(new t.File(null,e)):i==="node"&&t.typeOf(e.files)==="filelist"?t.each(e.files,c):i==="array"&&(n=null,t.each(e,c))}var s=this,u=[],a=[],f;f=w(),c(e),u.length&&t.inSeries(u,function(){a.length&&s.trigger("FilesAdded",a)})},removeFile:function(e){var t=typeof e=="string"?e:e.id;for(var n=f.length-1;n>=0;n--)if(f[n].id===t)return this.splice(n,1)[0]},splice:function(e,t){var r=f.splice(e===n?0:e,t===n?f.length:t),i=!1;return this.state==o.STARTED&&(i=!0,this.stop()),this.trigger("FilesRemoved",r),o.each(r,function(e){e.destroy()}),this.trigger("QueueChanged"),this.refresh(),i&&this.start(),r},bind:function(e,t,n){var r=this;o.Uploader.prototype.bind.call(this,e,function(){var e=[].slice.call(arguments);return e.splice(0,1,r),t.apply(this,e)},0,n)},destroy:function(){this.trigger("Destroy"),a=d=null,this.unbindAll()}})},o.Uploader.prototype=t.EventTarget.instance,o.File=function(){function n(n){o.extend(this,{id:o.guid(),name:n.name||n.fileName,type:n.type||"",size:n.size||n.fileSize,origSize:n.size||n.fileSize,loaded:0,percent:0,status:o.QUEUED,lastModifiedDate:n.lastModifiedDate||(new Date).toLocaleString(),getNative:function(){var e=this.getSource().getSource();return t.inArray(t.typeOf(e),["blob","file"])!==-1?e:null},getSource:function(){return e[this.id]?e[this.id]:null},destroy:function(){var t=this.getSource();t&&(t.destroy(),delete e[this.id])}}),e[this.id]=n}var e={};return n}(),o.QueueProgress=function(){var e=this;e.size=0,e.loaded=0,e.uploaded=0,e.failed=0,e.queued=0,e.percent=0,e.bytesPerSec=0,e.reset=function(){e.size=e.loaded=e.uploaded=e.failed=e.queued=e.percent=e.bytesPerSec=0}},e.plupload=o})(window,mOxie);
\ No newline at end of file diff --git a/phpBB/bin/phpbbcli.php b/phpBB/bin/phpbbcli.php new file mode 100755 index 0000000000..49f4ca13e7 --- /dev/null +++ b/phpBB/bin/phpbbcli.php @@ -0,0 +1,36 @@ +#!/usr/bin/env php +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +if (php_sapi_name() != 'cli') +{ + echo 'This program must be run from the command line.' . PHP_EOL; + exit(1); +} + +define('IN_PHPBB', true); +$phpbb_root_path = __DIR__ . '/../'; +$phpEx = substr(strrchr(__FILE__, '.'), 1); +require($phpbb_root_path . 'includes/startup.' . $phpEx); +require($phpbb_root_path . 'config.' . $phpEx); +require($phpbb_root_path . 'includes/constants.' . $phpEx); +require($phpbb_root_path . 'includes/functions.' . $phpEx); +require($phpbb_root_path . 'includes/functions_container.' . $phpEx); +require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx); + +$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx); +$phpbb_class_loader->register(); +$phpbb_class_loader_ext = new \phpbb\class_loader('\\', "{$phpbb_root_path}ext/", $phpEx); +$phpbb_class_loader_ext->register(); + +$phpbb_container = phpbb_create_update_container($phpbb_root_path, $phpEx, "$phpbb_root_path/config"); + +$application = new \phpbb\console\application('phpBB Console', PHPBB_VERSION); +$application->register_container_commands($phpbb_container); +$application->run(); diff --git a/phpBB/common.php b/phpBB/common.php index 6bb3509ea1..12dbe5a62c 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -115,6 +115,8 @@ set_config(null, null, null, $config); set_config_count(null, null, null, $config); $phpbb_log = $phpbb_container->get('log'); +$symfony_request = $phpbb_container->get('symfony_request'); +$phpbb_filesystem = $phpbb_container->get('filesystem'); $phpbb_path_helper = $phpbb_container->get('path_helper'); // load extensions @@ -149,6 +151,6 @@ if (!$config['use_system_cron']) * please use the core.user_setup event instead! * * @event core.common -* @since 3.1-A1 +* @since 3.1.0-a1 */ $phpbb_dispatcher->dispatch('core.common'); diff --git a/phpBB/composer.json b/phpBB/composer.json index 455ad49aac..f005fff805 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -1,8 +1,12 @@ { - "minimum-stability": "beta", + "_readme": [ + "You MUST update the clean-vendor-dir target in build/build.xml", + "accordingly when adding or upgrading dependencies." + ], "require": { "lusitanian/oauth": "0.2.*", "symfony/config": "2.3.*", + "symfony/console": "2.3.*", "symfony/dependency-injection": "2.3.*", "symfony/event-dispatcher": "2.3.*", "symfony/http-kernel": "2.3.*", @@ -14,6 +18,7 @@ "fabpot/goutte": "1.0.*", "phpunit/dbunit": "1.2.*", "phpunit/phpunit": "3.7.*", - "phing/phing": "2.4.*" + "phing/phing": "2.4.*", + "squizlabs/php_codesniffer": "1.*" } } diff --git a/phpBB/composer.lock b/phpBB/composer.lock index eb57ddb4d9..ee83dee047 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "0bc0fd0d784720629ae0ba6d4be6a577", + "hash": "9b683acbc766a345d90de958db4e7f48", "packages": [ { "name": "lusitanian/oauth", @@ -108,17 +108,17 @@ }, { "name": "symfony/config", - "version": "v2.3.4", + "version": "v2.3.12", "target-dir": "Symfony/Component/Config", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "65a927c15ca5a911ba2fa277a5457fa8129505b0" + "reference": "91faa2d4944d0c8a94d5b73cb7ccfb219aee9d21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/65a927c15ca5a911ba2fa277a5457fa8129505b0", - "reference": "65a927c15ca5a911ba2fa277a5457fa8129505b0", + "url": "https://api.github.com/repos/symfony/Config/zipball/91faa2d4944d0c8a94d5b73cb7ccfb219aee9d21", + "reference": "91faa2d4944d0c8a94d5b73cb7ccfb219aee9d21", "shasum": "" }, "require": { @@ -136,14 +136,16 @@ "Symfony\\Component\\Config\\": "" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -152,7 +154,62 @@ ], "description": "Symfony Config Component", "homepage": "http://symfony.com", - "time": "2013-08-06 05:49:23" + "time": "2014-03-31 10:15:50" + }, + { + "name": "symfony/console", + "version": "v2.3.12", + "target-dir": "Symfony/Component/Console", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "df17996d37eb113a5675ca4cc2ac45f4fc057cb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/df17996d37eb113a5675ca4cc2ac45f4fc057cb7", + "reference": "df17996d37eb113a5675ca4cc2ac45f4fc057cb7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/event-dispatcher": "~2.1" + }, + "suggest": { + "symfony/event-dispatcher": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "http://symfony.com", + "time": "2014-03-01 17:25:29" }, { "name": "symfony/debug", @@ -192,14 +249,16 @@ "Symfony\\Component\\Debug\\": "" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -212,17 +271,17 @@ }, { "name": "symfony/dependency-injection", - "version": "v2.3.4", + "version": "v2.3.12", "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "3678aa969e5bfeb8515a1f3047c63e8104723f5c" + "reference": "41e9e2078e8edf261c11be478300c8fcddb64e30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/3678aa969e5bfeb8515a1f3047c63e8104723f5c", - "reference": "3678aa969e5bfeb8515a1f3047c63e8104723f5c", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/41e9e2078e8edf261c11be478300c8fcddb64e30", + "reference": "41e9e2078e8edf261c11be478300c8fcddb64e30", "shasum": "" }, "require": { @@ -248,14 +307,16 @@ "Symfony\\Component\\DependencyInjection\\": "" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -264,21 +325,21 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "http://symfony.com", - "time": "2013-07-25 17:13:25" + "time": "2014-03-27 18:14:33" }, { "name": "symfony/event-dispatcher", - "version": "v2.3.4", + "version": "v2.3.12", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "41c9826457c65fa3cf746f214985b7ca9cba42f8" + "reference": "15645237c6ff70e74a28e8836362d82492765055" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/41c9826457c65fa3cf746f214985b7ca9cba42f8", - "reference": "41c9826457c65fa3cf746f214985b7ca9cba42f8", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/15645237c6ff70e74a28e8836362d82492765055", + "reference": "15645237c6ff70e74a28e8836362d82492765055", "shasum": "" }, "require": { @@ -302,14 +363,16 @@ "Symfony\\Component\\EventDispatcher\\": "" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -318,7 +381,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "http://symfony.com", - "time": "2013-07-21 12:12:18" + "time": "2014-02-11 10:29:24" }, { "name": "symfony/filesystem", @@ -349,14 +412,16 @@ "Symfony\\Component\\Filesystem\\": "" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -399,14 +464,16 @@ "Symfony/Component/HttpFoundation/Resources/stubs" ] }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -419,17 +486,17 @@ }, { "name": "symfony/http-kernel", - "version": "v2.3.4", + "version": "v2.3.12", "target-dir": "Symfony/Component/HttpKernel", "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel.git", - "reference": "9d35da40f07bbe7a4f8dfbc41555d2b69de674bf" + "reference": "48d61b3622ca35dd924b167441a9810ad55906ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/9d35da40f07bbe7a4f8dfbc41555d2b69de674bf", - "reference": "9d35da40f07bbe7a4f8dfbc41555d2b69de674bf", + "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/48d61b3622ca35dd924b167441a9810ad55906ce", + "reference": "48d61b3622ca35dd924b167441a9810ad55906ce", "shasum": "" }, "require": { @@ -470,14 +537,16 @@ "Symfony\\Component\\HttpKernel\\": "" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -486,21 +555,21 @@ ], "description": "Symfony HttpKernel Component", "homepage": "http://symfony.com", - "time": "2013-08-27 08:58:24" + "time": "2014-04-03 05:42:39" }, { "name": "symfony/routing", - "version": "v2.3.4", + "version": "v2.3.12", "target-dir": "Symfony/Component/Routing", "source": { "type": "git", "url": "https://github.com/symfony/Routing.git", - "reference": "69af3f07dbf3ae93dd513dbc373f561cb2e7f143" + "reference": "08afcafd9af22a24a8055669f85d63b863c4711b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/69af3f07dbf3ae93dd513dbc373f561cb2e7f143", - "reference": "69af3f07dbf3ae93dd513dbc373f561cb2e7f143", + "url": "https://api.github.com/repos/symfony/Routing/zipball/08afcafd9af22a24a8055669f85d63b863c4711b", + "reference": "08afcafd9af22a24a8055669f85d63b863c4711b", "shasum": "" }, "require": { @@ -528,14 +597,16 @@ "Symfony\\Component\\Routing\\": "" } }, - "notification-url": "http://packagist.org/downloads/", + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -544,21 +615,21 @@ ], "description": "Symfony Routing Component", "homepage": "http://symfony.com", - "time": "2013-08-23 15:14:07" + "time": "2014-03-28 10:34:27" }, { "name": "symfony/yaml", - "version": "v2.3.4", + "version": "v2.3.12", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "5a279f1b5f5e1045a6c432354d9ea727ff3a9847" + "reference": "3acf34f6993db3d873fa77ac2cb6e595db00b88d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/5a279f1b5f5e1045a6c432354d9ea727ff3a9847", - "reference": "5a279f1b5f5e1045a6c432354d9ea727ff3a9847", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/3acf34f6993db3d873fa77ac2cb6e595db00b88d", + "reference": "3acf34f6993db3d873fa77ac2cb6e595db00b88d", "shasum": "" }, "require": { @@ -582,7 +653,9 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -591,7 +664,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2013-08-24 15:26:22" + "time": "2014-03-04 16:04:39" }, { "name": "twig/twig", @@ -690,7 +763,9 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" } ], "description": "A simple PHP Web Scraper", @@ -1376,6 +1451,76 @@ "time": "2013-01-13 10:24:48" }, { + "name": "squizlabs/php_codesniffer", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "a76a39b317ce8106abe6264daa505e24e1731860" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/a76a39b317ce8106abe6264daa505e24e1731860", + "reference": "a76a39b317ce8106abe6264daa505e24e1731860", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.1.2" + }, + "suggest": { + "phpunit/php-timer": "dev-master" + }, + "bin": [ + "scripts/phpcs" + ], + "type": "library", + "autoload": { + "classmap": [ + "CodeSniffer.php", + "CodeSniffer/CLI.php", + "CodeSniffer/Exception.php", + "CodeSniffer/File.php", + "CodeSniffer/Report.php", + "CodeSniffer/Reporting.php", + "CodeSniffer/Sniff.php", + "CodeSniffer/Tokens.php", + "CodeSniffer/Reports/", + "CodeSniffer/CommentParser/", + "CodeSniffer/Tokenizers/", + "CodeSniffer/DocGenerators/", + "CodeSniffer/Standards/AbstractPatternSniff.php", + "CodeSniffer/Standards/AbstractScopeSniff.php", + "CodeSniffer/Standards/AbstractVariableSniff.php", + "CodeSniffer/Standards/IncorrectPatternException.php", + "CodeSniffer/Standards/Generic/Sniffs/", + "CodeSniffer/Standards/MySource/Sniffs/", + "CodeSniffer/Standards/PEAR/Sniffs/", + "CodeSniffer/Standards/PSR1/Sniffs/", + "CodeSniffer/Standards/PSR2/Sniffs/", + "CodeSniffer/Standards/Squiz/Sniffs/", + "CodeSniffer/Standards/Zend/Sniffs/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenises PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2014-02-04 23:49:58" + }, + { "name": "symfony/browser-kit", "version": "v2.3.4", "target-dir": "Symfony/Component/BrowserKit", @@ -1419,7 +1564,9 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -1466,7 +1613,9 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -1523,7 +1672,9 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -1570,7 +1721,9 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -1617,7 +1770,9 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" }, { "name": "Symfony Community", @@ -1632,7 +1787,7 @@ "aliases": [ ], - "minimum-stability": "beta", + "minimum-stability": "stable", "stability-flags": [ ], diff --git a/phpBB/config/auth_providers.yml b/phpBB/config/auth_providers.yml index e1c289334e..dac8b9d252 100644 --- a/phpBB/config/auth_providers.yml +++ b/phpBB/config/auth_providers.yml @@ -10,6 +10,7 @@ services: arguments: - @dbal.conn - @config + - @passwords.manager - @request - @user - %core.root_path% @@ -21,6 +22,7 @@ services: arguments: - @dbal.conn - @config + - @passwords.manager - @request - @user - %core.root_path% @@ -32,6 +34,7 @@ services: arguments: - @dbal.conn - @config + - @passwords.manager - @user tags: - { name: auth.provider } @@ -40,6 +43,7 @@ services: arguments: - @dbal.conn - @config + - @passwords.manager - @request - @user - %tables.auth_provider_oauth_token_storage% diff --git a/phpBB/config/avatars.yml b/phpBB/config/avatars.yml index 31ae1ecef9..d22a5db2ae 100644 --- a/phpBB/config/avatars.yml +++ b/phpBB/config/avatars.yml @@ -5,6 +5,7 @@ services: - @config - %core.root_path% - %core.php_ext% + - @path_helper - @cache.driver calls: - [set_name, [avatar.driver.gravatar]] @@ -17,6 +18,7 @@ services: - @config - %core.root_path% - %core.php_ext% + - @path_helper - @cache.driver calls: - [set_name, [avatar.driver.local]] @@ -29,6 +31,7 @@ services: - @config - %core.root_path% - %core.php_ext% + - @path_helper - @cache.driver calls: - [set_name, [avatar.driver.remote]] @@ -41,6 +44,7 @@ services: - @config - %core.root_path% - %core.php_ext% + - @path_helper - @cache.driver calls: - [set_name, [avatar.driver.upload]] diff --git a/phpBB/config/console.yml b/phpBB/config/console.yml new file mode 100644 index 0000000000..a4aae75e40 --- /dev/null +++ b/phpBB/config/console.yml @@ -0,0 +1,70 @@ +services: + console.command.config.delete: + class: phpbb\console\command\config\delete + arguments: + - @config + tags: + - { name: console.command } + + console.command.config.increment: + class: phpbb\console\command\config\increment + arguments: + - @config + tags: + - { name: console.command } + + console.command.config.get: + class: phpbb\console\command\config\get + arguments: + - @config + tags: + - { name: console.command } + + console.command.config.set: + class: phpbb\console\command\config\set + arguments: + - @config + tags: + - { name: console.command } + + console.command.config.set_atomic: + class: phpbb\console\command\config\set_atomic + arguments: + - @config + tags: + - { name: console.command } + + console.command.extension.disable: + class: phpbb\console\command\extension\disable + arguments: + - @ext.manager + tags: + - { name: console.command } + + console.command.extension.enable: + class: phpbb\console\command\extension\enable + arguments: + - @ext.manager + tags: + - { name: console.command } + + console.command.extension.purge: + class: phpbb\console\command\extension\purge + arguments: + - @ext.manager + tags: + - { name: console.command } + + console.command.extension.show: + class: phpbb\console\command\extension\show + arguments: + - @ext.manager + tags: + - { name: console.command } + + console.command.fixup.recalculate_email_hash: + class: phpbb\console\command\fixup\recalculate_email_hash + arguments: + - @dbal.conn + tags: + - { name: console.command } diff --git a/phpBB/config/cron_tasks.yml b/phpBB/config/cron_tasks.yml index 0c9795c0bd..4fa5d1440e 100644 --- a/phpBB/config/cron_tasks.yml +++ b/phpBB/config/cron_tasks.yml @@ -23,6 +23,29 @@ services: tags: - { name: cron.task } + cron.task.core.prune_shadow_topics: + class: phpbb\cron\task\core\prune_shadow_topics + arguments: + - %core.root_path% + - %core.php_ext% + - @config + - @dbal.conn + - @log + calls: + - [set_name, [cron.task.core.prune_shadow_topics]] + tags: + - { name: cron.task } + + cron.task.core.prune_notifications: + class: phpbb\cron\task\core\prune_notifications + arguments: + - @config + - @notification_manager + calls: + - [set_name, [cron.task.core.prune_notifications]] + tags: + - { name: cron.task } + cron.task.core.queue: class: phpbb\cron\task\core\queue arguments: @@ -55,6 +78,16 @@ services: tags: - { name: cron.task } + cron.task.core.tidy_plupload: + class: phpbb\cron\task\core\tidy_plupload + arguments: + - %core.root_path% + - @config + calls: + - [set_name, [cron.task.core.tidy_plupload]] + tags: + - { name: cron.task } + cron.task.core.tidy_search: class: phpbb\cron\task\core\tidy_search arguments: diff --git a/phpBB/config/feed.yml b/phpBB/config/feed.yml index 7712a832f3..48bd9fe76f 100644 --- a/phpBB/config/feed.yml +++ b/phpBB/config/feed.yml @@ -5,6 +5,7 @@ services: - @config - @user - %core.root_path% + - %core.php_ext% feed.factory: class: phpbb\feed\factory diff --git a/phpBB/config/migrator.yml b/phpBB/config/migrator.yml index a94609418f..202421c09f 100644 --- a/phpBB/config/migrator.yml +++ b/phpBB/config/migrator.yml @@ -10,6 +10,10 @@ services: - %core.php_ext% - %core.table_prefix% - @migrator.tool_collection + - @migrator.helper + + migrator.helper: + class: phpbb\db\migration\helper migrator.tool_collection: class: phpbb\di\service_collection diff --git a/phpBB/config/mimetype_guessers.yml b/phpBB/config/mimetype_guessers.yml new file mode 100644 index 0000000000..0115146deb --- /dev/null +++ b/phpBB/config/mimetype_guessers.yml @@ -0,0 +1,43 @@ +parameters: + mimetype.guesser.priority.lowest: -2 + mimetype.guesser.priority.low: -1 + mimetype.guesser.priority.default: 0 + mimetype.guesser.priority.high: 1 + mimetype.guesser.priority.highest: 2 + +services: + mimetype.fileinfo_mimetype_guesser: + class: Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser + tags: + - { name: mimetype.guessers } + + mimetype.filebinary_mimetype_guesser: + class: Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser + tags: + - { name: mimetype.guessers } + + mimetype.content_guesser: + class: phpbb\mimetype\content_guesser + calls: + - [set_priority, [%mimetype.guesser.priority.low%]] + tags: + - { name: mimetype.guessers } + + mimetype.extension_guesser: + class: phpbb\mimetype\extension_guesser + calls: + - [set_priority, [%mimetype.guesser.priority.lowest%]] + tags: + - { name: mimetype.guessers } + + mimetype.guesser_collection: + class: phpbb\di\service_collection + arguments: + - @service_container + tags: + - { name: service_collection, tag: mimetype.guessers } + + mimetype.guesser: + class: phpbb\mimetype\guesser + arguments: + - @mimetype.guesser_collection diff --git a/phpBB/config/notifications.yml b/phpBB/config/notifications.yml index 6fecae2aeb..5675e76a99 100644 --- a/phpBB/config/notifications.yml +++ b/phpBB/config/notifications.yml @@ -266,7 +266,7 @@ services: - { name: notification.type } notification.type.report_post_closed: - class: phpbb\notification\type\report_post + class: phpbb\notification\type\report_post_closed scope: prototype # scope MUST be prototype for this to work! arguments: - @user_loader @@ -319,6 +319,24 @@ services: tags: - { name: notification.type } + notification.type.admin_activate_user: + class: phpbb\notification\type\admin_activate_user + scope: prototype # scope MUST be prototype for this to work! + arguments: + - @user_loader + - @dbal.conn + - @cache.driver + - @user + - @auth + - @config + - %core.root_path% + - %core.php_ext% + - %tables.notification_types% + - %tables.notifications% + - %tables.user_notifications% + tags: + - { name: notification.type } + notification.method.email: class: phpbb\notification\method\email scope: prototype # scope MUST be prototype for this to work! diff --git a/phpBB/config/passwords.yml b/phpBB/config/passwords.yml new file mode 100644 index 0000000000..9e249a2c12 --- /dev/null +++ b/phpBB/config/passwords.yml @@ -0,0 +1,62 @@ +parameters: + passwords.algorithms: + - passwords.driver.bcrypt_2y + - passwords.driver.bcrypt + - passwords.driver.salted_md5 + - passwords.driver.phpass + +services: + passwords.driver.bcrypt: + class: phpbb\passwords\driver\bcrypt + arguments: + - @config + - @passwords.driver_helper + tags: + - { name: passwords.driver } + + passwords.driver.bcrypt_2y: + class: phpbb\passwords\driver\bcrypt_2y + arguments: + - @config + - @passwords.driver_helper + tags: + - { name: passwords.driver } + + passwords.driver.salted_md5: + class: phpbb\passwords\driver\salted_md5 + arguments: + - @config + - @passwords.driver_helper + tags: + - { name: passwords.driver } + + passwords.driver.phpass: + class: phpbb\passwords\driver\phpass + arguments: + - @config + - @passwords.driver_helper + tags: + - { name: passwords.driver } + + passwords.driver_collection: + class: phpbb\di\service_collection + arguments: + - @service_container + tags: + - { name: service_collection, tag: passwords.driver } + + passwords.driver_helper: + class: phpbb\passwords\driver\helper + arguments: + - @config + + passwords.manager: + class: phpbb\passwords\manager + arguments: + - @config + - @passwords.driver_collection + - @passwords.helper + - %passwords.algorithms% + + passwords.helper: + class: phpbb\passwords\helper diff --git a/phpBB/config/profilefields.yml b/phpBB/config/profilefields.yml new file mode 100644 index 0000000000..d12a1f8a37 --- /dev/null +++ b/phpBB/config/profilefields.yml @@ -0,0 +1,91 @@ +services: + profilefields.manager: + class: phpbb\profilefields\manager + arguments: + - @auth + - @dbal.conn + - @request + - @template + - @profilefields.type_collection + - @user + - %tables.profile_fields% + - %tables.profile_fields_language% + - %tables.profile_fields_data% + + profilefields.lang_helper: + class: phpbb\profilefields\lang_helper + arguments: + - @dbal.conn + - %tables.profile_fields_options_language% + + profilefields.type_collection: + class: phpbb\di\service_collection + arguments: + - @service_container + tags: + - { name: service_collection, tag: profilefield.type } + + profilefields.type.bool: + class: phpbb\profilefields\type\type_bool + arguments: + - @profilefields.lang_helper + - @request + - @template + - @user + tags: + - { name: profilefield.type } + + profilefields.type.date: + class: phpbb\profilefields\type\type_date + arguments: + - @request + - @template + - @user + tags: + - { name: profilefield.type } + + profilefields.type.dropdown: + class: phpbb\profilefields\type\type_dropdown + arguments: + - @profilefields.lang_helper + - @request + - @template + - @user + tags: + - { name: profilefield.type } + + profilefields.type.int: + class: phpbb\profilefields\type\type_int + arguments: + - @request + - @template + - @user + tags: + - { name: profilefield.type } + + profilefields.type.string: + class: phpbb\profilefields\type\type_string + arguments: + - @request + - @template + - @user + tags: + - { name: profilefield.type } + + profilefields.type.text: + class: phpbb\profilefields\type\type_text + arguments: + - @request + - @template + - @user + tags: + - { name: profilefield.type } + + profilefields.type.url: + class: phpbb\profilefields\type\type_url + arguments: + - @request + - @template + - @user + tags: + - { name: profilefield.type } diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 51ae5c454d..90a2f3b187 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -6,6 +6,10 @@ imports: - { resource: avatars.yml } - { resource: feed.yml } - { resource: auth_providers.yml } + - { resource: console.yml } + - { resource: mimetype_guessers.yml } + - { resource: passwords.yml } + - { resource: profilefields.yml } services: acl.permissions: @@ -22,7 +26,6 @@ services: arguments: - @config - @avatar.driver_collection - - @service_container cache: class: phpbb\cache\service @@ -91,6 +94,7 @@ services: - @template - @user - @config + - @controller.provider - %core.root_path% - %core.php_ext% @@ -101,6 +105,13 @@ services: - @service_container - @template + controller.provider: + class: phpbb\controller\provider + arguments: + - @ext.finder + calls: + - [find, [%core.root_path%]] + cron.task_collection: class: phpbb\di\service_collection arguments: @@ -141,10 +152,17 @@ services: class: phpbb\event\extension_subscriber_loader arguments: - @dispatcher - - @ext.manager + - @event.listener_collection calls: - [load, []] + event.listener_collection: + class: phpbb\di\service_collection + arguments: + - @service_container + tags: + - { name: service_collection, tag: event.listener } + ext.manager: class: phpbb\extension\manager arguments: @@ -237,6 +255,7 @@ services: - @notification.method_collection - @service_container - @user_loader + - @config - @dbal.conn - @cache - @user @@ -246,6 +265,13 @@ services: - %tables.notifications% - %tables.user_notifications% + pagination: + class: phpbb\pagination + arguments: + - @template + - @user + - @controller.helper + path_helper: class: phpbb\path_helper arguments: @@ -258,6 +284,16 @@ services: php_ini: class: phpbb\php\ini + plupload: + class: phpbb\plupload\plupload + arguments: + - %core.root_path% + - @config + - @request + - @user + - @php_ini + - @mimetype.guesser + request: class: phpbb\request\request @@ -288,3 +324,11 @@ services: - %core.root_path% - %core.php_ext% - %tables.users% + + version_helper: + class: phpbb\version_helper + scope: prototype + arguments: + - @cache + - @config + - @user diff --git a/phpBB/config/tables.yml b/phpBB/config/tables.yml index 0d364eb6b0..e4f7bda89b 100644 --- a/phpBB/config/tables.yml +++ b/phpBB/config/tables.yml @@ -10,6 +10,10 @@ parameters: tables.modules: %core.table_prefix%modules tables.notification_types: %core.table_prefix%notification_types tables.notifications: %core.table_prefix%notifications + tables.profile_fields: %core.table_prefix%profile_fields + tables.profile_fields_data: %core.table_prefix%profile_fields_data + tables.profile_fields_options_language: %core.table_prefix%profile_fields_lang + tables.profile_fields_language: %core.table_prefix%profile_lang tables.posts: %core.table_prefix%posts tables.topics: %core.table_prefix%topics tables.user_notifications: %core.table_prefix%user_notifications diff --git a/phpBB/develop/benchmark.php b/phpBB/develop/benchmark.php index c653fdaa24..27176c97d3 100644 --- a/phpBB/develop/benchmark.php +++ b/phpBB/develop/benchmark.php @@ -366,18 +366,10 @@ function make_user($username) $password = md5("benchpass"); $email = "nobody@localhost"; - $icq = "12345678"; - $website = "http://www.phpbb.com"; - $occupation = "phpBB tester"; - $location = "phpBB world hq"; - $interests = "Eating, sleeping, living, and breathing phpBB"; $signature = "$username: phpBB tester."; $signature_bbcode_uid = ""; $avatar_filename = ""; $viewemail = 0; - $aim = 0; - $yim = 0; - $msn = 0; $attachsig = 1; $allowsmilies = 1; $allowhtml = 1; @@ -422,8 +414,8 @@ function make_user($username) } - $sql = "INSERT INTO " . USERS_TABLE . " (user_id, username, user_regdate, user_password, user_email, user_icq, user_website, user_occ, user_from, user_interests, user_sig, user_sig_bbcode_uid, user_avatar, user_viewemail, user_aim, user_yim, user_msnm, user_attachsig, user_allowsmilies, user_allowhtml, user_allowbbcode, user_allow_viewonline, user_notify, user_notify_pm, user_timezone, user_dateformat, user_lang, user_style, user_level, user_allow_pm, user_active, user_actkey) - VALUES ($new_user_id, '$username', " . time() . ", '$password', '$email', '$icq', '$website', '$occupation', '$location', '$interests', '$signature', '$signature_bbcode_uid', '$avatar_filename', $viewemail, '$aim', '$yim', '$msn', $attachsig, $allowsmilies, $allowhtml, $allowbbcode, $allowviewonline, $notifyreply, $notifypm, $user_timezone, '$user_dateformat', '$user_lang', $user_style, 0, 1, "; + $sql = "INSERT INTO " . USERS_TABLE . " (user_id, username, user_regdate, user_password, user_email, user_sig, user_sig_bbcode_uid, user_avatar, user_viewemail, user_attachsig, user_allowsmilies, user_allowhtml, user_allowbbcode, user_allow_viewonline, user_notify, user_notify_pm, user_timezone, user_dateformat, user_lang, user_style, user_level, user_allow_pm, user_active, user_actkey) + VALUES ($new_user_id, '$username', " . time() . ", '$password', '$email', '$signature', '$signature_bbcode_uid', '$avatar_filename', $viewemail, $attachsig, $allowsmilies, $allowhtml, $allowbbcode, $allowviewonline, $notifyreply, $notifypm, $user_timezone, '$user_dateformat', '$user_lang', $user_style, 0, 1, "; $sql .= "1, '')"; diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 5ef278d493..9ab8bd193f 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -12,6 +12,16 @@ */ $schema_path = dirname(__FILE__) . '/../install/schemas/'; +$supported_dbms = array( + 'firebird', + 'mssql', + 'mysql_40', + 'mysql_41', + 'oracle', + 'postgres', + 'sqlite', +); +$table_prefix = 'phpbb_'; if (!is_writable($schema_path)) { @@ -19,22 +29,40 @@ if (!is_writable($schema_path)) } define('IN_PHPBB', true); +$phpbb_root_path = dirname(__FILE__) . '/../'; +$phpEx = substr(strrchr(__FILE__, '.'), 1); -require(dirname(__FILE__) . '/../includes/db/schema_data.php'); -require(dirname(__FILE__) . '/../phpbb/db/tools.php'); +include($phpbb_root_path . 'includes/constants.' . $phpEx); +require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx); +$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx); +$phpbb_class_loader->register(); +class phpbb_extension_empty_manager extends \phpbb\extension\manager +{ + public function __construct() + { + $this->extensions = array(); + } +} + +$finder = new \phpbb\extension\finder(new \phpbb_extension_empty_manager(), new \phpbb\filesystem(), $phpbb_root_path); +$classes = $finder->core_path('phpbb/') + ->directory('db/migration/data') + ->get_classes(); + +$db = new \phpbb\db\driver\sqlite(); +$schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, new \phpbb\db\tools($db, true), $phpbb_root_path, $phpEx, $table_prefix); +$schema_data = $schema_generator->get_schema(); $dbms_type_map = phpbb\db\tools::get_dbms_type_map(); -// A list of types being unsigned for better reference in some db's -$unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); -$supported_dbms = array('firebird', 'mssql', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite'); +$fp = fopen($schema_path . 'schema.json', 'wb'); +fwrite($fp, json_encode($schema_data, JSON_PRETTY_PRINT)); +fclose($fp); foreach ($supported_dbms as $dbms) { $fp = fopen($schema_path . $dbms . '_schema.sql', 'wb'); - $line = ''; - // Write Header switch ($dbms) { @@ -62,16 +90,9 @@ foreach ($supported_dbms as $dbms) break; } + $line = ''; switch ($dbms) { - case 'firebird': - $line .= custom_data('firebird') . "\n"; - break; - - case 'sqlite': - $line .= "BEGIN TRANSACTION;\n\n"; - break; - case 'oracle': $line .= custom_data('oracle') . "\n"; break; @@ -79,501 +100,7 @@ foreach ($supported_dbms as $dbms) case 'postgres': $line .= "BEGIN;\n\n"; $line .= custom_data('postgres') . "\n"; - break; - } - - fwrite($fp, $line); - - foreach ($schema_data as $table_name => $table_data) - { - // Write comment about table - switch ($dbms) - { - case 'mysql_40': - case 'mysql_41': - case 'firebird': - case 'sqlite': - fwrite($fp, "# Table: '{$table_name}'\n"); - break; - - case 'mssql': - case 'oracle': - case 'postgres': - fwrite($fp, "/*\n\tTable: '{$table_name}'\n*/\n"); - break; - } - - // Create Table statement - $generator = $textimage = false; - $line = ''; - - switch ($dbms) - { - case 'mysql_40': - case 'mysql_41': - case 'firebird': - case 'oracle': - case 'sqlite': - case 'postgres': - $line = "CREATE TABLE {$table_name} (\n"; - break; - - case 'mssql': - $line = "CREATE TABLE [{$table_name}] (\n"; - break; - } - - // Table specific so we don't get overlap - $modded_array = array(); - - // Write columns one by one... - foreach ($table_data['COLUMNS'] as $column_name => $column_data) - { - if (strlen($column_name) > 30) - { - trigger_error("Column name '$column_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); - } - if (isset($column_data[2]) && $column_data[2] == 'auto_increment' && strlen($column_name) > 26) // "${column_name}_gen" - { - trigger_error("Index name '${column_name}_gen' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); - } - - // Get type - if (strpos($column_data[0], ':') !== false) - { - list($orig_column_type, $column_length) = explode(':', $column_data[0]); - if (!is_array($dbms_type_map[$dbms][$orig_column_type . ':'])) - { - $column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'], $column_length); - } - else - { - if (isset($dbms_type_map[$dbms][$orig_column_type . ':']['rule'])) - { - switch ($dbms_type_map[$dbms][$orig_column_type . ':']['rule'][0]) - { - case 'div': - $column_length /= $dbms_type_map[$dbms][$orig_column_type . ':']['rule'][1]; - $column_length = ceil($column_length); - $column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length); - break; - } - } - - if (isset($dbms_type_map[$dbms][$orig_column_type . ':']['limit'])) - { - switch ($dbms_type_map[$dbms][$orig_column_type . ':']['limit'][0]) - { - case 'mult': - $column_length *= $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][1]; - if ($column_length > $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][2]) - { - $column_type = $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][3]; - $modded_array[$column_name] = $column_type; - } - else - { - $column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length); - } - break; - } - } - } - $orig_column_type .= ':'; - } - else - { - $orig_column_type = $column_data[0]; - $column_type = $dbms_type_map[$dbms][$column_data[0]]; - if ($column_type == 'text' || $column_type == 'blob') - { - $modded_array[$column_name] = $column_type; - } - } - - // Adjust default value if db-dependent specified - if (is_array($column_data[1])) - { - $column_data[1] = (isset($column_data[1][$dbms])) ? $column_data[1][$dbms] : $column_data[1]['default']; - } - - switch ($dbms) - { - case 'mysql_40': - case 'mysql_41': - $line .= "\t{$column_name} {$column_type} "; - - // For hexadecimal values do not use single quotes - if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob') - { - $line .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' "; - } - $line .= 'NOT NULL'; - - if (isset($column_data[2])) - { - if ($column_data[2] == 'auto_increment') - { - $line .= ' auto_increment'; - } - else if ($dbms === 'mysql_41' && $column_data[2] == 'true_sort') - { - $line .= ' COLLATE utf8_unicode_ci'; - } - } - - $line .= ",\n"; - break; - - case 'sqlite': - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $line .= "\t{$column_name} INTEGER PRIMARY KEY "; - $generator = $column_name; - } - else - { - $line .= "\t{$column_name} {$column_type} "; - } - - $line .= 'NOT NULL '; - $line .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : ''; - $line .= ",\n"; - break; - - case 'firebird': - $line .= "\t{$column_name} {$column_type} "; - - if (!is_null($column_data[1])) - { - $line .= 'DEFAULT ' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' '; - } - - $line .= 'NOT NULL'; - - // This is a UNICODE column and thus should be given it's fair share - if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0])) - { - $line .= ' COLLATE UNICODE'; - } - - $line .= ",\n"; - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $generator = $column_name; - } - break; - - case 'mssql': - if ($column_type == '[text]') - { - $textimage = true; - } - - $line .= "\t[{$column_name}] {$column_type} "; - - if (!is_null($column_data[1])) - { - // For hexadecimal values do not use single quotes - if (strpos($column_data[1], '0x') === 0) - { - $line .= 'DEFAULT (' . $column_data[1] . ') '; - } - else - { - $line .= 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') '; - } - } - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $line .= 'IDENTITY (1, 1) '; - } - - $line .= 'NOT NULL'; - $line .= " ,\n"; - break; - - case 'oracle': - $line .= "\t{$column_name} {$column_type} "; - $line .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : ''; - - // In Oracle empty strings ('') are treated as NULL. - // Therefore in oracle we allow NULL's for all DEFAULT '' entries - $line .= ($column_data[1] === '') ? ",\n" : "NOT NULL,\n"; - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $generator = $column_name; - } - break; - - case 'postgres': - $line .= "\t{$column_name} {$column_type} "; - - if (isset($column_data[2]) && $column_data[2] == 'auto_increment') - { - $line .= "DEFAULT nextval('{$table_name}_seq'),\n"; - - // Make sure the sequence will be created before creating the table - $line = "CREATE SEQUENCE {$table_name}_seq;\n\n" . $line; - } - else - { - $line .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : ''; - $line .= "NOT NULL"; - - // Unsigned? Then add a CHECK contraint - if (in_array($orig_column_type, $unsigned_types)) - { - $line .= " CHECK ({$column_name} >= 0)"; - } - - $line .= ",\n"; - } - break; - } - } - - switch ($dbms) - { - case 'firebird': - // Remove last line delimiter... - $line = substr($line, 0, -2); - $line .= "\n);;\n\n"; - break; - - case 'mssql': - $line = substr($line, 0, -2); - $line .= "\n) ON [PRIMARY]" . (($textimage) ? ' TEXTIMAGE_ON [PRIMARY]' : '') . "\n"; - $line .= "GO\n\n"; - break; - } - - // Write primary key - if (isset($table_data['PRIMARY_KEY'])) - { - if (!is_array($table_data['PRIMARY_KEY'])) - { - $table_data['PRIMARY_KEY'] = array($table_data['PRIMARY_KEY']); - } - - switch ($dbms) - { - case 'mysql_40': - case 'mysql_41': - case 'postgres': - $line .= "\tPRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . "),\n"; - break; - - case 'firebird': - $line .= "ALTER TABLE {$table_name} ADD PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ");;\n\n"; - break; - - case 'sqlite': - if ($generator === false || !in_array($generator, $table_data['PRIMARY_KEY'])) - { - $line .= "\tPRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . "),\n"; - } - break; - - case 'mssql': - $line .= "ALTER TABLE [{$table_name}] WITH NOCHECK ADD \n"; - $line .= "\tCONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED \n"; - $line .= "\t(\n"; - $line .= "\t\t[" . implode("],\n\t\t[", $table_data['PRIMARY_KEY']) . "]\n"; - $line .= "\t) ON [PRIMARY] \n"; - $line .= "GO\n\n"; - break; - - case 'oracle': - $line .= "\tCONSTRAINT pk_{$table_name} PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . "),\n"; - break; - } - } - - switch ($dbms) - { - case 'oracle': - // UNIQUE contrains to be added? - if (isset($table_data['KEYS'])) - { - foreach ($table_data['KEYS'] as $key_name => $key_data) - { - if (!is_array($key_data[1])) - { - $key_data[1] = array($key_data[1]); - } - - if ($key_data[0] == 'UNIQUE') - { - $line .= "\tCONSTRAINT u_phpbb_{$key_name} UNIQUE (" . implode(', ', $key_data[1]) . "),\n"; - } - } - } - - // Remove last line delimiter... - $line = substr($line, 0, -2); - $line .= "\n)\n/\n\n"; - break; - - case 'postgres': - // Remove last line delimiter... - $line = substr($line, 0, -2); - $line .= "\n);\n\n"; - break; - - case 'sqlite': - // Remove last line delimiter... - $line = substr($line, 0, -2); - $line .= "\n);\n\n"; - break; - } - - // Write Keys - if (isset($table_data['KEYS'])) - { - foreach ($table_data['KEYS'] as $key_name => $key_data) - { - if (!is_array($key_data[1])) - { - $key_data[1] = array($key_data[1]); - } - - if (strlen($table_name . $key_name) > 30) - { - trigger_error("Index name '${table_name}_$key_name' on table '$table_name' is too long. The maximum is 30 characters.", E_USER_ERROR); - } - - switch ($dbms) - { - case 'mysql_40': - case 'mysql_41': - $line .= ($key_data[0] == 'INDEX') ? "\tKEY" : ''; - $line .= ($key_data[0] == 'UNIQUE') ? "\tUNIQUE" : ''; - foreach ($key_data[1] as $key => $col_name) - { - if (isset($modded_array[$col_name])) - { - switch ($modded_array[$col_name]) - { - case 'text': - case 'blob': - $key_data[1][$key] = $col_name . '(255)'; - break; - } - } - } - $line .= ' ' . $key_name . ' (' . implode(', ', $key_data[1]) . "),\n"; - break; - - case 'firebird': - $line .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; - $line .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; - - $line .= ' ' . $table_name . '_' . $key_name . ' ON ' . $table_name . '(' . implode(', ', $key_data[1]) . ");;\n"; - break; - - case 'mssql': - $line .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; - $line .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; - $line .= " [{$key_name}] ON [{$table_name}]([" . implode('], [', $key_data[1]) . "]) ON [PRIMARY]\n"; - $line .= "GO\n\n"; - break; - - case 'oracle': - if ($key_data[0] == 'UNIQUE') - { - continue; - } - - $line .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; - - $line .= " {$table_name}_{$key_name} ON {$table_name} (" . implode(', ', $key_data[1]) . ")\n"; - $line .= "/\n"; - break; - - case 'sqlite': - $line .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; - $line .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; - - $line .= " {$table_name}_{$key_name} ON {$table_name} (" . implode(', ', $key_data[1]) . ");\n"; - break; - - case 'postgres': - $line .= ($key_data[0] == 'INDEX') ? 'CREATE INDEX' : ''; - $line .= ($key_data[0] == 'UNIQUE') ? 'CREATE UNIQUE INDEX' : ''; - - $line .= " {$table_name}_{$key_name} ON {$table_name} (" . implode(', ', $key_data[1]) . ");\n"; - break; - } - } - } - - switch ($dbms) - { - case 'mysql_40': - // Remove last line delimiter... - $line = substr($line, 0, -2); - $line .= "\n);\n\n"; - break; - - case 'mysql_41': - // Remove last line delimiter... - $line = substr($line, 0, -2); - $line .= "\n) CHARACTER SET `utf8` COLLATE `utf8_bin`;\n\n"; - break; - - // Create Generator - case 'firebird': - if ($generator !== false) - { - $line .= "\nCREATE GENERATOR {$table_name}_gen;;\n"; - $line .= 'SET GENERATOR ' . $table_name . "_gen TO 0;;\n\n"; - - $line .= 'CREATE TRIGGER t_' . $table_name . ' FOR ' . $table_name . "\n"; - $line .= "BEFORE INSERT\nAS\nBEGIN\n"; - $line .= "\tNEW.{$generator} = GEN_ID({$table_name}_gen, 1);\nEND;;\n\n"; - } - break; - - case 'oracle': - if ($generator !== false) - { - $line .= "\nCREATE SEQUENCE {$table_name}_seq\n/\n\n"; - - $line .= "CREATE OR REPLACE TRIGGER t_{$table_name}\n"; - $line .= "BEFORE INSERT ON {$table_name}\n"; - $line .= "FOR EACH ROW WHEN (\n"; - $line .= "\tnew.{$generator} IS NULL OR new.{$generator} = 0\n"; - $line .= ")\nBEGIN\n"; - $line .= "\tSELECT {$table_name}_seq.nextval\n"; - $line .= "\tINTO :new.{$generator}\n"; - $line .= "\tFROM dual;\nEND;\n/\n\n"; - } - break; - } - - fwrite($fp, $line . "\n"); - } - - $line = ''; - - // Write custom function at the end for some db's - switch ($dbms) - { - case 'mssql': - // No need to do this, no transaction support for schema changes - //$line = "\nCOMMIT\nGO\n\n"; - break; - - case 'sqlite': - $line = "\nCOMMIT;"; - break; - - case 'postgres': - $line = "\nCOMMIT;"; + $line .= "COMMIT;\n\n"; break; } diff --git a/phpBB/develop/export_events_for_wiki.php b/phpBB/develop/export_events_for_wiki.php new file mode 100644 index 0000000000..f4ebb42cf4 --- /dev/null +++ b/phpBB/develop/export_events_for_wiki.php @@ -0,0 +1,100 @@ +<?php +/** +* +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +if (php_sapi_name() != 'cli') +{ + die("This program must be run from the command line.\n"); +} + +$phpEx = substr(strrchr(__FILE__, '.'), 1); +$phpbb_root_path = __DIR__ . '/../'; + +function usage() +{ + echo "Usage: export_events_for_wiki.php COMMAND [EXTENSION]\n"; + echo "\n"; + echo "COMMAND:\n"; + echo " all:\n"; + echo " Generate the complete wikipage for https://wiki.phpbb.com/Event_List\n"; + echo "\n"; + echo " php:\n"; + echo " Generate the PHP event section of Event_List\n"; + echo "\n"; + echo " adm:\n"; + echo " Generate the ACP Template event section of Event_List\n"; + echo "\n"; + echo " styles:\n"; + echo " Generate the Styles Template event section of Event_List\n"; + echo "\n"; + echo "EXTENSION (Optional):\n"; + echo " If not given, only core events will be exported.\n"; + echo " Otherwise only events from the extension will be exported.\n"; + echo "\n"; + exit(2); +} + +function validate_argument_count($arguments, $count) +{ + if ($arguments <= $count) + { + usage(); + } +} + +validate_argument_count($argc, 1); + +$action = $argv[1]; +$extension = isset($argv[2]) ? $argv[2] : null; +require __DIR__ . '/../phpbb/event/php_exporter.' . $phpEx; +require __DIR__ . '/../phpbb/event/md_exporter.' . $phpEx; +require __DIR__ . '/../phpbb/event/recursive_event_filter_iterator.' . $phpEx; +require __DIR__ . '/../phpbb/recursive_dot_prefix_filter_iterator.' . $phpEx; + +switch ($action) +{ + case 'all': + echo '__FORCETOC__' . "\n"; + + case 'php': + $exporter = new \phpbb\event\php_exporter($phpbb_root_path, $extension); + $exporter->crawl_phpbb_directory_php(); + echo $exporter->export_events_for_wiki(); + + if ($action === 'php') + { + break; + } + echo "\n"; + // no break; + + case 'styles': + $exporter = new \phpbb\event\md_exporter($phpbb_root_path, $extension); + $exporter->crawl_phpbb_directory_styles('docs/events.md'); + echo $exporter->export_events_for_wiki(); + + if ($action === 'styles') + { + break; + } + echo "\n"; + // no break; + + case 'adm': + $exporter = new \phpbb\event\md_exporter($phpbb_root_path, $extension); + $exporter->crawl_phpbb_directory_adm('docs/events.md'); + echo $exporter->export_events_for_wiki(); + + if ($action === 'all') + { + echo "\n" . '[[Category:Events and Listeners]]' . "\n"; + } + break; + + default: + usage(); +} diff --git a/phpBB/develop/extensions.php b/phpBB/develop/extensions.php deleted file mode 100644 index 43621f3080..0000000000 --- a/phpBB/develop/extensions.php +++ /dev/null @@ -1,129 +0,0 @@ -<?php -/** -* -* @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -define('IN_PHPBB', 1); -define('ANONYMOUS', 1); -$phpEx = substr(strrchr(__FILE__, '.'), 1); -$phpbb_root_path = __DIR__.'/../'; - -include($phpbb_root_path . 'common.'.$phpEx); - -function usage() -{ - echo "Usage: extensions.php COMMAND [OPTION]...\n"; - echo "Console extension manager.\n"; - echo "\n"; - echo "list:\n"; - echo " Lists all extensions in the database and the filesystem.\n"; - echo "\n"; - echo "enable NAME:\n"; - echo " Enables the specified extension.\n"; - echo "\n"; - echo "disable NAME:\n"; - echo " Disables the specified extension.\n"; - echo "\n"; - echo "purge NAME:\n"; - echo " Purges the specified extension.\n"; - exit(2); -} - -function list_extensions() -{ - global $phpbb_extension_manager; - - $phpbb_extension_manager->load_extensions(); - $all = array_keys($phpbb_extension_manager->all_available()); - - if (empty($all)) - { - echo "There were no extensions found.\n"; - exit(3); - } - - echo "Enabled:\n"; - $enabled = array_keys($phpbb_extension_manager->all_enabled()); - print_extensions($enabled); - echo "\n"; - - echo "Disabled:\n"; - $disabled = array_keys($phpbb_extension_manager->all_disabled()); - print_extensions($disabled); - echo "\n"; - - echo "Available:\n"; - $purged = array_diff($all, $enabled, $disabled); - print_extensions($purged); -} - -function print_extensions($exts) -{ - foreach ($exts as $ext) - { - echo "- $ext\n"; - } -} - -function enable_extension($name) -{ - global $phpbb_extension_manager; - - $phpbb_extension_manager->enable($name); -} - -function disable_extension($name) -{ - global $phpbb_extension_manager; - - $phpbb_extension_manager->disable($name); -} - -function purge_extension($name) -{ - global $phpbb_extension_manager; - - $phpbb_extension_manager->purge($name); -} - -function validate_argument_count($count) -{ - global $argv; - - if (count($argv) <= $count) - { - usage(); - } -} - -validate_argument_count(1); - -$action = $argv[1]; - -switch ($action) -{ - case 'list': - list_extensions(); - break; - - case 'enable': - validate_argument_count(2); - enable_extension($argv[2]); - break; - - case 'disable': - validate_argument_count(2); - disable_extension($argv[2]); - break; - - case 'purge': - validate_argument_count(2); - purge_extension($argv[2]); - break; - - default: - usage(); -} diff --git a/phpBB/develop/migration_tips.php b/phpBB/develop/migration_tips.php new file mode 100644 index 0000000000..51a579bdb5 --- /dev/null +++ b/phpBB/develop/migration_tips.php @@ -0,0 +1,42 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +// This is to help with creating migration files for new versions +// Use this to find what migrations are not depended on by any other migration +// (the current migration tree tips) + +define('IN_PHPBB', true); +$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; +$phpEx = substr(strrchr(__FILE__, '.'), 1); +include($phpbb_root_path . 'common.' . $phpEx); + +$phpbb_extension_manager = $phpbb_container->get('ext.manager'); +$finder = $phpbb_extension_manager->get_finder(); + +$migrations = $finder + ->core_path('phpbb/db/migration/data/') + ->get_classes(); +$tips = $migrations; + +foreach ($migrations as $migration_class) +{ + foreach ($migration_class::depends_on() as $dependency) + { + if (($tips_key = array_search($dependency, $tips)) !== false) + { + unset($tips[$tips_key]); + } + } +} + +foreach ($tips as $migration) +{ + echo "\t\t\t'{$migration}',\n"; +} + diff --git a/phpBB/docs/AUTHORS b/phpBB/docs/AUTHORS index 512723b0d4..5ca52c19c0 100644 --- a/phpBB/docs/AUTHORS +++ b/phpBB/docs/AUTHORS @@ -23,10 +23,11 @@ involved in phpBB. phpBB Lead Developer: naderman (Nils Adermann) phpBB Developers: bantu (Andreas Fischer) - EXreaction (Nathan Guse) dhruv.goel92 (Dhruv Goel) + EXreaction (Nathan Guse) imkingdavid (David King) nickvergessen (Joas Schilling) + prototech (Cesar Gallegos) Contributions by: leviatan21 (Gabriel Vazquez) Raimon (Raimon Meuldijk) @@ -79,6 +80,7 @@ Chora (c) 2000-2006, The Horde Project. http://horde.org/chora/ Horde Project (c) 2000-2006, The Horde Project. http://horde.org/ jQuery (c) 2011, John Resig. http://jquery.com/ Sphinx Technologies Inc (c) 2001-2012 Andrew Aksyonoff, http://sphinxsearch.com/ +Plupload (c) 2010-2013 Moxiecode Systems AB, http://www.plupload.com/ PHP License, version 3.0: Pear (c) 2001-2004 PHP Group, http://pear.php.net diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index 2be63eb866..8499431f83 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -46,6 +46,11 @@ <ol> <li><a href="#changelog">Changelog</a> <ol style="list-style-type: lower-roman;"> + <li><a href="#v310b1">Changes since 3.1.0-b1</a></li> + <li><a href="#v310a3">Changes since 3.1.0-a3</a></li> + <li><a href="#v310a2">Changes since 3.1.0-a2</a></li> + <li><a href="#v310a1">Changes since 3.1.0-a1</a></li> + <li><a href="#v30x">Changes since 3.0.x</a></li> <li><a href="#v3011">Changes since 3.0.11</a></li> <li><a href="#v3010">Changes since 3.0.10</a></li> <li><a href="#v309">Changes since 3.0.9</a></li> @@ -86,7 +91,1087 @@ <div class="content"> - <a name="v3011"></a><h3>1.i. Changes since 3.0.11</h3> + <a name="v310b1"></a><h3>1.i. Changes since 3.1.0-b1</h3> + + <h4>Bug</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8309">PHPBB3-8309</a>] - Rename "Last visited" to "Last activity" on memberlist/viewprofile</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9040">PHPBB3-9040</a>] - Count HTML entities as single characters in Custom Profile fields</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9725">PHPBB3-9725</a>] - MSSQL Schema is not azure compatible</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10769">PHPBB3-10769</a>] - "ACP Access Denied" view includes ajax parts</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11071">PHPBB3-11071</a>] - User selection of an invalid style causes a general error</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11357">PHPBB3-11357</a>] - Invalid markup in installer</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11959">PHPBB3-11959</a>] - List of users in notifications should be trimmed</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12031">PHPBB3-12031</a>] - Bug language Notification list should trim users</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12127">PHPBB3-12127</a>] - Possible NOTIFICATION_QUOTE_TRIMMED miswording</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12160">PHPBB3-12160</a>] - Convert Page throws "invalid dbms driver" when no phpBB installation is present</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12257">PHPBB3-12257</a>] - MySQL Fulltext Tests are not run on Travis CI</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12281">PHPBB3-12281</a>] - Disable redis in travis setup on develop until redis fixes it</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12292">PHPBB3-12292</a>] - Buttons are mis-matched, unaligned in ACP Style Details</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12293">PHPBB3-12293</a>] - Core event listeners not working in log.php</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12294">PHPBB3-12294</a>] - phpbb_ in profile fields column names is incorrectly replaced with the table prefix</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12297">PHPBB3-12297</a>] - user_from column not deleted on update to b1</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12310">PHPBB3-12310</a>] - SMTP username and password should not autocomplete during install</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12311">PHPBB3-12311</a>] - Metadata Manager should require license instead of licence</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12314">PHPBB3-12314</a>] - HHVM SPL autoloader sometimes passes class name with leading backslash</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12315">PHPBB3-12315</a>] - NO_SEARCH_INDEX in language/en/acp/common.php uses invalid HTML</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12316">PHPBB3-12316</a>] - develop-ascraeus build status missing from "Automated Testing" section in README.md</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12317">PHPBB3-12317</a>] - Some notification tests fail on DBMS drivers using appropriate integer typing (MSSQL, Sqlite3, also MySQL on HHVM)</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12321">PHPBB3-12321</a>] - Remove execute bit from file ucp_main_subscribed.html and buttons.png in prosilver</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12324">PHPBB3-12324</a>] - Can not update from b1 to b2 because of missing install/update/new/config/ folder</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12326">PHPBB3-12326</a>] - Error while updating from b1 to b2 because of incomplete update files</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12330">PHPBB3-12330</a>] - Installation fails on MSSQL</li> + </ul> + <h4>Improvement</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10174">PHPBB3-10174</a>] - Rename "Ban usernames" to "Ban users" in ACP</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10590">PHPBB3-10590</a>] - Skip confirmation page after successful posting of an approved post</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11169">PHPBB3-11169</a>] - Move prune users from security to users category</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11230">PHPBB3-11230</a>] - Use @inheritdoc in docblocks in cache drivers</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11239">PHPBB3-11239</a>] - Include username before the Overview title.</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11336">PHPBB3-11336</a>] - Rename mode parameter from "leaders" to something more accurate for the "The team" page</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11360">PHPBB3-11360</a>] - page_header() argument "display_online_list" should be FALSE by default</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11666">PHPBB3-11666</a>] - POST_DELETED should refer to posts instead of messages</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12035">PHPBB3-12035</a>] - Add a link to user's posts in the ACP user overview page</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12198">PHPBB3-12198</a>] - Unused ERR_TEMPLATE_EVENT_* language strings in en/common.php</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12268">PHPBB3-12268</a>] - Extension finder should not crawl through .git/ of extensions</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12269">PHPBB3-12269</a>] - Delete "mods" folder from the language folder</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12274">PHPBB3-12274</a>] - Updater is using old version of adm/style/admin.css</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12276">PHPBB3-12276</a>] - Expand core.memberlist_view_profile event to include Zebra state</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12278">PHPBB3-12278</a>] - Add mcp.php core event to allow setting display options for custom MCP modules</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12284">PHPBB3-12284</a>] - Make Extension Details page more readable</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12289">PHPBB3-12289</a>] - Add viewtopic_body.html template event to allow custom post notices</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12300">PHPBB3-12300</a>] - Revert and Reimagine Link to last read posts</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12304">PHPBB3-12304</a>] - Add CSS class to rules-link container</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12308">PHPBB3-12308</a>] - Add Template Event forumlist_body_last_row_after</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12309">PHPBB3-12309</a>] - Add Template Event quickreply_editor_panel_before/after</li> + </ul> + <h4>New Feature</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-7580">PHPBB3-7580</a>] - Allow isset() check in IF template syntax</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12298">PHPBB3-12298</a>] - Template Event memberlist_view_contact_before/after</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12301">PHPBB3-12301</a>] - Template Event overall_header_body_before</li> + </ul> + <h4>Task</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11459">PHPBB3-11459</a>] - Deduplicate database schema definiton</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11904">PHPBB3-11904</a>] - Revisit ALLOW_CDN_EXPLAIN wording</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12302">PHPBB3-12302</a>] - Upgrade composer.phar to 1.0.0-alpha8</li> + </ul> + + <a name="v310a3"></a><h3>1.ii. Changes since 3.1.0-a3</h3> + + <h4>Bug</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8041">PHPBB3-8041</a>] - Do not concatenate the destination to L_RETURN_TO to allow better translations</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8122">PHPBB3-8122</a>] - Reviewing topics/posts - not correctly displayed</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8785">PHPBB3-8785</a>] - PM recipients/bcc list looks bad</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8919">PHPBB3-8919</a>] - Localisation imageset being refreshed too frequently causing broken images</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9106">PHPBB3-9106</a>] - Upload fails to complete for large files.</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9420">PHPBB3-9420</a>] - BBCode - Unable to use a proper URI token</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9459">PHPBB3-9459</a>] - Visiting ACP with screen resolution 800x600px</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10175">PHPBB3-10175</a>] - Class loader cannot find a/b_foo.php when a/b/bar.php exists</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10338">PHPBB3-10338</a>] - Attachments list is displayed incorrectly</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10722">PHPBB3-10722</a>] - Code Coverage generation fails</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11038">PHPBB3-11038</a>] - Does not correctly find module info classes using new naming conventions</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11146">PHPBB3-11146</a>] - MCP topic/post approval error</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11151">PHPBB3-11151</a>] - Can use negative start for memberlist.php</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11218">PHPBB3-11218</a>] - File upload functional test fails</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11255">PHPBB3-11255</a>] - Some tests do not run standalone due to dbal dependency on global $cache</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11271">PHPBB3-11271</a>] - Images in ATOM feed display, but attached inline images do not.</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11288">PHPBB3-11288</a>] - "Fulltext native" search fooled by hyphens</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11364">PHPBB3-11364</a>] - Add an easy-to-switch system for app.php?controller= vs mod-rewrite usage in append_sid</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11429">PHPBB3-11429</a>] - Extensions should increment assets number on enable</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11581">PHPBB3-11581</a>] - General Error in UCP if PMs are disabled in ACP</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11625">PHPBB3-11625</a>] - General Error accessing MCP from Global Announcement</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11648">PHPBB3-11648</a>] - Test suite creates files in phpBB directory</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11787">PHPBB3-11787</a>] - Permission language strings use samp for highlight instead of strong</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11880">PHPBB3-11880</a>] - Schema changes can take too long and cause a timeout</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11938">PHPBB3-11938</a>] - Use of deprecated sql_attr_str2ordinal in sphinx.conf</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12003">PHPBB3-12003</a>] - ACP broken when error thrown</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12072">PHPBB3-12072</a>] - Missing word "send" in comment in schema_data.sql</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12078">PHPBB3-12078</a>] - "Can permanently delete own posts" permission has no effect</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12080">PHPBB3-12080</a>] - Responsive design in ACP / User Administration / Signature needs fixing</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12093">PHPBB3-12093</a>] - IE 11 javascript selection is no longer supported</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12126">PHPBB3-12126</a>] - Alert box is aligned to the left instead of center in IE</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12132">PHPBB3-12132</a>] - viewtopic_print_head_append template event is missing in subsilver2</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12134">PHPBB3-12134</a>] - ucp_pm_viewmessage_print_head_append template event is missing in subsilver2</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12136">PHPBB3-12136</a>] - Call to undefined function generate_pagination() in functions_posting.php</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12138">PHPBB3-12138</a>] - Information and pagination of filtered attachments</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12139">PHPBB3-12139</a>] - Spaces missing after $show_guests in viewonline.php</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12141">PHPBB3-12141</a>] - Travis tests fail on 5.5</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12149">PHPBB3-12149</a>] - Division by zero in [ROOT] -/phpbb/pagination.php</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12153">PHPBB3-12153</a>] - PAGE_NUMBER should be assigned by pagination.generate_template_pagination()</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12158">PHPBB3-12158</a>] - pagination.validate_start() returns negative value when $num_items = 0</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12168">PHPBB3-12168</a>] - Nav Header Links Alignment Issues without small-icon</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12170">PHPBB3-12170</a>] - Migration helper replaces table name with 0 when creating tables</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12171">PHPBB3-12171</a>] - Attachments from soft-deleted posts are still downloadable</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12172">PHPBB3-12172</a>] - "Download all attachments" feature leaks post/pm attachments when being able to download one of them</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12175">PHPBB3-12175</a>] - Fix and run functional upload tests</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12176">PHPBB3-12176</a>] - No error shown when attempting to delete a founder</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12183">PHPBB3-12183</a>] - Update user_newpasswd column in users table for passwords manager</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12184">PHPBB3-12184</a>] - Undefined variable tpl_fields in profile field manager on memberlist</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12188">PHPBB3-12188</a>] - Add php 5.6 to travis tests</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12192">PHPBB3-12192</a>] - Avatars in PM report closed notifications are broken</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12194">PHPBB3-12194</a>] - Unknown column 'field_show_novalue' in 'field list' [1054] -</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12200">PHPBB3-12200</a>] - Profile field template files missing in adm/style</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12202">PHPBB3-12202</a>] - Variables read from style.cfg etc. should be htmlspecialchared</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12203">PHPBB3-12203</a>] - user_occ does not have a default value when registering</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12205">PHPBB3-12205</a>] - Custom Profile Field display bug</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12206">PHPBB3-12206</a>] - Errors in plupload doesn't pull lang vars right</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12207">PHPBB3-12207</a>] - prosilver layout breaks when error outputted before <html></li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12208">PHPBB3-12208</a>] - Plupload uploads files even if they were deleted from queue</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12210">PHPBB3-12210</a>] - dbtools::sql_create_table incorrectly throws error related to auto-increment length on non auto-increment fields</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12212">PHPBB3-12212</a>] - HTML in attachment file name rendered before upload</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12216">PHPBB3-12216</a>] - Undefined index: lang_options when creating date profile field</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12220">PHPBB3-12220</a>] - Debug message if no unread messages are present</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12222">PHPBB3-12222</a>] - Replace hardoded comma with translatable separator in forumlist_body.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12223">PHPBB3-12223</a>] - Pagination displayes additional &bull; when PAGE_NUMBER is empty</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12226">PHPBB3-12226</a>] - Incorrectly used plurals in ucp.php MOVE_PM_ERROR and FOLDER_MESSAGE_STATUS</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12227">PHPBB3-12227</a>] - "X from Y messages" should be "X out of Y messages"</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12243">PHPBB3-12243</a>] - subsilver2 is missing profile field files</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12245">PHPBB3-12245</a>] - "Invalid id refernce" for label "joined" and "group_id" in acp_prune_users.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12249">PHPBB3-12249</a>] - Undefined variable: row when editing profile</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12250">PHPBB3-12250</a>] - Remove deprecated phpbb_clean_path function</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12251">PHPBB3-12251</a>] - Clean up and Enhancement of Custom Profile Fields</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12256">PHPBB3-12256</a>] - phpbb\notification\type\admin_activate_user uses $sql as fetchrow parameter</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12261">PHPBB3-12261</a>] - Login redirect from extension front controllers broken</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12263">PHPBB3-12263</a>] - \phpbb\db\migration\tool\module.php contains several errors</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12267">PHPBB3-12267</a>] - Functional testcase method get_extension_manager() uses undefined variable php_ext</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12271">PHPBB3-12271</a>] - Decouple dropdown header/footer from #notification_list</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12272">PHPBB3-12272</a>] - Hardcoded colon in subforums list</li> + </ul> + <h4>Improvement</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9255">PHPBB3-9255</a>] - Friends Sidebar has scability issues..</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9479">PHPBB3-9479</a>] - Empty paragraphs for vertical spacing are rather old-fashioned</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9709">PHPBB3-9709</a>] - Missing language files for MCP could be substituted by default / english ones</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9871">PHPBB3-9871</a>] - Update version check file to use json format</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10288">PHPBB3-10288</a>] - Templates including other templates in loop can't access variables</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10549">PHPBB3-10549</a>] - Languages variables should be used, not hardcoded</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10555">PHPBB3-10555</a>] - Copyright notice in overall_header.html is not translatable</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10945">PHPBB3-10945</a>] - Show entered search query in the search box when no results are found.</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11019">PHPBB3-11019</a>] - Ability to store array of data in a log</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11022">PHPBB3-11022</a>] - Add "Tahoma" to used font families in css files</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11040">PHPBB3-11040</a>] - PostgreSQL fulltext search improvement</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11111">PHPBB3-11111</a>] - Allow only vertical resize on the textarea.</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11179">PHPBB3-11179</a>] - change the start parameter in search when out of bounds to display last(or first) page</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11201">PHPBB3-11201</a>] - MSNM / WLM closing - redundant profile field</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11254">PHPBB3-11254</a>] - Check CRLF line endings in the test suite</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11297">PHPBB3-11297</a>] - Running tests doc should mention dbunit dependency</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11610">PHPBB3-11610</a>] - Use a more secure hashing method like bcrypt</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11645">PHPBB3-11645</a>] - Rename ".MODs" tab in the ACP</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11693">PHPBB3-11693</a>] - Change phpbb_db_driver::sql_build_array() to support DELETE</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11716">PHPBB3-11716</a>] - Migration to convert soft delete/trash bin mods to 3.1 soft delete</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12029">PHPBB3-12029</a>] - Module names in the ACP should not be truncated when they are too long</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12073">PHPBB3-12073</a>] - Small text size in ACP between <samp></samp> and <code></code> tags</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12106">PHPBB3-12106</a>] - Document exceptions to "Disable Board" in ACP.</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12114">PHPBB3-12114</a>] - Convert current profile fields to custom-profile-field system</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12117">PHPBB3-12117</a>] - Nested Set Tree Classes Should be able to get all roots</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12166">PHPBB3-12166</a>] - Add template event "quickreply_editor_message_box_before"</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12167">PHPBB3-12167</a>] - Allow users to change style via style parameter by default</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12190">PHPBB3-12190</a>] - Add core event "core.modify_submit_post_data"</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12217">PHPBB3-12217</a>] - Add template events to viewtopic_body.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12224">PHPBB3-12224</a>] - Add template method to assign block arrays</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12231">PHPBB3-12231</a>] - Add template events to forumlist_body.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12238">PHPBB3-12238</a>] - There is no cancel input type.</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12239">PHPBB3-12239</a>] - Move deprecated password functions to compatibility file</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12240">PHPBB3-12240</a>] - Adding specific class names to buttons in posting_buttons.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12241">PHPBB3-12241</a>] - Event to add and/or modify acp_board configurations</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12244">PHPBB3-12244</a>] - Remove ambiguity between Extension Tab and Extensions Management links</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12248">PHPBB3-12248</a>] - Extension Details Homepage should be a clickable link</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12259">PHPBB3-12259</a>] - Too many redundant tests are run on Travis</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12260">PHPBB3-12260</a>] - Add core event to delete_posts() function</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12262">PHPBB3-12262</a>] - Adjust a script to export the events in wiki format</li> + </ul> + <h4>Sub-task</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12115">PHPBB3-12115</a>] - Convert occupation/interests profile field to custom field</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12169">PHPBB3-12169</a>] - Convert location user field to profile field </li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12187">PHPBB3-12187</a>] - Convert website user field to profile field</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12233">PHPBB3-12233</a>] - Allowing CPF to be have an icon on viewtopic and be listed in the contact section of the profile</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12234">PHPBB3-12234</a>] - Convert ICQ user field to profile field</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12235">PHPBB3-12235</a>] - Convert MSN/WLM user field to profile field </li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12236">PHPBB3-12236</a>] - Convert AOL user field to profile field</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12237">PHPBB3-12237</a>] - Convert Yahoo user field to profile field</li> + </ul> + <h4>Task</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10763">PHPBB3-10763</a>] - Audit code for non-static functions called statically</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10793">PHPBB3-10793</a>] - Use db_tools in create_schema_files</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11509">PHPBB3-11509</a>] - Travis should check commit message format</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11764">PHPBB3-11764</a>] - Remove Subsilver2 from installation packages</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12177">PHPBB3-12177</a>] - Add event ucp_zebra_friend_list_before/after</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12180">PHPBB3-12180</a>] - CodeSniffer: Ensure each file ends with a single newline</li> + </ul> + + + <a name="v310a2"></a><h3>1.iii. Changes since 3.1.0-a2</h3> + +<h4>Bug</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10810">PHPBB3-10810</a>] - Manage group in ucp requires access to adm/</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11246">PHPBB3-11246</a>] - Misleading Message in New User Pruning Feature</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11484">PHPBB3-11484</a>] - Topic Reply Notification email links not requiring user to log in</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11507">PHPBB3-11507</a>] - Impossible to prune users by group only</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11672">PHPBB3-11672</a>] - AJAX alerts contain unnecessary messages/links</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11709">PHPBB3-11709</a>] - Bulletin points in navigation menu are misaligned in RTL languages</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11842">PHPBB3-11842</a>] - Avatar driver error thrown when creating group</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11856">PHPBB3-11856</a>] - Require composer.json for extensions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11859">PHPBB3-11859</a>] - Avatar drivers should return template filename</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11869">PHPBB3-11869</a>] - Strict debug message when registering with profile fields displayed</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11911">PHPBB3-11911</a>] - ACP should warn if there is no search index created for the selected search engine</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11912">PHPBB3-11912</a>] - "Unable to guess the mime type as no guessers are available" when uploading files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11914">PHPBB3-11914</a>] - plupload should be updated to 2.0.x</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11915">PHPBB3-11915</a>] - plupload should be restyled to match the design of prosilver better</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11959">PHPBB3-11959</a>] - List of users in notifications should be trimmed</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11963">PHPBB3-11963</a>] - Stale MCP notifications get left behind</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11984">PHPBB3-11984</a>] - Ticket for more bugs/improvements for responsive design for both prosilver and ACP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11988">PHPBB3-11988</a>] - Active tab in ACP should not have hover effect</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11997">PHPBB3-11997</a>] - redirect() does not work for app.php/xyz pages</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12001">PHPBB3-12001</a>] - User input is ignored in AJAX confirmation forms</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12006">PHPBB3-12006</a>] - Disabled Extensions with Modules can break the ACP/UCP/MCP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12009">PHPBB3-12009</a>] - Incorrectly installed extensions should be ignored</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12011">PHPBB3-12011</a>] - RTL languages have style bugs in prosilver/ACP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12015">PHPBB3-12015</a>] - Enhance events in viewtopic to increase their usability</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12026">PHPBB3-12026</a>] - Unable to find template - in MCP/UCP, which are added via extensions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12027">PHPBB3-12027</a>] - Redis tests failing</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12028">PHPBB3-12028</a>] - Don't use L_COLON in a JavaScript context</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12030">PHPBB3-12030</a>] - Include config directory completely in update packages when one file is being updated</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12032">PHPBB3-12032</a>] - Certain notifications incorrectly inherit read status from post/topic</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12036">PHPBB3-12036</a>] - Module Management items have 2 move down buttons and no up</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12038">PHPBB3-12038</a>] - Move up/down buttons are not AJAXified in various ACP pages.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12040">PHPBB3-12040</a>] - ACP tabs flicker when AJAX background appears</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12042">PHPBB3-12042</a>] - Several strings of plupload are not being translated</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12045">PHPBB3-12045</a>] - Several HTML markup issues in adm/style/acp_prune_users.html</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12049">PHPBB3-12049</a>] - PLUPLOAD_ERR_UPLOAD_LIMIT should be using plurals</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12050">PHPBB3-12050</a>] - phpbb_notification_submit_post_base should be abstract</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12055">PHPBB3-12055</a>] - ACP BBCodes/Smilies Row Color Changes Needed After AJAX operations</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12058">PHPBB3-12058</a>] - Updating database fails in migration v310/avatar_types.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12059">PHPBB3-12059</a>] - ACP INCLUDECSS not working, missing {$STYLESHEETS}</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12062">PHPBB3-12062</a>] - INCLUDEJS broken for extension events in the ACP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12063">PHPBB3-12063</a>] - <tr> tags use invalid valign attribute</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12077">PHPBB3-12077</a>] - General Error thrown when submitting ACP language pack editor </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12079">PHPBB3-12079</a>] - request.untrimmed_variable() $multibyte param does not have default value</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12091">PHPBB3-12091</a>] - Plupload - File upload does not work in Internet Explorer 11</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12092">PHPBB3-12092</a>] - Plupload - File info missing for several uploaded files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12095">PHPBB3-12095</a>] - IE11 JavaScript plupload error</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12096">PHPBB3-12096</a>] - Not using plurals correctly in search.php MAX_NUM_SEARCH_KEYWORDS_REFINE</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12100">PHPBB3-12100</a>] - ACP Template files not purged during Extension Enable/Disable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12107">PHPBB3-12107</a>] - Log table name is hard-coded in log.get_logs()</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12110">PHPBB3-12110</a>] - Update Plupload to 2.1.1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12123">PHPBB3-12123</a>] - No category specified for soft-delete permission</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12124">PHPBB3-12124</a>] - Plupload broken on IE8</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12125">PHPBB3-12125</a>] - Topic rows are missing background in IE8</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12131">PHPBB3-12131</a>] - prosilver viewtopic print view has invalid imageset var</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12140">PHPBB3-12140</a>] - Avoid endless loop in build script</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12141">PHPBB3-12141</a>] - Travis tests fail on 5.5</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12151">PHPBB3-12151</a>] - Class 'phpbb\profilefields\profilefields' not found</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12154">PHPBB3-12154</a>] - DB Schema not built with develop script</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12156">PHPBB3-12156</a>] - Passwords Manager ~ Bug with OAuth</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12159">PHPBB3-12159</a>] - Fix code sniffer complaints after profilefields and passwords merge</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12161">PHPBB3-12161</a>] - build/save directories are no longer created</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12162">PHPBB3-12162</a>] - Binary files missing from update packages</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12163">PHPBB3-12163</a>] - Page number in viewtopic page title is incorrect</li> +</ul> +<h4>Improvement</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10910">PHPBB3-10910</a>] - function build_cfg_template() allow $size for $tpl_type = select</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11346">PHPBB3-11346</a>] - Do not show "Mark topics as read" when there are no topics</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11849">PHPBB3-11849</a>] - Move pagination from functions.php into class</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11950">PHPBB3-11950</a>] - Add 'I forgot my password' link to index page login form</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11961">PHPBB3-11961</a>] - Plupload is not updating uploaded files panel</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11966">PHPBB3-11966</a>] - Add Template Event overall_header_navigation_prepend/append to Subsilver2</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11969">PHPBB3-11969</a>] - Link topic title to unread post instead of first post</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11979">PHPBB3-11979</a>] - Add basic dropdown menu framework to prosilver</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12005">PHPBB3-12005</a>] - Remove code responsible for PM popup completely</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12010">PHPBB3-12010</a>] - Navbar icons should be clickable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12014">PHPBB3-12014</a>] - Add template event "index_body_forumlist_before"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12024">PHPBB3-12024</a>] - Add Template Event overall_header_content_before and overall_footer_content_after</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12034">PHPBB3-12034</a>] - AJAXify notifications popup</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12054">PHPBB3-12054</a>] - Improve Index Body Template Events</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12060">PHPBB3-12060</a>] - Add BBCode system core and template events</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12069">PHPBB3-12069</a>] - Add PHP event core.submit_post_modify_return_url in submit_post()</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12104">PHPBB3-12104</a>] - Shadowtopics SQL used in core event should use the SQL builder</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12135">PHPBB3-12135</a>] - editor.js function bbfontstyle()</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12146">PHPBB3-12146</a>] - Add color demo when editing a group from the UCP</li> +</ul> +<h4>New Feature</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12039">PHPBB3-12039</a>] - Add config functionality to CLI</li> +</ul> +<h4>Sub-task</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11241">PHPBB3-11241</a>] - Improve user interface for mass attachment downloader (all posts, all topics)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12111">PHPBB3-12111</a>] - Extract profile field types to individual classes</li> +</ul> +<h4>Task</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11432">PHPBB3-11432</a>] - Travis should complain when CRLF files are added.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11509">PHPBB3-11509</a>] - Travis should check commit message format</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11985">PHPBB3-11985</a>] - Enable APC module on Travis to run APC Cache tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12064">PHPBB3-12064</a>] - Remove obsolete viewsource.html from adm/style folder</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12147">PHPBB3-12147</a>] - Remove Travis CI notification configuration</li> +</ul> + + <a name="v310a1"></a><h3>1.iv. Changes since 3.1.0-a1</h3> + +<h4>Bug</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-4776">PHPBB3-4776</a>] - Long post gets hidden behind posting profile</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10449">PHPBB3-10449</a>] - Lines spilling in subscriptions view</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10948">PHPBB3-10948</a>] - Color swatch in 3.1 does not display properly</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11030">PHPBB3-11030</a>] - I beam cursor in prosilver when hovering on browse button for uploading attachments</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11073">PHPBB3-11073</a>] - Reported/Unapproved moderator information in viewtopic is striked through instead of underlined</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11138">PHPBB3-11138</a>] - Resync features in ACP should not use AJAX</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11280">PHPBB3-11280</a>] - Double clicking "mark topics read" produces an error the second time</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11525">PHPBB3-11525</a>] - phpbb_avatar_manager::clean_row collapses user_id and group_id</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11534">PHPBB3-11534</a>] - Remote avatar does not properly check if remote file is an image</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11626">PHPBB3-11626</a>] - Auth ACP options should be moved to separate html file</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11663">PHPBB3-11663</a>] - In generate_text_for_storage the function does not check for errors of parse_message:parse() and act accordingly</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11691">PHPBB3-11691</a>] - Soft delete migration conversion should be staggered</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11739">PHPBB3-11739</a>] - Wrong name for UCP Module "Edit "Remember Me" login keys"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11842">PHPBB3-11842</a>] - Create a new group Error with avatar driver</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11857">PHPBB3-11857</a>] - Avatar manager must not depend on entire container</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11872">PHPBB3-11872</a>] - MCP: Users with most warnings list is invalid</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11896">PHPBB3-11896</a>] - "Mark all notifications read" does not work</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11899">PHPBB3-11899</a>] - New ajax poll vote should give feedback while waiting for servers response</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11916">PHPBB3-11916</a>] - Remove files from hidden attach list after deletion</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11922">PHPBB3-11922</a>] - Migrator fails to remove columns on MSSQL when they have/had an index</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11923">PHPBB3-11923</a>] - UCP avatar error when user has no permissions to change his/her avatar</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11924">PHPBB3-11924</a>] - Add a script to export the events in wiki format</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11926">PHPBB3-11926</a>] - Plupload Migration has a broken dependency.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11927">PHPBB3-11927</a>] - Missing Files after 3.1.0-A1 Automatic Updater</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11930">PHPBB3-11930</a>] - Avatar paths are incorrect when using app.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11935">PHPBB3-11935</a>] - Invalid HTML in "Sort By" form elements in Prosilver</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11936">PHPBB3-11936</a>] - Fixes to Notifications Window</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11939">PHPBB3-11939</a>] - Quick reply editor has unnecessary data-ajax attribute</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11943">PHPBB3-11943</a>] - $VAR = false has unexpected result</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11945">PHPBB3-11945</a>] - Focused buttons are hard to notice</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11947">PHPBB3-11947</a>] - Notification popup does not appear when clicking number in text</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11948">PHPBB3-11948</a>] - Extensions should be allowed to have more then 1 routing file</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11949">PHPBB3-11949</a>] - cannot upgrade to 3.1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11960">PHPBB3-11960</a>] - Responsive design removed teampage names</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11972">PHPBB3-11972</a>] - Add template event posting_editor_subject_after</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11977">PHPBB3-11977</a>] - Ajax delete should disable moving options</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11982">PHPBB3-11982</a>] - Navigation is shown above AJAX background in ACP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11983">PHPBB3-11983</a>] - Subscriptions argument missing from docblock in ucp_notifications</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11986">PHPBB3-11986</a>] - Undefined index: poster_id in file.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11987">PHPBB3-11987</a>] - {ROOT_PATH} in ACP leads to adm/</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11990">PHPBB3-11990</a>] - Remove result_mssqlnative from acp_database</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11991">PHPBB3-11991</a>] - PHP notices when closing reported posts entries in MCP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11992">PHPBB3-11992</a>] - Wrong variable to close "Users with most warnings" block at MCP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11994">PHPBB3-11994</a>] - Admin options for extensions are bad/misleading</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11995">PHPBB3-11995</a>] - Reverting a config.remove fails</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12002">PHPBB3-12002</a>] - Extension management page should use generate/check link hash</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12007">PHPBB3-12007</a>] - Default last_result of callable steps must be integer instead of false</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12008">PHPBB3-12008</a>] - "Prune notifications" cron task always ran, blocking others</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12016">PHPBB3-12016</a>] - Event listeners should be services</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12017">PHPBB3-12017</a>] - Extension tests are broken on current develop</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12018">PHPBB3-12018</a>] - Use path_helper for admin style CSS in sql report</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12023">PHPBB3-12023</a>] - New css files missing after update</li> +</ul> +<h4>Improvement</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11552">PHPBB3-11552</a>] - Responsive design for prosilver</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11746">PHPBB3-11746</a>] - Add "account activation required" notification for Administrators</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11921">PHPBB3-11921</a>] - Improve Notifications and PMs in the header</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11928">PHPBB3-11928</a>] - Replace AJAX loading info pop up with animation</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11957">PHPBB3-11957</a>] - Responsive design for admin control panel</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11973">PHPBB3-11973</a>] - Remove logic from language files where possible</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11974">PHPBB3-11974</a>] - All timezones should be translatable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11975">PHPBB3-11975</a>] - Add ACP link next to MCP</li> +</ul> +<h4>Task</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11031">PHPBB3-11031</a>] - Bring phpBB2 converter up to speed with 3.1 changes</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11980">PHPBB3-11980</a>] - Setup PHP Code Sniffer</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11981">PHPBB3-11981</a>] - Review/Fix Code Sniffer complaints</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11998">PHPBB3-11998</a>] - Add console / command line client environment </li> +</ul> + + <a name="v30x"></a><h3>1.v. Changes since 3.0.x</h3> + +<h4>Bug</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-4412">PHPBB3-4412</a>] - MCP and viewtopic messed up when long profile fields used</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-6109">PHPBB3-6109</a>] - MSN is now called Windows Live Messenger (WLM)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-6855">PHPBB3-6855</a>] - The word separator has been misspelled in the code</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-7070">PHPBB3-7070</a>] - Making Font Type & Size Easy To modify</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-7252">PHPBB3-7252</a>] - Use IMAGETYPE_ constants in get_supported_image_types()</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-7448">PHPBB3-7448</a>] - Module management calling non-static method p_master::module_auth()</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8212">PHPBB3-8212</a>] - Comment spelling mistake in includes/acp/acp_board.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8228">PHPBB3-8228</a>] - Coding BBcode has whitespace before the code.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8542">PHPBB3-8542</a>] - No custom profile fields in private messages</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8641">PHPBB3-8641</a>] - Extra and missing comma in acp_board.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8713">PHPBB3-8713</a>] - trimming login inputs isn't sensible</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8841">PHPBB3-8841</a>] - Unexpected results when using "PHPBB_USE_BOARD_URL_PATH"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8912">PHPBB3-8912</a>] - phpbb_styles_template_data contans more than 4k records</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9022">PHPBB3-9022</a>] - Poll Deletion Problem on Global change</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9163">PHPBB3-9163</a>] - style.php cannot be properly cached</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9341">PHPBB3-9341</a>] - Incorrectly named template vars</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9394">PHPBB3-9394</a>] - wrong comment in functions_upload.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9474">PHPBB3-9474</a>] - Unnecessary mcp_viewlogs.html included</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9492">PHPBB3-9492</a>] - Group avatar overwrites currently defined user avatars</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9766">PHPBB3-9766</a>] - phpbb_default_captcha::delete_code() takes no argument but uses $confirm_id</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9918">PHPBB3-9918</a>] - $redirect variable set, but not used, in mcp functions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10006">PHPBB3-10006</a>] - phpbb_config::delete is missing</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10013">PHPBB3-10013</a>] - Cache test writes to a temporary location deep in the source tree</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10045">PHPBB3-10045</a>] - Database updater version for changes between 3.0.x and 3.1.0 should be 3.1.0-dev</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10070">PHPBB3-10070</a>] - CRLF in develop</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10080">PHPBB3-10080</a>] - request_var tests fail when other tests using request_var are executed first</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10103">PHPBB3-10103</a>] - Fix remaining usage of flock() by converting it to use the lock class</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10136">PHPBB3-10136</a>] - Missing $request globalizations in includes/functions.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10139">PHPBB3-10139</a>] - Use of $cache for two different things in includes/config/db.php </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10151">PHPBB3-10151</a>] - Version number needs to be updated in installer</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10152">PHPBB3-10152</a>] - Installer places ?> in config.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10156">PHPBB3-10156</a>] - Cron tests fail on windows</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10290">PHPBB3-10290</a>] - Who's online broken due to malformed SQL</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10300">PHPBB3-10300</a>] - Groups teampage legends settings</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10316">PHPBB3-10316</a>] - Inconsistency between prosilver and subsilver when locking a topic while moving</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10322">PHPBB3-10322</a>] - No longer possible to include templates via variables, captcha broken</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10329">PHPBB3-10329</a>] - Function pcre_utf8_support() needs the "phpbb_" prefix</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10350">PHPBB3-10350</a>] - class phpbb_template_renderer_eval does not work</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10355">PHPBB3-10355</a>] - Template tests do not correctly end output buffering</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10359">PHPBB3-10359</a>] - Fix phpbb_request regression in download/file.php and style.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10360">PHPBB3-10360</a>] - search_results.html gone haywire!</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10364">PHPBB3-10364</a>] - ACP Permissions Roles Tabs Broken</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10371">PHPBB3-10371</a>] - $user->theme['imageset_path'] - doesn't exist anymore</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10374">PHPBB3-10374</a>] - Template cache viewer broken</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10375">PHPBB3-10375</a>] - Template Cache keeps regenerating cache files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10378">PHPBB3-10378</a>] - Errors in imageset -> theme conversion</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10380">PHPBB3-10380</a>] - Imageset removal: bidi padding change</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10384">PHPBB3-10384</a>] - 1_DAY language variables are not working in templates anymore</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10392">PHPBB3-10392</a>] - Alternate nested block loop syntax broken for auto variables</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10393">PHPBB3-10393</a>] - Syntax error in cached template code</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10409">PHPBB3-10409</a>] - Running database_update.php multiple times breaks the update</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10417">PHPBB3-10417</a>] - phpbb_test_case_helpers::get_test_config() uses array_merge() on undefined $config</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10444">PHPBB3-10444</a>] - Edit reason remains if a post gets edited by a moderator for the second time</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10457">PHPBB3-10457</a>] - Undefined variable $request, when print-viewing PMs</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10458">PHPBB3-10458</a>] - Invalid html when print-viewing a PM</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10459">PHPBB3-10459</a>] - Make "Reply to all"on PMs as a button</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10463">PHPBB3-10463</a>] - Inherit template causes SQL error</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10464">PHPBB3-10464</a>] - Debug error in search settings/search index</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10477">PHPBB3-10477</a>] - Registration, forgot password broken</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10481">PHPBB3-10481</a>] - Test suite does not run on php 5.3</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10495">PHPBB3-10495</a>] - Tests have version checks against php 6.0.0</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10500">PHPBB3-10500</a>] - Miscellaneous issues in the new template engine</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10541">PHPBB3-10541</a>] - Empty "Select form:" dropdown when editing user</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10547">PHPBB3-10547</a>] - Log out instead of acp statistics page at the end of fresh install </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10560">PHPBB3-10560</a>] - Post count not updated to include unapproved posts (though topic count is) for moderators</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10575">PHPBB3-10575</a>] - UCP Register: Non-static method phpbb_captcha_factory::get_instance() should not be called statically</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10579">PHPBB3-10579</a>] - New license block has v2 duplicated</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10602">PHPBB3-10602</a>] - A bug in mail queue processing</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10618">PHPBB3-10618</a>] - Hardcoded phpBB 3.0 language in installer</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10634">PHPBB3-10634</a>] - cp modules: function loaded() only checks current module type</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10636">PHPBB3-10636</a>] - cache_moderators() generates invalid query</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10637">PHPBB3-10637</a>] - Extension manager: missed code changes in search</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10641">PHPBB3-10641</a>] - MCP still uses old plurality forms of language variables</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10645">PHPBB3-10645</a>] - Invalid CSS for checkboxes and radio buttons in ACP css</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10652">PHPBB3-10652</a>] - Template inheritance doesn't work</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10655">PHPBB3-10655</a>] - Bug in test case: phpbb_template_template_inheritance_test</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10663">PHPBB3-10663</a>] - Extension manager: finder class adds directories that should not match the query</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10667">PHPBB3-10667</a>] - Fix extensions and group positions tests under MySQL 5.5 strict mode</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10671">PHPBB3-10671</a>] - Integrity tests failing</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10672">PHPBB3-10672</a>] - Statistics .. Total posts</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10678">PHPBB3-10678</a>] - Provide Firebird, Oracle, and increased MSSQL support in unit tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10685">PHPBB3-10685</a>] - Template inheritance test produces a notice on php 5.4 due to an incompatible override of setup_engine</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10690">PHPBB3-10690</a>] - Undefined language string in MCP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10703">PHPBB3-10703</a>] - extensions.php script dies miserably when ext directory is missing</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10704">PHPBB3-10704</a>] - Typo in a comment</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10735">PHPBB3-10735</a>] - Incorrect styles search order, locator's inability to use template inheritance for extensions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10736">PHPBB3-10736</a>] - Composer is making tests fail</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10742">PHPBB3-10742</a>] - Tables in users list have incorrect width</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10752">PHPBB3-10752</a>] - acp_styles errors</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10754">PHPBB3-10754</a>] - $style should be renamed to $phpbb_style</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10756">PHPBB3-10756</a>] - Template classes don't belong in style directory</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10759">PHPBB3-10759</a>] - Database updater doesn't reset default style</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10777">PHPBB3-10777</a>] - Typo in viewtopic.php comment line 1632</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10778">PHPBB3-10778</a>] - Extra space on the link "Close Window" in prosilver/template/posting_smilies.html</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10779">PHPBB3-10779</a>] - "Serve jQuery using Google's CDN" Should be on ACP Load Settings, not Board Features</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10781">PHPBB3-10781</a>] - Quick Mod tools don't work</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10784">PHPBB3-10784</a>] - Do not show ajax overlay unless needed</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10785">PHPBB3-10785</a>] - Illegal use of $_REQUEST in develop/fill.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10801">PHPBB3-10801</a>] - Move topic in quickmod tools not functional</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10802">PHPBB3-10802</a>] - Splitting topics in quickmod tools not functional</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10803">PHPBB3-10803</a>] - When ajax requests fail, the failure message should remain visible until the user dismisses it</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10805">PHPBB3-10805</a>] - "Request timed out" ui appears over function ui in ajax</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10807">PHPBB3-10807</a>] - Deleting topics via quickmod provides no feedback</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10808">PHPBB3-10808</a>] - Locking topics via quickmod provides no feedback</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10811">PHPBB3-10811</a>] - AJAX callback "alt_text" insufficiently changes links</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10813">PHPBB3-10813</a>] - Installer does not check that php json extension is present</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10818">PHPBB3-10818</a>] - Global Announcements Update Dialog does not terminate with exit_handler()</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10826">PHPBB3-10826</a>] - 3.1-dev Database Updater keeps running group_legend query</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10837">PHPBB3-10837</a>] - Undefined index in extension tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10844">PHPBB3-10844</a>] - Extensions are not located when front-end file has a diffferent phpbb_root_path</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10845">PHPBB3-10845</a>] - Reported post text does not get bbcode-parsed when viewing a post report</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10847">PHPBB3-10847</a>] - Dependent is misspelled a number of times</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10871">PHPBB3-10871</a>] - In "Posts awaiting approval" if there's more than one post it shows no posts</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10875">PHPBB3-10875</a>] - SQL Cache is not used</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10876">PHPBB3-10876</a>] - Xampp crashes on Develop when template has too many ORs in an IF statement</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10885">PHPBB3-10885</a>] - UCP Main Error if no forums exist</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10888">PHPBB3-10888</a>] - cachepath in template class is set externally</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10905">PHPBB3-10905</a>] - Last topic title missing in subsilver</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10906">PHPBB3-10906</a>] - Last post title does not work for new installs of 3.1-dev due to missing change to schema_data.sql</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10912">PHPBB3-10912</a>] - Undefined variable: last_post_subject_truncated</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10915">PHPBB3-10915</a>] - Sort not installed styles list in admin control panel - styles</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10943">PHPBB3-10943</a>] - Search Box should display keywords entered by the user</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10954">PHPBB3-10954</a>] - Mark topics as read AJAX</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10976">PHPBB3-10976</a>] - Running tests using phpunit.xml.all fails</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10982">PHPBB3-10982</a>] - Allow setting dimming control overlay also as data-overlay</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10998">PHPBB3-10998</a>] - No border-radius for forum rules block</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10999">PHPBB3-10999</a>] - Asset version not defined in adm/</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11002">PHPBB3-11002</a>] - Etc/GMT timezones return wrong offset</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11003">PHPBB3-11003</a>] - Ability to show full list of timezones with JavaScript enabled</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11004">PHPBB3-11004</a>] - The timezone suggestion button is not a real button</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11007">PHPBB3-11007</a>] - Timezone selector shows all timezones</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11014">PHPBB3-11014</a>] - Previous/next links are no longer displayed.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11018">PHPBB3-11018</a>] - Pagination in memberlist</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11023">PHPBB3-11023</a>] - Fix excess tabbing and spacing in functions.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11029">PHPBB3-11029</a>] - Cannot break/continue 1 level in includes\cache\service.php:340</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11041">PHPBB3-11041</a>] - global $php_ext instead of global $phpEx</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11043">PHPBB3-11043</a>] - Update template hook name</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11046">PHPBB3-11046</a>] - No border-radius for UCP message colours block</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11047">PHPBB3-11047</a>] - Unclosed variable shows incorrect language key</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11052">PHPBB3-11052</a>] - Search class changes not reflected in installer or convertor</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11065">PHPBB3-11065</a>] - li tag on topic display options at MCP is unclosed</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11067">PHPBB3-11067</a>] - Pagination in ACP is missing CSS code from pagination change</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11077">PHPBB3-11077</a>] - Feed still has fallback code for global announcement with forum_id = 0</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11086">PHPBB3-11086</a>] - Database Updater still relies on cache factory - needs to be updated to use DIC</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11089">PHPBB3-11089</a>] - Database type mysql sets unusable board</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11092">PHPBB3-11092</a>] - phpbb_gen_download_links strict standards errors</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11095">PHPBB3-11095</a>] - Jumpbox should use "get" method</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11099">PHPBB3-11099</a>] - Clicking Banning tab in MCP causes all tabs to collapse down</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11100">PHPBB3-11100</a>] - jabber::can_use_ssl() should not be called statically in includes/acp/acp_jabber.php on line 124</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11101">PHPBB3-11101</a>] - Container processors are executed before globals exist</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11106">PHPBB3-11106</a>] - Undefined index: EDITED_TIME_TOTAL</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11139">PHPBB3-11139</a>] - Colour swatch window with Fatal error</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11140">PHPBB3-11140</a>] - MCP Front errors on reported posts</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11154">PHPBB3-11154</a>] - Unable to upgrade 3.0 QI-installed board to 3.1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11157">PHPBB3-11157</a>] - Strict spam renders spambot countermeasures page unusable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11159">PHPBB3-11159</a>] - Coding guidelines: static public</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11166">PHPBB3-11166</a>] - AJAX confirm box is not using custom templates given</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11171">PHPBB3-11171</a>] - Copy bbcode fields, etc. for reported posts</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11176">PHPBB3-11176</a>] - Functional tests do not run</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11177">PHPBB3-11177</a>] - Postgres search when query has only negation</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11187">PHPBB3-11187</a>] - Functional tests broken by new config class</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11188">PHPBB3-11188</a>] - postgres search result count does not get the total count</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11190">PHPBB3-11190</a>] - Functional tests do not clear the cache between each test</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11194">PHPBB3-11194</a>] - PHP Notice: Undefined index "tag" </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11198">PHPBB3-11198</a>] - AJAX move up/down links not replaced correctly</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11199">PHPBB3-11199</a>] - Cache purge should remove dumped container</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11200">PHPBB3-11200</a>] - Container construction fails with non-MySQLi drivers</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11204">PHPBB3-11204</a>] - Wrong indentation in functional test case base class</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11205">PHPBB3-11205</a>] - Merge conflict in readme.html</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11206">PHPBB3-11206</a>] - Avatars are broken, includes non-existent files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11208">PHPBB3-11208</a>] - Functional tests are broken</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11209">PHPBB3-11209</a>] - Always clone Ajax disable images to avoid problems if they are used multiple times on the same page</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11211">PHPBB3-11211</a>] - Call to undefined function phpbb_real_path() in /phpBB/includes/di/extension/ext.php on line 52</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11212">PHPBB3-11212</a>] - Catch non-existent globals if error occurs during container construction</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11213">PHPBB3-11213</a>] - Missing global in install_update.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11227">PHPBB3-11227</a>] - @return void -> @return null</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11236">PHPBB3-11236</a>] - Prune users requires group selection if any groups are defined</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11237">PHPBB3-11237</a>] - php spam when pruning users</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11247">PHPBB3-11247</a>] - php spam in flock class</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11248">PHPBB3-11248</a>] - CRLF line endings</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11253">PHPBB3-11253</a>] - Signature module acl is not going to be added to 3.1 boards</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11256">PHPBB3-11256</a>] - Unused service controller.route_collection</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11257">PHPBB3-11257</a>] - Using Service Collection requires set_name() method to exist</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11263">PHPBB3-11263</a>] - PHP Notice: in file functions_messenger.php on line 213: Undefined variable: extension_manager</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11273">PHPBB3-11273</a>] - Missing space after Sphinx "Indexer memory limit" input box </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11277">PHPBB3-11277</a>] - User DST column is not removed on update, and therefor user_timezone is updated everytime the update file is run</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11279">PHPBB3-11279</a>] - "Something went wrong when processing your request." is not acceptable language</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11291">PHPBB3-11291</a>] - "Could not open input file: ../composer.phar" error during phing's create-package</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11298">PHPBB3-11298</a>] - ACP_EXTENSIONS_MANAGEMENT missing string</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11302">PHPBB3-11302</a>] - No timezone is selected by default in registration form</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11303">PHPBB3-11303</a>] - Timezone selection is not preserved in registration form</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11305">PHPBB3-11305</a>] - Installer is broken on develop</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11309">PHPBB3-11309</a>] - phpbb_extension_interface::disable_step correct docblock</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11310">PHPBB3-11310</a>] - CSRF in style installation in acp</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11311">PHPBB3-11311</a>] - Include javascript core.js file in subsilver2 overall_footer.html</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11313">PHPBB3-11313</a>] - Typo in alt_text callback breaks replacement of text</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11320">PHPBB3-11320</a>] - Database test cases fail if functions file is not included and config file exists</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11321">PHPBB3-11321</a>] - Recreate schema files with develop/create_schema_files.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11323">PHPBB3-11323</a>] - Not possible to define template variable with other variables</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11329">PHPBB3-11329</a>] - Color values should be in colours.css, not buttons.css</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11334">PHPBB3-11334</a>] - Controller helper url() method still generates URLs like app.php/route/to/page instead of app.php?controller=route/to/page</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11335">PHPBB3-11335</a>] - Hook finder fails to load hooks</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11342">PHPBB3-11342</a>] - Marking subforums as read does not change the unread icons of active topics</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11344">PHPBB3-11344</a>] - ACP_STYLE_COMPONENTS</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11345">PHPBB3-11345</a>] - Font size on new buttons is too thin</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11350">PHPBB3-11350</a>] - $db should not be passed by reference to db_tools</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11362">PHPBB3-11362</a>] - Resource locator does not find admin template files from extensions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11363">PHPBB3-11363</a>] - Migrations module tool does not load info files from extensions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11367">PHPBB3-11367</a>] - Migrator throws error if migrations table does not exist</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11369">PHPBB3-11369</a>] - Reverting migration throws error (attempt to unserialize string)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11370">PHPBB3-11370</a>] - Effectively installed migrations not inserted into migrations table</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11372">PHPBB3-11372</a>] - Migrator should only check if effectively installed if the migration is not installed at all</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11381">PHPBB3-11381</a>] - Finder cannot find items for non-enabled extensions (required during installation)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11383">PHPBB3-11383</a>] - Uninstalling an extension that adds a module causes an error upon purge</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11385">PHPBB3-11385</a>] - get_module_infos from migrator does not return module info</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11386">PHPBB3-11386</a>] - Migrator can include files multiple times</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11387">PHPBB3-11387</a>] - Module add tool logs module as added even if it fails due to error (migrations)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11388">PHPBB3-11388</a>] - Extension CSS files are not being auto-loaded</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11394">PHPBB3-11394</a>] - Migration Tools are too strict</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11395">PHPBB3-11395</a>] - acp_modules::get_module_infos can include files multiple times</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11396">PHPBB3-11396</a>] - insert_migration also updates migration (should rename function)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11398">PHPBB3-11398</a>] - Migrations permission tool's method permission_set causes fatal error</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11400">PHPBB3-11400</a>] - Notification system assumes email is always available</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11402">PHPBB3-11402</a>] - Undefined offset 0 post/topic_in_queue (notifications)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11403">PHPBB3-11403</a>] - Multiinsert for notifications should use batches</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11404">PHPBB3-11404</a>] - Can not access ACP "manage group" page while creating new groups</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11405">PHPBB3-11405</a>] - Users that are subscribed to a forum, don't receive notifications for new replies</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11407">PHPBB3-11407</a>] - UI notifications have wrong <dfn> info next to checkbox</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11408">PHPBB3-11408</a>] - Undefined index jabber (should be user_jabber)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11411">PHPBB3-11411</a>] - Broken primary key on phpbb_notification_types table</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11413">PHPBB3-11413</a>] - phpbb_notification_types table should have an integer primary key</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11415">PHPBB3-11415</a>] - Accessing phpbb_migrations table from index page (or other pages)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11416">PHPBB3-11416</a>] - Primary key on phpbb_notifications table too small</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11417">PHPBB3-11417</a>] - Notification Options page in User Control Panel has "Mark read" as submit button.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11420">PHPBB3-11420</a>] - Notification methods are not (correctly) imported</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11421">PHPBB3-11421</a>] - Submit button missing from UCP notifications module</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11422">PHPBB3-11422</a>] - Assets should be incremented on database update</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11423">PHPBB3-11423</a>] - Email has HTML from username</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11433">PHPBB3-11433</a>] - Loading alert message is shown beneath overlay</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11435">PHPBB3-11435</a>] - Extension template files curly braces bug</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11437">PHPBB3-11437</a>] - Sphinx debug assert failed when no search results are found</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11438">PHPBB3-11438</a>] - Sphinx default config does not work properly</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11439">PHPBB3-11439</a>] - Notification tests are not run via phpunit.xml.dist</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11440">PHPBB3-11440</a>] - Mixed type (string vs integer) in SQL query against phpbb_users</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11442">PHPBB3-11442</a>] - AJAX in the ACP Does not work wherever Confirm Box modals are used</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11443">PHPBB3-11443</a>] - Two migration tests are not run via phpunit.xml.dist </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11448">PHPBB3-11448</a>] - phpbb_notification_manager::mark_notifications_read takes $user_id as a parameter but isn't using it</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11450">PHPBB3-11450</a>] - phpbb_extension_metadata_manager has wrong docs and too many arguments</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11451">PHPBB3-11451</a>] - class phpbb_notification_method_jabber extends phpbb_notification_method_email</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11452">PHPBB3-11452</a>] - phpbb_notification_method_email::is_available() should return false when user doesn't have an email address</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11454">PHPBB3-11454</a>] - Jabber notifications are not working at all</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11455">PHPBB3-11455</a>] - Sort phpBB/config/tables.yml in alphabetic order</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11457">PHPBB3-11457</a>] - class phpbb_notification_test should not require/use the global set_var() function</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11460">PHPBB3-11460</a>] - New installs have wrong data in phpbb_user_notifications table.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11464">PHPBB3-11464</a>] - Config table load_cpf_pm is missing on new install</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11466">PHPBB3-11466</a>] - phpunit configs excludes non-existant files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11471">PHPBB3-11471</a>] - Some email templates contain unrelated text</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11474">PHPBB3-11474</a>] - "Post in queue" notification send to too many moderators</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11478">PHPBB3-11478</a>] - Daylight Savingtime changes old posts in time, too.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11479">PHPBB3-11479</a>] - Can not access install/index.php?mode=update</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11485">PHPBB3-11485</a>] - migration doesn't add necessary columns to phpbb_styles table when updating schemas.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11488">PHPBB3-11488</a>] - Notification email error</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11489">PHPBB3-11489</a>] - Change forum list layout to work at any resolution</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11491">PHPBB3-11491</a>] - Functional test for extensions has wrong class name and is in the wrong directory</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11492">PHPBB3-11492</a>] - memberlist user_ids array uninitalized can lead to error</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11494">PHPBB3-11494</a>] - Fix memberlist leaders functional tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11501">PHPBB3-11501</a>] - Fix "This test did not perform any assertions" message on some tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11503">PHPBB3-11503</a>] - Implementation of DB drivers vary too much</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11516">PHPBB3-11516</a>] - .live() deprecated in new version of jquery</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11535">PHPBB3-11535</a>] - ACP und UCP avatar groups settings do not display an error upon submitting incorrect data</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11549">PHPBB3-11549</a>] - Resource locator does not find admin template files from extensions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11550">PHPBB3-11550</a>] - Functional extension controller test should use $helpers to copy and remove files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11551">PHPBB3-11551</a>] - ACP System tab errors: [phpBB Debug] - PHP Notice: in file [ROOT] -/includes/acp/acp_update.php on line 49: Undefined offset: 1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11553">PHPBB3-11553</a>] - Links list errors</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11554">PHPBB3-11554</a>] - forum_fn.js should be moved to footer</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11555">PHPBB3-11555</a>] - Pagination page selection JS is broken</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11556">PHPBB3-11556</a>] - Remove non-jquery fallback code from forum_fn.js</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11560">PHPBB3-11560</a>] - Missing T_JQUERY_LINK template variable in installer</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11561">PHPBB3-11561</a>] - Notification functional tests fail using phpunit.xml.all</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11562">PHPBB3-11562</a>] - forum_fn.js cleanup</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11563">PHPBB3-11563</a>] - Move subPanels() code from html templates to forum_fn.js</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11564">PHPBB3-11564</a>] - Notifications list errors</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11567">PHPBB3-11567</a>] - Fatal error at database update</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11569">PHPBB3-11569</a>] - Database update fails at continuing on some environments</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11570">PHPBB3-11570</a>] - No way to get back to update routine when in database updater</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11573">PHPBB3-11573</a>] - Test Suite does not work with MySQL STRICT_TRANS_TABLES (MySQL 5.6)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11574">PHPBB3-11574</a>] - Unable to "auto update" from 3.0 to 3.1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11585">PHPBB3-11585</a>] - Strict Standars error when editing the role </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11586">PHPBB3-11586</a>] - Fix/cleanup some of upload_attachment()'s code</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11587">PHPBB3-11587</a>] - Group gets removed from legend when editing one in UCP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11593">PHPBB3-11593</a>] - filter->compile_var_tags uses undefined variable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11594">PHPBB3-11594</a>] - Template filter not aware of extension context</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11599">PHPBB3-11599</a>] - Tree tests are very slow</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11602">PHPBB3-11602</a>] - Do not call avatar_manager's localize_errors() if avatars are disabled</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11605">PHPBB3-11605</a>] - Order of files and directories given to phpbb_test_case_helpers->remove_files() matters.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11622">PHPBB3-11622</a>] - Template events are loaded incorrectly</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11647">PHPBB3-11647</a>] - URLs are incorrectly handled by INCLUDEJS</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11660">PHPBB3-11660</a>] - Bootstrap container from config.php bugs</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11664">PHPBB3-11664</a>] - Creating php.html file in root path in tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11665">PHPBB3-11665</a>] - Can't change file names already sent to set_filenames</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11675">PHPBB3-11675</a>] - Uncaught exception 'Twig_Error_Syntax' -Permissions User roles- </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11687">PHPBB3-11687</a>] - assets_version is missing in phpbb_config</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11688">PHPBB3-11688</a>] - Cache purge does not purge the twig directory</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11691">PHPBB3-11691</a>] - Soft delete migration conversion should be staggered</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11692">PHPBB3-11692</a>] - Don't update search_type in dev migration if already appended with phpbb_search_</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11694">PHPBB3-11694</a>] - Twig Error on ACP Login page</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11695">PHPBB3-11695</a>] - Cannot edit first post in a topic more than once without manually changing "Options Per User" to 1 on second edit.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11696">PHPBB3-11696</a>] - phpbb_db_tools does not autoload</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11697">PHPBB3-11697</a>] - fulltext_mysql.php - author_search() uses incorrect $m_approve_fid_ary parameter</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11701">PHPBB3-11701</a>] - TWIG breaks template events for events inside of looped template code</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11702">PHPBB3-11702</a>] - Forumlink gives general error</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11706">PHPBB3-11706</a>] - getimagesize() should be called with @ to prevent PHP warning in remote avatar</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11707">PHPBB3-11707</a>] - Twig DEFINE not working as expected</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11708">PHPBB3-11708</a>] - Invalid bulletin point in notifications</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11712">PHPBB3-11712</a>] - Typo in editor.js</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11713">PHPBB3-11713</a>] - Module gets removed by ajax even if removal was not successful</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11717">PHPBB3-11717</a>] - View unanswered posts = General error</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11718">PHPBB3-11718</a>] - Twig lexer only correcting statements in IF, not ELSEIF</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11723">PHPBB3-11723</a>] - Can not agree to Terms of Service if more than one language is installed</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11725">PHPBB3-11725</a>] - No Avatar image -upload avatar-</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11727">PHPBB3-11727</a>] - INCLUDECSS and INCLUDEJS incorrectly default to /template/ folder</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11728">PHPBB3-11728</a>] - Fix last occurance of topic_approved index</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11729">PHPBB3-11729</a>] - memberlist.php is empty white page</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11731">PHPBB3-11731</a>] - Make calls for captcha garbage collections non-static</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11733">PHPBB3-11733</a>] - Illegal offset type Warning in [ROOT] -/includes/auth/auth.php via [ROOT] -/feed.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11734">PHPBB3-11734</a>] - Missing permession in language file</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11735">PHPBB3-11735</a>] - Missing checkbox in User Control Panel / Manage notifications</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11739">PHPBB3-11739</a>] - Wrong name for UCP Module "Edit "Remember Me" login keys"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11741">PHPBB3-11741</a>] - Brackets exist even without any text</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11751">PHPBB3-11751</a>] - MCP Softdelete Modules missing when updating board</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11754">PHPBB3-11754</a>] - Remove leftovers of style switcher</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11755">PHPBB3-11755</a>] - MySQL Upgrader out of date for 3.1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11757">PHPBB3-11757</a>] - Typo in signature_module_auth migration</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11759">PHPBB3-11759</a>] - Migrations update to the wrong 3.0.x version numbers.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11761">PHPBB3-11761</a>] - Example.org no longer serves blank responses, failing functional tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11763">PHPBB3-11763</a>] - Debug and SQL Error when reporting a PM</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11767">PHPBB3-11767</a>] - Unable to update DB from 3.0.X to 3.1.X because of post_visibility</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11770">PHPBB3-11770</a>] - Invalid class for pm list in outbox/sentbox</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11774">PHPBB3-11774</a>] - PHP errors on viewing reported post details</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11777">PHPBB3-11777</a>] - Extension template events are not loaded from subdirectories</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11779">PHPBB3-11779</a>] - Invalid class for unapproved posts in mcp index</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11780">PHPBB3-11780</a>] - Remove unused images from prosilver</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11781">PHPBB3-11781</a>] - update_post_information() is not defined in phpbb_content_visibility->set_post_visibility</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11782">PHPBB3-11782</a>] - Notices inside posts look messy</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11791">PHPBB3-11791</a>] - Template events are not loaded in ACP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11792">PHPBB3-11792</a>] - core.user_setup event doesn't support loading language files from extensions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11796">PHPBB3-11796</a>] - Duplicate code for pagination</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11800">PHPBB3-11800</a>] - Incorrect inclusion of scripts in popup window</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11804">PHPBB3-11804</a>] - </li> tag at overall_header.html (prosilver) which was not open</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11805">PHPBB3-11805</a>] - pagination does not support controller_helper urls</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11809">PHPBB3-11809</a>] - core.js should be loaded directly after jQuery and after every other JS file</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11811">PHPBB3-11811</a>] - Chrome 30 adds outline to focused elements</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11812">PHPBB3-11812</a>] - No longer able to define empty template variable using DEFINE</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11816">PHPBB3-11816</a>] - Twig regression: parentheses in IF statements stop DEFINE variables and loop lengths from working</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11822">PHPBB3-11822</a>] - Template include asset doesn't follow namespace lookup order</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11824">PHPBB3-11824</a>] - Controller URLs do not work anymore</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11825">PHPBB3-11825</a>] - phpBB/phpbb/ should only contain classes</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11828">PHPBB3-11828</a>] - Twig DEFINE is causing errors</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11832">PHPBB3-11832</a>] - URLs in tests aren't shortened, triggering errors in Composer files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11833">PHPBB3-11833</a>] - Twig error while viewing user notes</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11835">PHPBB3-11835</a>] - phpbb_db_migration_data_310_auth_provider_oauth: A required module does not exist: UCP_AUTH_LINK</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11836">PHPBB3-11836</a>] - Manage external account associations error</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11837">PHPBB3-11837</a>] - UCP_AUTH_LINK_NOT_SUPPORTED (untranslated)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11843">PHPBB3-11843</a>] - Regression: using underscores in template DEFINE variables yields unexpected behavior</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11846">PHPBB3-11846</a>] - Empty paragraph elements in jumpbox.html</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11850">PHPBB3-11850</a>] - $user->page contains bogus data on controller (app.php) pages</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11852">PHPBB3-11852</a>] - filesystem class must not depend on a web request</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11862">PHPBB3-11862</a>] - Events core.delete_user_before and core.delete_user_after compact the wrong vars</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11865">PHPBB3-11865</a>] - includes/bbcode.php is missing namespace change</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11866">PHPBB3-11866</a>] - "You have specified an invalid dbms driver" Error with config sample</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11867">PHPBB3-11867</a>] - Schema files are not created by create_schema_files.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11868">PHPBB3-11868</a>] - Class 'phpbb_request_interface' not found</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11871">PHPBB3-11871</a>] - Extension modules are not working with namespaces anymore</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11874">PHPBB3-11874</a>] - RSS Feed -Bug Url-</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11878">PHPBB3-11878</a>] - Missing leading \ in dependencies in soft_delete_mcp_modules</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11882">PHPBB3-11882</a>] - Incorrect dependency in signature module auth migration</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11888">PHPBB3-11888</a>] - On New installation the default search backend is not shown correctly.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11890">PHPBB3-11890</a>] - Language key used when soft-deleting in MCP.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11892">PHPBB3-11892</a>] - Undefined variable: to_forum_id after cancelling merge topic/move posts</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11893">PHPBB3-11893</a>] - Font size in "Edit 'Remember Me' login keys" is large</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11895">PHPBB3-11895</a>] - Forum feed stopped working</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11898">PHPBB3-11898</a>] - Unable to login to ACP on AREA51</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11901">PHPBB3-11901</a>] - Undefined offset: 3 in file [ROOT] -/includes/functions_content.php on line 776</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11905">PHPBB3-11905</a>] - Alpha 1 Migration</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11906">PHPBB3-11906</a>] - Missing database entries "read_notification"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11908">PHPBB3-11908</a>] - class phpbb_auth_provider_oauth_service_exception not using namespaces</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11918">PHPBB3-11918</a>] - Can not update from 3.0.x to 3.1.x with MSSQL</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11919">PHPBB3-11919</a>] - Improper argument order for sql_fetchfield() in notification manager</li> +</ul> +<h4>Improvement</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-7598">PHPBB3-7598</a>] - Reminding inactive users</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-7938">PHPBB3-7938</a>] - Display information about unread and new PMs in the header.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8065">PHPBB3-8065</a>] - Add an option to lock topics while moving them.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8270">PHPBB3-8270</a>] - Automatically loaded language-files for mods</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8796">PHPBB3-8796</a>] - Mark forum(s) read (or mark topics read) marks some topics you haven't read</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9346">PHPBB3-9346</a>] - Use different message template for jabber notification</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9532">PHPBB3-9532</a>] - Optimized Page Titles</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9549">PHPBB3-9549</a>] - Enhance teampage functionality</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9596">PHPBB3-9596</a>] - Modular cron and allowing cron tasks to be run from system cron</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9608">PHPBB3-9608</a>] - Cleanse object references from codebase for 3.1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9649">PHPBB3-9649</a>] - Moderator queue does not display icon if the new post is made in old thread</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9668">PHPBB3-9668</a>] - Automatic UTF-8 normalization</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9669">PHPBB3-9669</a>] - Native UTF-8 normalization</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9684">PHPBB3-9684</a>] - Link global announcements to forums</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9693">PHPBB3-9693</a>] - generate_smilies clean up </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9716">PHPBB3-9716</a>] - Handle user input through a request class providing a more complete mechanism than request_var</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9741">PHPBB3-9741</a>] - Do not store any themes or templates in the database</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9746">PHPBB3-9746</a>] - Normalise internet protocol version 6 addresses</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9792">PHPBB3-9792</a>] - Move function definitions out of download/file.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9823">PHPBB3-9823</a>] - Move functions definitions out of adm/index.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9979">PHPBB3-9979</a>] - Autoloading for test suite</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10001">PHPBB3-10001</a>] - Class Based Forum/Topic Image</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10076">PHPBB3-10076</a>] - STARTTLS for emails</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10143">PHPBB3-10143</a>] - Delete-write-read test for config classes</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10148">PHPBB3-10148</a>] - Turn TEMPLATE_BITFIELD into an instance variable in acp_styles.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10155">PHPBB3-10155</a>] - Inclusion of jQuery</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10161">PHPBB3-10161</a>] - Use one of "email" or "e-mail"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10172">PHPBB3-10172</a>] - Display empty birthday box in prosilver when birthdays are enabled but there are none today</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10258">PHPBB3-10258</a>] - Use HTML5 doctype</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10271">PHPBB3-10271</a>] - confirm_box operations should use AJAX</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10272">PHPBB3-10272</a>] - Simple operations should use AJAX</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10273">PHPBB3-10273</a>] - Accepting / denying posts should use AJAX</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10281">PHPBB3-10281</a>] - Reordering forums in the ACP should use AJAX</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10312">PHPBB3-10312</a>] - Un-check "Leave shadow topic in place" checkbox when moving topics</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10325">PHPBB3-10325</a>] - Ability to disable the "I forgot my password" feature</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10336">PHPBB3-10336</a>] - Removing imagesets in 3.1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10344">PHPBB3-10344</a>] - Add attachment icons to list of reports and queue</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10362">PHPBB3-10362</a>] - HTML5 Fix - "name" attribute is deprecated in anchors. Use "id" attribute instead.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10383">PHPBB3-10383</a>] - Polls should use AJAX</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10387">PHPBB3-10387</a>] - generate_pagination() should export the current page number as a template variable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10390">PHPBB3-10390</a>] - Add an ACP option to use jQuery via local copy or remote CDN</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10410">PHPBB3-10410</a>] - Add option to display users in their first teampage group</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10412">PHPBB3-10412</a>] - Use memory_get_peak_usage for debug output instead of memory_get_usage</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10431">PHPBB3-10431</a>] - Remove language from the button-graphics and use text strings instead</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10438">PHPBB3-10438</a>] - Alligning the Smileys on the same line as the text.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10484">PHPBB3-10484</a>] - Use variables for sql_build_query() calls, so mods/extensions can extend the arrays</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10510">PHPBB3-10510</a>] - Quick-mod markup should be in the template</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10524">PHPBB3-10524</a>] - Wrong version code name in Ascraeus coding guidelines document.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10535">PHPBB3-10535</a>] - Remove "Confirm Email Address" field from registration form</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10557">PHPBB3-10557</a>] - Missing IN_PHPBB check in phpBB/includes/functions_acp.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10601">PHPBB3-10601</a>] - Move inbox to top module in UCP Private Messages Tab</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10614">PHPBB3-10614</a>] - Script to manage extensions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10617">PHPBB3-10617</a>] - prosilver clean up: adding proper css reset</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10619">PHPBB3-10619</a>] - prosilver clean up: removing duplicate colors</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10632">PHPBB3-10632</a>] - Merging style components</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10640">PHPBB3-10640</a>] - Bigger Topic Title Length</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10650">PHPBB3-10650</a>] - Last Topic Title on Forum list</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10659">PHPBB3-10659</a>] - Allow all administrators to purge cache</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10665">PHPBB3-10665</a>] - INCLUDEJS template tag</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10679">PHPBB3-10679</a>] - Add new permission for changing profile field information</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10705">PHPBB3-10705</a>] - Replace WARNINGS_ZERO_TOTAL with NO_WARNINGS for consistency</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10714">PHPBB3-10714</a>] - Create a class for add_log() and unit tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10726">PHPBB3-10726</a>] - Preview from Quick Reply</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10727">PHPBB3-10727</a>] - Don't hide quickreply with javascript</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10733">PHPBB3-10733</a>] - Adding file locator function to style class</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10734">PHPBB3-10734</a>] - CSS3 rounded corners</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10741">PHPBB3-10741</a>] - Automatically resize textarea</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10743">PHPBB3-10743</a>] - Change theme to style in php code</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10762">PHPBB3-10762</a>] - Separate style and phpBB version numbers in style.cfg</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10771">PHPBB3-10771</a>] - Using Remember Me instead of autologin or persistent keys in the UI.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10780">PHPBB3-10780</a>] - Move colons from template files to language files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10783">PHPBB3-10783</a>] - assets_version config var appended to assets (css/js) URLs to prevent caching</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10786">PHPBB3-10786</a>] - Render search options by default on memberlist.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10799">PHPBB3-10799</a>] - includejs should not put phpbb root path in generated template code</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10800">PHPBB3-10800</a>] - includejs test confusingly includes an html file</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10864">PHPBB3-10864</a>] - Allow extensions to be accessed via controller with shorter access name than "vendor/extname"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10933">PHPBB3-10933</a>] - Make style code more understandable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10936">PHPBB3-10936</a>] - MySQL fulltext search improvement - removing check for PCRE UTF support</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10938">PHPBB3-10938</a>] - Display subforum listing on forumlist via template loop instead of PHP implode()</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10947">PHPBB3-10947</a>] - Quickmod tools have stopped autosubmitting</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10955">PHPBB3-10955</a>] - ajaxify should take options as the only argument</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10966">PHPBB3-10966</a>] - Remove code duplication from mysql* and mssql* dbal</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10968">PHPBB3-10968</a>] - Render pagination fully within the template</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10970">PHPBB3-10970</a>] - Allow INCLUDE template macros to accept paths of the form {FOO}/a/{BAR}/c</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10972">PHPBB3-10972</a>] - Add a new method to phpbb_functional_test_case to allow a new user to be created</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10973">PHPBB3-10973</a>] - Allow mocks to be autoloaded in tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10975">PHPBB3-10975</a>] - Memberlist functional tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10990">PHPBB3-10990</a>] - $user->lang['COMMA_SEPARATOR'] - is not uniformly used</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11001">PHPBB3-11001</a>] - html5 Placeholder for search box.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11008">PHPBB3-11008</a>] - Get rid of eval in javascript</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11010">PHPBB3-11010</a>] - HTML5 input types for form fields</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11011">PHPBB3-11011</a>] - Using dependency injection for global variables in all search backends.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11012">PHPBB3-11012</a>] - Member variable phpEx vs php_ext naming inconstistency</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11013">PHPBB3-11013</a>] - Allow arrays to be assigned and retrieved in templates</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11015">PHPBB3-11015</a>] - Make DBAL classes autoloadable</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11021">PHPBB3-11021</a>] - Link back to main site config setting</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11025">PHPBB3-11025</a>] - Make Last topic title in forum list Bold</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11032">PHPBB3-11032</a>] - Better error reporting for sphinx</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11037">PHPBB3-11037</a>] - Cache drivers require globals</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11044">PHPBB3-11044</a>] - Compress class should keep track of files added and deal with conflicts</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11048">PHPBB3-11048</a>] - Use access specifiers in search backends</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11050">PHPBB3-11050</a>] - Add docblocks missing in properties and methods in all search backends.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11051">PHPBB3-11051</a>] - Add retrieval functions for all public properties in search backends</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11068">PHPBB3-11068</a>] - Hiding foes posts should use JS to display them, rather then reloading the whole page</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11070">PHPBB3-11070</a>] - Redundant background-position property in Prosilver button CSS?</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11082">PHPBB3-11082</a>] - Redis cache driver should not have executable permission</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11083">PHPBB3-11083</a>] - Abstract cache drivers should use abstract keyword</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11088">PHPBB3-11088</a>] - Combine Style and Extension Management into one Customisations tab in the ACP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11116">PHPBB3-11116</a>] - Adjust Display of Warning/Error Messages in Extensions Controller</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11129">PHPBB3-11129</a>] - Misleading subscription state messages</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11152">PHPBB3-11152</a>] - Create cached, compiled container class rather than compiling it on every page load</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11156">PHPBB3-11156</a>] - Delete "Misc" tab of forum based permissions + move items</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11174">PHPBB3-11174</a>] - Unit tests for search backends</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11181">PHPBB3-11181</a>] - Bump PHP requirement to 5.3.3</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11183">PHPBB3-11183</a>] - Remove $load_extensions and weird dl() calls</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11189">PHPBB3-11189</a>] - Merge DEBUG and DEBUG_EXTRA</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11193">PHPBB3-11193</a>] - Generalize phpbb_di_pass_collection_pass to handle all collections using service tags</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11197">PHPBB3-11197</a>] - Prefix the css classes for the small arrow with "arrow".</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11202">PHPBB3-11202</a>] - Add response status checks to functional tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11215">PHPBB3-11215</a>] - Separate root path for filesystem and urls/assets</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11217">PHPBB3-11217</a>] - Prefix for template values to give back value URL encoded</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11238">PHPBB3-11238</a>] - Specify goutte version</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11250">PHPBB3-11250</a>] - Remake the unit tests for the BBCode parser.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11259">PHPBB3-11259</a>] - Make $phpbb_admin_path available everywhere</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11268">PHPBB3-11268</a>] - Delete phpbb_db_driver_mysql4 case</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11275">PHPBB3-11275</a>] - editor.js::colorPalette() breaks page with document.write > add proper target</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11283">PHPBB3-11283</a>] - Extensions as symlinks</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11294">PHPBB3-11294</a>] - Update extension list in running tests doc</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11306">PHPBB3-11306</a>] - Container should be created by a phpbb_create_default_container() function</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11314">PHPBB3-11314</a>] - Improve readability and code cleanup in new JavaScript files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11328">PHPBB3-11328</a>] - New language variables for buttons</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11373">PHPBB3-11373</a>] - Notifications - Purge old with cron</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11390">PHPBB3-11390</a>] - Remove pagination from ucp_notifications.html when list is empty.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11393">PHPBB3-11393</a>] - Give more information on database_updater about what exactly happened</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11409">PHPBB3-11409</a>] - No feedback provided when updating group position settings in ACP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11458">PHPBB3-11458</a>] - Automatically add extension permission language files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11461">PHPBB3-11461</a>] - [Template Event] - viewtopic_body_footer</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11463">PHPBB3-11463</a>] - Add topic title attribute in search results</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11477">PHPBB3-11477</a>] - Allow customisation of "Board index"</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11482">PHPBB3-11482</a>] - Extend syntax for DEFINE tag</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11495">PHPBB3-11495</a>] - Add nested sets implementation to phpBB core</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11519">PHPBB3-11519</a>] - Rename test event template file</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11533">PHPBB3-11533</a>] - Notification settings page is using topiclist class incorrectly</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11557">PHPBB3-11557</a>] - Allow to use tab when typing code and keep indentation</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11558">PHPBB3-11558</a>] - Notifications link in header should not include [ and ] -</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11577">PHPBB3-11577</a>] - Topiclist/Forumlist Needs tweaking after PR 1331</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11582">PHPBB3-11582</a>] - Split permission logic from translations</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11600">PHPBB3-11600</a>] - Increase code test coverage of avatar manager</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11606">PHPBB3-11606</a>] - make_clickable() in includes/functions_content.php uses deprecated preg_replace() /e modifier (PREG_REPLACE_EVAL)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11615">PHPBB3-11615</a>] - Partial refactoring of session tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11620">PHPBB3-11620</a>] - Improve session test coverage</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11621">PHPBB3-11621</a>] - Improve MySQL fulltext search indexes</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11651">PHPBB3-11651</a>] - Bootstrap container from config.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11667">PHPBB3-11667</a>] - phpbb_template_twig_node_includeasset should be abstract</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11669">PHPBB3-11669</a>] - Fix PHP bug #55124 (/./ in recursive mkdirs)</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11684">PHPBB3-11684</a>] - No utility to time-wasting user login confirmation message/screen</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11685">PHPBB3-11685</a>] - No utility to time-wasting user logout confirmation message/screen </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11700">PHPBB3-11700</a>] - Use namespaces rather than prefixes for class names</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11703">PHPBB3-11703</a>] - Make "Serve jQuery using Google’s CDN" generic</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11724">PHPBB3-11724</a>] - Support "ELSE IF" and "ELSEIF" in the same way</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11744">PHPBB3-11744</a>] - Group join request notification</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11745">PHPBB3-11745</a>] - Group join approved notification</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11747">PHPBB3-11747</a>] - UCP Prefs Core and Template Events</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11749">PHPBB3-11749</a>] - PHP and Template Event Requests for Topic Preview Extension</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11784">PHPBB3-11784</a>] - Remove naming redundancy for event listeners</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11786">PHPBB3-11786</a>] - Fix various defects in PHPDoc in-code documentation</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11795">PHPBB3-11795</a>] - Move all JavaScript from HTML code to external files</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11813">PHPBB3-11813</a>] - Mock authentication provider should implement base provider class</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11831">PHPBB3-11831</a>] - Update fabpot/goutte to 1.0.*</li> +</ul> +<h4>New Feature</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9498">PHPBB3-9498</a>] - External Avatar sources: Gravatar</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9550">PHPBB3-9550</a>] - Introduce new Event System</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9558">PHPBB3-9558</a>] - Use PHP timezone handling abilities</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9627">PHPBB3-9627</a>] - Resume support for attachments / HTTP range support</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9647">PHPBB3-9647</a>] - Ability to delete auto login keys from UCP</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9657">PHPBB3-9657</a>] - Soft Delete Posts and Topics </li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9721">PHPBB3-9721</a>] - Attachments management</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9726">PHPBB3-9726</a>] - Improved template engine</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9730">PHPBB3-9730</a>] - PostgreSQL Fulltext Search</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9737">PHPBB3-9737</a>] - Migrations</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9790">PHPBB3-9790</a>] - Support for X-Accel-Redirect and X-Sendfile headers for attachment downloads</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10018">PHPBB3-10018</a>] - Refactor Avatars to support custom modules</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10270">PHPBB3-10270</a>] - JavaScript - confirm / alert / input popups</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10323">PHPBB3-10323</a>] - Extensions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10328">PHPBB3-10328</a>] - There should be a way to send JSON</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10345">PHPBB3-10345</a>] - Support for arbitrary number of plural forms in language packs</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10411">PHPBB3-10411</a>] - Create grouping capability for custom ordered team page</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10586">PHPBB3-10586</a>] - Front-facing file in Extensions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10600">PHPBB3-10600</a>] - When creating a report for a post, copy the post itself</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10631">PHPBB3-10631</a>] - Extensions Admin</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10739">PHPBB3-10739</a>] - Dependency Injection Container</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10929">PHPBB3-10929</a>] - Improves the attachment uploader to use HTML5 features</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10931">PHPBB3-10931</a>] - Add a wrapper class for ini_get()</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10942">PHPBB3-10942</a>] - Add sql_case() and sql_concatenate() to dbal</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10946">PHPBB3-10946</a>] - Sphinx Search Backend integration</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11042">PHPBB3-11042</a>] - Feature to download all attachments in a post and topic.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11103">PHPBB3-11103</a>] - Notifications system</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11175">PHPBB3-11175</a>] - Add microdata to breadcrumbs</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11469">PHPBB3-11469</a>] - Add SQL insert buffer class</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11598">PHPBB3-11598</a>] - Replace template engine with Twig</li> +</ul> +<h4>Sub-task</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9556">PHPBB3-9556</a>] - Drop php closing tags</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9574">PHPBB3-9574</a>] - Drop fallback implementations</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9688">PHPBB3-9688</a>] - update_session API</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9738">PHPBB3-9738</a>] - Make installer and updater use migrations</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9797">PHPBB3-9797</a>] - Adjust existing access to superglobals</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10817">PHPBB3-10817</a>] - Use valid composer.json instead of non-standard extension.json</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10992">PHPBB3-10992</a>] - Use updated Goutte in Fileupload tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11109">PHPBB3-11109</a>] - Create a separate set of compress tests for the develop branch</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11243">PHPBB3-11243</a>] - Topics with attachments only show "download all attachments" links on pages containing attachments.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11318">PHPBB3-11318</a>] - Extensions use migrations</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11351">PHPBB3-11351</a>] - Add appropriate language strings for errors</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11531">PHPBB3-11531</a>] - Add functional tests for new avatar system</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11637">PHPBB3-11637</a>] - generate_text_for_display on search.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11638">PHPBB3-11638</a>] - generate_text_for_display on viewtopic.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11639">PHPBB3-11639</a>] - generate_text_for_display on includes/functions_posting.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11640">PHPBB3-11640</a>] - generate_text_for_display on includes/functions_privmsgs.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11641">PHPBB3-11641</a>] - generate_text_for_display on includes/mcp/mcp_pm_reports.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11642">PHPBB3-11642</a>] - generate_text_for_display on includes/mcp/mcp_post.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11643">PHPBB3-11643</a>] - generate_text_for_display on includes/mcp/mcp_queue.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11653">PHPBB3-11653</a>] - generate_text_for_display on includes/mcp/mcp_topic.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11654">PHPBB3-11654</a>] - generate_text_for_display on includes/mcp/mcp_warn.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11655">PHPBB3-11655</a>] - generate_text_for_display on includes/ucp/ucp_pm_viewmessage.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11656">PHPBB3-11656</a>] - generate_text_for_display on memberlist.php</li> +</ul> +<h4>Task</h4> +<ul> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-7090">PHPBB3-7090</a>] - Update minimum PHP version to 5.2</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9557">PHPBB3-9557</a>] - Update coding guidelines for 3.1 and PHP >= 5.2</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9682">PHPBB3-9682</a>] - Add a class loader for auto loading and define naming rules for new phpbb classes</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9783">PHPBB3-9783</a>] - Restore subsilver2</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9867">PHPBB3-9867</a>] - Adjust the implementation of error messages localization</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9983">PHPBB3-9983</a>] - Restructure ACM classes</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9988">PHPBB3-9988</a>] - Replace config with an instance of a class implementing ArrayAccess</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10091">PHPBB3-10091</a>] - Bump minimum required postgresql version for 3.1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10173">PHPBB3-10173</a>] - Move birthday list logic into templates</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10202">PHPBB3-10202</a>] - Provide a mechanism to manually retrieve long configuration options from a TEXT column</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10260">PHPBB3-10260</a>] - Remove prosilver styleswitcher</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10314">PHPBB3-10314</a>] - Whitelist all files in includes for code coverage reports</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10389">PHPBB3-10389</a>] - JSON extension should be checked in the installer</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10414">PHPBB3-10414</a>] - Functional testing</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10467">PHPBB3-10467</a>] - Check extensions diff for classes/constants not existing in php 5.2</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10609">PHPBB3-10609</a>] - Prefix phpBB functions with phpbb_ to prevent compatibility issues with other software</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10670">PHPBB3-10670</a>] - Require PHP 5.3 at minimum for phpBB 3.1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10680">PHPBB3-10680</a>] - Add ext/ to .gitignore</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10688">PHPBB3-10688</a>] - Change 3.0 language to 3.1</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10693">PHPBB3-10693</a>] - Change minimum PHP version for Ascraeus to 5.3.2</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10719">PHPBB3-10719</a>] - Remove second 5.2 test suite on ascreaus</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10732">PHPBB3-10732</a>] - Add config_dev.php and config_test.php to .gitignore</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10855">PHPBB3-10855</a>] - Coding guideline change - have curly brackets on same line in JS</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10869">PHPBB3-10869</a>] - Remove PHP 5.2 check from .travis.yml</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10877">PHPBB3-10877</a>] - Have bamboo generate and publish a phpBB package for every build.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10882">PHPBB3-10882</a>] - Expand test coverage for template engine - add tests for invalid constructs</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10893">PHPBB3-10893</a>] - Update the Usage of Composer</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10909">PHPBB3-10909</a>] - Update Travis Test Configuration: Travis no longer supports PHP 5.3.2</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10932">PHPBB3-10932</a>] - Store composer.phar in the phpBB repository to make sure a working version is always available</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10939">PHPBB3-10939</a>] - Modify the phpbb_request class to handle the $_FILES superglobal as well</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10941">PHPBB3-10941</a>] - Write tests for includes/functions_upload.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10944">PHPBB3-10944</a>] - Allow INCLUDEJS to include javascript from the assets directory</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10949">PHPBB3-10949</a>] - 3.1 AJAX code should use new coding guidelines</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10963">PHPBB3-10963</a>] - Use fileinfo in filespec::is_image() instead of trusting the mimetype sent by the browser</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10969">PHPBB3-10969</a>] - Remove remove_comments() and remove_remarks()</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10993">PHPBB3-10993</a>] - Update README to use composer.phar from the repository</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10994">PHPBB3-10994</a>] - Revert changes in PHPBB3-10963</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11054">PHPBB3-11054</a>] - Improper @var documentation syntax in includes/extension/controller.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11061">PHPBB3-11061</a>] - Fix README composer instructions</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11195">PHPBB3-11195</a>] - Put conditional opening brace on its own line, as per guidelines</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11225">PHPBB3-11225</a>] - Delete subsilver2 mcp_jumpbox.html</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11287">PHPBB3-11287</a>] - Add Template Event naming guidelines to docs/coding-guidelines.html</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11338">PHPBB3-11338</a>] - Enable Redis tests on Travis</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11441">PHPBB3-11441</a>] - Refactor phpbb_user_loader tests</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11476">PHPBB3-11476</a>] - Remove pass-by-reference from phpbb_db_driver::sql_multi_insert</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11481">PHPBB3-11481</a>] - Feed classes are currently all in feed.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11698">PHPBB3-11698</a>] - Move all autoloadable files to phpbb/ rather than includes/</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11722">PHPBB3-11722</a>] - Remove reference assignment for $captcha in report.php</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11760">PHPBB3-11760</a>] - 3.0.x Migration should use the phpbb_version_compare() wrapper.</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11818">PHPBB3-11818</a>] - Upgrade Symfony to 2.3 LTS</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11870">PHPBB3-11870</a>] - No longer exclude ./phpBB/phpbb/search/fulltext_*.php from code coverage</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11885">PHPBB3-11885</a>] - Add migrations for 3.0.12-RCx and 3.0.12</li> +<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11913">PHPBB3-11913</a>] - Apply reorganisation of download.phpbb.com to build_announcement.php</li> +</ul> + + <a name="v3011"></a><h3>1.vi. Changes since 3.0.11</h3> <h4>Bug</h4> <ul> @@ -241,7 +1326,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11753">PHPBB3-11753</a>] - Upgrade mysql_upgrader.php schema data.</li> </ul> - <a name="v3010"></a><h3>1.ii. Changes since 3.0.10</h3> + <a name="v3010"></a><h3>1.vii. Changes since 3.0.10</h3> <h4>Bug</h4> <ul> @@ -366,7 +1451,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10909">PHPBB3-10909</a>] - Update Travis Test Configuration: Travis no longer supports PHP 5.3.2</li> </ul> - <a name="v309"></a><h3>1.iii. Changes since 3.0.9</h3> + <a name="v309"></a><h3>1.viii. Changes since 3.0.9</h3> <h4>Bug</h4> <ul> @@ -502,7 +1587,7 @@ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10480">PHPBB3-10480</a>] - Automate changelog building</li> </ul> - <a name="v308"></a><h3>1.iv. Changes since 3.0.8</h3> + <a name="v308"></a><h3>1.ix. Changes since 3.0.8</h3> <h4> Bug </h4> @@ -870,7 +1955,7 @@ </ul> - <a name="v307-PL1"></a><h3>1.v. Changes since 3.0.7-PL1</h3> + <a name="v307-PL1"></a><h3>1.x. Changes since 3.0.7-PL1</h3> <h4> Security </h4> <ul> @@ -1328,13 +2413,13 @@ </ul> - <a name="v307"></a><h3>1.vi. Changes since 3.0.7</h3> + <a name="v307"></a><h3>1.xi. Changes since 3.0.7</h3> <ul> <li>[Sec] Do not expose forum content of forums with ACL entries but no actual permission in ATOM Feeds. (Bug #58595)</li> </ul> - <a name="v306"></a><h3>1.vii. Changes since 3.0.6</h3> + <a name="v306"></a><h3>1.xii. Changes since 3.0.6</h3> <ul> <li>[Fix] Allow ban reason and length to be selected and copied in ACP and subsilver2 MCP. (Bug #51095)</li> @@ -1438,7 +2523,7 @@ </ul> - <a name="v305"></a><h3>1.viii. Changes since 3.0.5</h3> + <a name="v305"></a><h3>1.xiii. Changes since 3.0.5</h3> <ul> <li>[Fix] Allow whitespaces in avatar gallery names. (Bug #44955)</li> @@ -1660,7 +2745,7 @@ <li>[Feature] Send anonymous statistical information to phpBB on installation and update (optional).</li> </ul> - <a name="v304"></a><h3>1.ix. Changes since 3.0.4</h3> + <a name="v304"></a><h3>1.xiv. Changes since 3.0.4</h3> <ul> <li>[Fix] Delete user entry from ban list table upon user deletion (Bug #40015 - Patch by TerraFrost)</li> @@ -1749,7 +2834,7 @@ <li>[Sec] Only use forum id supplied for posting if global announcement detected. (Reported by nickvergessen)</li> </ul> - <a name="v303"></a><h3>1.x. Changes since 3.0.3</h3> + <a name="v303"></a><h3>1.xv. Changes since 3.0.3</h3> <ul> <li>[Fix] Allow mixed-case template directories to be inherited (Bug #36725)</li> @@ -1781,7 +2866,7 @@ <li>[Sec] Ask for forum password if post within passworded forum quoted in private message. (Reported by nickvergessen)</li> </ul> - <a name="v302"></a><h3>1.xi. Changes since 3.0.2</h3> + <a name="v302"></a><h3>1.xvi. Changes since 3.0.2</h3> <ul> <li>[Fix] Correctly set topic starter if first post in topic removed (Bug #30575 - Patch by blueray2048)</li> @@ -1880,7 +2965,7 @@ <li>[Sec Precaution] Stricter validation of the HTTP_HOST header (Thanks to Techie-Micheal et al for pointing out possible issues in derived code)</li> </ul> - <a name="v301"></a><h3>1.xii. Changes since 3.0.1</h3> + <a name="v301"></a><h3>1.xvii. Changes since 3.0.1</h3> <ul> <li>[Fix] Ability to set permissions on non-mysql dbms (Bug #24955)</li> @@ -1928,7 +3013,7 @@ <li>[Sec] Only allow urls gone through redirect() being used within login_box(). (thanks nookieman)</li> </ul> - <a name="v300"></a><h3>1.xiii Changes since 3.0.0</h3> + <a name="v300"></a><h3>1.xviii. Changes since 3.0.0</h3> <ul> <li>[Change] Validate birthdays (Bug #15004)</li> @@ -1999,7 +3084,7 @@ <li>[Fix] Find and display colliding usernames correctly when converting from one database to another (Bug #23925)</li> </ul> - <a name="v30rc8"></a><h3>1.xiv. Changes since 3.0.RC8</h3> + <a name="v30rc8"></a><h3>1.xix. Changes since 3.0.RC8</h3> <ul> <li>[Fix] Cleaned usernames contain only single spaces, so "a_name" and "a__name" are treated as the same name (Bug #15634)</li> @@ -2008,7 +3093,7 @@ <li>[Fix] Call garbage_collection() within database updater to correctly close connections (affects Oracle for example)</li> </ul> - <a name="v30rc7"></a><h3>1.xv. Changes since 3.0.RC7</h3> + <a name="v30rc7"></a><h3>1.xx. Changes since 3.0.RC7</h3> <ul> <li>[Fix] Fixed MSSQL related bug in the update system</li> @@ -2043,7 +3128,7 @@ <li>[Fix] No duplication of active topics (Bug #15474)</li> </ul> - <a name="v30rc6"></a><h3>1.xvi. Changes since 3.0.RC6</h3> + <a name="v30rc6"></a><h3>1.xxi. Changes since 3.0.RC6</h3> <ul> <li>[Fix] Submitting language changes using acp_language (Bug #14736)</li> @@ -2053,7 +3138,7 @@ <li>[Fix] Able to request new password (Bug #14743)</li> </ul> - <a name="v30rc5"></a><h3>1.xvii. Changes since 3.0.RC5</h3> + <a name="v30rc5"></a><h3>1.xxii. Changes since 3.0.RC5</h3> <ul> <li>[Feature] Removing constant PHPBB_EMBEDDED in favor of using an exit_handler(); the constant was meant to achive this more or less.</li> @@ -2116,7 +3201,7 @@ <li>[Sec] New password hashing mechanism for storing passwords (#i42)</li> </ul> - <a name="v30rc4"></a><h3>1.xviii. Changes since 3.0.RC4</h3> + <a name="v30rc4"></a><h3>1.xxiii. Changes since 3.0.RC4</h3> <ul> <li>[Fix] MySQL, PostgreSQL and SQLite related database fixes (Bug #13862)</li> @@ -2167,7 +3252,7 @@ <li>[Fix] odbc_autocommit causing existing result sets to be dropped (Bug #14182)</li> </ul> - <a name="v30rc3"></a><h3>1.xix. Changes since 3.0.RC3</h3> + <a name="v30rc3"></a><h3>1.xxiv. Changes since 3.0.RC3</h3> <ul> <li>[Fix] Fixing some subsilver2 and prosilver style issues</li> @@ -2276,7 +3361,7 @@ </ul> - <a name="v30rc2"></a><h3>1.xx. Changes since 3.0.RC2</h3> + <a name="v30rc2"></a><h3>1.xxv. Changes since 3.0.RC2</h3> <ul> <li>[Fix] Re-allow searching within the memberlist</li> @@ -2322,7 +3407,7 @@ </ul> - <a name="v30rc1"></a><h3>1.xxi. Changes since 3.0.RC1</h3> + <a name="v30rc1"></a><h3>1.xxvi. Changes since 3.0.RC1</h3> <ul> <li>[Fix] (X)HTML issues within the templates (Bug #11255, #11255)</li> diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html index 937568cf10..01eeea6540 100644 --- a/phpBB/docs/INSTALL.html +++ b/phpBB/docs/INSTALL.html @@ -132,6 +132,7 @@ <li>A SQL database system, <strong>one of</strong>: <ul> <li>MySQL 3.23 or above (MySQLi supported)</li> + <li>MariaDB 5.1 or above</li> <li>PostgreSQL 8.3+</li> <li>SQLite 2.8.2+ (SQLite 3 is not supported)</li> <li>Firebird 2.1+</li> diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index 899ca64fb5..27ace05169 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -323,7 +323,7 @@ <p>Please remember that running any application on a development (unstable, e.g. a beta release) version of PHP can lead to strange/unexpected results which may appear to be bugs in the application. Therefore, we recommend you upgrade to the newest stable version of PHP before running phpBB3. If you are running a development version of PHP please check any bugs you find on a system running a stable release before submitting.</p> - <p>This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MSSQL Server 2000, PostgreSQL 8.x, Oracle 8, SQLite 2 and Firebird. Versions of PHP used range from 5.3.x to 5.4.x without problem.</p> + <p>This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MariaDB 5.x, MSSQL Server 2000, PostgreSQL 8.x, Oracle 8, SQLite 2 and Firebird. Versions of PHP used range from 5.3.x to 5.4.x without problem.</p> <a name="phpsec"></a><h3>7.i. Notice on PHP security issues</h3> diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index 6cd2627f43..cedf03ba9b 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -79,6 +79,8 @@ <ol style="list-style-type: lower-roman;"> <li><a href="#standardisation">Standardisation</a></li> <li><a href="#otherconsiderations">Other considerations</a></li> + <li><a href="#placeholders">Working with placeholders</a></li> + <li><a href="#usingplurals">Using plurals</a></li> <li><a href="#writingstyle">Writing Style</a></li> </ol> </li> @@ -106,8 +108,8 @@ <p>Tabs in front of lines are no problem, but having them within the text can be a problem if you do not set it to the amount of spaces every one of us uses. Here is a short example of how it should look like:</p> <div class="codebox"><pre> -{TAB}$mode{TAB}{TAB}= request_var('mode', ''); -{TAB}$search_id{TAB}= request_var('search_id', ''); +{TAB}$mode{TAB}{TAB}= $request->variable('mode', ''); +{TAB}$search_id{TAB}= $request->variable('search_id', ''); </pre></div> <p>If entered with tabs (replace the {TAB}) both equal signs need to be on the same column.</p> @@ -190,19 +192,12 @@ class ... <ul> <li><strong>phpBB3</strong><br />Core files and all files not assigned to a separate package</li> - <li><strong>acm</strong><br /><code>/includes/cache</code><br />Cache System</li> + <li><strong>acm</strong><br /><code>/phpbb/cache</code><br />Cache System</li> <li><strong>acp</strong><br /><code>/adm</code>, <code>/includes/acp</code>, <code>/includes/functions_admin.php</code><br />Administration Control Panel</li> - <li><strong>dbal</strong><br /><code>/includes/db</code><br />Database Abstraction Layer.<br />Base class is <code>dbal</code> + <li><strong>dbal</strong><br /><code>/phpbb/db</code>, <code>/includes/db</code><br />Database Abstraction Layer. <ul> - <li><code>/includes/db/dbal.php</code><br />Base DBAL class, defining the overall framework</li> - <li><code>/includes/db/firebird.php</code><br />Firebird/Interbase Database Abstraction Layer</li> - <li><code>/includes/db/msssql.php</code><br />MSSQL Database Abstraction Layer</li> - <li><code>/includes/db/mssql_odbc.php</code><br />MSSQL ODBC Database Abstraction Layer for MSSQL</li> - <li><code>/includes/db/mysql.php</code><br />MySQL Database Abstraction Layer for MySQL 3.x/4.0.x/4.1.x/5.x</li> - <li><code>/includes/db/mysqli.php</code><br />MySQLi Database Abstraction Layer</li> - <li><code>/includes/db/oracle.php</code><br />Oracle Database Abstraction Layer</li> - <li><code>/includes/db/postgres.php</code><br />PostgreSQL Database Abstraction Layer</li> - <li><code>/includes/db/sqlite.php</code><br />Sqlite Database Abstraction Layer</li> + <li><code>/phpbb/db/driver/</code><br />Database Abstraction Layer classes</li> + <li><code>/phpbb/db/migration/</code><br />Migrations are used for updating the database from one release to another</li> </ul> </li> <li><strong>diff</strong><br /><code>/includes/diff</code><br />Diff Engine</li> @@ -210,13 +205,13 @@ class ... <li><strong>images</strong><br /><code>/images</code><br />All global images not connected to styles</li> <li><strong>install</strong><br /><code>/install</code><br />Installation System</li> <li><strong>language</strong><br /><code>/language</code><br />All language files</li> - <li><strong>login</strong><br /><code>/includes/auth</code><br />Login Authentication Plugins</li> + <li><strong>login</strong><br /><code>/phpbb/auth</code><br />Login Authentication Plugins</li> <li><strong>VC</strong><br /><code>/includes/captcha</code><br />CAPTCHA</li> <li><strong>mcp</strong><br /><code>mcp.php</code>, <code>/includes/mcp</code>, <code>report.php</code><br />Moderator Control Panel</li> <li><strong>ucp</strong><br /><code>ucp.php</code>, <code>/includes/ucp</code><br />User Control Panel</li> <li><strong>utf</strong><br /><code>/includes/utf</code><br />UTF8-related functions/classes</li> - <li><strong>search</strong><br /><code>/includes/search</code>, <code>search.php</code><br />Search System</li> - <li><strong>styles</strong><br /><code>/styles</code>, <code>style.php</code><br />phpBB Styles/Templates/Themes/Imagesets</li> + <li><strong>search</strong><br /><code>/phpbb/search</code>, <code>search.php</code><br />Search System</li> + <li><strong>styles</strong><br /><code>/styles</code><br />phpBB Styles/Templates/Themes</li> </ul> <a name="constants"></a><h3>1.iv. Special Constants</h3> @@ -249,7 +244,7 @@ PHPBB_QA (Set board to QA-Mode, which means the updater also c <p>If the <code>PHPBB_USE_BOARD_URL_PATH</code> constant is set to true, phpBB uses generate_board_url() (this will return the boards url with the script path included) on all instances where web-accessible images are loaded. The exact locations are:</p> <ul> - <li>/includes/user.php - phpbb_user::img()</li> + <li>/phpbb/user.php - \phpbb\user::img()</li> <li>/includes/functions_content.php - smiley_text()</li> </ul> @@ -260,8 +255,6 @@ PHPBB_QA (Set board to QA-Mode, which means the updater also c <li>{T_THEME_PATH} - styles/xxx/theme</li> <li>{T_TEMPLATE_PATH} - styles/xxx/template</li> <li>{T_SUPER_TEMPLATE_PATH} - styles/xxx/template</li> - <li>{T_IMAGESET_PATH} - styles/xxx/imageset</li> - <li>{T_IMAGESET_LANG_PATH} - styles/xxx/imageset/yy</li> <li>{T_IMAGES_PATH} - images/</li> <li>{T_SMILIES_PATH} - $config['smilies_path']/</li> <li>{T_AVATAR_PATH} - $config['avatar_path']/</li> @@ -269,7 +262,7 @@ PHPBB_QA (Set board to QA-Mode, which means the updater also c <li>{T_ICONS_PATH} - $config['icons_path']/</li> <li>{T_RANKS_PATH} - $config['ranks_path']/</li> <li>{T_UPLOAD_PATH} - $config['upload_path']/</li> - <li>{T_STYLESHEET_LINK} - styles/xxx/theme/stylesheet.css (or link to style.php if css is parsed dynamically)</li> + <li>{T_STYLESHEET_LINK} - styles/xxx/theme/stylesheet.css</li> <li>New template variable {BOARD_URL} for the board url + script path.</li> </ul> @@ -324,7 +317,7 @@ for ($i = 0; $i < $outer_size; $i++) </pre></div> <h4>Function Names:</h4> - <p>Functions should also be named descriptively. We're not programming in C here, we don't want to write functions called things like "stristr()". Again, all lower-case names with words separated by a single underscore character in PHP, and camel caps in JavaScript. Function names should preferably have a verb in them somewhere. Good function names are <code>print_login_status()</code>, <code>get_user_data()</code>, etc. Constructor functions in JavaScript should begin with a capital letter.</p> + <p>Functions should also be named descriptively. We're not programming in C here, we don't want to write functions called things like "stristr()". Again, all lower-case names with words separated by a single underscore character in PHP, and camel caps in JavaScript. Function names should be prefixed with "phpbb_" and preferably have a verb in them somewhere. Good function names are <code>phpbb_print_login_status()</code>, <code>phpbb_get_user_data()</code>, etc. Constructor functions in JavaScript should begin with a capital letter.</p> <h4>Function Arguments:</h4> <p>Arguments are subject to the same guidelines as variable names. We don't want a bunch of functions like: <code>do_stuff($a, $b, $c)</code>. In most cases, we'd like to be able to tell how to use a function by just looking at its declaration. </p> @@ -334,33 +327,31 @@ for ($i = 0; $i < $outer_size; $i++) <p>Apart from following the rules for function names, all classes should meet the following conditions:</p> <ul> <li>Every class must be defined in a separate file.</li> - <li>The classes have to be located in a subdirectory of <code>includes/</code>.</li> - <li>Classnames to be prefixed with <code>phpbb_</code> to avoid name clashes, the filename should not contain the prefix.</li> - <li>Class names have to reflect the location of the file they are defined in. The longest list of prefixes, separated by underscores, which is a valid path must be the directory in which the file is located. So the directory names must not contain any underscores, but the filename may. If the filename would be empty the last directory name is used for the filename as well.</li> + <li>The classes have to be located in a subdirectory of <code>phpbb/</code>.</li> + <li>Classnames must be namespaced with <code>\phpbb\</code> to avoid name clashes.</li> + <li>Class names/namespaces have to reflect the location of the file they are defined in. The namespace must be the directory in which the file is located. So the directory names must not contain any underscores, but the filename may.</li> <li>Directories should typically be a singular noun (e.g. <code>dir</code> in the example below, not <code>dirs</code>.</li> </ul> <p>So given the following example directory structure you would result in the below listed lookups</p> <div class="codebox"><pre> -includes/ +phpbb/ class_name.php dir/ class_name.php - dir.php subdir/ class_name.php </pre></div> <div class="codebox"><pre> -phpbb_class_name - includes/class_name.php -phpbb_dir_class_name - includes/dir/class_name.php -phpbb_dir - includes/dir/dir.php -phpbb_dir_subdir_class_name - includes/dir/subdir/class_name.php +\phpbb\class_name - phpbb/class_name.php +\phpbb\dir\class_name - phpbb/dir/class_name.php +\phpbb\dir\subdir\class_name - phpbb/dir/subdir/class_name.php </pre></div> <h4>Summary:</h4> - <p>The basic philosophy here is to not hurt code clarity for the sake of laziness. This has to be balanced by a little bit of common sense, though; <code>print_login_status_for_a_given_user()</code> goes too far, for example -- that function would be better named <code>print_user_login_status()</code>, or just <code>print_login_status()</code>.</p> + <p>The basic philosophy here is to not hurt code clarity for the sake of laziness. This has to be balanced by a little bit of common sense, though; <code>phpbb_print_login_status_for_a_given_user()</code> goes too far, for example -- that function would be better named <code>phpbb_print_user_login_status()</code>, or just <code>phpbb_print_login_status()</code>.</p> <h4>Special Namings: </h4> <p>For all emoticons use the term <code>smiley</code> in singular and <code>smilies</code> in plural. For emails we use the term <code>email</code> (without dash between “e” and “m”).</p> @@ -1027,8 +1018,8 @@ for ($i = 0, $size = sizeof($post_data); $i < $size; $i++) <p>No attempt should be made to remove any copyright information (either contained within the source or displayed interactively when the source is run/compiled), neither should the copyright information be altered in any way (it may be added to).</p> <h4>Variables: </h4> - <p>Make use of the <code>request_var()</code> function for anything except for submit or single checking params.</p> - <p>The request_var function determines the type to set from the second parameter (which determines the default value too). If you need to get a scalar variable type, you need to tell this the request_var function explicitly. Examples:</p> + <p>Make use of the <code>\phpbb\request\request</code> class for everything.</p> + <p>The $request->variable() method determines the type to set from the second parameter (which determines the default value too). If you need to get a scalar variable type, you need to tell this the variable() method explicitly. Examples:</p> <p class="bad">// Old method, do not use it</p> <div class="codebox"><pre> @@ -1038,23 +1029,23 @@ $submit = (isset($HTTP_POST_VARS['submit'])) ? true : false; <p class="good">// Use request var and define a default variable (use the correct type)</p> <div class="codebox"><pre> -$start = request_var('start', 0); -$submit = (isset($_POST['submit'])) ? true : false; +$start = $request->variable('start', 0); +$submit = $request->is_set_post('submit'); </pre></div> - <p class="bad">// $start is an int, the following use of request_var therefore is not allowed</p> + <p class="bad">// $start is an int, the following use of $request->variable() therefore is not allowed</p> <div class="codebox"><pre> -$start = request_var('start', '0'); +$start = $request->variable('start', '0'); </pre></div> <p class="good">// Getting an array, keys are integers, value defaults to 0</p> <div class="codebox"><pre> -$mark_array = request_var('mark', array(0)); +$mark_array = $request->variable('mark', array(0)); </pre></div> <p class="good">// Getting an array, keys are strings, value defaults to 0</p> <div class="codebox"><pre> -$action_ary = request_var('action', array('' => 0)); +$action_ary = $request->variable('action', array('' => 0)); </pre></div> <h4>Login checks/redirection: </h4> @@ -1162,6 +1153,14 @@ append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&amp; <p>The <strong>e</strong> modifier in <strong>preg_replace</strong> can be replaced by <strong>preg_replace_callback</strong> and objects to encapsulate state that is needed in the callback code.</p> + <h4>Other functions, operators, statements and keywords:</h4> + + <p>The following PHP statements should also not be used in phpBB:</p> + + <ul> + <li><strong>goto</strong></li> + </ul> + </div> <div class="back2top"><a href="#wrap" class="top">Back to Top</a></div> @@ -1181,8 +1180,9 @@ append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&amp; <div class="codebox"><pre> # General Information about this style name = prosilver_duplicate -copyright = © phpBB Group, 2007 -version = 3.1.0 +copyright = © phpBB Group, 2007 +style_version = 3.1.0 +phpbb_version = 3.1.0 # Defining a different template bitfield # template_bitfield = lNg= @@ -1670,8 +1670,9 @@ div <div class="codebox"><pre> # General Information about this style name = Custom Style -copyright = &copy; phpBB Group, 2007 -version = 3.1.0 +copyright = © phpBB Group, 2007 +style_version = 3.1.0-b1 +phpbb_version = 3.1.0-b1 # Defining a different template bitfield # template_bitfield = lNg= @@ -1689,13 +1690,15 @@ parent = prosilver <ul> <li>An event name must be all lowercase, with each word separated by an underscore.</li> <li>An event name must briefly describe the location and purpose of the event.</li> - <li>An event name must end with one of the following suffixes:</li> - <ul> - <li><code>_prepend</code> - This event adds an item to the beginning of a block of related items, or adds to the beginning of individual items in a block.</li> - <li><code>_append</code> - This event adds an item to the end of a block of related items, or adds to the end of individual items in a block.</li> - <li><code>_before</code> - This event adds content directly before the specified block</li> - <li><code>_after</code> - This event adds content directly after the specified block</li> - </ul> + <li> + An event name must end with one of the following suffixes: + <ul> + <li><code>_prepend</code> - This event adds an item to the beginning of a block of related items, or adds to the beginning of individual items in a block.</li> + <li><code>_append</code> - This event adds an item to the end of a block of related items, or adds to the end of individual items in a block.</li> + <li><code>_before</code> - This event adds content directly before the specified block</li> + <li><code>_after</code> - This event adds content directly after the specified block</li> + </ul> + </li> </ul> <h4>Template event documentation</h4> @@ -1707,6 +1710,7 @@ parent = prosilver * Location: styles/<style_name>/template/filename.html * Purpose: A brief description of what this event should be used for. This may span multiple lines. +* Since: Version since when the event was added </pre></div></li> <li>An event found in multiple template files: <div class="codebox"><pre>event_name @@ -1715,6 +1719,7 @@ This may span multiple lines. + first/file/path.html + second/file/path.html * Purpose: Same as above. +* Since: 3.1.0-b1 </pre></div> <li>An event that is found multiple times in a file should have the number of instances in parenthesis next to the filename. <div class="codebox"><pre>event_name @@ -1723,6 +1728,7 @@ This may span multiple lines. + first/file/path.html (2) + second/file/path.html * Purpose: Same as above. +* Since: 3.1.0-b1 </pre></div></li> <li>An actual example event documentation: <div class="codebox"><pre>forumlist_body_last_post_title_prepend @@ -1730,7 +1736,9 @@ This may span multiple lines. * Locations: + styles/prosilver/template/forumlist_body.html + styles/subsilver2/template/forumlist_body.html -* Purpose: Add content before the post title of the latest post in a forum on the forum list.</pre></div></ul><br /> +* Purpose: Add content before the post title of the latest post in a forum on the forum list. +* Since: 3.1.0-a1 +</pre></div></ul><br /> </div> @@ -1760,16 +1768,16 @@ This may span multiple lines. <p>phpBB only uses the ASCII and the UTF-8 character encodings. Still all Strings are UTF-8 encoded because ASCII is a subset of UTF-8. The only exceptions to this rule are code sections which deal with external systems which use other encodings and character sets. Such external data should be converted to UTF-8 using the <code>utf8_recode()</code> function supplied with phpBB. It supports a variety of other character sets and encodings, a full list can be found below.</p> -<p>With <code>request_var()</code> you can either allow all UCS characters in user input or restrict user input to ASCII characters. This feature is controlled by the function's third parameter called <code>$multibyte</code>. You should allow multibyte characters in posts, PMs, topic titles, forum names, etc. but it's not necessary for internal uses like a <code>$mode</code> variable which should only hold a predefined list of ASCII strings anyway.</p> +<p>With <code>$request->variable()</code> you can either allow all UCS characters in user input or restrict user input to ASCII characters. This feature is controlled by the method's third parameter called <code>$multibyte</code>. You should allow multibyte characters in posts, PMs, topic titles, forum names, etc. but it's not necessary for internal uses like a <code>$mode</code> variable which should only hold a predefined list of ASCII strings anyway.</p> <div class="codebox"><pre> // an input string containing a multibyte character $_REQUEST['multibyte_string'] = 'Käse'; // print request variable as a UTF-8 string allowing multibyte characters -echo request_var('multibyte_string', '', true); +echo $request->variable('multibyte_string', '', true); // print request variable as ASCII string -echo request_var('multibyte_string', ''); +echo $request->variable('multibyte_string', ''); </pre></div> <p>This code snippet will generate the following output:</p> @@ -1779,19 +1787,6 @@ Käse K??se </pre></div> -<h4>Unicode Normalization</h4> - -<p>If you retrieve user input with multibyte characters you should additionally normalize the string using <code>utf8_normalize_nfc()</code> before you work with it. This is necessary to make sure that equal characters can only occur in one particular binary representation. For example the character Å can be represented either as <code>U+00C5</code> (LATIN CAPITAL LETTER A WITH RING ABOVE) or as <code>U+212B</code> (ANGSTROM SIGN). phpBB uses Normalization Form Canonical Composition (NFC) for all text. So the correct version of the above example would look like this:</p> - -<div class="codebox"><pre> -$_REQUEST['multibyte_string'] = 'Käse'; - -// normalize multibyte strings -echo utf8_normalize_nfc(request_var('multibyte_string', '', true)); -// ASCII strings do not need to be normalized -echo request_var('multibyte_string', ''); -</pre></div> - <h4>Case Folding</h4> <p>Case insensitive comparison of strings is no longer possible with <code>strtolower</code> or <code>strtoupper</code> as some characters have multiple lower case or multiple upper case forms depending on their position in a word. The <code>utf8_strtolower</code> and the <code>utf8_strtoupper</code> functions suffer from the same problem so they can only be used to display upper/lower case versions of a string but they cannot be used for case insensitive comparisons either. So instead you should use case folding which gives you a case insensitive version of the string which can be used for case insensitive comparisons. An NFC normalized string can be case folded using <code>utf8_case_fold_nfc()</code>.</p> @@ -2348,7 +2343,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) <p>Within some cases, there may be mixed scripts of a left-to-right and right-to-left direction, so using <code>LRE</code> & <code>RLE</code> with <code>PDF</code> may be more appropriate. Lastly, in very rare instances where directionality must be forced, then use <code>LRO</code> & <code>RLO</code> with <code>PDF</code>.</p> <p>For further information on authoring techniques of bi-directional text, please see the W3C tutorial on <a href="http://www.w3.org/International/tutorials/bidi-xhtml/">authoring techniques for XHTML pages with bi-directional text</a>.</p> - <h4>Working with placeholders:</h4> + <a name="placeholders"></a><h3>6.iii. Working with placeholders</h3> <p>As phpBB is translated into languages with different ordering rules to that of English, it is possible to show specific values in any order deemed appropriate. Take for example the extremely simple "Page <em>X</em> of <em>Y</em>", whilst in English this could just be coded as:</p> @@ -2380,7 +2375,59 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2)) ... </pre></div> - <a name="writingstyle"></a><h3>6.iii. Writing Style</h3> + <a name="usingplurals"></a><h3>6.iv. Using plurals</h3> + + <p> + The english language is very simple when it comes to plurals.<br /> + You have <code>0 elephants</code>, <code>1 elephant</code>, or <code>2+ elephants</code>. So basically you have 2 different forms: one singular and one plural.<br /> + But for some other languages this is quite more difficult. Let's take the Bosnian language as another example:<br /> + You have <code>[1/21/31] slon</code>, <code>[2/3/4] slona</code>, <code>[0/5/6] slonova</code> and <code>[7/8/9/11] ...</code> and some more difficult rules. + </p> + + <p>The <a href="https://wiki.phpbb.com/Plural_Rules">plural system</a> takes care of this and can be used as follows:</p> + + <p>The PHP code will basically look like this:</p> + + <div class="codebox"><pre> + ... + $user->lang('NUMBER_OF_ELEPHANTS', $number_of_elephants); + ... + </pre></div> + + <p>And the English translation would be:</p> + + <div class="codebox"><pre> + ... + 'NUMBER_OF_ELEPHANTS' => array( + 0 => 'You have no elephants', // Optional special case for 0 + 1 => 'You have 1 elephant', // Singular + 2 => 'You have %d elephants', // Plural + ), + ... + </pre></div> + + <p>While the Bosnian translation can have more cases:</p> + + <div class="codebox"><pre> + ... + 'NUMBER_OF_ELEPHANTS' => array( + 0 => 'You have no slonova', // Optional special case for 0 + 1 => 'You have %d slon', // Used for 1, 21, 31, .. + 2 => 'You have %d slona', // Used for 5, 6, + 3 => ... + ), + ... + </pre></div> + + <p><strong>NOTE:</strong> It is okay to use plurals for an unknown number compared to a single item, when the number is not known and displayed:</p> + <div class="codebox"><pre> + ... + 'MODERATOR' => 'Moderator', // Your board has 1 moderator + 'MODERATORS' => 'Moderators', // Your board has multiple moderators + ... + </pre></div> + + <a name="writingstyle"></a><h3>6.v. Writing Style</h3> <h4>Miscellaneous tips & hints:</h4> diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index bef4727149..67fa96ffbc 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -1,55 +1,221 @@ +acp_bbcodes_actions_append +=== +* Location: adm/style/acp_bbcodes.html +* Since: 3.1.0-a3 +* Purpose: Add actions to the BBCodes page, after edit/delete buttons + +acp_bbcodes_actions_prepend +=== +* Location: adm/style/acp_bbcodes.html +* Since: 3.1.0-a3 +* Purpose: Add actions to the BBCodes page, before edit/delete buttons + +acp_bbcodes_edit_fieldsets_after +=== +* Location: adm/style/acp_bbcodes.html +* Since: 3.1.0-a3 +* Purpose: Add settings to BBCode add/edit form + acp_forums_normal_settings_append === * Location: adm/style/acp_forums.html +* Since: 3.1.0-a1 * Purpose: Add settings to forums acp_main_actions_append === * Location: adm/style/acp_main.html +* Since: 3.1.0-a1 * Purpose: Add actions to the ACP main page below the cache purge action acp_main_notice_after === * Location: adm/style/acp_main.html +* Since: 3.1.0-a1 * Purpose: Add notices or other blocks in the ACP below other configuration notices acp_overall_footer_after === * Location: adm/style/overall_footer.html +* Since: 3.1.0-a1 * Purpose: Add content below the footer in the ACP +acp_overall_header_body_before +=== +* Location: adm/style/overall_header.html +* Since: 3.1.0-b2 +* Purpose: Add content to the header body + acp_overall_header_head_append === * Location: adm/style/overall_header.html -* Add assets within the `<head>` tags in the ACP +* Since: 3.1.0-a1 +* Purpose: Add assets within the `<head>` tags in the ACP acp_simple_footer_after === * Location: adm/style/simple_footer.html +* Since: 3.1.0-a1 * Purpose: Add content below the simple footer in the ACP +acp_simple_header_body_before +=== +* Location: adm/style/simple_header.html +* Since: 3.1.0-b2 +* Purpose: Add content to the header body + acp_simple_header_head_append === -* Location: adm/style/overall_header.html -* Add assets within the `<head>` tags in the simple header of the ACP +* Location: adm/style/simple_header.html +* Since: 3.1.0-a1 +* Purpose: Add assets within the `<head>` tags in the simple header of the ACP acp_users_overview_options_append === -* Location: adm/style/acp_users.html +* Location: adm/style/acp_users_overview.html +* Since: 3.1.0-a1 * Purpose: Add options and settings on user overview page +acp_users_prefs_append +=== +* Location: adm/style/acp_users_prefs.html +* Since: 3.1.0-b3 +* Purpose: Add user options fieldset to the bottom of ACP users prefs settings + +acp_users_prefs_prepend +=== +* Location: adm/style/acp_users_prefs.html +* Since: 3.1.0-b3 +* Purpose: Add user options fieldset to the top of ACP users prefs settings + +acp_users_prefs_personal_append +=== +* Location: adm/style/acp_users_prefs.html +* Since: 3.1.0-b3 +* Purpose: Add user options fieldset to the bottom of ACP users personal prefs settings + +acp_users_prefs_personal_prepend +=== +* Location: adm/style/acp_users_prefs.html +* Since: 3.1.0-b3 +* Purpose: Add user options fieldset to the top of ACP users personal prefs settings + +acp_users_prefs_post_append +=== +* Location: adm/style/acp_users_prefs.html +* Since: 3.1.0-b3 +* Purpose: Add user options fieldset to the bottom of ACP users post prefs settings + +acp_users_prefs_post_prepend +=== +* Location: adm/style/acp_users_prefs.html +* Since: 3.1.0-b3 +* Purpose: Add user options fieldset to the top of ACP users post prefs settings + +acp_users_prefs_view_append +=== +* Location: adm/style/acp_users_prefs.html +* Since: 3.1.0-b3 +* Purpose: Add user options fieldset to the bottom of ACP users view prefs settings + +acp_users_prefs_view_prepend +=== +* Location: adm/style/acp_users_prefs.html +* Since: 3.1.0-b3 +* Purpose: Add user options fieldset to the top of ACP users view prefs settings + +acp_users_signature_editor_buttons_after +=== +* Locations: + + adm/style/acp_users_signature.html +* Since: 3.1.0-a3 +* Purpose: Add content after BBCode posting buttons in the ACP user signature + +acp_users_signature_editor_buttons_before +=== +* Locations: + + adm/style/acp_users_signature.html +* Since: 3.1.0-a3 +* Purpose: Add content before BBCode posting buttons in the ACP user signature + +forumlist_body_category_header_after +=== +* Locations: + + styles/prosilver/template/forumlist_body.html + + styles/subsilver2/template/forumlist_body.html +* Since: 3.1.0-a4 +* Purpose: Add content after the header of the category on the forum list. + +forumlist_body_category_header_before +=== +* Locations: + + styles/prosilver/template/forumlist_body.html + + styles/subsilver2/template/forumlist_body.html +* Since: 3.1.0-a4 +* Purpose: Add content before the header of the category on the forum list. + forumlist_body_last_post_title_prepend -==== +=== * Locations: + styles/prosilver/template/forumlist_body.html + styles/subsilver2/template/forumlist_body.html +* Since: 3.1.0-a1 * Purpose: Add content before the post title of the latest post in a forum on the forum list. +forumlist_body_subforums_after +=== +* Locations: + + styles/prosilver/template/forumlist_body.html + + styles/subsilver2/template/forumlist_body.html +* Since: 3.1.0-a4 +* Purpose: Add content after the list of subforums (if any) for each forum on the forum list. + +forumlist_body_subforums_before +=== +* Locations: + + styles/prosilver/template/forumlist_body.html + + styles/subsilver2/template/forumlist_body.html +* Since: 3.1.0-a4 +* Purpose: Add content before the list of subforums (if any) for each forum on the forum list. + +forumlist_body_last_row_after +=== +* Locations: + + styles/prosilver/template/forumlist_body.html + + styles/subsilver2/template/forumlist_body.html +* Since: 3.1.0-b2 +* Purpose: Add content after the very last row of the forum list. + +index_body_linklist_after +=== +* Locations: + + styles/prosilver/template/index_body.html + + styles/subsilver2/template/index_body.html +* Since: 3.1.0-a3 +* Purpose: Add content after the linklist above the forum list on Board index + +index_body_linklist_before +=== +* Locations: + + styles/prosilver/template/index_body.html + + styles/subsilver2/template/index_body.html +* Since: 3.1.0-a3 +* Purpose: Add content before the linklist above the forum list on Board index + +index_body_stat_blocks_after +=== +* Locations: + + styles/prosilver/template/index_body.html + + styles/subsilver2/template/index_body.html +* Since: 3.1.0-b3 +* Purpose: Add new statistic blocks below the Who Is Online and Board Statistics blocks + index_body_stat_blocks_before === * Locations: + styles/prosilver/template/index_body.html + styles/subsilver2/template/index_body.html +* Since: 3.1.0-a1 * Purpose: Add new statistic blocks above the Who Is Online and Board Statistics blocks memberlist_body_username_append @@ -57,6 +223,7 @@ memberlist_body_username_append * Locations: + styles/prosilver/template/memberlist_body.html + styles/subsilver2/template/memberlist_body.html +* Since: 3.1.0-a1 * Purpose: Add information after every username in the memberlist. Works in all display modes (leader, group and normal memberlist). @@ -65,14 +232,40 @@ memberlist_body_username_prepend * Locations: + styles/prosilver/template/memberlist_body.html + styles/subsilver2/template/memberlist_body.html +* Since: 3.1.0-a1 * Purpose: Add information before every username in the memberlist. Works in all display modes (leader, group and normal memberlist). +memberlist_view_contact_after +=== +* Locations: + + styles/prosilver/template/memberlist_view.html + + styles/subsilver2/template/memberlist_view.html +* Since: 3.1.0-b2 +* Purpose: Add content after the user contact part of any user profile + +memberlist_view_contact_before +=== +* Locations: + + styles/prosilver/template/memberlist_view.html + + styles/subsilver2/template/memberlist_view.html +* Since: 3.1.0-b2 +* Purpose: Add content before the user contact part of any user profile + +memberlist_view_content_append +=== +* Locations: + + styles/prosilver/template/memberlist_view.html + + styles/subsilver2/template/memberlist_view.html +* Since: 3.1.0-b2 +* Purpose: Add custom content to the user profile view after the main content + memberlist_view_user_statistics_after === * Locations: + styles/prosilver/template/memberlist_view.html + styles/subsilver2/template/memberlist_view.html +* Since: 3.1.0-a1 * Purpose: Add entries after the user statistics part of any user profile memberlist_view_user_statistics_before @@ -80,6 +273,7 @@ memberlist_view_user_statistics_before * Locations: + styles/prosilver/template/memberlist_view.html + styles/subsilver2/template/memberlist_view.html +* Since: 3.1.0-a1 * Purpose: Add entries before the user statistics part of any user profile overall_footer_after @@ -87,18 +281,30 @@ overall_footer_after * Locations: + styles/prosilver/template/overall_footer.html + styles/subsilver2/template/overall_footer.html +* Since: 3.1.0-a1 * Purpose: Add content at the end of the file, directly prior to the `</body>` tag overall_footer_breadcrumb_append === -* Location: styles/prosilver/template/overall_footer.html +* Locations: + + styles/prosilver/template/navbar_footer.html +* Since: 3.1.0-a1 * Purpose: Add links to the list of breadcrumbs in the footer +overall_footer_content_after +=== +* Locations: + + styles/prosilver/template/overall_footer.html + + styles/subsilver2/template/overall_footer.html +* Since: 3.1.0-a3 +* Purpose: Add content on all pages after the main content, before the footer + overall_footer_copyright_append === * Locations: + styles/prosilver/template/overall_footer.html + styles/subsilver2/template/overall_footer.html +* Since: 3.1.0-a1 * Purpose: Add content after the copyright line (no new line by default), before the ACP link overall_footer_copyright_prepend @@ -106,44 +312,209 @@ overall_footer_copyright_prepend * Locations: + styles/prosilver/template/overall_footer.html + styles/subsilver2/template/overall_footer.html +* Since: 3.1.0-a1 * Purpose: Add content before the copyright line -overall_header_breadcrumb_append +overall_footer_page_body_after +=== +* Locations: + + styles/prosilver/template/overall_footer.html + + styles/subsilver2/template/overall_footer.html +* Since: 3.1.0-b3 +* Purpose: Add content after the page-body, but before the footer + +overall_footer_teamlink_after +=== +* Locations: + + styles/prosilver/template/navbar_footer.html + + styles/subsilver2/template/index_body.html +* Since: 3.1.0-b3 +* Purpose: Add contents after the team-link in the footer + +overall_footer_teamlink_before +=== +* Locations: + + styles/prosilver/template/navbar_footer.html + + styles/subsilver2/template/index_body.html +* Since: 3.1.0-b3 +* Purpose: Add contents before the team-link in the footer + +overall_footer_timezone_after +=== +* Locations: + + styles/prosilver/template/navbar_footer.html + + styles/subsilver2/template/breadcrumbs.html +* Since: 3.1.0-b3 +* Purpose: Add content to the navbar in the page footer, after "Timezone" + +overall_footer_timezone_before +=== +* Locations: + + styles/prosilver/template/navbar_footer.html + + styles/subsilver2/template/breadcrumbs.html +* Since: 3.1.0-b3 +* Purpose: Add content to the navbar in the page footer, before "Timezone" + +overall_header_body_before === * Locations: + styles/prosilver/template/overall_header.html + + styles/subsilver2/template/overall_header.html +* Since: 3.1.0-b2 +* Purpose: Add content to the header body + +overall_header_breadcrumb_append +=== +* Locations: + + styles/prosilver/template/navbar_header.html + styles/subsilver2/template/breadcrumbs.html +* Since: 3.1.0-a1 * Purpose: Add links to the list of breadcrumbs in the header +overall_header_content_before +=== +* Locations: + + styles/prosilver/template/overall_header.html + + styles/subsilver2/template/overall_header.html +* Since: 3.1.0-a3 +* Purpose: Add content on all pages before the main content, after the header + overall_header_head_append === * Locations: + styles/prosilver/template/overall_header.html + styles/subsilver2/template/overall_header.html +* Since: 3.1.0-a1 * Purpose: Add asset calls directly before the `</head>` tag overall_header_navigation_append === -* Location: styles/prosilver/template/overall_header.html +* Locations: + + styles/prosilver/template/navbar_header.html + + styles/subsilver2/template/overall_header.html +* Since: 3.1.0-a1 * Purpose: Add links after the navigation links in the header overall_header_navigation_prepend === -* Location: styles/prosilver/template/overall_header.html +* Locations: + + styles/prosilver/template/navbar_header.html + + styles/subsilver2/template/overall_header.html +* Since: 3.1.0-a1 * Purpose: Add links before the navigation links in the header +overall_header_page_body_before +=== +* Locations: + + styles/prosilver/template/overall_header.html + + styles/subsilver2/template/overall_header.html +* Since: 3.1.0-b3 +* Purpose: Add content after the page-header, but before the page-body + +posting_editor_buttons_after +=== +* Locations: + + styles/prosilver/template/posting_buttons.html + + styles/subsilver2/template/posting_buttons.html +* Since: 3.1.0-a3 +* Purpose: Add content after the BBCode posting buttons + +posting_editor_buttons_before +=== +* Locations: + + styles/prosilver/template/posting_buttons.html + + styles/subsilver2/template/posting_buttons.html +* Since: 3.1.0-a3 +* Purpose: Add content before the BBCode posting buttons + +posting_editor_message_after +=== +* Locations: + + styles/prosilver/template/posting_editor.html + + styles/subsilver2/template/posting_body.html +* Since: 3.1.0-a2 +* Purpose: Add field (e.g. textbox) to the posting screen after the message + +posting_editor_message_before +=== +* Locations: + + styles/prosilver/template/posting_editor.html + + styles/subsilver2/template/posting_body.html +* Since: 3.1.0-a2 +* Purpose: Add field (e.g. textbox) to the posting screen before the message + posting_editor_options_prepend === * Locations: + styles/prosilver/template/posting_editor.html - + styles/prosilver/template/posting_body.html + + styles/subsilver2/template/posting_body.html +* Since: 3.1.0-a1 * Purpose: Add posting options on the posting screen +posting_editor_subject_after +=== +* Locations: + + styles/prosilver/template/posting_editor.html + + styles/subsilver2/template/posting_body.html +* Since: 3.1.0-a2 +* Purpose: Add field (e.g. textbox) to the posting screen after the subject + +posting_editor_subject_before +=== +* Locations: + + styles/prosilver/template/posting_editor.html + + styles/subsilver2/template/posting_body.html +* Since: 3.1.0-a2 +* Purpose: Add field (e.g. textbox) to the posting screen before the subject + +quickreply_editor_panel_after +=== +* Locations: + + styles/prosilver/template/quickreply_editor.html + + styles/subsilver2/template/quickreply_editor.html +* Since: 3.1.0-b2 +* Purpose: Add content after the quick reply panel (but inside the form) + +quickreply_editor_panel_before +=== +* Locations: + + styles/prosilver/template/quickreply_editor.html + + styles/subsilver2/template/quickreply_editor.html +* Since: 3.1.0-b2 +* Purpose: Add content before the quick reply panel (but inside the form) + +quickreply_editor_message_after +=== +* Locations: + + styles/prosilver/template/quickreply_editor.html + + styles/subsilver2/template/quickreply_editor.html +* Since: 3.1.0-a4 +* Purpose: Add content after the quick reply textbox + +quickreply_editor_message_before +=== +* Locations: + + styles/prosilver/template/quickreply_editor.html + + styles/subsilver2/template/quickreply_editor.html +* Since: 3.1.0-a4 +* Purpose: Add content before the quick reply textbox + simple_footer_after === -* Location: styles/prosilver/template/simple_footer.html +* Locations: + + styles/prosilver/template/simple_footer.html + + styles/subsilver2/template/simple_footer.html +* Since: 3.1.0-a1 * Purpose: Add content directly prior to the `</body>` tag of the simple footer +simple_header_body_before +=== +* Locations: + + styles/prosilver/template/simple_header.html + + styles/subsilver2/template/simple_header.html +* Since: 3.1.0-b2 +* Purpose: Add content to the header body + topiclist_row_prepend === * Locations: @@ -151,6 +522,7 @@ topiclist_row_prepend + styles/prosilver/template/viewforum_body.html + styles/subsilver2/template/search_results.html + styles/subsilver2/template/viewforum_body.html +* Since: 3.1.0-a1 * Purpose: Add content into topic rows (inside the elements containing topic titles) topiclist_row_append @@ -160,23 +532,47 @@ topiclist_row_append + styles/prosilver/template/viewforum_body.html + styles/subsilver2/template/search_results.html + styles/subsilver2/template/viewforum_body.html +* Since: 3.1.0-a1 * Purpose: Add content into topic rows (inside the elements containing topic titles) +ucp_pm_viewmessage_contact_fields_after +=== +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html +* Since: 3.1.0-b1 +* Purpose: Add data after the contact fields on the user profile when viewing +a private message + +ucp_pm_viewmessage_contact_fields_before +=== +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html +* Since: 3.1.0-b1 +* Purpose: Add data before the contact fields on the user profile when viewing +a private message + ucp_pm_viewmessage_custom_fields_after === -* Location: styles/prosilver/template/ucp_pm_viewmessage.html +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html +* Since: 3.1.0-a1 * Purpose: Add data after the custom fields on the user profile when viewing a private message ucp_pm_viewmessage_custom_fields_before === -* Location: styles/prosilver/template/ucp_pm_viewmessage.html +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html +* Since: 3.1.0-a1 * Purpose: Add data before the custom fields on the user profile when viewing a private message ucp_pm_viewmessage_print_head_append === -* Location: styles/prosilver/template/ucp_pm_viewmessage_print.html +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage_print.html + + styles/subsilver2/template/ucp_pm_viewmessage_print.html +* Since: 3.1.0-a1 * Purpose: Add asset calls directly before the `</head>` tag of the Print PM screen ucp_prefs_personal_prepend @@ -184,6 +580,7 @@ ucp_prefs_personal_prepend * Locations: + styles/prosilver/template/ucp_prefs_personal.html + styles/subsilver2/template/ucp_prefs_personal.html +* Since: 3.1.0-a1 * Purpose: Add user options to the top of the Edit Global Settings block ucp_prefs_personal_append @@ -191,6 +588,7 @@ ucp_prefs_personal_append * Locations: + styles/prosilver/template/ucp_prefs_personal.html + styles/subsilver2/template/ucp_prefs_personal.html +* Since: 3.1.0-a1 * Purpose: Add user options to the bottom of the Edit Global Settings block ucp_prefs_post_prepend @@ -198,6 +596,7 @@ ucp_prefs_post_prepend * Locations: + styles/prosilver/template/ucp_prefs_post.html + styles/subsilver2/template/ucp_prefs_post.html +* Since: 3.1.0-a1 * Purpose: Add user options to the top of the Edit Posting Defaults block ucp_prefs_post_append @@ -205,6 +604,7 @@ ucp_prefs_post_append * Locations: + styles/prosilver/template/ucp_prefs_post.html + styles/subsilver2/template/ucp_prefs_post.html +* Since: 3.1.0-a1 * Purpose: Add user options to the bottom of the Edit Posting Defaults block ucp_prefs_view_radio_buttons_prepend @@ -212,6 +612,7 @@ ucp_prefs_view_radio_buttons_prepend * Locations: + styles/prosilver/template/ucp_prefs_view.html + styles/subsilver2/template/ucp_prefs_view.html +* Since: 3.1.0-a1 * Purpose: Add options to the top of the radio buttons block of the Edit Display Options screen @@ -220,6 +621,7 @@ ucp_prefs_view_radio_buttons_append * Locations: + styles/prosilver/template/ucp_prefs_view.html + styles/subsilver2/template/ucp_prefs_view.html +* Since: 3.1.0-a1 * Purpose: Add options to the bottom of the radio buttons block of the Edit Display Options screen @@ -228,6 +630,7 @@ ucp_prefs_view_select_menu_prepend * Locations: + styles/prosilver/template/ucp_prefs_view.html + styles/subsilver2/template/ucp_prefs_view.html +* Since: 3.1.0-a1 * Purpose: Add options to the top of the drop-down lists block of the Edit Display Options screen @@ -236,12 +639,32 @@ ucp_prefs_view_select_menu_append * Locations: + styles/prosilver/template/ucp_prefs_view.html + styles/subsilver2/template/ucp_prefs_view.html +* Since: 3.1.0-a1 * Purpose: Add options to the bottom of the drop-down lists block of the Edit Display Options screen +ucp_friend_list_before +=== +* Locations: + + styles/prosilver/template/ucp_zebra_friends.html + + styles/subsilver2/template/ucp_zebra_friends.html +* Since: 3.1.0-a4 +* Purpose: Add optional elements before list of friends in UCP + +ucp_friend_list_after +=== +* Locations: + + styles/prosilver/template/ucp_zebra_friends.html + + styles/subsilver2/template/ucp_zebra_friends.html +* Since: 3.1.0-a4 +* Purpose: Add optional elements after list of friends in UCP + viewtopic_print_head_append === -* Location: styles/prosilver/template/viewtopic_print.html +* Locations: + + styles/prosilver/template/viewtopic_print.html + + styles/subsilver2/template/viewtopic_print.html +* Since: 3.1.0-a1 * Purpose: Add asset calls directly before the `</head>` tag of the Print Topic screen viewtopic_body_footer_before @@ -249,6 +672,7 @@ viewtopic_body_footer_before * Locations: + styles/prosilver/template/viewtopic_body.html + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-a1 * Purpose: Add content to the bottom of the View topic screen below the posts and quick reply, directly before the jumpbox in Prosilver, breadcrumbs in Subsilver2. @@ -258,6 +682,7 @@ viewtopic_body_post_buttons_after * Locations: + styles/prosilver/template/viewtopic_body.html + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-a1 * Purpose: Add post button to posts (next to edit, quote etc), at the end of the list. @@ -266,6 +691,7 @@ viewtopic_body_post_buttons_before * Locations: + styles/prosilver/template/viewtopic_body.html + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-a1 * Purpose: Add post button to posts (next to edit, quote etc), at the start of the list. @@ -274,6 +700,7 @@ viewtopic_body_postrow_custom_fields_after * Locations: + styles/prosilver/template/viewtopic_body.html + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-a1 * Purpose: Add data after the custom fields on the user profile when viewing a post @@ -282,12 +709,68 @@ viewtopic_body_postrow_custom_fields_before * Locations: + styles/prosilver/template/viewtopic_body.html + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-a1 * Purpose: Add data before the custom fields on the user profile when viewing a post +viewtopic_body_postrow_post_after +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-a4 +* Purpose: Add data after posts + +viewtopic_body_postrow_post_before +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-a4 +* Purpose: Add data before posts + +viewtopic_body_postrow_post_notices_after +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-b2 +* Purpose: Add posts specific custom notices at the notices bottom. + +viewtopic_body_postrow_post_notices_before +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-b2 +* Purpose: Add posts specific custom notices at the notices top. + +viewtopic_body_topic_actions_before +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-a4 +* Purpose: Add data before the topic actions buttons (after the posts sorting options) + viewtopic_topic_title_prepend === * Locations: + styles/prosilver/template/viewtopic_body.html + styles/subsilver2/template/viewtopic_body.html +* Since: 3.1.0-a1 * Purpose: Add content directly before the topic title link on the View topic screen + +viewtopic_topic_tools_after +=== +* Locations: + + styles/prosilver/template/viewtopic_topic_tools.html +* Since: 3.1.0-a3 +* Purpose: Add a new topic tool after the rest of the existing ones + +viewtopic_topic_tools_before +=== +* Locations: + + styles/prosilver/template/viewtopic_topic_tools.html +* Since: 3.1.0-a3 +* Purpose: Add a new topic tool before the rest of the existing ones diff --git a/phpBB/docs/sphinx.sample.conf b/phpBB/docs/sphinx.sample.conf index 620ec25761..0a210ecd1a 100644 --- a/phpBB/docs/sphinx.sample.conf +++ b/phpBB/docs/sphinx.sample.conf @@ -38,7 +38,7 @@ source source_phpbb_{SPHINX_ID}_main sql_attr_bool = deleted sql_attr_timestamp = post_time sql_attr_timestamp = topic_last_post_time - sql_attr_str2ordinal = post_subject + sql_attr_string = post_subject } source source_phpbb_{SPHINX_ID}_delta : source_phpbb_{SPHINX_ID}_main { diff --git a/phpBB/download/file.php b/phpBB/download/file.php index 04d68f6a48..163ab673b9 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -144,7 +144,8 @@ require($phpbb_root_path . 'includes/functions_download' . '.' . $phpEx); $download_id = request_var('id', 0); $topic_id = $request->variable('topic_id', 0); -$post_msg_id = $request->variable('post_msg_id', 0); +$post_id = $request->variable('post_id', 0); +$msg_id = $request->variable('msg_id', 0); $archive = $request->variable('archive', '.tar'); $mode = request_var('mode', ''); $thumbnail = request_var('t', false); @@ -163,17 +164,22 @@ if (!$config['allow_attachments'] && !$config['allow_pm_attach']) if ($download_id) { // Attachment id (only 1 attachment) - $sql_where = "attach_id = $download_id"; + $sql_where = 'attach_id = ' . $download_id; } -else if ($post_msg_id) +else if ($msg_id) { - // Post id or private message id (multiple attachments) - $sql_where = "post_msg_id = $post_msg_id AND is_orphan = 0"; + // Private message id (multiple attachments) + $sql_where = 'is_orphan = 0 AND in_message = 1 AND post_msg_id = ' . $msg_id; +} +else if ($post_id) +{ + // Post id (multiple attachments) + $sql_where = 'is_orphan = 0 AND in_message = 0 AND post_msg_id = ' . $post_id; } else if ($topic_id) { // Topic id (multiple attachments) - $sql_where = "topic_id = $topic_id AND is_orphan = 0"; + $sql_where = 'is_orphan = 0 AND topic_id = ' . $topic_id; } else { @@ -181,7 +187,7 @@ else trigger_error('NO_ATTACHMENT_SELECTED'); } -$sql = 'SELECT attach_id, post_msg_id, topic_id, in_message, is_orphan, physical_filename, real_filename, extension, mimetype, filesize, filetime +$sql = 'SELECT attach_id, post_msg_id, topic_id, in_message, poster_id, is_orphan, physical_filename, real_filename, extension, mimetype, filesize, filetime FROM ' . ATTACHMENTS_TABLE . " WHERE $sql_where"; $result = $db->sql_query($sql); @@ -240,6 +246,20 @@ else if ($download_id) if (!$attachment['in_message']) { phpbb_download_handle_forum_auth($db, $auth, $attachment['topic_id']); + + $sql = 'SELECT forum_id, post_visibility + FROM ' . POSTS_TABLE . ' + WHERE post_id = ' . (int) $attachment['post_msg_id']; + $result = $db->sql_query($sql); + $post_row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!$post_row || ($post_row['post_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $post_row['forum_id']))) + { + // Attachment of a soft deleted post and the user is not allowed to see the post + send_status_line(404, 'Not Found'); + trigger_error('ERROR_NO_ATTACHMENT'); + } } else { @@ -251,7 +271,7 @@ else if ($download_id) $extensions = array(); if (!extension_allowed($row['forum_id'], $attachment['extension'], $extensions)) { - send_status_line(404, 'Forbidden'); + send_status_line(403, 'Forbidden'); trigger_error(sprintf($user->lang['EXTENSION_DISABLED_AFTER_POSTING'], $attachment['extension'])); } } @@ -328,23 +348,32 @@ else $archive = '.tar'; } - if ($post_msg_id) + $post_visibility = array(); + if ($msg_id) { - if ($attachment['in_message']) - { - $sql = 'SELECT message_subject AS attach_subject - FROM ' . PRIVMSGS_TABLE . " - WHERE msg_id = $post_msg_id"; - } - else - { - $sql = 'SELECT post_subject AS attach_subject, forum_id - FROM ' . POSTS_TABLE . " - WHERE post_id = $post_msg_id"; - } + $sql = 'SELECT message_subject AS attach_subject + FROM ' . PRIVMSGS_TABLE . " + WHERE msg_id = $msg_id"; + } + else if ($post_id) + { + $sql = 'SELECT post_subject AS attach_subject, forum_id, post_visibility + FROM ' . POSTS_TABLE . " + WHERE post_id = $post_id"; } else { + $sql = 'SELECT post_id, post_visibility + FROM ' . POSTS_TABLE . " + WHERE topic_id = $topic_id + AND post_attachment = 1"; + $result = $db->sql_query($sql); + while ($row = $db->sql_fetchrow($result)) + { + $post_visibility[(int) $row['post_id']] = (int) $row['post_visibility']; + } + $db->sql_freeresult($result); + $sql = 'SELECT topic_title AS attach_subject, forum_id FROM ' . TOPICS_TABLE . " WHERE topic_id = $topic_id"; @@ -361,7 +390,7 @@ else } $clean_name = phpbb_download_clean_filename($row['attach_subject']); - $suffix = '_' . (($post_msg_id) ? $post_msg_id : $topic_id) . '_' . $clean_name; + $suffix = '_' . (($msg_id) ? 'm' . $msg_id : (($post_id) ? 'p' . $post_id : 't' . $topic_id)) . '_' . $clean_name; $archive_name = 'attachments' . $suffix; $store_name = 'att_' . time() . '_' . unique_id(); @@ -379,13 +408,25 @@ else $extensions = array(); $files_added = 0; $forum_id = ($attachment['in_message']) ? false : (int) $row['forum_id']; - $disallowed = array(); + $disallowed_extension = array(); foreach ($attachments as $attach) { if (!extension_allowed($forum_id, $attach['extension'], $extensions)) { - $disallowed[$attach['extension']] = $attach['extension']; + $disallowed_extension[$attach['extension']] = $attach['extension']; + continue; + } + + if ($post_id && $row['post_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $forum_id)) + { + // Attachment of a soft deleted post and the user is not allowed to see the post + continue; + } + + if ($topic_id && (!isset($post_visibility[$attach['post_msg_id']]) || $post_visibility[$attach['post_msg_id']] != ITEM_APPROVED) && !$auth->acl_get('m_approve', $forum_id)) + { + // Attachment of a soft deleted post and the user is not allowed to see the post continue; } @@ -409,12 +450,17 @@ else unlink($archive_path); - if (!$files_added) + if (!$files_added && !empty($disallowed_extension)) { // None of the attachments had a valid extension - $disallowed = implode($user->lang['COMMA_SEPARATOR'], $disallowed); - send_status_line(404, 'Forbidden'); - trigger_error($user->lang('EXTENSION_DISABLED_AFTER_POSTING', $disallowed)); + $disallowed_extension = implode($user->lang['COMMA_SEPARATOR'], $disallowed_extension); + send_status_line(403, 'Forbidden'); + trigger_error($user->lang('EXTENSION_DISABLED_AFTER_POSTING', $disallowed_extension)); + } + else if (!$files_added) + { + send_status_line(404, 'Not Found'); + trigger_error('ERROR_NO_ATTACHMENT'); } file_gc(); diff --git a/phpBB/faq.php b/phpBB/faq.php index 052f78816e..19be7da43a 100644 --- a/phpBB/faq.php +++ b/phpBB/faq.php @@ -74,9 +74,10 @@ $template->assign_vars(array( 'L_BACK_TO_TOP' => $user->lang['BACK_TO_TOP'], 'SWITCH_COLUMN_MANUALLY' => (!$found_switch) ? true : false, + 'S_IN_FAQ' => true, )); -page_header($l_title, false); +page_header($l_title); $template->set_filenames(array( 'body' => 'faq_body.html') diff --git a/phpBB/feed.php b/phpBB/feed.php index 35cd7fda3f..9ff8c66b9d 100644 --- a/phpBB/feed.php +++ b/phpBB/feed.php @@ -18,6 +18,7 @@ define('IN_PHPBB', true); $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './'; $phpEx = substr(strrchr(__FILE__, '.'), 1); include($phpbb_root_path . 'common.' . $phpEx); +include($phpbb_root_path . 'includes/functions_display.' . $phpEx); if (!$config['feed_enable']) { @@ -36,7 +37,7 @@ if (!empty($config['feed_http_auth']) && request_var('auth', '') == 'http') } $auth->acl($user->data); -$user->setup(); +$user->setup('viewtopic'); // Initial var setup $forum_id = request_var('f', 0); @@ -72,6 +73,9 @@ if ($feed === false) trigger_error('NO_FEED'); } +// Get attachments for this feed +$feed->fetch_attachments(); + // Open Feed $feed->open(); @@ -107,7 +111,7 @@ while ($row = $feed->get_item()) 'title' => censor_text($title), 'category' => ($config['feed_item_statistics'] && !empty($row['forum_id'])) ? $board_url . '/viewforum.' . $phpEx . '?f=' . $row['forum_id'] : '', 'category_name' => ($config['feed_item_statistics'] && isset($row['forum_name'])) ? $row['forum_name'] : '', - 'description' => censor_text($phpbb_feed_helper->generate_content($row[$feed->get('text')], $row[$feed->get('bbcode_uid')], $row[$feed->get('bitfield')], $options)), + 'description' => censor_text($phpbb_feed_helper->generate_content($row[$feed->get('text')], $row[$feed->get('bbcode_uid')], $row[$feed->get('bitfield')], $options, $row['forum_id'], (($row['post_attachment']) ? $feed->attachments[$row['post_id']] : array()))), 'statistics' => '', ); diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 55459739ca..1aaf1f9c09 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -20,14 +20,37 @@ if (!defined('IN_PHPBB')) */ class acp_attachments { - var $u_action; - var $new_config; + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\config\config */ + protected $config; + + /** @var ContainerBuilder */ + protected $phpbb_container; + + /** @var \phpbb\template\template */ + protected $template; + + /** @var \phpbb\user */ + protected $user; + + public $id; + public $u_action; + protected $new_config; function main($id, $mode) { - global $db, $user, $auth, $template, $cache; + global $db, $user, $auth, $template, $cache, $phpbb_container; global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx; + $this->id = $id; + $this->db = $db; + $this->config = $config; + $this->template = $template; + $this->user = $user; + $this->phpbb_container = $phpbb_container; + $user->add_lang(array('posting', 'viewtopic', 'acp/attachments')); $error = $notify = array(); @@ -124,7 +147,6 @@ class acp_attachments 'secure_allow_empty_referer' => array('lang' => 'SECURE_EMPTY_REFERRER', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'check_attachment_content' => array('lang' => 'CHECK_CONTENT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'legend2' => $l_legend_cat_images, 'img_display_inlined' => array('lang' => 'DISPLAY_INLINED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'img_create_thumbnail' => array('lang' => 'CREATE_THUMBNAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), @@ -748,7 +770,6 @@ class acp_attachments } $template->assign_vars(array( - 'PHPBB_ROOT_PATH' => $phpbb_root_path, 'IMG_PATH' => $img_path, 'ACTION' => $action, 'GROUP_ID' => $group_id, @@ -1083,9 +1104,21 @@ class acp_attachments } } + if ($action == 'stats') + { + $this->handle_stats_resync(); + } + + $stats_error = $this->check_stats_accuracy(); + + if ($stats_error) + { + $error[] = $stats_error; + } + $template->assign_vars(array( - 'S_MANAGE' => true) - ); + 'S_MANAGE' => true, + )); $start = request_var('start', 0); @@ -1108,69 +1141,13 @@ class acp_attachments $attachments_per_page = (int) $config['topics_per_page']; - // Handle files stats resync - $action = request_var('action', ''); - $resync_files_stats = false; - if ($action && $action = 'stats') - { - if (!confirm_box(true)) - { - confirm_box(false, $user->lang['RESYNC_FILES_STATS_CONFIRM'], build_hidden_fields(array( - 'i' => $id, - 'mode' => $mode, - 'action' => $action, - ))); - } - else - { - $resync_files_stats = true; - add_log('admin', 'LOG_RESYNC_FILES_STATS'); - } - } - - // Check if files stats are accurate - $sql = 'SELECT COUNT(attach_id) as num_files - FROM ' . ATTACHMENTS_TABLE . ' - WHERE is_orphan = 0'; - $result = $db->sql_query($sql, 600); - $num_files_real = (int) $db->sql_fetchfield('num_files'); - if ($resync_files_stats === true) - { - set_config('num_files', $num_files_real, true); - } - $db->sql_freeresult($result); - - $sql = 'SELECT SUM(filesize) as upload_dir_size - FROM ' . ATTACHMENTS_TABLE . ' - WHERE is_orphan = 0'; - $result = $db->sql_query($sql, 600); - $total_size_real = (float) $db->sql_fetchfield('upload_dir_size'); - if ($resync_files_stats === true) - { - set_config('upload_dir_size', $total_size_real, true); - } - $db->sql_freeresult($result); - - // Get current files stats - $num_files = (int) $config['num_files']; - $total_size = (float) $config['upload_dir_size']; - - // Issue warning message if files stats are inaccurate - if (($num_files != $num_files_real) || ($total_size != $total_size_real)) - { - $error[] = $user->lang('FILES_STATS_WRONG', (int) $num_files_real, get_formatted_filesize($total_size_real)); - - $template->assign_vars(array( - 'S_ACTION_OPTIONS' => ($auth->acl_get('a_board')) ? true : false, - 'U_ACTION' => $this->u_action,) - ); - } + $stats = $this->get_attachment_stats($limit_filetime); + $num_files = $stats['num_files']; + $total_size = $stats['upload_dir_size']; // Make sure $start is set to the last page if it exceeds the amount - if ($start < 0 || $start > $num_files) - { - $start = ($start < 0) ? 0 : floor(($num_files - 1) / $attachments_per_page) * $attachments_per_page; - } + $pagination = $phpbb_container->get('pagination'); + $start = $pagination->validate_start($start, $attachments_per_page, $num_files); // If the user is trying to reach the second half of the attachments list, fetch it starting from the end $store_reverse = false; @@ -1180,15 +1157,11 @@ class acp_attachments { $store_reverse = true; - if ($start + $attachments_per_page > $num_files) - { - $sql_limit = min($attachments_per_page, max(1, $num_files - $start)); - } - // Select the sort order. Add time sort anchor for non-time sorting cases $sql_sort_anchor = ($sort_key != 't') ? ', a.filetime ' . (($sort_dir == 'd') ? 'ASC' : 'DESC') : ''; $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'ASC' : 'DESC') . $sql_sort_anchor; - $sql_start = max(0, $num_files - $sql_limit - $start); + $sql_limit = $pagination->reverse_limit($start, $sql_limit, $num_files); + $sql_start = $pagination->reverse_start($start, $sql_limit, $num_files); } else { @@ -1196,7 +1169,6 @@ class acp_attachments $sql_sort_anchor = ($sort_key != 't') ? ', a.filetime ' . (($sort_dir == 'd') ? 'DESC' : 'ASC') : ''; $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC') . $sql_sort_anchor; $sql_start = $start; - } $attachments_list = array(); @@ -1223,13 +1195,12 @@ class acp_attachments $db->sql_freeresult($result); $base_url = $this->u_action . "&$u_sort_param"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_files, $attachments_per_page, $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $num_files, $attachments_per_page, $start); $template->assign_vars(array( 'TOTAL_FILES' => $num_files, 'TOTAL_SIZE' => get_formatted_filesize($total_size), - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $num_files, $attachments_per_page, $start), 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir) @@ -1291,6 +1262,97 @@ class acp_attachments } /** + * Get attachment file count and size of upload directory + * + * @param $limit string Additional limit for WHERE clause to filter stats by. + * @return array Returns array with stats: num_files and upload_dir_size + */ + public function get_attachment_stats($limit = '') + { + $sql = 'SELECT COUNT(a.attach_id) AS num_files, SUM(a.filesize) AS upload_dir_size + FROM ' . ATTACHMENTS_TABLE . " a + WHERE a.is_orphan = 0 + $limit"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + return array( + 'num_files' => (int) $row['num_files'], + 'upload_dir_size' => (float) $row['upload_dir_size'], + ); + } + + /** + * Set config attachment stat values + * + * @param $stats array Array of config key => value pairs to set. + * @return null + */ + public function set_attachment_stats($stats) + { + foreach ($stats as $key => $value) + { + $this->config->set($key, $value, true); + } + } + + /** + * Check accuracy of attachment statistics. + * + * @param $resync bool Resync stats if they're incorrect. + * @return bool|string Returns false if stats are correct or error message + * otherwise. + */ + public function check_stats_accuracy() + { + // Get fresh stats. + $stats = $this->get_attachment_stats(); + + // Get current files stats + $num_files = (int) $this->config['num_files']; + $total_size = (float) $this->config['upload_dir_size']; + + if (($num_files != $stats['num_files']) || ($total_size != $stats['upload_dir_size'])) + { + $u_resync = $this->u_action . '&action=stats'; + + return $this->user->lang( + 'FILES_STATS_WRONG', + (int) $stats['num_files'], + get_formatted_filesize($stats['upload_dir_size']), + '<a href="' . $u_resync . '">', + '</a>' + ); + } + return false; + } + + /** + * Handle stats resync. + * + * @return null + */ + public function handle_stats_resync() + { + if (!confirm_box(true)) + { + confirm_box(false, $this->user->lang['RESYNC_FILES_STATS_CONFIRM'], build_hidden_fields(array( + 'i' => $this->id, + 'mode' => 'manage', + 'action' => 'stats', + ))); + } + else + { + $this->set_attachment_stats($this->get_attachment_stats()); + $log = $this->phpbb_container->get('log'); + $log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_RESYNC_FILES_STATS'); + } + + } + + /** * Build Select for category items */ function category_select($select_name, $group_id = false, $key = '') diff --git a/phpBB/includes/acp/acp_ban.php b/phpBB/includes/acp/acp_ban.php index 3ed9c225f5..41095f1382 100644 --- a/phpBB/includes/acp/acp_ban.php +++ b/phpBB/includes/acp/acp_ban.php @@ -109,7 +109,7 @@ class acp_ban 'L_NO_BAN_CELL' => $l_no_ban_cell, 'S_USERNAME_BAN' => ($mode == 'user') ? true : false, - + 'U_ACTION' => $this->u_action, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_ban&field=ban'), )); diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php index dca39df38c..4b9072d12a 100644 --- a/phpBB/includes/acp/acp_bbcodes.php +++ b/phpBB/includes/acp/acp_bbcodes.php @@ -24,7 +24,7 @@ class acp_bbcodes function main($id, $mode) { - global $db, $user, $auth, $template, $cache, $request; + global $db, $user, $auth, $template, $cache, $request, $phpbb_dispatcher; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/posting'); @@ -96,7 +96,7 @@ class acp_bbcodes case 'edit': case 'add': - $template->assign_vars(array( + $tpl_ary = array( 'S_EDIT_BBCODE' => true, 'U_BACK' => $this->u_action, 'U_ACTION' => $this->u_action . '&action=' . (($action == 'add') ? 'create' : 'modify') . (($bbcode_id) ? "&bbcode=$bbcode_id" : ''), @@ -105,14 +105,32 @@ class acp_bbcodes 'BBCODE_MATCH' => $bbcode_match, 'BBCODE_TPL' => $bbcode_tpl, 'BBCODE_HELPLINE' => $bbcode_helpline, - 'DISPLAY_ON_POSTING' => $display_on_posting) + 'DISPLAY_ON_POSTING' => $display_on_posting, ); - foreach ($user->lang['tokens'] as $token => $token_explain) + $bbcode_tokens = array('TEXT', 'SIMPLETEXT', 'INTTEXT', 'IDENTIFIER', 'NUMBER', 'EMAIL', 'URL', 'LOCAL_URL', 'RELATIVE_URL', 'COLOR'); + + /** + * Modify custom bbcode template data before we display the add/edit form + * + * @event core.acp_bbcodes_edit_add + * @var string action Type of the action: add|edit + * @var array tpl_ary Array with custom bbcode add/edit data + * @var int bbcode_id When editing: the bbcode id, + * when creating: 0 + * @var array bbcode_tokens Array of bbcode tokens + * @since 3.1.0-a3 + */ + $vars = array('action', 'tpl_ary', 'bbcode_id', 'bbcode_tokens'); + extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_edit_add', compact($vars))); + + $template->assign_vars($tpl_ary); + + foreach ($bbcode_tokens as $token) { $template->assign_block_vars('token', array( 'TOKEN' => '{' . $token . '}', - 'EXPLAIN' => ($token === 'LOCAL_URL') ? sprintf($token_explain, generate_board_url() . '/') : $token_explain, + 'EXPLAIN' => ($token === 'LOCAL_URL') ? $user->lang(array('tokens', $token), generate_board_url() . '/') : $user->lang(array('tokens', $token)), )); } @@ -123,6 +141,36 @@ class acp_bbcodes case 'modify': case 'create': + $sql_ary = $hidden_fields = array(); + + /** + * Modify custom bbcode data before the modify/create action + * + * @event core.acp_bbcodes_modify_create + * @var string action Type of the action: modify|create + * @var array sql_ary Array with new bbcode data + * @var int bbcode_id When editing: the bbcode id, + * when creating: 0 + * @var bool display_on_posting Display bbcode on posting form + * @var string bbcode_match The bbcode usage string to match + * @var string bbcode_tpl The bbcode HTML replacement string + * @var string bbcode_helpline The bbcode help line string + * @var array hidden_fields Array of hidden fields for use when + * submitting form when $warn_text is true + * @since 3.1.0-a3 + */ + $vars = array( + 'action', + 'sql_ary', + 'bbcode_id', + 'display_on_posting', + 'bbcode_match', + 'bbcode_tpl', + 'bbcode_helpline', + 'hidden_fields', + ); + extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_modify_create', compact($vars))); + $warn_text = preg_match('%<[^>]*\{text[\d]*\}[^>]*>%i', $bbcode_tpl); if (!$warn_text || confirm_box(true)) { @@ -171,13 +219,12 @@ class acp_bbcodes trigger_error($user->lang['BBCODE_TAG_DEF_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING); } - if (strlen($bbcode_helpline) > 255) { trigger_error($user->lang['BBCODE_HELPLINE_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING); } - $sql_ary = array( + $sql_ary = array_merge($sql_ary, array( 'bbcode_tag' => $data['bbcode_tag'], 'bbcode_match' => $bbcode_match, 'bbcode_tpl' => $bbcode_tpl, @@ -187,7 +234,7 @@ class acp_bbcodes 'first_pass_replace' => $data['first_pass_replace'], 'second_pass_match' => $data['second_pass_match'], 'second_pass_replace' => $data['second_pass_replace'] - ); + )); if ($action == 'create') { @@ -243,14 +290,14 @@ class acp_bbcodes } else { - confirm_box(false, $user->lang['BBCODE_DANGER'], build_hidden_fields(array( + confirm_box(false, $user->lang['BBCODE_DANGER'], build_hidden_fields(array_merge($hidden_fields, array( 'action' => $action, 'bbcode' => $bbcode_id, 'bbcode_match' => $bbcode_match, 'bbcode_tpl' => htmlspecialchars($bbcode_tpl), 'bbcode_helpline' => $bbcode_helpline, 'display_on_posting' => $display_on_posting, - )) + ))) , 'confirm_bbcode.html'); } @@ -272,7 +319,7 @@ class acp_bbcodes $db->sql_query('DELETE FROM ' . BBCODES_TABLE . " WHERE bbcode_id = $bbcode_id"); $cache->destroy('sql', BBCODES_TABLE); add_log('admin', 'LOG_BBCODE_DELETE', $row['bbcode_tag']); - + if ($request->is_ajax()) { $json_response = new \phpbb\json_response; @@ -299,22 +346,57 @@ class acp_bbcodes break; } - $template->assign_vars(array( - 'U_ACTION' => $this->u_action . '&action=add') + $u_action = $this->u_action; + + $template_data = array( + 'U_ACTION' => $this->u_action . '&action=add', ); - $sql = 'SELECT * - FROM ' . BBCODES_TABLE . ' - ORDER BY bbcode_tag'; - $result = $db->sql_query($sql); + $sql_ary = array( + 'SELECT' => 'b.*', + 'FROM' => array(BBCODES_TABLE => 'b'), + 'ORDER_BY' => 'b.bbcode_tag', + ); + + /** + * Modify custom bbcode template data before we display the form + * + * @event core.acp_bbcodes_display_form + * @var string action Type of the action: modify|create + * @var string sql_ary The SQL array to get custom bbcode data + * @var array template_data Array with form template data + * @var string u_action The u_action link + * @since 3.1.0-a3 + */ + $vars = array('action', 'sql_ary', 'template_data', 'u_action'); + extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_display_form', compact($vars))); + + $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary)); + + $template->assign_vars($template_data); while ($row = $db->sql_fetchrow($result)) { - $template->assign_block_vars('bbcodes', array( + $bbcodes_array = array( 'BBCODE_TAG' => $row['bbcode_tag'], - 'U_EDIT' => $this->u_action . '&action=edit&bbcode=' . $row['bbcode_id'], - 'U_DELETE' => $this->u_action . '&action=delete&bbcode=' . $row['bbcode_id']) + 'U_EDIT' => $u_action . '&action=edit&bbcode=' . $row['bbcode_id'], + 'U_DELETE' => $u_action . '&action=delete&bbcode=' . $row['bbcode_id'], ); + + /** + * Modify display of custom bbcodes in the form + * + * @event core.acp_bbcodes_display_bbcodes + * @var array row Array with current bbcode data + * @var array bbcodes_array Array of bbcodes template data + * @var string u_action The u_action link + * @since 3.1.0-a3 + */ + $vars = array('bbcodes_array', 'row', 'u_action'); + extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_display_bbcodes', compact($vars))); + + $template->assign_block_vars('bbcodes', $bbcodes_array); + } $db->sql_freeresult($result); } diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 8f2548166b..6b52fbbdb2 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -28,7 +28,7 @@ class acp_board { global $db, $user, $auth, $template; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; - global $cache, $phpbb_container; + global $cache, $phpbb_container, $phpbb_dispatcher; $user->add_lang('acp/board'); @@ -344,7 +344,7 @@ class acp_board 'load_jumpbox' => array('lang' => 'YES_JUMPBOX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_user_activity' => array('lang' => 'LOAD_USER_ACTIVITY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_tplcompile' => array('lang' => 'RECOMPILE_STYLES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'load_jquery_cdn' => array('lang' => 'LOAD_JQUERY_CDN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'allow_cdn' => array('lang' => 'ALLOW_CDN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'legend3' => 'CUSTOM_PROFILE_FIELDS', 'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), @@ -434,6 +434,7 @@ class acp_board 'email_function_name' => array('lang' => 'EMAIL_FUNCTION_NAME', 'validate' => 'string', 'type' => 'text:20:50', 'explain' => true), 'email_package_size' => array('lang' => 'EMAIL_PACKAGE_SIZE', 'validate' => 'int:0', 'type' => 'number:0:99999', 'explain' => true), 'board_contact' => array('lang' => 'CONTACT_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true), + 'board_contact_name' => array('lang' => 'CONTACT_EMAIL_NAME', 'validate' => 'string', 'type' => 'text:25:50', 'explain' => true), 'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true), 'board_email_sig' => array('lang' => 'EMAIL_SIG', 'validate' => 'string', 'type' => 'textarea:5:30', 'explain' => true), 'board_hide_emails' => array('lang' => 'BOARD_HIDE_EMAILS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), @@ -456,6 +457,18 @@ class acp_board break; } + /** + * Event to add and/or modify acp_board configurations + * + * @event core.acp_board_config_edit_add + * @var array display_vars Array of config values to display and process + * @var string mode Mode of the config page we are displaying + * @var boolean submit Do we display the form or process the submission + * @since 3.1.0-a4 + */ + $vars = array('display_vars', 'mode', 'submit'); + extract($phpbb_dispatcher->trigger_event('core.acp_board_config_edit_add', compact($vars))); + if (isset($display_vars['lang'])) { $user->add_lang($display_vars['lang']); @@ -763,8 +776,8 @@ class acp_board global $user, $config; $act_ary = array( - 'ACC_DISABLE' => USER_ACTIVATION_DISABLE, - 'ACC_NONE' => USER_ACTIVATION_NONE, + 'ACC_DISABLE' => USER_ACTIVATION_DISABLE, + 'ACC_NONE' => USER_ACTIVATION_NONE, ); if ($config['email_enable']) { diff --git a/phpBB/includes/acp/acp_bots.php b/phpBB/includes/acp/acp_bots.php index e28a8d6451..7384f719bf 100644 --- a/phpBB/includes/acp/acp_bots.php +++ b/phpBB/includes/acp/acp_bots.php @@ -157,7 +157,7 @@ class acp_bots { $error[] = $user->lang['ERR_BOT_NO_MATCHES']; } - + if ($bot_row['bot_ip'] && !preg_match('#^[\d\.,:]+$#', $bot_row['bot_ip'])) { if (!$ip_list = gethostbynamel($bot_row['bot_ip'])) @@ -176,7 +176,7 @@ class acp_bots { $error[] = $user->lang['ERR_BOT_AGENT_MATCHES_UA']; } - + $bot_name = false; if ($bot_id) { @@ -201,7 +201,7 @@ class acp_bots { $error[] = $user->lang['BOT_NAME_TAKEN']; } - + if (!sizeof($error)) { // New bot? Create a new user and group entry @@ -219,7 +219,6 @@ class acp_bots { trigger_error($user->lang['NO_BOT_GROUP'] . adm_back_link($this->u_action . "&id=$bot_id&action=$action"), E_USER_WARNING); } - $user_id = user_add(array( 'user_type' => (int) USER_IGNORE, @@ -233,7 +232,7 @@ class acp_bots 'user_style' => (int) $bot_row['bot_style'], 'user_allow_massemail' => 0, )); - + $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( 'user_id' => (int) $user_id, 'bot_name' => (string) $bot_row['bot_name'], @@ -242,7 +241,7 @@ class acp_bots 'bot_ip' => (string) $bot_row['bot_ip']) ); $db->sql_query($sql); - + $log = 'ADDED'; } else if ($bot_id) @@ -289,12 +288,12 @@ class acp_bots $log = 'UPDATED'; } - + $cache->destroy('_bots'); - + add_log('admin', 'LOG_BOT_' . $log, $bot_row['bot_name']); trigger_error($user->lang['BOT_' . $log] . adm_back_link($this->u_action)); - + } } else if ($bot_id) @@ -335,11 +334,11 @@ class acp_bots 'U_ACTION' => $this->u_action . "&id=$bot_id&action=$action", 'U_BACK' => $this->u_action, 'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '', - + 'BOT_NAME' => $bot_row['bot_name'], 'BOT_IP' => $bot_row['bot_ip'], 'BOT_AGENT' => $bot_row['bot_agent'], - + 'S_EDIT_BOT' => true, 'S_ACTIVE_OPTIONS' => $s_active_options, 'S_STYLE_OPTIONS' => $style_select, @@ -352,7 +351,7 @@ class acp_bots break; } - + if ($request->is_ajax() && ($action == 'activate' || $action == 'deactivate')) { $json_response = new \phpbb\json_response; @@ -397,7 +396,7 @@ class acp_bots } $db->sql_freeresult($result); } - + /** * Validate bot name against username table */ @@ -417,7 +416,7 @@ class acp_bots $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - + return ($row) ? false : true; } } diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php index 1a083c20ac..71defda09f 100644 --- a/phpBB/includes/acp/acp_captcha.php +++ b/phpBB/includes/acp/acp_captcha.php @@ -36,7 +36,6 @@ class acp_captcha $selected = (isset($captchas['available'][$selected]) || isset($captchas['unavailable'][$selected])) ? $selected : $config['captcha_plugin']; $configure = request_var('configure', false); - // Oh, they are just here for the view if (isset($_GET['captcha_demo'])) { diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php index fc08a5fb94..d28ee5b067 100644 --- a/phpBB/includes/acp/acp_database.php +++ b/phpBB/includes/acp/acp_database.php @@ -94,29 +94,29 @@ class acp_database case 'mysqli': case 'mysql4': case 'mysql': - $extractor = new mysql_extractor($download, $store, $format, $filename, $time); + $extractor = new mysql_extractor($format, $filename, $time, $download, $store); break; case 'sqlite': - $extractor = new sqlite_extractor($download, $store, $format, $filename, $time); + $extractor = new sqlite_extractor($format, $filename, $time, $download, $store); break; case 'postgres': - $extractor = new postgres_extractor($download, $store, $format, $filename, $time); + $extractor = new postgres_extractor($format, $filename, $time, $download, $store); break; case 'oracle': - $extractor = new oracle_extractor($download, $store, $format, $filename, $time); + $extractor = new oracle_extractor($format, $filename, $time, $download, $store); break; case 'mssql': case 'mssql_odbc': case 'mssqlnative': - $extractor = new mssql_extractor($download, $store, $format, $filename, $time); + $extractor = new mssql_extractor($format, $filename, $time, $download, $store); break; case 'firebird': - $extractor = new firebird_extractor($download, $store, $format, $filename, $time); + $extractor = new firebird_extractor($format, $filename, $time, $download, $store); break; } @@ -488,7 +488,7 @@ class base_extractor var $format; var $run_comp = false; - function base_extractor($download = false, $store = false, $format, $filename, $time) + function base_extractor($format, $filename, $time, $download = false, $store = false) { global $request; @@ -1180,7 +1180,6 @@ class postgres_extractor extends base_extractor } $db->sql_freeresult($result); - // Get the listing of primary keys. $sql_pri_keys = "SELECT ic.relname as index_name, bc.relname as tab_name, ta.attname as column_name, i.indisunique as unique_key, i.indisprimary as primary_key FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia @@ -1280,7 +1279,6 @@ class postgres_extractor extends base_extractor $ary_type[] = pg_field_type($result, $i); $ary_name[] = pg_field_name($result, $i); - $sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault FROM pg_attrdef d, pg_class c WHERE (c.relname = '{$table_name}') @@ -1607,16 +1605,17 @@ class mssql_extractor extends base_extractor return; } - $sql = "SELECT * FROM $table_name"; - $result_fields = $db->sql_query_limit($sql, 1); - - $row = new result_mssqlnative($result_fields); - $i_num_fields = $row->num_fields(); + $sql = "SELECT COLUMN_NAME, DATA_TYPE + FROM INFORMATION_SCHEMA.COLUMNS + WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = '" . $db->sql_escape($table_name) . "'"; + $result_fields = $db->sql_query($sql); - for ($i = 0; $i < $i_num_fields; $i++) + $i_num_fields = 0; + while ($row = $db->sql_fetchrow($result_fields)) { - $ary_type[$i] = $row->field_type($i); - $ary_name[$i] = $row->field_name($i); + $ary_type[$i_num_fields] = $row['DATA_TYPE']; + $ary_name[$i_num_fields] = $row['COLUMN_NAME']; + $i_num_fields++; } $db->sql_freeresult($result_fields); diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index b41f4d4e81..21a1909ac1 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -55,6 +55,11 @@ class acp_extensions $ext_name = ''; } + if (in_array($action, array('enable', 'disable', 'delete_data')) && !check_link_hash($request->variable('hash', ''), $action . '.' . $ext_name)) + { + trigger_error('FORM_INVALID', E_USER_WARNING); + } + // If they've specified an extension, let's load the metadata manager and validate it. if ($ext_name) { @@ -66,7 +71,7 @@ class acp_extensions } catch(\phpbb\extension\exception $e) { - trigger_error($e); + trigger_error($e, E_USER_WARNING); } } @@ -83,6 +88,11 @@ class acp_extensions break; case 'enable_pre': + if (!$md_manager->validate_dir()) + { + trigger_error($user->lang['EXTENSION_DIR_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + if (!$md_manager->validate_enable()) { trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING); @@ -96,12 +106,18 @@ class acp_extensions $this->tpl_name = 'acp_ext_enable'; $template->assign_vars(array( - 'PRE' => true, - 'U_ENABLE' => $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name), + 'PRE' => true, + 'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_ENABLE_CONFIRM', $md_manager->get_metadata('display-name')), + 'U_ENABLE' => $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('enable.' . $ext_name), )); break; case 'enable': + if (!$md_manager->validate_dir()) + { + trigger_error($user->lang['EXTENSION_DIR_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + if (!$md_manager->validate_enable()) { trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING); @@ -116,7 +132,7 @@ class acp_extensions { $template->assign_var('S_NEXT_STEP', true); - meta_refresh(0, $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name)); + meta_refresh(0, $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('enable.' . $ext_name)); } } } @@ -128,7 +144,7 @@ class acp_extensions $this->tpl_name = 'acp_ext_enable'; $template->assign_vars(array( - 'U_RETURN' => $this->u_action . '&action=list', + 'U_RETURN' => $this->u_action . '&action=list', )); break; @@ -141,8 +157,9 @@ class acp_extensions $this->tpl_name = 'acp_ext_disable'; $template->assign_vars(array( - 'PRE' => true, - 'U_DISABLE' => $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name), + 'PRE' => true, + 'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_DISABLE_CONFIRM', $md_manager->get_metadata('display-name')), + 'U_DISABLE' => $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('disable.' . $ext_name), )); break; @@ -154,7 +171,7 @@ class acp_extensions { $template->assign_var('S_NEXT_STEP', true); - meta_refresh(0, $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name)); + meta_refresh(0, $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('disable.' . $ext_name)); } } @@ -165,16 +182,21 @@ class acp_extensions )); break; - case 'purge_pre': - $this->tpl_name = 'acp_ext_purge'; + case 'delete_data_pre': + if ($phpbb_extension_manager->enabled($ext_name)) + { + redirect($this->u_action); + } + $this->tpl_name = 'acp_ext_delete_data'; $template->assign_vars(array( - 'PRE' => true, - 'U_PURGE' => $this->u_action . '&action=purge&ext_name=' . urlencode($ext_name), + 'PRE' => true, + 'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_DELETE_DATA_CONFIRM', $md_manager->get_metadata('display-name')), + 'U_PURGE' => $this->u_action . '&action=delete_data&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('delete_data.' . $ext_name), )); break; - case 'purge': + case 'delete_data': try { while ($phpbb_extension_manager->purge_step($ext_name)) @@ -184,7 +206,7 @@ class acp_extensions { $template->assign_var('S_NEXT_STEP', true); - meta_refresh(0, $this->u_action . '&action=purge&ext_name=' . urlencode($ext_name)); + meta_refresh(0, $this->u_action . '&action=delete_data&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('delete_data.' . $ext_name)); } } } @@ -193,7 +215,7 @@ class acp_extensions $template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user)); } - $this->tpl_name = 'acp_ext_purge'; + $this->tpl_name = 'acp_ext_delete_data'; $template->assign_vars(array( 'U_RETURN' => $this->u_action . '&action=list', @@ -219,22 +241,15 @@ class acp_extensions */ public function list_enabled_exts(\phpbb\extension\manager $phpbb_extension_manager) { + $enabled_extension_meta_data = array(); + foreach ($phpbb_extension_manager->all_enabled() as $name => $location) { $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template); try { - $this->template->assign_block_vars('enabled', array( - 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), - - 'U_DETAILS' => $this->u_action . '&action=details&ext_name=' . urlencode($name), - )); - - $this->output_actions('enabled', array( - 'DISABLE' => $this->u_action . '&action=disable_pre&ext_name=' . urlencode($name), - 'PURGE' => $this->u_action . '&action=purge_pre&ext_name=' . urlencode($name), - )); + $enabled_extension_meta_data[$name] = $md_manager->get_metadata('display-name'); } catch(\phpbb\extension\exception $e) { @@ -243,6 +258,21 @@ class acp_extensions )); } } + + natcasesort($enabled_extension_meta_data); + + foreach ($enabled_extension_meta_data as $name => $display_name) + { + $this->template->assign_block_vars('enabled', array( + 'META_DISPLAY_NAME' => $display_name, + + 'U_DETAILS' => $this->u_action . '&action=details&ext_name=' . urlencode($name), + )); + + $this->output_actions('enabled', array( + 'DISABLE' => $this->u_action . '&action=disable_pre&ext_name=' . urlencode($name), + )); + } } /** @@ -253,22 +283,15 @@ class acp_extensions */ public function list_disabled_exts(\phpbb\extension\manager $phpbb_extension_manager) { + $disabled_extension_meta_data = array(); + foreach ($phpbb_extension_manager->all_disabled() as $name => $location) { $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template); try { - $this->template->assign_block_vars('disabled', array( - 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), - - 'U_DETAILS' => $this->u_action . '&action=details&ext_name=' . urlencode($name), - )); - - $this->output_actions('disabled', array( - 'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name), - 'PURGE' => $this->u_action . '&action=purge_pre&ext_name=' . urlencode($name), - )); + $disabled_extension_meta_data[$name] = $md_manager->get_metadata('display-name'); } catch(\phpbb\extension\exception $e) { @@ -277,6 +300,22 @@ class acp_extensions )); } } + + natcasesort($disabled_extension_meta_data); + + foreach ($disabled_extension_meta_data as $name => $display_name) + { + $this->template->assign_block_vars('disabled', array( + 'META_DISPLAY_NAME' => $display_name, + + 'U_DETAILS' => $this->u_action . '&action=details&ext_name=' . urlencode($name), + )); + + $this->output_actions('disabled', array( + 'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name), + 'DELETE_DATA' => $this->u_action . '&action=delete_data_pre&ext_name=' . urlencode($name), + )); + } } /** @@ -289,21 +328,15 @@ class acp_extensions { $uninstalled = array_diff_key($phpbb_extension_manager->all_available(), $phpbb_extension_manager->all_configured()); + $available_extension_meta_data = array(); + foreach ($uninstalled as $name => $location) { $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template); try { - $this->template->assign_block_vars('disabled', array( - 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), - - 'U_DETAILS' => $this->u_action . '&action=details&ext_name=' . urlencode($name), - )); - - $this->output_actions('disabled', array( - 'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name), - )); + $available_extension_meta_data[$name] = $md_manager->get_metadata('display-name'); } catch(\phpbb\extension\exception $e) { @@ -312,6 +345,21 @@ class acp_extensions )); } } + + natcasesort($available_extension_meta_data); + + foreach ($available_extension_meta_data as $name => $display_name) + { + $this->template->assign_block_vars('disabled', array( + 'META_DISPLAY_NAME' => $display_name, + + 'U_DETAILS' => $this->u_action . '&action=details&ext_name=' . urlencode($name), + )); + + $this->output_actions('disabled', array( + 'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name), + )); + } } /** @@ -325,8 +373,9 @@ class acp_extensions foreach ($actions as $lang => $url) { $this->template->assign_block_vars($block . '.actions', array( - 'L_ACTION' => $this->user->lang($lang), - 'U_ACTION' => $url, + 'L_ACTION' => $this->user->lang('EXTENSION_' . $lang), + 'L_ACTION_EXPLAIN' => (isset($this->user->lang['EXTENSION_' . $lang . '_EXPLAIN'])) ? $this->user->lang('EXTENSION_' . $lang . '_EXPLAIN') : '', + 'U_ACTION' => $url, )); } } diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index 258aabcc0d..160bfc05de 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -138,12 +138,15 @@ class acp_forums 'enable_prune' => request_var('enable_prune', false), 'enable_post_review' => request_var('enable_post_review', true), 'enable_quick_reply' => request_var('enable_quick_reply', false), + 'enable_shadow_prune' => request_var('enable_shadow_prune', false), 'prune_days' => request_var('prune_days', 7), 'prune_viewed' => request_var('prune_viewed', 7), 'prune_freq' => request_var('prune_freq', 1), 'prune_old_polls' => request_var('prune_old_polls', false), 'prune_announce' => request_var('prune_announce', false), 'prune_sticky' => request_var('prune_sticky', false), + 'prune_shadow_days' => request_var('prune_shadow_days', 7), + 'prune_shadow_freq' => request_var('prune_shadow_freq', 1), 'forum_password' => request_var('forum_password', '', true), 'forum_password_confirm'=> request_var('forum_password_confirm', '', true), 'forum_password_unset' => request_var('forum_password_unset', false), @@ -155,7 +158,7 @@ class acp_forums * @event core.acp_manage_forums_request_data * @var string action Type of the action: add|edit * @var array forum_data Array with new forum data - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('action', 'forum_data'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_request_data', compact($vars))); @@ -457,6 +460,9 @@ class acp_forums 'prune_days' => 7, 'prune_viewed' => 7, 'prune_freq' => 1, + 'enable_shadow_prune' => false, + 'prune_shadow_days' => 7, + 'prune_shadow_freq' => 1, 'forum_flags' => FORUM_FLAG_POST_REVIEW + FORUM_FLAG_ACTIVE_TOPICS, 'forum_options' => 0, 'forum_password' => '', @@ -478,7 +484,7 @@ class acp_forums * empty when creating new forum * @var array forum_data Array with new forum data * @var string parents_list List of parent options - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('action', 'update', 'forum_id', 'row', 'forum_data', 'parents_list'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_initialise_data', compact($vars))); @@ -636,6 +642,8 @@ class acp_forums 'PRUNE_FREQ' => $forum_data['prune_freq'], 'PRUNE_DAYS' => $forum_data['prune_days'], 'PRUNE_VIEWED' => $forum_data['prune_viewed'], + 'PRUNE_SHADOW_FREQ' => $forum_data['prune_shadow_freq'], + 'PRUNE_SHADOW_DAYS' => $forum_data['prune_shadow_days'], 'TOPICS_PER_PAGE' => $forum_data['forum_topics_per_page'], 'FORUM_RULES_LINK' => $forum_data['forum_rules_link'], 'FORUM_RULES' => $forum_data['forum_rules'], @@ -668,6 +676,7 @@ class acp_forums 'S_DISPLAY_SUBFORUM_LIST' => ($forum_data['display_subforum_list']) ? true : false, 'S_DISPLAY_ON_INDEX' => ($forum_data['display_on_index']) ? true : false, 'S_PRUNE_ENABLE' => ($forum_data['enable_prune']) ? true : false, + 'S_PRUNE_SHADOW_ENABLE' => ($forum_data['enable_shadow_prune']) ? true : false, 'S_FORUM_LINK_TRACK' => ($forum_data['forum_flags'] & FORUM_FLAG_LINK_TRACK) ? true : false, 'S_PRUNE_OLD_POLLS' => ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_POLL) ? true : false, 'S_PRUNE_ANNOUNCE' => ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_ANNOUNCE) ? true : false, @@ -696,9 +705,18 @@ class acp_forums * ensure to update the template variables * S_ERROR and ERROR_MSG to display it * @var array template_data Array with new forum data - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('action', 'update', 'forum_id', 'row', 'forum_data', 'parents_list', 'errors', 'template_data'); + $vars = array( + 'action', + 'update', + 'forum_id', + 'row', + 'forum_data', + 'parents_list', + 'errors', + 'template_data', + ); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_display_form', compact($vars))); $template->assign_vars($template_data); @@ -926,7 +944,7 @@ class acp_forums */ function update_forum_data(&$forum_data) { - global $db, $user, $cache, $phpbb_root_path, $phpbb_dispatcher; + global $db, $user, $cache, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher; $errors = array(); @@ -937,7 +955,7 @@ class acp_forums * @var array forum_data Array with new forum data * @var array errors Array of errors, should be strings and not * language key. - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('forum_data', 'errors'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_validate_data', compact($vars))); @@ -1030,7 +1048,10 @@ class acp_forums } else { - $forum_data_sql['forum_password'] = phpbb_hash($forum_data_sql['forum_password']); + // Instantiate passwords manager + $passwords_manager = $phpbb_container->get('passwords.manager'); + + $forum_data_sql['forum_password'] = $passwords_manager->hash($forum_data_sql['forum_password']); } unset($forum_data_sql['forum_password_unset']); @@ -1042,7 +1063,7 @@ class acp_forums * @var array forum_data_sql Array with data we are going to update * If forum_data_sql[forum_id] is set, we update * that forum, otherwise a new one is created. - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('forum_data', 'forum_data_sql'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_before', compact($vars))); @@ -1335,7 +1356,7 @@ class acp_forums * ensure to set forum_data_sql[forum_id] * @var array errors Array of errors, should be strings and not * language key. - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('forum_data', 'forum_data_sql', 'is_new_forum', 'errors'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_after', compact($vars))); @@ -1373,7 +1394,7 @@ class acp_forums * @var int to_id If of the new parent forum * @var array errors Array of errors, should be strings and not * language key. - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('from_id', 'to_id', 'errors'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_children', compact($vars))); @@ -1470,14 +1491,14 @@ class acp_forums /** * Event when we move content from one forum to another * - * @event core.acp_manage_forums_move_children + * @event core.acp_manage_forums_move_content * @var int from_id If of the current parent forum * @var int to_id If of the new parent forum * @var bool sync Shall we sync the "to"-forum's data * @var array errors Array of errors, should be strings and not * language key. If this array is not empty, * The content will not be moved. - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('from_id', 'to_id', 'sync', 'errors'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_content', compact($vars))); diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index ad29a5521b..c52289aa72 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -53,7 +53,6 @@ class acp_groups $start = request_var('start', 0); $update = (isset($_POST['update'])) ? true : false; - // Clear some vars $group_row = array(); @@ -140,7 +139,7 @@ class acp_groups if (confirm_box(true)) { $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name']; - group_user_attributes('default', $group_id, $mark_ary, false, $group_name, $group_row); + group_user_attributes('default', $group_id, $mark_ary, false, $group_name, $group_row); trigger_error($user->lang['GROUP_DEFS_UPDATED'] . adm_back_link($this->u_action . '&action=list&g=' . $group_id)); } else @@ -324,10 +323,13 @@ class acp_groups $avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers(); // This is normalised data, without the group_ prefix - $avatar_data = \phpbb\avatar\manager::clean_row($group_row); + $avatar_data = \phpbb\avatar\manager::clean_row($group_row, 'group'); + if (!isset($avatar_data['id'])) + { + $avatar_data['id'] = 'g' . $group_id; + } } - // Did we submit? if ($update) { @@ -379,7 +381,7 @@ class acp_groups } else { - $driver = $phpbb_avatar_manager->get_driver($user->data['user_avatar_type']); + $driver = $phpbb_avatar_manager->get_driver($avatar_data['avatar_type']); if ($driver) { $driver->delete($avatar_data); @@ -657,7 +659,6 @@ class acp_groups 'GROUP_HIDDEN' => $type_hidden, 'U_BACK' => $u_back, - 'U_SWATCH' => append_sid("{$phpbb_admin_path}swatch.$phpEx", 'form=settings&name=group_colour'), 'U_ACTION' => "{$this->u_action}&action=$action&g=$group_id", 'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(), )); @@ -673,6 +674,7 @@ class acp_groups } $this->page_title = 'GROUP_MEMBERS'; + $pagination = $phpbb_container->get('pagination'); // Grab the leaders - always, on every page... $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_regdate, u.user_colour, u.user_posts, u.group_id, ug.group_leader, ug.user_pending @@ -716,14 +718,13 @@ class acp_groups } $base_url = $this->u_action . "&action=$action&g=$group_id"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); $template->assign_vars(array( 'S_LIST' => true, 'S_GROUP_SPECIAL' => ($group_row['group_type'] == GROUP_SPECIAL) ? true : false, 'S_ACTION_OPTIONS' => $s_action_options, - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $total_members, $config['topics_per_page'], $start), 'GROUP_NAME' => ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'], 'U_ACTION' => $this->u_action . "&g=$group_id", diff --git a/phpBB/includes/acp/acp_icons.php b/phpBB/includes/acp/acp_icons.php index 5b23f9c3a0..9c7acf506c 100644 --- a/phpBB/includes/acp/acp_icons.php +++ b/phpBB/includes/acp/acp_icons.php @@ -27,7 +27,7 @@ class acp_icons { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; - global $request; + global $request, $phpbb_container; $user->add_lang('acp/posting'); @@ -203,7 +203,6 @@ class acp_icons unset($_images[$row[$fields . '_url']]); } - if ($row[$fields . '_id'] == $icon_id) { $after = true; @@ -307,7 +306,6 @@ class acp_icons 'IMG_SRC' => $phpbb_root_path . $img_path . '/' . $default_row['smiley_url'], 'IMG_PATH' => $img_path, - 'PHPBB_ROOT_PATH' => $phpbb_root_path, 'CODE' => $default_row['code'], 'EMOTION' => $default_row['emotion'], @@ -480,7 +478,7 @@ class acp_icons $icons_updated++; } - } + } } $cache->destroy('_icons'); @@ -782,7 +780,7 @@ class acp_icons $cache->destroy('_icons'); $cache->destroy('sql', $table); - + if ($request->is_ajax()) { $json_response = new \phpbb\json_response; @@ -833,9 +831,10 @@ class acp_icons WHERE {$fields}_order = $switch_order_id AND {$fields}_id <> $icon_id"; $db->sql_query($sql); + $move_executed = (bool) $db->sql_affectedrows(); // Only update the other entry too if the previous entry got updated - if ($db->sql_affectedrows()) + if ($move_executed) { $sql = "UPDATE $table SET {$fields}_order = $switch_order_id @@ -847,6 +846,14 @@ class acp_icons $cache->destroy('_icons'); $cache->destroy('sql', $table); + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response; + $json_response->send(array( + 'success' => $move_executed, + )); + } + break; } @@ -894,6 +901,7 @@ class acp_icons ); $spacer = false; + $pagination = $phpbb_container->get('pagination'); $pagination_start = request_var('start', 0); $item_count = $this->item_count($table); @@ -928,7 +936,7 @@ class acp_icons } $db->sql_freeresult($result); - phpbb_generate_template_pagination($template, $this->u_action, 'pagination', 'start', $item_count, $config['smilies_per_page'], $pagination_start); + $pagination->generate_template_pagination($this->u_action, 'pagination', 'start', $item_count, $config['smilies_per_page'], $pagination_start); } /** diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index de4679b58d..140815f06a 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -30,7 +30,7 @@ class acp_inactive function main($id, $mode) { - global $config, $db, $user, $auth, $template; + global $config, $db, $user, $auth, $template, $phpbb_container; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix; include($phpbb_root_path . 'includes/functions_user.' . $phpEx); @@ -49,6 +49,7 @@ class acp_inactive $form_key = 'acp_inactive'; add_form_key($form_key); + $pagination = $phpbb_container->get('pagination'); // We build the sort key and per page settings here, because they may be needed later @@ -285,7 +286,7 @@ class acp_inactive } $base_url = $this->u_action . "&$u_sort_param&users_per_page=$per_page"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $inactive_count, $per_page, $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $inactive_count, $per_page, $start); $template->assign_vars(array( 'S_INACTIVE_USERS' => true, @@ -294,7 +295,6 @@ class acp_inactive 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $inactive_count, $per_page, $start), 'USERS_PER_PAGE' => $per_page, 'U_ACTION' => $this->u_action . "&$u_sort_param&users_per_page=$per_page&start=$start", diff --git a/phpBB/includes/acp/acp_logs.php b/phpBB/includes/acp/acp_logs.php index 229bf135ff..2c795bb77b 100644 --- a/phpBB/includes/acp/acp_logs.php +++ b/phpBB/includes/acp/acp_logs.php @@ -24,7 +24,7 @@ class acp_logs function main($id, $mode) { - global $db, $user, $auth, $template, $cache; + global $db, $user, $auth, $template, $cache, $phpbb_container; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; global $request; @@ -46,6 +46,7 @@ class acp_logs $this->tpl_name = 'acp_logs'; $this->log_type = constant('LOG_' . strtoupper($mode)); + $pagination = $phpbb_container->get('pagination'); // Delete entries if requested and able if (($deletemark || $deleteall) && $auth->acl_get('a_clearlogs')) @@ -117,7 +118,7 @@ class acp_logs if ($mode == 'mod') { $forum_box = '<option value="0">' . $user->lang['ALL_FORUMS'] . '</option>' . make_forum_select($forum_id); - + $template->assign_vars(array( 'S_SHOW_FORUMS' => true, 'S_FORUM_BOX' => $forum_box) @@ -130,15 +131,13 @@ class acp_logs $start = view_log($mode, $log_data, $log_count, $config['topics_per_page'], $start, $forum_id, 0, 0, $sql_where, $sql_sort, $keywords); $base_url = $this->u_action . "&$u_sort_param$keywords_param"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); $template->assign_vars(array( 'L_TITLE' => $l_title, 'L_EXPLAIN' => $l_title_explain, 'U_ACTION' => $this->u_action . "&$u_sort_param$keywords_param&start=$start", - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start), - 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, @@ -150,7 +149,7 @@ class acp_logs foreach ($log_data as $row) { $data = array(); - + $checks = array('viewtopic', 'viewlogs', 'viewforum'); foreach ($checks as $check) { diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index eecd8c72dc..4512905539 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -25,7 +25,7 @@ class acp_main function main($id, $mode) { global $config, $db, $cache, $user, $auth, $template, $request; - global $phpbb_root_path, $phpbb_admin_path, $phpEx; + global $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_container; // Show restore permissions notice if ($user->data['user_perm_from'] && $auth->acl_get('a_switchperm')) @@ -40,11 +40,7 @@ class acp_main $user_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - $perm_from = '<strong' . (($user_row['user_colour']) ? ' style="color: #' . $user_row['user_colour'] . '">' : '>'); - $perm_from .= ($user_row['user_id'] != ANONYMOUS) ? '<a href="' . append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u=' . $user_row['user_id']) . '">' : ''; - $perm_from .= $user_row['username']; - $perm_from .= ($user_row['user_id'] != ANONYMOUS) ? '</a>' : ''; - $perm_from .= '</strong>'; + $perm_from = get_username_string('full', $user_row['user_id'], $user_row['username'], $user_row['user_colour']); $template->assign_vars(array( 'S_RESTORE_PERMISSIONS' => true, @@ -432,17 +428,19 @@ class acp_main )); } - $latest_version_info = false; - if (($latest_version_info = obtain_latest_version_info(request_var('versioncheck_force', false))) === false) + $version_helper = $phpbb_container->get('version_helper'); + try { - $template->assign_var('S_VERSIONCHECK_FAIL', true); + $recheck = $request->variable('versioncheck_force', false); + $updates_available = $version_helper->get_suggested_updates($recheck); + + $template->assign_var('S_VERSION_UP_TO_DATE', empty($updates_available)); } - else + catch (\RuntimeException $e) { - $latest_version_info = explode("\n", $latest_version_info); - $template->assign_vars(array( - 'S_VERSION_UP_TO_DATE' => phpbb_version_compare(trim($latest_version_info[0]), $config['version'], '<='), + 'S_VERSIONCHECK_FAIL' => true, + 'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== $user->lang('VERSIONCHECK_FAIL')) ? $e->getMessage() : '', )); } @@ -620,6 +618,22 @@ class acp_main $template->assign_var('S_REMOVE_INSTALL', true); } + // Warn if no search index is created + if ($config['num_posts'] && class_exists($config['search_type'])) + { + $error = false; + $search_type = $config['search_type']; + $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user); + + if (!$search->index_created()) + { + $template->assign_vars(array( + 'S_SEARCH_INDEX_MISSING' => true, + 'L_NO_SEARCH_INDEX' => $user->lang('NO_SEARCH_INDEX', $search->get_name(), '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=acp_search&mode=index') . '">', '</a>'), + )); + } + } + if (!defined('PHPBB_DISABLE_CONFIG_CHECK') && file_exists($phpbb_root_path . 'config.' . $phpEx) && phpbb_is_writable($phpbb_root_path . 'config.' . $phpEx)) { // World-Writable? (000x) diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 6792886d2a..c124377ba9 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -170,6 +170,14 @@ class acp_modules $this->remove_cache_file(); } + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response; + $json_response->send(array( + 'success' => ($move_module_name !== false), + )); + } + break; case 'quickadd': @@ -565,7 +573,7 @@ class acp_modules { // Skip entries we do not need if we know the module we are // looking for - if ($module && strpos(str_replace('\\', '_', $cur_module), $module) === false) + if ($module && strpos(str_replace('\\', '_', $cur_module), $module) === false && $module !== $cur_module) { continue; } diff --git a/phpBB/includes/acp/acp_permission_roles.php b/phpBB/includes/acp/acp_permission_roles.php index 17e48d6576..812e22a025 100644 --- a/phpBB/includes/acp/acp_permission_roles.php +++ b/phpBB/includes/acp/acp_permission_roles.php @@ -27,6 +27,7 @@ class acp_permission_roles { global $db, $user, $auth, $template, $cache, $phpbb_container; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; + global $request; include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); @@ -46,6 +47,11 @@ class acp_permission_roles $form_name = 'acp_permissions'; add_form_key($form_name); + if (!$role_id && in_array($action, array('remove', 'edit', 'move_up', 'move_down'))) + { + trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); + } + switch ($mode) { case 'admin_roles': @@ -85,11 +91,6 @@ class acp_permission_roles { case 'remove': - if (!$role_id) - { - trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); - } - $sql = 'SELECT * FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; @@ -123,10 +124,6 @@ class acp_permission_roles break; case 'edit': - if (!$role_id) - { - trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); - } // Get role we edit $sql = 'SELECT * @@ -274,11 +271,6 @@ class acp_permission_roles if ($action == 'edit') { - if (!$role_id) - { - trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); - } - $sql = 'SELECT * FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; @@ -366,7 +358,18 @@ class acp_permission_roles case 'move_up': case 'move_down': - $order = request_var('order', 0); + $sql = 'SELECT role_order + FROM ' . ACL_ROLES_TABLE . " + WHERE role_id = $role_id"; + $result = $db->sql_query($sql); + $order = $db->sql_fetchfield('role_order'); + $db->sql_freeresult($result); + + if ($order === false || ($order == 0 && $action == 'move_up')) + { + break; + } + $order = (int) $order; $order_total = $order * 2 + (($action == 'move_up') ? -1 : 1); $sql = 'UPDATE ' . ACL_ROLES_TABLE . ' @@ -375,6 +378,14 @@ class acp_permission_roles AND role_order IN ($order, " . (($action == 'move_up') ? $order - 1 : $order + 1) . ')'; $db->sql_query($sql); + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response; + $json_response->send(array( + 'success' => (bool) $db->sql_affectedrows(), + )); + } + break; } @@ -421,8 +432,8 @@ class acp_permission_roles 'U_EDIT' => $this->u_action . '&action=edit&role_id=' . $row['role_id'], 'U_REMOVE' => $this->u_action . '&action=remove&role_id=' . $row['role_id'], - 'U_MOVE_UP' => $this->u_action . '&action=move_up&order=' . $row['role_order'], - 'U_MOVE_DOWN' => $this->u_action . '&action=move_down&order=' . $row['role_order'], + 'U_MOVE_UP' => $this->u_action . '&action=move_up&role_id=' . $row['role_id'], + 'U_MOVE_DOWN' => $this->u_action . '&action=move_down&role_id=' . $row['role_id'], 'U_DISPLAY_ITEMS' => ($row['role_id'] == $display_item) ? '' : $this->u_action . '&display_item=' . $row['role_id'] . '#assigned_to') ); diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php index e7dc03db5c..1924e2075b 100644 --- a/phpBB/includes/acp/acp_permissions.php +++ b/phpBB/includes/acp/acp_permissions.php @@ -330,7 +330,6 @@ class acp_permissions } } - // Setting permissions screen $s_hidden_fields = build_hidden_fields(array( 'user_id' => $user_id, diff --git a/phpBB/includes/acp/acp_php_info.php b/phpBB/includes/acp/acp_php_info.php index 125b77529f..13d2fd770a 100644 --- a/phpBB/includes/acp/acp_php_info.php +++ b/phpBB/includes/acp/acp_php_info.php @@ -81,7 +81,7 @@ class acp_php_info $template->assign_var('PHPINFO', $output); } - + function remove_spaces($matches) { return '<a name="' . str_replace(' ', '_', $matches[1]) . '">'; diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index 4e8145009f..b42b852fba 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -24,37 +24,34 @@ class acp_profile var $edit_lang_id; var $lang_defs; + protected $type_collection; function main($id, $mode) { global $config, $db, $user, $auth, $template, $cache; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix; - global $request; + global $request, $phpbb_container; include($phpbb_root_path . 'includes/functions_posting.' . $phpEx); include($phpbb_root_path . 'includes/functions_user.' . $phpEx); - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); $user->add_lang(array('ucp', 'acp/profile')); $this->tpl_name = 'acp_profile'; $this->page_title = 'ACP_CUSTOM_PROFILE_FIELDS'; + $field_id = $request->variable('field_id', 0); $action = (isset($_POST['create'])) ? 'create' : request_var('action', ''); $error = array(); $s_hidden_fields = ''; - // Define some default values for each field type - $default_values = array( - FIELD_STRING => array('field_length' => 10, 'field_minlen' => 0, 'field_maxlen' => 20, 'field_validation' => '.*', 'field_novalue' => '', 'field_default_value' => ''), - FIELD_TEXT => array('field_length' => '5|80', 'field_minlen' => 0, 'field_maxlen' => 1000, 'field_validation' => '.*', 'field_novalue' => '', 'field_default_value' => ''), - FIELD_INT => array('field_length' => 5, 'field_minlen' => 0, 'field_maxlen' => 100, 'field_validation' => '', 'field_novalue' => 0, 'field_default_value' => 0), - FIELD_DATE => array('field_length' => 10, 'field_minlen' => 10, 'field_maxlen' => 10, 'field_validation' => '', 'field_novalue' => ' 0- 0- 0', 'field_default_value' => ' 0- 0- 0'), - FIELD_BOOL => array('field_length' => 1, 'field_minlen' => 0, 'field_maxlen' => 0, 'field_validation' => '', 'field_novalue' => 0, 'field_default_value' => 0), - FIELD_DROPDOWN => array('field_length' => 0, 'field_minlen' => 0, 'field_maxlen' => 5, 'field_validation' => '', 'field_novalue' => 0, 'field_default_value' => 0), - ); + if (!$field_id && in_array($action, array('delete','activate', 'deactivate', 'move_up', 'move_down', 'edit'))) + { + trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); + } - $cp = new custom_profile_admin(); + $cp = $phpbb_container->get('profilefields.manager'); + $this->type_collection = $phpbb_container->get('profilefields.type_collection'); // Build Language array // Based on this, we decide which elements need to be edited later and which language items are missing @@ -88,22 +85,16 @@ class acp_profile // Have some fields been defined? if (isset($this->lang_defs['entry'])) { - foreach ($this->lang_defs['entry'] as $field_id => $field_ary) + foreach ($this->lang_defs['entry'] as $field_ident => $field_ary) { // Fill an array with the languages that are missing for each field - $this->lang_defs['diff'][$field_id] = array_diff(array_values($this->lang_defs['iso']), $field_ary); + $this->lang_defs['diff'][$field_ident] = array_diff(array_values($this->lang_defs['iso']), $field_ary); } } switch ($action) { case 'delete': - $field_id = request_var('field_id', 0); - - if (!$field_id) - { - trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); - } if (confirm_box(true)) { @@ -210,12 +201,6 @@ class acp_profile break; case 'activate': - $field_id = request_var('field_id', 0); - - if (!$field_id) - { - trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); - } $sql = 'SELECT lang_id FROM ' . LANG_TABLE . " @@ -256,12 +241,6 @@ class acp_profile break; case 'deactivate': - $field_id = request_var('field_id', 0); - - if (!$field_id) - { - trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); - } $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " SET field_active = 0 @@ -291,7 +270,19 @@ class acp_profile case 'move_up': case 'move_down': - $field_order = request_var('order', 0); + + $sql = 'SELECT field_order + FROM ' . PROFILE_FIELDS_TABLE . " + WHERE field_id = $field_id"; + $result = $db->sql_query($sql); + $field_order = $db->sql_fetchfield('field_order'); + $db->sql_freeresult($result); + + if ($field_order === false || ($field_order == 0 && $action == 'move_up')) + { + break; + } + $field_order = (int) $field_order; $order_total = $field_order * 2 + (($action == 'move_up') ? -1 : 1); $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " @@ -299,12 +290,19 @@ class acp_profile WHERE field_order IN ($field_order, " . (($action == 'move_up') ? $field_order - 1 : $field_order + 1) . ')'; $db->sql_query($sql); + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response; + $json_response->send(array( + 'success' => (bool) $db->sql_affectedrows(), + )); + } + break; case 'create': case 'edit': - $field_id = request_var('field_id', 0); $step = request_var('step', 1); $submit = (isset($_REQUEST['next']) || isset($_REQUEST['prev'])) ? true : false; @@ -316,11 +314,6 @@ class acp_profile // We are editing... we need to grab basic things if ($action == 'edit') { - if (!$field_id) - { - trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); - } - $sql = 'SELECT l.*, f.* FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f WHERE l.lang_id = ' . $this->edit_lang_id . " @@ -350,6 +343,7 @@ class acp_profile $this->edit_lang_id = $field_row['lang_id']; } $field_type = $field_row['field_type']; + $profile_field = $this->type_collection[$field_type]; // Get language entries $sql = 'SELECT * @@ -373,14 +367,15 @@ class acp_profile // We are adding a new field, define basic params $lang_options = $field_row = array(); - $field_type = request_var('field_type', 0); + $field_type = request_var('field_type', ''); - if (!$field_type) + if (!isset($this->type_collection[$field_type])) { trigger_error($user->lang['NO_FIELD_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING); } - $field_row = array_merge($default_values[$field_type], array( + $profile_field = $this->type_collection[$field_type]; + $field_row = array_merge($profile_field->get_default_option_values(), array( 'field_ident' => str_replace(' ', '_', utf8_clean_string(request_var('field_ident', '', true))), 'field_required' => 0, 'field_show_novalue'=> 0, @@ -390,6 +385,10 @@ class acp_profile 'field_show_on_reg' => 0, 'field_show_on_pm' => 0, 'field_show_on_vt' => 0, + 'field_show_on_ml' => 0, + 'field_is_contact' => 0, + 'field_contact_desc'=> '', + 'field_contact_url' => '', 'lang_name' => utf8_normalize_nfc(request_var('field_ident', '', true)), 'lang_explain' => '', 'lang_default_value'=> '') @@ -400,28 +399,11 @@ class acp_profile // $exclude contains the data we gather in each step $exclude = array( - 1 => array('field_ident', 'lang_name', 'lang_explain', 'field_option_none', 'field_show_on_reg', 'field_show_on_pm', 'field_show_on_vt', 'field_required', 'field_show_novalue', 'field_hide', 'field_show_profile', 'field_no_view'), + 1 => array('field_ident', 'lang_name', 'lang_explain', 'field_option_none', 'field_show_on_reg', 'field_show_on_pm', 'field_show_on_vt', 'field_show_on_ml', 'field_required', 'field_show_novalue', 'field_hide', 'field_show_profile', 'field_no_view', 'field_is_contact', 'field_contact_desc', 'field_contact_url'), 2 => array('field_length', 'field_maxlen', 'field_minlen', 'field_validation', 'field_novalue', 'field_default_value'), 3 => array('l_lang_name', 'l_lang_explain', 'l_lang_default_value', 'l_lang_options') ); - // Text-based fields require the lang_default_value to be excluded - if ($field_type == FIELD_STRING || $field_type == FIELD_TEXT) - { - $exclude[1][] = 'lang_default_value'; - } - - // option-specific fields require lang_options to be excluded - if ($field_type == FIELD_BOOL || $field_type == FIELD_DROPDOWN) - { - $exclude[1][] = 'lang_options'; - } - - $cp->vars['field_ident'] = ($action == 'create' && $step == 1) ? utf8_clean_string(request_var('field_ident', $field_row['field_ident'], true)) : request_var('field_ident', $field_row['field_ident']); - $cp->vars['lang_name'] = utf8_normalize_nfc(request_var('lang_name', $field_row['lang_name'], true)); - $cp->vars['lang_explain'] = utf8_normalize_nfc(request_var('lang_explain', $field_row['lang_explain'], true)); - $cp->vars['lang_default_value'] = utf8_normalize_nfc(request_var('lang_default_value', $field_row['lang_default_value'], true)); - // Visibility Options... $visibility_ary = array( 'field_required', @@ -429,27 +411,28 @@ class acp_profile 'field_show_on_reg', 'field_show_on_pm', 'field_show_on_vt', + 'field_show_on_ml', 'field_show_profile', 'field_hide', + 'field_is_contact', ); - foreach ($visibility_ary as $val) - { - $cp->vars[$val] = ($submit || $save) ? request_var($val, 0) : $field_row[$val]; - } + $options = $profile_field->prepare_options_form($exclude, $visibility_ary); - $cp->vars['field_no_view'] = request_var('field_no_view', (int) $field_row['field_no_view']); + $cp->vars['field_ident'] = ($action == 'create' && $step == 1) ? utf8_clean_string(request_var('field_ident', $field_row['field_ident'], true)) : request_var('field_ident', $field_row['field_ident']); + $cp->vars['lang_name'] = $request->variable('lang_name', $field_row['lang_name'], true); + $cp->vars['lang_explain'] = $request->variable('lang_explain', $field_row['lang_explain'], true); + $cp->vars['lang_default_value'] = $request->variable('lang_default_value', $field_row['lang_default_value'], true); + $cp->vars['field_contact_desc'] = $request->variable('field_contact_desc', $field_row['field_contact_desc'], true); + $cp->vars['field_contact_url'] = $request->variable('field_contact_url', $field_row['field_contact_url'], true); - // A boolean field expects an array as the lang options - if ($field_type == FIELD_BOOL) - { - $options = utf8_normalize_nfc(request_var('lang_options', array(''), true)); - } - else + foreach ($visibility_ary as $val) { - $options = utf8_normalize_nfc(request_var('lang_options', '', true)); + $cp->vars[$val] = ($submit || $save) ? $request->variable($val, 0) : $field_row[$val]; } + $cp->vars['field_no_view'] = $request->variable('field_no_view', (int) $field_row['field_no_view']); + // If the user has submitted a form with options (i.e. dropdown field) if ($options) { @@ -477,93 +460,9 @@ class acp_profile { $var = utf8_normalize_nfc(request_var($key, $field_row[$key], true)); - // Manipulate the intended variables a little bit if needed - if ($field_type == FIELD_DROPDOWN && $key == 'field_maxlen') - { - // Get the number of options if this key is 'field_maxlen' - $var = sizeof(explode("\n", utf8_normalize_nfc(request_var('lang_options', '', true)))); - } - else if ($field_type == FIELD_TEXT && $key == 'field_length') - { - if (isset($_REQUEST['rows'])) - { - $cp->vars['rows'] = request_var('rows', 0); - $cp->vars['columns'] = request_var('columns', 0); - $var = $cp->vars['rows'] . '|' . $cp->vars['columns']; - } - else - { - $row_col = explode('|', $var); - $cp->vars['rows'] = $row_col[0]; - $cp->vars['columns'] = $row_col[1]; - } - } - else if ($field_type == FIELD_DATE && $key == 'field_default_value') - { - $always_now = request_var('always_now', -1); - - if ($always_now == 1 || ($always_now === -1 && $var == 'now')) - { - $now = getdate(); - - $cp->vars['field_default_value_day'] = $now['mday']; - $cp->vars['field_default_value_month'] = $now['mon']; - $cp->vars['field_default_value_year'] = $now['year']; - $var = 'now'; - $request->overwrite('field_default_value', $var, \phpbb\request\request_interface::POST); - } - else - { - if (isset($_REQUEST['field_default_value_day'])) - { - $cp->vars['field_default_value_day'] = request_var('field_default_value_day', 0); - $cp->vars['field_default_value_month'] = request_var('field_default_value_month', 0); - $cp->vars['field_default_value_year'] = request_var('field_default_value_year', 0); - $var = sprintf('%2d-%2d-%4d', $cp->vars['field_default_value_day'], $cp->vars['field_default_value_month'], $cp->vars['field_default_value_year']); - $request->overwrite('field_default_value', $var, \phpbb\request\request_interface::POST); - } - else - { - list($cp->vars['field_default_value_day'], $cp->vars['field_default_value_month'], $cp->vars['field_default_value_year']) = explode('-', $var); - } - } - } - else if ($field_type == FIELD_BOOL && $key == 'field_default_value') - { - // 'field_length' == 1 defines radio buttons. Possible values are 1 or 2 only. - // 'field_length' == 2 defines checkbox. Possible values are 0 or 1 only. - // If we switch the type on step 2, we have to adjust field value. - // 1 is a common value for the checkbox and radio buttons. - - // Adjust unchecked checkbox value. - // If we return or save settings from 2nd/3rd page - // and the checkbox is unchecked, set the value to 0. - if (isset($_REQUEST['step']) && !isset($_REQUEST[$key])) - { - $var = 0; - } - - // If we switch to the checkbox type but former radio buttons value was 2, - // which is not the case for the checkbox, set it to 0 (unchecked). - if ($cp->vars['field_length'] == 2 && $var == 2) - { - $var = 0; - } - // If we switch to the radio buttons but the former checkbox value was 0, - // which is not the case for the radio buttons, set it to 0. - else if ($cp->vars['field_length'] == 1 && $var == 0) - { - $var = 2; - } - } - else if ($field_type == FIELD_INT && $key == 'field_default_value') - { - // Permit an empty string - if ($action == 'create' && request_var('field_default_value', '') === '') - { - $var = ''; - } - } + $field_data = $cp->vars; + $var = $profile_field->get_excluded_options($key, $action, $var, $field_data, 2); + $cp->vars = $field_data; $cp->vars[$key] = $var; } @@ -586,7 +485,6 @@ class acp_profile } $db->sql_freeresult($result); - $sql = 'SELECT lang_id, lang_name, lang_explain, lang_default_value FROM ' . PROFILE_LANG_TABLE . ' WHERE lang_id <> ' . $this->edit_lang_id . " @@ -612,18 +510,10 @@ class acp_profile { $cp->vars[$key] = $$key; } - else if ($key == 'l_lang_options' && $field_type == FIELD_BOOL) - { - $cp->vars[$key] = utf8_normalize_nfc(request_var($key, array(0 => array('')), true)); - } - else if ($key == 'l_lang_options' && is_array($cp->vars[$key])) - { - foreach ($cp->vars[$key] as $lang_id => $options) - { - $cp->vars[$key][$lang_id] = explode("\n", $options); - } - } + $field_data = $cp->vars; + $var = $profile_field->get_excluded_options($key, $action, $var, $field_data, 3); + $cp->vars = $field_data; } // Check for general issues in every step @@ -650,15 +540,7 @@ class acp_profile $error[] = $user->lang['EMPTY_USER_FIELD_NAME']; } - if ($field_type == FIELD_DROPDOWN && !sizeof($cp->vars['lang_options'])) - { - $error[] = $user->lang['NO_FIELD_ENTRIES']; - } - - if ($field_type == FIELD_BOOL && (empty($cp->vars['lang_options'][0]) || empty($cp->vars['lang_options'][1]))) - { - $error[] = $user->lang['NO_FIELD_ENTRIES']; - } + $error = $profile_field->validate_options_on_submit($error, $cp->vars); // Check for already existing field ident if ($action != 'edit') @@ -695,54 +577,16 @@ class acp_profile $_new_key_ary = array(); + $field_data = $cp->vars; foreach ($key_ary as $key) { - if ($field_type == FIELD_TEXT && $key == 'field_length' && isset($_REQUEST['rows'])) - { - $cp->vars['rows'] = request_var('rows', 0); - $cp->vars['columns'] = request_var('columns', 0); - $_new_key_ary[$key] = $cp->vars['rows'] . '|' . $cp->vars['columns']; - } - else if ($field_type == FIELD_DATE && $key == 'field_default_value') - { - $always_now = request_var('always_now', 0); - - if ($always_now) - { - $_new_key_ary[$key] = 'now'; - } - else if (isset($_REQUEST['field_default_value_day'])) - { - $cp->vars['field_default_value_day'] = request_var('field_default_value_day', 0); - $cp->vars['field_default_value_month'] = request_var('field_default_value_month', 0); - $cp->vars['field_default_value_year'] = request_var('field_default_value_year', 0); - $_new_key_ary[$key] = sprintf('%2d-%2d-%4d', $cp->vars['field_default_value_day'], $cp->vars['field_default_value_month'], $cp->vars['field_default_value_year']); - } - } - else if ($field_type == FIELD_BOOL && $key == 'l_lang_options' && isset($_REQUEST['l_lang_options'])) - { - $_new_key_ary[$key] = utf8_normalize_nfc(request_var($key, array(array('')), true)); - } - else if ($field_type == FIELD_BOOL && $key == 'field_default_value') - { - $_new_key_ary[$key] = request_var($key, $cp->vars[$key]); - } - else + $var = $profile_field->prepare_hidden_fields($step, $key, $action, $field_data); + if ($var !== null) { - if (!isset($_REQUEST[$key])) - { - $var = false; - } - else if ($key == 'field_ident' && isset($cp->vars[$key])) - { - $_new_key_ary[$key]= $cp->vars[$key]; - } - else - { - $_new_key_ary[$key] = ($field_type == FIELD_BOOL && $key == 'lang_options') ? utf8_normalize_nfc(request_var($key, array(''), true)) : utf8_normalize_nfc(request_var($key, '', true)); - } + $_new_key_ary[$key] = $profile_field->prepare_hidden_fields($step, $key, $action, $field_data); } } + $cp->vars = $field_data; $s_hidden_fields .= build_hidden_fields($_new_key_ary); } @@ -776,67 +620,34 @@ class acp_profile { // Create basic options - only small differences between field types case 1: - - // Build common create options - $template->assign_vars(array( + $template_vars = array( 'S_STEP_ONE' => true, 'S_FIELD_REQUIRED' => ($cp->vars['field_required']) ? true : false, 'S_FIELD_SHOW_NOVALUE'=> ($cp->vars['field_show_novalue']) ? true : false, 'S_SHOW_ON_REG' => ($cp->vars['field_show_on_reg']) ? true : false, 'S_SHOW_ON_PM' => ($cp->vars['field_show_on_pm']) ? true : false, 'S_SHOW_ON_VT' => ($cp->vars['field_show_on_vt']) ? true : false, + 'S_SHOW_ON_MEMBERLIST'=> ($cp->vars['field_show_on_ml']) ? true : false, 'S_FIELD_HIDE' => ($cp->vars['field_hide']) ? true : false, 'S_SHOW_PROFILE' => ($cp->vars['field_show_profile']) ? true : false, 'S_FIELD_NO_VIEW' => ($cp->vars['field_no_view']) ? true : false, + 'S_FIELD_CONTACT' => $cp->vars['field_is_contact'], + 'FIELD_CONTACT_DESC'=> $cp->vars['field_contact_desc'], + 'FIELD_CONTACT_URL' => $cp->vars['field_contact_url'], 'L_LANG_SPECIFIC' => sprintf($user->lang['LANG_SPECIFIC_OPTIONS'], $config['default_lang']), - 'FIELD_TYPE' => $user->lang['FIELD_' . strtoupper($cp->profile_types[$field_type])], + 'FIELD_TYPE' => $profile_field->get_name(), 'FIELD_IDENT' => $cp->vars['field_ident'], 'LANG_NAME' => $cp->vars['lang_name'], - 'LANG_EXPLAIN' => $cp->vars['lang_explain']) + 'LANG_EXPLAIN' => $cp->vars['lang_explain'], ); - // String and Text needs to set default values here... - if ($field_type == FIELD_STRING || $field_type == FIELD_TEXT) - { - $template->assign_vars(array( - 'S_TEXT' => ($field_type == FIELD_TEXT) ? true : false, - 'S_STRING' => ($field_type == FIELD_STRING) ? true : false, - - 'L_DEFAULT_VALUE_EXPLAIN' => $user->lang[strtoupper($cp->profile_types[$field_type]) . '_DEFAULT_VALUE_EXPLAIN'], - 'LANG_DEFAULT_VALUE' => $cp->vars['lang_default_value']) - ); - } - - if ($field_type == FIELD_BOOL || $field_type == FIELD_DROPDOWN) - { - // Initialize these array elements if we are creating a new field - if (!sizeof($cp->vars['lang_options'])) - { - if ($field_type == FIELD_BOOL) - { - // No options have been defined for a boolean field. - $cp->vars['lang_options'][0] = ''; - $cp->vars['lang_options'][1] = ''; - } - else - { - // No options have been defined for the dropdown menu - $cp->vars['lang_options'] = array(); - } - } - - $template->assign_vars(array( - 'S_BOOL' => ($field_type == FIELD_BOOL) ? true : false, - 'S_DROPDOWN' => ($field_type == FIELD_DROPDOWN) ? true : false, - - 'L_LANG_OPTIONS_EXPLAIN' => $user->lang[strtoupper($cp->profile_types[$field_type]) . '_ENTRIES_EXPLAIN'], - 'LANG_OPTIONS' => ($field_type == FIELD_DROPDOWN) ? implode("\n", $cp->vars['lang_options']) : '', - 'FIRST_LANG_OPTION' => ($field_type == FIELD_BOOL) ? $cp->vars['lang_options'][0] : '', - 'SECOND_LANG_OPTION' => ($field_type == FIELD_BOOL) ? $cp->vars['lang_options'][1] : '') - ); - } + $field_data = $cp->vars; + $profile_field->display_options($template_vars, $field_data); + $cp->vars = $field_data; + // Build common create options + $template->assign_vars($template_vars); break; case 2: @@ -847,8 +658,7 @@ class acp_profile ); // Build options based on profile type - $function = 'get_' . $cp->profile_types[$field_type] . '_options'; - $options = $cp->$function(); + $options = $profile_field->get_options($this->lang_defs['iso'][$config['default_lang']], $cp->vars); foreach ($options as $num => $option_ary) { @@ -910,17 +720,18 @@ class acp_profile $s_one_need_edit = true; } + $profile_field = $this->type_collection[$row['field_type']]; $template->assign_block_vars('fields', array( 'FIELD_IDENT' => $row['field_ident'], - 'FIELD_TYPE' => $user->lang['FIELD_' . strtoupper($cp->profile_types[$row['field_type']])], + 'FIELD_TYPE' => $profile_field->get_name(), 'L_ACTIVATE_DEACTIVATE' => $user->lang[$active_lang], 'U_ACTIVATE_DEACTIVATE' => $this->u_action . "&action=$active_value&field_id=$id", 'U_EDIT' => $this->u_action . "&action=edit&field_id=$id", 'U_TRANSLATE' => $this->u_action . "&action=edit&field_id=$id&step=3", 'U_DELETE' => $this->u_action . "&action=delete&field_id=$id", - 'U_MOVE_UP' => $this->u_action . "&action=move_up&order={$row['field_order']}", - 'U_MOVE_DOWN' => $this->u_action . "&action=move_down&order={$row['field_order']}", + 'U_MOVE_UP' => $this->u_action . "&action=move_up&field_id=$id", + 'U_MOVE_DOWN' => $this->u_action . "&action=move_down&field_id=$id", 'S_NEED_EDIT' => $s_need_edit) ); @@ -934,15 +745,15 @@ class acp_profile } $s_select_type = ''; - foreach ($cp->profile_types as $key => $value) + foreach ($this->type_collection as $key => $profile_field) { - $s_select_type .= '<option value="' . $key . '">' . $user->lang['FIELD_' . strtoupper($value)] . '</option>'; + $s_select_type .= '<option value="' . $key . '">' . $profile_field->get_name() . '</option>'; } $template->assign_vars(array( 'U_ACTION' => $this->u_action, - 'S_TYPE_OPTIONS' => $s_select_type) - ); + 'S_TYPE_OPTIONS' => $s_select_type, + )); } /** @@ -950,7 +761,7 @@ class acp_profile */ function build_language_options(&$cp, $field_type, $action = 'create') { - global $user, $config, $db; + global $user, $config, $db, $phpbb_container; $default_lang_id = (!empty($this->edit_lang_id)) ? $this->edit_lang_id : $this->lang_defs['iso'][$config['default_lang']]; @@ -967,31 +778,8 @@ class acp_profile } $db->sql_freeresult($result); - $options = array(); - $options['lang_name'] = 'string'; - if ($cp->vars['lang_explain']) - { - $options['lang_explain'] = 'text'; - } - - switch ($field_type) - { - case FIELD_BOOL: - $options['lang_options'] = 'two_options'; - break; - - case FIELD_DROPDOWN: - $options['lang_options'] = 'optionfield'; - break; - - case FIELD_TEXT: - case FIELD_STRING: - if (strlen($cp->vars['lang_default_value'])) - { - $options['lang_default_value'] = ($field_type == FIELD_STRING) ? 'string' : 'text'; - } - break; - } + $profile_field = $this->type_collection[$field_type]; + $options = $profile_field->get_language_options($cp->vars); $lang_options = array(); @@ -1070,7 +858,7 @@ class acp_profile */ function save_profile_field(&$cp, $field_type, $action = 'create') { - global $db, $config, $user; + global $db, $config, $user, $phpbb_container; $field_id = request_var('field_id', 0); @@ -1103,9 +891,13 @@ class acp_profile 'field_show_on_reg' => $cp->vars['field_show_on_reg'], 'field_show_on_pm' => $cp->vars['field_show_on_pm'], 'field_show_on_vt' => $cp->vars['field_show_on_vt'], + 'field_show_on_ml' => $cp->vars['field_show_on_ml'], 'field_hide' => $cp->vars['field_hide'], 'field_show_profile' => $cp->vars['field_show_profile'], - 'field_no_view' => $cp->vars['field_no_view'] + 'field_no_view' => $cp->vars['field_no_view'], + 'field_is_contact' => $cp->vars['field_is_contact'], + 'field_contact_desc' => $cp->vars['field_contact_desc'], + 'field_contact_url' => $cp->vars['field_contact_url'], ); if ($action == 'create') @@ -1131,10 +923,16 @@ class acp_profile $db->sql_query($sql); } + $profile_field = $this->type_collection[$field_type]; + if ($action == 'create') { $field_ident = 'pf_' . $field_ident; - $profile_sql[] = $this->add_field_ident($field_ident, $field_type); + + $db_tools = $phpbb_container->get('dbal.tools'); + + list($sql_type, $null) = $db_tools->get_column_type($profile_field->get_database_column_type()); + $profile_sql[] = $this->add_field_ident($field_ident, $sql_type); } $sql_ary = array( @@ -1188,23 +986,7 @@ class acp_profile } } - // These are always arrays because the key is the language id... - $cp->vars['l_lang_name'] = utf8_normalize_nfc(request_var('l_lang_name', array(0 => ''), true)); - $cp->vars['l_lang_explain'] = utf8_normalize_nfc(request_var('l_lang_explain', array(0 => ''), true)); - $cp->vars['l_lang_default_value'] = utf8_normalize_nfc(request_var('l_lang_default_value', array(0 => ''), true)); - - if ($field_type != FIELD_BOOL) - { - $cp->vars['l_lang_options'] = utf8_normalize_nfc(request_var('l_lang_options', array(0 => ''), true)); - } - else - { - /** - * @todo check if this line is correct... - $cp->vars['l_lang_default_value'] = request_var('l_lang_default_value', array(0 => array('')), true); - */ - $cp->vars['l_lang_options'] = utf8_normalize_nfc(request_var('l_lang_options', array(0 => array('')), true)); - } + $cp->vars = $profile_field->get_language_options_input($cp->vars); if ($cp->vars['lang_options']) { @@ -1224,7 +1006,7 @@ class acp_profile foreach ($cp->vars['lang_options'] as $option_id => $value) { $sql_ary = array( - 'field_type' => (int) $field_type, + 'field_type' => $field_type, 'lang_value' => $value ); @@ -1279,7 +1061,7 @@ class acp_profile 'field_id' => (int) $field_id, 'lang_id' => (int) $lang_id, 'option_id' => (int) $option_id, - 'field_type' => (int) $field_type, + 'field_type' => $field_type, 'lang_value' => $value ); } @@ -1333,7 +1115,6 @@ class acp_profile } } - $db->sql_transaction('begin'); if ($action == 'create') @@ -1409,7 +1190,7 @@ class acp_profile /** * Return sql statement for adding a new field ident (profile field) to the profile fields data table */ - function add_field_ident($field_ident, $field_type) + function add_field_ident($field_ident, $sql_type) { global $db; @@ -1418,73 +1199,11 @@ class acp_profile case 'mysql': case 'mysql4': case 'mysqli': - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD `$field_ident` "; - - switch ($field_type) - { - case FIELD_STRING: - $sql .= ' VARCHAR(255) '; - break; - - case FIELD_DATE: - $sql .= 'VARCHAR(10) '; - break; - - case FIELD_TEXT: - $sql .= "TEXT"; - // ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield INT(11) UNSIGNED"; - break; - - case FIELD_BOOL: - $sql .= 'TINYINT(2) '; - break; - - case FIELD_DROPDOWN: - $sql .= 'MEDIUMINT(8) '; - break; - - case FIELD_INT: - $sql .= 'BIGINT(20) '; - break; - } + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD `$field_ident` " . $sql_type; break; case 'sqlite': - - switch ($field_type) - { - case FIELD_STRING: - $type = ' VARCHAR(255) '; - break; - - case FIELD_DATE: - $type = 'VARCHAR(10) '; - break; - - case FIELD_TEXT: - $type = "TEXT(65535)"; - // ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield INT(11) UNSIGNED"; - break; - - case FIELD_BOOL: - $type = 'TINYINT(2) '; - break; - - case FIELD_DROPDOWN: - $type = 'MEDIUMINT(8) '; - break; - - case FIELD_INT: - $type = 'BIGINT(20) '; - break; - } - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. if (version_compare(sqlite_libversion(), '3.0') == -1) { $sql = "SELECT sql @@ -1519,7 +1238,7 @@ class acp_profile $columns = implode(',', $column_list); - $new_table_cols = $field_ident . ' ' . $type . ',' . $new_table_cols; + $new_table_cols = $field_ident . ' ' . $sql_type . ',' . $new_table_cols; // create a new table and fill it up. destroy the temp one $db->sql_query('CREATE TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' (' . $new_table_cols . ');'); @@ -1528,7 +1247,7 @@ class acp_profile } else { - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident [$type]"; + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident [$sql_type]"; } break; @@ -1536,140 +1255,22 @@ class acp_profile case 'mssql': case 'mssql_odbc': case 'mssqlnative': - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE [' . PROFILE_FIELDS_DATA_TABLE . "] ADD [$field_ident] "; - - switch ($field_type) - { - case FIELD_STRING: - $sql .= ' [VARCHAR] (255) '; - break; - - case FIELD_DATE: - $sql .= '[VARCHAR] (10) '; - break; - - case FIELD_TEXT: - $sql .= "[TEXT]"; - // ADD {$field_ident}_bbcode_uid [VARCHAR] (5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield [INT] UNSIGNED"; - break; - - case FIELD_BOOL: - case FIELD_DROPDOWN: - $sql .= '[INT] '; - break; - - case FIELD_INT: - $sql .= '[FLOAT] '; - break; - } + $sql = 'ALTER TABLE [' . PROFILE_FIELDS_DATA_TABLE . "] ADD [$field_ident] " . $sql_type; break; case 'postgres': - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD COLUMN \"$field_ident\" "; - - switch ($field_type) - { - case FIELD_STRING: - $sql .= ' VARCHAR(255) '; - break; - - case FIELD_DATE: - $sql .= 'VARCHAR(10) '; - break; - - case FIELD_TEXT: - $sql .= "TEXT"; - // ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield INT4 UNSIGNED"; - break; - - case FIELD_BOOL: - $sql .= 'INT2 '; - break; - - case FIELD_DROPDOWN: - $sql .= 'INT4 '; - break; - - case FIELD_INT: - $sql .= 'INT8 '; - break; - } + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD COLUMN \"$field_ident\" " . $sql_type; break; case 'firebird': - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' ADD "' . strtoupper($field_ident) . '" '; - - switch ($field_type) - { - case FIELD_STRING: - $sql .= ' VARCHAR(255) '; - break; - - case FIELD_DATE: - $sql .= 'VARCHAR(10) '; - break; - - case FIELD_TEXT: - $sql .= "BLOB SUB_TYPE TEXT"; - // ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield INTEGER UNSIGNED"; - break; - - case FIELD_BOOL: - case FIELD_DROPDOWN: - $sql .= 'INTEGER '; - break; - - case FIELD_INT: - $sql .= 'DOUBLE PRECISION '; - break; - } + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' ADD "' . strtoupper($field_ident) . '" ' . $sql_type; break; case 'oracle': - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident "; - - switch ($field_type) - { - case FIELD_STRING: - $sql .= ' VARCHAR2(255) '; - break; - - case FIELD_DATE: - $sql .= 'VARCHAR2(10) '; - break; - - case FIELD_TEXT: - $sql .= "CLOB"; - // ADD {$field_ident}_bbcode_uid VARCHAR2(5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield NUMBER(11) UNSIGNED"; - break; - - case FIELD_BOOL: - $sql .= 'NUMBER(2) '; - break; - - case FIELD_DROPDOWN: - $sql .= 'NUMBER(8) '; - break; - - case FIELD_INT: - $sql .= 'NUMBER(20) '; - break; - } + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident " . $sql_type; break; } diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index 4234ec1505..3850e7efe7 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -79,7 +79,7 @@ class acp_prune $prune_posted = request_var('prune_days', 0); $prune_viewed = request_var('prune_vieweddays', 0); $prune_all = (!$prune_posted && !$prune_viewed) ? true : false; - + $prune_flags = 0; $prune_flags += (request_var('prune_old_polls', 0)) ? 2 : 0; $prune_flags += (request_var('prune_announce', 0)) ? 4 : 0; @@ -109,7 +109,7 @@ class acp_prune $p_result['topics'] = 0; $p_result['posts'] = 0; $log_data = ''; - + do { if (!$auth->acl_get('f_list', $row['forum_id'])) @@ -129,7 +129,7 @@ class acp_prune $p_result['topics'] += $return['topics']; $p_result['posts'] += $return['posts']; } - + if ($prune_viewed) { $return = prune($row['forum_id'], 'viewed', $prunedate_viewed, $prune_flags, false); @@ -145,11 +145,11 @@ class acp_prune 'NUM_TOPICS' => $p_result['topics'], 'NUM_POSTS' => $p_result['posts']) ); - + $log_data .= (($log_data != '') ? ', ' : '') . $row['forum_name']; } while ($row = $db->sql_fetchrow($result)); - + // Sync all pruned forums at once sync('forum', 'forum_id', $prune_ids, true, true); add_log('admin', 'LOG_PRUNE', $log_data); @@ -256,7 +256,7 @@ class acp_prune if ($deleteposts) { user_delete('remove', $user_ids); - + $l_log = 'LOG_PRUNE_USER_DEL_DEL'; } else @@ -294,7 +294,7 @@ class acp_prune $template->assign_block_vars('users', array( 'USERNAME' => $usernames[$user_id], 'USER_ID' => $user_id, - 'U_PROFILE' => append_sid($phpbb_root_path . 'memberlist.' . $phpEx, 'mode=viewprofile&u=' . $user_id), + 'U_PROFILE' => get_username_string('profile', $user_id, $usernames[$user_id]), 'U_USER_ADMIN' => ($auth->acl_get('a_user')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=overview&u=' . $user_id, true, $user->session_id) : '', )); } @@ -331,23 +331,30 @@ class acp_prune $s_find_active_time .= '<option value="' . $key . '">' . $value . '</option>'; } - $s_group_list = '<option value="0"></option>'; $sql = 'SELECT group_id, group_name FROM ' . GROUPS_TABLE . ' WHERE group_type <> ' . GROUP_SPECIAL . ' ORDER BY group_name ASC'; $result = $db->sql_query($sql); + $s_group_list = ''; while ($row = $db->sql_fetchrow($result)) { $s_group_list .= '<option value="' . $row['group_id'] . '">' . $row['group_name'] . '</option>'; } $db->sql_freeresult($result); + if ($s_group_list) + { + // Only prepend the "All groups" option if there are groups, + // otherwise we don't want to display this option at all. + $s_group_list = '<option value="0">' . $user->lang['PRUNE_USERS_GROUP_NONE'] . '</option>' . $s_group_list; + } + $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'S_ACTIVE_OPTIONS' => $s_find_active_time, - 'S_GROUP_LIST' => $s_group_list, + 'S_GROUP_LIST' => $s_group_list, 'S_COUNT_OPTIONS' => $s_find_count, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_prune&field=users'), )); @@ -358,12 +365,12 @@ class acp_prune */ function get_prune_users(&$user_ids, &$usernames) { - global $user, $db; + global $user, $db, $request; $users_by_name = request_var('users', '', true); $users_by_id = request_var('user_ids', array(0)); $group_id = request_var('group_id', 0); - $posts_on_queue = request_var('posts_on_queue', 0); + $posts_on_queue = (trim($request->variable('posts_on_queue', '')) === '') ? false : $request->variable('posts_on_queue', 0); if ($users_by_name) { @@ -381,7 +388,6 @@ class acp_prune { $username = request_var('username', '', true); $email = request_var('email', ''); - $website = request_var('website', ''); $active_select = request_var('active_select', 'lt'); $count_select = request_var('count_select', 'eq'); @@ -431,7 +437,6 @@ class acp_prune $where_sql = ''; $where_sql .= ($username) ? ' AND username_clean ' . $db->sql_like_expression(str_replace('*', $db->any_char, utf8_clean_string($username))) : ''; $where_sql .= ($email) ? ' AND user_email ' . $db->sql_like_expression(str_replace('*', $db->any_char, $email)) . ' ' : ''; - $where_sql .= ($website) ? ' AND user_website ' . $db->sql_like_expression(str_replace('*', $db->any_char, $website)) . ' ' : ''; $where_sql .= $joined_sql; $where_sql .= ($count) ? " AND user_posts " . $key_match[$count_select] . ' ' . (int) $count . ' ' : ''; @@ -439,7 +444,7 @@ class acp_prune if (sizeof($active) && (int) $active[0] == 0 && (int) $active[1] == 0 && (int) $active[2] == 0) { $where_sql .= ' AND user_lastvisit = 0'; - } + } else if (sizeof($active) && $active_select != 'lt') { $where_sql .= ' AND user_lastvisit ' . $key_match[$active_select] . ' ' . gmmktime(0, 0, 0, (int) $active[1], (int) $active[2], (int) $active[0]); @@ -450,8 +455,8 @@ class acp_prune } } - // Protect the admin, do not prune if no options are given... - if (!$where_sql) + // If no search criteria were provided, go no further. + if (!$where_sql && !$group_id && $posts_on_queue === false) { return; } @@ -468,34 +473,40 @@ class acp_prune } $db->sql_freeresult($result); - // Do not prune founder members - $sql = 'SELECT user_id, username - FROM ' . USERS_TABLE . ' - WHERE user_id <> ' . ANONYMOUS . ' - AND user_type <> ' . USER_FOUNDER . " - $where_sql"; - $result = $db->sql_query($sql); + // Protect the admin, do not prune if no options are given... + if ($where_sql) + { + // Do not prune founder members + $sql = 'SELECT user_id, username + FROM ' . USERS_TABLE . ' + WHERE user_id <> ' . ANONYMOUS . ' + AND user_type <> ' . USER_FOUNDER . " + $where_sql"; + $result = $db->sql_query($sql); - $user_ids = $usernames = array(); + $user_ids = $usernames = array(); - while ($row = $db->sql_fetchrow($result)) - { - // Do not prune bots and the user currently pruning. - if ($row['user_id'] != $user->data['user_id'] && !in_array($row['user_id'], $bot_ids)) + while ($row = $db->sql_fetchrow($result)) { - $user_ids[] = $row['user_id']; - $usernames[$row['user_id']] = $row['username']; + // Do not prune bots and the user currently pruning. + if ($row['user_id'] != $user->data['user_id'] && !in_array($row['user_id'], $bot_ids)) + { + $user_ids[] = $row['user_id']; + $usernames[$row['user_id']] = $row['username']; + } } + $db->sql_freeresult($result); } - $db->sql_freeresult($result); if ($group_id) { $sql = 'SELECT u.user_id, u.username FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . ' u WHERE ug.group_id = ' . (int) $group_id . ' - AND ug.user_pending = 0 - AND ' . $db->sql_in_set('ug.user_id', $user_ids, false, true) . ' + AND ug.user_id <> ' . ANONYMOUS . ' + AND u.user_type <> ' . USER_FOUNDER . ' + AND ug.user_pending = 0 ' . + ((!empty($user_ids)) ? 'AND ' . $db->sql_in_set('ug.user_id', $user_ids) : '') . ' AND u.user_id = ug.user_id'; $result = $db->sql_query($sql); @@ -505,28 +516,39 @@ class acp_prune $user_ids = $usernames = array(); while ($row = $db->sql_fetchrow($result)) { - $user_ids[] = $row['user_id']; - $usernames[$row['user_id']] = $row['username']; + // Do not prune bots and the user currently pruning. + if ($row['user_id'] != $user->data['user_id'] && !in_array($row['user_id'], $bot_ids)) + { + $user_ids[] = $row['user_id']; + $usernames[$row['user_id']] = $row['username']; + } } $db->sql_freeresult($result); } - if ($posts_on_queue) + if ($posts_on_queue !== false) { $sql = 'SELECT u.user_id, u.username, COUNT(p.post_id) AS queue_posts FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u - WHERE ' . $db->sql_in_set('p.poster_id', $user_ids, false, true) . ' + WHERE u.user_id <> ' . ANONYMOUS . ' + AND u.user_type <> ' . USER_FOUNDER . + ((!empty($user_ids)) ? 'AND ' . $db->sql_in_set('p.poster_id', $user_ids) : '') . ' + AND ' . $db->sql_in_set('p.post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . ' AND u.user_id = p.poster_id GROUP BY p.poster_id HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue; - $result = $db->sql_query($result); + $result = $db->sql_query($sql); // same intersection logic as the above group ID portion $user_ids = $usernames = array(); while ($row = $db->sql_fetchrow($result)) { - $user_ids[] = $row['user_id']; - $usernames[$row['user_id']] = $row['username']; + // Do not prune bots and the user currently pruning. + if ($row['user_id'] != $user->data['user_id'] && !in_array($row['user_id'], $bot_ids)) + { + $user_ids[] = $row['user_id']; + $usernames[$row['user_id']] = $row['username']; + } } $db->sql_freeresult($result); } diff --git a/phpBB/includes/acp/acp_ranks.php b/phpBB/includes/acp/acp_ranks.php index 73e1de44d9..55028cc882 100644 --- a/phpBB/includes/acp/acp_ranks.php +++ b/phpBB/includes/acp/acp_ranks.php @@ -214,7 +214,6 @@ class acp_ranks 'MIN_POSTS' => (isset($ranks['rank_min']) && !$ranks['rank_special']) ? $ranks['rank_min'] : 0) ); - return; break; diff --git a/phpBB/includes/acp/acp_reasons.php b/phpBB/includes/acp/acp_reasons.php index 71e9108c2c..569bb73ab0 100644 --- a/phpBB/includes/acp/acp_reasons.php +++ b/phpBB/includes/acp/acp_reasons.php @@ -26,6 +26,7 @@ class acp_reasons { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; + global $request; $user->add_lang(array('mcp', 'acp/posting')); @@ -280,7 +281,18 @@ class acp_reasons case 'move_up': case 'move_down': - $order = request_var('order', 0); + $sql = 'SELECT reason_order + FROM ' . REPORTS_REASONS_TABLE . " + WHERE reason_id = $reason_id"; + $result = $db->sql_query($sql); + $order = $db->sql_fetchfield('reason_order'); + $db->sql_freeresult($result); + + if ($order === false || ($order == 0 && $action == 'move_up')) + { + break; + } + $order = (int) $order; $order_total = $order * 2 + (($action == 'move_up') ? -1 : 1); $sql = 'UPDATE ' . REPORTS_REASONS_TABLE . ' @@ -288,6 +300,13 @@ class acp_reasons WHERE reason_order IN (' . $order . ', ' . (($action == 'move_up') ? $order - 1 : $order + 1) . ')'; $db->sql_query($sql); + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response; + $json_response->send(array( + 'success' => (bool) $db->sql_affectedrows(), + )); + } break; } @@ -363,8 +382,8 @@ class acp_reasons 'U_EDIT' => $this->u_action . '&action=edit&id=' . $row['reason_id'], 'U_DELETE' => (!$other_reason) ? $this->u_action . '&action=delete&id=' . $row['reason_id'] : '', - 'U_MOVE_UP' => $this->u_action . '&action=move_up&order=' . $row['reason_order'], - 'U_MOVE_DOWN' => $this->u_action . '&action=move_down&order=' . $row['reason_order']) + 'U_MOVE_UP' => $this->u_action . '&action=move_up&id=' . $row['reason_id'], + 'U_MOVE_DOWN' => $this->u_action . '&action=move_down&id=' . $row['reason_id']) ); } $db->sql_freeresult($result); diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 094d84de40..3f9d21f56c 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -530,6 +530,9 @@ class acp_styles return; } + // Show page title + $this->welcome_message('ACP_STYLES', null); + // Show parent styles foreach ($list as $row) { @@ -888,7 +891,11 @@ class acp_styles protected function list_style(&$style, $level) { // Mark row as shown - if (!empty($style['_shown'])) return; + if (!empty($style['_shown'])) + { + return; + } + $style['_shown'] = true; // Generate template variables diff --git a/phpBB/includes/acp/acp_update.php b/phpBB/includes/acp/acp_update.php index 6b5407067d..e50409bd37 100644 --- a/phpBB/includes/acp/acp_update.php +++ b/phpBB/includes/acp/acp_update.php @@ -24,64 +24,42 @@ class acp_update function main($id, $mode) { - global $config, $db, $user, $auth, $template, $cache; - global $phpbb_root_path, $phpbb_admin_path, $phpEx; + global $config, $user, $template, $request; + global $phpbb_root_path, $phpEx, $phpbb_container; $user->add_lang('install'); $this->tpl_name = 'acp_update'; $this->page_title = 'ACP_VERSION_CHECK'; - // Get current and latest version - $errstr = ''; - $errno = 0; - - $info = obtain_latest_version_info(request_var('versioncheck_force', false)); - - if (empty($info)) + $version_helper = $phpbb_container->get('version_helper'); + try { - trigger_error('VERSIONCHECK_FAIL', E_USER_WARNING); + $recheck = $request->variable('versioncheck_force', false); + $updates_available = $version_helper->get_suggested_updates($recheck); } + catch (\RuntimeException $e) + { + $template->assign_var('S_VERSIONCHECK_FAIL', true); - $info = explode("\n", $info); - $latest_version = trim($info[0]); - - $announcement_url = trim($info[1]); - $announcement_url = (strpos($announcement_url, '&') === false) ? str_replace('&', '&', $announcement_url) : $announcement_url; - $update_link = append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=update'); + $updates_available = array(); + } - // next feature release - $next_feature_version = $next_feature_announcement_url = false; - if (isset($info[2]) && trim($info[2]) !== '') + foreach ($updates_available as $branch => $version_data) { - $next_feature_version = trim($info[2]); - $next_feature_announcement_url = trim($info[3]); + $template->assign_block_vars('updates_available', $version_data); } - // Determine automatic update... - $sql = 'SELECT config_value - FROM ' . CONFIG_TABLE . " - WHERE config_name = 'version_update_from'"; - $result = $db->sql_query($sql); - $version_update_from = (string) $db->sql_fetchfield('config_value'); - $db->sql_freeresult($result); - - $current_version = (!empty($version_update_from)) ? $version_update_from : $config['version']; + $update_link = append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=update'); $template->assign_vars(array( - 'S_UP_TO_DATE' => phpbb_version_compare($latest_version, $config['version'], '<='), - 'S_UP_TO_DATE_AUTO' => phpbb_version_compare($latest_version, $current_version, '<='), - 'S_VERSION_CHECK' => true, - 'U_ACTION' => $this->u_action, - 'U_VERSIONCHECK_FORCE' => append_sid($this->u_action . '&versioncheck_force=1'), + 'S_UP_TO_DATE' => empty($updates_available), + 'U_ACTION' => $this->u_action, + 'U_VERSIONCHECK_FORCE' => append_sid($this->u_action . '&versioncheck_force=1'), - 'LATEST_VERSION' => $latest_version, - 'CURRENT_VERSION' => $config['version'], - 'AUTO_VERSION' => $version_update_from, - 'NEXT_FEATURE_VERSION' => $next_feature_version, + 'CURRENT_VERSION' => $config['version'], - 'UPDATE_INSTRUCTIONS' => sprintf($user->lang['UPDATE_INSTRUCTIONS'], $announcement_url, $update_link), - 'UPGRADE_INSTRUCTIONS' => $next_feature_version ? $user->lang('UPGRADE_INSTRUCTIONS', $next_feature_version, $next_feature_announcement_url) : false, + 'UPDATE_INSTRUCTIONS' => sprintf($user->lang['UPDATE_INSTRUCTIONS'], $update_link), )); } } diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 8853200ddc..de8f1b48c6 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -37,7 +37,6 @@ class acp_users $user->add_lang(array('posting', 'ucp', 'acp/users')); $this->tpl_name = 'acp_users'; - $this->page_title = 'ACP_USER_' . strtoupper($mode); $error = array(); $username = utf8_normalize_nfc(request_var('username', '', true)); @@ -159,6 +158,8 @@ class acp_users trigger_error($user->lang['NOT_MANAGE_FOUNDER'] . adm_back_link($this->u_action), E_USER_WARNING); } + $this->page_title = $user_row['username'] . ' :: ' . $user->lang('ACP_USER_' . strtoupper($mode)); + switch ($mode) { case 'overview': @@ -173,8 +174,7 @@ class acp_users if ($submit) { - // You can't delete the founder - if ($delete && $user_row['user_type'] != USER_FOUNDER) + if ($delete) { if (!$auth->acl_get('a_userdel')) { @@ -187,6 +187,12 @@ class acp_users trigger_error($user->lang['CANNOT_REMOVE_ANONYMOUS'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } + // Founders can not be deleted. + if ($user_row['user_type'] == USER_FOUNDER) + { + trigger_error($user->lang['CANNOT_REMOVE_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); + } + if ($user_id == $user->data['user_id']) { trigger_error($user->lang['CANNOT_REMOVE_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); @@ -396,6 +402,9 @@ class acp_users { if ($config['require_activation'] == USER_ACTIVATION_ADMIN) { + $phpbb_notifications = $phpbb_container->get('notification_manager'); + $phpbb_notifications->delete_notifications('admin_activate_user', $user_row['user_id']); + include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); $messenger = new messenger(false); @@ -647,8 +656,9 @@ class acp_users while ($row = $db->sql_fetchrow($result)) { if ($topic_id_ary[$row['topic_id']][ITEM_APPROVED] == $row['topic_posts_approved'] - && $topic_id_ary[$row['topic_id']][ITEM_UNAPPROVED] == $row['topic_posts_unapproved'] - && $topic_id_ary[$row['topic_id']][ITEM_DELETED] == $row['topic_posts_softdeleted']) + && $topic_id_ary[$row['topic_id']][ITEM_UNAPPROVED] == $row['topic_posts_unapproved'] + && $topic_id_ary[$row['topic_id']][ITEM_REAPPROVE] == $row['topic_posts_unapproved'] + && $topic_id_ary[$row['topic_id']][ITEM_DELETED] == $row['topic_posts_softdeleted']) { $move_topic_ary[] = $row['topic_id']; } @@ -726,7 +736,6 @@ class acp_users sync('forum', 'forum_id', $forum_id_ary, false, true); } - add_log('admin', 'LOG_USER_MOVE_POSTS', $user_row['username'], $forum_info['forum_name']); add_log('user', $user_id, 'LOG_USER_MOVE_POSTS_USER', $forum_info['forum_name']); @@ -763,7 +772,7 @@ class acp_users * @event core.acp_users_overview_run_quicktool * @var array user_row Current user data * @var string action Quick tool that should be run - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('action', 'user_row'); extract($phpbb_dispatcher->trigger_event('core.acp_users_overview_run_quicktool', compact($vars))); @@ -821,9 +830,12 @@ class acp_users $error[] = 'FORM_INVALID'; } + // Instantiate passwords manager + $passwords_manager = $phpbb_container->get('passwords.manager'); + // Which updates do we need to do? $update_username = ($user_row['username'] != $data['username']) ? $data['username'] : false; - $update_password = ($data['new_password'] && !phpbb_check_hash($data['new_password'], $user_row['user_password'])) ? true : false; + $update_password = $data['new_password'] && !$passwords_manager->check($data['new_password'], $user_row['user_password']); $update_email = ($data['email'] != $user_row['user_email']) ? $data['email'] : false; if (!sizeof($error)) @@ -881,7 +893,7 @@ class acp_users * @var array user_row Current user data * @var array data Submitted user data * @var array sql_ary User data we udpate - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('user_row', 'data', 'sql_ary'); extract($phpbb_dispatcher->trigger_event('core.acp_users_overview_modify_data', compact($vars))); @@ -907,7 +919,7 @@ class acp_users if ($update_password) { $sql_ary += array( - 'user_password' => phpbb_hash($data['new_password']), + 'user_password' => $passwords_manager->hash($data['new_password']), 'user_passchg' => time(), 'user_pass_convert' => 0, ); @@ -996,7 +1008,7 @@ class acp_users * @event core.acp_users_display_overview * @var array user_row Array with user data * @var array quick_tool_ary Ouick tool options - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('user_row', 'quick_tool_ary'); extract($phpbb_dispatcher->trigger_event('core.acp_users_display_overview', compact($vars))); @@ -1007,7 +1019,7 @@ class acp_users $s_action_options .= '<option value="' . $value . '">' . $user->lang['USER_ADMIN_' . $lang] . '</option>'; } - $last_visit = (!empty($user_row['session_time'])) ? $user_row['session_time'] : $user_row['user_lastvisit']; + $last_active = (!empty($user_row['session_time'])) ? $user_row['session_time'] : $user_row['user_lastvisit']; $inactive_reason = ''; if ($user_row['user_type'] == USER_INACTIVE) @@ -1038,7 +1050,7 @@ class acp_users $sql = 'SELECT COUNT(post_id) as posts_in_queue FROM ' . POSTS_TABLE . ' WHERE poster_id = ' . $user_id . ' - AND post_visibility = ' . ITEM_UNAPPROVED; + AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)); $result = $db->sql_query($sql); $user_row['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue'); $db->sql_freeresult($result); @@ -1066,6 +1078,7 @@ class acp_users 'U_SHOW_IP' => $this->u_action . "&u=$user_id&ip=" . (($ip == 'ip') ? 'hostname' : 'ip'), 'U_WHOIS' => $this->u_action . "&action=whois&user_ip={$user_row['user_ip']}", 'U_MCP_QUEUE' => ($auth->acl_getf_global('m_approve')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue', true, $user->session_id) : '', + 'U_SEARCH_USER' => ($config['load_search'] && $auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id={$user_row['user_id']}&sr=posts") : '', 'U_SWITCH_PERMISSIONS' => ($auth->acl_get('a_switchperm') && $user->data['user_id'] != $user_row['user_id']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", "mode=switch_perm&u={$user_row['user_id']}&hash=" . generate_link_hash('switchperm')) : '', @@ -1073,7 +1086,7 @@ class acp_users 'USER' => $user_row['username'], 'USER_REGISTERED' => $user->format_date($user_row['user_regdate']), 'REGISTERED_IP' => ($ip == 'hostname') ? gethostbyaddr($user_row['user_ip']) : $user_row['user_ip'], - 'USER_LASTACTIVE' => ($last_visit) ? $user->format_date($last_visit) : ' - ', + 'USER_LASTACTIVE' => ($last_active) ? $user->format_date($last_active) : ' - ', 'USER_EMAIL' => $user_row['user_email'], 'USER_WARNINGS' => $user_row['user_warnings'], 'USER_POSTS' => $user_row['user_posts'], @@ -1093,6 +1106,7 @@ class acp_users $deleteall = (isset($_POST['delall'])) ? true : false; $marked = request_var('mark', array(0)); $message = utf8_normalize_nfc(request_var('message', '', true)); + $pagination = $phpbb_container->get('pagination'); // Sort keys $sort_days = request_var('st', 0); @@ -1163,11 +1177,10 @@ class acp_users $start = view_log('user', $log_data, $log_count, $config['topics_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort); $base_url = $this->u_action . "&u=$user_id&$u_sort_param"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); $template->assign_vars(array( 'S_FEEDBACK' => true, - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start), 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, @@ -1240,17 +1253,13 @@ class acp_users WHERE user_id = $user_id"; $db->sql_query($sql); - switch ($log_warnings) + if ($log_warnings) { - case 2: - add_log('admin', 'LOG_WARNINGS_DELETED', $user_row['username'], $num_warnings); - break; - case 1: - add_log('admin', 'LOG_WARNING_DELETED', $user_row['username']); - break; - default: - add_log('admin', 'LOG_WARNINGS_DELETED_ALL', $user_row['username']); - break; + add_log('admin', 'LOG_WARNINGS_DELETED', $user_row['username'], $num_warnings); + } + else + { + add_log('admin', 'LOG_WARNINGS_DELETED_ALL', $user_row['username']); } } } @@ -1320,7 +1329,6 @@ class acp_users } } - $template->assign_block_vars('warn', array( 'ID' => $row['warning_id'], 'USERNAME' => ($row['log_operation']) ? get_username_string('full', $row['mod_user_id'], $row['mod_username'], $row['mod_user_colour']) : '-', @@ -1339,9 +1347,8 @@ class acp_users case 'profile': include($phpbb_root_path . 'includes/functions_user.' . $phpEx); - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields.manager'); $cp_data = $cp_error = array(); @@ -1355,15 +1362,7 @@ class acp_users $user_row['iso_lang_id'] = $row['lang_id']; $data = array( - 'icq' => request_var('icq', $user_row['user_icq']), - 'aim' => request_var('aim', $user_row['user_aim']), - 'msn' => request_var('msn', $user_row['user_msnm']), - 'yim' => request_var('yim', $user_row['user_yim']), 'jabber' => utf8_normalize_nfc(request_var('jabber', $user_row['user_jabber'], true)), - 'website' => request_var('website', $user_row['user_website']), - 'location' => utf8_normalize_nfc(request_var('location', $user_row['user_from'], true)), - 'occupation' => utf8_normalize_nfc(request_var('occupation', $user_row['user_occ'], true)), - 'interests' => utf8_normalize_nfc(request_var('interests', $user_row['user_interests'], true)), 'bday_day' => 0, 'bday_month' => 0, 'bday_year' => 0, @@ -1379,25 +1378,12 @@ class acp_users $data['bday_year'] = request_var('bday_year', $data['bday_year']); $data['user_birthday'] = sprintf('%2d-%2d-%4d', $data['bday_day'], $data['bday_month'], $data['bday_year']); - if ($submit) { $error = validate_data($data, array( - 'icq' => array( - array('string', true, 3, 15), - array('match', true, '#^[0-9]+$#i')), - 'aim' => array('string', true, 3, 255), - 'msn' => array('string', true, 5, 255), 'jabber' => array( array('string', true, 5, 255), array('jabber')), - 'yim' => array('string', true, 5, 255), - 'website' => array( - array('string', true, 12, 255), - array('match', true, '#^http[s]?://(.*?\.)*?[a-z0-9\-]+\.[a-z]{2,4}#i')), - 'location' => array('string', true, 2, 100), - 'occupation' => array('string', true, 2, 500), - 'interests' => array('string', true, 2, 500), 'bday_day' => array('num', true, 1, 31), 'bday_month' => array('num', true, 1, 12), 'bday_year' => array('num', true, 1901, gmdate('Y', time())), @@ -1419,15 +1405,7 @@ class acp_users if (!sizeof($error)) { $sql_ary = array( - 'user_icq' => $data['icq'], - 'user_aim' => $data['aim'], - 'user_msnm' => $data['msn'], - 'user_yim' => $data['yim'], 'user_jabber' => $data['jabber'], - 'user_website' => $data['website'], - 'user_from' => $data['location'], - 'user_occ' => $data['occupation'], - 'user_interests'=> $data['interests'], 'user_birthday' => $data['user_birthday'], ); @@ -1471,16 +1449,7 @@ class acp_users unset($now); $template->assign_vars(array( - 'ICQ' => $data['icq'], - 'YIM' => $data['yim'], - 'AIM' => $data['aim'], - 'MSN' => $data['msn'], 'JABBER' => $data['jabber'], - 'WEBSITE' => $data['website'], - 'LOCATION' => $data['location'], - 'OCCUPATION' => $data['occupation'], - 'INTERESTS' => $data['interests'], - 'S_BIRTHDAY_DAY_OPTIONS' => $s_birthday_day_options, 'S_BIRTHDAY_MONTH_OPTIONS' => $s_birthday_month_options, 'S_BIRTHDAY_YEAR_OPTIONS' => $s_birthday_year_options, @@ -1509,7 +1478,6 @@ class acp_users 'hideonline' => request_var('hideonline', !$user_row['user_allow_viewonline']), 'notifymethod' => request_var('notifymethod', $user_row['user_notify_type']), 'notifypm' => request_var('notifypm', $user_row['user_notify_pm']), - 'popuppm' => request_var('popuppm', $this->optionget($user_row, 'popuppm')), 'allowpm' => request_var('allowpm', $user_row['user_allow_pm']), 'topic_sk' => request_var('topic_sk', ($user_row['user_topic_sortby_type']) ? $user_row['user_topic_sortby_type'] : 't'), @@ -1533,6 +1501,17 @@ class acp_users 'notify' => request_var('notify', $user_row['user_notify']), ); + /** + * Modify users preferences data + * + * @event core.acp_users_prefs_modify_data + * @var array data Array with users preferences data + * @var array user_row Array with user data + * @since 3.1.0-b3 + */ + $vars = array('data', 'user_row'); + extract($phpbb_dispatcher->trigger_event('core.acp_users_prefs_modify_data', compact($vars))); + if ($submit) { $error = validate_data($data, array( @@ -1553,7 +1532,6 @@ class acp_users if (!sizeof($error)) { - $this->optionset($user_row, 'popuppm', $data['popuppm']); $this->optionset($user_row, 'viewimg', $data['view_images']); $this->optionset($user_row, 'viewflash', $data['view_flash']); $this->optionset($user_row, 'viewsmilies', $data['view_smilies']); @@ -1590,37 +1568,53 @@ class acp_users 'user_notify' => $data['notify'], ); - $sql = 'UPDATE ' . USERS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " - WHERE user_id = $user_id"; - $db->sql_query($sql); + /** + * Modify SQL query before users preferences are updated + * + * @event core.acp_users_prefs_modify_sql + * @var array data Array with users preferences data + * @var array user_row Array with user data + * @var array sql_ary SQL array with users preferences data to update + * @var array error Array with errors data + * @since 3.1.0-b3 + */ + $vars = array('data', 'user_row', 'sql_ary', 'error'); + extract($phpbb_dispatcher->trigger_event('core.acp_users_prefs_modify_sql', compact($vars))); - // Check if user has an active session - if ($user_row['session_id']) + if (!sizeof($error)) { - // We'll update the session if user_allow_viewonline has changed and the user is a bot - // Or if it's a regular user and the admin set it to hide the session - if ($user_row['user_allow_viewonline'] != $sql_ary['user_allow_viewonline'] && $user_row['user_type'] == USER_IGNORE - || $user_row['user_allow_viewonline'] && !$sql_ary['user_allow_viewonline']) + $sql = 'UPDATE ' . USERS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " + WHERE user_id = $user_id"; + $db->sql_query($sql); + + // Check if user has an active session + if ($user_row['session_id']) { - // We also need to check if the user has the permission to cloak. - $user_auth = new \phpbb\auth\auth(); - $user_auth->acl($user_row); + // We'll update the session if user_allow_viewonline has changed and the user is a bot + // Or if it's a regular user and the admin set it to hide the session + if ($user_row['user_allow_viewonline'] != $sql_ary['user_allow_viewonline'] && $user_row['user_type'] == USER_IGNORE + || $user_row['user_allow_viewonline'] && !$sql_ary['user_allow_viewonline']) + { + // We also need to check if the user has the permission to cloak. + $user_auth = new \phpbb\auth\auth(); + $user_auth->acl($user_row); - $session_sql_ary = array( - 'session_viewonline' => ($user_auth->acl_get('u_hideonline')) ? $sql_ary['user_allow_viewonline'] : true, - ); + $session_sql_ary = array( + 'session_viewonline' => ($user_auth->acl_get('u_hideonline')) ? $sql_ary['user_allow_viewonline'] : true, + ); - $sql = 'UPDATE ' . SESSIONS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $session_sql_ary) . " - WHERE session_user_id = $user_id"; - $db->sql_query($sql); + $sql = 'UPDATE ' . SESSIONS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $session_sql_ary) . " + WHERE session_user_id = $user_id"; + $db->sql_query($sql); - unset($user_auth); + unset($user_auth); + } } - } - trigger_error($user->lang['USER_PREFS_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id)); + trigger_error($user->lang['USER_PREFS_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id)); + } } // Replace "error" strings with their real, localised form @@ -1684,7 +1678,7 @@ class acp_users } $timezone_selects = phpbb_timezone_select($user, $data['tz'], true); - $template->assign_vars(array( + $user_prefs_data = array( 'S_PREFS' => true, 'S_JABBER_DISABLED' => ($config['jab_enable'] && $user_row['user_jabber'] && @extension_loaded('xml')) ? false : true, @@ -1696,7 +1690,6 @@ class acp_users 'NOTIFY_IM' => ($data['notifymethod'] == NOTIFY_IM) ? true : false, 'NOTIFY_BOTH' => ($data['notifymethod'] == NOTIFY_BOTH) ? true : false, 'NOTIFY_PM' => $data['notifypm'], - 'POPUP_PM' => $data['popuppm'], 'BBCODE' => $data['bbcode'], 'SMILIES' => $data['smilies'], 'ATTACH_SIG' => $data['sig'], @@ -1725,9 +1718,22 @@ class acp_users 'S_STYLE_OPTIONS' => style_select($data['style']), 'S_TZ_OPTIONS' => $timezone_selects['tz_select'], 'S_TZ_DATE_OPTIONS' => $timezone_selects['tz_dates'], - ) ); + /** + * Modify users preferences data before assigning it to the template + * + * @event core.acp_users_prefs_modify_template_data + * @var array data Array with users preferences data + * @var array user_row Array with user data + * @var array user_prefs_data Array with users preferences data to be assigned to the template + * @since 3.1.0-b3 + */ + $vars = array('data', 'user_row', 'user_prefs_data'); + extract($phpbb_dispatcher->trigger_event('core.acp_users_prefs_modify_template_data', compact($vars))); + + $template->assign_vars($user_prefs_data); + break; case 'avatar': @@ -1742,7 +1748,7 @@ class acp_users $avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers(); // This is normalised data, without the user_ prefix - $avatar_data = \phpbb\avatar\manager::clean_row($user_row); + $avatar_data = \phpbb\avatar\manager::clean_row($user_row, 'user'); if ($submit) { @@ -1775,7 +1781,7 @@ class acp_users } else { - $driver = $phpbb_avatar_manager->get_driver($user->data['user_avatar_type']); + $driver = $phpbb_avatar_manager->get_driver($avatar_data['avatar_type']); if ($driver) { $driver->delete($avatar_data); @@ -1998,6 +2004,7 @@ class acp_users $start = request_var('start', 0); $deletemark = (isset($_POST['delmarked'])) ? true : false; $marked = request_var('mark', array(0)); + $pagination = $phpbb_container->get('pagination'); // Sort keys $sort_key = request_var('sk', 'a'); @@ -2099,7 +2106,7 @@ class acp_users WHERE a.poster_id = ' . $user_id . " AND a.is_orphan = 0 ORDER BY $order_by"; - $result = $db->sql_query_limit($sql, $config['posts_per_page'], $start); + $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start); while ($row = $db->sql_fetchrow($result)) { @@ -2134,11 +2141,10 @@ class acp_users $db->sql_freeresult($result); $base_url = $this->u_action . "&u=$user_id&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); $template->assign_vars(array( 'S_ATTACHMENTS' => true, - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $num_attachments, $config['topics_per_page'], $start), 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, )); @@ -2275,7 +2281,6 @@ class acp_users $error = array(); } - $sql = 'SELECT ug.*, g.* FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . " ug WHERE ug.user_id = $user_id diff --git a/phpBB/includes/acp/acp_words.php b/phpBB/includes/acp/acp_words.php index d8d14ba4ad..859b586302 100644 --- a/phpBB/includes/acp/acp_words.php +++ b/phpBB/includes/acp/acp_words.php @@ -101,7 +101,7 @@ class acp_words 'word' => $word, 'replacement' => $replacement ); - + if ($word_id) { $db->sql_query('UPDATE ' . WORDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE word_id = ' . $word_id); @@ -162,7 +162,6 @@ class acp_words break; } - $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'S_HIDDEN_FIELDS' => $s_hidden_fields) diff --git a/phpBB/includes/acp/auth.php b/phpBB/includes/acp/auth.php index f5f90fb5b8..c95dd1d153 100644 --- a/phpBB/includes/acp/auth.php +++ b/phpBB/includes/acp/auth.php @@ -139,7 +139,6 @@ class auth_admin extends \phpbb\auth\auth $auth2 = &$auth; } - $hold_ary[$userdata['user_id']] = array(); foreach ($forum_ids as $f_id) { @@ -506,7 +505,7 @@ class auth_admin extends \phpbb\auth\auth 'FORUM_ID' => $forum_id) ); - $this->assign_cat_array($ug_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, $show_trace, ($mode == 'view')); + $this->assign_cat_array($ug_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, ($mode == 'view'), $show_trace); unset($content_array[$ug_id]); } @@ -593,7 +592,7 @@ class auth_admin extends \phpbb\auth\auth 'FORUM_ID' => $forum_id) ); - $this->assign_cat_array($forum_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, $show_trace, ($mode == 'view')); + $this->assign_cat_array($forum_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, ($mode == 'view'), $show_trace); } unset($hold_ary[$ug_id], $ug_names_ary[$ug_id]); @@ -649,9 +648,9 @@ class auth_admin extends \phpbb\auth\auth { $template->assign_block_vars('role_mask.users', array( 'USER_ID' => $row['user_id'], - 'USERNAME' => $row['username'], - 'U_PROFILE' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=viewprofile&u={$row['user_id']}")) - ); + 'USERNAME' => get_username_string('username', $row['user_id'], $row['username']), + 'U_PROFILE' => get_username_string('profile', $row['user_id'], $row['username']), + )); } $db->sql_freeresult($result); } @@ -1099,7 +1098,7 @@ class auth_admin extends \phpbb\auth\auth * Assign category to template * used by display_mask() */ - function assign_cat_array(&$category_array, $tpl_cat, $tpl_mask, $ug_id, $forum_id, $show_trace = false, $s_view) + function assign_cat_array(&$category_array, $tpl_cat, $tpl_mask, $ug_id, $forum_id, $s_view, $show_trace = false) { global $template, $user, $phpbb_admin_path, $phpEx, $phpbb_container; diff --git a/phpBB/includes/acp/info/acp_prune.php b/phpBB/includes/acp/info/acp_prune.php index 7498e46cad..0f70d9d638 100644 --- a/phpBB/includes/acp/info/acp_prune.php +++ b/phpBB/includes/acp/info/acp_prune.php @@ -20,7 +20,7 @@ class acp_prune_info 'version' => '1.0.0', 'modes' => array( 'forums' => array('title' => 'ACP_PRUNE_FORUMS', 'auth' => 'acl_a_prune', 'cat' => array('ACP_MANAGE_FORUMS')), - 'users' => array('title' => 'ACP_PRUNE_USERS', 'auth' => 'acl_a_userdel', 'cat' => array('ACP_USER_SECURITY')), + 'users' => array('title' => 'ACP_PRUNE_USERS', 'auth' => 'acl_a_userdel', 'cat' => array('ACP_CAT_USERS')), ), ); } diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index c4076a0120..7b5d8449b3 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -362,7 +362,7 @@ class bbcode } // Replace {L_*} lang strings - $bbcode_tpl = preg_replace('/{L_([A-Z_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $bbcode_tpl); + $bbcode_tpl = preg_replace('/{L_([A-Z0-9_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $bbcode_tpl); if (!empty($rowset[$bbcode_id]['second_pass_replace'])) { @@ -404,7 +404,7 @@ class bbcode 'i_close' => '</span>', 'u_open' => '<span style="text-decoration: underline">', 'u_close' => '</span>', - 'img' => '<img src="$1" alt="' . $user->lang['IMAGE'] . '" />', + 'img' => '<img src="$1" class="postimage" alt="' . $user->lang['IMAGE'] . '" />', 'size' => '<span style="font-size: $1%; line-height: normal">$2</span>', 'color' => '<span style="color: $1">$2</span>', 'email' => '<a href="mailto:$1">$2</a>' @@ -466,7 +466,7 @@ class bbcode 'email' => array('{EMAIL}' => '$1', '{DESCRIPTION}' => '$2') ); - $tpl = preg_replace('/{L_([A-Z_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $tpl); + $tpl = preg_replace('/{L_([A-Z0-9_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $tpl); if (!empty($replacements[$tpl_name])) { diff --git a/phpBB/includes/captcha/captcha_gd.php b/phpBB/includes/captcha/captcha_gd.php index f58b590c4b..e7c01c040a 100644 --- a/phpBB/includes/captcha/captcha_gd.php +++ b/phpBB/includes/captcha/captcha_gd.php @@ -26,14 +26,13 @@ class captcha var $width = 360; var $height = 96; - /** * Create the image containing $code with a seed of $seed */ function execute($code, $seed) { global $config; - + mt_srand($seed); // Create image @@ -69,7 +68,6 @@ class captcha $bounding_boxes[$i] = $box; } - // Redistribute leftover x-space $offset = array(); for ($i = 0; $i < $code_len; ++$i) @@ -99,12 +97,12 @@ class captcha imagedashedline($img, mt_rand($x -3, $x + 3), mt_rand(0, 4), mt_rand($x -3, $x + 3), mt_rand($this->height - 5, $this->height), $current_colour); } } + if ($config['captcha_gd_wave'] && ($config['captcha_gd_y_grid'] || $config['captcha_gd_y_grid'])) { $this->wave($img); } - - + if ($config['captcha_gd_3d_noise']) { $xoffset = mt_rand(0,9); @@ -122,11 +120,12 @@ class captcha $dimm = $bounding_boxes[$i]; $xoffset += ($offset[$i] - $dimm[0]); $yoffset = mt_rand(-$dimm[1], $this->height - $dimm[3]); - + $noise[$i]->drawchar($sizes[$i], $xoffset, $yoffset, $img, $colour->get_resource('background'), $scheme); $xoffset += $dimm[2]; } } + $xoffset = 5; for ($i = 0; $i < $code_len; ++$i) { @@ -137,14 +136,17 @@ class captcha $characters[$i]->drawchar($sizes[$i], $xoffset, $yoffset, $img, $colour->get_resource('background'), $scheme); $xoffset += $dimm[2]; } + if ($config['captcha_gd_wave']) { $this->wave($img); } + if ($config['captcha_gd_foreground_noise']) { $this->noise_line($img, 0, 0, $this->width, $this->height, $colour->get_resource('background'), $scheme, $bg_colours); } + // Send image header('Content-Type: image/png'); header('Cache-control: no-cache, no-store'); @@ -158,13 +160,13 @@ class captcha function wave($img) { global $config; - + $period_x = mt_rand(12,18); $period_y = mt_rand(7,14); $amp_x = mt_rand(5,10); - $amp_y = mt_rand(2,4); + $amp_y = mt_rand(2,4); $socket = mt_rand(0,100); - + $dampen_x = mt_rand($this->width/5, $this->width/2); $dampen_y = mt_rand($this->height/5, $this->height/2); $direction_x = (mt_rand (0, 1)); @@ -183,7 +185,7 @@ class captcha } return $img; } - + /** * Noise line */ @@ -233,9 +235,8 @@ class captcha imagesetthickness($img, 1); } - function captcha_noise_bg_bitmaps() - { + { return array( 'width' => 15, 'height' => 5, @@ -292,14 +293,14 @@ class captcha ), )); } - + /** * Return bitmaps */ function captcha_bitmaps() { global $config; - + $chars = array( 'A' => array( array( @@ -1680,7 +1681,7 @@ class captcha 'J' => $chars['J'][mt_rand(0, min(sizeof($chars['J']), $config['captcha_gd_fonts']) -1)], 'K' => $chars['K'][mt_rand(0, min(sizeof($chars['K']), $config['captcha_gd_fonts']) -1)], 'L' => $chars['L'][mt_rand(0, min(sizeof($chars['L']), $config['captcha_gd_fonts']) -1)], - 'M' => $chars['M'][mt_rand(0, min(sizeof($chars['M']), $config['captcha_gd_fonts']) -1)], + 'M' => $chars['M'][mt_rand(0, min(sizeof($chars['M']), $config['captcha_gd_fonts']) -1)], 'N' => $chars['N'][mt_rand(0, min(sizeof($chars['N']), $config['captcha_gd_fonts']) -1)], 'O' => $chars['O'][mt_rand(0, min(sizeof($chars['O']), $config['captcha_gd_fonts']) -1)], 'P' => $chars['P'][mt_rand(0, min(sizeof($chars['P']), $config['captcha_gd_fonts']) -1)], @@ -2195,7 +2196,7 @@ class colour_manager { $mode = $this->mode; } - + if (!is_array($colour)) { if (isset($this->named_rgb[$colour])) @@ -2225,8 +2226,8 @@ class colour_manager return $this->random_colour($colour, $mode); } - $rgb = colour_manager::model_convert($colour, $mode, 'rgb'); - $store = ($this->mode == 'rgb') ? $rgb : colour_manager::model_convert($colour, $mode, $this->mode); + $rgb = $this->model_convert($colour, $mode, 'rgb'); + $store = ($this->mode == 'rgb') ? $rgb : $this->model_convert($colour, $mode, $this->mode); $resource = imagecolorallocate($this->img, $rgb[0], $rgb[1], $rgb[2]); $this->colours[$resource] = $store; @@ -2344,14 +2345,13 @@ class colour_manager $resource = $pre; } - $colour = colour_manager::model_convert($this->colours[$resource], $this->mode, $mode); + $colour = $this->model_convert($this->colours[$resource], $this->mode, $mode); $results = ($include_original) ? array($resource) : array(); $colour2 = $colour3 = $colour4 = $colour; $colour2[0] += 150; $colour3[0] += 180; $colour4[0] += 210; - $results[] = $this->allocate($colour2, $mode); $results[] = $this->allocate($colour3, $mode); $results[] = $this->allocate($colour4, $mode); @@ -2379,7 +2379,7 @@ class colour_manager $resource = $pre; } - $colour = colour_manager::model_convert($this->colours[$resource], $this->mode, $mode); + $colour = $this->model_convert($this->colours[$resource], $this->mode, $mode); $results = array(); if ($include_original) @@ -2389,7 +2389,7 @@ class colour_manager } // This is a hard problem. I chicken out and try to maintain readability at the cost of less randomness. - + while ($count > 0) { $colour[1] = ($colour[1] + mt_rand(40,60)) % 99; @@ -2417,11 +2417,11 @@ class colour_manager switch ($from_model) { case 'ahsv': - return colour_manager::ah2h($colour); + return $this->ah2h($colour); break; case 'rgb': - return colour_manager::rgb2hsv($colour); + return $this->rgb2hsv($colour); break; } break; @@ -2431,11 +2431,11 @@ class colour_manager switch ($from_model) { case 'hsv': - return colour_manager::h2ah($colour); + return $this->h2ah($colour); break; case 'rgb': - return colour_manager::h2ah(colour_manager::rgb2hsv($colour)); + return $this->h2ah($this->rgb2hsv($colour)); break; } break; @@ -2444,11 +2444,11 @@ class colour_manager switch ($from_model) { case 'hsv': - return colour_manager::hsv2rgb($colour); + return $this->hsv2rgb($colour); break; case 'ahsv': - return colour_manager::hsv2rgb(colour_manager::ah2h($colour)); + return $this->hsv2rgb($this->ah2h($colour)); break; } break; @@ -2461,7 +2461,7 @@ class colour_manager */ function hsv2rgb($hsv) { - colour_manager::normalize_hue($hsv[0]); + $this->normalize_hue($hsv[0]); $h = $hsv[0]; $s = min(1, max(0, $hsv[1] / 100)); @@ -2553,7 +2553,7 @@ class colour_manager break; } } - colour_manager::normalize_hue($h); + $this->normalize_hue($h); return array($h, $s * 100, $v * 100); } @@ -2577,10 +2577,10 @@ class colour_manager { if (is_array($ahue)) { - $ahue[0] = colour_manager::ah2h($ahue[0]); + $ahue[0] = $this->ah2h($ahue[0]); return $ahue; } - colour_manager::normalize_hue($ahue); + $this->normalize_hue($ahue); // blue through red is already ok if ($ahue >= 240) @@ -2611,10 +2611,10 @@ class colour_manager { if (is_array($hue)) { - $hue[0] = colour_manager::h2ah($hue[0]); + $hue[0] = $this->h2ah($hue[0]); return $hue; } - colour_manager::normalize_hue($hue); + $this->normalize_hue($hue); // blue through red is already ok if ($hue >= 240) diff --git a/phpBB/includes/captcha/captcha_gd_wave.php b/phpBB/includes/captcha/captcha_gd_wave.php index e19f54f777..185352dd4e 100644 --- a/phpBB/includes/captcha/captcha_gd_wave.php +++ b/phpBB/includes/captcha/captcha_gd_wave.php @@ -86,7 +86,7 @@ class captcha $fontcolors[0] = imagecolorallocate($img, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120)); - $colors = array(); + $colors = array(); $minr = mt_rand(20, 30); $ming = mt_rand(20, 30); @@ -184,7 +184,7 @@ class captcha for ($x = 1; $x <= $full_x; ++$x) { - $cur_height = $this->wave_height($x, $y, $subdivision_factor) + $this->grid_height($x, $y, 1, $x_grid, $y_grid); + $cur_height = $this->wave_height($x, $y, $subdivision_factor) + $this->grid_height($x, $y, $x_grid, $y_grid, 1); // height is a z-factor, not a y-factor $offset = $cur_height - $prev_height; @@ -264,7 +264,7 @@ class captcha return ((sin($x / (3 * $factor)) + sin($y / (3 * $factor))) * 10 * $tweak); } - function grid_height($x, $y, $factor = 1, $x_grid, $y_grid) + function grid_height($x, $y, $x_grid, $y_grid, $factor = 1) { return ((!($x % ($x_grid * $factor)) || !($y % ($y_grid * $factor))) ? 3 : 0); } diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index ae55a71e50..a59b4a8add 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -24,7 +24,7 @@ if (!defined('IN_PHPBB')) */ // phpBB Version -define('PHPBB_VERSION', '3.1.0-dev'); +define('PHPBB_VERSION', '3.1.0-b3-dev'); // QA-related // define('PHPBB_QA', 1); @@ -91,6 +91,7 @@ define('ITEM_MOVED', 2); define('ITEM_UNAPPROVED', 0); // => has not yet been approved define('ITEM_APPROVED', 1); // => has been approved, and has not been soft deleted define('ITEM_DELETED', 2); // => has been soft deleted +define('ITEM_REAPPROVE', 3); // => has been edited and needs to be re-approved // Forum Flags define('FORUM_FLAG_LINK_TRACK', 1); @@ -289,4 +290,3 @@ define('WORDS_TABLE', $table_prefix . 'words'); define('ZEBRA_TABLE', $table_prefix . 'zebra'); // Additional tables - diff --git a/phpBB/includes/db/index.htm b/phpBB/includes/db/index.htm deleted file mode 100644 index ee1f723a7d..0000000000 --- a/phpBB/includes/db/index.htm +++ /dev/null @@ -1,10 +0,0 @@ -<html> -<head> -<title></title> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -</head> - -<body bgcolor="#FFFFFF" text="#000000"> - -</body> -</html> diff --git a/phpBB/includes/db/schema_data.php b/phpBB/includes/db/schema_data.php deleted file mode 100644 index 69d39e0f8c..0000000000 --- a/phpBB/includes/db/schema_data.php +++ /dev/null @@ -1,1219 +0,0 @@ -<?php -/** -* -* @package dbal -* @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -$schema_data = array(); - -/** -* Define the basic structure -* The format: -* array('{TABLE_NAME}' => {TABLE_DATA}) -* {TABLE_DATA}: -* COLUMNS = array({column_name} = array({column_type}, {default}, {auto_increment})) -* PRIMARY_KEY = {column_name(s)} -* KEYS = array({key_name} = array({key_type}, {column_name(s)})), -* -* Column Types: -* INT:x => SIGNED int(x) -* BINT => BIGINT -* UINT => mediumint(8) UNSIGNED -* UINT:x => int(x) UNSIGNED -* TINT:x => tinyint(x) -* USINT => smallint(4) UNSIGNED (for _order columns) -* BOOL => tinyint(1) UNSIGNED -* VCHAR => varchar(255) -* CHAR:x => char(x) -* XSTEXT_UNI => text for storing 100 characters (topic_title for example) -* STEXT_UNI => text for storing 255 characters (normal input field with a max of 255 single-byte chars) - same as VCHAR_UNI -* TEXT_UNI => text for storing 3000 characters (short text, descriptions, comments, etc.) -* MTEXT_UNI => mediumtext (post text, large text) -* VCHAR:x => varchar(x) -* TIMESTAMP => int(11) UNSIGNED -* DECIMAL => decimal number (5,2) -* DECIMAL: => decimal number (x,2) -* PDECIMAL => precision decimal number (6,3) -* PDECIMAL: => precision decimal number (x,3) -* VCHAR_UNI => varchar(255) BINARY -* VCHAR_CI => varchar_ci for postgresql, others VCHAR -*/ -$schema_data['phpbb_attachments'] = array( - 'COLUMNS' => array( - 'attach_id' => array('UINT', NULL, 'auto_increment'), - 'post_msg_id' => array('UINT', 0), - 'topic_id' => array('UINT', 0), - 'in_message' => array('BOOL', 0), - 'poster_id' => array('UINT', 0), - 'is_orphan' => array('BOOL', 1), - 'physical_filename' => array('VCHAR', ''), - 'real_filename' => array('VCHAR', ''), - 'download_count' => array('UINT', 0), - 'attach_comment' => array('TEXT_UNI', ''), - 'extension' => array('VCHAR:100', ''), - 'mimetype' => array('VCHAR:100', ''), - 'filesize' => array('UINT:20', 0), - 'filetime' => array('TIMESTAMP', 0), - 'thumbnail' => array('BOOL', 0), - ), - 'PRIMARY_KEY' => 'attach_id', - 'KEYS' => array( - 'filetime' => array('INDEX', 'filetime'), - 'post_msg_id' => array('INDEX', 'post_msg_id'), - 'topic_id' => array('INDEX', 'topic_id'), - 'poster_id' => array('INDEX', 'poster_id'), - 'is_orphan' => array('INDEX', 'is_orphan'), - ), -); - -$schema_data['phpbb_acl_groups'] = array( - 'COLUMNS' => array( - 'group_id' => array('UINT', 0), - 'forum_id' => array('UINT', 0), - 'auth_option_id' => array('UINT', 0), - 'auth_role_id' => array('UINT', 0), - 'auth_setting' => array('TINT:2', 0), - ), - 'KEYS' => array( - 'group_id' => array('INDEX', 'group_id'), - 'auth_opt_id' => array('INDEX', 'auth_option_id'), - 'auth_role_id' => array('INDEX', 'auth_role_id'), - ), -); - -$schema_data['phpbb_acl_options'] = array( - 'COLUMNS' => array( - 'auth_option_id' => array('UINT', NULL, 'auto_increment'), - 'auth_option' => array('VCHAR:50', ''), - 'is_global' => array('BOOL', 0), - 'is_local' => array('BOOL', 0), - 'founder_only' => array('BOOL', 0), - ), - 'PRIMARY_KEY' => 'auth_option_id', - 'KEYS' => array( - 'auth_option' => array('UNIQUE', 'auth_option'), - ), -); - -$schema_data['phpbb_acl_roles'] = array( - 'COLUMNS' => array( - 'role_id' => array('UINT', NULL, 'auto_increment'), - 'role_name' => array('VCHAR_UNI', ''), - 'role_description' => array('TEXT_UNI', ''), - 'role_type' => array('VCHAR:10', ''), - 'role_order' => array('USINT', 0), - ), - 'PRIMARY_KEY' => 'role_id', - 'KEYS' => array( - 'role_type' => array('INDEX', 'role_type'), - 'role_order' => array('INDEX', 'role_order'), - ), -); - -$schema_data['phpbb_acl_roles_data'] = array( - 'COLUMNS' => array( - 'role_id' => array('UINT', 0), - 'auth_option_id' => array('UINT', 0), - 'auth_setting' => array('TINT:2', 0), - ), - 'PRIMARY_KEY' => array('role_id', 'auth_option_id'), - 'KEYS' => array( - 'ath_op_id' => array('INDEX', 'auth_option_id'), - ), -); - -$schema_data['phpbb_acl_users'] = array( - 'COLUMNS' => array( - 'user_id' => array('UINT', 0), - 'forum_id' => array('UINT', 0), - 'auth_option_id' => array('UINT', 0), - 'auth_role_id' => array('UINT', 0), - 'auth_setting' => array('TINT:2', 0), - ), - 'KEYS' => array( - 'user_id' => array('INDEX', 'user_id'), - 'auth_option_id' => array('INDEX', 'auth_option_id'), - 'auth_role_id' => array('INDEX', 'auth_role_id'), - ), -); - -$schema_data['phpbb_banlist'] = array( - 'COLUMNS' => array( - 'ban_id' => array('UINT', NULL, 'auto_increment'), - 'ban_userid' => array('UINT', 0), - 'ban_ip' => array('VCHAR:40', ''), - 'ban_email' => array('VCHAR_UNI:100', ''), - 'ban_start' => array('TIMESTAMP', 0), - 'ban_end' => array('TIMESTAMP', 0), - 'ban_exclude' => array('BOOL', 0), - 'ban_reason' => array('VCHAR_UNI', ''), - 'ban_give_reason' => array('VCHAR_UNI', ''), - ), - 'PRIMARY_KEY' => 'ban_id', - 'KEYS' => array( - 'ban_end' => array('INDEX', 'ban_end'), - 'ban_user' => array('INDEX', array('ban_userid', 'ban_exclude')), - 'ban_email' => array('INDEX', array('ban_email', 'ban_exclude')), - 'ban_ip' => array('INDEX', array('ban_ip', 'ban_exclude')), - ), -); - -$schema_data['phpbb_bbcodes'] = array( - 'COLUMNS' => array( - 'bbcode_id' => array('USINT', 0), - 'bbcode_tag' => array('VCHAR:16', ''), - 'bbcode_helpline' => array('VCHAR_UNI', ''), - 'display_on_posting' => array('BOOL', 0), - 'bbcode_match' => array('TEXT_UNI', ''), - 'bbcode_tpl' => array('MTEXT_UNI', ''), - 'first_pass_match' => array('MTEXT_UNI', ''), - 'first_pass_replace' => array('MTEXT_UNI', ''), - 'second_pass_match' => array('MTEXT_UNI', ''), - 'second_pass_replace' => array('MTEXT_UNI', ''), - ), - 'PRIMARY_KEY' => 'bbcode_id', - 'KEYS' => array( - 'display_on_post' => array('INDEX', 'display_on_posting'), - ), -); - -$schema_data['phpbb_bookmarks'] = array( - 'COLUMNS' => array( - 'topic_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - ), - 'PRIMARY_KEY' => array('topic_id', 'user_id'), -); - -$schema_data['phpbb_bots'] = array( - 'COLUMNS' => array( - 'bot_id' => array('UINT', NULL, 'auto_increment'), - 'bot_active' => array('BOOL', 1), - 'bot_name' => array('STEXT_UNI', ''), - 'user_id' => array('UINT', 0), - 'bot_agent' => array('VCHAR', ''), - 'bot_ip' => array('VCHAR', ''), - ), - 'PRIMARY_KEY' => 'bot_id', - 'KEYS' => array( - 'bot_active' => array('INDEX', 'bot_active'), - ), -); - -$schema_data['phpbb_config'] = array( - 'COLUMNS' => array( - 'config_name' => array('VCHAR', ''), - 'config_value' => array('VCHAR_UNI', ''), - 'is_dynamic' => array('BOOL', 0), - ), - 'PRIMARY_KEY' => 'config_name', - 'KEYS' => array( - 'is_dynamic' => array('INDEX', 'is_dynamic'), - ), -); - -$schema_data['phpbb_config_text'] = array( - 'COLUMNS' => array( - 'config_name' => array('VCHAR', ''), - 'config_value' => array('MTEXT', ''), - ), - 'PRIMARY_KEY' => 'config_name', -); - -$schema_data['phpbb_confirm'] = array( - 'COLUMNS' => array( - 'confirm_id' => array('CHAR:32', ''), - 'session_id' => array('CHAR:32', ''), - 'confirm_type' => array('TINT:3', 0), - 'code' => array('VCHAR:8', ''), - 'seed' => array('UINT:10', 0), - 'attempts' => array('UINT', 0), - ), - 'PRIMARY_KEY' => array('session_id', 'confirm_id'), - 'KEYS' => array( - 'confirm_type' => array('INDEX', 'confirm_type'), - ), -); - -$schema_data['phpbb_disallow'] = array( - 'COLUMNS' => array( - 'disallow_id' => array('UINT', NULL, 'auto_increment'), - 'disallow_username' => array('VCHAR_UNI:255', ''), - ), - 'PRIMARY_KEY' => 'disallow_id', -); - -$schema_data['phpbb_drafts'] = array( - 'COLUMNS' => array( - 'draft_id' => array('UINT', NULL, 'auto_increment'), - 'user_id' => array('UINT', 0), - 'topic_id' => array('UINT', 0), - 'forum_id' => array('UINT', 0), - 'save_time' => array('TIMESTAMP', 0), - 'draft_subject' => array('STEXT_UNI', ''), - 'draft_message' => array('MTEXT_UNI', ''), - ), - 'PRIMARY_KEY' => 'draft_id', - 'KEYS' => array( - 'save_time' => array('INDEX', 'save_time'), - ), -); - -$schema_data['phpbb_ext'] = array( - 'COLUMNS' => array( - 'ext_name' => array('VCHAR', ''), - 'ext_active' => array('BOOL', 0), - 'ext_state' => array('TEXT', ''), - ), - 'KEYS' => array( - 'ext_name' => array('UNIQUE', 'ext_name'), - ), -); - -$schema_data['phpbb_extensions'] = array( - 'COLUMNS' => array( - 'extension_id' => array('UINT', NULL, 'auto_increment'), - 'group_id' => array('UINT', 0), - 'extension' => array('VCHAR:100', ''), - ), - 'PRIMARY_KEY' => 'extension_id', -); - -$schema_data['phpbb_extension_groups'] = array( - 'COLUMNS' => array( - 'group_id' => array('UINT', NULL, 'auto_increment'), - 'group_name' => array('VCHAR_UNI', ''), - 'cat_id' => array('TINT:2', 0), - 'allow_group' => array('BOOL', 0), - 'download_mode' => array('BOOL', 1), - 'upload_icon' => array('VCHAR', ''), - 'max_filesize' => array('UINT:20', 0), - 'allowed_forums' => array('TEXT', ''), - 'allow_in_pm' => array('BOOL', 0), - ), - 'PRIMARY_KEY' => 'group_id', -); - -$schema_data['phpbb_forums'] = array( - 'COLUMNS' => array( - 'forum_id' => array('UINT', NULL, 'auto_increment'), - 'parent_id' => array('UINT', 0), - 'left_id' => array('UINT', 0), - 'right_id' => array('UINT', 0), - 'forum_parents' => array('MTEXT', ''), - 'forum_name' => array('STEXT_UNI', ''), - 'forum_desc' => array('TEXT_UNI', ''), - 'forum_desc_bitfield' => array('VCHAR:255', ''), - 'forum_desc_options' => array('UINT:11', 7), - 'forum_desc_uid' => array('VCHAR:8', ''), - 'forum_link' => array('VCHAR_UNI', ''), - 'forum_password' => array('VCHAR_UNI:40', ''), - 'forum_style' => array('UINT', 0), - 'forum_image' => array('VCHAR', ''), - 'forum_rules' => array('TEXT_UNI', ''), - 'forum_rules_link' => array('VCHAR_UNI', ''), - 'forum_rules_bitfield' => array('VCHAR:255', ''), - 'forum_rules_options' => array('UINT:11', 7), - 'forum_rules_uid' => array('VCHAR:8', ''), - 'forum_topics_per_page' => array('TINT:4', 0), - 'forum_type' => array('TINT:4', 0), - 'forum_status' => array('TINT:4', 0), - 'forum_posts_approved' => array('UINT', 0), - 'forum_posts_unapproved' => array('UINT', 0), - 'forum_posts_softdeleted' => array('UINT', 0), - 'forum_topics_approved' => array('UINT', 0), - 'forum_topics_unapproved' => array('UINT', 0), - 'forum_topics_softdeleted' => array('UINT', 0), - 'forum_last_post_id' => array('UINT', 0), - 'forum_last_poster_id' => array('UINT', 0), - 'forum_last_post_subject' => array('STEXT_UNI', ''), - 'forum_last_post_time' => array('TIMESTAMP', 0), - 'forum_last_poster_name'=> array('VCHAR_UNI', ''), - 'forum_last_poster_colour'=> array('VCHAR:6', ''), - 'forum_flags' => array('TINT:4', 32), - 'forum_options' => array('UINT:20', 0), - 'display_subforum_list' => array('BOOL', 1), - 'display_on_index' => array('BOOL', 1), - 'enable_indexing' => array('BOOL', 1), - 'enable_icons' => array('BOOL', 1), - 'enable_prune' => array('BOOL', 0), - 'prune_next' => array('TIMESTAMP', 0), - 'prune_days' => array('UINT', 0), - 'prune_viewed' => array('UINT', 0), - 'prune_freq' => array('UINT', 0), - ), - 'PRIMARY_KEY' => 'forum_id', - 'KEYS' => array( - 'left_right_id' => array('INDEX', array('left_id', 'right_id')), - 'forum_lastpost_id' => array('INDEX', 'forum_last_post_id'), - ), -); - -$schema_data['phpbb_forums_access'] = array( - 'COLUMNS' => array( - 'forum_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'session_id' => array('CHAR:32', ''), - ), - 'PRIMARY_KEY' => array('forum_id', 'user_id', 'session_id'), -); - -$schema_data['phpbb_forums_track'] = array( - 'COLUMNS' => array( - 'user_id' => array('UINT', 0), - 'forum_id' => array('UINT', 0), - 'mark_time' => array('TIMESTAMP', 0), - ), - 'PRIMARY_KEY' => array('user_id', 'forum_id'), -); - -$schema_data['phpbb_forums_watch'] = array( - 'COLUMNS' => array( - 'forum_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'notify_status' => array('BOOL', 0), - ), - 'KEYS' => array( - 'forum_id' => array('INDEX', 'forum_id'), - 'user_id' => array('INDEX', 'user_id'), - 'notify_stat' => array('INDEX', 'notify_status'), - ), -); - -$schema_data['phpbb_groups'] = array( - 'COLUMNS' => array( - 'group_id' => array('UINT', NULL, 'auto_increment'), - 'group_type' => array('TINT:4', 1), - 'group_founder_manage' => array('BOOL', 0), - 'group_skip_auth' => array('BOOL', 0), - 'group_name' => array('VCHAR_CI', ''), - 'group_desc' => array('TEXT_UNI', ''), - 'group_desc_bitfield' => array('VCHAR:255', ''), - 'group_desc_options' => array('UINT:11', 7), - 'group_desc_uid' => array('VCHAR:8', ''), - 'group_display' => array('BOOL', 0), - 'group_avatar' => array('VCHAR', ''), - 'group_avatar_type' => array('VCHAR:255', ''), - 'group_avatar_width' => array('USINT', 0), - 'group_avatar_height' => array('USINT', 0), - 'group_rank' => array('UINT', 0), - 'group_colour' => array('VCHAR:6', ''), - 'group_sig_chars' => array('UINT', 0), - 'group_receive_pm' => array('BOOL', 0), - 'group_message_limit' => array('UINT', 0), - 'group_max_recipients' => array('UINT', 0), - 'group_legend' => array('UINT', 0), - ), - 'PRIMARY_KEY' => 'group_id', - 'KEYS' => array( - 'group_legend_name' => array('INDEX', array('group_legend', 'group_name')), - ), -); - -$schema_data['phpbb_icons'] = array( - 'COLUMNS' => array( - 'icons_id' => array('UINT', NULL, 'auto_increment'), - 'icons_url' => array('VCHAR', ''), - 'icons_width' => array('TINT:4', 0), - 'icons_height' => array('TINT:4', 0), - 'icons_order' => array('UINT', 0), - 'display_on_posting' => array('BOOL', 1), - ), - 'PRIMARY_KEY' => 'icons_id', - 'KEYS' => array( - 'display_on_posting' => array('INDEX', 'display_on_posting'), - ), -); - -$schema_data['phpbb_lang'] = array( - 'COLUMNS' => array( - 'lang_id' => array('TINT:4', NULL, 'auto_increment'), - 'lang_iso' => array('VCHAR:30', ''), - 'lang_dir' => array('VCHAR:30', ''), - 'lang_english_name' => array('VCHAR_UNI:100', ''), - 'lang_local_name' => array('VCHAR_UNI:255', ''), - 'lang_author' => array('VCHAR_UNI:255', ''), - ), - 'PRIMARY_KEY' => 'lang_id', - 'KEYS' => array( - 'lang_iso' => array('INDEX', 'lang_iso'), - ), -); - -$schema_data['phpbb_log'] = array( - 'COLUMNS' => array( - 'log_id' => array('UINT', NULL, 'auto_increment'), - 'log_type' => array('TINT:4', 0), - 'user_id' => array('UINT', 0), - 'forum_id' => array('UINT', 0), - 'topic_id' => array('UINT', 0), - 'reportee_id' => array('UINT', 0), - 'log_ip' => array('VCHAR:40', ''), - 'log_time' => array('TIMESTAMP', 0), - 'log_operation' => array('TEXT_UNI', ''), - 'log_data' => array('MTEXT_UNI', ''), - ), - 'PRIMARY_KEY' => 'log_id', - 'KEYS' => array( - 'log_type' => array('INDEX', 'log_type'), - 'log_time' => array('INDEX', 'log_time'), - 'forum_id' => array('INDEX', 'forum_id'), - 'topic_id' => array('INDEX', 'topic_id'), - 'reportee_id' => array('INDEX', 'reportee_id'), - 'user_id' => array('INDEX', 'user_id'), - ), -); - -$schema_data['phpbb_login_attempts'] = array( - 'COLUMNS' => array( - 'attempt_ip' => array('VCHAR:40', ''), - 'attempt_browser' => array('VCHAR:150', ''), - 'attempt_forwarded_for' => array('VCHAR:255', ''), - 'attempt_time' => array('TIMESTAMP', 0), - 'user_id' => array('UINT', 0), - 'username' => array('VCHAR_UNI:255', 0), - 'username_clean' => array('VCHAR_CI', 0), - ), - 'KEYS' => array( - 'att_ip' => array('INDEX', array('attempt_ip', 'attempt_time')), - 'att_for' => array('INDEX', array('attempt_forwarded_for', 'attempt_time')), - 'att_time' => array('INDEX', array('attempt_time')), - 'user_id' => array('INDEX', 'user_id'), - ), -); - -$schema_data['phpbb_moderator_cache'] = array( - 'COLUMNS' => array( - 'forum_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'username' => array('VCHAR_UNI:255', ''), - 'group_id' => array('UINT', 0), - 'group_name' => array('VCHAR_UNI', ''), - 'display_on_index' => array('BOOL', 1), - ), - 'KEYS' => array( - 'disp_idx' => array('INDEX', 'display_on_index'), - 'forum_id' => array('INDEX', 'forum_id'), - ), -); - -$schema_data['phpbb_migrations'] = array( - 'COLUMNS' => array( - 'migration_name' => array('VCHAR', ''), - 'migration_depends_on' => array('TEXT', ''), - 'migration_schema_done' => array('BOOL', 0), - 'migration_data_done' => array('BOOL', 0), - 'migration_data_state' => array('TEXT', ''), - 'migration_start_time' => array('TIMESTAMP', 0), - 'migration_end_time' => array('TIMESTAMP', 0), - ), - 'PRIMARY_KEY' => 'migration_name', -); - -$schema_data['phpbb_modules'] = array( - 'COLUMNS' => array( - 'module_id' => array('UINT', NULL, 'auto_increment'), - 'module_enabled' => array('BOOL', 1), - 'module_display' => array('BOOL', 1), - 'module_basename' => array('VCHAR', ''), - 'module_class' => array('VCHAR:10', ''), - 'parent_id' => array('UINT', 0), - 'left_id' => array('UINT', 0), - 'right_id' => array('UINT', 0), - 'module_langname' => array('VCHAR', ''), - 'module_mode' => array('VCHAR', ''), - 'module_auth' => array('VCHAR', ''), - ), - 'PRIMARY_KEY' => 'module_id', - 'KEYS' => array( - 'left_right_id' => array('INDEX', array('left_id', 'right_id')), - 'module_enabled' => array('INDEX', 'module_enabled'), - 'class_left_id' => array('INDEX', array('module_class', 'left_id')), - ), -); - -$schema_data['phpbb_notification_types'] = array( - 'COLUMNS' => array( - 'notification_type_id' => array('USINT', NULL, 'auto_increment'), - 'notification_type_name' => array('VCHAR:255', ''), - 'notification_type_enabled' => array('BOOL', 1), - ), - 'PRIMARY_KEY' => array('notification_type_id'), - 'KEYS' => array( - 'type' => array('UNIQUE', array('notification_type_name')), - ), -); - -$schema_data['phpbb_notifications'] = array( - 'COLUMNS' => array( - 'notification_id' => array('UINT:10', NULL, 'auto_increment'), - 'notification_type_id' => array('USINT', 0), - 'item_id' => array('UINT', 0), - 'item_parent_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'notification_read' => array('BOOL', 0), - 'notification_time' => array('TIMESTAMP', 1), - 'notification_data' => array('TEXT_UNI', ''), - ), - 'PRIMARY_KEY' => 'notification_id', - 'KEYS' => array( - 'item_ident' => array('INDEX', array('notification_type_id', 'item_id')), - 'user' => array('INDEX', array('user_id', 'notification_read')), - ), -); - -$schema_data['phpbb_oauth_accounts'] = array( - 'COLUMNS' => array( - 'user_id' => array('UINT', 0), - 'provider' => array('VCHAR', ''), - 'oauth_provider_id' => array('TEXT_UNI', ''), - ), - 'PRIMARY_KEY' => array( - 'user_id', - 'provider', - ), -); - -$schema_data['phpbb_oauth_tokens'] = array( - 'COLUMNS' => array( - 'user_id' => array('UINT', 0), // phpbb_users.user_id - 'session_id' => array('CHAR:32', ''), // phpbb_sessions.session_id used only when user_id not set - 'provider' => array('VCHAR', ''), // Name of the OAuth provider - 'oauth_token' => array('MTEXT', ''), // Serialized token - ), - 'KEYS' => array( - 'user_id' => array('INDEX', 'user_id'), - 'provider' => array('INDEX', 'provider'), - ), -); - -$schema_data['phpbb_poll_options'] = array( - 'COLUMNS' => array( - 'poll_option_id' => array('TINT:4', 0), - 'topic_id' => array('UINT', 0), - 'poll_option_text' => array('TEXT_UNI', ''), - 'poll_option_total' => array('UINT', 0), - ), - 'KEYS' => array( - 'poll_opt_id' => array('INDEX', 'poll_option_id'), - 'topic_id' => array('INDEX', 'topic_id'), - ), -); - -$schema_data['phpbb_poll_votes'] = array( - 'COLUMNS' => array( - 'topic_id' => array('UINT', 0), - 'poll_option_id' => array('TINT:4', 0), - 'vote_user_id' => array('UINT', 0), - 'vote_user_ip' => array('VCHAR:40', ''), - ), - 'KEYS' => array( - 'topic_id' => array('INDEX', 'topic_id'), - 'vote_user_id' => array('INDEX', 'vote_user_id'), - 'vote_user_ip' => array('INDEX', 'vote_user_ip'), - ), -); - -$schema_data['phpbb_posts'] = array( - 'COLUMNS' => array( - 'post_id' => array('UINT', NULL, 'auto_increment'), - 'topic_id' => array('UINT', 0), - 'forum_id' => array('UINT', 0), - 'poster_id' => array('UINT', 0), - 'icon_id' => array('UINT', 0), - 'poster_ip' => array('VCHAR:40', ''), - 'post_time' => array('TIMESTAMP', 0), - 'post_visibility' => array('TINT:3', 0), - 'post_reported' => array('BOOL', 0), - 'enable_bbcode' => array('BOOL', 1), - 'enable_smilies' => array('BOOL', 1), - 'enable_magic_url' => array('BOOL', 1), - 'enable_sig' => array('BOOL', 1), - 'post_username' => array('VCHAR_UNI:255', ''), - 'post_subject' => array('STEXT_UNI', '', 'true_sort'), - 'post_text' => array('MTEXT_UNI', ''), - 'post_checksum' => array('VCHAR:32', ''), - 'post_attachment' => array('BOOL', 0), - 'bbcode_bitfield' => array('VCHAR:255', ''), - 'bbcode_uid' => array('VCHAR:8', ''), - 'post_postcount' => array('BOOL', 1), - 'post_edit_time' => array('TIMESTAMP', 0), - 'post_edit_reason' => array('STEXT_UNI', ''), - 'post_edit_user' => array('UINT', 0), - 'post_edit_count' => array('USINT', 0), - 'post_edit_locked' => array('BOOL', 0), - 'post_delete_time' => array('TIMESTAMP', 0), - 'post_delete_reason' => array('STEXT_UNI', ''), - 'post_delete_user' => array('UINT', 0), - ), - 'PRIMARY_KEY' => 'post_id', - 'KEYS' => array( - 'forum_id' => array('INDEX', 'forum_id'), - 'topic_id' => array('INDEX', 'topic_id'), - 'poster_ip' => array('INDEX', 'poster_ip'), - 'poster_id' => array('INDEX', 'poster_id'), - 'post_visibility' => array('INDEX', 'post_visibility'), - 'post_username' => array('INDEX', 'post_username'), - 'tid_post_time' => array('INDEX', array('topic_id', 'post_time')), - ), -); - -$schema_data['phpbb_privmsgs'] = array( - 'COLUMNS' => array( - 'msg_id' => array('UINT', NULL, 'auto_increment'), - 'root_level' => array('UINT', 0), - 'author_id' => array('UINT', 0), - 'icon_id' => array('UINT', 0), - 'author_ip' => array('VCHAR:40', ''), - 'message_time' => array('TIMESTAMP', 0), - 'enable_bbcode' => array('BOOL', 1), - 'enable_smilies' => array('BOOL', 1), - 'enable_magic_url' => array('BOOL', 1), - 'enable_sig' => array('BOOL', 1), - 'message_subject' => array('STEXT_UNI', ''), - 'message_text' => array('MTEXT_UNI', ''), - 'message_edit_reason' => array('STEXT_UNI', ''), - 'message_edit_user' => array('UINT', 0), - 'message_attachment' => array('BOOL', 0), - 'bbcode_bitfield' => array('VCHAR:255', ''), - 'bbcode_uid' => array('VCHAR:8', ''), - 'message_edit_time' => array('TIMESTAMP', 0), - 'message_edit_count' => array('USINT', 0), - 'to_address' => array('TEXT_UNI', ''), - 'bcc_address' => array('TEXT_UNI', ''), - 'message_reported' => array('BOOL', 0), - ), - 'PRIMARY_KEY' => 'msg_id', - 'KEYS' => array( - 'author_ip' => array('INDEX', 'author_ip'), - 'message_time' => array('INDEX', 'message_time'), - 'author_id' => array('INDEX', 'author_id'), - 'root_level' => array('INDEX', 'root_level'), - ), -); - -$schema_data['phpbb_privmsgs_folder'] = array( - 'COLUMNS' => array( - 'folder_id' => array('UINT', NULL, 'auto_increment'), - 'user_id' => array('UINT', 0), - 'folder_name' => array('VCHAR_UNI', ''), - 'pm_count' => array('UINT', 0), - ), - 'PRIMARY_KEY' => 'folder_id', - 'KEYS' => array( - 'user_id' => array('INDEX', 'user_id'), - ), -); - -$schema_data['phpbb_privmsgs_rules'] = array( - 'COLUMNS' => array( - 'rule_id' => array('UINT', NULL, 'auto_increment'), - 'user_id' => array('UINT', 0), - 'rule_check' => array('UINT', 0), - 'rule_connection' => array('UINT', 0), - 'rule_string' => array('VCHAR_UNI', ''), - 'rule_user_id' => array('UINT', 0), - 'rule_group_id' => array('UINT', 0), - 'rule_action' => array('UINT', 0), - 'rule_folder_id' => array('INT:11', 0), - ), - 'PRIMARY_KEY' => 'rule_id', - 'KEYS' => array( - 'user_id' => array('INDEX', 'user_id'), - ), -); - -$schema_data['phpbb_privmsgs_to'] = array( - 'COLUMNS' => array( - 'msg_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'author_id' => array('UINT', 0), - 'pm_deleted' => array('BOOL', 0), - 'pm_new' => array('BOOL', 1), - 'pm_unread' => array('BOOL', 1), - 'pm_replied' => array('BOOL', 0), - 'pm_marked' => array('BOOL', 0), - 'pm_forwarded' => array('BOOL', 0), - 'folder_id' => array('INT:11', 0), - ), - 'KEYS' => array( - 'msg_id' => array('INDEX', 'msg_id'), - 'author_id' => array('INDEX', 'author_id'), - 'usr_flder_id' => array('INDEX', array('user_id', 'folder_id')), - ), -); - -$schema_data['phpbb_profile_fields'] = array( - 'COLUMNS' => array( - 'field_id' => array('UINT', NULL, 'auto_increment'), - 'field_name' => array('VCHAR_UNI', ''), - 'field_type' => array('TINT:4', 0), - 'field_ident' => array('VCHAR:20', ''), - 'field_length' => array('VCHAR:20', ''), - 'field_minlen' => array('VCHAR', ''), - 'field_maxlen' => array('VCHAR', ''), - 'field_novalue' => array('VCHAR_UNI', ''), - 'field_default_value' => array('VCHAR_UNI', ''), - 'field_validation' => array('VCHAR_UNI:20', ''), - 'field_required' => array('BOOL', 0), - 'field_show_novalue' => array('BOOL', 0), - 'field_show_on_reg' => array('BOOL', 0), - 'field_show_on_pm' => array('BOOL', 0), - 'field_show_on_vt' => array('BOOL', 0), - 'field_show_profile' => array('BOOL', 0), - 'field_hide' => array('BOOL', 0), - 'field_no_view' => array('BOOL', 0), - 'field_active' => array('BOOL', 0), - 'field_order' => array('UINT', 0), - ), - 'PRIMARY_KEY' => 'field_id', - 'KEYS' => array( - 'fld_type' => array('INDEX', 'field_type'), - 'fld_ordr' => array('INDEX', 'field_order'), - ), -); - -$schema_data['phpbb_profile_fields_data'] = array( - 'COLUMNS' => array( - 'user_id' => array('UINT', 0), - ), - 'PRIMARY_KEY' => 'user_id', -); - -$schema_data['phpbb_profile_fields_lang'] = array( - 'COLUMNS' => array( - 'field_id' => array('UINT', 0), - 'lang_id' => array('UINT', 0), - 'option_id' => array('UINT', 0), - 'field_type' => array('TINT:4', 0), - 'lang_value' => array('VCHAR_UNI', ''), - ), - 'PRIMARY_KEY' => array('field_id', 'lang_id', 'option_id'), -); - -$schema_data['phpbb_profile_lang'] = array( - 'COLUMNS' => array( - 'field_id' => array('UINT', 0), - 'lang_id' => array('UINT', 0), - 'lang_name' => array('VCHAR_UNI', ''), - 'lang_explain' => array('TEXT_UNI', ''), - 'lang_default_value' => array('VCHAR_UNI', ''), - ), - 'PRIMARY_KEY' => array('field_id', 'lang_id'), -); - -$schema_data['phpbb_ranks'] = array( - 'COLUMNS' => array( - 'rank_id' => array('UINT', NULL, 'auto_increment'), - 'rank_title' => array('VCHAR_UNI', ''), - 'rank_min' => array('UINT', 0), - 'rank_special' => array('BOOL', 0), - 'rank_image' => array('VCHAR', ''), - ), - 'PRIMARY_KEY' => 'rank_id', -); - -$schema_data['phpbb_reports'] = array( - 'COLUMNS' => array( - 'report_id' => array('UINT', NULL, 'auto_increment'), - 'reason_id' => array('USINT', 0), - 'post_id' => array('UINT', 0), - 'pm_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'user_notify' => array('BOOL', 0), - 'report_closed' => array('BOOL', 0), - 'report_time' => array('TIMESTAMP', 0), - 'report_text' => array('MTEXT_UNI', ''), - 'reported_post_text' => array('MTEXT_UNI', ''), - 'reported_post_uid' => array('VCHAR:8', ''), - 'reported_post_bitfield' => array('VCHAR:255', ''), - 'reported_post_enable_magic_url' => array('BOOL', 1), - 'reported_post_enable_smilies' => array('BOOL', 1), - 'reported_post_enable_bbcode' => array('BOOL', 1) - ), - 'PRIMARY_KEY' => 'report_id', - 'KEYS' => array( - 'post_id' => array('INDEX', 'post_id'), - 'pm_id' => array('INDEX', 'pm_id'), - ), -); - -$schema_data['phpbb_reports_reasons'] = array( - 'COLUMNS' => array( - 'reason_id' => array('USINT', NULL, 'auto_increment'), - 'reason_title' => array('VCHAR_UNI', ''), - 'reason_description' => array('MTEXT_UNI', ''), - 'reason_order' => array('USINT', 0), - ), - 'PRIMARY_KEY' => 'reason_id', -); - -$schema_data['phpbb_search_results'] = array( - 'COLUMNS' => array( - 'search_key' => array('VCHAR:32', ''), - 'search_time' => array('TIMESTAMP', 0), - 'search_keywords' => array('MTEXT_UNI', ''), - 'search_authors' => array('MTEXT', ''), - ), - 'PRIMARY_KEY' => 'search_key', -); - -$schema_data['phpbb_search_wordlist'] = array( - 'COLUMNS' => array( - 'word_id' => array('UINT', NULL, 'auto_increment'), - 'word_text' => array('VCHAR_UNI', ''), - 'word_common' => array('BOOL', 0), - 'word_count' => array('UINT', 0), - ), - 'PRIMARY_KEY' => 'word_id', - 'KEYS' => array( - 'wrd_txt' => array('UNIQUE', 'word_text'), - 'wrd_cnt' => array('INDEX', 'word_count'), - ), -); - -$schema_data['phpbb_search_wordmatch'] = array( - 'COLUMNS' => array( - 'post_id' => array('UINT', 0), - 'word_id' => array('UINT', 0), - 'title_match' => array('BOOL', 0), - ), - 'KEYS' => array( - 'unq_mtch' => array('UNIQUE', array('word_id', 'post_id', 'title_match')), - 'word_id' => array('INDEX', 'word_id'), - 'post_id' => array('INDEX', 'post_id'), - ), -); - -$schema_data['phpbb_sessions'] = array( - 'COLUMNS' => array( - 'session_id' => array('CHAR:32', ''), - 'session_user_id' => array('UINT', 0), - 'session_forum_id' => array('UINT', 0), - 'session_last_visit' => array('TIMESTAMP', 0), - 'session_start' => array('TIMESTAMP', 0), - 'session_time' => array('TIMESTAMP', 0), - 'session_ip' => array('VCHAR:40', ''), - 'session_browser' => array('VCHAR:150', ''), - 'session_forwarded_for' => array('VCHAR:255', ''), - 'session_page' => array('VCHAR_UNI', ''), - 'session_viewonline' => array('BOOL', 1), - 'session_autologin' => array('BOOL', 0), - 'session_admin' => array('BOOL', 0), - ), - 'PRIMARY_KEY' => 'session_id', - 'KEYS' => array( - 'session_time' => array('INDEX', 'session_time'), - 'session_user_id' => array('INDEX', 'session_user_id'), - 'session_fid' => array('INDEX', 'session_forum_id'), - ), -); - -$schema_data['phpbb_sessions_keys'] = array( - 'COLUMNS' => array( - 'key_id' => array('CHAR:32', ''), - 'user_id' => array('UINT', 0), - 'last_ip' => array('VCHAR:40', ''), - 'last_login' => array('TIMESTAMP', 0), - ), - 'PRIMARY_KEY' => array('key_id', 'user_id'), - 'KEYS' => array( - 'last_login' => array('INDEX', 'last_login'), - ), -); - -$schema_data['phpbb_sitelist'] = array( - 'COLUMNS' => array( - 'site_id' => array('UINT', NULL, 'auto_increment'), - 'site_ip' => array('VCHAR:40', ''), - 'site_hostname' => array('VCHAR', ''), - 'ip_exclude' => array('BOOL', 0), - ), - 'PRIMARY_KEY' => 'site_id', -); - -$schema_data['phpbb_smilies'] = array( - 'COLUMNS' => array( - 'smiley_id' => array('UINT', NULL, 'auto_increment'), - // We may want to set 'code' to VCHAR:50 or check if unicode support is possible... at the moment only ASCII characters are allowed. - 'code' => array('VCHAR_UNI:50', ''), - 'emotion' => array('VCHAR_UNI:50', ''), - 'smiley_url' => array('VCHAR:50', ''), - 'smiley_width' => array('USINT', 0), - 'smiley_height' => array('USINT', 0), - 'smiley_order' => array('UINT', 0), - 'display_on_posting'=> array('BOOL', 1), - ), - 'PRIMARY_KEY' => 'smiley_id', - 'KEYS' => array( - 'display_on_post' => array('INDEX', 'display_on_posting'), - ), -); - -$schema_data['phpbb_styles'] = array( - 'COLUMNS' => array( - 'style_id' => array('UINT', NULL, 'auto_increment'), - 'style_name' => array('VCHAR_UNI:255', ''), - 'style_copyright' => array('VCHAR_UNI', ''), - 'style_active' => array('BOOL', 1), - 'style_path' => array('VCHAR:100', ''), - 'bbcode_bitfield' => array('VCHAR:255', 'kNg='), - 'style_parent_id' => array('UINT:4', 0), - 'style_parent_tree' => array('TEXT', ''), - ), - 'PRIMARY_KEY' => 'style_id', - 'KEYS' => array( - 'style_name' => array('UNIQUE', 'style_name'), - ), -); - -$schema_data['phpbb_teampage'] = array( - 'COLUMNS' => array( - 'teampage_id' => array('UINT', NULL, 'auto_increment'), - 'group_id' => array('UINT', 0), - 'teampage_name' => array('VCHAR_UNI:255', ''), - 'teampage_position' => array('UINT', 0), - 'teampage_parent' => array('UINT', 0), - ), - 'PRIMARY_KEY' => 'teampage_id', -); - -$schema_data['phpbb_topics'] = array( - 'COLUMNS' => array( - 'topic_id' => array('UINT', NULL, 'auto_increment'), - 'forum_id' => array('UINT', 0), - 'icon_id' => array('UINT', 0), - 'topic_attachment' => array('BOOL', 0), - 'topic_visibility' => array('TINT:3', 0), - 'topic_reported' => array('BOOL', 0), - 'topic_title' => array('STEXT_UNI', '', 'true_sort'), - 'topic_poster' => array('UINT', 0), - 'topic_time' => array('TIMESTAMP', 0), - 'topic_time_limit' => array('TIMESTAMP', 0), - 'topic_views' => array('UINT', 0), - 'topic_posts_approved' => array('UINT', 0), - 'topic_posts_unapproved' => array('UINT', 0), - 'topic_posts_softdeleted' => array('UINT', 0), - 'topic_status' => array('TINT:3', 0), - 'topic_type' => array('TINT:3', 0), - 'topic_first_post_id' => array('UINT', 0), - 'topic_first_poster_name' => array('VCHAR_UNI', ''), - 'topic_first_poster_colour' => array('VCHAR:6', ''), - 'topic_last_post_id' => array('UINT', 0), - 'topic_last_poster_id' => array('UINT', 0), - 'topic_last_poster_name' => array('VCHAR_UNI', ''), - 'topic_last_poster_colour' => array('VCHAR:6', ''), - 'topic_last_post_subject' => array('STEXT_UNI', ''), - 'topic_last_post_time' => array('TIMESTAMP', 0), - 'topic_last_view_time' => array('TIMESTAMP', 0), - 'topic_moved_id' => array('UINT', 0), - 'topic_bumped' => array('BOOL', 0), - 'topic_bumper' => array('UINT', 0), - 'poll_title' => array('STEXT_UNI', ''), - 'poll_start' => array('TIMESTAMP', 0), - 'poll_length' => array('TIMESTAMP', 0), - 'poll_max_options' => array('TINT:4', 1), - 'poll_last_vote' => array('TIMESTAMP', 0), - 'poll_vote_change' => array('BOOL', 0), - 'topic_delete_time' => array('TIMESTAMP', 0), - 'topic_delete_reason' => array('STEXT_UNI', ''), - 'topic_delete_user' => array('UINT', 0), - ), - 'PRIMARY_KEY' => 'topic_id', - 'KEYS' => array( - 'forum_id' => array('INDEX', 'forum_id'), - 'forum_id_type' => array('INDEX', array('forum_id', 'topic_type')), - 'last_post_time' => array('INDEX', 'topic_last_post_time'), - 'topic_visibility' => array('INDEX', 'topic_visibility'), - 'forum_appr_last' => array('INDEX', array('forum_id', 'topic_visibility', 'topic_last_post_id')), - 'fid_time_moved' => array('INDEX', array('forum_id', 'topic_last_post_time', 'topic_moved_id')), - ), -); - -$schema_data['phpbb_topics_track'] = array( - 'COLUMNS' => array( - 'user_id' => array('UINT', 0), - 'topic_id' => array('UINT', 0), - 'forum_id' => array('UINT', 0), - 'mark_time' => array('TIMESTAMP', 0), - ), - 'PRIMARY_KEY' => array('user_id', 'topic_id'), - 'KEYS' => array( - 'topic_id' => array('INDEX', 'topic_id'), - 'forum_id' => array('INDEX', 'forum_id'), - ), -); - -$schema_data['phpbb_topics_posted'] = array( - 'COLUMNS' => array( - 'user_id' => array('UINT', 0), - 'topic_id' => array('UINT', 0), - 'topic_posted' => array('BOOL', 0), - ), - 'PRIMARY_KEY' => array('user_id', 'topic_id'), -); - -$schema_data['phpbb_topics_watch'] = array( - 'COLUMNS' => array( - 'topic_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'notify_status' => array('BOOL', 0), - ), - 'KEYS' => array( - 'topic_id' => array('INDEX', 'topic_id'), - 'user_id' => array('INDEX', 'user_id'), - 'notify_stat' => array('INDEX', 'notify_status'), - ), -); - -$schema_data['phpbb_user_notifications'] = array( - 'COLUMNS' => array( - 'item_type' => array('VCHAR:255', ''), - 'item_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'method' => array('VCHAR:255', ''), - 'notify' => array('BOOL', 1), - ), -); - -$schema_data['phpbb_user_group'] = array( - 'COLUMNS' => array( - 'group_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'group_leader' => array('BOOL', 0), - 'user_pending' => array('BOOL', 1), - ), - 'KEYS' => array( - 'group_id' => array('INDEX', 'group_id'), - 'user_id' => array('INDEX', 'user_id'), - 'group_leader' => array('INDEX', 'group_leader'), - ), -); - -$schema_data['phpbb_users'] = array( - 'COLUMNS' => array( - 'user_id' => array('UINT', NULL, 'auto_increment'), - 'user_type' => array('TINT:2', 0), - 'group_id' => array('UINT', 3), - 'user_permissions' => array('MTEXT', ''), - 'user_perm_from' => array('UINT', 0), - 'user_ip' => array('VCHAR:40', ''), - 'user_regdate' => array('TIMESTAMP', 0), - 'username' => array('VCHAR_CI', ''), - 'username_clean' => array('VCHAR_CI', ''), - 'user_password' => array('VCHAR_UNI:40', ''), - 'user_passchg' => array('TIMESTAMP', 0), - 'user_pass_convert' => array('BOOL', 0), - 'user_email' => array('VCHAR_UNI:100', ''), - 'user_email_hash' => array('BINT', 0), - 'user_birthday' => array('VCHAR:10', ''), - 'user_lastvisit' => array('TIMESTAMP', 0), - 'user_lastmark' => array('TIMESTAMP', 0), - 'user_lastpost_time' => array('TIMESTAMP', 0), - 'user_lastpage' => array('VCHAR_UNI:200', ''), - 'user_last_confirm_key' => array('VCHAR:10', ''), - 'user_last_search' => array('TIMESTAMP', 0), - 'user_warnings' => array('TINT:4', 0), - 'user_last_warning' => array('TIMESTAMP', 0), - 'user_login_attempts' => array('TINT:4', 0), - 'user_inactive_reason' => array('TINT:2', 0), - 'user_inactive_time' => array('TIMESTAMP', 0), - 'user_posts' => array('UINT', 0), - 'user_lang' => array('VCHAR:30', ''), - 'user_timezone' => array('VCHAR:100', 'UTC'), - 'user_dateformat' => array('VCHAR_UNI:30', 'd M Y H:i'), - 'user_style' => array('UINT', 0), - 'user_rank' => array('UINT', 0), - 'user_colour' => array('VCHAR:6', ''), - 'user_new_privmsg' => array('INT:4', 0), - 'user_unread_privmsg' => array('INT:4', 0), - 'user_last_privmsg' => array('TIMESTAMP', 0), - 'user_message_rules' => array('BOOL', 0), - 'user_full_folder' => array('INT:11', -3), - 'user_emailtime' => array('TIMESTAMP', 0), - 'user_topic_show_days' => array('USINT', 0), - 'user_topic_sortby_type' => array('VCHAR:1', 't'), - 'user_topic_sortby_dir' => array('VCHAR:1', 'd'), - 'user_post_show_days' => array('USINT', 0), - 'user_post_sortby_type' => array('VCHAR:1', 't'), - 'user_post_sortby_dir' => array('VCHAR:1', 'a'), - 'user_notify' => array('BOOL', 0), - 'user_notify_pm' => array('BOOL', 1), - 'user_notify_type' => array('TINT:4', 0), - 'user_allow_pm' => array('BOOL', 1), - 'user_allow_viewonline' => array('BOOL', 1), - 'user_allow_viewemail' => array('BOOL', 1), - 'user_allow_massemail' => array('BOOL', 1), - 'user_options' => array('UINT:11', 230271), - 'user_avatar' => array('VCHAR', ''), - 'user_avatar_type' => array('VCHAR:255', ''), - 'user_avatar_width' => array('USINT', 0), - 'user_avatar_height' => array('USINT', 0), - 'user_sig' => array('MTEXT_UNI', ''), - 'user_sig_bbcode_uid' => array('VCHAR:8', ''), - 'user_sig_bbcode_bitfield' => array('VCHAR:255', ''), - 'user_from' => array('VCHAR_UNI:100', ''), - 'user_icq' => array('VCHAR:15', ''), - 'user_aim' => array('VCHAR_UNI', ''), - 'user_yim' => array('VCHAR_UNI', ''), - 'user_msnm' => array('VCHAR_UNI', ''), - 'user_jabber' => array('VCHAR_UNI', ''), - 'user_website' => array('VCHAR_UNI:200', ''), - 'user_occ' => array('TEXT_UNI', ''), - 'user_interests' => array('TEXT_UNI', ''), - 'user_actkey' => array('VCHAR:32', ''), - 'user_newpasswd' => array('VCHAR_UNI:40', ''), - 'user_form_salt' => array('VCHAR_UNI:32', ''), - 'user_new' => array('BOOL', 1), - 'user_reminded' => array('TINT:4', 0), - 'user_reminded_time' => array('TIMESTAMP', 0), - ), - 'PRIMARY_KEY' => 'user_id', - 'KEYS' => array( - 'user_birthday' => array('INDEX', 'user_birthday'), - 'user_email_hash' => array('INDEX', 'user_email_hash'), - 'user_type' => array('INDEX', 'user_type'), - 'username_clean' => array('UNIQUE', 'username_clean'), - ), -); - -$schema_data['phpbb_warnings'] = array( - 'COLUMNS' => array( - 'warning_id' => array('UINT', NULL, 'auto_increment'), - 'user_id' => array('UINT', 0), - 'post_id' => array('UINT', 0), - 'log_id' => array('UINT', 0), - 'warning_time' => array('TIMESTAMP', 0), - ), - 'PRIMARY_KEY' => 'warning_id', -); - -$schema_data['phpbb_words'] = array( - 'COLUMNS' => array( - 'word_id' => array('UINT', NULL, 'auto_increment'), - 'word' => array('VCHAR_UNI', ''), - 'replacement' => array('VCHAR_UNI', ''), - ), - 'PRIMARY_KEY' => 'word_id', -); - -$schema_data['phpbb_zebra'] = array( - 'COLUMNS' => array( - 'user_id' => array('UINT', 0), - 'zebra_id' => array('UINT', 0), - 'friend' => array('BOOL', 0), - 'foe' => array('BOOL', 0), - ), - 'PRIMARY_KEY' => array('user_id', 'zebra_id'), -); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index e1f96c0b1e..92fe090823 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -368,207 +368,6 @@ function still_on_time($extra_time = 15) } /** -* -* @version Version 0.1 / slightly modified for phpBB 3.1.x (using $H$ as hash type identifier) -* -* Portable PHP password hashing framework. -* -* Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in -* the public domain. -* -* There's absolutely no warranty. -* -* The homepage URL for this framework is: -* -* http://www.openwall.com/phpass/ -* -* Please be sure to update the Version line if you edit this file in any way. -* It is suggested that you leave the main version number intact, but indicate -* your project name (after the slash) and add your own revision information. -* -* Please do not change the "private" password hashing method implemented in -* here, thereby making your hashes incompatible. However, if you must, please -* change the hash type identifier (the "$P$") to something different. -* -* Obviously, since this code is in the public domain, the above are not -* requirements (there can be none), but merely suggestions. -* -* -* Hash the password -*/ -function phpbb_hash($password) -{ - $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; - - $random_state = unique_id(); - $random = ''; - $count = 6; - - if (($fh = @fopen('/dev/urandom', 'rb'))) - { - $random = fread($fh, $count); - fclose($fh); - } - - if (strlen($random) < $count) - { - $random = ''; - - for ($i = 0; $i < $count; $i += 16) - { - $random_state = md5(unique_id() . $random_state); - $random .= pack('H*', md5($random_state)); - } - $random = substr($random, 0, $count); - } - - $hash = _hash_crypt_private($password, _hash_gensalt_private($random, $itoa64), $itoa64); - - if (strlen($hash) == 34) - { - return $hash; - } - - return md5($password); -} - -/** -* Check for correct password -* -* @param string $password The password in plain text -* @param string $hash The stored password hash -* -* @return bool Returns true if the password is correct, false if not. -*/ -function phpbb_check_hash($password, $hash) -{ - if (strlen($password) > 4096) - { - // If the password is too huge, we will simply reject it - // and not let the server try to hash it. - return false; - } - - $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; - if (strlen($hash) == 34) - { - return (_hash_crypt_private($password, $hash, $itoa64) === $hash) ? true : false; - } - - return (md5($password) === $hash) ? true : false; -} - -/** -* Generate salt for hash generation -*/ -function _hash_gensalt_private($input, &$itoa64, $iteration_count_log2 = 6) -{ - if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31) - { - $iteration_count_log2 = 8; - } - - $output = '$H$'; - $output .= $itoa64[min($iteration_count_log2 + 5, 30)]; - $output .= _hash_encode64($input, 6, $itoa64); - - return $output; -} - -/** -* Encode hash -*/ -function _hash_encode64($input, $count, &$itoa64) -{ - $output = ''; - $i = 0; - - do - { - $value = ord($input[$i++]); - $output .= $itoa64[$value & 0x3f]; - - if ($i < $count) - { - $value |= ord($input[$i]) << 8; - } - - $output .= $itoa64[($value >> 6) & 0x3f]; - - if ($i++ >= $count) - { - break; - } - - if ($i < $count) - { - $value |= ord($input[$i]) << 16; - } - - $output .= $itoa64[($value >> 12) & 0x3f]; - - if ($i++ >= $count) - { - break; - } - - $output .= $itoa64[($value >> 18) & 0x3f]; - } - while ($i < $count); - - return $output; -} - -/** -* The crypt function/replacement -*/ -function _hash_crypt_private($password, $setting, &$itoa64) -{ - $output = '*'; - - // Check for correct hash - if (substr($setting, 0, 3) != '$H$' && substr($setting, 0, 3) != '$P$') - { - return $output; - } - - $count_log2 = strpos($itoa64, $setting[3]); - - if ($count_log2 < 7 || $count_log2 > 30) - { - return $output; - } - - $count = 1 << $count_log2; - $salt = substr($setting, 4, 8); - - if (strlen($salt) != 8) - { - return $output; - } - - /** - * We're kind of forced to use MD5 here since it's the only - * cryptographic primitive available in all versions of PHP - * currently in use. To implement our own low-level crypto - * in PHP would result in much worse performance and - * consequently in lower iteration counts and hashes that are - * quicker to crack (by non-PHP code). - */ - $hash = md5($salt . $password, true); - do - { - $hash = md5($hash . $password, true); - } - while (--$count); - - $output = substr($setting, 0, 12); - $output .= _hash_encode64($hash, 16, $itoa64); - - return $output; -} - -/** * Hashes an email address to a big integer * * @param string $email Email address @@ -1051,46 +850,6 @@ else } } -/** -* Eliminates useless . and .. components from specified path. -* -* Deprecated, use filesystem class instead -* -* @param string $path Path to clean -* @return string Cleaned path -* -* @deprecated -*/ -function phpbb_clean_path($path) -{ - global $phpbb_path_helper, $phpbb_container; - - if (!$phpbb_path_helper && $phpbb_container) - { - $phpbb_path_helper = $phpbb_container->get('path_helper'); - } - else if (!$phpbb_path_helper) - { - // The container is not yet loaded, use a new instance - if (!class_exists('\phpbb\path_helper')) - { - global $phpbb_root_path, $phpEx; - require($phpbb_root_path . 'phpbb/path_helper.' . $phpEx); - } - - $phpbb_path_helper = new phpbb\path_helper( - new phpbb\symfony_request( - new phpbb\request\request() - ), - new phpbb\filesystem(), - $phpbb_root_path, - $phpEx - ); - } - - return $phpbb_path_helper->clean_path($path); -} - // functions used for building option fields /** @@ -1246,24 +1005,6 @@ function phpbb_get_timezone_identifiers($selected_timezone) } /** -* Pick a timezone -* -* @param string $default A timezone to select -* @param boolean $truncate Shall we truncate the options text -* -* @return string Returns the options for timezone selector only -* -* @deprecated -*/ -function tz_select($default = '', $truncate = false) -{ - global $user; - - $timezone_select = phpbb_timezone_select($user, $default, $truncate); - return $timezone_select['tz_select']; -} - -/** * Options to pick a timezone and date/time * * @param \phpbb\user $user Object of the current user @@ -1318,18 +1059,12 @@ function phpbb_timezone_select($user, $default = '', $truncate = false) $tz_dates .= '<option value="' . $timezone['offest'] . ' - ' . $timezone['current'] . '"' . $selected . '>' . $timezone['offest'] . ' - ' . $timezone['current'] . '</option>'; } - if (isset($user->lang['timezones'][$timezone['tz']])) + $label = $timezone['tz']; + if (isset($user->lang['timezones'][$label])) { - $title = $label = $user->lang['timezones'][$timezone['tz']]; - } - else - { - // No label, we'll figure one out - $bits = explode('/', str_replace('_', ' ', $timezone['tz'])); - - $label = implode(' - ', $bits); - $title = $timezone['offest'] . ' - ' . $label; + $label = $user->lang['timezones'][$label]; } + $title = $timezone['offest'] . ' - ' . $label; if ($truncate) { @@ -1478,7 +1213,6 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ $sql = 'SELECT forum_id FROM ' . FORUMS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']} - AND mark_time < $post_time AND " . $db->sql_in_set('forum_id', $forum_id); $result = $db->sql_query($sql); @@ -2212,225 +1946,6 @@ function tracking_unserialize($string, $max_depth = 3) return $level; } -// Pagination functions -/** -* Generate a pagination link based on the url and the page information -* -* @param string $base_url is url prepended to all links generated within the function -* If you use page numbers inside your controller route, base_url should contains a placeholder (%d) -* for the page. Also be sure to specify the pagination path information into the start_name argument -* @param string $on_page is the page for which we want to generate the link -* @param string $start_name is the name of the parameter containing the first item of the given page (example: start=20) -* If you use page numbers inside your controller route, start name should be the string -* that should be removed for the first page (example: /page/%d) -* @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce -* @return URL for the requested page -*/ -function phpbb_generate_page_link($base_url, $on_page, $start_name, $per_page) -{ - - if (strpos($start_name, '%d') !== false) - { - return ($on_page > 1) ? sprintf($base_url, (int) $on_page) : str_replace($start_name, '', $base_url); - } - else - { - $url_delim = (strpos($base_url, '?') === false) ? '?' : ((strpos($base_url, '?') === strlen($base_url) - 1) ? '' : '&'); - return ($on_page > 1) ? $base_url . $url_delim . $start_name . '=' . (($on_page - 1) * $per_page) : $base_url; - } -} - -/** -* Generate template rendered pagination -* Allows full control of rendering of pagination with the template -* -* @param object $template the template object -* @param string $base_url is url prepended to all links generated within the function -* If you use page numbers inside your controller route, base_url should contains a placeholder (%d) -* for the page. Also be sure to specify the pagination path information into the start_name argument -* @param string $block_var_name is the name assigned to the pagination data block within the template (example: <!-- BEGIN pagination -->) -* @param string $start_name is the name of the parameter containing the first item of the given page (example: start=20) -* If you use page numbers inside your controller route, start name should be the string -* that should be removed for the first page (example: /page/%d) -* @param int $num_items the total number of items, posts, etc., used to determine the number of pages to produce -* @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce -* @param int $start_item the item which should be considered currently active, used to determine the page we're on -* @param bool $reverse_count determines whether we weight display of the list towards the start (false) or end (true) of the list -* @param bool $ignore_on_page decides whether we enable an active (unlinked) item, used primarily for embedded lists -* @return null -*/ -function phpbb_generate_template_pagination($template, $base_url, $block_var_name, $start_name, $num_items, $per_page, $start_item = 1, $reverse_count = false, $ignore_on_page = false) -{ - // Make sure $per_page is a valid value - $per_page = ($per_page <= 0) ? 1 : $per_page; - $total_pages = ceil($num_items / $per_page); - - if ($total_pages == 1 || !$num_items) - { - return; - } - - $on_page = floor($start_item / $per_page) + 1; - - if ($reverse_count) - { - $start_page = ($total_pages > 5) ? $total_pages - 4 : 1; - $end_page = $total_pages; - } - else - { - // What we're doing here is calculating what the "start" and "end" pages should be. We - // do this by assuming pagination is "centered" around the currently active page with - // the three previous and three next page links displayed. Anything more than that and - // we display the ellipsis, likewise anything less. - // - // $start_page is the page at which we start creating the list. When we have five or less - // pages we start at page 1 since there will be no ellipsis displayed. Anymore than that - // and we calculate the start based on the active page. This is the min/max calculation. - // First (max) would we end up starting on a page less than 1? Next (min) would we end - // up starting so close to the end that we'd not display our minimum number of pages. - // - // $end_page is the last page in the list to display. Like $start_page we use a min/max to - // determine this number. Again at most five pages? Then just display them all. More than - // five and we first (min) determine whether we'd end up listing more pages than exist. - // We then (max) ensure we're displaying the minimum number of pages. - $start_page = ($total_pages > 5) ? min(max(1, $on_page - 3), $total_pages - 4) : 1; - $end_page = ($total_pages > 5) ? max(min($total_pages, $on_page + 3), 5) : $total_pages; - } - - $u_previous_page = $u_next_page = ''; - if ($on_page != 1) - { - $u_previous_page = phpbb_generate_page_link($base_url, $on_page - 1, $start_name, $per_page); - - $template->assign_block_vars($block_var_name, array( - 'PAGE_NUMBER' => '', - 'PAGE_URL' => $u_previous_page, - 'S_IS_CURRENT' => false, - 'S_IS_PREV' => true, - 'S_IS_NEXT' => false, - 'S_IS_ELLIPSIS' => false, - )); - } - - // This do...while exists purely to negate the need for start and end assign_block_vars, i.e. - // to display the first and last page in the list plus any ellipsis. We use this loop to jump - // around a little within the list depending on where we're starting (and ending). - $at_page = 1; - do - { - // We decide whether to display the ellipsis during the loop. The ellipsis is always - // displayed as either the second or penultimate item in the list. So are we at either - // of those points and of course do we even need to display it, i.e. is the list starting - // on at least page 3 and ending three pages before the final item. - $template->assign_block_vars($block_var_name, array( - 'PAGE_NUMBER' => $at_page, - 'PAGE_URL' => phpbb_generate_page_link($base_url, $at_page, $start_name, $per_page), - 'S_IS_CURRENT' => (!$ignore_on_page && $at_page == $on_page), - 'S_IS_NEXT' => false, - 'S_IS_PREV' => false, - 'S_IS_ELLIPSIS' => ($at_page == 2 && $start_page > 2) || ($at_page == $total_pages - 1 && $end_page < $total_pages - 1), - )); - - // We may need to jump around in the list depending on whether we have or need to display - // the ellipsis. Are we on page 2 and are we more than one page away from the start - // of the list? Yes? Then we jump to the start of the list. Likewise are we at the end of - // the list and are there more than two pages left in total? Yes? Then jump to the penultimate - // page (so we can display the ellipsis next pass). Else, increment the counter and keep - // going - if ($at_page == 2 && $at_page < $start_page - 1) - { - $at_page = $start_page; - } - else if ($at_page == $end_page && $end_page < $total_pages - 1) - { - $at_page = $total_pages - 1; - } - else - { - $at_page++; - } - } - while ($at_page <= $total_pages); - - if ($on_page != $total_pages) - { - $u_next_page = phpbb_generate_page_link($base_url, $on_page + 1, $start_name, $per_page); - - $template->assign_block_vars($block_var_name, array( - 'PAGE_NUMBER' => '', - 'PAGE_URL' => $u_next_page, - 'S_IS_CURRENT' => false, - 'S_IS_PREV' => false, - 'S_IS_NEXT' => true, - 'S_IS_ELLIPSIS' => false, - )); - } - - // If the block_var_name is a nested block, we will use the last (most - // inner) block as a prefix for the template variables. If the last block - // name is pagination, the prefix is empty. If the rest of the - // block_var_name is not empty, we will modify the last row of that block - // and add our pagination items. - $tpl_block_name = $tpl_prefix = ''; - if (strrpos($block_var_name, '.') !== false) - { - $tpl_block_name = substr($block_var_name, 0, strrpos($block_var_name, '.')); - $tpl_prefix = strtoupper(substr($block_var_name, strrpos($block_var_name, '.') + 1)); - } - else - { - $tpl_prefix = strtoupper($block_var_name); - } - $tpl_prefix = ($tpl_prefix == 'PAGINATION') ? '' : $tpl_prefix . '_'; - - $template_array = array( - $tpl_prefix . 'BASE_URL' => $base_url, - $tpl_prefix . 'PER_PAGE' => $per_page, - 'U_' . $tpl_prefix . 'PREVIOUS_PAGE' => ($on_page != 1) ? $u_previous_page : '', - 'U_' . $tpl_prefix . 'NEXT_PAGE' => ($on_page != $total_pages) ? $u_next_page : '', - $tpl_prefix . 'TOTAL_PAGES' => $total_pages, - $tpl_prefix . 'CURRENT_PAGE' => $on_page, - ); - - if ($tpl_block_name) - { - $template->alter_block_array($tpl_block_name, $template_array, true, 'change'); - } - else - { - $template->assign_vars($template_array); - } -} - -/** -* Return current page -* This function also sets certain specific template variables -* -* @param object $template the template object -* @param object $user the user object -* @param string $base_url the base url used to call this page, used by Javascript for popup jump to page -* @param int $num_items the total number of items, posts, topics, etc. -* @param int $per_page the number of items, posts, etc. per page -* @param int $start the item which should be considered currently active, used to determine the page we're on -* @return null -*/ -function phpbb_on_page($template, $user, $base_url, $num_items, $per_page, $start) -{ - // Make sure $per_page is a valid value - $per_page = ($per_page <= 0) ? 1 : $per_page; - - $on_page = floor($start / $per_page) + 1; - - $template->assign_vars(array( - 'PER_PAGE' => $per_page, - 'ON_PAGE' => $on_page, - 'BASE_URL' => $base_url, - )); - - return sprintf($user->lang['PAGE_OF'], $on_page, max(ceil($num_items / $per_page), 1)); -} - // Server functions (building urls, redirecting...) /** @@ -2489,7 +2004,7 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false) * the global one (false) * @var bool|string append_sid_overwrite Overwrite function (string * URL) or not (false) - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('url', 'params', 'is_amp', 'session_id', 'append_sid_overwrite'); extract($phpbb_dispatcher->trigger_event('core.append_sid', compact($vars))); @@ -2660,7 +2175,7 @@ function generate_board_url($without_script_path = false) */ function redirect($url, $return = false, $disable_cd_check = false) { - global $db, $cache, $config, $user, $phpbb_root_path; + global $db, $cache, $config, $user, $phpbb_root_path, $phpbb_filesystem, $phpbb_path_helper, $phpEx; $failover_flag = false; @@ -2703,78 +2218,34 @@ function redirect($url, $return = false, $disable_cd_check = false) // Relative uri $pathinfo = pathinfo($url); - if (!$disable_cd_check && !file_exists($pathinfo['dirname'] . '/')) + // Is the uri pointing to the current directory? + if ($pathinfo['dirname'] == '.') { - $url = str_replace('../', '', $url); - $pathinfo = pathinfo($url); + $url = str_replace('./', '', $url); - if (!file_exists($pathinfo['dirname'] . '/')) + // Strip / from the beginning + if ($url && substr($url, 0, 1) == '/') { - // fallback to "last known user page" - // at least this way we know the user does not leave the phpBB root - $url = generate_board_url() . '/' . $user->page['page']; - $failover_flag = true; + $url = substr($url, 1); } } - if (!$failover_flag) - { - // Is the uri pointing to the current directory? - if ($pathinfo['dirname'] == '.') - { - $url = str_replace('./', '', $url); - - // Strip / from the beginning - if ($url && substr($url, 0, 1) == '/') - { - $url = substr($url, 1); - } + $url = $phpbb_path_helper->remove_web_root_path($url); - if ($user->page['page_dir']) - { - $url = generate_board_url() . '/' . $user->page['page_dir'] . '/' . $url; - } - else - { - $url = generate_board_url() . '/' . $url; - } - } - else - { - // Used ./ before, but $phpbb_root_path is working better with urls within another root path - $root_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($phpbb_root_path))); - $page_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($pathinfo['dirname']))); - $intersection = array_intersect_assoc($root_dirs, $page_dirs); - - $root_dirs = array_diff_assoc($root_dirs, $intersection); - $page_dirs = array_diff_assoc($page_dirs, $intersection); - - $dir = str_repeat('../', sizeof($root_dirs)) . implode('/', $page_dirs); - - // Strip / from the end - if ($dir && substr($dir, -1, 1) == '/') - { - $dir = substr($dir, 0, -1); - } - - // Strip / from the beginning - if ($dir && substr($dir, 0, 1) == '/') - { - $dir = substr($dir, 1); - } + if ($user->page['page_dir']) + { + $url = $user->page['page_dir'] . '/' . $url; + } - $url = str_replace($pathinfo['dirname'] . '/', '', $url); + $url = generate_board_url() . '/' . $url; + } - // Strip / from the beginning - if (substr($url, 0, 1) == '/') - { - $url = substr($url, 1); - } + // Clean URL and check if we go outside the forum directory + $url = $phpbb_path_helper->clean_url($url); - $url = (!empty($dir) ? $dir . '/' : '') . $url; - $url = generate_board_url() . '/' . $url; - } - } + if (!$disable_cd_check && strpos($url, generate_board_url(true)) === false) + { + trigger_error('INSECURE_REDIRECT', E_USER_ERROR); } // Make sure no linebreaks are there... to prevent http response splitting for PHP < 4.4.2 @@ -2855,7 +2326,7 @@ function reapply_sid($url) */ function build_url($strip_vars = false) { - global $user, $phpbb_root_path; + global $config, $user, $phpEx, $phpbb_root_path; $page = $user->page['page']; @@ -2866,8 +2337,14 @@ function build_url($strip_vars = false) $url_parts = parse_url($page); // URL - if ($url_parts !== false && !empty($url_parts['scheme']) && !empty($url_parts['host'])) + if ($url_parts === false || empty($url_parts['scheme']) || empty($url_parts['host'])) { + // Remove 'app.php/' from the page, when rewrite is enabled + if ($config['enable_mod_rewrite'] && strpos($page, 'app.' . $phpEx . '/') === 0) + { + $page = substr($page, strlen('app.' . $phpEx . '/')); + } + $page = $phpbb_root_path . $page; } @@ -2942,19 +2419,19 @@ function meta_refresh($time, $url, $disable_cd_check = false) { global $template, $refresh_data, $request; + $url = redirect($url, true, $disable_cd_check); if ($request->is_ajax()) { $refresh_data = array( 'time' => $time, - 'url' => str_replace('&', '&', $url) + 'url' => $url, ); } else { - $url = redirect($url, true, $disable_cd_check); + // For XHTML compatibility we change back & to & $url = str_replace('&', '&', $url); - // For XHTML compatibility we change back & to & $template->assign_vars(array( 'META' => '<meta http-equiv="refresh" content="' . $time . '; url=' . $url . '" />') ); @@ -3184,7 +2661,7 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo } else { - page_header(((!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title]), false); + page_header((!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title]); } $template->set_filenames(array( @@ -3217,7 +2694,6 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo WHERE user_id = " . $user->data['user_id']; $db->sql_query($sql); - if ($request->is_ajax()) { $u_action .= '&confirm_uid=' . $user->data['user_id'] . '&sess=' . $user->session_id . '&sid=' . $user->session_id; @@ -3461,7 +2937,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa 'PASSWORD_CREDENTIAL' => ($admin) ? 'password_' . $credential : 'password', )); - page_header($user->lang['LOGIN'], false); + page_header($user->lang['LOGIN']); $template->set_filenames(array( 'body' => 'login_body.html') @@ -3476,9 +2952,9 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa */ function login_forum_box($forum_data) { - global $db, $config, $user, $template, $phpEx; + global $db, $phpbb_container, $request, $template, $user; - $password = request_var('password', '', true); + $password = $request->variable('password', '', true); $sql = 'SELECT forum_id FROM ' . FORUMS_ACCESS_TABLE . ' @@ -3519,7 +2995,9 @@ function login_forum_box($forum_data) } $db->sql_freeresult($result); - if (phpbb_check_hash($password, $forum_data['forum_password'])) + $passwords_manager = $phpbb_container->get('passwords.manager'); + + if ($passwords_manager->check($password, $forum_data['forum_password'])) { $sql_ary = array( 'forum_id' => (int) $forum_data['forum_id'], @@ -3535,7 +3013,7 @@ function login_forum_box($forum_data) $template->assign_var('LOGIN_ERROR', $user->lang['WRONG_PASSWORD']); } - page_header($user->lang['LOGIN'], false); + page_header($user->lang['LOGIN']); $template->assign_vars(array( 'FORUM_NAME' => isset($forum_data['forum_name']) ? $forum_data['forum_name'] : '', @@ -3626,7 +3104,7 @@ function parse_cfg_file($filename, $lines = false) } // Determine first occurrence, since in values the equal sign is allowed - $key = strtolower(trim(substr($line, 0, $delim_pos))); + $key = htmlspecialchars(strtolower(trim(substr($line, 0, $delim_pos)))); $value = trim(substr($line, $delim_pos + 1)); if (in_array($value, array('off', 'false', '0'))) @@ -3643,7 +3121,11 @@ function parse_cfg_file($filename, $lines = false) } else if (($value[0] == "'" && $value[sizeof($value) - 1] == "'") || ($value[0] == '"' && $value[sizeof($value) - 1] == '"')) { - $value = substr($value, 1, sizeof($value)-2); + $value = htmlspecialchars(substr($value, 1, sizeof($value)-2)); + } + else + { + $value = htmlspecialchars($value); } $parsed_items[$key] = $value; @@ -4348,6 +3830,16 @@ function msg_handler($errno, $msg_text, $errfile, $errline) if (defined('IN_INSTALL') || defined('DEBUG') || isset($auth) && $auth->acl_get('a_')) { $msg_text = $log_text; + + // If this is defined there already was some output + // So let's not break it + if (defined('IN_DB_UPDATE')) + { + echo '<div class="errorbox">' . $msg_text . '</div>'; + + $db->sql_return_on_error(true); + phpbb_end_update($cache, $config); + } } if ((defined('IN_CRON') || defined('IMAGE_OUTPUT')) && isset($db)) @@ -4444,7 +3936,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline) } else { - page_header($msg_title, false); + page_header($msg_title); } } @@ -5119,12 +4611,98 @@ function phpbb_build_hidden_fields_for_query_params($request, $exclude = null) } /** +* Get user avatar +* +* @param array $user_row Row from the users table +* @param string $alt Optional language string for alt tag within image, can be a language key or text +* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP +* +* @return string Avatar html +*/ +function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config = false) +{ + $row = \phpbb\avatar\manager::clean_row($user_row, 'user'); + return phpbb_get_avatar($row, $alt, $ignore_config); +} + +/** +* Get group avatar +* +* @param array $group_row Row from the groups table +* @param string $alt Optional language string for alt tag within image, can be a language key or text +* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP +* +* @return string Avatar html +*/ +function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config = false) +{ + $row = \phpbb\avatar\manager::clean_row($user_row, 'group'); + return phpbb_get_avatar($row, $alt, $ignore_config); +} + +/** +* Get avatar +* +* @param array $row Row cleaned by \phpbb\avatar\driver\driver::clean_row +* @param string $alt Optional language string for alt tag within image, can be a language key or text +* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP +* +* @return string Avatar html +*/ +function phpbb_get_avatar($row, $alt, $ignore_config = false) +{ + global $user, $config, $cache, $phpbb_root_path, $phpEx; + global $request; + global $phpbb_container; + + if (!$config['allow_avatar'] && !$ignore_config) + { + return ''; + } + + $avatar_data = array( + 'src' => $row['avatar'], + 'width' => $row['avatar_width'], + 'height' => $row['avatar_height'], + ); + + $phpbb_avatar_manager = $phpbb_container->get('avatar.manager'); + $driver = $phpbb_avatar_manager->get_driver($row['avatar_type'], $ignore_config); + $html = ''; + + if ($driver) + { + $html = $driver->get_custom_html($user, $row, $alt); + if (!empty($html)) + { + return $html; + } + + $avatar_data = $driver->get_data($row, $ignore_config); + } + else + { + $avatar_data['src'] = ''; + } + + if (!empty($avatar_data['src'])) + { + $html = '<img src="' . $avatar_data['src'] . '" ' . + ($avatar_data['width'] ? ('width="' . $avatar_data['width'] . '" ') : '') . + ($avatar_data['height'] ? ('height="' . $avatar_data['height'] . '" ') : '') . + 'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />'; + } + + return $html; +} + +/** * Generate page header */ -function page_header($page_title = '', $display_online_list = true, $item_id = 0, $item = 'forum') +function page_header($page_title = '', $display_online_list = false, $item_id = 0, $item = 'forum') { global $db, $config, $template, $SID, $_SID, $_EXTRA_URL, $user, $auth, $phpEx, $phpbb_root_path; - global $phpbb_dispatcher, $request, $phpbb_container, $adm_relative_path; + global $phpbb_dispatcher, $request, $phpbb_container, $phpbb_admin_path; if (defined('HEADER_INC')) { @@ -5148,7 +4726,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 * @var int item_id Restrict online users to item id * @var bool page_header_override Shall we return instead of running * the rest of page_header() - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('page_title', 'display_online_list', 'item_id', 'item', 'page_header_override'); extract($phpbb_dispatcher->trigger_event('core.page_header', compact($vars))); @@ -5185,7 +4763,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 if ($user->data['user_id'] != ANONYMOUS) { $u_login_logout = append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=logout', true, $user->session_id); - $l_login_logout = sprintf($user->lang['LOGOUT_USER'], $user->data['username']); + $l_login_logout = $user->lang['LOGOUT']; } else { @@ -5225,16 +4803,13 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 $l_online_time = $user->lang('VIEW_ONLINE_TIMES', (int) $config['load_online_time']); } - $l_privmsgs_text = $l_privmsgs_text_unread = ''; $s_privmsg_new = false; - // Obtain number of new private messages if user is logged in + // Check for new private messages if user is logged in if (!empty($user->data['is_registered'])) { if ($user->data['user_new_privmsg']) { - $l_privmsgs_text = $user->lang('NEW_PMS', (int) $user->data['user_new_privmsg']); - if (!$user->data['user_last_privmsg'] || $user->data['user_last_privmsg'] > $user->data['session_last_visit']) { $sql = 'UPDATE ' . USERS_TABLE . ' @@ -5251,16 +4826,8 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 } else { - $l_privmsgs_text = $user->lang('NEW_PMS', 0); $s_privmsg_new = false; } - - $l_privmsgs_text_unread = ''; - - if ($user->data['user_unread_privmsg'] && $user->data['user_unread_privmsg'] != $user->data['user_new_privmsg']) - { - $l_privmsgs_text_unread = $user->lang('UNREAD_PMS', (int) $user->data['user_unread_privmsg']); - } } $forum_id = request_var('f', 0); @@ -5336,10 +4903,11 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 } $hidden_fields_for_jumpbox = phpbb_build_hidden_fields_for_query_params($request, array('f')); - + $notification_mark_hash = generate_link_hash('mark_all_notifications_read'); // The following assigns all _common_ variables that may be used at any point in a template. $template->assign_vars(array( + 'CURRENT_USER_AVATAR' => phpbb_get_user_avatar($user->data), 'SITENAME' => $config['sitename'], 'SITE_DESCRIPTION' => $config['site_desc'], 'PAGE_TITLE' => $page_title, @@ -5350,13 +4918,13 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'TOTAL_USERS_ONLINE' => $l_online_users, 'LOGGED_IN_USER_LIST' => $online_userlist, 'RECORD_USERS' => $l_online_record, - 'PRIVATE_MESSAGE_INFO' => $l_privmsgs_text, - 'PRIVATE_MESSAGE_INFO_UNREAD' => $l_privmsgs_text_unread, + 'PRIVATE_MESSAGE_COUNT' => (!empty($user->data['user_unread_privmsg'])) ? $user->data['user_unread_privmsg'] : 0, 'HIDDEN_FIELDS_FOR_JUMPBOX' => $hidden_fields_for_jumpbox, 'UNREAD_NOTIFICATIONS_COUNT' => ($notifications !== false) ? $notifications['unread_count'] : '', - 'NOTIFICATIONS_COUNT' => ($notifications !== false) ? $user->lang('NOTIFICATIONS_COUNT', $notifications['unread_count']) : '', + 'NOTIFICATIONS_COUNT' => ($notifications !== false) ? $notifications['unread_count'] : '', 'U_VIEW_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications'), + 'U_MARK_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications&mode=notification_list&mark=all&token=' . $notification_mark_hash), 'U_NOTIFICATION_SETTINGS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications&mode=notification_options'), 'S_NOTIFICATIONS_DISPLAY' => $config['load_notifications'], @@ -5369,6 +4937,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'SESSION_ID' => $user->session_id, 'ROOT_PATH' => $web_path, 'BOARD_URL' => $board_url, + 'USERNAME_FULL' => get_username_string('full', $user->data['user_id'], $user->data['username'], $user->data['user_colour']), 'L_LOGIN_LOGOUT' => $l_login_logout, 'L_INDEX' => ($config['board_index_text'] !== '') ? $config['board_index_text'] : $user->lang['FORUM_INDEX'], @@ -5377,7 +4946,6 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'U_PRIVATEMSGS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox'), 'U_RETURN_INBOX' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox'), - 'U_POPUP_PM' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=popup'), 'U_MEMBERLIST' => append_sid("{$phpbb_root_path}memberlist.$phpEx"), 'U_VIEWONLINE' => ($auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel')) ? append_sid("{$phpbb_root_path}viewonline.$phpEx") : '', 'U_LOGIN_LOGOUT' => $u_login_logout, @@ -5386,6 +4954,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'U_SITE_HOME' => $config['site_home_url'], 'U_REGISTER' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'), 'U_PROFILE' => append_sid("{$phpbb_root_path}ucp.$phpEx"), + 'U_USER_PROFILE' => get_username_string('profile', $user->data['user_id'], $user->data['username'], $user->data['user_colour']), 'U_MODCP' => append_sid("{$phpbb_root_path}mcp.$phpEx", false, true, $user->session_id), 'U_FAQ' => append_sid("{$phpbb_root_path}faq.$phpEx"), 'U_SEARCH_SELF' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=egosearch'), @@ -5394,7 +4963,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'U_SEARCH_UNREAD' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=unreadposts'), 'U_SEARCH_ACTIVE_TOPICS'=> append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=active_topics'), 'U_DELETE_COOKIES' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=delete_cookies'), - 'U_TEAM' => ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile')) ? '' : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=leaders'), + 'U_TEAM' => ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile')) ? '' : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=team'), 'U_TERMS_USE' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=terms'), 'U_PRIVACY' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=privacy'), 'U_RESTORE_PERMISSIONS' => ($user->data['user_perm_from'] && $auth->acl_get('a_switchperm')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=restore_perm') : '', @@ -5405,7 +4974,6 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'S_BOARD_DISABLED' => ($config['board_disable']) ? true : false, 'S_REGISTERED_USER' => (!empty($user->data['is_registered'])) ? true : false, 'S_IS_BOT' => (!empty($user->data['is_bot'])) ? true : false, - 'S_USER_PM_POPUP' => $user->optionget('popuppm'), 'S_USER_LANG' => $user_lang, 'S_USER_BROWSER' => (isset($user->data['session_browser'])) ? $user->data['session_browser'] : $user->lang['UNKNOWN_BROWSER'], 'S_USERNAME' => $user->data['username'], @@ -5423,8 +4991,8 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'S_FORUM_ID' => $forum_id, 'S_TOPIC_ID' => $topic_id, - 'S_LOGIN_ACTION' => ((!defined('ADMIN_START')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') : append_sid("{$phpbb_root_path}{$adm_relative_path}index.$phpEx", false, true, $user->session_id)), - 'S_LOGIN_REDIRECT' => build_hidden_fields(array('redirect' => build_url())), + 'S_LOGIN_ACTION' => ((!defined('ADMIN_START')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') : append_sid("{$phpbb_admin_path}index.$phpEx", false, true, $user->session_id)), + 'S_LOGIN_REDIRECT' => build_hidden_fields(array('redirect' => $phpbb_path_helper->remove_web_root_path(build_url()))), 'S_ENABLE_FEEDS' => ($config['feed_enable']) ? true : false, 'S_ENABLE_FEEDS_OVERALL' => ($config['feed_overall']) ? true : false, @@ -5451,8 +5019,8 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/", 'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/stylesheet.css?assets_version=' . $config['assets_version'], 'T_STYLESHEET_LANG_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'], - 'T_JQUERY_LINK' => ($config['load_jquery_cdn'] && !empty($config['load_jquery_url'])) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.js?assets_version=" . $config['assets_version'], - 'S_JQUERY_FALLBACK' => ($config['load_jquery_cdn']) ? true : false, + 'T_JQUERY_LINK' => !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.js?assets_version=" . $config['assets_version'], + 'S_ALLOW_CDN' => !empty($config['allow_cdn']), 'T_THEME_NAME' => rawurlencode($user->style['style_path']), 'T_THEME_LANG_NAME' => $user->data['user_lang'], @@ -5469,6 +5037,22 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'SITE_LOGO_IMG' => $user->img('site_logo'), )); + /** + * Execute code and/or overwrite _common_ template variables after they have been assigned. + * + * @event core.page_header_after + * @var string page_title Page title + * @var bool display_online_list Do we display online users list + * @var string item Restrict online users to a certain + * session item, e.g. forum for + * session_forum_id + * @var int item_id Restrict online users to item id + * + * @since 3.1.0-b3 + */ + $vars = array('page_title', 'display_online_list', 'item_id', 'item'); + extract($phpbb_dispatcher->trigger_event('core.page_header_after', compact($vars))); + // application/xhtml+xml not used because of IE header('Content-type: text/html; charset=UTF-8'); @@ -5507,7 +5091,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler = * @var bool run_cron Shall we run cron tasks * @var bool page_footer_override Shall we return instead of running * the rest of page_footer() - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('run_cron', 'page_footer_override'); extract($phpbb_dispatcher->trigger_event('core.page_footer', compact($vars))); @@ -5609,14 +5193,14 @@ function garbage_collection() global $cache, $db; global $phpbb_dispatcher; - /** - * Unload some objects, to free some memory, before we finish our task - * - * @event core.garbage_collection - * @since 3.1-A1 - */ if (!empty($phpbb_dispatcher)) { + /** + * Unload some objects, to free some memory, before we finish our task + * + * @event core.garbage_collection + * @since 3.1.0-a1 + */ $phpbb_dispatcher->dispatch('core.garbage_collection'); } diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php index 60c44e90e1..2c66f6009c 100644 --- a/phpBB/includes/functions_acp.php +++ b/phpBB/includes/functions_acp.php @@ -41,7 +41,7 @@ function adm_page_header($page_title) * @var string page_title Page title * @var bool adm_page_header_override Shall we return instead of * running the rest of adm_page_header() - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('page_title', 'adm_page_header_override'); extract($phpbb_dispatcher->trigger_event('core.adm_page_header', compact($vars))); @@ -67,7 +67,8 @@ function adm_page_header($page_title) 'SID' => $SID, '_SID' => $_SID, 'SESSION_ID' => $user->session_id, - 'ROOT_PATH' => $phpbb_admin_path, + 'ROOT_PATH' => $phpbb_root_path, + 'ADMIN_ROOT_PATH' => $phpbb_admin_path, 'U_LOGOUT' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=logout'), 'U_ADM_LOGOUT' => append_sid("{$phpbb_admin_path}index.$phpEx", 'action=admlogout'), @@ -131,7 +132,7 @@ function adm_page_footer($copyright_html = true) * @var bool copyright_html Shall we display the copyright? * @var bool adm_page_footer_override Shall we return instead of * running the rest of adm_page_footer() - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('copyright_html', 'adm_page_footer_override'); extract($phpbb_dispatcher->trigger_event('core.adm_page_footer', compact($vars))); @@ -175,8 +176,8 @@ function adm_page_footer($copyright_html = true) 'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '', 'S_COPYRIGHT_HTML' => $copyright_html, 'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Group'), - 'T_JQUERY_LINK' => ($config['load_jquery_cdn'] && !empty($config['load_jquery_url'])) ? $config['load_jquery_url'] : "{$phpbb_root_path}assets/javascript/jquery.js", - 'S_JQUERY_FALLBACK' => ($config['load_jquery_cdn']) ? true : false, + 'T_JQUERY_LINK' => !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$phpbb_root_path}assets/javascript/jquery.js", + 'S_ALLOW_CDN' => !empty($config['allow_cdn']), 'VERSION' => $config['version']) ); @@ -362,7 +363,9 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars) if ($tpl_type[0] == 'select') { - $tpl = '<select id="' . $key . '" name="' . $name . '">' . $return . '</select>'; + $size = (isset($tpl_type[1])) ? (int) $tpl_type[1] : 1; + + $tpl = '<select id="' . $key . '" name="' . $name . '"' . (($size > 1) ? ' size="' . $size . '"' : '') . '>' . $return . '</select>'; } else { @@ -393,7 +396,7 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars) * @var string name Should be used for the name attribute * @var array vars Array with the options for the config * @var string tpl The resulting html code we display - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('tpl_type', 'key', 'new', 'name', 'vars', 'tpl'); extract($phpbb_dispatcher->trigger_event('core.build_config_template', compact($vars))); @@ -603,7 +606,7 @@ function validate_config_vars($config_vars, &$cfg_array, &$error) * @var array error Array of errors, the errors should * be strings only, language keys are * not replaced afterwards - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('cfg_array', 'config_name', 'config_definition', 'error'); extract($phpbb_dispatcher->trigger_event('core.validate_config_variable', compact($vars))); diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 722d3c9c67..50b3b61eaa 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -731,7 +731,38 @@ function delete_topics($where_type, $where_ids, $auto_sync = true, $post_count_s */ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = true, $post_count_sync = true, $call_delete_topics = true) { - global $db, $config, $phpbb_root_path, $phpEx, $auth, $user, $phpbb_container; + global $db, $config, $phpbb_root_path, $phpEx, $auth, $user, $phpbb_container, $phpbb_dispatcher; + + // Notifications types to delete + $delete_notifications_types = array( + 'quote', + 'approve_post', + 'post_in_queue', + ); + + /** + * Perform additional actions before post(s) deletion + * + * @event core.delete_posts_before + * @var string where_type Variable containing posts deletion mode + * @var mixed where_ids Array or comma separated list of posts ids to delete + * @var bool auto_sync Flag indicating if topics/forums should be synchronized + * @var bool posted_sync Flag indicating if topics_posted table should be resynchronized + * @var bool post_count_sync Flag indicating if posts count should be resynchronized + * @var bool call_delete_topics Flag indicating if topics having no posts should be deleted + * @var array delete_notifications_types Array with notifications types to delete + * @since 3.1.0-a4 + */ + $vars = array( + 'where_type', + 'where_ids', + 'auto_sync', + 'posted_sync', + 'post_count_sync', + 'call_delete_topics', + 'delete_notifications_types', + ); + extract($phpbb_dispatcher->trigger_event('core.delete_posts_before', compact($vars))); if ($where_type === 'range') { @@ -874,8 +905,56 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = delete_attachments('post', $post_ids, false); + /** + * Perform additional actions during post(s) deletion + * + * @event core.delete_posts_in_transaction + * @var array post_ids Array with deleted posts' ids + * @var array poster_ids Array with deleted posts' author ids + * @var array topic_ids Array with deleted posts' topic ids + * @var array forum_ids Array with deleted posts' forum ids + * @var string where_type Variable containing posts deletion mode + * @var mixed where_ids Array or comma separated list of posts ids to delete + * @var array delete_notifications_types Array with notifications types to delete + * @since 3.1.0-a4 + */ + $vars = array( + 'post_ids', + 'poster_ids', + 'topic_ids', + 'forum_ids', + 'where_type', + 'where_ids', + 'delete_notifications_types', + ); + extract($phpbb_dispatcher->trigger_event('core.delete_posts_in_transaction', compact($vars))); + $db->sql_transaction('commit'); + /** + * Perform additional actions after post(s) deletion + * + * @event core.delete_posts_after + * @var array post_ids Array with deleted posts' ids + * @var array poster_ids Array with deleted posts' author ids + * @var array topic_ids Array with deleted posts' topic ids + * @var array forum_ids Array with deleted posts' forum ids + * @var string where_type Variable containing posts deletion mode + * @var mixed where_ids Array or comma separated list of posts ids to delete + * @var array delete_notifications_types Array with notifications types to delete + * @since 3.1.0-a4 + */ + $vars = array( + 'post_ids', + 'poster_ids', + 'topic_ids', + 'forum_ids', + 'where_type', + 'where_ids', + 'delete_notifications_types', + ); + extract($phpbb_dispatcher->trigger_event('core.delete_posts_after', compact($vars))); + // Resync topics_posted table if ($posted_sync) { @@ -902,13 +981,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = $phpbb_notifications = $phpbb_container->get('notification_manager'); - $phpbb_notifications->delete_notifications(array( - 'quote', - 'bookmark', - 'post', - 'approve_post', - 'post_in_queue', - ), $post_ids); + $phpbb_notifications->delete_notifications($delete_notifications_types, $post_ids); return sizeof($post_ids); } @@ -1438,7 +1511,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, ITEM_DELETED => (!empty($topics_softdeleted)) ? ' WHERE ' . $db->sql_in_set('topic_id', $topics_softdeleted) : '', ); - foreach ($topic_visiblities as $visibility => $sql_where) + foreach ($update_ary as $visibility => $sql_where) { if ($sql_where) { @@ -1727,7 +1800,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, { $forum_data[$forum_id]['topics_approved'] = $row['total_topics']; } - else if ($row['topic_visibility'] == ITEM_UNAPPROVED) + else if ($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) { $forum_data[$forum_id]['topics_unapproved'] = $row['total_topics']; } @@ -1950,7 +2023,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, { $topic_data[$topic_id]['posts_approved'] = $row['total_posts']; } - else if ($row['post_visibility'] == ITEM_UNAPPROVED) + else if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) { $topic_data[$topic_id]['posts_unapproved'] = $row['total_posts']; } @@ -1972,7 +2045,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false, $topic_data[$topic_id]['first_post_id'] = (!empty($topic_data[$topic_id]['first_post_id'])) ? min($topic_data[$topic_id]['first_post_id'], $row['first_post_id']) : $row['first_post_id']; $topic_data[$topic_id]['last_post_id'] = max($topic_data[$topic_id]['last_post_id'], $row['last_post_id']); - if ($topic_data[$topic_id]['visibility'] == ITEM_UNAPPROVED) + if ($topic_data[$topic_id]['visibility'] == ITEM_UNAPPROVED || $topic_data[$topic_id]['visibility'] == ITEM_REAPPROVE) { // Soft delete status is stronger than unapproved. $topic_data[$topic_id]['visibility'] = $row['post_visibility']; @@ -2275,6 +2348,11 @@ function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync $sql_and .= " AND topic_last_view_time < $prune_date"; } + if ($prune_mode == 'shadow') + { + $sql_and .= ' AND topic_status = ' . ITEM_MOVED . " AND topic_last_post_time < $prune_date"; + } + $sql = 'SELECT topic_id FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_id) . " @@ -2348,7 +2426,7 @@ function auto_prune($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_fr * via admin_permissions. Changes of usernames and group names * must be carried through for the moderators table. * -* @param \phpbb\db\driver\driver $db Database connection +* @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\cache\driver\driver_interface Cache driver * @param \phpbb\auth\auth $auth Authentication object * @return null @@ -2525,20 +2603,6 @@ function phpbb_cache_moderators($db, $cache, $auth) } /** -* Cache moderators. Called whenever permissions are changed -* via admin_permissions. Changes of usernames and group names -* must be carried through for the moderators table. -* -* @deprecated 3.1 -* @return null -*/ -function cache_moderators() -{ - global $db, $cache, $auth; - return phpbb_cache_moderators($db, $cache, $auth); -} - -/** * View log * * @param string $mode The mode defines which log_type is used and from which log the entry is retrieved @@ -2571,7 +2635,7 @@ function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id /** * Removes moderators and administrators from foe lists. * -* @param \phpbb\db\driver\driver $db Database connection +* @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\auth\auth $auth Authentication object * @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore * @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore @@ -2688,20 +2752,6 @@ function phpbb_update_foes($db, $auth, $group_id = false, $user_id = false) } /** -* Removes moderators and administrators from foe lists. -* -* @deprecated 3.1 -* @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore -* @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore -* @return null -*/ -function update_foes($group_id = false, $user_id = false) -{ - global $db, $auth; - return phpbb_update_foes($db, $auth, $group_id, $user_id); -} - -/** * Lists inactive users */ function view_inactive_users(&$users, &$user_count, $limit = 0, $offset = 0, $limit_days = 0, $sort_by = 'user_inactive_time DESC') @@ -2869,8 +2919,24 @@ function get_database_size() case 'mssql': case 'mssql_odbc': case 'mssqlnative': + $sql = 'SELECT @@VERSION AS mssql_version'; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + $sql = 'SELECT ((SUM(size) * 8.0) * 1024.0) as dbsize FROM sysfiles'; + + if ($row) + { + // Azure stats are stored elsewhere + if (strpos($row['mssql_version'], 'SQL Azure') !== false) + { + $sql = 'SELECT ((SUM(reserved_page_count) * 8.0) * 1024.0) as dbsize + FROM sys.dm_db_partition_stats'; + } + } + $result = $db->sql_query($sql, 7200); $database_size = ($row = $db->sql_fetchrow($result)) ? $row['dbsize'] : false; $db->sql_freeresult($result); @@ -2990,7 +3056,7 @@ function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port return $file_info; } -/** +/* * Tidy Warnings * Remove all warnings which have now expired from the database * The duration of a warning can be defined by the administrator @@ -3100,45 +3166,6 @@ function add_permission_language() } /** - * Obtains the latest version information - * - * @param bool $force_update Ignores cached data. Defaults to false. - * @param bool $warn_fail Trigger a warning if obtaining the latest version information fails. Defaults to false. - * @param int $ttl Cache version information for $ttl seconds. Defaults to 86400 (24 hours). - * - * @return string | false Version info on success, false on failure. - */ -function obtain_latest_version_info($force_update = false, $warn_fail = false, $ttl = 86400) -{ - global $cache; - - $info = $cache->get('versioncheck'); - - if ($info === false || $force_update) - { - $errstr = ''; - $errno = 0; - - $info = get_remote_file('version.phpbb.com', '/phpbb', - ((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno); - - if (empty($info)) - { - $cache->destroy('versioncheck'); - if ($warn_fail) - { - trigger_error($errstr, E_USER_WARNING); - } - return false; - } - - $cache->put('versioncheck', $info, $ttl); - } - - return $info; -} - -/** * Enables a particular flag in a bitfield column of a given table. * * @param string $table_name The table to update diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php index 2197815087..c2db53f86c 100644 --- a/phpBB/includes/functions_compatibility.php +++ b/phpBB/includes/functions_compatibility.php @@ -39,12 +39,126 @@ function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $ 'avatar_height' => $avatar_height, ); - if (!function_exists('phpbb_get_avatar')) + return phpbb_get_avatar($row, $alt, $ignore_config); +} + +/** +* Hash the password +* +* @deprecated 3.1.0-a2 (To be removed: 3.3.0) +* +* @param string $password Password to be hashed +* +* @return string|bool Password hash or false if something went wrong during hashing +*/ +function phpbb_hash($password) +{ + global $phpbb_container; + + $passwords_manager = $phpbb_container->get('passwords.manager'); + return $passwords_manager->hash($password); +} + +/** +* Check for correct password +* +* @deprecated 3.1.0-a2 (To be removed: 3.3.0) +* +* @param string $password The password in plain text +* @param string $hash The stored password hash +* +* @return bool Returns true if the password is correct, false if not. +*/ +function phpbb_check_hash($password, $hash) +{ + global $phpbb_container; + + $passwords_manager = $phpbb_container->get('passwords.manager'); + return $passwords_manager->check($password, $hash); +} + +/** +* Eliminates useless . and .. components from specified path. +* +* Deprecated, use filesystem class instead +* +* @param string $path Path to clean +* @return string Cleaned path +* +* @deprecated +*/ +function phpbb_clean_path($path) +{ + global $phpbb_path_helper, $phpbb_container; + + if (!$phpbb_path_helper && $phpbb_container) + { + $phpbb_path_helper = $phpbb_container->get('path_helper'); + } + else if (!$phpbb_path_helper) { - global $phpbb_root_path, $phpEx; + // The container is not yet loaded, use a new instance + if (!class_exists('\phpbb\path_helper')) + { + global $phpbb_root_path, $phpEx; + require($phpbb_root_path . 'phpbb/path_helper.' . $phpEx); + } - include($phpbb_root_path . 'includes/functions_display.' . $phpEx); + $phpbb_path_helper = new phpbb\path_helper( + new phpbb\symfony_request( + new phpbb\request\request() + ), + new phpbb\filesystem(), + $phpbb_root_path, + $phpEx + ); } - return phpbb_get_avatar($row, $alt, $ignore_config); + return $phpbb_path_helper->clean_path($path); +} + +/** +* Pick a timezone +* +* @param string $default A timezone to select +* @param boolean $truncate Shall we truncate the options text +* +* @return string Returns the options for timezone selector only +* +* @deprecated +*/ +function tz_select($default = '', $truncate = false) +{ + global $user; + + $timezone_select = phpbb_timezone_select($user, $default, $truncate); + return $timezone_select['tz_select']; +} + +/** +* Cache moderators. Called whenever permissions are changed +* via admin_permissions. Changes of usernames and group names +* must be carried through for the moderators table. +* +* @deprecated 3.1 +* @return null +*/ +function cache_moderators() +{ + global $db, $cache, $auth; + return phpbb_cache_moderators($db, $cache, $auth); +} + +/** +* Removes moderators and administrators from foe lists. +* +* @deprecated 3.1 +* @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore +* @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore +* @return null +*/ +function update_foes($group_id = false, $user_id = false) +{ + global $db, $auth; + return phpbb_update_foes($db, $auth, $group_id, $user_id); } diff --git a/phpBB/includes/functions_compress.php b/phpBB/includes/functions_compress.php index c79a31930e..39a1b2ad21 100644 --- a/phpBB/includes/functions_compress.php +++ b/phpBB/includes/functions_compress.php @@ -46,7 +46,7 @@ class compress if (is_file($phpbb_root_path . $src)) { - $this->data($src_path, file_get_contents("$phpbb_root_path$src"), false, stat("$phpbb_root_path$src")); + $this->data($src_path, file_get_contents("$phpbb_root_path$src"), stat("$phpbb_root_path$src"), false); } else if (is_dir($phpbb_root_path . $src)) { @@ -86,7 +86,7 @@ class compress continue; } - $this->data("$src_path$path$file", file_get_contents("$phpbb_root_path$src$path$file"), false, stat("$phpbb_root_path$src$path$file")); + $this->data("$src_path$path$file", file_get_contents("$phpbb_root_path$src$path$file"), stat("$phpbb_root_path$src$path$file"), false); } } } @@ -109,7 +109,7 @@ class compress return false; } - $this->data($filename, file_get_contents($src), false, stat($src)); + $this->data($filename, file_get_contents($src), stat($src), false); return true; } @@ -123,7 +123,7 @@ class compress $stat[4] = $stat[5] = 0; $stat[7] = strlen($src); $stat[9] = time(); - $this->data($name, $src, false, $stat); + $this->data($name, $src, $stat, false); return true; } @@ -395,7 +395,7 @@ class compress_zip extends compress /** * Create the structures ... note we assume version made by is MSDOS */ - function data($name, $data, $is_dir = false, $stat) + function data($name, $data, $stat, $is_dir = false) { $name = str_replace('\\', '/', $name); $name = $this->unique_filename($name); @@ -669,7 +669,7 @@ class compress_tar extends compress /** * Create the structures */ - function data($name, $data, $is_dir = false, $stat) + function data($name, $data, $stat, $is_dir = false) { $name = $this->unique_filename($name); $this->wrote = true; diff --git a/phpBB/includes/functions_container.php b/phpBB/includes/functions_container.php index 667d27fd20..4a01c934bf 100644 --- a/phpBB/includes/functions_container.php +++ b/phpBB/includes/functions_container.php @@ -26,7 +26,7 @@ if (!defined('IN_PHPBB')) * Used to bootstrap the container. * * @param string $config_file -* @return \phpbb\db\driver\driver +* @return \phpbb\db\driver\driver_interface */ function phpbb_bootstrap_db_connection($config_file) { @@ -239,7 +239,7 @@ function phpbb_create_dumped_container($config_file, array $extensions, array $p */ function phpbb_create_dumped_container_unless_debug($config_file, array $extensions, array $passes, $phpbb_root_path, $php_ext) { - $container_factory = defined('DEBUG') ? 'phpbb_create_compiled_container' : 'phpbb_create_dumped_container'; + $container_factory = defined('DEBUG_CONTAINER') ? 'phpbb_create_compiled_container' : 'phpbb_create_dumped_container'; return $container_factory($config_file, $extensions, $passes, $phpbb_root_path, $php_ext); } diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index 863450a4b2..bb94967606 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -20,6 +20,7 @@ if (!defined('IN_PHPBB')) * make_jumpbox() * bump_topic_allowed() * get_context() +* phpbb_clean_search_string() * decode_message() * strip_bbcode() * generate_text_for_display() @@ -360,6 +361,23 @@ function get_context($text, $words, $length = 400) } /** +* Cleans a search string by removing single wildcards from it and replacing multiple spaces with a single one. +* +* @param string $search_string The full search string which should be cleaned. +* +* @return string The cleaned search string without any wildcards and multiple spaces. +*/ +function phpbb_clean_search_string($search_string) +{ + // This regular expressions matches every single wildcard. + // That means one after a whitespace or the beginning of the string or one before a whitespace or the end of the string. + $search_string = preg_replace('#(?<=^|\s)\*+(?=\s|$)#', '', $search_string); + $search_string = trim($search_string); + $search_string = preg_replace(array('#\s+#u', '#\*+#u'), array(' ', '*'), $search_string); + return $search_string; +} + +/** * Decode text whereby text is coming from the db and expected to be pre-parsed content * We are placing this outside of the message parser because we are often in need of it... */ @@ -427,13 +445,13 @@ function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text * @var string bitfield The BBCode Bitfield * @var int flags The BBCode Flags * @var bool censor_text Whether or not to apply word censors - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('text', 'uid', 'bitfield', 'flags', 'censor_text'); extract($phpbb_dispatcher->trigger_event('core.modify_text_for_display_before', compact($vars))); if ($censor_text) - { + { $text = censor_text($text); } @@ -469,7 +487,7 @@ function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text * @var string uid The BBCode UID * @var string bitfield The BBCode Bitfield * @var int flags The BBCode Flags - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('text', 'uid', 'bitfield', 'flags'); extract($phpbb_dispatcher->trigger_event('core.modify_text_for_display_after', compact($vars))); @@ -481,6 +499,16 @@ function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text * For parsing custom parsed text to be stored within the database. * This function additionally returns the uid and bitfield that needs to be stored. * Expects $text to be the value directly from request_var() and in it's non-parsed form +* +* @param string $text The text to be replaced with the parsed one +* @param string $uid The BBCode uid for this parse +* @param string $bitfield The BBCode bitfield for this parse +* @param int $flags The allow_bbcode, allow_urls and allow_smilies compiled into a single integer. +* @param bool $allow_bbcode If BBCode is allowed (i.e. if BBCode is parsed) +* @param bool $allow_urls If urls is allowed +* @param bool $allow_smilies If smilies are allowed +* +* @return array An array of string with the errors that occurred while parsing */ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bbcode = false, $allow_urls = false, $allow_smilies = false) { @@ -497,9 +525,17 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb * @var bool allow_bbcode Whether or not to parse BBCode * @var bool allow_urls Whether or not to parse URLs * @var bool allow_smilies Whether or not to parse Smilies - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('text', 'uid', 'bitfield', 'flags', 'allow_bbcode', 'allow_urls', 'allow_smilies'); + $vars = array( + 'text', + 'uid', + 'bitfield', + 'flags', + 'allow_bbcode', + 'allow_urls', + 'allow_smilies', + ); extract($phpbb_dispatcher->trigger_event('core.modify_text_for_storage_before', compact($vars))); $uid = $bitfield = ''; @@ -537,12 +573,12 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb * @var string uid The BBCode UID * @var string bitfield The BBCode Bitfield * @var int flags The BBCode Flags - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('text', 'uid', 'bitfield', 'flags'); extract($phpbb_dispatcher->trigger_event('core.modify_text_for_storage_after', compact($vars))); - return; + return $message_parser->warn_msg; } /** @@ -560,7 +596,7 @@ function generate_text_for_edit($text, $uid, $flags) * @var string text The text to parse * @var string uid The BBCode UID * @var int flags The BBCode Flags - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('text', 'uid', 'flags'); extract($phpbb_dispatcher->trigger_event('core.modify_text_for_edit_before', compact($vars))); @@ -573,7 +609,7 @@ function generate_text_for_edit($text, $uid, $flags) * @event core.modify_text_for_edit_after * @var string text The text to parse * @var int flags The BBCode Flags - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('text', 'flags'); extract($phpbb_dispatcher->trigger_event('core.modify_text_for_edit_after', compact($vars))); @@ -773,7 +809,8 @@ function make_clickable($text, $server_url = false, $class = 'postlink') { $text = preg_replace_callback($magic_args[0], function($matches) use ($magic_args) { - return make_clickable_callback($magic_args[1], $matches[1], $matches[2], $matches[3], $magic_args[2]); + $relative_url = isset($matches[3]) ? $matches[3] : ''; + return make_clickable_callback($magic_args[1], $matches[1], $matches[2], $relative_url, $magic_args[2]); }, $text); } } @@ -1363,7 +1400,7 @@ function get_username_string($mode, $user_id, $username, $username_colour = '', { $username_string = str_replace(array('{PROFILE_URL}', '{USERNAME_COLOUR}', '{USERNAME}'), array($profile_url, $username_colour, $username), (!$username_colour) ? $_profile_cache['tpl_profile'] : $_profile_cache['tpl_profile_colour']); } - + /** * Use this event to change the output of get_username_string() * @@ -1379,9 +1416,18 @@ function get_username_string($mode, $user_id, $username, $username_colour = '', * profile url. * @var string username_string The string that has been generated * @var array _profile_cache Array of original return templates - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('mode', 'user_id', 'username', 'username_colour', 'guest_username', 'custom_profile_url', 'username_string', '_profile_cache'); + $vars = array( + 'mode', + 'user_id', + 'username', + 'username_colour', + 'guest_username', + 'custom_profile_url', + 'username_string', + '_profile_cache', + ); extract($phpbb_dispatcher->trigger_event('core.modify_username_string', compact($vars))); return $username_string; @@ -1404,6 +1450,38 @@ function phpbb_add_quickmod_option($option, $lang_string) } /** +* Concatenate an array into a string list. +* +* @param array $items Array of items to concatenate +* @param object $user The phpBB $user object. +* +* @return string String list. Examples: "A"; "A and B"; "A, B, and C" +*/ +function phpbb_generate_string_list($items, $user) +{ + if (empty($items)) + { + return ''; + } + + $count = sizeof($items); + $last_item = array_pop($items); + $lang_key = 'STRING_LIST_MULTI'; + + if ($count == 1) + { + return $last_item; + } + else if ($count == 2) + { + $lang_key = 'STRING_LIST_SIMPLE'; + } + $list = implode($user->lang['COMMA_SEPARATOR'], $items); + + return $user->lang($lang_key, $list, $last_item); +} + +/** * @package phpBB3 */ class bitfield diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php index a34a193f60..1646c79161 100644 --- a/phpBB/includes/functions_convert.php +++ b/phpBB/includes/functions_convert.php @@ -823,7 +823,7 @@ function get_avatar_dim($src, $axis, $func = false, $arg1 = false, $arg2 = false break; case AVATAR_REMOTE: - // see notes on this functions usage and (hopefully) model $func to avoid this accordingly + // see notes on this functions usage and (hopefully) model $func to avoid this accordingly return get_remote_avatar_dim($src, $axis); break; @@ -1027,7 +1027,6 @@ function set_user_options() 'attachsig' => array('bit' => 6, 'default' => 0), 'bbcode' => array('bit' => 8, 'default' => 1), 'smilies' => array('bit' => 9, 'default' => 1), - 'popuppm' => array('bit' => 10, 'default' => 0), 'sig_bbcode' => array('bit' => 15, 'default' => 1), 'sig_smilies' => array('bit' => 16, 'default' => 1), 'sig_links' => array('bit' => 17, 'default' => 1), @@ -1117,7 +1116,7 @@ function words_unique(&$words) * Adds a user to the specified group and optionally makes them a group leader * This function does not create the group if it does not exist and so should only be called after the groups have been created */ -function add_user_group($group_id, $user_id, $group_leader=false) +function add_user_group($group_id, $user_id, $group_leader = false) { global $convert, $phpbb_root_path, $config, $user, $db; @@ -1297,7 +1296,7 @@ function restore_config($schema) $src_ary = $schema['array_name']; $config_value = (isset($convert_config[$src_ary][$src])) ? $convert_config[$src_ary][$src] : ''; } - } + } if ($config_value !== '') { @@ -1719,7 +1718,7 @@ function add_default_groups() 'GUESTS' => array('', 0, 0), 'REGISTERED' => array('', 0, 0), 'REGISTERED_COPPA' => array('', 0, 0), - 'GLOBAL_MODERATORS' => array('00AA00', 1, 0), + 'GLOBAL_MODERATORS' => array('00AA00', 2, 0), 'ADMINISTRATORS' => array('AA0000', 1, 1), 'BOTS' => array('9E8DA7', 0, 0), 'NEWLY_REGISTERED' => array('', 0, 0), @@ -1748,7 +1747,7 @@ function add_default_groups() 'group_type' => GROUP_SPECIAL, 'group_colour' => (string) $data[0], 'group_legend' => (int) $data[1], - 'group_founder_manage' => (int) $data[2] + 'group_founder_manage' => (int) $data[2], ); } @@ -1758,6 +1757,38 @@ function add_default_groups() } } +function add_groups_to_teampage() +{ + global $db; + + $teampage_groups = array( + 'ADMINISTRATORS' => 1, + 'GLOBAL_MODERATORS' => 2, + ); + + $sql = 'SELECT * + FROM ' . GROUPS_TABLE . ' + WHERE ' . $db->sql_in_set('group_name', array_keys($teampage_groups)); + $result = $db->sql_query($sql); + + $teampage_ary = array(); + while ($row = $db->sql_fetchrow($result)) + { + $teampage_ary[] = array( + 'group_id' => (int) $row['group_id'], + 'teampage_name' => '', + 'teampage_position' => (int) $teampage_groups[$row['group_name']], + 'teampage_parent' => 0, + ); + } + $db->sql_freeresult($result); + + if (sizeof($teampage_ary)) + { + $db->sql_multi_insert(TEAMPAGE_TABLE, $teampage_ary); + } +} + /** * Sync post count. We might need to do this in batches. diff --git a/phpBB/includes/functions_database_helper.php b/phpBB/includes/functions_database_helper.php index 923e542690..4b2cbdd25b 100644 --- a/phpBB/includes/functions_database_helper.php +++ b/phpBB/includes/functions_database_helper.php @@ -22,14 +22,14 @@ if (!defined('IN_PHPBB')) * * The only supported table is bookmarks. * -* @param \phpbb\db\driver\driver $db Database object +* @param \phpbb\db\driver\driver_interface $db Database object * @param string $table Table on which to perform the update * @param string $column Column whose values to change * @param array $from_values An array of values that should be changed * @param int $to_value The new value * @return null */ -function phpbb_update_rows_avoiding_duplicates(\phpbb\db\driver\driver $db, $table, $column, $from_values, $to_value) +function phpbb_update_rows_avoiding_duplicates(\phpbb\db\driver\driver_interface $db, $table, $column, $from_values, $to_value) { $sql = "SELECT $column, user_id FROM $table @@ -107,14 +107,14 @@ function phpbb_update_rows_avoiding_duplicates(\phpbb\db\driver\driver $db, $tab * * The only supported table is topics_watch. * -* @param \phpbb\db\driver\driver $db Database object +* @param \phpbb\db\driver\driver_interface $db Database object * @param string $table Table on which to perform the update * @param string $column Column whose values to change * @param array $from_values An array of values that should be changed * @param int $to_value The new value * @return null */ -function phpbb_update_rows_avoiding_duplicates_notify_status(\phpbb\db\driver\driver $db, $table, $column, $from_values, $to_value) +function phpbb_update_rows_avoiding_duplicates_notify_status(\phpbb\db\driver\driver_interface $db, $table, $column, $from_values, $to_value) { $sql = "SELECT $column, user_id, notify_status FROM $table diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index c6ab5df90f..353f0be04b 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -138,7 +138,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod * * @event core.display_forums_modify_sql * @var array sql_ary The SQL array to get the data of the forums - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('sql_ary'); extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_sql', compact($vars))); @@ -161,7 +161,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod * @event core.display_forums_modify_row * @var int branch_root_id Last top-level forum * @var array row The data of the forum - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('branch_root_id', 'row'); extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_row', compact($vars))); @@ -318,7 +318,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod * @var int branch_root_id Current top-level forum * @var int parent_id Current parent forum * @var array row The data of the forum - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('forum_rows', 'subforums', 'branch_root_id', 'parent_id', 'row'); extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_forum_rows', compact($vars))); @@ -441,7 +441,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod } } - $l_subforums = (sizeof($subforums[$forum_id]) == 1) ? $user->lang['SUBFORUM'] . ': ' : $user->lang['SUBFORUMS'] . ': '; + $l_subforums = (sizeof($subforums[$forum_id]) == 1) ? $user->lang['SUBFORUM'] : $user->lang['SUBFORUMS']; $folder_image = ($forum_unread) ? 'forum_unread_subforum' : 'forum_read_subforum'; } else @@ -568,7 +568,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod * @event core.display_forums_modify_template_vars * @var array forum_row Template data of the forum * @var array row The data of the forum - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('forum_row', 'row'); extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_template_vars', compact($vars))); @@ -900,7 +900,6 @@ function topic_status(&$topic_row, $replies, $unread_topic, &$folder_img, &$fold $folder_new .= '_locked'; } - $folder_img = ($unread_topic) ? $folder_new : $folder; $folder_alt = ($unread_topic) ? 'UNREAD_POSTS' : (($topic_row['topic_status'] == ITEM_LOCKED) ? 'TOPIC_LOCKED' : 'NO_UNREAD_POSTS'); @@ -919,7 +918,7 @@ function topic_status(&$topic_row, $replies, $unread_topic, &$folder_img, &$fold /** * Assign/Build custom bbcodes for display in screens supporting using of bbcodes -* The custom bbcodes buttons will be placed within the template block 'custom_codes' +* The custom bbcodes buttons will be placed within the template block 'custom_tags' */ function display_custom_bbcodes() { @@ -928,11 +927,26 @@ function display_custom_bbcodes() // Start counting from 22 for the bbcode ids (every bbcode takes two ids - opening/closing) $num_predefined_bbcodes = 22; - $sql = 'SELECT bbcode_id, bbcode_tag, bbcode_helpline - FROM ' . BBCODES_TABLE . ' - WHERE display_on_posting = 1 - ORDER BY bbcode_tag'; - $result = $db->sql_query($sql); + $sql_ary = array( + 'SELECT' => 'b.bbcode_id, b.bbcode_tag, b.bbcode_helpline', + 'FROM' => array(BBCODES_TABLE => 'b'), + 'WHERE' => 'b.display_on_posting = 1', + 'ORDER_BY' => 'b.bbcode_tag', + ); + + /** + * Event to modify the SQL query before custom bbcode data is queried + * + * @event core.display_custom_bbcodes_modify_sql + * @var array sql_ary The SQL array to get the bbcode data + * @var int num_predefined_bbcodes The number of predefined core bbcodes + * (multiplied by factor of 2) + * @since 3.1.0-a3 + */ + $vars = array('sql_ary', 'num_predefined_bbcodes'); + extract($phpbb_dispatcher->trigger_event('core.display_custom_bbcodes_modify_sql', compact($vars))); + + $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary)); $i = 0; while ($row = $db->sql_fetchrow($result)) @@ -947,19 +961,20 @@ function display_custom_bbcodes() 'BBCODE_NAME' => "'[{$row['bbcode_tag']}]', '[/" . str_replace('=', '', $row['bbcode_tag']) . "]'", 'BBCODE_ID' => $num_predefined_bbcodes + ($i * 2), 'BBCODE_TAG' => $row['bbcode_tag'], + 'BBCODE_TAG_CLEAN' => str_replace('=', '-', $row['bbcode_tag']), 'BBCODE_HELPLINE' => $row['bbcode_helpline'], 'A_BBCODE_HELPLINE' => str_replace(array('&', '"', "'", '<', '>'), array('&', '"', "\'", '<', '>'), $row['bbcode_helpline']), ); /** - * Modify the template data block of a bbcode + * Event to modify the template data block of a custom bbcode * * This event is triggered once per bbcode * * @event core.display_custom_bbcodes_modify_row * @var array custom_tags Template data of the bbcode * @var array row The data of the bbcode - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('custom_tags', 'row'); extract($phpbb_dispatcher->trigger_event('core.display_custom_bbcodes_modify_row', compact($vars))); @@ -974,7 +989,7 @@ function display_custom_bbcodes() * Display custom bbcodes * * @event core.display_custom_bbcodes - * @since 3.1-A1 + * @since 3.1.0-a1 */ $phpbb_dispatcher->dispatch('core.display_custom_bbcodes'); } @@ -1167,7 +1182,12 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, if ($uid != $user_id || $request->variable('unwatch', '', false, \phpbb\request\request_interface::GET) != $mode) { $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); - $message = $user->lang['ERR_UNWATCHING'] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); + $message = $user->lang['ERR_UNWATCHING']; + + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('RETURN_' . strtoupper($mode), '<a href="' . $redirect_url . '">', '</a>'); + } trigger_error($message); } @@ -1177,8 +1197,12 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, $db->sql_query($sql); $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); - $message = $user->lang['NOT_WATCHING_' . strtoupper($mode)] . '<br /><br />'; - $message .= sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); + $message = $user->lang['NOT_WATCHING_' . strtoupper($mode)]; + + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('RETURN_' . strtoupper($mode), '<a href="' . $redirect_url . '">', '</a>'); + } meta_refresh(3, $redirect_url); trigger_error($message); } @@ -1232,7 +1256,12 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, if ($uid != $user_id || $request->variable('watch', '', false, \phpbb\request\request_interface::GET) != $mode) { $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); - $message = $user->lang['ERR_WATCHING'] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); + $message = $user->lang['ERR_WATCHING']; + + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('RETURN_' . strtoupper($mode), '<a href="' . $redirect_url . '">', '</a>'); + } trigger_error($message); } @@ -1243,7 +1272,12 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, $db->sql_query($sql); $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&start=$start"); - $message = $user->lang['ARE_WATCHING_' . strtoupper($mode)] . '<br /><br />' . sprintf($user->lang['RETURN_' . strtoupper($mode)], '<a href="' . $redirect_url . '">', '</a>'); + $message = $user->lang['ARE_WATCHING_' . strtoupper($mode)]; + + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('RETURN_' . strtoupper($mode), '<a href="' . $redirect_url . '">', '</a>'); + } meta_refresh(3, $redirect_url); trigger_error($message); } @@ -1342,92 +1376,6 @@ function get_user_rank($user_rank, $user_posts, &$rank_title, &$rank_img, &$rank } /** -* Get user avatar -* -* @param array $user_row Row from the users table -* @param string $alt Optional language string for alt tag within image, can be a language key or text -* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP -* -* @return string Avatar html -*/ -function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config = false) -{ - $row = \phpbb\avatar\manager::clean_row($user_row); - return phpbb_get_avatar($row, $alt, $ignore_config); -} - -/** -* Get group avatar -* -* @param array $group_row Row from the groups table -* @param string $alt Optional language string for alt tag within image, can be a language key or text -* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP -* -* @return string Avatar html -*/ -function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config = false) -{ - $row = \phpbb\avatar\manager::clean_row($user_row); - return phpbb_get_avatar($row, $alt, $ignore_config); -} - -/** -* Get avatar -* -* @param array $row Row cleaned by \phpbb\avatar\driver\driver::clean_row -* @param string $alt Optional language string for alt tag within image, can be a language key or text -* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP -* -* @return string Avatar html -*/ -function phpbb_get_avatar($row, $alt, $ignore_config = false) -{ - global $user, $config, $cache, $phpbb_root_path, $phpEx; - global $request; - global $phpbb_container; - - if (!$config['allow_avatar'] && !$ignore_config) - { - return ''; - } - - $avatar_data = array( - 'src' => $row['avatar'], - 'width' => $row['avatar_width'], - 'height' => $row['avatar_height'], - ); - - $phpbb_avatar_manager = $phpbb_container->get('avatar.manager'); - $driver = $phpbb_avatar_manager->get_driver($row['avatar_type'], $ignore_config); - $html = ''; - - if ($driver) - { - $html = $driver->get_custom_html($user, $row, $alt); - if (!empty($html)) - { - return $html; - } - - $avatar_data = $driver->get_data($row, $ignore_config); - } - else - { - $avatar_data['src'] = ''; - } - - if (!empty($avatar_data['src'])) - { - $html = '<img src="' . $avatar_data['src'] . '" ' . - ($avatar_data['width'] ? ('width="' . $avatar_data['width'] . '" ') : '') . - ($avatar_data['height'] ? ('height="' . $avatar_data['height'] . '" ') : '') . - 'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />'; - } - - return $html; -} - -/** * Generate a list of archive types available for compressing attachments * * @param string $param_key Either topic_id or post_id @@ -1445,6 +1393,8 @@ function phpbb_gen_download_links($param_key, $param_val, $phpbb_root_path, $php } $methods = compress::methods(); + // Sort by preferred type. + $methods = array_intersect(array('.zip', '.tar.bz2', '.tar.gz', '.tar'), $methods); $links = array(); foreach ($methods as $method) diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index e7a1d2bff5..7ad34d9515 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -596,7 +596,7 @@ function phpbb_parse_range_request($request_array, $filesize) /** * Increments the download count of all provided attachments * -* @param \phpbb\db\driver\driver $db The database object +* @param \phpbb\db\driver\driver_interface $db The database object * @param array|int $ids The attach_id of each attachment * * @return null @@ -617,7 +617,7 @@ function phpbb_increment_downloads($db, $ids) /** * Handles authentication when downloading attachments from a post or topic * -* @param \phpbb\db\driver\driver $db The database object +* @param \phpbb\db\driver\driver_interface $db The database object * @param \phpbb\auth\auth $auth The authentication object * @param int $topic_id The id of the topic that we are downloading from * @@ -625,17 +625,29 @@ function phpbb_increment_downloads($db, $ids) */ function phpbb_download_handle_forum_auth($db, $auth, $topic_id) { - $sql = 'SELECT t.forum_id, f.forum_name, f.forum_password, f.parent_id - FROM ' . TOPICS_TABLE . ' t, ' . FORUMS_TABLE . " f - WHERE t.topic_id = " . (int) $topic_id . " - AND t.forum_id = f.forum_id"; + $sql_array = array( + 'SELECT' => 't.topic_visibility, t.forum_id, f.forum_name, f.forum_password, f.parent_id', + 'FROM' => array( + TOPICS_TABLE => 't', + FORUMS_TABLE => 'f', + ), + 'WHERE' => 't.topic_id = ' . (int) $topic_id . ' + AND t.forum_id = f.forum_id', + ); + + $sql = $db->sql_build_query('SELECT', $sql_array); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - if ($auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id'])) + if ($row && $row['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) { - if ($row && $row['forum_password']) + send_status_line(404, 'Not Found'); + trigger_error('ERROR_NO_ATTACHMENT'); + } + else if ($row && $auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id'])) + { + if ($row['forum_password']) { // Do something else ... ? login_forum_box($row); @@ -651,7 +663,7 @@ function phpbb_download_handle_forum_auth($db, $auth, $topic_id) /** * Handles authentication when downloading attachments from PMs * -* @param \phpbb\db\driver\driver $db The database object +* @param \phpbb\db\driver\driver_interface $db The database object * @param \phpbb\auth\auth $auth The authentication object * @param int $user_id The user id * @param int $msg_id The id of the PM that we are downloading from @@ -678,7 +690,7 @@ function phpbb_download_handle_pm_auth($db, $auth, $user_id, $msg_id) /** * Checks whether a user can download from a particular PM * -* @param \phpbb\db\driver\driver $db The database object +* @param \phpbb\db\driver\driver_interface $db The database object * @param int $user_id The user id * @param int $msg_id The id of the PM that we are downloading from * diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index bfd669fdfa..4f8ec99d88 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -486,12 +486,14 @@ function adjust_language_keys_callback($matches) * @param array $data Array containing the database connection information * @param string $dbms The name of the DBAL class to use * @param bool $debug If the debug constants should be enabled by default or not +* @param bool $debug_container If the container should be compiled on +* every page load or not * @param bool $debug_test If the DEBUG_TEST constant should be added * NOTE: Only for use within the testing framework * * @return string The output to write to the file */ -function phpbb_create_config_file_data($data, $dbms, $debug = false, $debug_test = false) +function phpbb_create_config_file_data($data, $dbms, $debug = false, $debug_container = false, $debug_test = false) { $config_data = "<?php\n"; $config_data .= "// phpBB 3.1.x auto-generated configuration file\n// Do not change anything in this file!\n"; @@ -505,7 +507,7 @@ function phpbb_create_config_file_data($data, $dbms, $debug = false, $debug_test 'dbpasswd' => htmlspecialchars_decode($data['dbpasswd']), 'table_prefix' => $data['table_prefix'], - 'adm_relative_path' => 'adm/', + 'phpbb_adm_relative_path' => 'adm/', 'acm_type' => 'phpbb\cache\driver\file', ); @@ -526,6 +528,15 @@ function phpbb_create_config_file_data($data, $dbms, $debug = false, $debug_test $config_data .= "// @define('DEBUG', true);\n"; } + if ($debug_container) + { + $config_data .= "@define('DEBUG_CONTAINER', true);\n"; + } + else + { + $config_data .= "// @define('DEBUG_CONTAINER', true);\n"; + } + if ($debug_test) { $config_data .= "@define('DEBUG_TEST', true);\n"; @@ -533,3 +544,70 @@ function phpbb_create_config_file_data($data, $dbms, $debug = false, $debug_test return $config_data; } + +/** +* Check whether a file should be ignored on update +* +* We ignore new files in some circumstances: +* 1. The file is a language file, but the language is not installed +* 2. The file is a style file, but the style is not installed +* 3. The file is a style language file, but the language is not installed +* +* @param string $phpbb_root_path phpBB root path +* @param string $file File including path from phpbb root +* @return bool Should we ignore the new file or add it to the board? +*/ +function phpbb_ignore_new_file_on_update($phpbb_root_path, $file) +{ + $ignore_new_file = false; + + // We ignore new files in some circumstances: + // 1. The file is a language file, but the language is not installed + if (!$ignore_new_file && strpos($file, 'language/') === 0) + { + list($language_dir, $language_iso) = explode('/', $file); + $ignore_new_file = !file_exists($phpbb_root_path . $language_dir . '/' . $language_iso); + } + + // 2. The file is a style file, but the style is not installed + if (!$ignore_new_file && strpos($file, 'styles/') === 0) + { + list($styles_dir, $style_name) = explode('/', $file); + $ignore_new_file = !file_exists($phpbb_root_path . $styles_dir . '/' . $style_name); + } + + // 3. The file is a style language file, but the language is not installed + if (!$ignore_new_file && strpos($file, 'styles/') === 0) + { + $dirs = explode('/', $file); + if (sizeof($dirs) >= 5) + { + list($styles_dir, $style_name, $template_component, $language_iso) = explode('/', $file); + if ($template_component == 'theme' && $language_iso !== 'images') + { + $ignore_new_file = !file_exists($phpbb_root_path . 'language/' . $language_iso); + } + } + } + + return $ignore_new_file; +} + +/** +* Check whether phpBB is installed. +* +* @param string $phpbb_root_path Path to the phpBB board root. +* @param string $php_ext PHP file extension. +* +* @return bool Returns true if phpBB is installed. +*/ +function phpbb_check_installation_exists($phpbb_root_path, $php_ext) +{ + // Try opening config file + if (file_exists($phpbb_root_path . 'config.' . $php_ext)) + { + include($phpbb_root_path . 'config.' . $php_ext); + } + + return defined('PHPBB_INSTALLED'); +} diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 5b343e616e..79a5aeda1a 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -484,14 +484,17 @@ class messenger $use_queue = true; } + $contact_name = htmlspecialchars_decode($config['board_contact_name']); + $board_contact = (($contact_name !== '') ? '"' . mail_encode($contact_name) . '" ' : '') . '<' . $config['board_contact'] . '>'; + if (empty($this->replyto)) { - $this->replyto = '<' . $config['board_contact'] . '>'; + $this->replyto = $board_contact; } if (empty($this->from)) { - $this->from = '<' . $config['board_contact'] . '>'; + $this->from = $board_contact; } $encode_eol = ($config['smtp_delivery']) ? "\r\n" : $this->eol; @@ -768,13 +771,15 @@ class queue if (!$this->jabber->connect()) { - messenger::error('JABBER', $user->lang['ERR_JAB_CONNECT']); + $messenger = new messenger(); + $messenger->error('JABBER', $user->lang['ERR_JAB_CONNECT']); continue 2; } if (!$this->jabber->login()) { - messenger::error('JABBER', $user->lang['ERR_JAB_AUTH']); + $messenger = new messenger(); + $messenger->error('JABBER', $user->lang['ERR_JAB_AUTH']); continue 2; } @@ -807,7 +812,8 @@ class queue if (!$result) { - messenger::error('EMAIL', $err_msg); + $messenger = new messenger(); + $messenger->error('EMAIL', $err_msg); continue 2; } break; @@ -817,7 +823,8 @@ class queue { if ($this->jabber->send_message($address, $msg, $subject) === false) { - messenger::error('JABBER', $this->jabber->get_log()); + $messenger = new messenger(); + $messenger->error('JABBER', $this->jabber->get_log()); continue 3; } } @@ -1414,7 +1421,7 @@ class smtp_class $result = false; $stream_meta = stream_get_meta_data($this->socket); - if (socket_set_blocking($this->socket, 1)); + if (socket_set_blocking($this->socket, 1)) { $result = stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); socket_set_blocking($this->socket, (int) $stream_meta['blocked']); diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index b33f3d6866..04efcb7b2e 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -80,7 +80,7 @@ class p_master function list_modules($p_class) { global $auth, $db, $user, $cache; - global $config, $phpbb_root_path, $phpEx; + global $config, $phpbb_root_path, $phpEx, $phpbb_dispatcher; // Sanitise for future path use, it's escaped as appropriate for queries $this->p_class = str_replace(array('.', '/', '\\'), '', basename($p_class)); @@ -125,8 +125,17 @@ class p_master // Clean up module cache array to only let survive modules the user can access $right_id = false; + + $hide_categories = array(); foreach ($this->module_cache['modules'] as $key => $row) { + // When the module has no mode (category) we check whether it has visible children + // before listing it as well. + if (!$row['module_mode']) + { + $hide_categories[(int) $row['module_id']] = $key; + } + // Not allowed to view module? if (!$this->module_auth_self($row['module_auth'])) { @@ -161,6 +170,22 @@ class p_master $right_id = $row['right_id']; continue; } + + if ($row['module_mode']) + { + // The parent category has a visible child + // So remove it and all its parents from the hide array + unset($hide_categories[(int) $row['parent_id']]); + foreach ($this->module_cache['parents'][$row['module_id']] as $module_id => $row_id) + { + unset($hide_categories[$module_id]); + } + } + } + + foreach ($hide_categories as $module_id => $row_id) + { + unset($this->module_cache['modules'][$row_id]); } // Re-index (this is needed, else we are not able to array_slice later) @@ -259,6 +284,20 @@ class p_master $custom_func($row['module_mode'], $module_row); } + /** + * This event allows to modify parameters for building modules list + * + * @event core.modify_module_row + * @var string url_func Function for building 'url_extra' + * @var string lang_func Function for building the language name + * @var string custom_func Custom function for calling parameters on module init + * @var array row Array holding the basic module data + * @var array module_row Array holding the module display parameters + * @since 3.1.0-b3 + */ + $vars = array('url_func', 'lang_func', 'custom_func', 'row', 'module_row'); + extract($phpbb_dispatcher->trigger_event('core.modify_module_row', compact($vars))); + $this->module_ary[] = $module_row; } @@ -334,7 +373,7 @@ class p_master static function module_auth($module_auth, $forum_id) { global $auth, $config; - global $request; + global $request, $phpbb_extension_manager, $phpbb_dispatcher; $module_auth = trim($module_auth); @@ -351,6 +390,31 @@ class p_master [(),] | [^\s(),]+)/x', $module_auth, $match); + // Valid tokens for auth and their replacements + $valid_tokens = array( + 'acl_([a-z0-9_]+)(,\$id)?' => '(int) $auth->acl_get(\'\\1\'\\2)', + '\$id' => '(int) $forum_id', + 'aclf_([a-z0-9_]+)' => '(int) $auth->acl_getf_global(\'\\1\')', + 'cfg_([a-z0-9_]+)' => '(int) $config[\'\\1\']', + 'request_([a-zA-Z0-9_]+)' => '$request->variable(\'\\1\', false)', + 'ext_([a-zA-Z0-9_/]+)' => 'array_key_exists(\'\\1\', $phpbb_extension_manager->all_enabled())', + 'authmethod_([a-z0-9_\\\\]+)' => '($config[\'auth_method\'] === \'\\1\')', + ); + + /** + * Alter tokens for module authorisation check + * + * @event core.module_auth + * @var array valid_tokens Valid tokens and their auth check + * replacements + * @var string module_auth The module_auth of the current + * module + * @var int forum_id The current forum_id + * @since 3.1.0-a3 + */ + $vars = array('valid_tokens', 'module_auth', 'forum_id'); + extract($phpbb_dispatcher->trigger_event('core.module_auth', compact($vars))); + $tokens = $match[0]; for ($i = 0, $size = sizeof($tokens); $i < $size; $i++) { @@ -366,7 +430,7 @@ class p_master break; default: - if (!preg_match('#(?:acl_([a-z0-9_]+)(,\$id)?)|(?:\$id)|(?:aclf_([a-z0-9_]+))|(?:cfg_([a-z0-9_]+))|(?:request_([a-zA-Z0-9_]+))#', $token)) + if (!preg_match('#(?:' . implode(array_keys($valid_tokens), ')|(?:') . ')#', $token)) { $token = ''; } @@ -379,8 +443,17 @@ class p_master // Make sure $id separation is working fine $module_auth = str_replace(' , ', ',', $module_auth); + $module_auth = preg_replace( + // Array keys with # prepended/appended + array_map(function($value) { + return '#' . $value . '#'; + }, array_keys($valid_tokens)), + array_values($valid_tokens), + $module_auth + ); + $is_auth = false; - eval('$is_auth = (int) (' . preg_replace(array('#acl_([a-z0-9_]+)(,\$id)?#', '#\$id#', '#aclf_([a-z0-9_]+)#', '#cfg_([a-z0-9_]+)#', '#request_([a-zA-Z0-9_]+)#'), array('(int) $auth->acl_get(\'\\1\'\\2)', '(int) $forum_id', '(int) $auth->acl_getf_global(\'\\1\')', '(int) $config[\'\\1\']', '$request->variable(\'\\1\', false)'), $module_auth) . ');'); + eval('$is_auth = (int) (' . $module_auth . ');'); return $is_auth; } @@ -462,7 +535,7 @@ class p_master if ($this->active_module === false) { - trigger_error('Module not accessible', E_USER_ERROR); + trigger_error('MODULE_NOT_ACCESS', E_USER_ERROR); } // new modules use the full class names, old ones are always called <type>_<name>, e.g. acp_board @@ -470,14 +543,14 @@ class p_master { if (!file_exists("$module_path/{$this->p_name}.$phpEx")) { - trigger_error("Cannot find module $module_path/{$this->p_name}.$phpEx", E_USER_ERROR); + trigger_error($user->lang('MODULE_NOT_FIND', "$module_path/{$this->p_name}.$phpEx"), E_USER_ERROR); } include("$module_path/{$this->p_name}.$phpEx"); if (!class_exists($this->p_name)) { - trigger_error("Module file $module_path/{$this->p_name}.$phpEx does not contain correct class [{$this->p_name}]", E_USER_ERROR); + trigger_error($user->lang('MODULE_FILE_INCORRECT_CLASS', "$module_path/{$this->p_name}.$phpEx", $this->p_name), E_USER_ERROR); } } @@ -519,7 +592,7 @@ class p_master } // Not being able to overwrite ;) - $this->module->u_action = append_sid("{$phpbb_admin_path}index.$phpEx", "i={$this->p_name}") . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; + $this->module->u_action = append_sid("{$phpbb_admin_path}index.$phpEx", 'i=' . $this->get_module_identifier($this->p_name, $this->p_id)) . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; } else { @@ -528,12 +601,12 @@ class p_master * the style paths for the extension (the ext author can change them * if necessary). */ - $module_dir = explode('_', get_class($this->module)); + $module_dir = explode('\\', get_class($this->module)); - // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... - if (isset($module_dir[3]) && $module_dir[1] === 'ext') + // 0 vendor, 1 extension name, ... + if (isset($module_dir[1])) { - $module_style_dir = 'ext/' . $module_dir[2] . '/' . $module_dir[3] . '/styles'; + $module_style_dir = 'ext/' . $module_dir[0] . '/' . $module_dir[1] . '/styles'; if (is_dir($phpbb_root_path . $module_style_dir)) { @@ -551,7 +624,7 @@ class p_master $this->module->u_action = $phpbb_root_path . (($user->page['page_dir']) ? $user->page['page_dir'] . '/' : '') . $user->page['page_name']; } - $this->module->u_action = append_sid($this->module->u_action, "i={$this->p_name}") . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; + $this->module->u_action = append_sid($this->module->u_action, 'i=' . $this->get_module_identifier($this->p_name, $this->p_id)) . (($icat) ? '&icat=' . $icat : '') . "&mode={$this->p_mode}"; } // Add url_extra parameter to u_action url @@ -799,12 +872,12 @@ class p_master // if the item has a name use it, else use its id if (empty($item_ary['name'])) { - $u_title .= $item_ary['id']; + $u_title .= $item_ary['id']; } else { // if the category has a name, then use it. - $u_title .= $item_ary['name']; + $u_title .= $this->get_module_identifier($item_ary['name'], $item_ary['id']); } // If the item is not a category append the mode if (!$item_ary['cat']) @@ -898,7 +971,7 @@ class p_master /** * Display module */ - function display($page_title, $display_online_list = true) + function display($page_title, $display_online_list = false) { global $template, $user; @@ -983,6 +1056,29 @@ class p_master } /** + * If the basename contains a \ we dont use that for the URL. + * + * Firefox is currently unable to correctly copy a urlencoded \ + * so users will be unable to post links to modules. + * However we can still fallback to the id instead of the name, + * so we do that in this case. + * + * @param string $basename Basename of the module + * @param int $id Id of the module + * @return mixed Identifier that should be used for + * module link creation + */ + protected function get_module_identifier($basename, $id) + { + if (strpos($basename, '\\') === false) + { + return $basename; + } + + return $id; + } + + /** * Checks whether the given module basename is a correct class name * * @param string $basename A module basename diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index ce1238d8e0..547ea69e81 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -21,8 +21,10 @@ if (!defined('IN_PHPBB')) function generate_smilies($mode, $forum_id) { global $db, $user, $config, $template, $phpbb_dispatcher; - global $phpEx, $phpbb_root_path; + global $phpEx, $phpbb_root_path, $phpbb_container; + $base_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id); + $pagination = $phpbb_container->get('pagination'); $start = request_var('start', 0); if ($mode == 'window') @@ -61,7 +63,8 @@ function generate_smilies($mode, $forum_id) 'body' => 'posting_smilies.html') ); - generate_pagination(append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id), $smiley_count, $config['smilies_per_page'], $start); + $start = $pagination->validate_start($start, $config['smilies_per_page'], $smiley_count); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $smiley_count, $config['smilies_per_page'], $start); } $display_link = false; @@ -130,7 +133,7 @@ function generate_smilies($mode, $forum_id) * @var string mode Mode of the smilies: window|inline * @var int forum_id The forum ID we are currently in * @var bool display_link Shall we display the "more smilies" link? - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('mode', 'forum_id', 'display_link'); extract($phpbb_dispatcher->trigger_event('core.generate_smilies_after', compact($vars))); @@ -139,8 +142,8 @@ function generate_smilies($mode, $forum_id) { $template->assign_vars(array( 'S_SHOW_SMILEY_LINK' => true, - 'U_MORE_SMILIES' => append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id)) - ); + 'U_MORE_SMILIES' => $base_url, + )); } if ($mode == 'window') @@ -170,7 +173,6 @@ function update_post_information($type, $ids, $return_update_sql = false) $ids = array($ids); } - $update_sql = $empty_forums = $not_empty_forums = array(); if ($type != 'topic') @@ -385,8 +387,18 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL) /** * Upload Attachment - filedata is generated here * Uses upload class +* +* @param string $form_name The form name of the file upload input +* @param int $forum_id The id of the forum +* @param bool $local Whether the file is local or not +* @param string $local_storage The path to the local file +* @param bool $is_message Whether it is a PM or not +* @param \filespec $local_filedata A filespec object created for the local file +* @param \phpbb\plupload\plupload $plupload The plupload object if one is being used +* +* @return object filespec */ -function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false) +function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false, \phpbb\plupload\plupload $plupload = null) { global $auth, $user, $config, $db, $cache; global $phpbb_root_path, $phpEx; @@ -402,6 +414,10 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage { $upload->set_disallowed_content(explode('|', $config['mime_triggers'])); } + else if (!$config['check_attachment_content']) + { + $upload->set_disallowed_content(array()); + } $filedata['post_attach'] = $local || $upload->is_valid($form_name); @@ -414,7 +430,7 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage $extensions = $cache->obtain_attach_extensions((($is_message) ? false : (int) $forum_id)); $upload->set_allowed_extensions(array_keys($extensions['_allowed_'])); - $file = ($local) ? $upload->local_upload($local_storage, $local_filedata) : $upload->form_upload($form_name); + $file = ($local) ? $upload->local_upload($local_storage, $local_filedata) : $upload->form_upload($form_name, $plupload); if ($file->init_error) { @@ -469,6 +485,11 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage { $file->remove(); + if ($plupload && $plupload->is_active()) + { + $plupload->emit_error(104, 'ATTACHED_IMAGE_NOT_IMAGE'); + } + // If this error occurs a user tried to exploit an IE Bug by renaming extensions // Since the image category is displaying content inline we need to catch this. trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']); @@ -847,6 +868,7 @@ function posting_gen_attachment_entry($attachment_data, &$filename_data, $show_a 'ATTACH_ID' => $attach_row['attach_id'], 'S_IS_ORPHAN' => $attach_row['is_orphan'], 'ASSOC_INDEX' => $count, + 'FILESIZE' => get_formatted_filesize($attach_row['filesize']), 'U_VIEW_ATTACHMENT' => $download_link, 'S_HIDDEN' => $hidden) @@ -1130,7 +1152,7 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id 'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false, 'S_FRIEND' => ($row['friend']) ? true : false, 'S_IGNORE_POST' => ($row['foe']) ? true : false, - 'L_IGNORE_POST' => ($row['foe']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), "<a href=\"{$u_show_post}\" onclick=\"dE('{$post_anchor}', 1); return false;\">", '</a>') : '', + 'L_IGNORE_POST' => ($row['foe']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), "<a href=\"{$u_show_post}\" onclick=\"phpbb.toggleDisplay('{$post_anchor}', 1); return false;\">", '</a>') : '', 'POST_SUBJECT' => $post_subject, 'MINI_POST_IMG' => $user->img('icon_post_target', $user->lang['POST']), @@ -1273,7 +1295,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $ { $sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1'; } - else if ($data['topic_visibility'] == ITEM_UNAPPROVED) + else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) { $sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1'; } @@ -1380,7 +1402,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $ { $phpbb_content_visibility->remove_post_from_statistic($data, $sql_data); } - else if ($data['post_visibility'] == ITEM_UNAPPROVED) + else if ($data['post_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE) { $sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_unapproved = forum_posts_unapproved - 1'; $sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_unapproved = topic_posts_unapproved - 1'; @@ -1458,7 +1480,33 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $ */ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $update_message = true, $update_search_index = true) { - global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path, $phpbb_container; + global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher; + + /** + * Modify the data for post submitting + * + * @event core.modify_submit_post_data + * @var string mode Variable containing posting mode value + * @var string subject Variable containing post subject value + * @var string username Variable containing post author name + * @var int topic_type Variable containing topic type value + * @var array poll Array with the poll data for the post + * @var array data Array with the data for the post + * @var bool update_message Flag indicating if the post will be updated + * @var bool update_search_index Flag indicating if the search index will be updated + * @since 3.1.0-a4 + */ + $vars = array( + 'mode', + 'subject', + 'username', + 'topic_type', + 'poll', + 'data', + 'update_message', + 'update_search_index', + ); + extract($phpbb_dispatcher->trigger_event('core.modify_submit_post_data', compact($vars))); // We do not handle erasing posts here if ($mode == 'delete') @@ -1516,16 +1564,25 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u { // Post not approved, but in queue $post_visibility = ITEM_UNAPPROVED; + switch ($post_mode) + { + case 'edit_first_post': + case 'edit': + case 'edit_last_post': + case 'edit_topic': + $post_visibility = ITEM_REAPPROVE; + break; + } } // MODs/Extensions are able to force any visibility on posts if (isset($data['force_approved_state'])) { - $post_visibility = (in_array((int) $data['force_approved_state'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED))) ? (int) $data['force_approved_state'] : $post_visibility; + $post_visibility = (in_array((int) $data['force_approved_state'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED, ITEM_REAPPROVE))) ? (int) $data['force_approved_state'] : $post_visibility; } if (isset($data['force_visibility'])) { - $post_visibility = (in_array((int) $data['force_visibility'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED))) ? (int) $data['force_visibility'] : $post_visibility; + $post_visibility = (in_array((int) $data['force_visibility'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED, ITEM_REAPPROVE))) ? (int) $data['force_visibility'] : $post_visibility; } // Start the transaction here @@ -1993,6 +2050,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $first_post_has_topic_info = ($post_mode == 'edit_first_post' && (($post_visibility == ITEM_DELETED && $data['topic_posts_softdeleted'] == 1) || ($post_visibility == ITEM_UNAPPROVED && $data['topic_posts_unapproved'] == 1) || + ($post_visibility == ITEM_REAPPROVE && $data['topic_posts_unapproved'] == 1) || ($post_visibility == ITEM_APPROVED && $data['topic_posts_approved'] == 1))); // Fix the post's and topic's visibility and first/last post information, when the post is edited if (($post_mode != 'post' && $post_mode != 'reply') && $data['post_visibility'] != $post_visibility) @@ -2000,7 +2058,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u // If the post was not approved, it could also be the starter, // so we sync the starter after approving/restoring, to ensure that the stats are correct // Same applies for the last post - $is_starter = ($post_mode == 'edit_first_post' || $data['post_visibility'] != ITEM_APPROVED); + $is_starter = ($post_mode == 'edit_first_post' || $post_mode == 'edit_topic' || $data['post_visibility'] != ITEM_APPROVED); $is_latest = ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || $data['post_visibility'] != ITEM_APPROVED); $phpbb_content_visibility = $phpbb_container->get('content.visibility'); @@ -2233,39 +2291,51 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u case 'edit_first_post': case 'edit': case 'edit_last_post': - // @todo: Check whether these notification deletions are correct - $phpbb_notifications->delete_notifications('topic', $data['topic_id']); - - $phpbb_notifications->delete_notifications(array( - 'quote', - 'bookmark', - 'post', - ), $data['post_id']); + // Nothing to do here break; } } - else if ($post_visibility == ITEM_DELETED) + else if ($post_visibility == ITEM_REAPPROVE) { switch ($mode) { + case 'edit_topic': + case 'edit_first_post': + $phpbb_notifications->add_notifications('topic_in_queue', $notification_data); + + // Delete the approve_post notification so we can notify the user again, + // when his post got reapproved + $phpbb_notifications->delete_notifications('approve_post', $notification_data['post_id']); + break; + + case 'edit': + case 'edit_last_post': + $phpbb_notifications->add_notifications('post_in_queue', $notification_data); + + // Delete the approve_post notification so we can notify the user again, + // when his post got reapproved + $phpbb_notifications->delete_notifications('approve_post', $notification_data['post_id']); + break; + case 'post': case 'reply': case 'quote': // Nothing to do here break; - + } + } + else if ($post_visibility == ITEM_DELETED) + { + switch ($mode) + { + case 'post': + case 'reply': + case 'quote': case 'edit_topic': case 'edit_first_post': case 'edit': case 'edit_last_post': - // @todo: Check whether these notification deletions are correct - $phpbb_notifications->delete_notifications('topic', $data['topic_id']); - - $phpbb_notifications->delete_notifications(array( - 'quote', - 'bookmark', - 'post', - ), $data['post_id']); + // Nothing to do here break; } } @@ -2290,6 +2360,23 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $url = (!$params) ? "{$phpbb_root_path}viewforum.$phpEx" : "{$phpbb_root_path}viewtopic.$phpEx"; $url = append_sid($url, 'f=' . $data['forum_id'] . $params) . $add_anchor; + /** + * This event is used for performing actions directly after a post or topic + * has been submitted. When a new topic is posted, the topic ID is + * available in the $data array. + * + * The only action that can be done by altering data made available to this + * event is to modify the return URL ($url). + * + * @event core.submit_post_end + * @var string url The "Return to topic" URL + * @var array data Array of post data about the + * submitted post + * @since 3.1.0-a3 + */ + $vars = array('url', 'data'); + extract($phpbb_dispatcher->trigger_event('core.submit_post_end', compact($vars))); + return $url; } diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index a2a79e032f..352e3b8c1f 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -314,7 +314,6 @@ function check_rule(&$rules, &$rule_row, &$message_row, $user_id) break; } - if (!$result) { return false; @@ -1561,7 +1560,7 @@ function get_folder_status($folder_id, $folder) 'percent' => ($user->data['message_limit']) ? (($user->data['message_limit'] > 0) ? round(($folder['num_messages'] / $user->data['message_limit']) * 100) : 100) : 0, ); - $return['message'] = $user->lang('FOLDER_STATUS_MSG', (int) $return['max'], $return['cur'], $return['percent']); + $return['message'] = $user->lang('FOLDER_STATUS_MSG', $user->lang('MESSAGES_COUNT', (int) $return['max']), $return['cur'], $return['percent']); return $return; } @@ -1575,7 +1574,7 @@ function get_folder_status($folder_id, $folder) */ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) { - global $db, $auth, $config, $phpEx, $template, $user, $phpbb_root_path, $phpbb_container; + global $db, $auth, $config, $phpEx, $template, $user, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher; // We do not handle erasing pms here if ($mode == 'delete') @@ -1585,6 +1584,18 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) $current_time = time(); + /** + * Get all parts of the PM that are to be submited to the DB. + * + * @event core.submit_pm_before + * @var string mode PM Post mode - post|reply|quote|quotepost|forward|edit + * @var string subject Subject of the private message + * @var array data The whole row data of the PM. + * @since 3.1.0-b3 + */ + $vars = array('mode', 'subject', 'data'); + extract($phpbb_dispatcher->trigger_event('core.submit_pm_before', compact($vars))); + // Collect some basic information about which tables and which rows to update/insert $sql_data = array(); $root_level = 0; @@ -2018,10 +2029,10 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode $decoded_message = bbcode_nl2br($decoded_message); } - + $parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0); $parse_flags |= ($row['enable_smilies'] ? OPTION_FLAG_SMILIES : 0); - + $message = generate_text_for_display($message, $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, false); $subject = censor_text($subject); diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php deleted file mode 100644 index 7dd0b0e87d..0000000000 --- a/phpBB/includes/functions_profile_fields.php +++ /dev/null @@ -1,1187 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Custom Profile Fields -* @package phpBB3 -*/ -class custom_profile -{ - var $profile_types = array(FIELD_INT => 'int', FIELD_STRING => 'string', FIELD_TEXT => 'text', FIELD_BOOL => 'bool', FIELD_DROPDOWN => 'dropdown', FIELD_DATE => 'date'); - var $profile_cache = array(); - var $options_lang = array(); - - /** - * Assign editable fields to template, mode can be profile (for profile change) or register (for registration) - * Called by ucp_profile and ucp_register - * @access public - */ - function generate_profile_fields($mode, $lang_id) - { - global $db, $template, $auth; - - $sql_where = ''; - switch ($mode) - { - case 'register': - // If the field is required we show it on the registration page - $sql_where .= ' AND f.field_show_on_reg = 1'; - break; - - case 'profile': - // Show hidden fields to moderators/admins - if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) - { - $sql_where .= ' AND f.field_show_profile = 1'; - } - break; - - default: - trigger_error('Wrong profile mode specified', E_USER_ERROR); - break; - } - - $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . " f - WHERE f.field_active = 1 - $sql_where - AND l.lang_id = $lang_id - AND l.field_id = f.field_id - ORDER BY f.field_order"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - // Return templated field - $tpl_snippet = $this->process_field_row('change', $row); - - // Some types are multivalue, we can't give them a field_id as we would not know which to pick - $type = (int) $row['field_type']; - - $template->assign_block_vars('profile_fields', array( - 'LANG_NAME' => $row['lang_name'], - 'LANG_EXPLAIN' => $row['lang_explain'], - 'FIELD' => $tpl_snippet, - 'FIELD_ID' => ($type == FIELD_DATE || ($type == FIELD_BOOL && $row['field_length'] == '1')) ? '' : 'pf_' . $row['field_ident'], - 'S_REQUIRED' => ($row['field_required']) ? true : false) - ); - } - $db->sql_freeresult($result); - } - - /** - * Validate entered profile field data - * @access public - */ - function validate_profile_field($field_type, &$field_value, $field_data) - { - switch ($field_type) - { - case FIELD_DATE: - $field_validate = explode('-', $field_value); - - $day = (isset($field_validate[0])) ? (int) $field_validate[0] : 0; - $month = (isset($field_validate[1])) ? (int) $field_validate[1] : 0; - $year = (isset($field_validate[2])) ? (int) $field_validate[2] : 0; - - if ((!$day || !$month || !$year) && !$field_data['field_required']) - { - return false; - } - - if ((!$day || !$month || !$year) && $field_data['field_required']) - { - return 'FIELD_REQUIRED'; - } - - if ($day < 0 || $day > 31 || $month < 0 || $month > 12 || ($year < 1901 && $year > 0) || $year > gmdate('Y', time()) + 50) - { - return 'FIELD_INVALID_DATE'; - } - - if (checkdate($month, $day, $year) === false) - { - return 'FIELD_INVALID_DATE'; - } - break; - - case FIELD_BOOL: - $field_value = (bool) $field_value; - - if (!$field_value && $field_data['field_required']) - { - return 'FIELD_REQUIRED'; - } - break; - - case FIELD_INT: - if (trim($field_value) === '' && !$field_data['field_required']) - { - return false; - } - - $field_value = (int) $field_value; - - if ($field_value < $field_data['field_minlen']) - { - return 'FIELD_TOO_SMALL'; - } - else if ($field_value > $field_data['field_maxlen']) - { - return 'FIELD_TOO_LARGE'; - } - break; - - case FIELD_DROPDOWN: - $field_value = (int) $field_value; - - // retrieve option lang data if necessary - if (!isset($this->options_lang[$field_data['field_id']]) || !isset($this->options_lang[$field_data['field_id']][$field_data['lang_id']]) || !sizeof($this->options_lang[$file_data['field_id']][$field_data['lang_id']])) - { - $this->get_option_lang($field_data['field_id'], $field_data['lang_id'], FIELD_DROPDOWN, false); - } - - if (!isset($this->options_lang[$field_data['field_id']][$field_data['lang_id']][$field_value])) - { - return 'FIELD_INVALID_VALUE'; - } - - if ($field_value == $field_data['field_novalue'] && $field_data['field_required']) - { - return 'FIELD_REQUIRED'; - } - break; - - case FIELD_STRING: - case FIELD_TEXT: - if (trim($field_value) === '' && !$field_data['field_required']) - { - return false; - } - else if (trim($field_value) === '' && $field_data['field_required']) - { - return 'FIELD_REQUIRED'; - } - - if ($field_data['field_minlen'] && utf8_strlen($field_value) < $field_data['field_minlen']) - { - return 'FIELD_TOO_SHORT'; - } - else if ($field_data['field_maxlen'] && utf8_strlen($field_value) > $field_data['field_maxlen']) - { - return 'FIELD_TOO_LONG'; - } - - if (!empty($field_data['field_validation']) && $field_data['field_validation'] != '.*') - { - $field_validate = ($field_type == FIELD_STRING) ? $field_value : bbcode_nl2br($field_value); - if (!preg_match('#^' . str_replace('\\\\', '\\', $field_data['field_validation']) . '$#i', $field_validate)) - { - return 'FIELD_INVALID_CHARS'; - } - } - break; - } - - return false; - } - - /** - * Build profile cache, used for display - * @access private - */ - function build_cache() - { - global $db, $user, $auth; - - $this->profile_cache = array(); - - // Display hidden/no_view fields for admin/moderator - $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f - WHERE l.lang_id = ' . $user->get_iso_lang_id() . ' - AND f.field_active = 1 ' . - ((!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) ? ' AND f.field_hide = 0 ' : '') . ' - AND f.field_no_view = 0 - AND l.field_id = f.field_id - ORDER BY f.field_order'; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $this->profile_cache[$row['field_ident']] = $row; - } - $db->sql_freeresult($result); - } - - /** - * Get language entries for options and store them here for later use - */ - function get_option_lang($field_id, $lang_id, $field_type, $preview) - { - global $db; - - if ($preview) - { - $lang_options = (!is_array($this->vars['lang_options'])) ? explode("\n", $this->vars['lang_options']) : $this->vars['lang_options']; - - foreach ($lang_options as $num => $var) - { - $this->options_lang[$field_id][$lang_id][($num + 1)] = $var; - } - } - else - { - $sql = 'SELECT option_id, lang_value - FROM ' . PROFILE_FIELDS_LANG_TABLE . " - WHERE field_id = $field_id - AND lang_id = $lang_id - AND field_type = $field_type - ORDER BY option_id"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $this->options_lang[$field_id][$lang_id][($row['option_id'] + 1)] = $row['lang_value']; - } - $db->sql_freeresult($result); - } - } - - /** - * Submit profile field for validation - * @access public - */ - function submit_cp_field($mode, $lang_id, &$cp_data, &$cp_error) - { - global $auth, $db, $user; - - $sql_where = ''; - switch ($mode) - { - case 'register': - // If the field is required we show it on the registration page - $sql_where .= ' AND f.field_show_on_reg = 1'; - break; - - case 'profile': - // Show hidden fields to moderators/admins - if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) - { - $sql_where .= ' AND f.field_show_profile = 1'; - } - break; - - default: - trigger_error('Wrong profile mode specified', E_USER_ERROR); - break; - } - - $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . " f - WHERE l.lang_id = $lang_id - AND f.field_active = 1 - $sql_where - AND l.field_id = f.field_id - ORDER BY f.field_order"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $cp_data['pf_' . $row['field_ident']] = $this->get_profile_field($row); - $check_value = $cp_data['pf_' . $row['field_ident']]; - - if (($cp_result = $this->validate_profile_field($row['field_type'], $check_value, $row)) !== false) - { - // If not and only showing common error messages, use this one - $error = ''; - switch ($cp_result) - { - case 'FIELD_INVALID_DATE': - case 'FIELD_INVALID_VALUE': - case 'FIELD_REQUIRED': - $error = $user->lang($cp_result, $row['lang_name']); - break; - - case 'FIELD_TOO_SHORT': - case 'FIELD_TOO_SMALL': - $error = $user->lang($cp_result, (int) $row['field_minlen'], $row['lang_name']); - break; - - case 'FIELD_TOO_LONG': - case 'FIELD_TOO_LARGE': - $error = $user->lang($cp_result, (int) $row['field_maxlen'], $row['lang_name']); - break; - - case 'FIELD_INVALID_CHARS': - switch ($row['field_validation']) - { - case '[0-9]+': - $error = $user->lang($cp_result . '_NUMBERS_ONLY', $row['lang_name']); - break; - - case '[\w]+': - $error = $user->lang($cp_result . '_ALPHA_ONLY', $row['lang_name']); - break; - - case '[\w_\+\. \-\[\]]+': - $error = $user->lang($cp_result . '_SPACERS_ONLY', $row['lang_name']); - break; - } - break; - } - - if ($error != '') - { - $cp_error[] = $error; - } - } - } - $db->sql_freeresult($result); - } - - /** - * Update profile field data directly - */ - function update_profile_field_data($user_id, &$cp_data) - { - global $db; - - if (!sizeof($cp_data)) - { - return; - } - - switch ($db->sql_layer) - { - case 'oracle': - case 'firebird': - case 'postgres': - $right_delim = $left_delim = '"'; - break; - - case 'sqlite': - case 'mssql': - case 'mssql_odbc': - case 'mssqlnative': - $right_delim = ']'; - $left_delim = '['; - break; - - case 'mysql': - case 'mysql4': - case 'mysqli': - $right_delim = $left_delim = '`'; - break; - } - - // use new array for the UPDATE; changes in the key do not affect the original array - $cp_data_sql = array(); - foreach ($cp_data as $key => $value) - { - // Firebird is case sensitive with delimiter - $cp_data_sql[$left_delim . (($db->sql_layer == 'firebird' || $db->sql_layer == 'oracle') ? strtoupper($key) : $key) . $right_delim] = $value; - } - - $sql = 'UPDATE ' . PROFILE_FIELDS_DATA_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $cp_data_sql) . " - WHERE user_id = $user_id"; - $db->sql_query($sql); - - if (!$db->sql_affectedrows()) - { - $cp_data_sql['user_id'] = (int) $user_id; - - $db->sql_return_on_error(true); - - $sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $cp_data_sql); - $db->sql_query($sql); - - $db->sql_return_on_error(false); - } - } - - /** - * Assign fields to template, used for viewprofile, viewtopic and memberlist (if load setting is enabled) - * This is directly connected to the user -> mode == grab is to grab the user specific fields, mode == show is for assigning the row to the template - * @access public - */ - function generate_profile_fields_template($mode, $user_id = 0, $profile_row = false) - { - global $db; - - if ($mode == 'grab') - { - if (!is_array($user_id)) - { - $user_id = array($user_id); - } - - if (!sizeof($this->profile_cache)) - { - $this->build_cache(); - } - - if (!sizeof($user_id)) - { - return array(); - } - - $sql = 'SELECT * - FROM ' . PROFILE_FIELDS_DATA_TABLE . ' - WHERE ' . $db->sql_in_set('user_id', array_map('intval', $user_id)); - $result = $db->sql_query($sql); - - $field_data = array(); - while ($row = $db->sql_fetchrow($result)) - { - $field_data[$row['user_id']] = $row; - } - $db->sql_freeresult($result); - - $user_fields = array(); - - $user_ids = $user_id; - - // Go through the fields in correct order - foreach (array_keys($this->profile_cache) as $used_ident) - { - foreach ($field_data as $user_id => $row) - { - $user_fields[$user_id][$used_ident]['value'] = $row['pf_' . $used_ident]; - $user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident]; - } - - foreach ($user_ids as $user_id) - { - if (!isset($user_fields[$user_id][$used_ident]) && $this->profile_cache[$used_ident]['field_show_novalue']) - { - $user_fields[$user_id][$used_ident]['value'] = ''; - $user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident]; - } - } - } - - return $user_fields; - } - else if ($mode == 'show') - { - // $profile_row == $user_fields[$row['user_id']]; - $tpl_fields = array(); - $tpl_fields['row'] = $tpl_fields['blockrow'] = array(); - - foreach ($profile_row as $ident => $ident_ary) - { - $value = $this->get_profile_value($ident_ary); - - if ($value === NULL) - { - continue; - } - - $tpl_fields['row'] += array( - 'PROFILE_' . strtoupper($ident) . '_VALUE' => $value, - 'PROFILE_' . strtoupper($ident) . '_TYPE' => $ident_ary['data']['field_type'], - 'PROFILE_' . strtoupper($ident) . '_NAME' => $ident_ary['data']['lang_name'], - 'PROFILE_' . strtoupper($ident) . '_EXPLAIN'=> $ident_ary['data']['lang_explain'], - - 'S_PROFILE_' . strtoupper($ident) => true - ); - - $tpl_fields['blockrow'][] = array( - 'PROFILE_FIELD_VALUE' => $value, - 'PROFILE_FIELD_TYPE' => $ident_ary['data']['field_type'], - 'PROFILE_FIELD_NAME' => $ident_ary['data']['lang_name'], - 'PROFILE_FIELD_EXPLAIN' => $ident_ary['data']['lang_explain'], - - 'S_PROFILE_' . strtoupper($ident) => true - ); - } - - return $tpl_fields; - } - else - { - trigger_error('Wrong mode for custom profile', E_USER_ERROR); - } - } - - /** - * Get Profile Value for display - */ - function get_profile_value($ident_ary) - { - $value = $ident_ary['value']; - $field_type = $ident_ary['data']['field_type']; - - switch ($this->profile_types[$field_type]) - { - case 'int': - if ($value === '' && !$ident_ary['data']['field_show_novalue']) - { - return NULL; - } - return (int) $value; - break; - - case 'string': - case 'text': - if (!$value && !$ident_ary['data']['field_show_novalue']) - { - return NULL; - } - - $value = make_clickable($value); - $value = censor_text($value); - $value = bbcode_nl2br($value); - return $value; - break; - - // case 'datetime': - case 'date': - $date = explode('-', $value); - $day = (isset($date[0])) ? (int) $date[0] : 0; - $month = (isset($date[1])) ? (int) $date[1] : 0; - $year = (isset($date[2])) ? (int) $date[2] : 0; - - if (!$day && !$month && !$year && !$ident_ary['data']['field_show_novalue']) - { - return NULL; - } - else if ($day && $month && $year) - { - global $user; - // Date should display as the same date for every user regardless of timezone - - return $user->create_datetime() - ->setDate($year, $month, $day) - ->setTime(0, 0, 0) - ->format($user->lang['DATE_FORMAT'], true); - } - - return $value; - break; - - case 'dropdown': - $field_id = $ident_ary['data']['field_id']; - $lang_id = $ident_ary['data']['lang_id']; - if (!isset($this->options_lang[$field_id][$lang_id])) - { - $this->get_option_lang($field_id, $lang_id, FIELD_DROPDOWN, false); - } - - if ($value == $ident_ary['data']['field_novalue'] && !$ident_ary['data']['field_show_novalue']) - { - return NULL; - } - - $value = (int) $value; - - // User not having a value assigned - if (!isset($this->options_lang[$field_id][$lang_id][$value])) - { - if ($ident_ary['data']['field_show_novalue']) - { - $value = $ident_ary['data']['field_novalue']; - } - else - { - return NULL; - } - } - - return $this->options_lang[$field_id][$lang_id][$value]; - break; - - case 'bool': - $field_id = $ident_ary['data']['field_id']; - $lang_id = $ident_ary['data']['lang_id']; - if (!isset($this->options_lang[$field_id][$lang_id])) - { - $this->get_option_lang($field_id, $lang_id, FIELD_BOOL, false); - } - - if (!$value && $ident_ary['data']['field_show_novalue']) - { - $value = $ident_ary['data']['field_default_value']; - } - - if ($ident_ary['data']['field_length'] == 1) - { - return (isset($this->options_lang[$field_id][$lang_id][(int) $value])) ? $this->options_lang[$field_id][$lang_id][(int) $value] : NULL; - } - else if (!$value) - { - return NULL; - } - else - { - return $this->options_lang[$field_id][$lang_id][(int) ($value) + 1]; - } - break; - - default: - trigger_error('Unknown profile type', E_USER_ERROR); - break; - } - } - - /** - * Get field value for registration/profile - * @access private - */ - function get_var($field_validation, &$profile_row, $default_value, $preview) - { - global $user; - global $request; - - $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; - $user_ident = $profile_row['field_ident']; - // checkbox - set the value to "true" if it has been set to 1 - if ($profile_row['field_type'] == FIELD_BOOL && $profile_row['field_length'] == 2) - { - $value = (isset($_REQUEST[$profile_row['field_ident']]) && request_var($profile_row['field_ident'], $default_value) == 1) ? true : ((!isset($user->profile_fields[$user_ident]) || $preview) ? $default_value : $user->profile_fields[$user_ident]); - } - else if ($profile_row['field_type'] == FIELD_INT) - { - if (isset($_REQUEST[$profile_row['field_ident']])) - { - $value = ($request->variable($profile_row['field_ident'], '') === '') ? NULL : $request->variable($profile_row['field_ident'], $default_value); - } - else - { - if (!$preview && array_key_exists($user_ident, $user->profile_fields) && is_null($user->profile_fields[$user_ident])) - { - $value = NULL; - } - else if (!isset($user->profile_fields[$user_ident]) || $preview) - { - $value = $default_value; - } - else - { - $value = $user->profile_fields[$user_ident]; - } - } - - return (is_null($value) || $value === '') ? '' : (int) $value; - } - else - { - $value = (isset($_REQUEST[$profile_row['field_ident']])) ? request_var($profile_row['field_ident'], $default_value, true) : ((!isset($user->profile_fields[$user_ident]) || $preview) ? $default_value : $user->profile_fields[$user_ident]); - - if (gettype($value) == 'string') - { - $value = utf8_normalize_nfc($value); - } - } - - switch ($field_validation) - { - case 'int': - return (int) $value; - break; - } - - return $value; - } - - /** - * Process int-type - * @access private - */ - function generate_int($profile_row, $preview = false) - { - global $template; - - $profile_row['field_value'] = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - } - - /** - * Process date-type - * @access private - */ - function generate_date($profile_row, $preview = false) - { - global $user, $template; - - $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; - $user_ident = $profile_row['field_ident']; - - $now = getdate(); - - if (!isset($_REQUEST[$profile_row['field_ident'] . '_day'])) - { - if ($profile_row['field_default_value'] == 'now') - { - $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); - } - list($day, $month, $year) = explode('-', ((!isset($user->profile_fields[$user_ident]) || $preview) ? $profile_row['field_default_value'] : $user->profile_fields[$user_ident])); - } - else - { - if ($preview && $profile_row['field_default_value'] == 'now') - { - $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); - list($day, $month, $year) = explode('-', ((!isset($user->profile_fields[$user_ident]) || $preview) ? $profile_row['field_default_value'] : $user->profile_fields[$user_ident])); - } - else - { - $day = request_var($profile_row['field_ident'] . '_day', 0); - $month = request_var($profile_row['field_ident'] . '_month', 0); - $year = request_var($profile_row['field_ident'] . '_year', 0); - } - } - - $profile_row['s_day_options'] = '<option value="0"' . ((!$day) ? ' selected="selected"' : '') . '>--</option>'; - for ($i = 1; $i < 32; $i++) - { - $profile_row['s_day_options'] .= '<option value="' . $i . '"' . (($i == $day) ? ' selected="selected"' : '') . ">$i</option>"; - } - - $profile_row['s_month_options'] = '<option value="0"' . ((!$month) ? ' selected="selected"' : '') . '>--</option>'; - for ($i = 1; $i < 13; $i++) - { - $profile_row['s_month_options'] .= '<option value="' . $i . '"' . (($i == $month) ? ' selected="selected"' : '') . ">$i</option>"; - } - - $profile_row['s_year_options'] = '<option value="0"' . ((!$year) ? ' selected="selected"' : '') . '>--</option>'; - for ($i = $now['year'] - 100; $i <= $now['year'] + 100; $i++) - { - $profile_row['s_year_options'] .= '<option value="' . $i . '"' . (($i == $year) ? ' selected="selected"' : '') . ">$i</option>"; - } - unset($now); - - $profile_row['field_value'] = 0; - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - } - - /** - * Process bool-type - * @access private - */ - function generate_bool($profile_row, $preview = false) - { - global $template; - - $value = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); - - $profile_row['field_value'] = $value; - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - - if ($profile_row['field_length'] == 1) - { - if (!isset($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']]) || !sizeof($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']])) - { - $this->get_option_lang($profile_row['field_id'], $profile_row['lang_id'], FIELD_BOOL, $preview); - } - - foreach ($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']] as $option_id => $option_value) - { - $template->assign_block_vars('bool.options', array( - 'OPTION_ID' => $option_id, - 'CHECKED' => ($value == $option_id) ? ' checked="checked"' : '', - 'VALUE' => $option_value) - ); - } - } - } - - /** - * Process string-type - * @access private - */ - function generate_string($profile_row, $preview = false) - { - global $template; - - $profile_row['field_value'] = $this->get_var('string', $profile_row, $profile_row['lang_default_value'], $preview); - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - } - - /** - * Process text-type - * @access private - */ - function generate_text($profile_row, $preview = false) - { - global $template; - global $user, $phpEx, $phpbb_root_path; - - $field_length = explode('|', $profile_row['field_length']); - $profile_row['field_rows'] = $field_length[0]; - $profile_row['field_cols'] = $field_length[1]; - - $profile_row['field_value'] = $this->get_var('string', $profile_row, $profile_row['lang_default_value'], $preview); - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - } - - /** - * Process dropdown-type - * @access private - */ - function generate_dropdown($profile_row, $preview = false) - { - global $user, $template; - - $value = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); - - if (!isset($this->options_lang[$profile_row['field_id']]) || !isset($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']]) || !sizeof($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']])) - { - $this->get_option_lang($profile_row['field_id'], $profile_row['lang_id'], FIELD_DROPDOWN, $preview); - } - - $profile_row['field_value'] = $value; - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - - foreach ($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']] as $option_id => $option_value) - { - $template->assign_block_vars('dropdown.options', array( - 'OPTION_ID' => $option_id, - 'SELECTED' => ($value == $option_id) ? ' selected="selected"' : '', - 'VALUE' => $option_value) - ); - } - } - - /** - * Return Templated value/field. Possible values for $mode are: - * change == user is able to set/enter profile values; preview == just show the value - * @access private - */ - function process_field_row($mode, $profile_row) - { - global $template; - - $preview = ($mode == 'preview') ? true : false; - - // set template filename - $template->set_filenames(array( - 'cp_body' => 'custom_profile_fields.html') - ); - - // empty previously filled blockvars - foreach ($this->profile_types as $field_case => $field_type) - { - $template->destroy_block_vars($field_type); - } - - // Assign template variables - $type_func = 'generate_' . $this->profile_types[$profile_row['field_type']]; - $this->$type_func($profile_row, $preview); - - // Return templated data - return $template->assign_display('cp_body'); - } - - /** - * Build Array for user insertion into custom profile fields table - */ - function build_insert_sql_array($cp_data) - { - global $db, $user, $auth; - - $sql_not_in = array(); - foreach ($cp_data as $key => $null) - { - $sql_not_in[] = (strncmp($key, 'pf_', 3) === 0) ? substr($key, 3) : $key; - } - - $sql = 'SELECT f.field_type, f.field_ident, f.field_default_value, l.lang_default_value - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f - WHERE l.lang_id = ' . $user->get_iso_lang_id() . ' - ' . ((sizeof($sql_not_in)) ? ' AND ' . $db->sql_in_set('f.field_ident', $sql_not_in, true) : '') . ' - AND l.field_id = f.field_id'; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - if ($row['field_default_value'] == 'now' && $row['field_type'] == FIELD_DATE) - { - $now = getdate(); - $row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); - } - else if ($row['field_default_value'] === '' && $row['field_type'] == FIELD_INT) - { - // We cannot insert an empty string into an integer column. - $row['field_default_value'] = NULL; - } - - $cp_data['pf_' . $row['field_ident']] = (in_array($row['field_type'], array(FIELD_TEXT, FIELD_STRING))) ? $row['lang_default_value'] : $row['field_default_value']; - } - $db->sql_freeresult($result); - - return $cp_data; - } - - /** - * Get profile field value on submit - * @access private - */ - function get_profile_field($profile_row) - { - global $phpbb_root_path, $phpEx; - global $config; - global $request; - - $var_name = 'pf_' . $profile_row['field_ident']; - - switch ($profile_row['field_type']) - { - case FIELD_DATE: - - if (!isset($_REQUEST[$var_name . '_day'])) - { - if ($profile_row['field_default_value'] == 'now') - { - $now = getdate(); - $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); - } - list($day, $month, $year) = explode('-', $profile_row['field_default_value']); - } - else - { - $day = request_var($var_name . '_day', 0); - $month = request_var($var_name . '_month', 0); - $year = request_var($var_name . '_year', 0); - } - - $var = sprintf('%2d-%2d-%4d', $day, $month, $year); - break; - - case FIELD_BOOL: - // Checkbox - if ($profile_row['field_length'] == 2) - { - $var = (isset($_REQUEST[$var_name])) ? 1 : 0; - } - else - { - $var = request_var($var_name, (int) $profile_row['field_default_value']); - } - break; - - case FIELD_STRING: - case FIELD_TEXT: - $var = utf8_normalize_nfc(request_var($var_name, (string) $profile_row['field_default_value'], true)); - break; - - case FIELD_INT: - if (isset($_REQUEST[$var_name]) && $request->variable($var_name, '') === '') - { - $var = NULL; - } - else - { - $var = request_var($var_name, (int) $profile_row['field_default_value']); - } - break; - - case FIELD_DROPDOWN: - $var = request_var($var_name, (int) $profile_row['field_default_value']); - break; - - default: - $var = request_var($var_name, $profile_row['field_default_value']); - break; - } - - return $var; - } -} - -/** -* Custom Profile Fields ACP -* @package phpBB3 -*/ -class custom_profile_admin extends custom_profile -{ - var $vars = array(); - - /** - * Return possible validation options - */ - function validate_options() - { - global $user; - - $validate_ary = array('CHARS_ANY' => '.*', 'NUMBERS_ONLY' => '[0-9]+', 'ALPHA_ONLY' => '[\w]+', 'ALPHA_SPACERS' => '[\w_\+\. \-\[\]]+'); - - $validate_options = ''; - foreach ($validate_ary as $lang => $value) - { - $selected = ($this->vars['field_validation'] == $value) ? ' selected="selected"' : ''; - $validate_options .= '<option value="' . $value . '"' . $selected . '>' . $user->lang[$lang] . '</option>'; - } - - return $validate_options; - } - - /** - * Get string options for second step in ACP - */ - function get_string_options() - { - global $user; - - $options = array( - 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'), - 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'), - 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" size="5" value="' . $this->vars['field_maxlen'] . '" />'), - 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options() . '</select>') - ); - - return $options; - } - - /** - * Get text options for second step in ACP - */ - function get_text_options() - { - global $user; - - $options = array( - 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" max="99999" name="rows" size="5" value="' . $this->vars['rows'] . '" /> ' . $user->lang['ROWS'] . '</dd><dd><input type="number" min="0" max="99999" name="columns" size="5" value="' . $this->vars['columns'] . '" /> ' . $user->lang['COLUMNS'] . ' <input type="hidden" name="field_length" value="' . $this->vars['field_length'] . '" />'), - 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" max="9999999999" name="field_minlen" size="10" value="' . $this->vars['field_minlen'] . '" />'), - 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" max="9999999999" name="field_maxlen" size="10" value="' . $this->vars['field_maxlen'] . '" />'), - 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options() . '</select>') - ); - - return $options; - } - - /** - * Get int options for second step in ACP - */ - function get_int_options() - { - global $user; - - $options = array( - 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'), - 1 => array('TITLE' => $user->lang['MIN_FIELD_NUMBER'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'), - 2 => array('TITLE' => $user->lang['MAX_FIELD_NUMBER'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_maxlen" size="5" value="' . $this->vars['field_maxlen'] . '" />'), - 3 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => '<input type="post" name="field_default_value" value="' . $this->vars['field_default_value'] . '" />') - ); - - return $options; - } - - /** - * Get bool options for second step in ACP - */ - function get_bool_options() - { - global $user, $config, $lang_defs; - - $default_lang_id = $lang_defs['iso'][$config['default_lang']]; - - $profile_row = array( - 'var_name' => 'field_default_value', - 'field_id' => 1, - 'lang_name' => $this->vars['lang_name'], - 'lang_explain' => $this->vars['lang_explain'], - 'lang_id' => $default_lang_id, - 'field_default_value' => $this->vars['field_default_value'], - 'field_ident' => 'field_default_value', - 'field_type' => FIELD_BOOL, - 'field_length' => $this->vars['field_length'], - 'lang_options' => $this->vars['lang_options'] - ); - - $options = array( - 0 => array('TITLE' => $user->lang['FIELD_TYPE'], 'EXPLAIN' => $user->lang['BOOL_TYPE_EXPLAIN'], 'FIELD' => '<label><input type="radio" class="radio" name="field_length" value="1"' . (($this->vars['field_length'] == 1) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['RADIO_BUTTONS'] . '</label><label><input type="radio" class="radio" name="field_length" value="2"' . (($this->vars['field_length'] == 2) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['CHECKBOX'] . '</label>'), - 1 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row)) - ); - - return $options; - } - - /** - * Get dropdown options for second step in ACP - */ - function get_dropdown_options() - { - global $user, $config, $lang_defs; - - $default_lang_id = $lang_defs['iso'][$config['default_lang']]; - - $profile_row[0] = array( - 'var_name' => 'field_default_value', - 'field_id' => 1, - 'lang_name' => $this->vars['lang_name'], - 'lang_explain' => $this->vars['lang_explain'], - 'lang_id' => $default_lang_id, - 'field_default_value' => $this->vars['field_default_value'], - 'field_ident' => 'field_default_value', - 'field_type' => FIELD_DROPDOWN, - 'lang_options' => $this->vars['lang_options'] - ); - - $profile_row[1] = $profile_row[0]; - $profile_row[1]['var_name'] = 'field_novalue'; - $profile_row[1]['field_ident'] = 'field_novalue'; - $profile_row[1]['field_default_value'] = $this->vars['field_novalue']; - - $options = array( - 0 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row[0])), - 1 => array('TITLE' => $user->lang['NO_VALUE_OPTION'], 'EXPLAIN' => $user->lang['NO_VALUE_OPTION_EXPLAIN'], 'FIELD' => $this->process_field_row('preview', $profile_row[1])) - ); - - return $options; - } - - /** - * Get date options for second step in ACP - */ - function get_date_options() - { - global $user, $config, $lang_defs; - - $default_lang_id = $lang_defs['iso'][$config['default_lang']]; - - $profile_row = array( - 'var_name' => 'field_default_value', - 'lang_name' => $this->vars['lang_name'], - 'lang_explain' => $this->vars['lang_explain'], - 'lang_id' => $default_lang_id, - 'field_default_value' => $this->vars['field_default_value'], - 'field_ident' => 'field_default_value', - 'field_type' => FIELD_DATE, - 'field_length' => $this->vars['field_length'] - ); - - $always_now = request_var('always_now', -1); - if ($always_now == -1) - { - $s_checked = ($this->vars['field_default_value'] == 'now') ? true : false; - } - else - { - $s_checked = ($always_now) ? true : false; - } - - $options = array( - 0 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row)), - 1 => array('TITLE' => $user->lang['ALWAYS_TODAY'], 'FIELD' => '<label><input type="radio" class="radio" name="always_now" value="1"' . (($s_checked) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['YES'] . '</label><label><input type="radio" class="radio" name="always_now" value="0"' . ((!$s_checked) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['NO'] . '</label>'), - ); - - return $options; - } -} diff --git a/phpBB/includes/functions_transfer.php b/phpBB/includes/functions_transfer.php index 07c9171c60..17b458d2cb 100644 --- a/phpBB/includes/functions_transfer.php +++ b/phpBB/includes/functions_transfer.php @@ -234,7 +234,7 @@ class transfer /** * Determine methods able to be used */ - function methods() + static public function methods() { $methods = array(); $disabled_functions = explode(',', @ini_get('disable_functions')); @@ -279,7 +279,7 @@ class ftp extends transfer } // Init some needed values - transfer::transfer(); + $this->transfer(); return; } @@ -287,7 +287,7 @@ class ftp extends transfer /** * Requests data */ - function data() + static public function data() { global $user; @@ -533,7 +533,7 @@ class ftp_fsock extends transfer } // Init some needed values - transfer::transfer(); + $this->transfer(); return; } @@ -541,7 +541,7 @@ class ftp_fsock extends transfer /** * Requests data */ - function data() + static public function data() { global $user; diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index 4181896eca..b4e165502b 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -44,10 +44,16 @@ class filespec var $upload = ''; /** + * The plupload object + * @var \phpbb\plupload\plupload + */ + protected $plupload; + + /** * File Class * @access private */ - function filespec($upload_ary, $upload_namespace) + function filespec($upload_ary, $upload_namespace, \phpbb\plupload\plupload $plupload = null) { if (!isset($upload_ary)) { @@ -58,7 +64,7 @@ class filespec $this->filename = $upload_ary['tmp_name']; $this->filesize = $upload_ary['size']; $name = (STRIP) ? stripslashes($upload_ary['name']) : $upload_ary['name']; - $name = trim(utf8_htmlspecialchars(utf8_basename($name))); + $name = trim(utf8_basename($name)); $this->realname = $this->uploadname = $name; $this->mimetype = $upload_ary['type']; @@ -80,6 +86,7 @@ class filespec $this->local = (isset($upload_ary['local_mode'])) ? true : false; $this->upload = $upload_namespace; + $this->plupload = $plupload; } /** @@ -161,12 +168,14 @@ class filespec */ function is_uploaded() { - if (!$this->local && !is_uploaded_file($this->filename)) + $is_plupload = $this->plupload && $this->plupload->is_active(); + + if (!$this->local && !$is_plupload && !is_uploaded_file($this->filename)) { return false; } - if ($this->local && !file_exists($this->filename)) + if (($this->local || $is_plupload) && !file_exists($this->filename)) { return false; } @@ -466,7 +475,7 @@ class fileerror extends filespec class fileupload { var $allowed_extensions = array(); - var $disallowed_content = array('body', 'head', 'html', 'img', 'plaintext', 'a href', 'pre', 'script', 'table', 'title'); + var $disallowed_content = array('body', 'head', 'html', 'img', 'plaintext', 'a href', 'pre', 'script', 'table', 'title'); var $max_filesize = 0; var $min_width = 0; var $min_height = 0; @@ -564,16 +573,28 @@ class fileupload * Upload file from users harddisk * * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) + * @param \phpbb\plupload\plupload $plupload The plupload object + * * @return object $file Object "filespec" is returned, all further operations can be done with this object * @access public */ - function form_upload($form_name) + function form_upload($form_name, \phpbb\plupload\plupload $plupload = null) { global $user, $request; $upload = $request->file($form_name); unset($upload['local_mode']); - $file = new filespec($upload, $this); + + if ($plupload) + { + $result = $plupload->handle_upload($form_name); + if (is_array($result)) + { + $upload = array_merge($upload, $result); + } + } + + $file = new filespec($upload, $this, $plupload); if ($file->init_error) { diff --git a/phpBB/includes/functions_url_matcher.php b/phpBB/includes/functions_url_matcher.php index fdde302e3b..8e5ae20f93 100644 --- a/phpBB/includes/functions_url_matcher.php +++ b/phpBB/includes/functions_url_matcher.php @@ -32,7 +32,7 @@ function phpbb_get_url_matcher(\phpbb\extension\finder $finder, RequestContext $ { if (defined('DEBUG')) { - return phpbb_create_url_matcher($finder, $context); + return phpbb_create_url_matcher($finder, $context, $root_path); } if (!phpbb_url_matcher_dumped($root_path, $php_ext)) @@ -53,8 +53,8 @@ function phpbb_get_url_matcher(\phpbb\extension\finder $finder, RequestContext $ */ function phpbb_create_dumped_url_matcher(\phpbb\extension\finder $finder, $root_path, $php_ext) { - $provider = new \phpbb\controller\provider(); - $routes = $provider->import_paths_from_finder($finder)->find(); + $provider = new \phpbb\controller\provider($finder); + $routes = $provider->find($root_path)->get_routes(); $dumper = new PhpMatcherDumper($routes); $cached_url_matcher_dump = $dumper->dump(array( 'class' => 'phpbb_url_matcher', @@ -70,10 +70,10 @@ function phpbb_create_dumped_url_matcher(\phpbb\extension\finder $finder, $root_ * @param RequestContext $context Symfony RequestContext object * @return UrlMatcher */ -function phpbb_create_url_matcher(\phpbb\extension\finder $finder, RequestContext $context) +function phpbb_create_url_matcher(\phpbb\extension\finder $finder, RequestContext $context, $root_path) { - $provider = new \phpbb\controller\provider(); - $routes = $provider->import_paths_from_finder($finder)->find(); + $provider = new \phpbb\controller\provider($finder); + $routes = $provider->find($root_path)->get_routes(); return new UrlMatcher($routes, $context); } diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 0a0656377c..dcc0d727a1 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -143,7 +143,7 @@ function user_update_name($old_name, $new_name) * @event core.update_username * @var string old_name The old username that is replaced * @var string new_name The new username - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('old_name', 'new_name'); extract($phpbb_dispatcher->trigger_event('core.update_username', compact($vars))); @@ -162,7 +162,7 @@ function user_update_name($old_name, $new_name) function user_add($user_row, $cp_data = false) { global $db, $user, $auth, $config, $phpbb_root_path, $phpEx; - global $phpbb_dispatcher; + global $phpbb_dispatcher, $phpbb_container; if (empty($user_row['username']) || !isset($user_row['group_id']) || !isset($user_row['user_email']) || !isset($user_row['user_type'])) { @@ -210,10 +210,8 @@ function user_add($user_row, $cp_data = false) 'user_lastpage' => '', 'user_posts' => 0, 'user_colour' => '', - 'user_occ' => '', - 'user_interests' => '', 'user_avatar' => '', - 'user_avatar_type' => 0, + 'user_avatar_type' => '', 'user_avatar_width' => 0, 'user_avatar_height' => 0, 'user_new_privmsg' => 0, @@ -261,7 +259,7 @@ function user_add($user_row, $cp_data = false) * * @event core.user_add_modify_data * @var array sql_ary Array of data to be inserted when a user is added - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('sql_ary'); extract($phpbb_dispatcher->trigger_event('core.user_add_modify_data', compact($vars))); @@ -276,13 +274,9 @@ function user_add($user_row, $cp_data = false) { $cp_data['user_id'] = (int) $user_id; - if (!class_exists('custom_profile')) - { - include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - } - + $cp = $phpbb_container->get('profilefields.manager'); $sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . - $db->sql_build_array('INSERT', custom_profile::build_insert_sql_array($cp_data)); + $db->sql_build_array('INSERT', $cp->build_insert_sql_array($cp_data)); $db->sql_query($sql); } @@ -392,7 +386,7 @@ function user_delete($mode, $user_ids, $retain_username = true) * @var array user_ids IDs of the deleted user * @var mixed retain_username True if username should be retained * or false if not - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('mode', 'user_ids', 'retain_username'); extract($phpbb_dispatcher->trigger_event('core.delete_user_before', compact($vars))); @@ -463,7 +457,7 @@ function user_delete($mode, $user_ids, $retain_username = true) $added_guest_posts = 0; foreach ($user_rows as $user_id => $user_row) { - if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == AVATAR_UPLOAD) + if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == 'avatar.driver.upload') { avatar_delete('user', $user_row); } @@ -621,7 +615,7 @@ function user_delete($mode, $user_ids, $retain_username = true) * @var array user_ids IDs of the deleted user * @var mixed retain_username True if username should be retained * or false if not - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('mode', 'user_ids', 'retain_username'); extract($phpbb_dispatcher->trigger_event('core.delete_user_after', compact($vars))); @@ -1332,9 +1326,18 @@ function validate_data($data, $val_ary) { $function = array_shift($validate); array_unshift($validate, $data[$var]); - $function_prefix = (function_exists('phpbb_validate_' . $function)) ? 'phpbb_validate_' : 'validate_'; - if ($result = call_user_func_array($function_prefix . $function, $validate)) + if (is_array($function)) + { + $result = call_user_func_array(array($function[0], 'validate_' . $function[1]), $validate); + } + else + { + $function_prefix = (function_exists('phpbb_validate_' . $function)) ? 'phpbb_validate_' : 'validate_'; + $result = call_user_func_array($function_prefix . $function, $validate); + } + + if ($result) { // Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted. $error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var); @@ -2083,7 +2086,6 @@ function get_avatar_filename($avatar_entry) { global $config; - if ($avatar_entry[0] === 'g') { $avatar_group = true; @@ -2314,7 +2316,7 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow { $group_id = $db->sql_nextid(); - if (isset($sql_ary['group_avatar_type']) && $sql_ary['group_avatar_type'] == AVATAR_UPLOAD) + if (isset($sql_ary['group_avatar_type']) && $sql_ary['group_avatar_type'] == 'avatar.driver.upload') { group_correct_avatar($group_id, $sql_ary['group_avatar']); } @@ -2415,7 +2417,7 @@ function avatar_remove_db($avatar_name) $sql = 'UPDATE ' . USERS_TABLE . " SET user_avatar = '', - user_avatar_type = 0 + user_avatar_type = '' WHERE user_avatar = '" . $db->sql_escape($avatar_name) . '\''; $db->sql_query($sql); } @@ -2510,7 +2512,7 @@ function group_delete($group_id, $group_name = false) * @event core.delete_group_after * @var int group_id ID of the deleted group * @var string group_name Name of the deleted group - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('group_id', 'group_name'); extract($phpbb_dispatcher->trigger_event('core.delete_group_after', compact($vars))); @@ -2754,11 +2756,11 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false, * Event before users are removed from a group * * @event core.group_delete_user_before - * @var int group_id ID of the group from which users are deleted - * @var string group_name Name of the group + * @var int group_id ID of the group from which users are deleted + * @var string group_name Name of the group * @var array user_id_ary IDs of the users which are removed * @var array username_ary names of the users which are removed - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('group_id', 'group_name', 'user_id_ary', 'username_ary'); extract($phpbb_dispatcher->trigger_event('core.group_delete_user_before', compact($vars))); @@ -2825,7 +2827,7 @@ function remove_default_avatar($group_id, $user_ids) $sql = 'UPDATE ' . USERS_TABLE . " SET user_avatar = '', - user_avatar_type = 0, + user_avatar_type = '', user_avatar_width = 0, user_avatar_height = 0 WHERE group_id = " . (int) $group_id . " @@ -3083,7 +3085,7 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal 'group_colour' => 'string', 'group_rank' => 'int', 'group_avatar' => 'string', - 'group_avatar_type' => 'int', + 'group_avatar_type' => 'string', 'group_avatar_width' => 'int', 'group_avatar_height' => 'int', ); @@ -3204,7 +3206,7 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal * @var array group_attributes Group attributes which were changed * @var array update_listing Update the list of moderators and foes * @var array sql_ary User attributes which were changed - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('group_id', 'user_id_ary', 'group_attributes', 'update_listing', 'sql_ary'); extract($phpbb_dispatcher->trigger_event('core.user_set_default_group', compact($vars))); diff --git a/phpBB/includes/mcp/info/mcp_pm_reports.php b/phpBB/includes/mcp/info/mcp_pm_reports.php index 07dc564b19..d530a917cb 100644 --- a/phpBB/includes/mcp/info/mcp_pm_reports.php +++ b/phpBB/includes/mcp/info/mcp_pm_reports.php @@ -19,7 +19,7 @@ class mcp_pm_reports_info 'title' => 'MCP_PM_REPORTS', 'version' => '1.0.0', 'modes' => array( - 'pm_reports' => array('title' => 'MCP_PM_REPORTS_OPEN', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')), + 'pm_reports' => array('title' => 'MCP_PM_REPORTS_OPEN', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')), 'pm_reports_closed' => array('title' => 'MCP_PM_REPORTS_CLOSED', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')), 'pm_report_details' => array('title' => 'MCP_PM_REPORT_DETAILS', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')), ), diff --git a/phpBB/includes/mcp/mcp_ban.php b/phpBB/includes/mcp/mcp_ban.php index d3bc336293..925d0878fc 100644 --- a/phpBB/includes/mcp/mcp_ban.php +++ b/phpBB/includes/mcp/mcp_ban.php @@ -171,7 +171,7 @@ class mcp_ban case 'user': $pre_fill = (string) $db->sql_fetchfield('username'); break; - + case 'ip': $pre_fill = (string) $db->sql_fetchfield('user_ip'); break; diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index 6df3320a97..b4f7f4d70a 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -73,6 +73,8 @@ function mcp_forum_view($id, $mode, $action, $forum_info) break; } + $pagination = $phpbb_container->get('pagination'); + $selected_ids = ''; if (sizeof($post_id_list) && $action != 'merge_topics') { @@ -102,7 +104,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $limit_time_sql = ($sort_days) ? 'AND t.topic_last_post_time >= ' . (time() - ($sort_days * 86400)) : ''; $base_url = $url . "&i=$id&action=$action&mode=$mode&sd=$sort_dir&sk=$sort_key&st=$sort_days" . (($merge_select) ? $selected_ids : ''); - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $forum_topics, $topics_per_page, $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $forum_topics, $topics_per_page, $start); $template->assign_vars(array( 'ACTION' => $action, @@ -133,7 +135,6 @@ function mcp_forum_view($id, $mode, $action, $forum_info) 'S_MCP_ACTION' => $url . "&i=$id&forum_action=$action&mode=$mode&start=$start" . (($merge_select) ? $selected_ids : ''), - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $forum_topics, $topics_per_page, $start), 'TOTAL_TOPICS' => $user->lang('VIEW_FORUM_TOPICS', (int) $forum_topics), )); @@ -223,7 +224,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $topic_title = censor_text($row['topic_title']); - $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false; + $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false; $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false; $topic_deleted = $row['topic_visibility'] == ITEM_DELETED; $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? $url . '&i=queue&mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . '&t=' . $row['topic_id'] : ''; @@ -301,7 +302,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) * @event core.mcp_view_forum_modify_topicrow * @var array row Array with topic data * @var array topic_row Template array with topic data - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('row', 'topic_row'); extract($phpbb_dispatcher->trigger_event('core.mcp_view_forum_modify_topicrow', compact($vars))); @@ -450,22 +451,14 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id) // Link to the new topic $return_link .= (($return_link) ? '<br /><br />' : '') . sprintf($user->lang['RETURN_NEW_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $to_forum_id . '&t=' . $to_topic_id) . '">', '</a>'); - } - else - { - confirm_box(false, 'MERGE_TOPICS', $s_hidden_fields); - } - - $redirect = request_var('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id"); - $redirect = reapply_sid($redirect); + $redirect = request_var('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id"); + $redirect = reapply_sid($redirect); - if (!$success_msg) - { - return; + meta_refresh(3, $redirect); + trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); } else { - meta_refresh(3, $redirect); - trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); + confirm_box(false, 'MERGE_TOPICS', $s_hidden_fields); } } diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php index 44cab5d910..aee43c471d 100644 --- a/phpBB/includes/mcp/mcp_front.php +++ b/phpBB/includes/mcp/mcp_front.php @@ -39,7 +39,7 @@ function mcp_front_view($id, $mode, $action) $sql = 'SELECT COUNT(post_id) AS total FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_list) . ' - AND post_visibility = ' . ITEM_UNAPPROVED; + AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)); $result = $db->sql_query($sql); $total = (int) $db->sql_fetchfield('total'); $db->sql_freeresult($result); @@ -60,7 +60,7 @@ function mcp_front_view($id, $mode, $action) $sql = 'SELECT post_id FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_list) . ' - AND post_visibility = ' . ITEM_UNAPPROVED . ' + AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . ' ORDER BY post_time DESC'; $result = $db->sql_query_limit($sql, 5); diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php index f706840492..7bcb0fc477 100644 --- a/phpBB/includes/mcp/mcp_logs.php +++ b/phpBB/includes/mcp/mcp_logs.php @@ -33,7 +33,7 @@ class mcp_logs function main($id, $mode) { global $auth, $db, $user, $template; - global $config, $phpbb_root_path, $phpEx; + global $config, $phpbb_root_path, $phpEx, $phpbb_container; $user->add_lang('acp/common'); @@ -62,6 +62,8 @@ class mcp_logs $this->tpl_name = 'mcp_logs'; $this->page_title = 'MCP_LOGS'; + $pagination = $phpbb_container->get('pagination'); + $forum_list = array_values(array_intersect(get_forum_list('f_read'), get_forum_list('m_'))); $forum_list[] = 0; @@ -172,10 +174,9 @@ class mcp_logs $start = view_log('mod', $log_data, $log_count, $config['topics_per_page'], $start, $forum_list, $topic_id, 0, $sql_where, $sql_sort, $keywords); $base_url = $this->u_action . "&$u_sort_param$keywords_param"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start), 'TOTAL' => $user->lang('TOTAL_LOGS', (int) $log_count), 'L_TITLE' => $user->lang['MCP_LOGS'], diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 4f27d32a5a..6b2e9266b3 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -34,6 +34,7 @@ class mcp_main { global $auth, $db, $user, $template, $action; global $config, $phpbb_root_path, $phpEx, $request; + global $phpbb_dispatcher; $quickmod = ($mode == 'quickmod') ? true : false; @@ -151,6 +152,16 @@ class mcp_main mcp_restore_topic($topic_ids); break; + + default: + /** + * This event allows you to handle custom quickmod options + * + * @event core.modify_quickmod_actions + * @since 3.1.0-a4 + */ + $phpbb_dispatcher->dispatch('core.modify_quickmod_actions'); + break; } switch ($mode) @@ -219,7 +230,7 @@ class mcp_main */ function lock_unlock($action, $ids) { - global $auth, $user, $db, $phpEx, $phpbb_root_path; + global $auth, $user, $db, $phpEx, $phpbb_root_path, $request; if ($action == 'lock' || $action == 'unlock') { @@ -256,6 +267,7 @@ function lock_unlock($action, $ids) unset($orig_ids); $redirect = request_var('redirect', build_url(array('action', 'quickmod'))); + $redirect = reapply_sid($redirect); $s_hidden_fields = build_hidden_fields(array( $sql_id . '_list' => $ids, @@ -279,24 +291,22 @@ function lock_unlock($action, $ids) } $success_msg = $l_prefix . ((sizeof($ids) == 1) ? '' : 'S') . '_' . (($action == 'lock' || $action == 'lock_post') ? 'LOCKED' : 'UNLOCKED') . '_SUCCESS'; - } - else - { - confirm_box(false, strtoupper($action) . '_' . $l_prefix . ((sizeof($ids) == 1) ? '' : 'S'), $s_hidden_fields); - } - $redirect = request_var('redirect', "index.$phpEx"); - $redirect = reapply_sid($redirect); + meta_refresh(2, $redirect); + $message = $user->lang[$success_msg]; - if (!$success_msg) - { - redirect($redirect); + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>'); + } + trigger_error($message); } else { - meta_refresh(2, $redirect); - trigger_error($user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>')); + confirm_box(false, strtoupper($action) . '_' . $l_prefix . ((sizeof($ids) == 1) ? '' : 'S'), $s_hidden_fields); } + + redirect($redirect); } /** @@ -304,7 +314,7 @@ function lock_unlock($action, $ids) */ function change_topic_type($action, $topic_ids) { - global $auth, $user, $db, $phpEx, $phpbb_root_path; + global $auth, $user, $db, $phpEx, $phpbb_root_path, $request; switch ($action) { @@ -341,6 +351,7 @@ function change_topic_type($action, $topic_ids) } $redirect = request_var('redirect', build_url(array('action', 'quickmod'))); + $redirect = reapply_sid($redirect); $s_hidden_fields = array( 'topic_id_list' => $topic_ids, @@ -381,24 +392,22 @@ function change_topic_type($action, $topic_ids) add_log('mod', $forum_id, $topic_id, 'LOG_TOPIC_TYPE_CHANGED', $row['topic_title']); } } - } - else - { - confirm_box(false, $l_new_type, build_hidden_fields($s_hidden_fields)); - } - $redirect = request_var('redirect', "index.$phpEx"); - $redirect = reapply_sid($redirect); + meta_refresh(2, $redirect); + $message = $user->lang[$success_msg]; - if (!$success_msg) - { - redirect($redirect); + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>'); + } + trigger_error($message); } else { - meta_refresh(2, $redirect); - trigger_error($user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>')); + confirm_box(false, $l_new_type, build_hidden_fields($s_hidden_fields)); } + + redirect($redirect); } /** @@ -406,9 +415,8 @@ function change_topic_type($action, $topic_ids) */ function mcp_move_topic($topic_ids) { - global $auth, $user, $db, $template; + global $auth, $user, $db, $template, $phpbb_log, $request; global $phpEx, $phpbb_root_path; - global $request; // Here we limit the operation to one forum only $forum_id = check_ids($topic_ids, TOPICS_TABLE, 'topic_id', array('m_move'), true); @@ -485,7 +493,7 @@ function mcp_move_topic($topic_ids) { $topics_moved++; } - elseif ($topic_info['topic_visibility'] == ITEM_UNAPPROVED) + elseif ($topic_info['topic_visibility'] == ITEM_UNAPPROVED || $topic_info['topic_visibility'] == ITEM_REAPPROVE) { $topics_moved_unapproved++; } @@ -516,9 +524,19 @@ function mcp_move_topic($topic_ids) $forum_ids = array($to_forum_id); foreach ($topic_data as $topic_id => $row) { - // Get the list of forums to resync, add a log entry + // Get the list of forums to resync $forum_ids[] = $row['forum_id']; - add_log('mod', $to_forum_id, $topic_id, 'LOG_MOVE', $row['forum_name'], $forum_data['forum_name']); + + // We add the $to_forum_id twice, because 'forum_id' is updated + // when the topic is moved again later. + $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_MOVE', false, array( + 'forum_id' => (int) $to_forum_id, + 'topic_id' => (int) $topic_id, + $row['forum_name'], + $forum_data['forum_name'], + (int) $row['forum_id'], + (int) $forum_data['forum_id'], + )); // Leave a redirection if required and only if the topic is visible to users if ($leave_shadow && $row['topic_visibility'] == ITEM_APPROVED && $row['topic_type'] != POST_GLOBAL) @@ -921,7 +939,7 @@ function mcp_delete_post($post_ids, $is_soft = false, $soft_delete_reason = '', // None of the topics is really deleted, so a redirect won't hurt much. $deleted_topics = 0; - $success_msg = (sizeof($post_info) == 1) ? 'POST_DELETED_SUCCESS' : 'POSTS_DELETED_SUCCESS'; + $success_msg = (sizeof($post_info) == 1) ? $user->lang['POST_DELETED_SUCCESS'] : $user->lang['POSTS_DELETED_SUCCESS']; foreach ($approve_log as $row) { @@ -1212,6 +1230,7 @@ function mcp_fork_topic($topic_ids) $total_topics++; break; case ITEM_UNAPPROVED: + case ITEM_REAPPROVE: $total_topics_unapproved++; break; case ITEM_DELETED: @@ -1298,6 +1317,7 @@ function mcp_fork_topic($topic_ids) $total_posts++; break; case ITEM_UNAPPROVED: + case ITEM_REAPPROVE: $total_posts_unapproved++; break; case ITEM_DELETED: diff --git a/phpBB/includes/mcp/mcp_notes.php b/phpBB/includes/mcp/mcp_notes.php index 12fcbfe91e..be8e09b0c3 100644 --- a/phpBB/includes/mcp/mcp_notes.php +++ b/phpBB/includes/mcp/mcp_notes.php @@ -72,7 +72,7 @@ class mcp_notes function mcp_notes_user_view($action) { global $phpEx, $phpbb_root_path, $config; - global $template, $db, $user, $auth; + global $template, $db, $user, $auth, $phpbb_container; $user_id = request_var('u', 0); $username = request_var('username', '', true); @@ -80,6 +80,7 @@ class mcp_notes $st = request_var('st', 0); $sk = request_var('sk', 'b'); $sd = request_var('sd', 'd'); + $pagination = $phpbb_container->get('pagination'); add_form_key('mcp_notes'); @@ -173,10 +174,6 @@ class mcp_notes } // Generate the appropriate user information for the user we are looking at - if (!function_exists('phpbb_get_user_avatar')) - { - include($phpbb_root_path . 'includes/functions_display.' . $phpEx); - } $rank_title = $rank_img = ''; $avatar_img = phpbb_get_user_avatar($userrow); @@ -216,7 +213,7 @@ class mcp_notes } $base_url = $this->u_action . "&$u_sort_param$keywords_param"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); $template->assign_vars(array( 'U_POST_ACTION' => $this->u_action, @@ -228,7 +225,6 @@ class mcp_notes 'L_TITLE' => $user->lang['MCP_NOTES_USER'], - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start), 'TOTAL_REPORTS' => $user->lang('LIST_REPORTS', (int) $log_count), 'RANK_TITLE' => $rank_title, diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php index f0452b37a5..b0a06dd6ce 100644 --- a/phpBB/includes/mcp/mcp_pm_reports.php +++ b/phpBB/includes/mcp/mcp_pm_reports.php @@ -39,6 +39,7 @@ class mcp_pm_reports include_once($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx); $start = request_var('start', 0); + $pagination = $phpbb_container->get('pagination'); $this->page_title = 'MCP_PM_REPORTS'; @@ -169,7 +170,7 @@ class mcp_pm_reports 'U_MCP_USER_NOTES' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes&u=' . $pm_info['author_id']), 'U_MCP_WARN_REPORTER' => ($auth->acl_get('m_warn')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&mode=warn_user&u=' . $report['user_id']) : '', 'U_MCP_WARN_USER' => ($auth->acl_get('m_warn')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&mode=warn_user&u=' . $pm_info['author_id']) : '', - + 'EDIT_IMG' => $user->img('icon_post_edit', $user->lang['EDIT_POST']), 'MINI_POST_IMG' => $user->img('icon_post_target', 'POST'), @@ -297,18 +298,17 @@ class mcp_pm_reports } $base_url = $this->u_action . "&st=$sort_days&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); // Now display the page $template->assign_vars(array( 'L_EXPLAIN' => ($mode == 'pm_reports') ? $user->lang['MCP_PM_REPORTS_OPEN_EXPLAIN'] : $user->lang['MCP_PM_REPORTS_CLOSED_EXPLAIN'], 'L_TITLE' => ($mode == 'pm_reports') ? $user->lang['MCP_PM_REPORTS_OPEN'] : $user->lang['MCP_PM_REPORTS_CLOSED'], - + 'S_PM' => true, 'S_MCP_ACTION' => $this->u_action, 'S_CLOSED' => ($mode == 'pm_reports_closed') ? true : false, - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $total, $config['topics_per_page'], $start), 'TOTAL' => $total, 'TOTAL_REPORTS' => $user->lang('LIST_REPORTS', (int) $total), ) diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php index 06f27655ae..5925575577 100644 --- a/phpBB/includes/mcp/mcp_post.php +++ b/phpBB/includes/mcp/mcp_post.php @@ -203,7 +203,7 @@ function mcp_post_details($id, $mode, $action) 'S_CAN_DELETE_POST' => $auth->acl_get('m_delete', $post_info['forum_id']), 'S_POST_REPORTED' => ($post_info['post_reported']) ? true : false, - 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED) ? true : false, + 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE) ? true : false, 'S_POST_DELETED' => ($post_info['post_visibility'] == ITEM_DELETED) ? true : false, 'S_POST_LOCKED' => ($post_info['post_edit_locked']) ? true : false, 'S_USER_NOTES' => true, @@ -294,8 +294,8 @@ function mcp_post_details($id, $mode, $action) 'REPORT_ID' => $row['report_id'], 'REASON_TITLE' => $row['reason_title'], 'REASON_DESC' => $row['reason_description'], - 'REPORTER' => ($row['user_id'] != ANONYMOUS) ? $row['username'] : $user->lang['GUEST'], - 'U_REPORTER' => ($row['user_id'] != ANONYMOUS) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u=' . $row['user_id']) : '', + 'REPORTER' => get_username_string('username', $row['user_id'], $row['username']), + 'U_REPORTER' => get_username_string('profile', $row['user_id'], $row['username']), 'USER_NOTIFY' => ($row['user_notify']) ? true : false, 'REPORT_TIME' => $user->format_date($row['report_time']), 'REPORT_TEXT' => bbcode_nl2br(trim($row['report_text'])), @@ -354,11 +354,11 @@ function mcp_post_details($id, $mode, $action) foreach ($users_ary as $user_id => $user_row) { $template->assign_block_vars('userrow', array( - 'USERNAME' => ($user_id == ANONYMOUS) ? $user->lang['GUEST'] : $user_row['username'], + 'USERNAME' => get_username_string('username', $user_id, $user_row['username']), 'NUM_POSTS' => $user_row['postings'], 'L_POST_S' => ($user_row['postings'] == 1) ? $user->lang['POST'] : $user->lang['POSTS'], - 'U_PROFILE' => ($user_id == ANONYMOUS) ? '' : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u=' . $user_id), + 'U_PROFILE' => get_username_string('profile', $user_id, $user_row['username']), 'U_SEARCHPOSTS' => append_sid("{$phpbb_root_path}search.$phpEx", 'author_id=' . $user_id . '&sr=topics')) ); } diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index db461d07fa..a71bc997e9 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -115,10 +115,10 @@ class mcp_queue if (!empty($topic_id_list)) { - $post_visibility = ($mode == 'deleted_topics') ? ITEM_DELETED : ITEM_UNAPPROVED; + $post_visibility = ($mode == 'deleted_topics') ? ITEM_DELETED : array(ITEM_UNAPPROVED, ITEM_REAPPROVE); $sql = 'SELECT post_id FROM ' . POSTS_TABLE . ' - WHERE post_visibility = ' . $post_visibility . ' + WHERE ' . $db->sql_in_set('post_visibility', $post_visibility) . ' AND ' . $db->sql_in_set('topic_id', $topic_id_list); $result = $db->sql_query($sql); @@ -281,7 +281,7 @@ class mcp_queue 'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&p=$post_id&f=$forum_id"), 'S_CAN_VIEWIP' => $auth->acl_get('m_info', $post_info['forum_id']), 'S_POST_REPORTED' => $post_info['post_reported'], - 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED), + 'S_POST_UNAPPROVED' => $post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE, 'S_POST_LOCKED' => $post_info['post_edit_locked'], 'S_USER_NOTES' => true, 'S_POST_DELETED' => ($post_info['post_visibility'] == ITEM_DELETED), @@ -298,7 +298,6 @@ class mcp_queue 'MINI_POST_IMG' => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'), - 'RETURN_QUEUE' => sprintf($user->lang['RETURN_QUEUE'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue' . (($topic_id) ? '&mode=unapproved_topics' : '&mode=unapproved_posts')) . '&start=' . $start . '">', '</a>'), 'RETURN_POST' => sprintf($user->lang['RETURN_POST'], '<a href="' . $post_url . '">', '</a>'), 'RETURN_TOPIC_SIMPLE' => sprintf($user->lang['RETURN_TOPIC_SIMPLE'], '<a href="' . $topic_url . '">', '</a>'), @@ -331,12 +330,13 @@ class mcp_queue $m_perm = 'm_approve'; $is_topics = ($mode == 'unapproved_topics' || $mode == 'deleted_topics') ? true : false; $is_restore = ($mode == 'deleted_posts' || $mode == 'deleted_topics') ? true : false; - $visibility_const = (!$is_restore) ? ITEM_UNAPPROVED : ITEM_DELETED; + $visibility_const = (!$is_restore) ? array(ITEM_UNAPPROVED, ITEM_REAPPROVE) : ITEM_DELETED; $user->add_lang(array('viewtopic', 'viewforum')); $topic_id = $request->variable('t', 0); $forum_info = array(); + $pagination = $phpbb_container->get('pagination'); if ($topic_id) { @@ -418,7 +418,7 @@ class mcp_queue $sql = 'SELECT p.post_id FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t' . (($sort_order_sql[0] == 'u') ? ', ' . USERS_TABLE . ' u' : '') . ' WHERE ' . $db->sql_in_set('p.forum_id', $forum_list) . ' - AND p.post_visibility = ' . $visibility_const . ' + AND ' . $db->sql_in_set('p.post_visibility', $visibility_const) . ' ' . (($sort_order_sql[0] == 'u') ? 'AND u.user_id = p.poster_id' : '') . ' ' . (($topic_id) ? 'AND p.topic_id = ' . $topic_id : '') . " AND t.topic_id = p.topic_id @@ -471,7 +471,7 @@ class mcp_queue $sql = 'SELECT t.forum_id, t.topic_id, t.topic_title, t.topic_title AS post_subject, t.topic_time AS post_time, t.topic_poster AS poster_id, t.topic_first_post_id AS post_id, t.topic_attachment AS post_attachment, t.topic_first_poster_name AS username, t.topic_first_poster_colour AS user_colour FROM ' . TOPICS_TABLE . ' t WHERE ' . $db->sql_in_set('forum_id', $forum_list) . ' - AND topic_visibility = ' . $visibility_const . " + AND ' . $db->sql_in_set('topic_visibility', $visibility_const) . " AND topic_delete_user <> 0 $limit_time_sql ORDER BY $sort_order_sql"; @@ -532,7 +532,7 @@ class mcp_queue unset($rowset, $forum_names); $base_url = $this->u_action . "&f=$forum_id&st=$sort_days&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); // Now display the page $template->assign_vars(array( @@ -546,7 +546,6 @@ class mcp_queue 'S_TOPICS' => $is_topics, 'S_RESTORE' => $is_restore, - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $total, $config['topics_per_page'], $start), 'TOPIC_ID' => $topic_id, 'TOTAL' => $user->lang(((!$is_topics) ? 'VIEW_TOPIC_POSTS' : 'VIEW_FORUM_TOPICS'), (int) $total), )); @@ -576,6 +575,7 @@ class mcp_queue } $redirect = $request->variable('redirect', build_url(array('quickmod'))); + $redirect = reapply_sid($redirect); $success_msg = $post_url = ''; $approve_log = array(); @@ -652,13 +652,25 @@ class mcp_queue // Handle notifications foreach ($post_info as $post_id => $post_data) { + // A single topic approval may also happen here, so handle deleting the respective notification. + if (!$post_data['topic_posts_approved']) + { + $phpbb_notifications->delete_notifications('topic_in_queue', $post_data['topic_id']); + } $phpbb_notifications->delete_notifications('post_in_queue', $post_id); - $phpbb_notifications->add_notifications(array( - 'quote', - 'bookmark', - 'post', - ), $post_data); + // Only add notifications, if we are not reapproving post + // When the topic was already approved, but was edited and + // now needs re-approval, we don't want to notify the users + // again. + if ($post_data['post_visibility'] == ITEM_UNAPPROVED) + { + $phpbb_notifications->add_notifications(array( + 'quote', + 'bookmark', + 'post', + ), $post_data); + } $phpbb_notifications->mark_notifications_read(array( 'quote', @@ -678,6 +690,28 @@ class mcp_queue } } } + + meta_refresh(3, $redirect); + $message = $user->lang[$success_msg]; + + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response; + $json_response->send(array( + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $message, + 'REFRESH_DATA' => null, + 'visible' => true, + )); + } + $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>'); + + // If approving one post, also give links back to post... + if (sizeof($post_info) == 1 && $post_url) + { + $message .= '<br /><br />' . $user->lang('RETURN_POST', '<a href="' . $post_url . '">', '</a>'); + } + trigger_error($message); } else { @@ -707,39 +741,7 @@ class mcp_queue confirm_box(false, strtoupper($action) . '_POST' . ((sizeof($post_id_list) == 1) ? '' : 'S'), $s_hidden_fields, 'mcp_approve.html'); } - $redirect = $request->variable('redirect', "index.$phpEx"); - $redirect = reapply_sid($redirect); - - if (!$success_msg) - { - redirect($redirect); - } - else - { - meta_refresh(3, $redirect); - - // If approving one post, also give links back to post... - $add_message = ''; - if (sizeof($post_info) == 1 && $post_url) - { - $add_message = '<br /><br />' . sprintf($user->lang['RETURN_POST'], '<a href="' . $post_url . '">', '</a>'); - } - - $message = $user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>') . $add_message; - - if ($request->is_ajax()) - { - $json_response = new \phpbb\json_response; - $json_response->send(array( - 'MESSAGE_TITLE' => $user->lang['INFORMATION'], - 'MESSAGE_TEXT' => $message, - 'REFRESH_DATA' => null, - 'visible' => true, - )); - } - - trigger_error($message); - } + redirect($redirect); } /** @@ -762,6 +764,7 @@ class mcp_queue } $redirect = $request->variable('redirect', build_url(array('quickmod'))); + $redirect = reapply_sid($redirect); $success_msg = $topic_url = ''; $approve_log = array(); @@ -780,9 +783,12 @@ class mcp_queue $notify_poster = ($action == 'approve' && isset($_REQUEST['notify_poster'])) ? true : false; $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + $first_post_ids = array(); + foreach ($topic_info as $topic_id => $topic_data) { $phpbb_content_visibility->set_topic_visibility(ITEM_APPROVED, $topic_id, $topic_data['forum_id'], $user->data['user_id'], time(), ''); + $first_post_ids[$topic_id] = (int) $topic_data['topic_first_post_id']; $topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$topic_data['forum_id']}&t={$topic_id}"); @@ -806,26 +812,76 @@ class mcp_queue // Only send out the mails, when the posts are being approved if ($action == 'approve') { + // Grab the first post text as it's needed for the quote notification. + $sql = 'SELECT topic_id, post_text + FROM ' . POSTS_TABLE . ' + WHERE ' . $db->sql_in_set('post_id', $first_post_ids); + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $topic_info[$row['topic_id']]['post_text'] = $row['post_text']; + } + $db->sql_freeresult($result); + // Handle notifications $phpbb_notifications = $phpbb_container->get('notification_manager'); foreach ($topic_info as $topic_id => $topic_data) { - $phpbb_notifications->delete_notifications('topic_in_queue', $post_data['topic_id']); - $phpbb_notifications->add_notifications(array( - 'quote', - 'topic', - ), $post_data); + $topic_data = array_merge($topic_data, array( + 'post_id' => $topic_data['topic_first_post_id'], + 'post_subject' => $topic_data['topic_title'], + 'post_time' => $topic_data['topic_time'], + 'poster_id' => $topic_data['topic_poster'], + 'username' => $topic_data['topic_first_poster_name'], + )); + + $phpbb_notifications->delete_notifications('topic_in_queue', $topic_id); - $phpbb_notifications->mark_notifications_read('quote', $post_data['post_id'], $user->data['user_id']); - $phpbb_notifications->mark_notifications_read('topic', $post_data['topic_id'], $user->data['user_id']); + // Only add notifications, if we are not reapproving post + // When the topic was already approved, but was edited and + // now needs re-approval, we don't want to notify the users + // again. + if ($topic_data['topic_visibility'] == ITEM_UNAPPROVED) + { + $phpbb_notifications->add_notifications(array( + 'quote', + 'topic', + ), $topic_data); + } + + $phpbb_notifications->mark_notifications_read('quote', $topic_data['post_id'], $user->data['user_id']); + $phpbb_notifications->mark_notifications_read('topic', $topic_id, $user->data['user_id']); if ($notify_poster) { - $phpbb_notifications->add_notifications('approve_topic', $post_data); + $phpbb_notifications->add_notifications('approve_topic', $topic_data); } } } + + meta_refresh(3, $redirect); + $message = $user->lang[$success_msg]; + + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response; + $json_response->send(array( + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $message, + 'REFRESH_DATA' => null, + 'visible' => true, + )); + } + $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>'); + + // If approving one topic, also give links back to topic... + if (sizeof($topic_info) == 1 && $topic_url) + { + $message .= '<br /><br />' . $user->lang('RETURN_TOPIC', '<a href="' . $topic_url . '">', '</a>'); + } + trigger_error($message); } else { @@ -855,39 +911,7 @@ class mcp_queue confirm_box(false, strtoupper($action) . '_TOPIC' . ((sizeof($topic_id_list) == 1) ? '' : 'S'), $s_hidden_fields, 'mcp_approve.html'); } - $redirect = $request->variable('redirect', "index.$phpEx"); - $redirect = reapply_sid($redirect); - - if (!$success_msg) - { - redirect($redirect); - } - else - { - meta_refresh(3, $redirect); - - // If approving one topic, also give links back to topic... - $add_message = ''; - if (sizeof($topic_info) == 1 && $topic_url) - { - $add_message = '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $topic_url . '">', '</a>'); - } - - $message = $user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>') . $add_message; - - if ($request->is_ajax()) - { - $json_response = new \phpbb\json_response; - $json_response->send(array( - 'MESSAGE_TITLE' => $user->lang['INFORMATION'], - 'MESSAGE_TEXT' => $message, - 'REFRESH_DATA' => null, - 'visible' => true, - )); - } - - trigger_error($message); - } + redirect($redirect); } /** @@ -909,6 +933,7 @@ class mcp_queue } $redirect = $request->variable('redirect', build_url(array('t', 'mode', 'quickmod')) . "&mode=$mode"); + $redirect = reapply_sid($redirect); $reason = $request->variable('reason', '', true); $reason_id = $request->variable('reason_id', 0); $success_msg = $additional_msg = ''; @@ -1049,7 +1074,7 @@ class mcp_queue if ($is_disapproving) { $l_log_message = ($log_data['type'] == 'topic') ? 'LOG_TOPIC_DISAPPROVED' : 'LOG_POST_DISAPPROVED'; - add_log('mod', $log_data['forum_id'], $log_data['topic_id'], $l_log_message, $log_data['post_subject'], $disapprove_reason); + add_log('mod', $log_data['forum_id'], $log_data['topic_id'], $l_log_message, $log_data['post_subject'], $disapprove_reason, $log_data['post_username']); } else { @@ -1115,7 +1140,6 @@ class mcp_queue $post_data['disapprove_reason'] .= ($reason) ? "\n\n" . $reason : ''; } - if ($disapprove_all_posts_in_topic && $topic_information[$topic_id]['topic_posts_unapproved'] == 1) { // If there is only 1 post when disapproving the topic, @@ -1133,7 +1157,6 @@ class mcp_queue unset($lang_reasons, $post_info, $disapprove_reason, $disapprove_reason_lang); - if ($num_disapproved_topics) { $success_msg = ($num_disapproved_topics == 1) ? 'TOPIC' : 'TOPICS'; @@ -1151,6 +1174,38 @@ class mcp_queue { $success_msg .= '_DELETED_SUCCESS'; } + + // If we came from viewtopic, we try to go back to it. + if (strpos($redirect, $phpbb_root_path . 'viewtopic.' . $phpEx) === 0) + { + if ($num_disapproved_topics == 0) + { + // So we need to remove the post id part from the Url + $redirect = str_replace("&p={$post_id_list[0]}#p{$post_id_list[0]}", '', $redirect); + } + else + { + // However this is only possible if the topic still exists, + // Otherwise we go back to the viewforum page + $redirect = append_sid($phpbb_root_path . 'viewforum.' . $phpEx, 'f=' . $request->variable('f', 0)); + } + } + + meta_refresh(3, $redirect); + $message = $user->lang[$success_msg]; + + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response; + $json_response->send(array( + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $message, + 'REFRESH_DATA' => null, + 'visible' => false, + )); + } + $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>'); + trigger_error($message); } else { @@ -1199,30 +1254,6 @@ class mcp_queue confirm_box(false, $l_confirm_msg, $s_hidden_fields, $confirm_template); } - $redirect = $request->variable('redirect', "index.$phpEx"); - $redirect = reapply_sid($redirect); - - if (!$success_msg) - { - redirect($redirect); - } - else - { - $message = $user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>'); - - if ($request->is_ajax()) - { - $json_response = new \phpbb\json_response; - $json_response->send(array( - 'MESSAGE_TITLE' => $user->lang['INFORMATION'], - 'MESSAGE_TEXT' => $message, - 'REFRESH_DATA' => null, - 'visible' => false, - )); - } - - meta_refresh(3, $redirect); - trigger_error($message); - } + redirect($redirect); } } diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 8db5bb9727..5681b83212 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -98,10 +98,10 @@ class mcp_reports $post_id = $report['post_id']; $report_id = $report['report_id']; - + $parse_post_flags = $report['reported_post_enable_bbcode'] ? OPTION_FLAG_BBCODE : 0; $parse_post_flags += $report['reported_post_enable_smilies'] ? OPTION_FLAG_SMILIES : 0; - $parse_post_flags += $report['reported_post_enable_magic_url'] ? OPTION_FLAG_LINKS : 0; + $parse_post_flags += $report['reported_post_enable_magic_url'] ? OPTION_FLAG_LINKS : 0; $post_info = get_post_data(array($post_id), 'm_report', true); @@ -144,7 +144,6 @@ class mcp_reports $post_unread = (isset($topic_tracking_info[$post_info['topic_id']]) && $post_info['post_time'] > $topic_tracking_info[$post_info['topic_id']]) ? true : false; - $report['report_text'] = make_clickable(bbcode_nl2br($report['report_text'])); if ($post_info['post_attachment'] && $auth->acl_get('u_download') && $auth->acl_get('f_download', $post_info['forum_id'])) @@ -187,7 +186,7 @@ class mcp_reports 'S_CLOSE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&mode=report_details&f=' . $post_info['forum_id'] . '&p=' . $post_id), 'S_CAN_VIEWIP' => $auth->acl_get('m_info', $post_info['forum_id']), 'S_POST_REPORTED' => $post_info['post_reported'], - 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED), + 'S_POST_UNAPPROVED' => $post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE, 'S_POST_LOCKED' => $post_info['post_edit_locked'], 'S_REPORT_CLOSED' => $report['report_closed'], 'S_USER_NOTES' => true, @@ -315,6 +314,7 @@ class mcp_reports $forum_list[] = 0; $forum_data = array(); + $pagination = $phpbb_container->get('pagination'); $forum_options = '<option value="0"' . (($forum_id == 0) ? ' selected="selected"' : '') . '>' . $user->lang['ALL_FORUMS'] . '</option>'; foreach ($forum_list_reports as $row) @@ -410,7 +410,7 @@ class mcp_reports } $base_url = $this->u_action . "&f=$forum_id&t=$topic_id&st=$sort_days&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); // Now display the page $template->assign_vars(array( @@ -422,7 +422,6 @@ class mcp_reports 'S_FORUM_OPTIONS' => $forum_options, 'S_CLOSED' => ($mode == 'reports_closed') ? true : false, - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $total, $config['topics_per_page'], $start), 'TOPIC_ID' => $topic_id, 'TOTAL' => $total, 'TOTAL_REPORTS' => $user->lang('LIST_REPORTS', (int) $total), @@ -578,7 +577,6 @@ function close_report($report_id_list, $mode, $action, $pm = false) } $db->sql_query($sql); - if (sizeof($close_report_posts)) { if ($pm) @@ -615,23 +613,25 @@ function close_report($report_id_list, $mode, $action, $pm = false) } unset($close_report_posts, $close_report_topics); + $phpbb_notifications = $phpbb_container->get('notification_manager'); + foreach ($reports as $report) { if ($pm) { add_log('mod', 0, 0, 'LOG_PM_REPORT_' . strtoupper($action) . 'D', $post_info[$report['pm_id']]['message_subject']); + $phpbb_notifications->delete_notifications('report_pm', $report['pm_id']); } else { add_log('mod', $post_info[$report['post_id']]['forum_id'], $post_info[$report['post_id']]['topic_id'], 'LOG_REPORT_' . strtoupper($action) . 'D', $post_info[$report['post_id']]['post_subject']); + $phpbb_notifications->delete_notifications('report_post', $report['post_id']); } } // Notify reporters if (sizeof($notify_reporters)) { - $phpbb_notifications = $phpbb_container->get('notification_manager'); - foreach ($notify_reporters as $report_id => $reporter) { if ($reporter['user_id'] == ANONYMOUS) @@ -648,8 +648,6 @@ function close_report($report_id_list, $mode, $action, $pm = false) 'closer_id' => $user->data['user_id'], 'from_user_id' => $post_info[$post_id]['author_id'], ))); - - $phpbb_notifications->delete_notifications('report_pm', $post_id); } else { @@ -657,8 +655,6 @@ function close_report($report_id_list, $mode, $action, $pm = false) 'reporter' => $reporter['user_id'], 'closer_id' => $user->data['user_id'], ))); - - $phpbb_notifications->delete_notifications('report_post', $post_id); } } } diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 9c294b96c8..48efa330d4 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -26,6 +26,7 @@ function mcp_topic_view($id, $mode, $action) $url = append_sid("{$phpbb_root_path}mcp.$phpEx?" . extra_url()); $user->add_lang('viewtopic'); + $pagination = $phpbb_container->get('pagination'); $topic_id = request_var('t', 0); $topic_info = get_topic_data(array($topic_id), false, true); @@ -129,12 +130,7 @@ function mcp_topic_view($id, $mode, $action) { $start = 0; } - - // Make sure $start is set to the last page if it exceeds the amount - if ($start < 0 || $start >= $total) - { - $start = ($start < 0) ? 0 : floor(($total - 1) / $posts_per_page) * $posts_per_page; - } + $start = $pagination->validate_start($start, $posts_per_page, $total); $sql = 'SELECT u.username, u.username_clean, u.user_colour, p.* FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u @@ -216,7 +212,7 @@ function mcp_topic_view($id, $mode, $action) parse_attachments($topic_info['forum_id'], $message, $attachments[$row['post_id']], $update_count); } - if ($row['post_visibility'] == ITEM_UNAPPROVED) + if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) { $has_unapproved_posts = true; } @@ -243,7 +239,7 @@ function mcp_topic_view($id, $mode, $action) 'MINI_POST_IMG' => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'), 'S_POST_REPORTED' => ($row['post_reported'] && $auth->acl_get('m_report', $topic_info['forum_id'])), - 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $topic_info['forum_id'])), + 'S_POST_UNAPPROVED' => (($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $topic_info['forum_id'])), 'S_POST_DELETED' => ($row['post_visibility'] == ITEM_DELETED && $auth->acl_get('m_approve', $topic_info['forum_id'])), 'S_CHECKED' => (($submitted_id_list && !in_array(intval($row['post_id']), $submitted_id_list)) || in_array(intval($row['post_id']), $checked_ids)) ? true : false, 'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false, @@ -304,7 +300,7 @@ function mcp_topic_view($id, $mode, $action) $base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&t={$topic_info['topic_id']}&mode=$mode&action=$action&to_topic_id=$to_topic_id&posts_per_page=$posts_per_page&st=$sort_days&sk=$sort_key&sd=$sort_dir"); if ($posts_per_page) { - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $posts_per_page, $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $posts_per_page, $start); } $template->assign_vars(array( @@ -347,7 +343,6 @@ function mcp_topic_view($id, $mode, $action) 'RETURN_TOPIC' => sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$topic_info['forum_id']}&t={$topic_info['topic_id']}&start=$start") . '">', '</a>'), 'RETURN_FORUM' => sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f={$topic_info['forum_id']}&start=$start") . '">', '</a>'), - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $total, $posts_per_page, $start), 'TOTAL_POSTS' => $user->lang('VIEW_TOPIC_POSTS', (int) $total), )); } @@ -467,7 +462,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) while ($row = $db->sql_fetchrow($result)) { // If split from selected post (split_beyond), we split the unapproved items too. - if ($row['post_visibility'] == ITEM_UNAPPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) + if (($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) && !$auth->acl_get('m_approve', $row['forum_id'])) { // continue; } @@ -568,23 +563,15 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) // Link back to both topics $return_link = sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $post_info['forum_id'] . '&t=' . $post_info['topic_id']) . '">', '</a>') . '<br /><br />' . sprintf($user->lang['RETURN_NEW_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $to_forum_id . '&t=' . $to_topic_id) . '">', '</a>'); - } - else - { - confirm_box(false, ($action == 'split_all') ? 'SPLIT_TOPIC_ALL' : 'SPLIT_TOPIC_BEYOND', $s_hidden_fields); - } + $redirect = request_var('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id"); + $redirect = reapply_sid($redirect); - $redirect = request_var('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id"); - $redirect = reapply_sid($redirect); - - if (!$success_msg) - { - return; + meta_refresh(3, $redirect); + trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); } else { - meta_refresh(3, $redirect); - trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); + confirm_box(false, ($action == 'split_all') ? 'SPLIT_TOPIC_ALL' : 'SPLIT_TOPIC_BEYOND', $s_hidden_fields); } } @@ -677,22 +664,14 @@ function merge_posts($topic_id, $to_topic_id) // Link to the new topic $return_link .= (($return_link) ? '<br /><br />' : '') . sprintf($user->lang['RETURN_NEW_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $to_forum_id . '&t=' . $to_topic_id) . '">', '</a>'); - } - else - { - confirm_box(false, 'MERGE_POSTS', $s_hidden_fields); - } - - $redirect = request_var('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id"); - $redirect = reapply_sid($redirect); + $redirect = request_var('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id"); + $redirect = reapply_sid($redirect); - if (!$success_msg) - { - return; + meta_refresh(3, $redirect); + trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); } else { - meta_refresh(3, $redirect); - trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); + confirm_box(false, 'MERGE_POSTS', $s_hidden_fields); } } diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php index 3ffd75ac78..4275182d26 100644 --- a/phpBB/includes/mcp/mcp_warn.php +++ b/phpBB/includes/mcp/mcp_warn.php @@ -96,9 +96,6 @@ class mcp_warn 'U_NOTES' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes&u=' . $row['user_id']), 'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']), - 'USERNAME' => $row['username'], - 'USERNAME_COLOUR' => ($row['user_colour']) ? '#' . $row['user_colour'] : '', - 'U_USER' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u=' . $row['user_id']), 'WARNING_TIME' => $user->format_date($row['user_last_warning']), 'WARNINGS' => $row['user_warnings'], @@ -118,9 +115,6 @@ class mcp_warn 'U_NOTES' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes&u=' . $row['user_id']), 'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']), - 'USERNAME' => $row['username'], - 'USERNAME_COLOUR' => ($row['user_colour']) ? '#' . $row['user_colour'] : '', - 'U_USER' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u=' . $row['user_id']), 'WARNING_TIME' => $user->format_date($row['warning_time']), 'WARNINGS' => $row['user_warnings'], @@ -134,10 +128,11 @@ class mcp_warn */ function mcp_warn_list_view($action) { - global $phpEx, $phpbb_root_path, $config; + global $phpEx, $phpbb_root_path, $config, $phpbb_container; global $template, $db, $user, $auth; $user->add_lang('memberlist'); + $pagination = $phpbb_container->get('pagination'); $start = request_var('start', 0); $st = request_var('st', 0); @@ -166,9 +161,6 @@ class mcp_warn 'U_NOTES' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes&u=' . $row['user_id']), 'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']), - 'USERNAME' => $row['username'], - 'USERNAME_COLOUR' => ($row['user_colour']) ? '#' . $row['user_colour'] : '', - 'U_USER' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u=' . $row['user_id']), 'WARNING_TIME' => $user->format_date($row['user_last_warning']), 'WARNINGS' => $row['user_warnings'], @@ -176,7 +168,7 @@ class mcp_warn } $base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=warn&mode=list&st=$st&sk=$sk&sd=$sd"); - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $user_count, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $user_count, $config['topics_per_page'], $start); $template->assign_vars(array( 'U_POST_ACTION' => $this->u_action, @@ -185,7 +177,6 @@ class mcp_warn 'S_SELECT_SORT_KEY' => $s_sort_key, 'S_SELECT_SORT_DAYS' => $s_limit_days, - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $user_count, $config['topics_per_page'], $start), 'TOTAL_USERS' => $user->lang('LIST_USERS', (int) $user_count), )); } @@ -293,7 +284,7 @@ class mcp_warn $message = generate_text_for_display($user_row['post_text'], $user_row['bbcode_uid'], $user_row['bbcode_bitfield'], $parse_flags, true); // Generate the appropriate user information for the user we are looking at - if (!function_exists('phpbb_get_user_avatar')) + if (!function_exists('get_user_rank')) { include($phpbb_root_path . 'includes/functions_display.' . $phpEx); } @@ -398,11 +389,10 @@ class mcp_warn } // Generate the appropriate user information for the user we are looking at - if (!function_exists('phpbb_get_user_avatar')) + if (!function_exists('get_user_rank')) { include($phpbb_root_path . 'includes/functions_display.' . $phpEx); } - get_user_rank($user_row['user_rank'], $user_row['user_posts'], $rank_title, $rank_img, $rank_img_src); $avatar_img = phpbb_get_user_avatar($user_row); diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index 3e348801c7..17a350bab3 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -103,6 +103,8 @@ class bbcode_firstpass extends bbcode */ function bbcode_init($allow_custom_bbcode = true) { + global $phpbb_dispatcher; + static $rowset; // This array holds all bbcode data. BBCodes will be processed in this @@ -162,6 +164,21 @@ class bbcode_firstpass extends bbcode 'regexp' => array($row['first_pass_match'] => str_replace('$uid', $this->bbcode_uid, $row['first_pass_replace'])) ); } + + $bbcodes = $this->bbcodes; + + /** + * Event to modify the bbcode data for later parsing + * + * @event core.modify_bbcode_init + * @var array bbcodes Array of bbcode data for use in parsing + * @var array rowset Array of bbcode data from the database + * @since 3.1.0-a3 + */ + $vars = array('bbcodes', 'rowset'); + extract($phpbb_dispatcher->trigger_event('core.modify_bbcode_init', compact($vars))); + + $this->bbcodes = $bbcodes; } /** @@ -1050,6 +1067,12 @@ class parse_message extends bbcode_firstpass var $mode; /** + * The plupload object used for dealing with attachments + * @var \phpbb\plupload\plupload + */ + protected $plupload; + + /** * Init - give message here or manually */ function parse_message($message = '') @@ -1192,6 +1215,8 @@ class parse_message extends bbcode_firstpass */ function format_display($allow_bbcode, $allow_magic_url, $allow_smilies, $update_this_message = true) { + global $phpbb_dispatcher; + // If false, then the parsed message get returned but internal message not processed. if (!$update_this_message) { @@ -1220,6 +1245,28 @@ class parse_message extends bbcode_firstpass $this->message = bbcode_nl2br($this->message); $this->message = smiley_text($this->message, !$allow_smilies); + $text = $this->message; + $uid = $this->bbcode_uid; + + /** + * Event to modify the text after it is parsed + * + * @event core.modify_format_display_text_after + * @var string text The message text to parse + * @var string uid The bbcode uid + * @var bool allow_bbcode Do we allow bbcodes + * @var bool allow_magic_url Do we allow magic urls + * @var bool allow_smilies Do we allow smilies + * @var bool update_this_message Do we update the internal message + * with the parsed result + * @since 3.1.0-a3 + */ + $vars = array('text', 'uid', 'allow_bbcode', 'allow_magic_url', 'allow_smilies', 'update_this_message'); + extract($phpbb_dispatcher->trigger_event('core.modify_format_display_text_after', compact($vars))); + + $this->message = $text; + $this->bbcode_uid = $uid; + if (!$update_this_message) { unset($this->message); @@ -1414,6 +1461,7 @@ class parse_message extends bbcode_firstpass 'is_orphan' => 1, 'real_filename' => $filedata['real_filename'], 'attach_comment'=> $this->filename_data['filecomment'], + 'filesize' => $filedata['filesize'], ); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); @@ -1440,6 +1488,11 @@ class parse_message extends bbcode_firstpass if ($preview || $refresh || sizeof($error)) { + if (isset($this->plupload) && $this->plupload->is_active()) + { + $json_response = new \phpbb\json_response(); + } + // Perform actions on temporary attachments if ($delete_file) { @@ -1484,13 +1537,17 @@ class parse_message extends bbcode_firstpass // Reindex Array $this->attachment_data = array_values($this->attachment_data); + if (isset($this->plupload) && $this->plupload->is_active()) + { + $json_response->send($this->attachment_data); + } } } else if (($add_file || $preview) && $upload_file) { if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id)) { - $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message); + $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message, false, $this->plupload); $error = array_merge($error, $filedata['error']); if (!sizeof($error)) @@ -1516,17 +1573,40 @@ class parse_message extends bbcode_firstpass 'is_orphan' => 1, 'real_filename' => $filedata['real_filename'], 'attach_comment'=> $this->filename_data['filecomment'], + 'filesize' => $filedata['filesize'], ); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message); $this->filename_data['filecomment'] = ''; + + if (isset($this->plupload) && $this->plupload->is_active()) + { + $download_url = append_sid("{$phpbb_root_path}download/file.{$phpEx}", 'mode=view&id=' . $new_entry['attach_id']); + + // Send the client the attachment data to maintain state + $json_response->send(array('data' => $this->attachment_data, 'download_url' => $download_url)); + } } } else { $error[] = $user->lang('TOO_MANY_ATTACHMENTS', (int) $cfg['max_attachments']); } + + if (!empty($error) && isset($this->plupload) && $this->plupload->is_active()) + { + // If this is a plupload (and thus ajax) request, give the + // client the first error we have + $json_response->send(array( + 'jsonrpc' => '2.0', + 'id' => 'id', + 'error' => array( + 'code' => 105, + 'message' => current($error), + ), + )); + } } } @@ -1573,7 +1653,7 @@ class parse_message extends bbcode_firstpass if (sizeof($not_orphan)) { // Get the attachment data, based on the poster id... - $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment + $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment, filesize FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', array_keys($not_orphan)) . ' AND poster_id = ' . $check_user_id; @@ -1598,7 +1678,7 @@ class parse_message extends bbcode_firstpass // Regenerate newly uploaded attachments if (sizeof($orphan)) { - $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment + $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment, filesize FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan)) . ' AND poster_id = ' . $user->data['user_id'] . ' @@ -1687,4 +1767,16 @@ class parse_message extends bbcode_firstpass $poll['poll_max_options'] = ($poll['poll_max_options'] < 1) ? 1 : (($poll['poll_max_options'] > $config['max_poll_options']) ? $config['max_poll_options'] : $poll['poll_max_options']); } + + /** + * Setter function for passing the plupload object + * + * @param \phpbb\plupload\plupload $plupload The plupload object + * + * @return null + */ + public function set_plupload(\phpbb\plupload\plupload $plupload) + { + $this->plupload = $plupload; + } } diff --git a/phpBB/includes/ucp/info/ucp_auth_link.php b/phpBB/includes/ucp/info/ucp_auth_link.php index ee88b15ea8..3a34232d28 100644 --- a/phpBB/includes/ucp/info/ucp_auth_link.php +++ b/phpBB/includes/ucp/info/ucp_auth_link.php @@ -19,7 +19,7 @@ class ucp_auth_link_info 'title' => 'UCP_AUTH_LINK', 'version' => '1.0.0', 'modes' => array( - 'auth_link' => array('title' => 'UCP_AUTH_LINK_MANAGE', 'auth' => '', 'cat' => array('UCP_PROFILE')), + 'auth_link' => array('title' => 'UCP_AUTH_LINK_MANAGE', 'auth' => 'authmethod_oauth', 'cat' => array('UCP_PROFILE')), ), ); } diff --git a/phpBB/includes/ucp/info/ucp_pm.php b/phpBB/includes/ucp/info/ucp_pm.php index 02931e9d31..a80de21999 100644 --- a/phpBB/includes/ucp/info/ucp_pm.php +++ b/phpBB/includes/ucp/info/ucp_pm.php @@ -22,7 +22,6 @@ class ucp_pm_info 'compose' => array('title' => 'UCP_PM_COMPOSE', 'auth' => 'cfg_allow_privmsg', 'cat' => array('UCP_PM')), 'drafts' => array('title' => 'UCP_PM_DRAFTS', 'auth' => 'cfg_allow_privmsg', 'cat' => array('UCP_PM')), 'options' => array('title' => 'UCP_PM_OPTIONS', 'auth' => 'cfg_allow_privmsg', 'cat' => array('UCP_PM')), - 'popup' => array('title' => 'UCP_PM_POPUP_TITLE', 'auth' => 'cfg_allow_privmsg', 'display' => false, 'cat' => array('UCP_PM')), ), ); } diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php index 898dacd831..2a94acbe02 100644 --- a/phpBB/includes/ucp/ucp_activate.php +++ b/phpBB/includes/ucp/ucp_activate.php @@ -27,7 +27,7 @@ class ucp_activate function main($id, $mode) { global $config, $phpbb_root_path, $phpEx; - global $db, $user, $auth, $template; + global $db, $user, $auth, $template, $phpbb_container; $user_id = request_var('u', 0); $key = request_var('k', ''); @@ -108,6 +108,9 @@ class ucp_activate if ($config['require_activation'] == USER_ACTIVATION_ADMIN && !$update_password) { + $phpbb_notifications = $phpbb_container->get('notification_manager'); + $phpbb_notifications->delete_notifications('admin_activate_user', $user_row['user_id']); + include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); $messenger = new messenger(false); diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php index dc095e7b73..6a5b48a181 100644 --- a/phpBB/includes/ucp/ucp_attachments.php +++ b/phpBB/includes/ucp/ucp_attachments.php @@ -26,7 +26,7 @@ class ucp_attachments function main($id, $mode) { - global $template, $user, $db, $config, $phpEx, $phpbb_root_path; + global $template, $user, $db, $config, $phpEx, $phpbb_root_path, $phpbb_container; $start = request_var('start', 0); $sort_key = request_var('sk', 'a'); @@ -119,6 +119,10 @@ class ucp_attachments $num_attachments = $db->sql_fetchfield('num_attachments'); $db->sql_freeresult($result); + // Ensure start is a valid value + $pagination = $phpbb_container->get('pagination'); + $start = $pagination->validate_start($start, $config['topics_per_page'], $num_attachments); + $sql = 'SELECT a.*, t.topic_title, p.message_subject as message_title FROM ' . ATTACHMENTS_TABLE . ' a LEFT JOIN ' . TOPICS_TABLE . ' t ON (a.topic_id = t.topic_id AND a.in_message = 0) @@ -171,10 +175,9 @@ class ucp_attachments $db->sql_freeresult($result); $base_url = $this->u_action . "&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $num_attachments, $config['topics_per_page'], $start), 'TOTAL_ATTACHMENTS' => $num_attachments, 'L_TITLE' => $user->lang['UCP_ATTACHMENTS'], diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index a75d2e9bfc..373d9433b2 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -465,7 +465,7 @@ class ucp_groups $avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers(); // This is normalised data, without the group_ prefix - $avatar_data = \phpbb\avatar\manager::clean_row($group_row); + $avatar_data = \phpbb\avatar\manager::clean_row($group_row, 'group'); } // Did we submit? @@ -509,7 +509,7 @@ class ucp_groups } else { - if ($driver = $phpbb_avatar_manager->get_driver($user->data['user_avatar_type'])) + if ($driver = $phpbb_avatar_manager->get_driver($avatar_data['avatar_type'])) { $driver->delete($avatar_data); } @@ -699,7 +699,6 @@ class ucp_groups 'GROUP_CLOSED' => $type_closed, 'GROUP_HIDDEN' => $type_hidden, - 'U_SWATCH' => append_sid("{$phpbb_admin_path}swatch.$phpEx", 'form=ucp&name=group_colour'), 'S_UCP_ACTION' => $this->u_action . "&action=$action&g=$group_id", 'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(), )); @@ -814,13 +813,14 @@ class ucp_groups $s_action_options .= '<option value="' . $option . '">' . $user->lang['GROUP_' . $lang] . '</option>'; } + $pagination = $phpbb_container->get('pagination'); $base_url = $this->u_action . "&action=$action&g=$group_id"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); + $start = $pagination->validate_start($start, $config['topics_per_page'], $total_members); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); $template->assign_vars(array( 'S_LIST' => true, 'S_ACTION_OPTIONS' => $s_action_options, - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $total_members, $config['topics_per_page'], $start), 'U_ACTION' => $this->u_action . "&g=$group_id", 'S_UCP_ACTION' => $this->u_action . "&g=$group_id", diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php index b859413d92..11ba2fba4d 100644 --- a/phpBB/includes/ucp/ucp_main.php +++ b/phpBB/includes/ucp/ucp_main.php @@ -189,15 +189,12 @@ class ucp_main $template->assign_vars(array( 'USER_COLOR' => (!empty($user->data['user_colour'])) ? $user->data['user_colour'] : '', 'JOINED' => $user->format_date($user->data['user_regdate']), - 'VISITED' => (empty($last_visit)) ? ' - ' : $user->format_date($last_visit), + 'LAST_ACTIVE' => (empty($last_active)) ? ' - ' : $user->format_date($last_active), 'WARNINGS' => ($user->data['user_warnings']) ? $user->data['user_warnings'] : 0, 'POSTS' => ($user->data['user_posts']) ? $user->data['user_posts'] : 0, 'POSTS_DAY' => $user->lang('POST_DAY', $posts_per_day), 'POSTS_PCT' => $user->lang('POST_PCT', $percentage), - 'OCCUPATION' => (!empty($row['user_occ'])) ? $row['user_occ'] : '', - 'INTERESTS' => (!empty($row['user_interests'])) ? $row['user_interests'] : '', - // 'S_GROUP_OPTIONS' => $group_options, 'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", 'author_id=' . $user->data['user_id'] . '&sr=posts') : '', @@ -357,6 +354,8 @@ class ucp_main 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), 'U_LAST_POST_AUTHOR' => get_username_string('profile', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), + 'S_UNREAD_FORUM' => $unread_forum, + 'U_LAST_POST' => $last_post_url, 'U_VIEWFORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id'])) ); @@ -620,7 +619,6 @@ class ucp_main break; } - $template->assign_vars(array( 'L_TITLE' => $user->lang['UCP_MAIN_' . strtoupper($mode)], @@ -646,6 +644,7 @@ class ucp_main $table = ($mode == 'subscribed') ? TOPICS_WATCH_TABLE : BOOKMARKS_TABLE; $start = request_var('start', 0); + $pagination = $phpbb_container->get('pagination'); // Grab icons $icons = $cache->obtain_icons(); @@ -669,10 +668,10 @@ class ucp_main if ($topics_count) { - phpbb_generate_template_pagination($template, $this->u_action, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start); + $start = $pagination->validate_start($start, $config['topics_per_page'], $topics_count); + $pagination->generate_template_pagination($this->u_action, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $this->u_action, $topics_count, $config['topics_per_page'], $start), 'TOTAL_TOPICS' => $user->lang('VIEW_FORUM_TOPICS', (int) $topics_count), )); } @@ -691,7 +690,6 @@ class ucp_main AND t.topic_id = tw.topic_id AND ' . $db->sql_in_set('t.forum_id', $forbidden_forum_ary, true, true), - 'ORDER_BY' => 't.topic_last_post_time DESC' ); @@ -839,7 +837,7 @@ class ucp_main 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id), )); - phpbb_generate_template_pagination($template, append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id'] . "&t=$topic_id"), 'topicrow.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); + $pagination->generate_template_pagination(append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id'] . "&t=$topic_id"), 'topicrow.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); } } } diff --git a/phpBB/includes/ucp/ucp_notifications.php b/phpBB/includes/ucp/ucp_notifications.php index 2f22f6cf9c..f3b72d12aa 100644 --- a/phpBB/includes/ucp/ucp_notifications.php +++ b/phpBB/includes/ucp/ucp_notifications.php @@ -27,9 +27,11 @@ class ucp_notifications add_form_key('ucp_notification'); $start = $request->variable('start', 0); - $form_time = min($request->variable('form_time', 0), time()); + $form_time = $request->variable('form_time', 0); + $form_time = ($form_time <= 0 || $form_time > time()) ? time() : $form_time; $phpbb_notifications = $phpbb_container->get('notification_manager'); + $pagination = $phpbb_container->get('pagination'); switch ($mode) { @@ -78,9 +80,9 @@ class ucp_notifications trigger_error($message); } - $this->output_notification_methods('notification_methods', $phpbb_notifications, $template, $user); + $this->output_notification_methods($phpbb_notifications, $template, $user, 'notification_methods'); - $this->output_notification_types($subscriptions, 'notification_types', $phpbb_notifications, $template, $user); + $this->output_notification_types($subscriptions, $phpbb_notifications, $template, $user, 'notification_types'); $this->tpl_name = 'ucp_notifications'; $this->page_title = 'UCP_NOTIFICATION_OPTIONS'; @@ -96,7 +98,19 @@ class ucp_notifications $phpbb_notifications->mark_notifications_read(false, false, $user->data['user_id'], $form_time); meta_refresh(3, $this->u_action); - $message = $user->lang['NOTIFICATIONS_MARK_ALL_READ_SUCCESS'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>'); + $message = $user->lang['NOTIFICATIONS_MARK_ALL_READ_SUCCESS']; + + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response(); + $json_response->send(array( + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $message, + 'success' => true, + )); + } + $message .= '<br /><br />' . $user->lang('RETURN_UCP', '<a href="' . $this->u_action . '">', '</a>'); + trigger_error($message); } else @@ -136,11 +150,11 @@ class ucp_notifications } $base_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=ucp_notifications&mode=notification_list"); - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $notifications['total_count'], $config['topics_per_page'], $start); + $start = $pagination->validate_start($start, $config['topics_per_page'], $notifications['total_count']); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $notifications['total_count'], $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $notifications['total_count'], $config['topics_per_page'], $start), - 'TOTAL_COUNT' => $user->lang('NOTIFICATIONS_COUNT', $notifications['total_count']), + 'TOTAL_COUNT' => $notifications['total_count'], 'U_MARK_ALL' => $base_url . '&mark=all&token=' . generate_link_hash('mark_all_notifications_read'), )); @@ -162,12 +176,13 @@ class ucp_notifications /** * Output all the notification types to the template * - * @param string $block + * @param array $subscriptions Array containing global subscriptions * @param \phpbb\notification\manager $phpbb_notifications * @param \phpbb\template\template $template * @param \phpbb\user $user + * @param string $block */ - public function output_notification_types($subscriptions, $block = 'notification_types', \phpbb\notification\manager $phpbb_notifications, \phpbb\template\template $template, \phpbb\user $user) + public function output_notification_types($subscriptions, \phpbb\notification\manager $phpbb_notifications, \phpbb\template\template $template, \phpbb\user $user, $block = 'notification_types') { $notification_methods = $phpbb_notifications->get_subscription_methods(); @@ -209,12 +224,12 @@ class ucp_notifications /** * Output all the notification methods to the template * - * @param string $block * @param \phpbb\notification\manager $phpbb_notifications * @param \phpbb\template\template $template * @param \phpbb\user $user + * @param string $block */ - public function output_notification_methods($block = 'notification_methods', \phpbb\notification\manager $phpbb_notifications, \phpbb\template\template $template, \phpbb\user $user) + public function output_notification_methods(\phpbb\notification\manager $phpbb_notifications, \phpbb\template\template $template, \phpbb\user $user, $block = 'notification_methods') { $notification_methods = $phpbb_notifications->get_subscription_methods(); diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php index d4ce8e41ee..74dc08d875 100644 --- a/phpBB/includes/ucp/ucp_pm.php +++ b/phpBB/includes/ucp/ucp_pm.php @@ -83,33 +83,6 @@ class ucp_pm switch ($mode) { - // New private messages popup - case 'popup': - - $l_new_message = ''; - if ($user->data['is_registered']) - { - if ($user->data['user_new_privmsg']) - { - $l_new_message = ($user->data['user_new_privmsg'] == 1) ? $user->lang['YOU_NEW_PM'] : $user->lang['YOU_NEW_PMS']; - } - else - { - $l_new_message = $user->lang['YOU_NO_NEW_PM']; - } - } - - $template->assign_vars(array( - 'MESSAGE' => $l_new_message, - 'S_NOT_LOGGED_IN' => ($user->data['user_id'] == ANONYMOUS) ? true : false, - 'CLICK_TO_VIEW' => sprintf($user->lang['CLICK_VIEW_PRIVMSG'], '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox') . '" onclick="jump_to_inbox(this.href); return false;">', '</a>'), - 'U_INBOX' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox'), - 'UA_INBOX' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox', false)) - ); - - $tpl_file = 'ucp_pm_popup'; - break; - // Compose message case 'compose': $action = request_var('action', 'post'); @@ -199,7 +172,6 @@ class ucp_pm trigger_error('NO_AUTH_READ_HOLD_MESSAGE'); } - // First Handle Mark actions and moving messages $submit_mark = (isset($_POST['submit_mark'])) ? true : false; $move_pm = (isset($_POST['move_pm'])) ? true : false; @@ -379,9 +351,10 @@ class ucp_pm else if ($action == 'view_message') { $template->assign_vars(array( - 'S_VIEW_MESSAGE' => true, - 'MSG_ID' => $msg_id) - ); + 'S_VIEW_MESSAGE' => true, + 'L_RETURN_TO_FOLDER' => $user->lang('RETURN_TO', $folder_status['folder_name']), + 'MSG_ID' => $msg_id, + )); if (!$msg_id) { diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index e0e7a46494..e5a1c1b915 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -21,9 +21,10 @@ if (!defined('IN_PHPBB')) */ function compose_pm($id, $mode, $action, $user_folders = array()) { - global $template, $db, $auth, $user; + global $template, $db, $auth, $user, $cache; global $phpbb_root_path, $phpEx, $config; global $request; + global $phpbb_container; // Damn php and globals - i know, this is horrible // Needed for handle_message_list_actions() @@ -385,6 +386,8 @@ function compose_pm($id, $mode, $action, $user_folders = array()) } $message_parser = new parse_message(); + $plupload = $phpbb_container->get('plupload'); + $message_parser->set_plupload($plupload); $message_parser->message = ($action == 'reply') ? '' : $message_text; unset($message_text); @@ -583,7 +586,6 @@ function compose_pm($id, $mode, $action, $user_folders = array()) ); $s_hidden_fields .= build_address_field($address_list); - confirm_box(false, 'SAVE_DRAFT', $s_hidden_fields); } } @@ -745,7 +747,6 @@ function compose_pm($id, $mode, $action, $user_folders = array()) $return_box_url = ($action === 'post' || $action === 'edit') ? $outbox_folder_url : $inbox_folder_url; $return_box_lang = ($action === 'post' || $action === 'edit') ? 'PM_OUTBOX' : 'PM_INBOX'; - $save_message = ($action === 'edit') ? $user->lang['MESSAGE_EDITED'] : $user->lang['MESSAGE_STORED']; $message = $save_message . '<br /><br />' . $user->lang('VIEW_PRIVATE_MESSAGE', '<a href="' . $return_message_url . '">', '</a>'); @@ -1003,7 +1004,6 @@ function compose_pm($id, $mode, $action, $user_folders = array()) // Build hidden address list $s_hidden_address_field = build_address_field($address_list); - $bbcode_checked = (isset($enable_bbcode)) ? !$enable_bbcode : (($config['allow_bbcode'] && $auth->acl_get('u_pm_bbcode')) ? !$user->optionget('bbcode') : 1); $smilies_checked = (isset($enable_smilies)) ? !$enable_smilies : (($config['allow_smilies'] && $auth->acl_get('u_pm_smilies')) ? !$user->optionget('smilies') : 1); $urls_checked = (isset($enable_urls)) ? !$enable_urls : 0; @@ -1078,6 +1078,7 @@ function compose_pm($id, $mode, $action, $user_folders = array()) 'S_SAVE_ALLOWED' => ($auth->acl_get('u_savedrafts') && $action != 'edit') ? true : false, 'S_HAS_DRAFTS' => ($auth->acl_get('u_savedrafts') && $drafts), 'S_FORM_ENCTYPE' => $form_enctype, + 'S_ATTACH_DATA' => json_encode($message_parser->attachment_data), 'S_BBCODE_IMG' => $img_status, 'S_BBCODE_FLASH' => $flash_status, @@ -1099,6 +1100,12 @@ function compose_pm($id, $mode, $action, $user_folders = array()) // Show attachment box for adding attachments if true $allowed = ($auth->acl_get('u_pm_attach') && $config['allow_pm_attach'] && $form_enctype); + if ($allowed) + { + $max_files = ($auth->acl_gets('a_', 'm_')) ? 0 : (int) $config['max_attachments_pm']; + $plupload->configure($cache, $template, $s_action, false, $max_files); + } + // Attachment entry posting_gen_attachment_entry($attachment_data, $filename_data, $allowed); diff --git a/phpBB/includes/ucp/ucp_pm_options.php b/phpBB/includes/ucp/ucp_pm_options.php index bf7334b307..71c96a25b6 100644 --- a/phpBB/includes/ucp/ucp_pm_options.php +++ b/phpBB/includes/ucp/ucp_pm_options.php @@ -65,7 +65,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit trigger_error($message); } } - + // Add Folder if (isset($_POST['addfolder'])) { @@ -226,11 +226,11 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit // Move Messages case 1: $num_moved = move_pm($user->data['user_id'], $user->data['message_limit'], $msg_ids, $move_to, $remove_folder_id); - + // Something went wrong, only partially moved? if ($num_moved != $folder_row['pm_count']) { - trigger_error($user->lang('MOVE_PM_ERROR', (int) $folder_row['pm_count'], $num_moved)); + trigger_error($user->lang('MOVE_PM_ERROR', $user->lang('MESSAGES_COUNT', (int) $folder_row['pm_count']), $num_moved)); } break; @@ -418,10 +418,10 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit $result = $db->sql_query($sql); $num_messages = (int) $db->sql_fetchfield('num_messages'); $db->sql_freeresult($result); - + $folder[PRIVMSGS_INBOX] = array( 'folder_name' => $user->lang['PM_INBOX'], - 'message_status' => $user->lang('FOLDER_MESSAGE_STATUS', (int) $user->data['message_limit'], $num_messages), + 'message_status' => $user->lang('FOLDER_MESSAGE_STATUS', $user->lang('MESSAGES_COUNT', (int) $user->data['message_limit']), $num_messages), ); $sql = 'SELECT folder_id, folder_name, pm_count @@ -435,7 +435,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit $num_user_folder++; $folder[$row['folder_id']] = array( 'folder_name' => $row['folder_name'], - 'message_status' => $user->lang('FOLDER_MESSAGE_STATUS', (int) $user->data['message_limit'], $row['pm_count']), + 'message_status' => $user->lang('FOLDER_MESSAGE_STATUS', $user->lang('MESSAGES_COUNT', (int) $user->data['message_limit']), (int) $row['pm_count']), ); } $db->sql_freeresult($result); @@ -691,7 +691,7 @@ function define_rule_option($hardcoded, $rule_option, $rule_lang, $check_ary) function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule_conditions) { global $db, $template, $auth, $user; - + $template->assign_vars(array( 'S_COND_DEFINED' => true, 'S_COND_SELECT' => (!$hardcoded && isset($global_rule_conditions[$rule_option])) ? true : false) @@ -715,7 +715,7 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule { case 'text': $rule_string = utf8_normalize_nfc(request_var('rule_string', '', true)); - + $template->assign_vars(array( 'S_TEXT_CONDITION' => true, 'CURRENT_STRING' => $rule_string, @@ -729,7 +729,7 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule case 'user': $rule_user_id = request_var('rule_user_id', 0); $rule_string = utf8_normalize_nfc(request_var('rule_string', '', true)); - + if ($rule_string && !$rule_user_id) { $sql = 'SELECT user_id @@ -791,10 +791,10 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule { $sql .= 'WHERE'; } - - $sql .= " (g.group_name NOT IN ('GUESTS', 'BOTS') OR g.group_type <> " . GROUP_SPECIAL . ') + + $sql .= " (g.group_name NOT IN ('GUESTS', 'BOTS') OR g.group_type <> " . GROUP_SPECIAL . ') ORDER BY g.group_type DESC, g.group_name ASC'; - + $result = $db->sql_query($sql); $s_group_options = ''; @@ -807,7 +807,7 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule $s_class = ($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : ''; $s_selected = ($row['group_id'] == $rule_group_id) ? ' selected="selected"' : ''; - + $s_group_options .= '<option value="' . $row['group_id'] . '"' . $s_class . $s_selected . '>' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>'; } $db->sql_freeresult($result); @@ -845,7 +845,7 @@ function show_defined_rules($user_id, $check_lang, $rule_lang, $action_lang, $fo WHERE user_id = ' . $user_id . ' ORDER BY rule_id ASC'; $result = $db->sql_query($sql); - + $count = 0; while ($row = $db->sql_fetchrow($result)) { diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php index 625da23736..a567283543 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -269,7 +269,7 @@ function view_folder($id, $mode, $folder_id, $folder) // There is the chance that all recipients of the message got deleted. To avoid creating // exports without recipients, we add a bogus "undisclosed recipient". if (!(isset($address[$message_id]['g']) && sizeof($address[$message_id]['g'])) && - !(isset($address[$message_id]['u']) && sizeof($address[$message_id]['u']))) + !(isset($address[$message_id]['u']) && sizeof($address[$message_id]['u']))) { $address[$message_id]['u'] = array(); $address[$message_id]['u']['to'] = array(); @@ -393,7 +393,7 @@ function view_folder($id, $mode, $folder_id, $folder) */ function get_pm_from($folder_id, $folder, $user_id) { - global $user, $db, $template, $config, $auth, $phpbb_root_path, $phpEx; + global $user, $db, $template, $config, $auth, $phpbb_container, $phpbb_root_path, $phpEx; $start = request_var('start', 0); @@ -402,6 +402,8 @@ function get_pm_from($folder_id, $folder, $user_id) $sort_key = request_var('sk', 't'); $sort_dir = request_var('sd', 'd'); + $pagination = $phpbb_container->get('pagination'); + // PM ordering options $limit_days = array(0 => $user->lang['ALL_MESSAGES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); @@ -452,10 +454,10 @@ function get_pm_from($folder_id, $folder, $user_id) } $base_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=view&action=view_folder&f=$folder_id&$u_sort_param"); - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $pm_count, $config['topics_per_page'], $start); + $start = $pagination->validate_start($start, $config['topics_per_page'], $pm_count); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $pm_count, $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $pm_count, $config['topics_per_page'], $start), 'TOTAL_MESSAGES' => $user->lang('VIEW_PM_MESSAGES', (int) $pm_count), 'POST_IMG' => (!$auth->acl_get('u_sendpm')) ? $user->img('button_topic_locked', 'POST_PM_LOCKED') : $user->img('button_pm_new', 'POST_NEW_PM'), @@ -481,14 +483,10 @@ function get_pm_from($folder_id, $folder, $user_id) { $store_reverse = true; - if ($start + $config['topics_per_page'] > $pm_count) - { - $sql_limit = min($config['topics_per_page'], max(1, $pm_count - $start)); - } - // Select the sort order $direction = ($sort_dir == 'd') ? 'ASC' : 'DESC'; - $sql_start = max(0, $pm_count - $sql_limit - $start); + $sql_limit = $pagination->reverse_limit($start, $sql_limit, $pm_count); + $sql_start = $pagination->reverse_start($start, $sql_limit, $pm_count); } else { diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index c7b4489daf..364d0caf25 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -20,7 +20,7 @@ if (!defined('IN_PHPBB')) */ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) { - global $user, $template, $auth, $db, $cache; + global $user, $template, $auth, $db, $cache, $phpbb_container; global $phpbb_root_path, $request, $phpEx, $config, $phpbb_dispatcher; $user->add_lang(array('viewtopic', 'memberlist')); @@ -61,13 +61,9 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) // Load the custom profile fields if ($config['load_cpf_pm']) { - if (!class_exists('custom_profile')) - { - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - } - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields.manager'); - $profile_fields = $cp->generate_profile_fields_template('grab', $author_id); + $profile_fields = $cp->grab_profile_fields_data($author_id); } // Assign TO/BCC Addresses to template @@ -177,7 +173,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) if (isset($profile_fields[$author_id])) { - $cp_row = $cp->generate_profile_fields_template('show', false, $profile_fields[$author_id]); + $cp_row = $cp->generate_profile_fields_template_data($profile_fields[$author_id]); } } @@ -192,7 +188,6 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) 'AUTHOR_AVATAR' => (isset($user_info['avatar'])) ? $user_info['avatar'] : '', 'AUTHOR_JOINED' => $user->format_date($user_info['user_regdate']), 'AUTHOR_POSTS' => (int) $user_info['user_posts'], - 'AUTHOR_FROM' => (!empty($user_info['user_from'])) ? $user_info['user_from'] : '', 'ONLINE_IMG' => (!$config['load_onlinetrack']) ? '' : ((isset($user_info['online']) && $user_info['online']) ? $user->img('icon_user_online', $user->lang['ONLINE']) : $user->img('icon_user_offline', $user->lang['OFFLINE'])), 'S_ONLINE' => (!$config['load_onlinetrack']) ? false : ((isset($user_info['online']) && $user_info['online']) ? true : false), @@ -214,11 +209,6 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) 'MESSAGE_ID' => $message_row['msg_id'], 'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($user_info['user_allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose&u=' . $author_id) : '', - 'U_WWW' => (!empty($user_info['user_website'])) ? $user_info['user_website'] : '', - 'U_ICQ' => ($user_info['user_icq']) ? 'http://www.icq.com/people/' . urlencode($user_info['user_icq']) . '/' : '', - 'U_AIM' => ($user_info['user_aim'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=aim&u=' . $author_id) : '', - 'U_YIM' => ($user_info['user_yim']) ? 'http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($user_info['user_yim']) . '&.src=pg' : '', - 'U_MSN' => ($user_info['user_msnm'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=msnm&u=' . $author_id) : '', 'U_JABBER' => ($user_info['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=jabber&u=' . $author_id) : '', 'U_DELETE' => ($auth->acl_get('u_pm_delete')) ? "$url&mode=compose&action=delete&f=$folder_id&p=" . $message_row['msg_id'] : '', @@ -254,13 +244,22 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) * @var string mode Active module * @var int folder_id ID of the folder the message is in * @var int msg_id ID of the private message - * var array folder Array with data of user's message folders - * @var array message_row Array with message data + * @var array folder Array with data of user's message folders + * @var array message_row Array with message data * @var array cp_row Array with senders custom profile field data * @var array msg_data Template array with message data - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('id', 'mode', 'folder_id', 'msg_id', 'folder', 'message_row', 'cp_row', 'msg_data'); + $vars = array( + 'id', + 'mode', + 'folder_id', + 'msg_id', + 'folder', + 'message_row', + 'cp_row', + 'msg_data', + ); extract($phpbb_dispatcher->trigger_event('core.ucp_pm_view_messsage', compact($vars))); $template->assign_vars($msg_data); @@ -279,12 +278,12 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) // Display not already displayed Attachments for this post, we already parsed them. ;) if (isset($attachments) && sizeof($attachments)) { - $methods = phpbb_gen_download_links('post_msg_id', $msg_id, $phpbb_root_path, $phpEx); + $methods = phpbb_gen_download_links('msg_id', $msg_id, $phpbb_root_path, $phpEx); foreach ($methods as $method) { $template->assign_block_vars('dl_method', $method); } - + foreach ($attachments as $attachment) { $template->assign_block_vars('attachment', array( @@ -348,13 +347,13 @@ function get_user_information($user_id, $user_row) } } - if (!function_exists('phpbb_get_user_avatar')) + $user_row['avatar'] = ($user->optionget('viewavatars')) ? phpbb_get_user_avatar($user_row) : ''; + + if (!function_exists('get_user_rank')) { include($phpbb_root_path . 'includes/functions_display.' . $phpEx); } - $user_row['avatar'] = ($user->optionget('viewavatars')) ? phpbb_get_user_avatar($user_row) : ''; - get_user_rank($user_row['user_rank'], $user_row['user_posts'], $user_row['rank_title'], $user_row['rank_image'], $user_row['rank_image_src']); if ((!empty($user_row['user_allow_viewemail']) && $auth->acl_get('u_sendemail')) || $auth->acl_get('a_email')) diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index e80cc2dce3..e3339c4c0b 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -64,7 +64,7 @@ class ucp_prefs * @var bool submit Do we display the form only * or did the user press submit * @var array data Array with current ucp options data - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('submit', 'data'); extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_personal_data', compact($vars))); @@ -113,7 +113,7 @@ class ucp_prefs * @event core.ucp_prefs_personal_update_data * @var array data Submitted display options data * @var array sql_ary Display options data we udpate - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('data', 'sql_ary'); extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_personal_update_data', compact($vars))); @@ -243,7 +243,7 @@ class ucp_prefs * @var bool submit Do we display the form only * or did the user press submit * @var array data Array with current ucp options data - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('submit', 'data'); extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_view_data', compact($vars))); @@ -292,7 +292,7 @@ class ucp_prefs * @event core.ucp_prefs_view_update_data * @var array data Submitted display options data * @var array sql_ary Display options data we udpate - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('data', 'sql_ary'); extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_view_update_data', compact($vars))); @@ -394,7 +394,7 @@ class ucp_prefs * @var bool submit Do we display the form only * or did the user press submit * @var array data Array with current ucp options data - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('submit', 'data'); extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_post_data', compact($vars))); @@ -418,7 +418,7 @@ class ucp_prefs * @event core.ucp_prefs_post_update_data * @var array data Submitted display options data * @var array sql_ary Display options data we udpate - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('data', 'sql_ary'); extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_post_update_data', compact($vars))); diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 8ae7acaa11..00b53b6576 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -29,8 +29,7 @@ class ucp_profile function main($id, $mode) { global $cache, $config, $db, $user, $auth, $template, $phpbb_root_path, $phpEx; - global $request; - global $phpbb_container; + global $request, $phpbb_container; $user->add_lang('posting'); @@ -82,13 +81,16 @@ class ucp_profile $error[] = ($data['password_confirm']) ? 'NEW_PASSWORD_ERROR' : 'NEW_PASSWORD_CONFIRM_EMPTY'; } + // Instantiate passwords manager + $passwords_manager = $phpbb_container->get('passwords.manager'); + // Only check the new password against the previous password if there have been no errors - if (!sizeof($error) && $auth->acl_get('u_chgpasswd') && $data['new_password'] && phpbb_check_hash($data['new_password'], $user->data['user_password'])) + if (!sizeof($error) && $auth->acl_get('u_chgpasswd') && $data['new_password'] && $passwords_manager->check($data['new_password'], $user->data['user_password'])) { $error[] = 'SAME_PASSWORD_ERROR'; } - if (!phpbb_check_hash($data['cur_password'], $user->data['user_password'])) + if (!$passwords_manager->check($data['cur_password'], $user->data['user_password'])) { $error[] = ($data['cur_password']) ? 'CUR_PASSWORD_ERROR' : 'CUR_PASSWORD_EMPTY'; } @@ -105,7 +107,7 @@ class ucp_profile 'username_clean' => ($auth->acl_get('u_chgname') && $config['allow_namechange']) ? utf8_clean_string($data['username']) : $user->data['username_clean'], 'user_email' => ($auth->acl_get('u_chgemail')) ? $data['email'] : $user->data['user_email'], 'user_email_hash' => ($auth->acl_get('u_chgemail')) ? phpbb_email_hash($data['email']) : $user->data['user_email_hash'], - 'user_password' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? phpbb_hash($data['new_password']) : $user->data['user_password'], + 'user_password' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? $passwords_manager->hash($data['new_password']) : $user->data['user_password'], 'user_passchg' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? time() : 0, ); @@ -114,7 +116,7 @@ class ucp_profile add_log('user', $user->data['user_id'], 'LOG_USER_UPDATE_NAME', $user->data['username'], $data['username']); } - if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && !phpbb_check_hash($data['new_password'], $user->data['user_password'])) + if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && !$passwords_manager->check($data['new_password'], $user->data['user_password'])) { $user->reset_login_keys(); add_log('user', $user->data['user_id'], 'LOG_USER_NEW_PASSWORD', $data['username']); @@ -257,22 +259,12 @@ class ucp_profile trigger_error('NO_AUTH_PROFILEINFO'); } - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields.manager'); $cp_data = $cp_error = array(); $data = array( - 'icq' => request_var('icq', $user->data['user_icq']), - 'aim' => request_var('aim', $user->data['user_aim']), - 'msn' => request_var('msn', $user->data['user_msnm']), - 'yim' => request_var('yim', $user->data['user_yim']), 'jabber' => utf8_normalize_nfc(request_var('jabber', $user->data['user_jabber'], true)), - 'website' => request_var('website', $user->data['user_website']), - 'location' => utf8_normalize_nfc(request_var('location', $user->data['user_from'], true)), - 'occupation' => utf8_normalize_nfc(request_var('occupation', $user->data['user_occ'], true)), - 'interests' => utf8_normalize_nfc(request_var('interests', $user->data['user_interests'], true)), ); if ($config['allow_birthdays']) @@ -295,21 +287,9 @@ class ucp_profile if ($submit) { $validate_array = array( - 'icq' => array( - array('string', true, 3, 15), - array('match', true, '#^[0-9]+$#i')), - 'aim' => array('string', true, 3, 255), - 'msn' => array('string', true, 5, 255), 'jabber' => array( array('string', true, 5, 255), array('jabber')), - 'yim' => array('string', true, 5, 255), - 'website' => array( - array('string', true, 12, 255), - array('match', true, '#^http[s]?://(.*?\.)*?[a-z0-9\-]+\.[a-z]{2,4}#i')), - 'location' => array('string', true, 2, 100), - 'occupation' => array('string', true, 2, 500), - 'interests' => array('string', true, 2, 500), ); if ($config['allow_birthdays']) @@ -349,15 +329,7 @@ class ucp_profile } $sql_ary = array( - 'user_icq' => $data['icq'], - 'user_aim' => $data['aim'], - 'user_msnm' => $data['msn'], - 'user_yim' => $data['yim'], 'user_jabber' => $data['jabber'], - 'user_website' => $data['website'], - 'user_from' => $data['location'], - 'user_occ' => $data['occupation'], - 'user_interests'=> $data['interests'], 'user_notify_type' => $data['notify'], ); @@ -419,16 +391,7 @@ class ucp_profile $template->assign_vars(array( 'ERROR' => (sizeof($error)) ? implode('<br />', $error) : '', - - 'ICQ' => $data['icq'], - 'YIM' => $data['yim'], - 'AIM' => $data['aim'], - 'MSN' => $data['msn'], 'JABBER' => $data['jabber'], - 'WEBSITE' => $data['website'], - 'LOCATION' => $data['location'], - 'OCCUPATION'=> $data['occupation'], - 'INTERESTS' => $data['interests'], )); // Get additional profile fields and assign them to the template block var 'profile_fields' @@ -552,10 +515,6 @@ class ucp_profile break; case 'avatar': - if (!function_exists('phpbb_get_user_avatar')) - { - include($phpbb_root_path . 'includes/functions_display.' . $phpEx); - } add_form_key('ucp_avatar'); @@ -567,7 +526,7 @@ class ucp_profile $avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers(); // This is normalised data, without the user_ prefix - $avatar_data = \phpbb\avatar\manager::clean_row($user->data); + $avatar_data = \phpbb\avatar\manager::clean_row($user->data, 'user'); if ($submit) { @@ -603,7 +562,7 @@ class ucp_profile } else { - if ($driver = $phpbb_avatar_manager->get_driver($user->data['user_avatar_type'])) + if ($driver = $phpbb_avatar_manager->get_driver($avatar_data['avatar_type'])) { $driver->delete($avatar_data); } @@ -658,10 +617,10 @@ class ucp_profile )); } } - } - // Replace "error" strings with their real, localised form - $error = $phpbb_avatar_manager->localize_errors($user, $error); + // Replace "error" strings with their real, localised form + $error = $phpbb_avatar_manager->localize_errors($user, $error); + } $avatar = phpbb_get_user_avatar($user->data, 'USER_AVATAR', true); @@ -713,15 +672,14 @@ class ucp_profile $sql = 'SELECT key_id, last_ip, last_login FROM ' . SESSIONS_KEYS_TABLE . ' - WHERE user_id = ' . (int) $user->data['user_id']; + WHERE user_id = ' . (int) $user->data['user_id'] . ' + ORDER BY last_login ASC'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $template->assign_block_vars('sessions', array( - 'errors' => $error, - 'KEY' => $row['key_id'], 'IP' => $row['last_ip'], 'LOGIN_TIME' => $user->format_date($row['last_login']), @@ -734,6 +692,8 @@ class ucp_profile } $template->assign_vars(array( + 'ERROR' => (sizeof($error)) ? implode('<br />', $error) : '', + 'L_TITLE' => $user->lang['UCP_PROFILE_' . strtoupper($mode)], 'S_HIDDEN_FIELDS' => $s_hidden_fields, diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 1f9ab23326..ff51ca7b3c 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -35,8 +35,6 @@ class ucp_register trigger_error('UCP_REGISTER_DISABLE'); } - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - $coppa = $request->is_set('coppa') ? (int) $request->variable('coppa', false) : false; $agreed = $request->variable('agreed', false); $submit = $request->is_set_post('submit'); @@ -78,7 +76,7 @@ class ucp_register } } - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields.manager'); $error = $cp_data = $cp_error = array(); $s_hidden_fields = array(); @@ -294,9 +292,12 @@ class ucp_register $user_inactive_time = 0; } + // Instantiate passwords manager + $passwords_manager = $phpbb_container->get('passwords.manager'); + $user_row = array( 'username' => $data['username'], - 'user_password' => phpbb_hash($data['new_password']), + 'user_password' => $passwords_manager->hash($data['new_password']), 'user_email' => $data['email'], 'group_id' => (int) $group_id, 'user_timezone' => $data['tz'], @@ -379,41 +380,16 @@ class ucp_register } $messenger->send(NOTIFY_EMAIL); + } - if ($config['require_activation'] == USER_ACTIVATION_ADMIN) - { - // Grab an array of user_id's with a_user permissions ... these users can activate a user - $admin_ary = $auth->acl_get_list(false, 'a_user', false); - $admin_ary = (!empty($admin_ary[0]['a_user'])) ? $admin_ary[0]['a_user'] : array(); - - // Also include founders - $where_sql = ' WHERE user_type = ' . USER_FOUNDER; - - if (sizeof($admin_ary)) - { - $where_sql .= ' OR ' . $db->sql_in_set('user_id', $admin_ary); - } - - $sql = 'SELECT user_id, username, user_email, user_lang, user_jabber, user_notify_type - FROM ' . USERS_TABLE . ' ' . - $where_sql; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $messenger->template('admin_activate', $row['user_lang']); - $messenger->set_addresses($row); - - $messenger->assign_vars(array( - 'USERNAME' => htmlspecialchars_decode($data['username']), - 'U_USER_DETAILS' => "$server_url/memberlist.$phpEx?mode=viewprofile&u=$user_id", - 'U_ACTIVATE' => "$server_url/ucp.$phpEx?mode=activate&u=$user_id&k=$user_actkey") - ); - - $messenger->send($row['user_notify_type']); - } - $db->sql_freeresult($result); - } + if ($config['require_activation'] == USER_ACTIVATION_ADMIN) + { + $phpbb_notifications = $phpbb_container->get('notification_manager'); + $phpbb_notifications->add_notifications('admin_activate_user', array( + 'user_id' => $user_id, + 'user_actkey' => $user_row['user_actkey'], + 'user_regdate' => $user_row['user_regdate'], + )); } // Perform account linking if necessary diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index b3def63896..99e945eeae 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -27,7 +27,7 @@ class ucp_remind function main($id, $mode) { global $config, $phpbb_root_path, $phpEx; - global $db, $user, $auth, $template; + global $db, $user, $auth, $template, $phpbb_container; if (!$config['allow_password_reset']) { @@ -88,8 +88,11 @@ class ucp_remind // For the activation key a random length between 6 and 10 will do. $user_actkey = gen_rand_string(mt_rand(6, 10)); + // Instantiate passwords manager + $passwords_manager = $phpbb_container->get('passwords.manager'); + $sql = 'UPDATE ' . USERS_TABLE . " - SET user_newpasswd = '" . $db->sql_escape(phpbb_hash($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "' + SET user_newpasswd = '" . $db->sql_escape($passwords_manager->hash($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "' WHERE user_id = " . $user_row['user_id']; $db->sql_query($sql); diff --git a/phpBB/includes/ucp/ucp_zebra.php b/phpBB/includes/ucp/ucp_zebra.php index 6bb3cdc145..bf9a15027a 100644 --- a/phpBB/includes/ucp/ucp_zebra.php +++ b/phpBB/includes/ucp/ucp_zebra.php @@ -62,9 +62,9 @@ class ucp_zebra * @event core.ucp_remove_zebra * @var string mode Zebra type: friends|foes * @var array user_ids User ids we remove - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('user_ids'); + $vars = array('mode', 'user_ids'); extract($phpbb_dispatcher->trigger_event('core.ucp_remove_zebra', compact($vars))); $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' @@ -207,7 +207,7 @@ class ucp_zebra * friends|foes * @var array sql_ary Array of * entries we add - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('mode', 'sql_ary'); extract($phpbb_dispatcher->trigger_event('core.ucp_add_zebra', compact($vars))); @@ -224,15 +224,15 @@ class ucp_zebra } } } - + if ($request->is_ajax()) { $message = ($updated) ? $user->lang[$l_mode . '_UPDATED'] : implode('<br />', $error); - + $json_response = new \phpbb\json_response; $json_response->send(array( 'success' => $updated, - + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], 'MESSAGE_TEXT' => $message, 'REFRESH_DATA' => array( diff --git a/phpBB/includes/utf/utf_normalizer.php b/phpBB/includes/utf/utf_normalizer.php index a208552d53..f8c9c76d4f 100644 --- a/phpBB/includes/utf/utf_normalizer.php +++ b/phpBB/includes/utf/utf_normalizer.php @@ -479,7 +479,6 @@ class utf_normalizer continue; } - // STEP 1: Decompose current char // We have found a character that is either: @@ -527,7 +526,6 @@ class utf_normalizer $utf_seq = array($utf_char); } - // STEP 2: Capture the starter // Check out the combining class of the first character of the UTF sequence @@ -683,7 +681,6 @@ class utf_normalizer } } - // STEP 3: Capture following combining modifiers while ($pos < $len) @@ -752,7 +749,6 @@ class utf_normalizer } } - // STEP 4: Sort and combine // Here we sort... @@ -991,7 +987,6 @@ class utf_normalizer $tmp_pos = $last_cc = $sort = $dump = 0; $utf_sort = array(); - // Main loop do { @@ -1047,7 +1042,6 @@ class utf_normalizer continue; } - // STEP 1: Decide what to do with current char // Now, in that order: diff --git a/phpBB/index.php b/phpBB/index.php index 74fc1b9bda..1c481d4363 100644 --- a/phpBB/index.php +++ b/phpBB/index.php @@ -27,24 +27,44 @@ $user->setup('viewforum'); // Mark notifications read if (($mark_notification = $request->variable('mark_notification', 0))) { - $phpbb_notifications = $phpbb_container->get('notification_manager'); - - $notification = $phpbb_notifications->load_notifications(array( - 'notification_id' => $mark_notification - )); + if ($user->data['user_id'] == ANONYMOUS) + { + if ($request->is_ajax()) + { + trigger_error('LOGIN_REQUIRED'); + } + login_box('', $user->lang['LOGIN_REQUIRED']); + } - if (isset($notification['notifications'][$mark_notification])) + if (check_link_hash($request->variable('hash', ''), 'mark_notification_read')) { - $notification = $notification['notifications'][$mark_notification]; + $phpbb_notifications = $phpbb_container->get('notification_manager'); - $notification->mark_read(); + $notification = $phpbb_notifications->load_notifications(array( + 'notification_id' => $mark_notification, + )); - if (($redirect = $request->variable('redirect', ''))) + if (isset($notification['notifications'][$mark_notification])) { - redirect(append_sid($phpbb_root_path . $redirect)); - } + $notification = $notification['notifications'][$mark_notification]; + + $notification->mark_read(); + + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response(); + $json_response->send(array( + 'success' => true, + )); + } - redirect($notification->get_url()); + if (($redirect = $request->variable('redirect', ''))) + { + redirect(append_sid($phpbb_root_path . $redirect)); + } + + redirect($notification->get_redirect_url()); + } } } @@ -153,7 +173,9 @@ $template->assign_vars(array( 'FORUM_UNREAD_LOCKED_IMG' => $user->img('forum_unread_locked', 'UNREAD_POSTS_LOCKED'), 'S_LOGIN_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'), + 'U_SEND_PASSWORD' => ($config['email_enable']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=sendpassword') : '', 'S_DISPLAY_BIRTHDAY_LIST' => ($config['load_birthdays']) ? true : false, + 'S_INDEX' => true, 'U_MARK_FORUMS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}index.$phpEx", 'hash=' . generate_link_hash('global') . '&mark=forums&mark_time=' . time()) : '', 'U_MCP' => ($auth->acl_get('m_') || $auth->acl_getf_global('m_')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&mode=front', true, $user->session_id) : '') @@ -166,13 +188,13 @@ $page_title = $user->lang['INDEX']; * * @event core.index_modify_page_title * @var string page_title Title of the index page -* @since 3.1-A1 +* @since 3.1.0-a1 */ $vars = array('page_title'); extract($phpbb_dispatcher->trigger_event('core.index_modify_page_title', compact($vars))); // Output page -page_header($page_title); +page_header($page_title, true); $template->set_filenames(array( 'body' => 'index_body.html') diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index 4532ecb609..926f139da4 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -33,7 +33,7 @@ $dbms = phpbb_convert_30_dbms_to_31($dbms); $convertor_data = array( 'forum_name' => 'phpBB 2.0.x', 'version' => '1.0.3', - 'phpbb_version' => '3.1.0-dev', + 'phpbb_version' => '3.1.0-b2', 'author' => '<a href="https://www.phpbb.com/">phpBB Group</a>', 'dbms' => $dbms, 'dbhost' => $dbhost, @@ -136,7 +136,7 @@ $config_schema = array( 'avatar_max_width' => 'avatar_max_width', 'avatar_max_height' => 'avatar_max_height', 'default_dateformat' => 'phpbb_set_encoding(default_dateformat)', - 'board_timezone' => 'board_timezone', + 'board_timezone' => 'phpbb_convert_timezone(board_timezone)', 'allow_privmsg' => 'not(privmsg_disable)', 'gzip_compress' => 'gzip_compress', 'coppa_enable' => '!is_empty(coppa_mail)', @@ -341,6 +341,9 @@ if (!$get_info) update_folder_pm_count(); ', ' update_unread_count(); + ', (defined('MOD_ATTACHMENT')) ? ' + phpbb_attachment_extension_group_name(); + ' : ' ', ' phpbb_convert_authentication(\'start\'); ', ' @@ -399,7 +402,7 @@ if (!$get_info) array('is_orphan', 0, ''), array('poster_id', 'attachments.user_id_1 AS poster_id', 'phpbb_user_id'), array('physical_filename', 'attachments_desc.physical_filename', 'import_attachment'), - array('real_filename', 'attachments_desc.real_filename', ''), + array('real_filename', 'attachments_desc.real_filename', 'phpbb_set_encoding'), array('download_count', 'attachments_desc.download_count', ''), array('attach_comment', 'attachments_desc.comment', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), array('extension', 'attachments_desc.extension', ''), @@ -497,7 +500,7 @@ if (!$get_info) array('topic_title', 'topics.topic_title', 'phpbb_set_encoding'), array('topic_time', 'topics.topic_time', ''), array('topic_views', 'topics.topic_views', ''), - array('topic_posts_approved', 'topics.topic_replies + 1', ''), + array('topic_posts_approved', 'topics.topic_replies', 'phpbb_topic_replies_to_posts'), array('topic_posts_unapproved', 0, ''), array('topic_posts_softdeleted',0, ''), array('topic_last_post_id', 'topics.topic_last_post_id', ''), @@ -506,6 +509,8 @@ if (!$get_info) array('topic_type', 'topics.topic_type', 'phpbb_convert_topic_type'), array('topic_first_post_id', 'topics.topic_first_post_id', ''), array('topic_last_view_time', 'posts.post_time', 'intval'), + array('topic_visibility', ITEM_APPROVED, ''), + array('poll_title', 'vote_desc.vote_text', array('function1' => 'null_to_str', 'function2' => 'phpbb_set_encoding', 'function3' => 'htmlspecialchars_decode', 'function4' => 'utf8_htmlspecialchars')), array('poll_start', 'vote_desc.vote_start', 'null_to_zero'), array('poll_length', 'vote_desc.vote_length', 'null_to_zero'), @@ -531,7 +536,7 @@ if (!$get_info) array('topic_title', 'topics.topic_title', 'phpbb_set_encoding'), array('topic_time', 'topics.topic_time', ''), array('topic_views', 'topics.topic_views', ''), - array('topic_posts_approved', 'topics.topic_replies + 1', ''), + array('topic_posts_approved', 'topics.topic_replies', 'phpbb_topic_replies_to_posts'), array('topic_posts_unapproved', 0, ''), array('topic_posts_softdeleted',0, ''), array('topic_last_post_id', 'topics.topic_last_post_id', ''), @@ -539,6 +544,7 @@ if (!$get_info) array('topic_moved_id', 'topics.topic_moved_id', ''), array('topic_type', 'topics.topic_type', 'phpbb_convert_topic_type'), array('topic_first_post_id', 'topics.topic_first_post_id', ''), + array('topic_visibility', ITEM_APPROVED, ''), array('poll_title', 'vote_desc.vote_text', array('function1' => 'null_to_str', 'function2' => 'phpbb_set_encoding', 'function3' => 'htmlspecialchars_decode', 'function4' => 'utf8_htmlspecialchars')), array('poll_start', 'vote_desc.vote_start', 'null_to_zero'), @@ -646,6 +652,7 @@ if (!$get_info) array('post_edit_count', 'posts.post_edit_count', ''), array('post_edit_reason', '', ''), array('post_edit_user', '', 'phpbb_post_edit_user'), + array('post_visibility', ITEM_APPROVED, ''), array('bbcode_uid', 'posts.post_time', 'make_uid'), array('post_text', 'posts_text.post_text', 'phpbb_prepare_message'), @@ -821,7 +828,10 @@ if (!$get_info) array( 'target' => GROUPS_TABLE, 'autoincrement' => 'group_id', - 'query_first' => array('target', $convert->truncate_statement . GROUPS_TABLE), + 'query_first' => array( + array('target', $convert->truncate_statement . GROUPS_TABLE), + array('target', $convert->truncate_statement . TEAMPAGE_TABLE), + ), array('group_id', 'groups.group_id', ''), array('group_type', 'groups.group_type', 'phpbb_convert_group_type'), @@ -838,6 +848,7 @@ if (!$get_info) 'query_first' => array('target', $convert->truncate_statement . USER_GROUP_TABLE), 'execute_first' => ' add_default_groups(); + add_groups_to_teampage(); ', array('group_id', 'groups.group_id', ''), @@ -865,7 +876,8 @@ if (!$get_info) 'autoincrement' => 'user_id', 'query_first' => array( array('target', 'DELETE FROM ' . USERS_TABLE . ' WHERE user_id <> ' . ANONYMOUS), - array('target', $convert->truncate_statement . BOTS_TABLE) + array('target', $convert->truncate_statement . BOTS_TABLE), + array('target', $convert->truncate_statement . USER_NOTIFICATIONS_TABLE), ), 'execute_last' => ' @@ -889,20 +901,12 @@ if (!$get_info) array('user_lastmark', 'users.user_lastvisit', 'intval'), array('user_lang', $config['default_lang'], ''), array('', 'users.user_lang', ''), - array('user_timezone', 'users.user_timezone', 'floatval'), + array('user_timezone', 'users.user_timezone', 'phpbb_convert_timezone'), array('user_dateformat', 'users.user_dateformat', array('function1' => 'phpbb_set_encoding', 'function2' => 'fill_dateformat')), array('user_inactive_reason', '', 'phpbb_inactive_reason'), array('user_inactive_time', '', 'phpbb_inactive_time'), - array('user_interests', 'users.user_interests', array('function1' => 'phpbb_set_encoding')), - array('user_occ', 'users.user_occ', array('function1' => 'phpbb_set_encoding')), - array('user_website', 'users.user_website', 'validate_website'), array('user_jabber', '', ''), - array('user_msnm', 'users.user_msnm', array('function1' => 'phpbb_set_encoding')), - array('user_yim', 'users.user_yim', array('function1' => 'phpbb_set_encoding')), - array('user_aim', 'users.user_aim', array('function1' => 'phpbb_set_encoding')), - array('user_icq', 'users.user_icq', array('function1' => 'phpbb_set_encoding')), - array('user_from', 'users.user_from', array('function1' => 'phpbb_set_encoding')), array('user_rank', 'users.user_rank', 'intval'), array('user_permissions', '', ''), @@ -938,6 +942,28 @@ if (!$get_info) array('user_sig_bbcode_bitfield', '', 'get_bbcode_bitfield'), array('', 'users.user_regdate AS post_time', ''), + array('', 'users.user_notify_pm', 'phpbb_add_notification_options'), + + 'where' => 'users.user_id <> -1', + ), + + array( + 'target' => PROFILE_FIELDS_DATA_TABLE, + 'primary' => 'users.user_id', + 'query_first' => array( + array('target', $convert->truncate_statement . PROFILE_FIELDS_DATA_TABLE), + ), + + array('user_id', 'users.user_id', 'phpbb_user_id'), + array('pf_phpbb_occupation', 'users.user_occ', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_interests', 'users.user_interests', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_location', 'users.user_from', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_icq', 'users.user_icq', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_wlm', 'users.user_msnm', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_yahoo', 'users.user_yim', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_aol', 'users.user_aim', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_website', 'users.user_website', 'validate_website'), + 'where' => 'users.user_id <> -1', ), ), diff --git a/phpBB/install/convertors/functions_phpbb20.php b/phpBB/install/convertors/functions_phpbb20.php index a698f0ef13..f3b8c82131 100644 --- a/phpBB/install/convertors/functions_phpbb20.php +++ b/phpBB/install/convertors/functions_phpbb20.php @@ -71,7 +71,6 @@ function phpbb_insert_forums() $prune_enabled = (int) $src_db->sql_fetchfield('config_value'); $src_db->sql_freeresult($result); - // Insert categories $sql = 'SELECT cat_id, cat_title FROM ' . $convert->src_table_prefix . 'categories @@ -540,6 +539,15 @@ function phpbb_user_id($user_id) return (int) $user_id; } +/** +* Return correct user id value +* Everyone's id will be one higher to allow the guest/anonymous user to have a positive id as well +*/ +function phpbb_topic_replies_to_posts($num_replies) +{ + return (int) $num_replies + 1; +} + /* Copy additional table fields from old forum to new forum if user wants this (for Mod compatibility for example) function phpbb_copy_table_fields() { @@ -562,7 +570,6 @@ function phpbb_convert_authentication($mode) // What we will do is handling all 2.0.x admins as founder to replicate what is common in 2.0.x. // After conversion the main admin need to make sure he is removing permissions and the founder status if wanted. - // Grab user ids of users with user_level of ADMIN $sql = "SELECT user_id FROM {$convert->src_table_prefix}users @@ -1406,6 +1413,55 @@ function phpbb_attachment_category($cat_id) } /** +* Convert the attachment extension names +* This is only used if the Attachment MOD was installed +*/ +function phpbb_attachment_extension_group_name() +{ + global $db, $phpbb_root_path, $phpEx; + + // Update file extension group names to use language strings. + $sql = 'SELECT lang_dir + FROM ' . LANG_TABLE; + $result = $db->sql_query($sql); + + $extension_groups_updated = array(); + while ($lang_dir = $db->sql_fetchfield('lang_dir')) + { + $lang_dir = basename($lang_dir); + $lang_file = $phpbb_root_path . 'language/' . $lang_dir . '/acp/attachments.' . $phpEx; + + if (!file_exists($lang_file)) + { + continue; + } + + $lang = array(); + include($lang_file); + + foreach ($lang as $lang_key => $lang_val) + { + if (isset($extension_groups_updated[$lang_key]) || strpos($lang_key, 'EXT_GROUP_') !== 0) + { + continue; + } + + $sql_ary = array( + 'group_name' => substr($lang_key, 10), // Strip off 'EXT_GROUP_' + ); + + $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " + WHERE group_name = '" . $db->sql_escape($lang_val) . "'"; + $db->sql_query($sql); + + $extension_groups_updated[$lang_key] = true; + } + } + $db->sql_freeresult($result); +} + +/** * Obtain list of forums in which different attachment categories can be used */ function phpbb_attachment_forum_perms($forum_permissions) @@ -1868,3 +1924,50 @@ function phpbb_check_username_collisions() $drop_sql = 'DROP TABLE ' . USERCONV_TABLE; $db->sql_query($drop_sql); } + +function phpbb_convert_timezone($timezone) +{ + global $config, $db, $phpbb_root_path, $phpEx, $table_prefix; + $timezone_migration = new \phpbb\db\migration\data\v310\timezone($config, $db, new \phpbb\db\tools($db), $phpbb_root_path, $phpEx, $table_prefix); + return $timezone_migration->convert_phpbb30_timezone($timezone, 0); +} + +function phpbb_add_notification_options($user_notify_pm) +{ + global $convert_row, $db; + + $user_id = phpbb_user_id($convert_row['user_id']); + if ($user_id == ANONYMOUS) + { + return; + } + + $rows = array(); + + $rows[] = array( + 'item_type' => 'post', + 'item_id' => 0, + 'user_id' => (int) $user_id, + 'notify' => 1, + 'method' => 'email', + ); + $rows[] = array( + 'item_type' => 'topic', + 'item_id' => 0, + 'user_id' => (int) $user_id, + 'notify' => 1, + 'method' => 'email', + ); + if ($user_notify_pm) + { + $rows[] = array( + 'item_type' => 'pm', + 'item_id' => 0, + 'user_id' => (int) $user_id, + 'notify' => 1, + 'method' => 'email', + ); + } + + $sql = $db->sql_multi_insert(USER_NOTIFICATIONS_TABLE, $rows); +} diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index fa8ec6b6ce..6c9eeb6a75 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -169,6 +169,8 @@ header('Content-type: text/html; charset=UTF-8'); <?php +define('IN_DB_UPDATE', true); + /** * @todo firebird/mysql update? */ @@ -203,10 +205,20 @@ $migrations = $finder $migrator->set_migrations($migrations); // What is a safe limit of execution time? Half the max execution time should be safe. -$safe_time_limit = (ini_get('max_execution_time') / 2); +// No more than 15 seconds so the user isn't sitting and waiting for a very long time +$phpbb_ini = new \phpbb\php\ini(); +$safe_time_limit = min(15, ($phpbb_ini->get_int('max_execution_time') / 2)); + +// While we're going to try limit this to half the max execution time, +// we want to try and take additional measures to prevent hitting the +// max execution time (if, say, one migration step takes much longer +// than the max execution time) +@set_time_limit(0); while (!$migrator->finished()) { + $migration_start_time = microtime(true); + try { $migrator->update(); @@ -227,20 +239,26 @@ while (!$migrator->finished()) if (isset($migrator->last_run_migration['effectively_installed']) && $migrator->last_run_migration['effectively_installed']) { - echo $user->lang('MIGRATION_EFFECTIVELY_INSTALLED', $migrator->last_run_migration['name']) . '<br />'; + echo $user->lang('MIGRATION_EFFECTIVELY_INSTALLED', $migrator->last_run_migration['name']); } else { - if ($state['migration_data_done']) + if ($migrator->last_run_migration['task'] == 'process_data_step' && $state['migration_data_done']) { - echo $user->lang('MIGRATION_DATA_DONE', $migrator->last_run_migration['name']) . '<br />'; + echo $user->lang('MIGRATION_DATA_DONE', $migrator->last_run_migration['name'], (microtime(true) - $migration_start_time)); + } + else if ($migrator->last_run_migration['task'] == 'process_data_step') + { + echo $user->lang('MIGRATION_DATA_IN_PROGRESS', $migrator->last_run_migration['name'], (microtime(true) - $migration_start_time)); } else if ($state['migration_schema_done']) { - echo $user->lang('MIGRATION_SCHEMA_DONE', $migrator->last_run_migration['name']) . '<br />'; + echo $user->lang('MIGRATION_SCHEMA_DONE', $migrator->last_run_migration['name'], (microtime(true) - $migration_start_time)); } } + echo "<br />\n"; + // Are we approaching the time limit? If so we want to pause the update and continue after refreshing if ((time() - $update_start_time) >= $safe_time_limit) { diff --git a/phpBB/install/index.php b/phpBB/install/index.php index 161dc78173..66c8559e98 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -244,14 +244,18 @@ $config = new \phpbb\config\config(array( 'load_tplcompile' => '1' )); +$symfony_request = $phpbb_container->get('symfony_request'); +$phpbb_filesystem = $phpbb_container->get('filesystem'); $phpbb_path_helper = $phpbb_container->get('path_helper'); $template = new \phpbb\template\twig\twig($phpbb_path_helper, $config, $user, new \phpbb\template\context()); $paths = array($phpbb_root_path . 'install/update/new/adm/style', $phpbb_admin_path . 'style'); $paths = array_filter($paths, 'is_dir'); $template->set_custom_style('adm', $paths); -$template->assign_var('T_ASSETS_PATH', '../assets'); -$template->assign_var('T_TEMPLATE_PATH', $phpbb_admin_path . 'style'); +$path = array_shift($paths); + +$template->assign_var('T_ASSETS_PATH', $path . '/../../assets'); +$template->assign_var('T_TEMPLATE_PATH', $path); $install = new module(); @@ -395,7 +399,7 @@ class module } define('HEADER_INC', true); - global $template, $lang, $stage, $phpbb_root_path, $phpbb_admin_path; + global $template, $lang, $stage, $phpbb_admin_path, $path; $template->assign_vars(array( 'L_CHANGE' => $lang['CHANGE'], @@ -405,7 +409,7 @@ class module 'L_SKIP' => $lang['SKIP'], 'PAGE_TITLE' => $this->get_page_title(), 'T_IMAGE_PATH' => htmlspecialchars($phpbb_admin_path) . 'images/', - 'T_JQUERY_LINK' => $phpbb_root_path . 'assets/javascript/jquery.js', + 'T_JQUERY_LINK' => $path . '/../../assets/javascript/jquery.js', 'S_CONTENT_DIRECTION' => $lang['DIRECTION'], 'S_CONTENT_FLOW_BEGIN' => ($lang['DIRECTION'] == 'ltr') ? 'left' : 'right', @@ -689,7 +693,7 @@ class module /** * Generate the relevant HTML for an input field and the associated label and explanatory text */ - function input_field($name, $type, $value='', $options='') + function input_field($name, $type, $value = '', $options = '') { global $lang; $tpl_type = explode(':', $type); @@ -716,8 +720,9 @@ class module $size = (int) $tpl_type[1]; $maxlength = (int) $tpl_type[2]; + $autocomplete = (isset($options['autocomplete']) && $options['autocomplete'] == 'off') ? ' autocomplete="off"' : ''; - $tpl = '<input id="' . $name . '" type="' . $tpl_type[0] . '"' . (($size) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength) ? $maxlength : 255) . '" name="' . $name . '" value="' . $value . '" />'; + $tpl = '<input id="' . $name . '" type="' . $tpl_type[0] . '"' . (($size) ? ' size="' . $size . '"' : '') . ' maxlength="' . (($maxlength) ? $maxlength : 255) . '" name="' . $name . '"' . $autocomplete . ' value="' . $value . '" />'; break; case 'textarea': diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php index 4d3e1d3d4a..82311bd04d 100644 --- a/phpBB/install/install_convert.php +++ b/phpBB/install/install_convert.php @@ -79,6 +79,21 @@ class convert */ class install_convert extends module { + /** @var array */ + protected $lang; + + /** @var string */ + protected $language; + + /** @var \phpbb\template\template */ + protected $template; + + /** @var string */ + protected $phpbb_root_path; + + /** @var string */ + protected $php_ext; + /** * Variables used while converting, they are accessible from the global variable $convert */ @@ -90,35 +105,34 @@ class install_convert extends module function main($mode, $sub) { global $lang, $template, $phpbb_root_path, $phpEx, $cache, $config, $language, $table_prefix; - global $convert; + global $convert, $request, $phpbb_container; $this->tpl_name = 'install_convert'; $this->mode = $mode; + $this->lang = $lang; + $this->language = $language; + $this->template = $template; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $phpEx; + + if (!$this->check_phpbb_installed()) + { + return; + } $convert = new convert($this->p_master); + // Enable super globals to prevent issues with the new \phpbb\request\request object + $request->enable_super_globals(); + // Create a normal container now + $phpbb_container = phpbb_create_default_container($phpbb_root_path, $phpEx); + + // Create cache + $cache = $phpbb_container->get('cache'); + switch ($sub) { case 'intro': - // Try opening config file - // @todo If phpBB is not installed, we need to do a cut-down installation here - // For now, we redirect to the installation script instead - if (@file_exists($phpbb_root_path . 'config.' . $phpEx)) - { - include($phpbb_root_path . 'config.' . $phpEx); - } - - if (!defined('PHPBB_INSTALLED')) - { - $template->assign_vars(array( - 'S_NOT_INSTALLED' => true, - 'TITLE' => $lang['BOARD_NOT_INSTALLED'], - 'BODY' => sprintf($lang['BOARD_NOT_INSTALLED_EXPLAIN'], append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=install&language=' . $language)), - )); - - return; - } - require($phpbb_root_path . 'config.' . $phpEx); require($phpbb_root_path . 'includes/constants.' . $phpEx); require($phpbb_root_path . 'includes/functions_convert.' . $phpEx); @@ -251,6 +265,30 @@ class install_convert extends module } /** + * Check whether phpBB is installed. + * Assigns error template vars if not installed. + * + * @return bool Returns true if phpBB is installed. + */ + public function check_phpbb_installed() + { + if (phpbb_check_installation_exists($this->phpbb_root_path, $this->php_ext)) + { + return true; + } + + $this->page_title = 'BOARD_NOT_INSTALLED'; + $install_url = append_sid($this->phpbb_root_path . 'install/index.' . $this->php_ext, 'mode=install&language=' . $this->language); + + $this->template->assign_vars(array( + 'S_NOT_INSTALLED' => true, + 'BODY' => sprintf($this->lang['BOARD_NOT_INSTALLED_EXPLAIN'], $install_url), + )); + + return false; + } + + /** * Generate a list of all available conversion modules */ function list_convertors($sub) @@ -405,7 +443,7 @@ class install_convert extends module if (!isset($available_dbms[$src_dbms]) || !$available_dbms[$src_dbms]['AVAILABLE']) { - $error['db'][] = $lang['INST_ERR_NO_DB']; + $error[] = $lang['INST_ERR_NO_DB']; $connect_test = false; } else @@ -418,6 +456,7 @@ class install_convert extends module { $error[] = sprintf($lang['TABLE_PREFIX_SAME'], $src_table_prefix); } + $src_dbms = phpbb_convert_30_dbms_to_31($src_dbms); // Check table prefix if (!sizeof($error)) @@ -1537,7 +1576,7 @@ class install_convert extends module function finish_conversion() { global $db, $phpbb_root_path, $phpEx, $convert, $config, $language, $user, $template; - global $cache, $auth; + global $cache, $auth, $phpbb_container, $phpbb_log; $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'convert_progress' @@ -1550,6 +1589,7 @@ class install_convert extends module phpbb_cache_moderators($db, $cache, $auth); // And finally, add a note to the log + $phpbb_log = $phpbb_container->get('log'); add_log('admin', 'LOG_INSTALL_CONVERTED', $convert->convertor_data['forum_name'], $config['version']); $url = $this->p_master->module_url . "?mode={$this->mode}&sub=final&language=$language"; diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index c273660d08..191be59258 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -18,14 +18,9 @@ if (!defined('IN_INSTALL')) if (!empty($setmodules)) { // If phpBB is already installed we do not include this module - if (@file_exists($phpbb_root_path . 'config.' . $phpEx) && !file_exists($phpbb_root_path . 'cache/install_lock')) + if (phpbb_check_installation_exists($phpbb_root_path, $phpEx) && !file_exists($phpbb_root_path . 'cache/install_lock')) { - include_once($phpbb_root_path . 'config.' . $phpEx); - - if (defined('PHPBB_INSTALLED')) - { - return; - } + return; } $module[] = array( @@ -222,7 +217,6 @@ class install_install extends module 'S_LEGEND' => false, )); - // Check for getimagesize if (@function_exists('getimagesize')) { @@ -540,7 +534,6 @@ class install_install extends module $url = (!in_array(false, $passed)) ? $this->p_master->module_url . "?mode=$mode&sub=database&language=$language" : $this->p_master->module_url . "?mode=$mode&sub=requirements&language=$language "; $submit = (!in_array(false, $passed)) ? $lang['INSTALL_START'] : $lang['INSTALL_TEST']; - $template->assign_vars(array( 'L_SUBMIT' => $submit, 'S_HIDDEN' => $s_hidden_fields, @@ -1156,13 +1149,9 @@ class install_install extends module // How should we treat this schema? $delimiter = $available_dbms[$data['dbms']]['DELIM']; - $sql_query = @file_get_contents($dbms_schema); - $sql_query = preg_replace('#phpbb_#i', $data['table_prefix'], $sql_query); - $sql_query = phpbb_remove_comments($sql_query); - $sql_query = split_sql_file($sql_query, $delimiter); foreach ($sql_query as $sql) @@ -1176,6 +1165,27 @@ class install_install extends module } unset($sql_query); + // Ok we have the db info go ahead and work on building the table + $db_table_schema = @file_get_contents('schemas/schema.json'); + $db_table_schema = json_decode($db_table_schema, true); + + if (!defined('CONFIG_TABLE')) + { + // CONFIG_TABLE is required by sql_create_index() to check the + // length of index names. However table_prefix is not defined + // here yet, so we need to create the constant ourselves. + define('CONFIG_TABLE', $data['table_prefix'] . 'config'); + } + + $db_tools = new \phpbb\db\tools($db); + foreach ($db_table_schema as $table_name => $table_data) + { + $db_tools->sql_create_table( + $data['table_prefix'] . substr($table_name, 6), + $table_data + ); + } + // Ok tables have been built, let's fill in the basic information $sql_query = file_get_contents('schemas/schema_data.sql'); @@ -1322,6 +1332,10 @@ class install_install extends module SET config_value = '" . md5(mt_rand()) . "' WHERE config_name = 'avatar_salt'", + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . md5(mt_rand()) . "' + WHERE config_name = 'plupload_salt'", + 'UPDATE ' . $data['table_prefix'] . "users SET username = '" . $db->sql_escape($data['admin_name']) . "', user_password='" . $db->sql_escape(md5($data['admin_pass1'])) . "', user_ip = '" . $db->sql_escape($user_ip) . "', user_lang = '" . $db->sql_escape($data['default_lang']) . "', user_email='" . $db->sql_escape($data['board_email']) . "', user_dateformat='" . $db->sql_escape($lang['default_dateformat']) . "', user_email_hash = " . $db->sql_escape(phpbb_email_hash($data['board_email'])) . ", username_clean = '" . $db->sql_escape(utf8_clean_string($data['admin_name'])) . "' WHERE username = 'Admin'", @@ -1633,6 +1647,45 @@ class install_install extends module $_module->move_module_by($row, 'move_up', 5); } + if ($module_class == 'mcp') + { + // Move pm report details module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_report_details'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'move_down', 3); + + // Move closed pm reports module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_reports_closed'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'move_down', 3); + + // Move open pm reports module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_reports'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'move_down', 3); + } + if ($module_class == 'ucp') { // Move attachment module 4 down... @@ -1646,6 +1699,30 @@ class install_install extends module $db->sql_freeresult($result); $_module->move_module_by($row, 'move_down', 4); + + // Move notification options module 4 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_notifications' + AND module_class = 'ucp' + AND module_mode = 'notification_options'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'move_down', 4); + + // Move OAuth module 5 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_auth_link' + AND module_class = 'ucp' + AND module_mode = 'auth_link'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'move_down', 5); } // And now for the special ones @@ -1714,6 +1791,7 @@ class install_install extends module $this->error('Unable to access the language directory', __LINE__, __FILE__); } + $installed_languages = array(); while (($file = readdir($dir)) !== false) { $path = $phpbb_root_path . 'language/' . $file; @@ -1737,6 +1815,7 @@ class install_install extends module $db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $lang_pack)); + $installed_languages[] = (int) $db->sql_nextid(); if ($db->sql_error_triggered) { $error = $db->sql_error($db->sql_error_sql); @@ -1745,6 +1824,29 @@ class install_install extends module } } closedir($dir); + + $sql = 'SELECT * + FROM ' . PROFILE_FIELDS_TABLE; + $result = $db->sql_query($sql); + + $profile_fields = array(); + $insert_buffer = new \phpbb\db\sql_insert_buffer($db, PROFILE_LANG_TABLE); + while ($row = $db->sql_fetchrow($result)) + { + foreach ($installed_languages as $lang_id) + { + $insert_buffer->insert(array( + 'field_id' => $row['field_id'], + 'lang_id' => $lang_id, + 'lang_name' => strtoupper(substr($row['field_name'], 6)),// Remove phpbb_ from field name + 'lang_explain' => '', + 'lang_default_value' => '', + )); + } + } + $db->sql_freeresult($result); + + $insert_buffer->flush(); } /** @@ -1993,8 +2095,8 @@ class install_install extends module 'smtp_delivery' => array('lang' => 'USE_SMTP', 'type' => 'radio:yes_no', 'explain' => true), 'smtp_host' => array('lang' => 'SMTP_SERVER', 'type' => 'text:25:50', 'explain' => false), 'smtp_auth' => array('lang' => 'SMTP_AUTH_METHOD', 'type' => 'select', 'options' => '$this->module->mail_auth_select(\'{VALUE}\')', 'explain' => true), - 'smtp_user' => array('lang' => 'SMTP_USERNAME', 'type' => 'text:25:255', 'explain' => true), - 'smtp_pass' => array('lang' => 'SMTP_PASSWORD', 'type' => 'password:25:255', 'explain' => true), + 'smtp_user' => array('lang' => 'SMTP_USERNAME', 'type' => 'text:25:255', 'explain' => true, 'options' => array('autocomplete' => 'off')), + 'smtp_pass' => array('lang' => 'SMTP_PASSWORD', 'type' => 'password:25:255', 'explain' => true, 'options' => array('autocomplete' => 'off')), 'legend2' => 'SERVER_URL_SETTINGS', 'cookie_secure' => array('lang' => 'COOKIE_SECURE', 'type' => 'radio:enabled_disabled', 'explain' => true), diff --git a/phpBB/install/install_update.php b/phpBB/install/install_update.php index b7b358ab2f..87b7d8d703 100644 --- a/phpBB/install/install_update.php +++ b/phpBB/install/install_update.php @@ -19,16 +19,7 @@ if (!defined('IN_INSTALL')) if (!empty($setmodules)) { // If phpBB is not installed we do not include this module - if (@file_exists($phpbb_root_path . 'config.' . $phpEx) && !@file_exists($phpbb_root_path . 'cache/install_lock')) - { - include_once($phpbb_root_path . 'config.' . $phpEx); - - if (!defined('PHPBB_INSTALLED')) - { - return; - } - } - else + if (!phpbb_check_installation_exists($phpbb_root_path, $phpEx) || file_exists($phpbb_root_path . 'cache/install_lock')) { return; } @@ -79,7 +70,14 @@ class install_update extends module $request->enable_super_globals(); // Create a normal container now - $phpbb_container = phpbb_create_update_container($phpbb_root_path, $phpEx, $phpbb_root_path . 'install/update/new/config'); + if (file_exists($phpbb_root_path . 'install/update/new/config')) + { + $phpbb_container = phpbb_create_update_container($phpbb_root_path, $phpEx, $phpbb_root_path . 'install/update/new/config'); + } + else + { + $phpbb_container = phpbb_create_update_container($phpbb_root_path, $phpEx, $phpbb_root_path . 'config'); + } // Writes into global $cache $cache = $phpbb_container->get('cache'); @@ -154,14 +152,23 @@ class install_update extends module )); // Get current and latest version - if (($latest_version = $cache->get('_version_info')) === false) + $version_helper = $phpbb_container->get('version_helper'); + try { - $this->latest_version = $this->get_file('version_info'); - $cache->put('_version_info', $this->latest_version); + $this->latest_version = $version_helper->get_latest_on_current_branch(true); } - else + catch (\RuntimeException $e) { - $this->latest_version = $latest_version; + $this->latest_version = false; + + $update_info = array(); + include($phpbb_root_path . 'install/update/index.' . $phpEx); + $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info; + + if ($info !== false) + { + $this->latest_version = (!empty($info['version']['to'])) ? trim($info['version']['to']) : false; + } } // For the current version we trick a bit. ;) @@ -1311,7 +1318,7 @@ class install_update extends module } }*/ - if (file_exists($phpbb_root_path . dirname($file)) || (strpos($file, 'styles/') !== 0 && strpos($file, 'language/') !== 0)) + if (!phpbb_ignore_new_file_on_update($phpbb_root_path, $file)) { $this->get_custom_info($update_list['new'], $file); $update_list['new'][] = array('filename' => $file, 'custom' => false); @@ -1606,37 +1613,6 @@ class install_update extends module switch ($mode) { - case 'version_info': - global $phpbb_root_path, $phpEx; - - $info = get_remote_file('version.phpbb.com', '/phpbb', - ((defined('PHPBB_QA')) ? '30x_qa.txt' : '30x.txt'), $errstr, $errno); - - if ($info !== false) - { - $info = explode("\n", $info); - $info = trim($info[0]); - } - - if ($this->test_update !== false) - { - $info = $this->test_update; - } - - // If info is false the fsockopen function may not be working. Instead get the latest version from our update file (and pray it is up-to-date) - if ($info === false) - { - $update_info = array(); - include($phpbb_root_path . 'install/update/index.' . $phpEx); - $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info; - - if ($info !== false) - { - $info = (!empty($info['version']['to'])) ? trim($info['version']['to']) : false; - } - } - break; - case 'update_info': global $phpbb_root_path, $phpEx; diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 1e47008d73..28649dc54c 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -3,1506 +3,3 @@ # To change the contents of this file, edit # phpBB/develop/create_schema_files.php and # run it. - -# Table: 'phpbb_attachments' -CREATE TABLE phpbb_attachments ( - attach_id INTEGER NOT NULL, - post_msg_id INTEGER DEFAULT 0 NOT NULL, - topic_id INTEGER DEFAULT 0 NOT NULL, - in_message INTEGER DEFAULT 0 NOT NULL, - poster_id INTEGER DEFAULT 0 NOT NULL, - is_orphan INTEGER DEFAULT 1 NOT NULL, - physical_filename VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - real_filename VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - download_count INTEGER DEFAULT 0 NOT NULL, - attach_comment BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - extension VARCHAR(100) CHARACTER SET NONE DEFAULT '' NOT NULL, - mimetype VARCHAR(100) CHARACTER SET NONE DEFAULT '' NOT NULL, - filesize INTEGER DEFAULT 0 NOT NULL, - filetime INTEGER DEFAULT 0 NOT NULL, - thumbnail INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_attachments ADD PRIMARY KEY (attach_id);; - -CREATE INDEX phpbb_attachments_filetime ON phpbb_attachments(filetime);; -CREATE INDEX phpbb_attachments_post_msg_id ON phpbb_attachments(post_msg_id);; -CREATE INDEX phpbb_attachments_topic_id ON phpbb_attachments(topic_id);; -CREATE INDEX phpbb_attachments_poster_id ON phpbb_attachments(poster_id);; -CREATE INDEX phpbb_attachments_is_orphan ON phpbb_attachments(is_orphan);; - -CREATE GENERATOR phpbb_attachments_gen;; -SET GENERATOR phpbb_attachments_gen TO 0;; - -CREATE TRIGGER t_phpbb_attachments FOR phpbb_attachments -BEFORE INSERT -AS -BEGIN - NEW.attach_id = GEN_ID(phpbb_attachments_gen, 1); -END;; - - -# Table: 'phpbb_acl_groups' -CREATE TABLE phpbb_acl_groups ( - group_id INTEGER DEFAULT 0 NOT NULL, - forum_id INTEGER DEFAULT 0 NOT NULL, - auth_option_id INTEGER DEFAULT 0 NOT NULL, - auth_role_id INTEGER DEFAULT 0 NOT NULL, - auth_setting INTEGER DEFAULT 0 NOT NULL -);; - -CREATE INDEX phpbb_acl_groups_group_id ON phpbb_acl_groups(group_id);; -CREATE INDEX phpbb_acl_groups_auth_opt_id ON phpbb_acl_groups(auth_option_id);; -CREATE INDEX phpbb_acl_groups_auth_role_id ON phpbb_acl_groups(auth_role_id);; - -# Table: 'phpbb_acl_options' -CREATE TABLE phpbb_acl_options ( - auth_option_id INTEGER NOT NULL, - auth_option VARCHAR(50) CHARACTER SET NONE DEFAULT '' NOT NULL, - is_global INTEGER DEFAULT 0 NOT NULL, - is_local INTEGER DEFAULT 0 NOT NULL, - founder_only INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_acl_options ADD PRIMARY KEY (auth_option_id);; - -CREATE UNIQUE INDEX phpbb_acl_options_auth_option ON phpbb_acl_options(auth_option);; - -CREATE GENERATOR phpbb_acl_options_gen;; -SET GENERATOR phpbb_acl_options_gen TO 0;; - -CREATE TRIGGER t_phpbb_acl_options FOR phpbb_acl_options -BEFORE INSERT -AS -BEGIN - NEW.auth_option_id = GEN_ID(phpbb_acl_options_gen, 1); -END;; - - -# Table: 'phpbb_acl_roles' -CREATE TABLE phpbb_acl_roles ( - role_id INTEGER NOT NULL, - role_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - role_description BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - role_type VARCHAR(10) CHARACTER SET NONE DEFAULT '' NOT NULL, - role_order INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_acl_roles ADD PRIMARY KEY (role_id);; - -CREATE INDEX phpbb_acl_roles_role_type ON phpbb_acl_roles(role_type);; -CREATE INDEX phpbb_acl_roles_role_order ON phpbb_acl_roles(role_order);; - -CREATE GENERATOR phpbb_acl_roles_gen;; -SET GENERATOR phpbb_acl_roles_gen TO 0;; - -CREATE TRIGGER t_phpbb_acl_roles FOR phpbb_acl_roles -BEFORE INSERT -AS -BEGIN - NEW.role_id = GEN_ID(phpbb_acl_roles_gen, 1); -END;; - - -# Table: 'phpbb_acl_roles_data' -CREATE TABLE phpbb_acl_roles_data ( - role_id INTEGER DEFAULT 0 NOT NULL, - auth_option_id INTEGER DEFAULT 0 NOT NULL, - auth_setting INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_acl_roles_data ADD PRIMARY KEY (role_id, auth_option_id);; - -CREATE INDEX phpbb_acl_roles_data_ath_op_id ON phpbb_acl_roles_data(auth_option_id);; - -# Table: 'phpbb_acl_users' -CREATE TABLE phpbb_acl_users ( - user_id INTEGER DEFAULT 0 NOT NULL, - forum_id INTEGER DEFAULT 0 NOT NULL, - auth_option_id INTEGER DEFAULT 0 NOT NULL, - auth_role_id INTEGER DEFAULT 0 NOT NULL, - auth_setting INTEGER DEFAULT 0 NOT NULL -);; - -CREATE INDEX phpbb_acl_users_user_id ON phpbb_acl_users(user_id);; -CREATE INDEX phpbb_acl_users_auth_option_id ON phpbb_acl_users(auth_option_id);; -CREATE INDEX phpbb_acl_users_auth_role_id ON phpbb_acl_users(auth_role_id);; - -# Table: 'phpbb_oauth_tokens' -CREATE TABLE phpbb_oauth_tokens ( - user_id INTEGER DEFAULT 0 NOT NULL, - session_id CHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL, - provider VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - oauth_token BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -CREATE INDEX phpbb_oauth_tokens_user_id ON phpbb_oauth_tokens(user_id);; -CREATE INDEX phpbb_oauth_tokens_provider ON phpbb_oauth_tokens(provider);; - -# Table: 'phpbb_oauth_accounts' -CREATE TABLE phpbb_oauth_accounts ( - user_id INTEGER DEFAULT 0 NOT NULL, - provider VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - oauth_provider_id BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_oauth_accounts ADD PRIMARY KEY (user_id, provider);; - - -# Table: 'phpbb_banlist' -CREATE TABLE phpbb_banlist ( - ban_id INTEGER NOT NULL, - ban_userid INTEGER DEFAULT 0 NOT NULL, - ban_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, - ban_email VARCHAR(100) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - ban_start INTEGER DEFAULT 0 NOT NULL, - ban_end INTEGER DEFAULT 0 NOT NULL, - ban_exclude INTEGER DEFAULT 0 NOT NULL, - ban_reason VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - ban_give_reason VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE -);; - -ALTER TABLE phpbb_banlist ADD PRIMARY KEY (ban_id);; - -CREATE INDEX phpbb_banlist_ban_end ON phpbb_banlist(ban_end);; -CREATE INDEX phpbb_banlist_ban_user ON phpbb_banlist(ban_userid, ban_exclude);; -CREATE INDEX phpbb_banlist_ban_email ON phpbb_banlist(ban_email, ban_exclude);; -CREATE INDEX phpbb_banlist_ban_ip ON phpbb_banlist(ban_ip, ban_exclude);; - -CREATE GENERATOR phpbb_banlist_gen;; -SET GENERATOR phpbb_banlist_gen TO 0;; - -CREATE TRIGGER t_phpbb_banlist FOR phpbb_banlist -BEFORE INSERT -AS -BEGIN - NEW.ban_id = GEN_ID(phpbb_banlist_gen, 1); -END;; - - -# Table: 'phpbb_bbcodes' -CREATE TABLE phpbb_bbcodes ( - bbcode_id INTEGER DEFAULT 0 NOT NULL, - bbcode_tag VARCHAR(16) CHARACTER SET NONE DEFAULT '' NOT NULL, - bbcode_helpline VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - display_on_posting INTEGER DEFAULT 0 NOT NULL, - bbcode_match BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - bbcode_tpl BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - first_pass_match BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - first_pass_replace BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - second_pass_match BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - second_pass_replace BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_bbcodes ADD PRIMARY KEY (bbcode_id);; - -CREATE INDEX phpbb_bbcodes_display_on_post ON phpbb_bbcodes(display_on_posting);; - -# Table: 'phpbb_bookmarks' -CREATE TABLE phpbb_bookmarks ( - topic_id INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_bookmarks ADD PRIMARY KEY (topic_id, user_id);; - - -# Table: 'phpbb_bots' -CREATE TABLE phpbb_bots ( - bot_id INTEGER NOT NULL, - bot_active INTEGER DEFAULT 1 NOT NULL, - bot_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_id INTEGER DEFAULT 0 NOT NULL, - bot_agent VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - bot_ip VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_bots ADD PRIMARY KEY (bot_id);; - -CREATE INDEX phpbb_bots_bot_active ON phpbb_bots(bot_active);; - -CREATE GENERATOR phpbb_bots_gen;; -SET GENERATOR phpbb_bots_gen TO 0;; - -CREATE TRIGGER t_phpbb_bots FOR phpbb_bots -BEFORE INSERT -AS -BEGIN - NEW.bot_id = GEN_ID(phpbb_bots_gen, 1); -END;; - - -# Table: 'phpbb_config' -CREATE TABLE phpbb_config ( - config_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - config_value VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - is_dynamic INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_config ADD PRIMARY KEY (config_name);; - -CREATE INDEX phpbb_config_is_dynamic ON phpbb_config(is_dynamic);; - -# Table: 'phpbb_config_text' -CREATE TABLE phpbb_config_text ( - config_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - config_value BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_config_text ADD PRIMARY KEY (config_name);; - - -# Table: 'phpbb_confirm' -CREATE TABLE phpbb_confirm ( - confirm_id CHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL, - session_id CHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL, - confirm_type INTEGER DEFAULT 0 NOT NULL, - code VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, - seed INTEGER DEFAULT 0 NOT NULL, - attempts INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_confirm ADD PRIMARY KEY (session_id, confirm_id);; - -CREATE INDEX phpbb_confirm_confirm_type ON phpbb_confirm(confirm_type);; - -# Table: 'phpbb_disallow' -CREATE TABLE phpbb_disallow ( - disallow_id INTEGER NOT NULL, - disallow_username VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE -);; - -ALTER TABLE phpbb_disallow ADD PRIMARY KEY (disallow_id);; - - -CREATE GENERATOR phpbb_disallow_gen;; -SET GENERATOR phpbb_disallow_gen TO 0;; - -CREATE TRIGGER t_phpbb_disallow FOR phpbb_disallow -BEFORE INSERT -AS -BEGIN - NEW.disallow_id = GEN_ID(phpbb_disallow_gen, 1); -END;; - - -# Table: 'phpbb_drafts' -CREATE TABLE phpbb_drafts ( - draft_id INTEGER NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - topic_id INTEGER DEFAULT 0 NOT NULL, - forum_id INTEGER DEFAULT 0 NOT NULL, - save_time INTEGER DEFAULT 0 NOT NULL, - draft_subject VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - draft_message BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_drafts ADD PRIMARY KEY (draft_id);; - -CREATE INDEX phpbb_drafts_save_time ON phpbb_drafts(save_time);; - -CREATE GENERATOR phpbb_drafts_gen;; -SET GENERATOR phpbb_drafts_gen TO 0;; - -CREATE TRIGGER t_phpbb_drafts FOR phpbb_drafts -BEFORE INSERT -AS -BEGIN - NEW.draft_id = GEN_ID(phpbb_drafts_gen, 1); -END;; - - -# Table: 'phpbb_ext' -CREATE TABLE phpbb_ext ( - ext_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - ext_active INTEGER DEFAULT 0 NOT NULL, - ext_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext(ext_name);; - -# Table: 'phpbb_extensions' -CREATE TABLE phpbb_extensions ( - extension_id INTEGER NOT NULL, - group_id INTEGER DEFAULT 0 NOT NULL, - extension VARCHAR(100) CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_extensions ADD PRIMARY KEY (extension_id);; - - -CREATE GENERATOR phpbb_extensions_gen;; -SET GENERATOR phpbb_extensions_gen TO 0;; - -CREATE TRIGGER t_phpbb_extensions FOR phpbb_extensions -BEFORE INSERT -AS -BEGIN - NEW.extension_id = GEN_ID(phpbb_extensions_gen, 1); -END;; - - -# Table: 'phpbb_extension_groups' -CREATE TABLE phpbb_extension_groups ( - group_id INTEGER NOT NULL, - group_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - cat_id INTEGER DEFAULT 0 NOT NULL, - allow_group INTEGER DEFAULT 0 NOT NULL, - download_mode INTEGER DEFAULT 1 NOT NULL, - upload_icon VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - max_filesize INTEGER DEFAULT 0 NOT NULL, - allowed_forums BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, - allow_in_pm INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_extension_groups ADD PRIMARY KEY (group_id);; - - -CREATE GENERATOR phpbb_extension_groups_gen;; -SET GENERATOR phpbb_extension_groups_gen TO 0;; - -CREATE TRIGGER t_phpbb_extension_groups FOR phpbb_extension_groups -BEFORE INSERT -AS -BEGIN - NEW.group_id = GEN_ID(phpbb_extension_groups_gen, 1); -END;; - - -# Table: 'phpbb_forums' -CREATE TABLE phpbb_forums ( - forum_id INTEGER NOT NULL, - parent_id INTEGER DEFAULT 0 NOT NULL, - left_id INTEGER DEFAULT 0 NOT NULL, - right_id INTEGER DEFAULT 0 NOT NULL, - forum_parents BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, - forum_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - forum_desc BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - forum_desc_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - forum_desc_options INTEGER DEFAULT 7 NOT NULL, - forum_desc_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, - forum_link VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - forum_password VARCHAR(40) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - forum_style INTEGER DEFAULT 0 NOT NULL, - forum_image VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - forum_rules BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - forum_rules_link VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - forum_rules_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - forum_rules_options INTEGER DEFAULT 7 NOT NULL, - forum_rules_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, - forum_topics_per_page INTEGER DEFAULT 0 NOT NULL, - forum_type INTEGER DEFAULT 0 NOT NULL, - forum_status INTEGER DEFAULT 0 NOT NULL, - forum_posts_approved INTEGER DEFAULT 0 NOT NULL, - forum_posts_unapproved INTEGER DEFAULT 0 NOT NULL, - forum_posts_softdeleted INTEGER DEFAULT 0 NOT NULL, - forum_topics_approved INTEGER DEFAULT 0 NOT NULL, - forum_topics_unapproved INTEGER DEFAULT 0 NOT NULL, - forum_topics_softdeleted INTEGER DEFAULT 0 NOT NULL, - forum_last_post_id INTEGER DEFAULT 0 NOT NULL, - forum_last_poster_id INTEGER DEFAULT 0 NOT NULL, - forum_last_post_subject VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - forum_last_post_time INTEGER DEFAULT 0 NOT NULL, - forum_last_poster_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - forum_last_poster_colour VARCHAR(6) CHARACTER SET NONE DEFAULT '' NOT NULL, - forum_flags INTEGER DEFAULT 32 NOT NULL, - forum_options INTEGER DEFAULT 0 NOT NULL, - display_subforum_list INTEGER DEFAULT 1 NOT NULL, - display_on_index INTEGER DEFAULT 1 NOT NULL, - enable_indexing INTEGER DEFAULT 1 NOT NULL, - enable_icons INTEGER DEFAULT 1 NOT NULL, - enable_prune INTEGER DEFAULT 0 NOT NULL, - prune_next INTEGER DEFAULT 0 NOT NULL, - prune_days INTEGER DEFAULT 0 NOT NULL, - prune_viewed INTEGER DEFAULT 0 NOT NULL, - prune_freq INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_forums ADD PRIMARY KEY (forum_id);; - -CREATE INDEX phpbb_forums_left_right_id ON phpbb_forums(left_id, right_id);; -CREATE INDEX phpbb_forums_forum_lastpost_id ON phpbb_forums(forum_last_post_id);; - -CREATE GENERATOR phpbb_forums_gen;; -SET GENERATOR phpbb_forums_gen TO 0;; - -CREATE TRIGGER t_phpbb_forums FOR phpbb_forums -BEFORE INSERT -AS -BEGIN - NEW.forum_id = GEN_ID(phpbb_forums_gen, 1); -END;; - - -# Table: 'phpbb_forums_access' -CREATE TABLE phpbb_forums_access ( - forum_id INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - session_id CHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_forums_access ADD PRIMARY KEY (forum_id, user_id, session_id);; - - -# Table: 'phpbb_forums_track' -CREATE TABLE phpbb_forums_track ( - user_id INTEGER DEFAULT 0 NOT NULL, - forum_id INTEGER DEFAULT 0 NOT NULL, - mark_time INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_forums_track ADD PRIMARY KEY (user_id, forum_id);; - - -# Table: 'phpbb_forums_watch' -CREATE TABLE phpbb_forums_watch ( - forum_id INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - notify_status INTEGER DEFAULT 0 NOT NULL -);; - -CREATE INDEX phpbb_forums_watch_forum_id ON phpbb_forums_watch(forum_id);; -CREATE INDEX phpbb_forums_watch_user_id ON phpbb_forums_watch(user_id);; -CREATE INDEX phpbb_forums_watch_notify_stat ON phpbb_forums_watch(notify_status);; - -# Table: 'phpbb_groups' -CREATE TABLE phpbb_groups ( - group_id INTEGER NOT NULL, - group_type INTEGER DEFAULT 1 NOT NULL, - group_founder_manage INTEGER DEFAULT 0 NOT NULL, - group_skip_auth INTEGER DEFAULT 0 NOT NULL, - group_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - group_desc BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - group_desc_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - group_desc_options INTEGER DEFAULT 7 NOT NULL, - group_desc_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, - group_display INTEGER DEFAULT 0 NOT NULL, - group_avatar VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - group_avatar_type VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - group_avatar_width INTEGER DEFAULT 0 NOT NULL, - group_avatar_height INTEGER DEFAULT 0 NOT NULL, - group_rank INTEGER DEFAULT 0 NOT NULL, - group_colour VARCHAR(6) CHARACTER SET NONE DEFAULT '' NOT NULL, - group_sig_chars INTEGER DEFAULT 0 NOT NULL, - group_receive_pm INTEGER DEFAULT 0 NOT NULL, - group_message_limit INTEGER DEFAULT 0 NOT NULL, - group_max_recipients INTEGER DEFAULT 0 NOT NULL, - group_legend INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_groups ADD PRIMARY KEY (group_id);; - -CREATE INDEX phpbb_groups_group_legend_name ON phpbb_groups(group_legend, group_name);; - -CREATE GENERATOR phpbb_groups_gen;; -SET GENERATOR phpbb_groups_gen TO 0;; - -CREATE TRIGGER t_phpbb_groups FOR phpbb_groups -BEFORE INSERT -AS -BEGIN - NEW.group_id = GEN_ID(phpbb_groups_gen, 1); -END;; - - -# Table: 'phpbb_icons' -CREATE TABLE phpbb_icons ( - icons_id INTEGER NOT NULL, - icons_url VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - icons_width INTEGER DEFAULT 0 NOT NULL, - icons_height INTEGER DEFAULT 0 NOT NULL, - icons_order INTEGER DEFAULT 0 NOT NULL, - display_on_posting INTEGER DEFAULT 1 NOT NULL -);; - -ALTER TABLE phpbb_icons ADD PRIMARY KEY (icons_id);; - -CREATE INDEX phpbb_icons_display_on_posting ON phpbb_icons(display_on_posting);; - -CREATE GENERATOR phpbb_icons_gen;; -SET GENERATOR phpbb_icons_gen TO 0;; - -CREATE TRIGGER t_phpbb_icons FOR phpbb_icons -BEFORE INSERT -AS -BEGIN - NEW.icons_id = GEN_ID(phpbb_icons_gen, 1); -END;; - - -# Table: 'phpbb_lang' -CREATE TABLE phpbb_lang ( - lang_id INTEGER NOT NULL, - lang_iso VARCHAR(30) CHARACTER SET NONE DEFAULT '' NOT NULL, - lang_dir VARCHAR(30) CHARACTER SET NONE DEFAULT '' NOT NULL, - lang_english_name VARCHAR(100) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - lang_local_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - lang_author VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE -);; - -ALTER TABLE phpbb_lang ADD PRIMARY KEY (lang_id);; - -CREATE INDEX phpbb_lang_lang_iso ON phpbb_lang(lang_iso);; - -CREATE GENERATOR phpbb_lang_gen;; -SET GENERATOR phpbb_lang_gen TO 0;; - -CREATE TRIGGER t_phpbb_lang FOR phpbb_lang -BEFORE INSERT -AS -BEGIN - NEW.lang_id = GEN_ID(phpbb_lang_gen, 1); -END;; - - -# Table: 'phpbb_log' -CREATE TABLE phpbb_log ( - log_id INTEGER NOT NULL, - log_type INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - forum_id INTEGER DEFAULT 0 NOT NULL, - topic_id INTEGER DEFAULT 0 NOT NULL, - reportee_id INTEGER DEFAULT 0 NOT NULL, - log_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, - log_time INTEGER DEFAULT 0 NOT NULL, - log_operation BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - log_data BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_log ADD PRIMARY KEY (log_id);; - -CREATE INDEX phpbb_log_log_type ON phpbb_log(log_type);; -CREATE INDEX phpbb_log_log_time ON phpbb_log(log_time);; -CREATE INDEX phpbb_log_forum_id ON phpbb_log(forum_id);; -CREATE INDEX phpbb_log_topic_id ON phpbb_log(topic_id);; -CREATE INDEX phpbb_log_reportee_id ON phpbb_log(reportee_id);; -CREATE INDEX phpbb_log_user_id ON phpbb_log(user_id);; - -CREATE GENERATOR phpbb_log_gen;; -SET GENERATOR phpbb_log_gen TO 0;; - -CREATE TRIGGER t_phpbb_log FOR phpbb_log -BEFORE INSERT -AS -BEGIN - NEW.log_id = GEN_ID(phpbb_log_gen, 1); -END;; - - -# Table: 'phpbb_login_attempts' -CREATE TABLE phpbb_login_attempts ( - attempt_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, - attempt_browser VARCHAR(150) CHARACTER SET NONE DEFAULT '' NOT NULL, - attempt_forwarded_for VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - attempt_time INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - username VARCHAR(255) CHARACTER SET UTF8 DEFAULT 0 NOT NULL COLLATE UNICODE, - username_clean VARCHAR(255) CHARACTER SET UTF8 DEFAULT 0 NOT NULL COLLATE UNICODE -);; - -CREATE INDEX phpbb_login_attempts_att_ip ON phpbb_login_attempts(attempt_ip, attempt_time);; -CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts(attempt_forwarded_for, attempt_time);; -CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts(attempt_time);; -CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts(user_id);; - -# Table: 'phpbb_moderator_cache' -CREATE TABLE phpbb_moderator_cache ( - forum_id INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - username VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - group_id INTEGER DEFAULT 0 NOT NULL, - group_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - display_on_index INTEGER DEFAULT 1 NOT NULL -);; - -CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache(display_on_index);; -CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache(forum_id);; - -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - migration_depends_on BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, - migration_schema_done INTEGER DEFAULT 0 NOT NULL, - migration_data_done INTEGER DEFAULT 0 NOT NULL, - migration_data_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, - migration_start_time INTEGER DEFAULT 0 NOT NULL, - migration_end_time INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_migrations ADD PRIMARY KEY (migration_name);; - - -# Table: 'phpbb_modules' -CREATE TABLE phpbb_modules ( - module_id INTEGER NOT NULL, - module_enabled INTEGER DEFAULT 1 NOT NULL, - module_display INTEGER DEFAULT 1 NOT NULL, - module_basename VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - module_class VARCHAR(10) CHARACTER SET NONE DEFAULT '' NOT NULL, - parent_id INTEGER DEFAULT 0 NOT NULL, - left_id INTEGER DEFAULT 0 NOT NULL, - right_id INTEGER DEFAULT 0 NOT NULL, - module_langname VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - module_mode VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - module_auth VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_modules ADD PRIMARY KEY (module_id);; - -CREATE INDEX phpbb_modules_left_right_id ON phpbb_modules(left_id, right_id);; -CREATE INDEX phpbb_modules_module_enabled ON phpbb_modules(module_enabled);; -CREATE INDEX phpbb_modules_class_left_id ON phpbb_modules(module_class, left_id);; - -CREATE GENERATOR phpbb_modules_gen;; -SET GENERATOR phpbb_modules_gen TO 0;; - -CREATE TRIGGER t_phpbb_modules FOR phpbb_modules -BEFORE INSERT -AS -BEGIN - NEW.module_id = GEN_ID(phpbb_modules_gen, 1); -END;; - - -# Table: 'phpbb_notification_types' -CREATE TABLE phpbb_notification_types ( - notification_type_id INTEGER NOT NULL, - notification_type_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - notification_type_enabled INTEGER DEFAULT 1 NOT NULL -);; - -ALTER TABLE phpbb_notification_types ADD PRIMARY KEY (notification_type_id);; - -CREATE UNIQUE INDEX phpbb_notification_types_type ON phpbb_notification_types(notification_type_name);; - -CREATE GENERATOR phpbb_notification_types_gen;; -SET GENERATOR phpbb_notification_types_gen TO 0;; - -CREATE TRIGGER t_phpbb_notification_types FOR phpbb_notification_types -BEFORE INSERT -AS -BEGIN - NEW.notification_type_id = GEN_ID(phpbb_notification_types_gen, 1); -END;; - - -# Table: 'phpbb_notifications' -CREATE TABLE phpbb_notifications ( - notification_id INTEGER NOT NULL, - notification_type_id INTEGER DEFAULT 0 NOT NULL, - item_id INTEGER DEFAULT 0 NOT NULL, - item_parent_id INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - notification_read INTEGER DEFAULT 0 NOT NULL, - notification_time INTEGER DEFAULT 1 NOT NULL, - notification_data BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_notifications ADD PRIMARY KEY (notification_id);; - -CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications(notification_type_id, item_id);; -CREATE INDEX phpbb_notifications_user ON phpbb_notifications(user_id, notification_read);; - -CREATE GENERATOR phpbb_notifications_gen;; -SET GENERATOR phpbb_notifications_gen TO 0;; - -CREATE TRIGGER t_phpbb_notifications FOR phpbb_notifications -BEFORE INSERT -AS -BEGIN - NEW.notification_id = GEN_ID(phpbb_notifications_gen, 1); -END;; - - -# Table: 'phpbb_poll_options' -CREATE TABLE phpbb_poll_options ( - poll_option_id INTEGER DEFAULT 0 NOT NULL, - topic_id INTEGER DEFAULT 0 NOT NULL, - poll_option_text BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - poll_option_total INTEGER DEFAULT 0 NOT NULL -);; - -CREATE INDEX phpbb_poll_options_poll_opt_id ON phpbb_poll_options(poll_option_id);; -CREATE INDEX phpbb_poll_options_topic_id ON phpbb_poll_options(topic_id);; - -# Table: 'phpbb_poll_votes' -CREATE TABLE phpbb_poll_votes ( - topic_id INTEGER DEFAULT 0 NOT NULL, - poll_option_id INTEGER DEFAULT 0 NOT NULL, - vote_user_id INTEGER DEFAULT 0 NOT NULL, - vote_user_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -CREATE INDEX phpbb_poll_votes_topic_id ON phpbb_poll_votes(topic_id);; -CREATE INDEX phpbb_poll_votes_vote_user_id ON phpbb_poll_votes(vote_user_id);; -CREATE INDEX phpbb_poll_votes_vote_user_ip ON phpbb_poll_votes(vote_user_ip);; - -# Table: 'phpbb_posts' -CREATE TABLE phpbb_posts ( - post_id INTEGER NOT NULL, - topic_id INTEGER DEFAULT 0 NOT NULL, - forum_id INTEGER DEFAULT 0 NOT NULL, - poster_id INTEGER DEFAULT 0 NOT NULL, - icon_id INTEGER DEFAULT 0 NOT NULL, - poster_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, - post_time INTEGER DEFAULT 0 NOT NULL, - post_visibility INTEGER DEFAULT 0 NOT NULL, - post_reported INTEGER DEFAULT 0 NOT NULL, - enable_bbcode INTEGER DEFAULT 1 NOT NULL, - enable_smilies INTEGER DEFAULT 1 NOT NULL, - enable_magic_url INTEGER DEFAULT 1 NOT NULL, - enable_sig INTEGER DEFAULT 1 NOT NULL, - post_username VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - post_subject VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - post_text BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - post_checksum VARCHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL, - post_attachment INTEGER DEFAULT 0 NOT NULL, - bbcode_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - bbcode_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, - post_postcount INTEGER DEFAULT 1 NOT NULL, - post_edit_time INTEGER DEFAULT 0 NOT NULL, - post_edit_reason VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - post_edit_user INTEGER DEFAULT 0 NOT NULL, - post_edit_count INTEGER DEFAULT 0 NOT NULL, - post_edit_locked INTEGER DEFAULT 0 NOT NULL, - post_delete_time INTEGER DEFAULT 0 NOT NULL, - post_delete_reason VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - post_delete_user INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_posts ADD PRIMARY KEY (post_id);; - -CREATE INDEX phpbb_posts_forum_id ON phpbb_posts(forum_id);; -CREATE INDEX phpbb_posts_topic_id ON phpbb_posts(topic_id);; -CREATE INDEX phpbb_posts_poster_ip ON phpbb_posts(poster_ip);; -CREATE INDEX phpbb_posts_poster_id ON phpbb_posts(poster_id);; -CREATE INDEX phpbb_posts_post_visibility ON phpbb_posts(post_visibility);; -CREATE INDEX phpbb_posts_post_username ON phpbb_posts(post_username);; -CREATE INDEX phpbb_posts_tid_post_time ON phpbb_posts(topic_id, post_time);; - -CREATE GENERATOR phpbb_posts_gen;; -SET GENERATOR phpbb_posts_gen TO 0;; - -CREATE TRIGGER t_phpbb_posts FOR phpbb_posts -BEFORE INSERT -AS -BEGIN - NEW.post_id = GEN_ID(phpbb_posts_gen, 1); -END;; - - -# Table: 'phpbb_privmsgs' -CREATE TABLE phpbb_privmsgs ( - msg_id INTEGER NOT NULL, - root_level INTEGER DEFAULT 0 NOT NULL, - author_id INTEGER DEFAULT 0 NOT NULL, - icon_id INTEGER DEFAULT 0 NOT NULL, - author_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, - message_time INTEGER DEFAULT 0 NOT NULL, - enable_bbcode INTEGER DEFAULT 1 NOT NULL, - enable_smilies INTEGER DEFAULT 1 NOT NULL, - enable_magic_url INTEGER DEFAULT 1 NOT NULL, - enable_sig INTEGER DEFAULT 1 NOT NULL, - message_subject VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - message_text BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - message_edit_reason VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - message_edit_user INTEGER DEFAULT 0 NOT NULL, - message_attachment INTEGER DEFAULT 0 NOT NULL, - bbcode_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - bbcode_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, - message_edit_time INTEGER DEFAULT 0 NOT NULL, - message_edit_count INTEGER DEFAULT 0 NOT NULL, - to_address BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - bcc_address BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - message_reported INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_privmsgs ADD PRIMARY KEY (msg_id);; - -CREATE INDEX phpbb_privmsgs_author_ip ON phpbb_privmsgs(author_ip);; -CREATE INDEX phpbb_privmsgs_message_time ON phpbb_privmsgs(message_time);; -CREATE INDEX phpbb_privmsgs_author_id ON phpbb_privmsgs(author_id);; -CREATE INDEX phpbb_privmsgs_root_level ON phpbb_privmsgs(root_level);; - -CREATE GENERATOR phpbb_privmsgs_gen;; -SET GENERATOR phpbb_privmsgs_gen TO 0;; - -CREATE TRIGGER t_phpbb_privmsgs FOR phpbb_privmsgs -BEFORE INSERT -AS -BEGIN - NEW.msg_id = GEN_ID(phpbb_privmsgs_gen, 1); -END;; - - -# Table: 'phpbb_privmsgs_folder' -CREATE TABLE phpbb_privmsgs_folder ( - folder_id INTEGER NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - folder_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - pm_count INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_privmsgs_folder ADD PRIMARY KEY (folder_id);; - -CREATE INDEX phpbb_privmsgs_folder_user_id ON phpbb_privmsgs_folder(user_id);; - -CREATE GENERATOR phpbb_privmsgs_folder_gen;; -SET GENERATOR phpbb_privmsgs_folder_gen TO 0;; - -CREATE TRIGGER t_phpbb_privmsgs_folder FOR phpbb_privmsgs_folder -BEFORE INSERT -AS -BEGIN - NEW.folder_id = GEN_ID(phpbb_privmsgs_folder_gen, 1); -END;; - - -# Table: 'phpbb_privmsgs_rules' -CREATE TABLE phpbb_privmsgs_rules ( - rule_id INTEGER NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - rule_check INTEGER DEFAULT 0 NOT NULL, - rule_connection INTEGER DEFAULT 0 NOT NULL, - rule_string VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - rule_user_id INTEGER DEFAULT 0 NOT NULL, - rule_group_id INTEGER DEFAULT 0 NOT NULL, - rule_action INTEGER DEFAULT 0 NOT NULL, - rule_folder_id INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_privmsgs_rules ADD PRIMARY KEY (rule_id);; - -CREATE INDEX phpbb_privmsgs_rules_user_id ON phpbb_privmsgs_rules(user_id);; - -CREATE GENERATOR phpbb_privmsgs_rules_gen;; -SET GENERATOR phpbb_privmsgs_rules_gen TO 0;; - -CREATE TRIGGER t_phpbb_privmsgs_rules FOR phpbb_privmsgs_rules -BEFORE INSERT -AS -BEGIN - NEW.rule_id = GEN_ID(phpbb_privmsgs_rules_gen, 1); -END;; - - -# Table: 'phpbb_privmsgs_to' -CREATE TABLE phpbb_privmsgs_to ( - msg_id INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - author_id INTEGER DEFAULT 0 NOT NULL, - pm_deleted INTEGER DEFAULT 0 NOT NULL, - pm_new INTEGER DEFAULT 1 NOT NULL, - pm_unread INTEGER DEFAULT 1 NOT NULL, - pm_replied INTEGER DEFAULT 0 NOT NULL, - pm_marked INTEGER DEFAULT 0 NOT NULL, - pm_forwarded INTEGER DEFAULT 0 NOT NULL, - folder_id INTEGER DEFAULT 0 NOT NULL -);; - -CREATE INDEX phpbb_privmsgs_to_msg_id ON phpbb_privmsgs_to(msg_id);; -CREATE INDEX phpbb_privmsgs_to_author_id ON phpbb_privmsgs_to(author_id);; -CREATE INDEX phpbb_privmsgs_to_usr_flder_id ON phpbb_privmsgs_to(user_id, folder_id);; - -# Table: 'phpbb_profile_fields' -CREATE TABLE phpbb_profile_fields ( - field_id INTEGER NOT NULL, - field_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - field_type INTEGER DEFAULT 0 NOT NULL, - field_ident VARCHAR(20) CHARACTER SET NONE DEFAULT '' NOT NULL, - field_length VARCHAR(20) CHARACTER SET NONE DEFAULT '' NOT NULL, - field_minlen VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - field_maxlen VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - field_novalue VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - field_default_value VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - field_validation VARCHAR(20) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - field_required INTEGER DEFAULT 0 NOT NULL, - field_show_novalue INTEGER DEFAULT 0 NOT NULL, - field_show_on_reg INTEGER DEFAULT 0 NOT NULL, - field_show_on_pm INTEGER DEFAULT 0 NOT NULL, - field_show_on_vt INTEGER DEFAULT 0 NOT NULL, - field_show_profile INTEGER DEFAULT 0 NOT NULL, - field_hide INTEGER DEFAULT 0 NOT NULL, - field_no_view INTEGER DEFAULT 0 NOT NULL, - field_active INTEGER DEFAULT 0 NOT NULL, - field_order INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_profile_fields ADD PRIMARY KEY (field_id);; - -CREATE INDEX phpbb_profile_fields_fld_type ON phpbb_profile_fields(field_type);; -CREATE INDEX phpbb_profile_fields_fld_ordr ON phpbb_profile_fields(field_order);; - -CREATE GENERATOR phpbb_profile_fields_gen;; -SET GENERATOR phpbb_profile_fields_gen TO 0;; - -CREATE TRIGGER t_phpbb_profile_fields FOR phpbb_profile_fields -BEFORE INSERT -AS -BEGIN - NEW.field_id = GEN_ID(phpbb_profile_fields_gen, 1); -END;; - - -# Table: 'phpbb_profile_fields_data' -CREATE TABLE phpbb_profile_fields_data ( - user_id INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_profile_fields_data ADD PRIMARY KEY (user_id);; - - -# Table: 'phpbb_profile_fields_lang' -CREATE TABLE phpbb_profile_fields_lang ( - field_id INTEGER DEFAULT 0 NOT NULL, - lang_id INTEGER DEFAULT 0 NOT NULL, - option_id INTEGER DEFAULT 0 NOT NULL, - field_type INTEGER DEFAULT 0 NOT NULL, - lang_value VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE -);; - -ALTER TABLE phpbb_profile_fields_lang ADD PRIMARY KEY (field_id, lang_id, option_id);; - - -# Table: 'phpbb_profile_lang' -CREATE TABLE phpbb_profile_lang ( - field_id INTEGER DEFAULT 0 NOT NULL, - lang_id INTEGER DEFAULT 0 NOT NULL, - lang_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - lang_explain BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - lang_default_value VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE -);; - -ALTER TABLE phpbb_profile_lang ADD PRIMARY KEY (field_id, lang_id);; - - -# Table: 'phpbb_ranks' -CREATE TABLE phpbb_ranks ( - rank_id INTEGER NOT NULL, - rank_title VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - rank_min INTEGER DEFAULT 0 NOT NULL, - rank_special INTEGER DEFAULT 0 NOT NULL, - rank_image VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_ranks ADD PRIMARY KEY (rank_id);; - - -CREATE GENERATOR phpbb_ranks_gen;; -SET GENERATOR phpbb_ranks_gen TO 0;; - -CREATE TRIGGER t_phpbb_ranks FOR phpbb_ranks -BEFORE INSERT -AS -BEGIN - NEW.rank_id = GEN_ID(phpbb_ranks_gen, 1); -END;; - - -# Table: 'phpbb_reports' -CREATE TABLE phpbb_reports ( - report_id INTEGER NOT NULL, - reason_id INTEGER DEFAULT 0 NOT NULL, - post_id INTEGER DEFAULT 0 NOT NULL, - pm_id INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - user_notify INTEGER DEFAULT 0 NOT NULL, - report_closed INTEGER DEFAULT 0 NOT NULL, - report_time INTEGER DEFAULT 0 NOT NULL, - report_text BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - reported_post_text BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - reported_post_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, - reported_post_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - reported_post_enable_magic_url INTEGER DEFAULT 1 NOT NULL, - reported_post_enable_smilies INTEGER DEFAULT 1 NOT NULL, - reported_post_enable_bbcode INTEGER DEFAULT 1 NOT NULL -);; - -ALTER TABLE phpbb_reports ADD PRIMARY KEY (report_id);; - -CREATE INDEX phpbb_reports_post_id ON phpbb_reports(post_id);; -CREATE INDEX phpbb_reports_pm_id ON phpbb_reports(pm_id);; - -CREATE GENERATOR phpbb_reports_gen;; -SET GENERATOR phpbb_reports_gen TO 0;; - -CREATE TRIGGER t_phpbb_reports FOR phpbb_reports -BEFORE INSERT -AS -BEGIN - NEW.report_id = GEN_ID(phpbb_reports_gen, 1); -END;; - - -# Table: 'phpbb_reports_reasons' -CREATE TABLE phpbb_reports_reasons ( - reason_id INTEGER NOT NULL, - reason_title VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - reason_description BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - reason_order INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_reports_reasons ADD PRIMARY KEY (reason_id);; - - -CREATE GENERATOR phpbb_reports_reasons_gen;; -SET GENERATOR phpbb_reports_reasons_gen TO 0;; - -CREATE TRIGGER t_phpbb_reports_reasons FOR phpbb_reports_reasons -BEFORE INSERT -AS -BEGIN - NEW.reason_id = GEN_ID(phpbb_reports_reasons_gen, 1); -END;; - - -# Table: 'phpbb_search_results' -CREATE TABLE phpbb_search_results ( - search_key VARCHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL, - search_time INTEGER DEFAULT 0 NOT NULL, - search_keywords BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - search_authors BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_search_results ADD PRIMARY KEY (search_key);; - - -# Table: 'phpbb_search_wordlist' -CREATE TABLE phpbb_search_wordlist ( - word_id INTEGER NOT NULL, - word_text VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - word_common INTEGER DEFAULT 0 NOT NULL, - word_count INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_search_wordlist ADD PRIMARY KEY (word_id);; - -CREATE UNIQUE INDEX phpbb_search_wordlist_wrd_txt ON phpbb_search_wordlist(word_text);; -CREATE INDEX phpbb_search_wordlist_wrd_cnt ON phpbb_search_wordlist(word_count);; - -CREATE GENERATOR phpbb_search_wordlist_gen;; -SET GENERATOR phpbb_search_wordlist_gen TO 0;; - -CREATE TRIGGER t_phpbb_search_wordlist FOR phpbb_search_wordlist -BEFORE INSERT -AS -BEGIN - NEW.word_id = GEN_ID(phpbb_search_wordlist_gen, 1); -END;; - - -# Table: 'phpbb_search_wordmatch' -CREATE TABLE phpbb_search_wordmatch ( - post_id INTEGER DEFAULT 0 NOT NULL, - word_id INTEGER DEFAULT 0 NOT NULL, - title_match INTEGER DEFAULT 0 NOT NULL -);; - -CREATE UNIQUE INDEX phpbb_search_wordmatch_unq_mtch ON phpbb_search_wordmatch(word_id, post_id, title_match);; -CREATE INDEX phpbb_search_wordmatch_word_id ON phpbb_search_wordmatch(word_id);; -CREATE INDEX phpbb_search_wordmatch_post_id ON phpbb_search_wordmatch(post_id);; - -# Table: 'phpbb_sessions' -CREATE TABLE phpbb_sessions ( - session_id CHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL, - session_user_id INTEGER DEFAULT 0 NOT NULL, - session_forum_id INTEGER DEFAULT 0 NOT NULL, - session_last_visit INTEGER DEFAULT 0 NOT NULL, - session_start INTEGER DEFAULT 0 NOT NULL, - session_time INTEGER DEFAULT 0 NOT NULL, - session_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, - session_browser VARCHAR(150) CHARACTER SET NONE DEFAULT '' NOT NULL, - session_forwarded_for VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - session_page VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - session_viewonline INTEGER DEFAULT 1 NOT NULL, - session_autologin INTEGER DEFAULT 0 NOT NULL, - session_admin INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_sessions ADD PRIMARY KEY (session_id);; - -CREATE INDEX phpbb_sessions_session_time ON phpbb_sessions(session_time);; -CREATE INDEX phpbb_sessions_session_user_id ON phpbb_sessions(session_user_id);; -CREATE INDEX phpbb_sessions_session_fid ON phpbb_sessions(session_forum_id);; - -# Table: 'phpbb_sessions_keys' -CREATE TABLE phpbb_sessions_keys ( - key_id CHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - last_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, - last_login INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_sessions_keys ADD PRIMARY KEY (key_id, user_id);; - -CREATE INDEX phpbb_sessions_keys_last_login ON phpbb_sessions_keys(last_login);; - -# Table: 'phpbb_sitelist' -CREATE TABLE phpbb_sitelist ( - site_id INTEGER NOT NULL, - site_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, - site_hostname VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - ip_exclude INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_sitelist ADD PRIMARY KEY (site_id);; - - -CREATE GENERATOR phpbb_sitelist_gen;; -SET GENERATOR phpbb_sitelist_gen TO 0;; - -CREATE TRIGGER t_phpbb_sitelist FOR phpbb_sitelist -BEFORE INSERT -AS -BEGIN - NEW.site_id = GEN_ID(phpbb_sitelist_gen, 1); -END;; - - -# Table: 'phpbb_smilies' -CREATE TABLE phpbb_smilies ( - smiley_id INTEGER NOT NULL, - code VARCHAR(50) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - emotion VARCHAR(50) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - smiley_url VARCHAR(50) CHARACTER SET NONE DEFAULT '' NOT NULL, - smiley_width INTEGER DEFAULT 0 NOT NULL, - smiley_height INTEGER DEFAULT 0 NOT NULL, - smiley_order INTEGER DEFAULT 0 NOT NULL, - display_on_posting INTEGER DEFAULT 1 NOT NULL -);; - -ALTER TABLE phpbb_smilies ADD PRIMARY KEY (smiley_id);; - -CREATE INDEX phpbb_smilies_display_on_post ON phpbb_smilies(display_on_posting);; - -CREATE GENERATOR phpbb_smilies_gen;; -SET GENERATOR phpbb_smilies_gen TO 0;; - -CREATE TRIGGER t_phpbb_smilies FOR phpbb_smilies -BEFORE INSERT -AS -BEGIN - NEW.smiley_id = GEN_ID(phpbb_smilies_gen, 1); -END;; - - -# Table: 'phpbb_styles' -CREATE TABLE phpbb_styles ( - style_id INTEGER NOT NULL, - style_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - style_copyright VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - style_active INTEGER DEFAULT 1 NOT NULL, - style_path VARCHAR(100) CHARACTER SET NONE DEFAULT '' NOT NULL, - bbcode_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT 'kNg=' NOT NULL, - style_parent_id INTEGER DEFAULT 0 NOT NULL, - style_parent_tree BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL -);; - -ALTER TABLE phpbb_styles ADD PRIMARY KEY (style_id);; - -CREATE UNIQUE INDEX phpbb_styles_style_name ON phpbb_styles(style_name);; - -CREATE GENERATOR phpbb_styles_gen;; -SET GENERATOR phpbb_styles_gen TO 0;; - -CREATE TRIGGER t_phpbb_styles FOR phpbb_styles -BEFORE INSERT -AS -BEGIN - NEW.style_id = GEN_ID(phpbb_styles_gen, 1); -END;; - - -# Table: 'phpbb_teampage' -CREATE TABLE phpbb_teampage ( - teampage_id INTEGER NOT NULL, - group_id INTEGER DEFAULT 0 NOT NULL, - teampage_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - teampage_position INTEGER DEFAULT 0 NOT NULL, - teampage_parent INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_teampage ADD PRIMARY KEY (teampage_id);; - - -CREATE GENERATOR phpbb_teampage_gen;; -SET GENERATOR phpbb_teampage_gen TO 0;; - -CREATE TRIGGER t_phpbb_teampage FOR phpbb_teampage -BEFORE INSERT -AS -BEGIN - NEW.teampage_id = GEN_ID(phpbb_teampage_gen, 1); -END;; - - -# Table: 'phpbb_topics' -CREATE TABLE phpbb_topics ( - topic_id INTEGER NOT NULL, - forum_id INTEGER DEFAULT 0 NOT NULL, - icon_id INTEGER DEFAULT 0 NOT NULL, - topic_attachment INTEGER DEFAULT 0 NOT NULL, - topic_visibility INTEGER DEFAULT 0 NOT NULL, - topic_reported INTEGER DEFAULT 0 NOT NULL, - topic_title VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - topic_poster INTEGER DEFAULT 0 NOT NULL, - topic_time INTEGER DEFAULT 0 NOT NULL, - topic_time_limit INTEGER DEFAULT 0 NOT NULL, - topic_views INTEGER DEFAULT 0 NOT NULL, - topic_posts_approved INTEGER DEFAULT 0 NOT NULL, - topic_posts_unapproved INTEGER DEFAULT 0 NOT NULL, - topic_posts_softdeleted INTEGER DEFAULT 0 NOT NULL, - topic_status INTEGER DEFAULT 0 NOT NULL, - topic_type INTEGER DEFAULT 0 NOT NULL, - topic_first_post_id INTEGER DEFAULT 0 NOT NULL, - topic_first_poster_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - topic_first_poster_colour VARCHAR(6) CHARACTER SET NONE DEFAULT '' NOT NULL, - topic_last_post_id INTEGER DEFAULT 0 NOT NULL, - topic_last_poster_id INTEGER DEFAULT 0 NOT NULL, - topic_last_poster_name VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - topic_last_poster_colour VARCHAR(6) CHARACTER SET NONE DEFAULT '' NOT NULL, - topic_last_post_subject VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - topic_last_post_time INTEGER DEFAULT 0 NOT NULL, - topic_last_view_time INTEGER DEFAULT 0 NOT NULL, - topic_moved_id INTEGER DEFAULT 0 NOT NULL, - topic_bumped INTEGER DEFAULT 0 NOT NULL, - topic_bumper INTEGER DEFAULT 0 NOT NULL, - poll_title VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - poll_start INTEGER DEFAULT 0 NOT NULL, - poll_length INTEGER DEFAULT 0 NOT NULL, - poll_max_options INTEGER DEFAULT 1 NOT NULL, - poll_last_vote INTEGER DEFAULT 0 NOT NULL, - poll_vote_change INTEGER DEFAULT 0 NOT NULL, - topic_delete_time INTEGER DEFAULT 0 NOT NULL, - topic_delete_reason VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - topic_delete_user INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_topics ADD PRIMARY KEY (topic_id);; - -CREATE INDEX phpbb_topics_forum_id ON phpbb_topics(forum_id);; -CREATE INDEX phpbb_topics_forum_id_type ON phpbb_topics(forum_id, topic_type);; -CREATE INDEX phpbb_topics_last_post_time ON phpbb_topics(topic_last_post_time);; -CREATE INDEX phpbb_topics_topic_visibility ON phpbb_topics(topic_visibility);; -CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics(forum_id, topic_visibility, topic_last_post_id);; -CREATE INDEX phpbb_topics_fid_time_moved ON phpbb_topics(forum_id, topic_last_post_time, topic_moved_id);; - -CREATE GENERATOR phpbb_topics_gen;; -SET GENERATOR phpbb_topics_gen TO 0;; - -CREATE TRIGGER t_phpbb_topics FOR phpbb_topics -BEFORE INSERT -AS -BEGIN - NEW.topic_id = GEN_ID(phpbb_topics_gen, 1); -END;; - - -# Table: 'phpbb_topics_track' -CREATE TABLE phpbb_topics_track ( - user_id INTEGER DEFAULT 0 NOT NULL, - topic_id INTEGER DEFAULT 0 NOT NULL, - forum_id INTEGER DEFAULT 0 NOT NULL, - mark_time INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_topics_track ADD PRIMARY KEY (user_id, topic_id);; - -CREATE INDEX phpbb_topics_track_topic_id ON phpbb_topics_track(topic_id);; -CREATE INDEX phpbb_topics_track_forum_id ON phpbb_topics_track(forum_id);; - -# Table: 'phpbb_topics_posted' -CREATE TABLE phpbb_topics_posted ( - user_id INTEGER DEFAULT 0 NOT NULL, - topic_id INTEGER DEFAULT 0 NOT NULL, - topic_posted INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_topics_posted ADD PRIMARY KEY (user_id, topic_id);; - - -# Table: 'phpbb_topics_watch' -CREATE TABLE phpbb_topics_watch ( - topic_id INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - notify_status INTEGER DEFAULT 0 NOT NULL -);; - -CREATE INDEX phpbb_topics_watch_topic_id ON phpbb_topics_watch(topic_id);; -CREATE INDEX phpbb_topics_watch_user_id ON phpbb_topics_watch(user_id);; -CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch(notify_status);; - -# Table: 'phpbb_user_notifications' -CREATE TABLE phpbb_user_notifications ( - item_type VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - item_id INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - method VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - notify INTEGER DEFAULT 1 NOT NULL -);; - - -# Table: 'phpbb_user_group' -CREATE TABLE phpbb_user_group ( - group_id INTEGER DEFAULT 0 NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - group_leader INTEGER DEFAULT 0 NOT NULL, - user_pending INTEGER DEFAULT 1 NOT NULL -);; - -CREATE INDEX phpbb_user_group_group_id ON phpbb_user_group(group_id);; -CREATE INDEX phpbb_user_group_user_id ON phpbb_user_group(user_id);; -CREATE INDEX phpbb_user_group_group_leader ON phpbb_user_group(group_leader);; - -# Table: 'phpbb_users' -CREATE TABLE phpbb_users ( - user_id INTEGER NOT NULL, - user_type INTEGER DEFAULT 0 NOT NULL, - group_id INTEGER DEFAULT 3 NOT NULL, - user_permissions BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, - user_perm_from INTEGER DEFAULT 0 NOT NULL, - user_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_regdate INTEGER DEFAULT 0 NOT NULL, - username VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - username_clean VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_password VARCHAR(40) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_passchg INTEGER DEFAULT 0 NOT NULL, - user_pass_convert INTEGER DEFAULT 0 NOT NULL, - user_email VARCHAR(100) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_email_hash DOUBLE PRECISION DEFAULT 0 NOT NULL, - user_birthday VARCHAR(10) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_lastvisit INTEGER DEFAULT 0 NOT NULL, - user_lastmark INTEGER DEFAULT 0 NOT NULL, - user_lastpost_time INTEGER DEFAULT 0 NOT NULL, - user_lastpage VARCHAR(200) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_last_confirm_key VARCHAR(10) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_last_search INTEGER DEFAULT 0 NOT NULL, - user_warnings INTEGER DEFAULT 0 NOT NULL, - user_last_warning INTEGER DEFAULT 0 NOT NULL, - user_login_attempts INTEGER DEFAULT 0 NOT NULL, - user_inactive_reason INTEGER DEFAULT 0 NOT NULL, - user_inactive_time INTEGER DEFAULT 0 NOT NULL, - user_posts INTEGER DEFAULT 0 NOT NULL, - user_lang VARCHAR(30) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_timezone VARCHAR(100) CHARACTER SET NONE DEFAULT 'UTC' NOT NULL, - user_dateformat VARCHAR(30) CHARACTER SET UTF8 DEFAULT 'd M Y H:i' NOT NULL COLLATE UNICODE, - user_style INTEGER DEFAULT 0 NOT NULL, - user_rank INTEGER DEFAULT 0 NOT NULL, - user_colour VARCHAR(6) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_new_privmsg INTEGER DEFAULT 0 NOT NULL, - user_unread_privmsg INTEGER DEFAULT 0 NOT NULL, - user_last_privmsg INTEGER DEFAULT 0 NOT NULL, - user_message_rules INTEGER DEFAULT 0 NOT NULL, - user_full_folder INTEGER DEFAULT -3 NOT NULL, - user_emailtime INTEGER DEFAULT 0 NOT NULL, - user_topic_show_days INTEGER DEFAULT 0 NOT NULL, - user_topic_sortby_type VARCHAR(1) CHARACTER SET NONE DEFAULT 't' NOT NULL, - user_topic_sortby_dir VARCHAR(1) CHARACTER SET NONE DEFAULT 'd' NOT NULL, - user_post_show_days INTEGER DEFAULT 0 NOT NULL, - user_post_sortby_type VARCHAR(1) CHARACTER SET NONE DEFAULT 't' NOT NULL, - user_post_sortby_dir VARCHAR(1) CHARACTER SET NONE DEFAULT 'a' NOT NULL, - user_notify INTEGER DEFAULT 0 NOT NULL, - user_notify_pm INTEGER DEFAULT 1 NOT NULL, - user_notify_type INTEGER DEFAULT 0 NOT NULL, - user_allow_pm INTEGER DEFAULT 1 NOT NULL, - user_allow_viewonline INTEGER DEFAULT 1 NOT NULL, - user_allow_viewemail INTEGER DEFAULT 1 NOT NULL, - user_allow_massemail INTEGER DEFAULT 1 NOT NULL, - user_options INTEGER DEFAULT 230271 NOT NULL, - user_avatar VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_avatar_type VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_avatar_width INTEGER DEFAULT 0 NOT NULL, - user_avatar_height INTEGER DEFAULT 0 NOT NULL, - user_sig BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - user_sig_bbcode_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_sig_bbcode_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_from VARCHAR(100) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_icq VARCHAR(15) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_aim VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_yim VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_msnm VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_jabber VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_website VARCHAR(200) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_occ BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - user_interests BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - user_actkey VARCHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_newpasswd VARCHAR(40) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_form_salt VARCHAR(32) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - user_new INTEGER DEFAULT 1 NOT NULL, - user_reminded INTEGER DEFAULT 0 NOT NULL, - user_reminded_time INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_users ADD PRIMARY KEY (user_id);; - -CREATE INDEX phpbb_users_user_birthday ON phpbb_users(user_birthday);; -CREATE INDEX phpbb_users_user_email_hash ON phpbb_users(user_email_hash);; -CREATE INDEX phpbb_users_user_type ON phpbb_users(user_type);; -CREATE UNIQUE INDEX phpbb_users_username_clean ON phpbb_users(username_clean);; - -CREATE GENERATOR phpbb_users_gen;; -SET GENERATOR phpbb_users_gen TO 0;; - -CREATE TRIGGER t_phpbb_users FOR phpbb_users -BEFORE INSERT -AS -BEGIN - NEW.user_id = GEN_ID(phpbb_users_gen, 1); -END;; - - -# Table: 'phpbb_warnings' -CREATE TABLE phpbb_warnings ( - warning_id INTEGER NOT NULL, - user_id INTEGER DEFAULT 0 NOT NULL, - post_id INTEGER DEFAULT 0 NOT NULL, - log_id INTEGER DEFAULT 0 NOT NULL, - warning_time INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_warnings ADD PRIMARY KEY (warning_id);; - - -CREATE GENERATOR phpbb_warnings_gen;; -SET GENERATOR phpbb_warnings_gen TO 0;; - -CREATE TRIGGER t_phpbb_warnings FOR phpbb_warnings -BEFORE INSERT -AS -BEGIN - NEW.warning_id = GEN_ID(phpbb_warnings_gen, 1); -END;; - - -# Table: 'phpbb_words' -CREATE TABLE phpbb_words ( - word_id INTEGER NOT NULL, - word VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, - replacement VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE -);; - -ALTER TABLE phpbb_words ADD PRIMARY KEY (word_id);; - - -CREATE GENERATOR phpbb_words_gen;; -SET GENERATOR phpbb_words_gen TO 0;; - -CREATE TRIGGER t_phpbb_words FOR phpbb_words -BEFORE INSERT -AS -BEGIN - NEW.word_id = GEN_ID(phpbb_words_gen, 1); -END;; - - -# Table: 'phpbb_zebra' -CREATE TABLE phpbb_zebra ( - user_id INTEGER DEFAULT 0 NOT NULL, - zebra_id INTEGER DEFAULT 0 NOT NULL, - friend INTEGER DEFAULT 0 NOT NULL, - foe INTEGER DEFAULT 0 NOT NULL -);; - -ALTER TABLE phpbb_zebra ADD PRIMARY KEY (user_id, zebra_id);; - - diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 922313236e..f88513cf0e 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -6,1825 +6,3 @@ * run it. */ -/* - Table: 'phpbb_attachments' -*/ -CREATE TABLE [phpbb_attachments] ( - [attach_id] [int] IDENTITY (1, 1) NOT NULL , - [post_msg_id] [int] DEFAULT (0) NOT NULL , - [topic_id] [int] DEFAULT (0) NOT NULL , - [in_message] [int] DEFAULT (0) NOT NULL , - [poster_id] [int] DEFAULT (0) NOT NULL , - [is_orphan] [int] DEFAULT (1) NOT NULL , - [physical_filename] [varchar] (255) DEFAULT ('') NOT NULL , - [real_filename] [varchar] (255) DEFAULT ('') NOT NULL , - [download_count] [int] DEFAULT (0) NOT NULL , - [attach_comment] [varchar] (4000) DEFAULT ('') NOT NULL , - [extension] [varchar] (100) DEFAULT ('') NOT NULL , - [mimetype] [varchar] (100) DEFAULT ('') NOT NULL , - [filesize] [int] DEFAULT (0) NOT NULL , - [filetime] [int] DEFAULT (0) NOT NULL , - [thumbnail] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_attachments] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_attachments] PRIMARY KEY CLUSTERED - ( - [attach_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [filetime] ON [phpbb_attachments]([filetime]) ON [PRIMARY] -GO - -CREATE INDEX [post_msg_id] ON [phpbb_attachments]([post_msg_id]) ON [PRIMARY] -GO - -CREATE INDEX [topic_id] ON [phpbb_attachments]([topic_id]) ON [PRIMARY] -GO - -CREATE INDEX [poster_id] ON [phpbb_attachments]([poster_id]) ON [PRIMARY] -GO - -CREATE INDEX [is_orphan] ON [phpbb_attachments]([is_orphan]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_acl_groups' -*/ -CREATE TABLE [phpbb_acl_groups] ( - [group_id] [int] DEFAULT (0) NOT NULL , - [forum_id] [int] DEFAULT (0) NOT NULL , - [auth_option_id] [int] DEFAULT (0) NOT NULL , - [auth_role_id] [int] DEFAULT (0) NOT NULL , - [auth_setting] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -CREATE INDEX [group_id] ON [phpbb_acl_groups]([group_id]) ON [PRIMARY] -GO - -CREATE INDEX [auth_opt_id] ON [phpbb_acl_groups]([auth_option_id]) ON [PRIMARY] -GO - -CREATE INDEX [auth_role_id] ON [phpbb_acl_groups]([auth_role_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_acl_options' -*/ -CREATE TABLE [phpbb_acl_options] ( - [auth_option_id] [int] IDENTITY (1, 1) NOT NULL , - [auth_option] [varchar] (50) DEFAULT ('') NOT NULL , - [is_global] [int] DEFAULT (0) NOT NULL , - [is_local] [int] DEFAULT (0) NOT NULL , - [founder_only] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_acl_options] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_acl_options] PRIMARY KEY CLUSTERED - ( - [auth_option_id] - ) ON [PRIMARY] -GO - -CREATE UNIQUE INDEX [auth_option] ON [phpbb_acl_options]([auth_option]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_acl_roles' -*/ -CREATE TABLE [phpbb_acl_roles] ( - [role_id] [int] IDENTITY (1, 1) NOT NULL , - [role_name] [varchar] (255) DEFAULT ('') NOT NULL , - [role_description] [varchar] (4000) DEFAULT ('') NOT NULL , - [role_type] [varchar] (10) DEFAULT ('') NOT NULL , - [role_order] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_acl_roles] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_acl_roles] PRIMARY KEY CLUSTERED - ( - [role_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [role_type] ON [phpbb_acl_roles]([role_type]) ON [PRIMARY] -GO - -CREATE INDEX [role_order] ON [phpbb_acl_roles]([role_order]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_acl_roles_data' -*/ -CREATE TABLE [phpbb_acl_roles_data] ( - [role_id] [int] DEFAULT (0) NOT NULL , - [auth_option_id] [int] DEFAULT (0) NOT NULL , - [auth_setting] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_acl_roles_data] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_acl_roles_data] PRIMARY KEY CLUSTERED - ( - [role_id], - [auth_option_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [ath_op_id] ON [phpbb_acl_roles_data]([auth_option_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_acl_users' -*/ -CREATE TABLE [phpbb_acl_users] ( - [user_id] [int] DEFAULT (0) NOT NULL , - [forum_id] [int] DEFAULT (0) NOT NULL , - [auth_option_id] [int] DEFAULT (0) NOT NULL , - [auth_role_id] [int] DEFAULT (0) NOT NULL , - [auth_setting] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -CREATE INDEX [user_id] ON [phpbb_acl_users]([user_id]) ON [PRIMARY] -GO - -CREATE INDEX [auth_option_id] ON [phpbb_acl_users]([auth_option_id]) ON [PRIMARY] -GO - -CREATE INDEX [auth_role_id] ON [phpbb_acl_users]([auth_role_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_oauth_tokens' -*/ -CREATE TABLE [phpbb_oauth_tokens] ( - [user_id] [int] DEFAULT (0) NOT NULL , - [session_id] [char] (32) DEFAULT ('') NOT NULL , - [provider] [varchar] (255) DEFAULT ('') NOT NULL , - [oauth_token] [text] DEFAULT ('') NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -CREATE INDEX [user_id] ON [phpbb_oauth_tokens]([user_id]) ON [PRIMARY] -GO - -CREATE INDEX [provider] ON [phpbb_oauth_tokens]([provider]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_oauth_accounts' -*/ -CREATE TABLE [phpbb_oauth_accounts] ( - [user_id] [int] DEFAULT (0) NOT NULL , - [provider] [varchar] (255) DEFAULT ('') NOT NULL , - [oauth_provider_id] [varchar] (4000) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_oauth_accounts] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_oauth_accounts] PRIMARY KEY CLUSTERED - ( - [user_id], - [provider] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_banlist' -*/ -CREATE TABLE [phpbb_banlist] ( - [ban_id] [int] IDENTITY (1, 1) NOT NULL , - [ban_userid] [int] DEFAULT (0) NOT NULL , - [ban_ip] [varchar] (40) DEFAULT ('') NOT NULL , - [ban_email] [varchar] (100) DEFAULT ('') NOT NULL , - [ban_start] [int] DEFAULT (0) NOT NULL , - [ban_end] [int] DEFAULT (0) NOT NULL , - [ban_exclude] [int] DEFAULT (0) NOT NULL , - [ban_reason] [varchar] (255) DEFAULT ('') NOT NULL , - [ban_give_reason] [varchar] (255) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_banlist] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_banlist] PRIMARY KEY CLUSTERED - ( - [ban_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [ban_end] ON [phpbb_banlist]([ban_end]) ON [PRIMARY] -GO - -CREATE INDEX [ban_user] ON [phpbb_banlist]([ban_userid], [ban_exclude]) ON [PRIMARY] -GO - -CREATE INDEX [ban_email] ON [phpbb_banlist]([ban_email], [ban_exclude]) ON [PRIMARY] -GO - -CREATE INDEX [ban_ip] ON [phpbb_banlist]([ban_ip], [ban_exclude]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_bbcodes' -*/ -CREATE TABLE [phpbb_bbcodes] ( - [bbcode_id] [int] DEFAULT (0) NOT NULL , - [bbcode_tag] [varchar] (16) DEFAULT ('') NOT NULL , - [bbcode_helpline] [varchar] (255) DEFAULT ('') NOT NULL , - [display_on_posting] [int] DEFAULT (0) NOT NULL , - [bbcode_match] [varchar] (4000) DEFAULT ('') NOT NULL , - [bbcode_tpl] [text] DEFAULT ('') NOT NULL , - [first_pass_match] [text] DEFAULT ('') NOT NULL , - [first_pass_replace] [text] DEFAULT ('') NOT NULL , - [second_pass_match] [text] DEFAULT ('') NOT NULL , - [second_pass_replace] [text] DEFAULT ('') NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_bbcodes] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_bbcodes] PRIMARY KEY CLUSTERED - ( - [bbcode_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [display_on_post] ON [phpbb_bbcodes]([display_on_posting]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_bookmarks' -*/ -CREATE TABLE [phpbb_bookmarks] ( - [topic_id] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_bookmarks] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_bookmarks] PRIMARY KEY CLUSTERED - ( - [topic_id], - [user_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_bots' -*/ -CREATE TABLE [phpbb_bots] ( - [bot_id] [int] IDENTITY (1, 1) NOT NULL , - [bot_active] [int] DEFAULT (1) NOT NULL , - [bot_name] [varchar] (255) DEFAULT ('') NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [bot_agent] [varchar] (255) DEFAULT ('') NOT NULL , - [bot_ip] [varchar] (255) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_bots] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_bots] PRIMARY KEY CLUSTERED - ( - [bot_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [bot_active] ON [phpbb_bots]([bot_active]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_config' -*/ -CREATE TABLE [phpbb_config] ( - [config_name] [varchar] (255) DEFAULT ('') NOT NULL , - [config_value] [varchar] (255) DEFAULT ('') NOT NULL , - [is_dynamic] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_config] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_config] PRIMARY KEY CLUSTERED - ( - [config_name] - ) ON [PRIMARY] -GO - -CREATE INDEX [is_dynamic] ON [phpbb_config]([is_dynamic]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_config_text' -*/ -CREATE TABLE [phpbb_config_text] ( - [config_name] [varchar] (255) DEFAULT ('') NOT NULL , - [config_value] [text] DEFAULT ('') NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_config_text] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_config_text] PRIMARY KEY CLUSTERED - ( - [config_name] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_confirm' -*/ -CREATE TABLE [phpbb_confirm] ( - [confirm_id] [char] (32) DEFAULT ('') NOT NULL , - [session_id] [char] (32) DEFAULT ('') NOT NULL , - [confirm_type] [int] DEFAULT (0) NOT NULL , - [code] [varchar] (8) DEFAULT ('') NOT NULL , - [seed] [int] DEFAULT (0) NOT NULL , - [attempts] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_confirm] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_confirm] PRIMARY KEY CLUSTERED - ( - [session_id], - [confirm_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [confirm_type] ON [phpbb_confirm]([confirm_type]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_disallow' -*/ -CREATE TABLE [phpbb_disallow] ( - [disallow_id] [int] IDENTITY (1, 1) NOT NULL , - [disallow_username] [varchar] (255) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_disallow] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_disallow] PRIMARY KEY CLUSTERED - ( - [disallow_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_drafts' -*/ -CREATE TABLE [phpbb_drafts] ( - [draft_id] [int] IDENTITY (1, 1) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [topic_id] [int] DEFAULT (0) NOT NULL , - [forum_id] [int] DEFAULT (0) NOT NULL , - [save_time] [int] DEFAULT (0) NOT NULL , - [draft_subject] [varchar] (255) DEFAULT ('') NOT NULL , - [draft_message] [text] DEFAULT ('') NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_drafts] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_drafts] PRIMARY KEY CLUSTERED - ( - [draft_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [save_time] ON [phpbb_drafts]([save_time]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_ext' -*/ -CREATE TABLE [phpbb_ext] ( - [ext_name] [varchar] (255) DEFAULT ('') NOT NULL , - [ext_active] [int] DEFAULT (0) NOT NULL , - [ext_state] [varchar] (8000) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -CREATE UNIQUE INDEX [ext_name] ON [phpbb_ext]([ext_name]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_extensions' -*/ -CREATE TABLE [phpbb_extensions] ( - [extension_id] [int] IDENTITY (1, 1) NOT NULL , - [group_id] [int] DEFAULT (0) NOT NULL , - [extension] [varchar] (100) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_extensions] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_extensions] PRIMARY KEY CLUSTERED - ( - [extension_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_extension_groups' -*/ -CREATE TABLE [phpbb_extension_groups] ( - [group_id] [int] IDENTITY (1, 1) NOT NULL , - [group_name] [varchar] (255) DEFAULT ('') NOT NULL , - [cat_id] [int] DEFAULT (0) NOT NULL , - [allow_group] [int] DEFAULT (0) NOT NULL , - [download_mode] [int] DEFAULT (1) NOT NULL , - [upload_icon] [varchar] (255) DEFAULT ('') NOT NULL , - [max_filesize] [int] DEFAULT (0) NOT NULL , - [allowed_forums] [varchar] (8000) DEFAULT ('') NOT NULL , - [allow_in_pm] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_extension_groups] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_extension_groups] PRIMARY KEY CLUSTERED - ( - [group_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_forums' -*/ -CREATE TABLE [phpbb_forums] ( - [forum_id] [int] IDENTITY (1, 1) NOT NULL , - [parent_id] [int] DEFAULT (0) NOT NULL , - [left_id] [int] DEFAULT (0) NOT NULL , - [right_id] [int] DEFAULT (0) NOT NULL , - [forum_parents] [text] DEFAULT ('') NOT NULL , - [forum_name] [varchar] (255) DEFAULT ('') NOT NULL , - [forum_desc] [varchar] (4000) DEFAULT ('') NOT NULL , - [forum_desc_bitfield] [varchar] (255) DEFAULT ('') NOT NULL , - [forum_desc_options] [int] DEFAULT (7) NOT NULL , - [forum_desc_uid] [varchar] (8) DEFAULT ('') NOT NULL , - [forum_link] [varchar] (255) DEFAULT ('') NOT NULL , - [forum_password] [varchar] (40) DEFAULT ('') NOT NULL , - [forum_style] [int] DEFAULT (0) NOT NULL , - [forum_image] [varchar] (255) DEFAULT ('') NOT NULL , - [forum_rules] [varchar] (4000) DEFAULT ('') NOT NULL , - [forum_rules_link] [varchar] (255) DEFAULT ('') NOT NULL , - [forum_rules_bitfield] [varchar] (255) DEFAULT ('') NOT NULL , - [forum_rules_options] [int] DEFAULT (7) NOT NULL , - [forum_rules_uid] [varchar] (8) DEFAULT ('') NOT NULL , - [forum_topics_per_page] [int] DEFAULT (0) NOT NULL , - [forum_type] [int] DEFAULT (0) NOT NULL , - [forum_status] [int] DEFAULT (0) NOT NULL , - [forum_posts_approved] [int] DEFAULT (0) NOT NULL , - [forum_posts_unapproved] [int] DEFAULT (0) NOT NULL , - [forum_posts_softdeleted] [int] DEFAULT (0) NOT NULL , - [forum_topics_approved] [int] DEFAULT (0) NOT NULL , - [forum_topics_unapproved] [int] DEFAULT (0) NOT NULL , - [forum_topics_softdeleted] [int] DEFAULT (0) NOT NULL , - [forum_last_post_id] [int] DEFAULT (0) NOT NULL , - [forum_last_poster_id] [int] DEFAULT (0) NOT NULL , - [forum_last_post_subject] [varchar] (255) DEFAULT ('') NOT NULL , - [forum_last_post_time] [int] DEFAULT (0) NOT NULL , - [forum_last_poster_name] [varchar] (255) DEFAULT ('') NOT NULL , - [forum_last_poster_colour] [varchar] (6) DEFAULT ('') NOT NULL , - [forum_flags] [int] DEFAULT (32) NOT NULL , - [forum_options] [int] DEFAULT (0) NOT NULL , - [display_subforum_list] [int] DEFAULT (1) NOT NULL , - [display_on_index] [int] DEFAULT (1) NOT NULL , - [enable_indexing] [int] DEFAULT (1) NOT NULL , - [enable_icons] [int] DEFAULT (1) NOT NULL , - [enable_prune] [int] DEFAULT (0) NOT NULL , - [prune_next] [int] DEFAULT (0) NOT NULL , - [prune_days] [int] DEFAULT (0) NOT NULL , - [prune_viewed] [int] DEFAULT (0) NOT NULL , - [prune_freq] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_forums] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_forums] PRIMARY KEY CLUSTERED - ( - [forum_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [left_right_id] ON [phpbb_forums]([left_id], [right_id]) ON [PRIMARY] -GO - -CREATE INDEX [forum_lastpost_id] ON [phpbb_forums]([forum_last_post_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_forums_access' -*/ -CREATE TABLE [phpbb_forums_access] ( - [forum_id] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [session_id] [char] (32) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_forums_access] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_forums_access] PRIMARY KEY CLUSTERED - ( - [forum_id], - [user_id], - [session_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_forums_track' -*/ -CREATE TABLE [phpbb_forums_track] ( - [user_id] [int] DEFAULT (0) NOT NULL , - [forum_id] [int] DEFAULT (0) NOT NULL , - [mark_time] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_forums_track] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_forums_track] PRIMARY KEY CLUSTERED - ( - [user_id], - [forum_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_forums_watch' -*/ -CREATE TABLE [phpbb_forums_watch] ( - [forum_id] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [notify_status] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -CREATE INDEX [forum_id] ON [phpbb_forums_watch]([forum_id]) ON [PRIMARY] -GO - -CREATE INDEX [user_id] ON [phpbb_forums_watch]([user_id]) ON [PRIMARY] -GO - -CREATE INDEX [notify_stat] ON [phpbb_forums_watch]([notify_status]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_groups' -*/ -CREATE TABLE [phpbb_groups] ( - [group_id] [int] IDENTITY (1, 1) NOT NULL , - [group_type] [int] DEFAULT (1) NOT NULL , - [group_founder_manage] [int] DEFAULT (0) NOT NULL , - [group_skip_auth] [int] DEFAULT (0) NOT NULL , - [group_name] [varchar] (255) DEFAULT ('') NOT NULL , - [group_desc] [varchar] (4000) DEFAULT ('') NOT NULL , - [group_desc_bitfield] [varchar] (255) DEFAULT ('') NOT NULL , - [group_desc_options] [int] DEFAULT (7) NOT NULL , - [group_desc_uid] [varchar] (8) DEFAULT ('') NOT NULL , - [group_display] [int] DEFAULT (0) NOT NULL , - [group_avatar] [varchar] (255) DEFAULT ('') NOT NULL , - [group_avatar_type] [varchar] (255) DEFAULT ('') NOT NULL , - [group_avatar_width] [int] DEFAULT (0) NOT NULL , - [group_avatar_height] [int] DEFAULT (0) NOT NULL , - [group_rank] [int] DEFAULT (0) NOT NULL , - [group_colour] [varchar] (6) DEFAULT ('') NOT NULL , - [group_sig_chars] [int] DEFAULT (0) NOT NULL , - [group_receive_pm] [int] DEFAULT (0) NOT NULL , - [group_message_limit] [int] DEFAULT (0) NOT NULL , - [group_max_recipients] [int] DEFAULT (0) NOT NULL , - [group_legend] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_groups] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_groups] PRIMARY KEY CLUSTERED - ( - [group_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [group_legend_name] ON [phpbb_groups]([group_legend], [group_name]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_icons' -*/ -CREATE TABLE [phpbb_icons] ( - [icons_id] [int] IDENTITY (1, 1) NOT NULL , - [icons_url] [varchar] (255) DEFAULT ('') NOT NULL , - [icons_width] [int] DEFAULT (0) NOT NULL , - [icons_height] [int] DEFAULT (0) NOT NULL , - [icons_order] [int] DEFAULT (0) NOT NULL , - [display_on_posting] [int] DEFAULT (1) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_icons] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_icons] PRIMARY KEY CLUSTERED - ( - [icons_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [display_on_posting] ON [phpbb_icons]([display_on_posting]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_lang' -*/ -CREATE TABLE [phpbb_lang] ( - [lang_id] [int] IDENTITY (1, 1) NOT NULL , - [lang_iso] [varchar] (30) DEFAULT ('') NOT NULL , - [lang_dir] [varchar] (30) DEFAULT ('') NOT NULL , - [lang_english_name] [varchar] (100) DEFAULT ('') NOT NULL , - [lang_local_name] [varchar] (255) DEFAULT ('') NOT NULL , - [lang_author] [varchar] (255) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_lang] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_lang] PRIMARY KEY CLUSTERED - ( - [lang_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [lang_iso] ON [phpbb_lang]([lang_iso]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_log' -*/ -CREATE TABLE [phpbb_log] ( - [log_id] [int] IDENTITY (1, 1) NOT NULL , - [log_type] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [forum_id] [int] DEFAULT (0) NOT NULL , - [topic_id] [int] DEFAULT (0) NOT NULL , - [reportee_id] [int] DEFAULT (0) NOT NULL , - [log_ip] [varchar] (40) DEFAULT ('') NOT NULL , - [log_time] [int] DEFAULT (0) NOT NULL , - [log_operation] [varchar] (4000) DEFAULT ('') NOT NULL , - [log_data] [text] DEFAULT ('') NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_log] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_log] PRIMARY KEY CLUSTERED - ( - [log_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [log_type] ON [phpbb_log]([log_type]) ON [PRIMARY] -GO - -CREATE INDEX [log_time] ON [phpbb_log]([log_time]) ON [PRIMARY] -GO - -CREATE INDEX [forum_id] ON [phpbb_log]([forum_id]) ON [PRIMARY] -GO - -CREATE INDEX [topic_id] ON [phpbb_log]([topic_id]) ON [PRIMARY] -GO - -CREATE INDEX [reportee_id] ON [phpbb_log]([reportee_id]) ON [PRIMARY] -GO - -CREATE INDEX [user_id] ON [phpbb_log]([user_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_login_attempts' -*/ -CREATE TABLE [phpbb_login_attempts] ( - [attempt_ip] [varchar] (40) DEFAULT ('') NOT NULL , - [attempt_browser] [varchar] (150) DEFAULT ('') NOT NULL , - [attempt_forwarded_for] [varchar] (255) DEFAULT ('') NOT NULL , - [attempt_time] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [username] [varchar] (255) DEFAULT (0) NOT NULL , - [username_clean] [varchar] (255) DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -CREATE INDEX [att_ip] ON [phpbb_login_attempts]([attempt_ip], [attempt_time]) ON [PRIMARY] -GO - -CREATE INDEX [att_for] ON [phpbb_login_attempts]([attempt_forwarded_for], [attempt_time]) ON [PRIMARY] -GO - -CREATE INDEX [att_time] ON [phpbb_login_attempts]([attempt_time]) ON [PRIMARY] -GO - -CREATE INDEX [user_id] ON [phpbb_login_attempts]([user_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_moderator_cache' -*/ -CREATE TABLE [phpbb_moderator_cache] ( - [forum_id] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [username] [varchar] (255) DEFAULT ('') NOT NULL , - [group_id] [int] DEFAULT (0) NOT NULL , - [group_name] [varchar] (255) DEFAULT ('') NOT NULL , - [display_on_index] [int] DEFAULT (1) NOT NULL -) ON [PRIMARY] -GO - -CREATE INDEX [disp_idx] ON [phpbb_moderator_cache]([display_on_index]) ON [PRIMARY] -GO - -CREATE INDEX [forum_id] ON [phpbb_moderator_cache]([forum_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_migrations' -*/ -CREATE TABLE [phpbb_migrations] ( - [migration_name] [varchar] (255) DEFAULT ('') NOT NULL , - [migration_depends_on] [varchar] (8000) DEFAULT ('') NOT NULL , - [migration_schema_done] [int] DEFAULT (0) NOT NULL , - [migration_data_done] [int] DEFAULT (0) NOT NULL , - [migration_data_state] [varchar] (8000) DEFAULT ('') NOT NULL , - [migration_start_time] [int] DEFAULT (0) NOT NULL , - [migration_end_time] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_migrations] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_migrations] PRIMARY KEY CLUSTERED - ( - [migration_name] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_modules' -*/ -CREATE TABLE [phpbb_modules] ( - [module_id] [int] IDENTITY (1, 1) NOT NULL , - [module_enabled] [int] DEFAULT (1) NOT NULL , - [module_display] [int] DEFAULT (1) NOT NULL , - [module_basename] [varchar] (255) DEFAULT ('') NOT NULL , - [module_class] [varchar] (10) DEFAULT ('') NOT NULL , - [parent_id] [int] DEFAULT (0) NOT NULL , - [left_id] [int] DEFAULT (0) NOT NULL , - [right_id] [int] DEFAULT (0) NOT NULL , - [module_langname] [varchar] (255) DEFAULT ('') NOT NULL , - [module_mode] [varchar] (255) DEFAULT ('') NOT NULL , - [module_auth] [varchar] (255) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_modules] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_modules] PRIMARY KEY CLUSTERED - ( - [module_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [left_right_id] ON [phpbb_modules]([left_id], [right_id]) ON [PRIMARY] -GO - -CREATE INDEX [module_enabled] ON [phpbb_modules]([module_enabled]) ON [PRIMARY] -GO - -CREATE INDEX [class_left_id] ON [phpbb_modules]([module_class], [left_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_notification_types' -*/ -CREATE TABLE [phpbb_notification_types] ( - [notification_type_id] [int] IDENTITY (1, 1) NOT NULL , - [notification_type_name] [varchar] (255) DEFAULT ('') NOT NULL , - [notification_type_enabled] [int] DEFAULT (1) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_notification_types] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_notification_types] PRIMARY KEY CLUSTERED - ( - [notification_type_id] - ) ON [PRIMARY] -GO - -CREATE UNIQUE INDEX [type] ON [phpbb_notification_types]([notification_type_name]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_notifications' -*/ -CREATE TABLE [phpbb_notifications] ( - [notification_id] [int] IDENTITY (1, 1) NOT NULL , - [notification_type_id] [int] DEFAULT (0) NOT NULL , - [item_id] [int] DEFAULT (0) NOT NULL , - [item_parent_id] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [notification_read] [int] DEFAULT (0) NOT NULL , - [notification_time] [int] DEFAULT (1) NOT NULL , - [notification_data] [varchar] (4000) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_notifications] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_notifications] PRIMARY KEY CLUSTERED - ( - [notification_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [item_ident] ON [phpbb_notifications]([notification_type_id], [item_id]) ON [PRIMARY] -GO - -CREATE INDEX [user] ON [phpbb_notifications]([user_id], [notification_read]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_poll_options' -*/ -CREATE TABLE [phpbb_poll_options] ( - [poll_option_id] [int] DEFAULT (0) NOT NULL , - [topic_id] [int] DEFAULT (0) NOT NULL , - [poll_option_text] [varchar] (4000) DEFAULT ('') NOT NULL , - [poll_option_total] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -CREATE INDEX [poll_opt_id] ON [phpbb_poll_options]([poll_option_id]) ON [PRIMARY] -GO - -CREATE INDEX [topic_id] ON [phpbb_poll_options]([topic_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_poll_votes' -*/ -CREATE TABLE [phpbb_poll_votes] ( - [topic_id] [int] DEFAULT (0) NOT NULL , - [poll_option_id] [int] DEFAULT (0) NOT NULL , - [vote_user_id] [int] DEFAULT (0) NOT NULL , - [vote_user_ip] [varchar] (40) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -CREATE INDEX [topic_id] ON [phpbb_poll_votes]([topic_id]) ON [PRIMARY] -GO - -CREATE INDEX [vote_user_id] ON [phpbb_poll_votes]([vote_user_id]) ON [PRIMARY] -GO - -CREATE INDEX [vote_user_ip] ON [phpbb_poll_votes]([vote_user_ip]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_posts' -*/ -CREATE TABLE [phpbb_posts] ( - [post_id] [int] IDENTITY (1, 1) NOT NULL , - [topic_id] [int] DEFAULT (0) NOT NULL , - [forum_id] [int] DEFAULT (0) NOT NULL , - [poster_id] [int] DEFAULT (0) NOT NULL , - [icon_id] [int] DEFAULT (0) NOT NULL , - [poster_ip] [varchar] (40) DEFAULT ('') NOT NULL , - [post_time] [int] DEFAULT (0) NOT NULL , - [post_visibility] [int] DEFAULT (0) NOT NULL , - [post_reported] [int] DEFAULT (0) NOT NULL , - [enable_bbcode] [int] DEFAULT (1) NOT NULL , - [enable_smilies] [int] DEFAULT (1) NOT NULL , - [enable_magic_url] [int] DEFAULT (1) NOT NULL , - [enable_sig] [int] DEFAULT (1) NOT NULL , - [post_username] [varchar] (255) DEFAULT ('') NOT NULL , - [post_subject] [varchar] (255) DEFAULT ('') NOT NULL , - [post_text] [text] DEFAULT ('') NOT NULL , - [post_checksum] [varchar] (32) DEFAULT ('') NOT NULL , - [post_attachment] [int] DEFAULT (0) NOT NULL , - [bbcode_bitfield] [varchar] (255) DEFAULT ('') NOT NULL , - [bbcode_uid] [varchar] (8) DEFAULT ('') NOT NULL , - [post_postcount] [int] DEFAULT (1) NOT NULL , - [post_edit_time] [int] DEFAULT (0) NOT NULL , - [post_edit_reason] [varchar] (255) DEFAULT ('') NOT NULL , - [post_edit_user] [int] DEFAULT (0) NOT NULL , - [post_edit_count] [int] DEFAULT (0) NOT NULL , - [post_edit_locked] [int] DEFAULT (0) NOT NULL , - [post_delete_time] [int] DEFAULT (0) NOT NULL , - [post_delete_reason] [varchar] (255) DEFAULT ('') NOT NULL , - [post_delete_user] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_posts] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_posts] PRIMARY KEY CLUSTERED - ( - [post_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [forum_id] ON [phpbb_posts]([forum_id]) ON [PRIMARY] -GO - -CREATE INDEX [topic_id] ON [phpbb_posts]([topic_id]) ON [PRIMARY] -GO - -CREATE INDEX [poster_ip] ON [phpbb_posts]([poster_ip]) ON [PRIMARY] -GO - -CREATE INDEX [poster_id] ON [phpbb_posts]([poster_id]) ON [PRIMARY] -GO - -CREATE INDEX [post_visibility] ON [phpbb_posts]([post_visibility]) ON [PRIMARY] -GO - -CREATE INDEX [post_username] ON [phpbb_posts]([post_username]) ON [PRIMARY] -GO - -CREATE INDEX [tid_post_time] ON [phpbb_posts]([topic_id], [post_time]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_privmsgs' -*/ -CREATE TABLE [phpbb_privmsgs] ( - [msg_id] [int] IDENTITY (1, 1) NOT NULL , - [root_level] [int] DEFAULT (0) NOT NULL , - [author_id] [int] DEFAULT (0) NOT NULL , - [icon_id] [int] DEFAULT (0) NOT NULL , - [author_ip] [varchar] (40) DEFAULT ('') NOT NULL , - [message_time] [int] DEFAULT (0) NOT NULL , - [enable_bbcode] [int] DEFAULT (1) NOT NULL , - [enable_smilies] [int] DEFAULT (1) NOT NULL , - [enable_magic_url] [int] DEFAULT (1) NOT NULL , - [enable_sig] [int] DEFAULT (1) NOT NULL , - [message_subject] [varchar] (255) DEFAULT ('') NOT NULL , - [message_text] [text] DEFAULT ('') NOT NULL , - [message_edit_reason] [varchar] (255) DEFAULT ('') NOT NULL , - [message_edit_user] [int] DEFAULT (0) NOT NULL , - [message_attachment] [int] DEFAULT (0) NOT NULL , - [bbcode_bitfield] [varchar] (255) DEFAULT ('') NOT NULL , - [bbcode_uid] [varchar] (8) DEFAULT ('') NOT NULL , - [message_edit_time] [int] DEFAULT (0) NOT NULL , - [message_edit_count] [int] DEFAULT (0) NOT NULL , - [to_address] [varchar] (4000) DEFAULT ('') NOT NULL , - [bcc_address] [varchar] (4000) DEFAULT ('') NOT NULL , - [message_reported] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_privmsgs] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_privmsgs] PRIMARY KEY CLUSTERED - ( - [msg_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [author_ip] ON [phpbb_privmsgs]([author_ip]) ON [PRIMARY] -GO - -CREATE INDEX [message_time] ON [phpbb_privmsgs]([message_time]) ON [PRIMARY] -GO - -CREATE INDEX [author_id] ON [phpbb_privmsgs]([author_id]) ON [PRIMARY] -GO - -CREATE INDEX [root_level] ON [phpbb_privmsgs]([root_level]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_privmsgs_folder' -*/ -CREATE TABLE [phpbb_privmsgs_folder] ( - [folder_id] [int] IDENTITY (1, 1) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [folder_name] [varchar] (255) DEFAULT ('') NOT NULL , - [pm_count] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_privmsgs_folder] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_privmsgs_folder] PRIMARY KEY CLUSTERED - ( - [folder_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [user_id] ON [phpbb_privmsgs_folder]([user_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_privmsgs_rules' -*/ -CREATE TABLE [phpbb_privmsgs_rules] ( - [rule_id] [int] IDENTITY (1, 1) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [rule_check] [int] DEFAULT (0) NOT NULL , - [rule_connection] [int] DEFAULT (0) NOT NULL , - [rule_string] [varchar] (255) DEFAULT ('') NOT NULL , - [rule_user_id] [int] DEFAULT (0) NOT NULL , - [rule_group_id] [int] DEFAULT (0) NOT NULL , - [rule_action] [int] DEFAULT (0) NOT NULL , - [rule_folder_id] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_privmsgs_rules] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_privmsgs_rules] PRIMARY KEY CLUSTERED - ( - [rule_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [user_id] ON [phpbb_privmsgs_rules]([user_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_privmsgs_to' -*/ -CREATE TABLE [phpbb_privmsgs_to] ( - [msg_id] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [author_id] [int] DEFAULT (0) NOT NULL , - [pm_deleted] [int] DEFAULT (0) NOT NULL , - [pm_new] [int] DEFAULT (1) NOT NULL , - [pm_unread] [int] DEFAULT (1) NOT NULL , - [pm_replied] [int] DEFAULT (0) NOT NULL , - [pm_marked] [int] DEFAULT (0) NOT NULL , - [pm_forwarded] [int] DEFAULT (0) NOT NULL , - [folder_id] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -CREATE INDEX [msg_id] ON [phpbb_privmsgs_to]([msg_id]) ON [PRIMARY] -GO - -CREATE INDEX [author_id] ON [phpbb_privmsgs_to]([author_id]) ON [PRIMARY] -GO - -CREATE INDEX [usr_flder_id] ON [phpbb_privmsgs_to]([user_id], [folder_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_profile_fields' -*/ -CREATE TABLE [phpbb_profile_fields] ( - [field_id] [int] IDENTITY (1, 1) NOT NULL , - [field_name] [varchar] (255) DEFAULT ('') NOT NULL , - [field_type] [int] DEFAULT (0) NOT NULL , - [field_ident] [varchar] (20) DEFAULT ('') NOT NULL , - [field_length] [varchar] (20) DEFAULT ('') NOT NULL , - [field_minlen] [varchar] (255) DEFAULT ('') NOT NULL , - [field_maxlen] [varchar] (255) DEFAULT ('') NOT NULL , - [field_novalue] [varchar] (255) DEFAULT ('') NOT NULL , - [field_default_value] [varchar] (255) DEFAULT ('') NOT NULL , - [field_validation] [varchar] (20) DEFAULT ('') NOT NULL , - [field_required] [int] DEFAULT (0) NOT NULL , - [field_show_novalue] [int] DEFAULT (0) NOT NULL , - [field_show_on_reg] [int] DEFAULT (0) NOT NULL , - [field_show_on_pm] [int] DEFAULT (0) NOT NULL , - [field_show_on_vt] [int] DEFAULT (0) NOT NULL , - [field_show_profile] [int] DEFAULT (0) NOT NULL , - [field_hide] [int] DEFAULT (0) NOT NULL , - [field_no_view] [int] DEFAULT (0) NOT NULL , - [field_active] [int] DEFAULT (0) NOT NULL , - [field_order] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_profile_fields] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_profile_fields] PRIMARY KEY CLUSTERED - ( - [field_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [fld_type] ON [phpbb_profile_fields]([field_type]) ON [PRIMARY] -GO - -CREATE INDEX [fld_ordr] ON [phpbb_profile_fields]([field_order]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_profile_fields_data' -*/ -CREATE TABLE [phpbb_profile_fields_data] ( - [user_id] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_profile_fields_data] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_profile_fields_data] PRIMARY KEY CLUSTERED - ( - [user_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_profile_fields_lang' -*/ -CREATE TABLE [phpbb_profile_fields_lang] ( - [field_id] [int] DEFAULT (0) NOT NULL , - [lang_id] [int] DEFAULT (0) NOT NULL , - [option_id] [int] DEFAULT (0) NOT NULL , - [field_type] [int] DEFAULT (0) NOT NULL , - [lang_value] [varchar] (255) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_profile_fields_lang] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_profile_fields_lang] PRIMARY KEY CLUSTERED - ( - [field_id], - [lang_id], - [option_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_profile_lang' -*/ -CREATE TABLE [phpbb_profile_lang] ( - [field_id] [int] DEFAULT (0) NOT NULL , - [lang_id] [int] DEFAULT (0) NOT NULL , - [lang_name] [varchar] (255) DEFAULT ('') NOT NULL , - [lang_explain] [varchar] (4000) DEFAULT ('') NOT NULL , - [lang_default_value] [varchar] (255) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_profile_lang] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_profile_lang] PRIMARY KEY CLUSTERED - ( - [field_id], - [lang_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_ranks' -*/ -CREATE TABLE [phpbb_ranks] ( - [rank_id] [int] IDENTITY (1, 1) NOT NULL , - [rank_title] [varchar] (255) DEFAULT ('') NOT NULL , - [rank_min] [int] DEFAULT (0) NOT NULL , - [rank_special] [int] DEFAULT (0) NOT NULL , - [rank_image] [varchar] (255) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_ranks] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_ranks] PRIMARY KEY CLUSTERED - ( - [rank_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_reports' -*/ -CREATE TABLE [phpbb_reports] ( - [report_id] [int] IDENTITY (1, 1) NOT NULL , - [reason_id] [int] DEFAULT (0) NOT NULL , - [post_id] [int] DEFAULT (0) NOT NULL , - [pm_id] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [user_notify] [int] DEFAULT (0) NOT NULL , - [report_closed] [int] DEFAULT (0) NOT NULL , - [report_time] [int] DEFAULT (0) NOT NULL , - [report_text] [text] DEFAULT ('') NOT NULL , - [reported_post_text] [text] DEFAULT ('') NOT NULL , - [reported_post_uid] [varchar] (8) DEFAULT ('') NOT NULL , - [reported_post_bitfield] [varchar] (255) DEFAULT ('') NOT NULL , - [reported_post_enable_magic_url] [int] DEFAULT (1) NOT NULL , - [reported_post_enable_smilies] [int] DEFAULT (1) NOT NULL , - [reported_post_enable_bbcode] [int] DEFAULT (1) NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_reports] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_reports] PRIMARY KEY CLUSTERED - ( - [report_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [post_id] ON [phpbb_reports]([post_id]) ON [PRIMARY] -GO - -CREATE INDEX [pm_id] ON [phpbb_reports]([pm_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_reports_reasons' -*/ -CREATE TABLE [phpbb_reports_reasons] ( - [reason_id] [int] IDENTITY (1, 1) NOT NULL , - [reason_title] [varchar] (255) DEFAULT ('') NOT NULL , - [reason_description] [text] DEFAULT ('') NOT NULL , - [reason_order] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_reports_reasons] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_reports_reasons] PRIMARY KEY CLUSTERED - ( - [reason_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_search_results' -*/ -CREATE TABLE [phpbb_search_results] ( - [search_key] [varchar] (32) DEFAULT ('') NOT NULL , - [search_time] [int] DEFAULT (0) NOT NULL , - [search_keywords] [text] DEFAULT ('') NOT NULL , - [search_authors] [text] DEFAULT ('') NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_search_results] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_search_results] PRIMARY KEY CLUSTERED - ( - [search_key] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_search_wordlist' -*/ -CREATE TABLE [phpbb_search_wordlist] ( - [word_id] [int] IDENTITY (1, 1) NOT NULL , - [word_text] [varchar] (255) DEFAULT ('') NOT NULL , - [word_common] [int] DEFAULT (0) NOT NULL , - [word_count] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_search_wordlist] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_search_wordlist] PRIMARY KEY CLUSTERED - ( - [word_id] - ) ON [PRIMARY] -GO - -CREATE UNIQUE INDEX [wrd_txt] ON [phpbb_search_wordlist]([word_text]) ON [PRIMARY] -GO - -CREATE INDEX [wrd_cnt] ON [phpbb_search_wordlist]([word_count]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_search_wordmatch' -*/ -CREATE TABLE [phpbb_search_wordmatch] ( - [post_id] [int] DEFAULT (0) NOT NULL , - [word_id] [int] DEFAULT (0) NOT NULL , - [title_match] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -CREATE UNIQUE INDEX [unq_mtch] ON [phpbb_search_wordmatch]([word_id], [post_id], [title_match]) ON [PRIMARY] -GO - -CREATE INDEX [word_id] ON [phpbb_search_wordmatch]([word_id]) ON [PRIMARY] -GO - -CREATE INDEX [post_id] ON [phpbb_search_wordmatch]([post_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_sessions' -*/ -CREATE TABLE [phpbb_sessions] ( - [session_id] [char] (32) DEFAULT ('') NOT NULL , - [session_user_id] [int] DEFAULT (0) NOT NULL , - [session_forum_id] [int] DEFAULT (0) NOT NULL , - [session_last_visit] [int] DEFAULT (0) NOT NULL , - [session_start] [int] DEFAULT (0) NOT NULL , - [session_time] [int] DEFAULT (0) NOT NULL , - [session_ip] [varchar] (40) DEFAULT ('') NOT NULL , - [session_browser] [varchar] (150) DEFAULT ('') NOT NULL , - [session_forwarded_for] [varchar] (255) DEFAULT ('') NOT NULL , - [session_page] [varchar] (255) DEFAULT ('') NOT NULL , - [session_viewonline] [int] DEFAULT (1) NOT NULL , - [session_autologin] [int] DEFAULT (0) NOT NULL , - [session_admin] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_sessions] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_sessions] PRIMARY KEY CLUSTERED - ( - [session_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [session_time] ON [phpbb_sessions]([session_time]) ON [PRIMARY] -GO - -CREATE INDEX [session_user_id] ON [phpbb_sessions]([session_user_id]) ON [PRIMARY] -GO - -CREATE INDEX [session_fid] ON [phpbb_sessions]([session_forum_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_sessions_keys' -*/ -CREATE TABLE [phpbb_sessions_keys] ( - [key_id] [char] (32) DEFAULT ('') NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [last_ip] [varchar] (40) DEFAULT ('') NOT NULL , - [last_login] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_sessions_keys] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_sessions_keys] PRIMARY KEY CLUSTERED - ( - [key_id], - [user_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [last_login] ON [phpbb_sessions_keys]([last_login]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_sitelist' -*/ -CREATE TABLE [phpbb_sitelist] ( - [site_id] [int] IDENTITY (1, 1) NOT NULL , - [site_ip] [varchar] (40) DEFAULT ('') NOT NULL , - [site_hostname] [varchar] (255) DEFAULT ('') NOT NULL , - [ip_exclude] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_sitelist] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_sitelist] PRIMARY KEY CLUSTERED - ( - [site_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_smilies' -*/ -CREATE TABLE [phpbb_smilies] ( - [smiley_id] [int] IDENTITY (1, 1) NOT NULL , - [code] [varchar] (50) DEFAULT ('') NOT NULL , - [emotion] [varchar] (50) DEFAULT ('') NOT NULL , - [smiley_url] [varchar] (50) DEFAULT ('') NOT NULL , - [smiley_width] [int] DEFAULT (0) NOT NULL , - [smiley_height] [int] DEFAULT (0) NOT NULL , - [smiley_order] [int] DEFAULT (0) NOT NULL , - [display_on_posting] [int] DEFAULT (1) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_smilies] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_smilies] PRIMARY KEY CLUSTERED - ( - [smiley_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [display_on_post] ON [phpbb_smilies]([display_on_posting]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_styles' -*/ -CREATE TABLE [phpbb_styles] ( - [style_id] [int] IDENTITY (1, 1) NOT NULL , - [style_name] [varchar] (255) DEFAULT ('') NOT NULL , - [style_copyright] [varchar] (255) DEFAULT ('') NOT NULL , - [style_active] [int] DEFAULT (1) NOT NULL , - [style_path] [varchar] (100) DEFAULT ('') NOT NULL , - [bbcode_bitfield] [varchar] (255) DEFAULT ('kNg=') NOT NULL , - [style_parent_id] [int] DEFAULT (0) NOT NULL , - [style_parent_tree] [varchar] (8000) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_styles] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_styles] PRIMARY KEY CLUSTERED - ( - [style_id] - ) ON [PRIMARY] -GO - -CREATE UNIQUE INDEX [style_name] ON [phpbb_styles]([style_name]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_teampage' -*/ -CREATE TABLE [phpbb_teampage] ( - [teampage_id] [int] IDENTITY (1, 1) NOT NULL , - [group_id] [int] DEFAULT (0) NOT NULL , - [teampage_name] [varchar] (255) DEFAULT ('') NOT NULL , - [teampage_position] [int] DEFAULT (0) NOT NULL , - [teampage_parent] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_teampage] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_teampage] PRIMARY KEY CLUSTERED - ( - [teampage_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_topics' -*/ -CREATE TABLE [phpbb_topics] ( - [topic_id] [int] IDENTITY (1, 1) NOT NULL , - [forum_id] [int] DEFAULT (0) NOT NULL , - [icon_id] [int] DEFAULT (0) NOT NULL , - [topic_attachment] [int] DEFAULT (0) NOT NULL , - [topic_visibility] [int] DEFAULT (0) NOT NULL , - [topic_reported] [int] DEFAULT (0) NOT NULL , - [topic_title] [varchar] (255) DEFAULT ('') NOT NULL , - [topic_poster] [int] DEFAULT (0) NOT NULL , - [topic_time] [int] DEFAULT (0) NOT NULL , - [topic_time_limit] [int] DEFAULT (0) NOT NULL , - [topic_views] [int] DEFAULT (0) NOT NULL , - [topic_posts_approved] [int] DEFAULT (0) NOT NULL , - [topic_posts_unapproved] [int] DEFAULT (0) NOT NULL , - [topic_posts_softdeleted] [int] DEFAULT (0) NOT NULL , - [topic_status] [int] DEFAULT (0) NOT NULL , - [topic_type] [int] DEFAULT (0) NOT NULL , - [topic_first_post_id] [int] DEFAULT (0) NOT NULL , - [topic_first_poster_name] [varchar] (255) DEFAULT ('') NOT NULL , - [topic_first_poster_colour] [varchar] (6) DEFAULT ('') NOT NULL , - [topic_last_post_id] [int] DEFAULT (0) NOT NULL , - [topic_last_poster_id] [int] DEFAULT (0) NOT NULL , - [topic_last_poster_name] [varchar] (255) DEFAULT ('') NOT NULL , - [topic_last_poster_colour] [varchar] (6) DEFAULT ('') NOT NULL , - [topic_last_post_subject] [varchar] (255) DEFAULT ('') NOT NULL , - [topic_last_post_time] [int] DEFAULT (0) NOT NULL , - [topic_last_view_time] [int] DEFAULT (0) NOT NULL , - [topic_moved_id] [int] DEFAULT (0) NOT NULL , - [topic_bumped] [int] DEFAULT (0) NOT NULL , - [topic_bumper] [int] DEFAULT (0) NOT NULL , - [poll_title] [varchar] (255) DEFAULT ('') NOT NULL , - [poll_start] [int] DEFAULT (0) NOT NULL , - [poll_length] [int] DEFAULT (0) NOT NULL , - [poll_max_options] [int] DEFAULT (1) NOT NULL , - [poll_last_vote] [int] DEFAULT (0) NOT NULL , - [poll_vote_change] [int] DEFAULT (0) NOT NULL , - [topic_delete_time] [int] DEFAULT (0) NOT NULL , - [topic_delete_reason] [varchar] (255) DEFAULT ('') NOT NULL , - [topic_delete_user] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_topics] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_topics] PRIMARY KEY CLUSTERED - ( - [topic_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [forum_id] ON [phpbb_topics]([forum_id]) ON [PRIMARY] -GO - -CREATE INDEX [forum_id_type] ON [phpbb_topics]([forum_id], [topic_type]) ON [PRIMARY] -GO - -CREATE INDEX [last_post_time] ON [phpbb_topics]([topic_last_post_time]) ON [PRIMARY] -GO - -CREATE INDEX [topic_visibility] ON [phpbb_topics]([topic_visibility]) ON [PRIMARY] -GO - -CREATE INDEX [forum_appr_last] ON [phpbb_topics]([forum_id], [topic_visibility], [topic_last_post_id]) ON [PRIMARY] -GO - -CREATE INDEX [fid_time_moved] ON [phpbb_topics]([forum_id], [topic_last_post_time], [topic_moved_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_topics_track' -*/ -CREATE TABLE [phpbb_topics_track] ( - [user_id] [int] DEFAULT (0) NOT NULL , - [topic_id] [int] DEFAULT (0) NOT NULL , - [forum_id] [int] DEFAULT (0) NOT NULL , - [mark_time] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_topics_track] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_topics_track] PRIMARY KEY CLUSTERED - ( - [user_id], - [topic_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [topic_id] ON [phpbb_topics_track]([topic_id]) ON [PRIMARY] -GO - -CREATE INDEX [forum_id] ON [phpbb_topics_track]([forum_id]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_topics_posted' -*/ -CREATE TABLE [phpbb_topics_posted] ( - [user_id] [int] DEFAULT (0) NOT NULL , - [topic_id] [int] DEFAULT (0) NOT NULL , - [topic_posted] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_topics_posted] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_topics_posted] PRIMARY KEY CLUSTERED - ( - [user_id], - [topic_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_topics_watch' -*/ -CREATE TABLE [phpbb_topics_watch] ( - [topic_id] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [notify_status] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -CREATE INDEX [topic_id] ON [phpbb_topics_watch]([topic_id]) ON [PRIMARY] -GO - -CREATE INDEX [user_id] ON [phpbb_topics_watch]([user_id]) ON [PRIMARY] -GO - -CREATE INDEX [notify_stat] ON [phpbb_topics_watch]([notify_status]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_user_notifications' -*/ -CREATE TABLE [phpbb_user_notifications] ( - [item_type] [varchar] (255) DEFAULT ('') NOT NULL , - [item_id] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [method] [varchar] (255) DEFAULT ('') NOT NULL , - [notify] [int] DEFAULT (1) NOT NULL -) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_user_group' -*/ -CREATE TABLE [phpbb_user_group] ( - [group_id] [int] DEFAULT (0) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [group_leader] [int] DEFAULT (0) NOT NULL , - [user_pending] [int] DEFAULT (1) NOT NULL -) ON [PRIMARY] -GO - -CREATE INDEX [group_id] ON [phpbb_user_group]([group_id]) ON [PRIMARY] -GO - -CREATE INDEX [user_id] ON [phpbb_user_group]([user_id]) ON [PRIMARY] -GO - -CREATE INDEX [group_leader] ON [phpbb_user_group]([group_leader]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_users' -*/ -CREATE TABLE [phpbb_users] ( - [user_id] [int] IDENTITY (1, 1) NOT NULL , - [user_type] [int] DEFAULT (0) NOT NULL , - [group_id] [int] DEFAULT (3) NOT NULL , - [user_permissions] [text] DEFAULT ('') NOT NULL , - [user_perm_from] [int] DEFAULT (0) NOT NULL , - [user_ip] [varchar] (40) DEFAULT ('') NOT NULL , - [user_regdate] [int] DEFAULT (0) NOT NULL , - [username] [varchar] (255) DEFAULT ('') NOT NULL , - [username_clean] [varchar] (255) DEFAULT ('') NOT NULL , - [user_password] [varchar] (40) DEFAULT ('') NOT NULL , - [user_passchg] [int] DEFAULT (0) NOT NULL , - [user_pass_convert] [int] DEFAULT (0) NOT NULL , - [user_email] [varchar] (100) DEFAULT ('') NOT NULL , - [user_email_hash] [float] DEFAULT (0) NOT NULL , - [user_birthday] [varchar] (10) DEFAULT ('') NOT NULL , - [user_lastvisit] [int] DEFAULT (0) NOT NULL , - [user_lastmark] [int] DEFAULT (0) NOT NULL , - [user_lastpost_time] [int] DEFAULT (0) NOT NULL , - [user_lastpage] [varchar] (200) DEFAULT ('') NOT NULL , - [user_last_confirm_key] [varchar] (10) DEFAULT ('') NOT NULL , - [user_last_search] [int] DEFAULT (0) NOT NULL , - [user_warnings] [int] DEFAULT (0) NOT NULL , - [user_last_warning] [int] DEFAULT (0) NOT NULL , - [user_login_attempts] [int] DEFAULT (0) NOT NULL , - [user_inactive_reason] [int] DEFAULT (0) NOT NULL , - [user_inactive_time] [int] DEFAULT (0) NOT NULL , - [user_posts] [int] DEFAULT (0) NOT NULL , - [user_lang] [varchar] (30) DEFAULT ('') NOT NULL , - [user_timezone] [varchar] (100) DEFAULT ('UTC') NOT NULL , - [user_dateformat] [varchar] (30) DEFAULT ('d M Y H:i') NOT NULL , - [user_style] [int] DEFAULT (0) NOT NULL , - [user_rank] [int] DEFAULT (0) NOT NULL , - [user_colour] [varchar] (6) DEFAULT ('') NOT NULL , - [user_new_privmsg] [int] DEFAULT (0) NOT NULL , - [user_unread_privmsg] [int] DEFAULT (0) NOT NULL , - [user_last_privmsg] [int] DEFAULT (0) NOT NULL , - [user_message_rules] [int] DEFAULT (0) NOT NULL , - [user_full_folder] [int] DEFAULT (-3) NOT NULL , - [user_emailtime] [int] DEFAULT (0) NOT NULL , - [user_topic_show_days] [int] DEFAULT (0) NOT NULL , - [user_topic_sortby_type] [varchar] (1) DEFAULT ('t') NOT NULL , - [user_topic_sortby_dir] [varchar] (1) DEFAULT ('d') NOT NULL , - [user_post_show_days] [int] DEFAULT (0) NOT NULL , - [user_post_sortby_type] [varchar] (1) DEFAULT ('t') NOT NULL , - [user_post_sortby_dir] [varchar] (1) DEFAULT ('a') NOT NULL , - [user_notify] [int] DEFAULT (0) NOT NULL , - [user_notify_pm] [int] DEFAULT (1) NOT NULL , - [user_notify_type] [int] DEFAULT (0) NOT NULL , - [user_allow_pm] [int] DEFAULT (1) NOT NULL , - [user_allow_viewonline] [int] DEFAULT (1) NOT NULL , - [user_allow_viewemail] [int] DEFAULT (1) NOT NULL , - [user_allow_massemail] [int] DEFAULT (1) NOT NULL , - [user_options] [int] DEFAULT (230271) NOT NULL , - [user_avatar] [varchar] (255) DEFAULT ('') NOT NULL , - [user_avatar_type] [varchar] (255) DEFAULT ('') NOT NULL , - [user_avatar_width] [int] DEFAULT (0) NOT NULL , - [user_avatar_height] [int] DEFAULT (0) NOT NULL , - [user_sig] [text] DEFAULT ('') NOT NULL , - [user_sig_bbcode_uid] [varchar] (8) DEFAULT ('') NOT NULL , - [user_sig_bbcode_bitfield] [varchar] (255) DEFAULT ('') NOT NULL , - [user_from] [varchar] (100) DEFAULT ('') NOT NULL , - [user_icq] [varchar] (15) DEFAULT ('') NOT NULL , - [user_aim] [varchar] (255) DEFAULT ('') NOT NULL , - [user_yim] [varchar] (255) DEFAULT ('') NOT NULL , - [user_msnm] [varchar] (255) DEFAULT ('') NOT NULL , - [user_jabber] [varchar] (255) DEFAULT ('') NOT NULL , - [user_website] [varchar] (200) DEFAULT ('') NOT NULL , - [user_occ] [varchar] (4000) DEFAULT ('') NOT NULL , - [user_interests] [varchar] (4000) DEFAULT ('') NOT NULL , - [user_actkey] [varchar] (32) DEFAULT ('') NOT NULL , - [user_newpasswd] [varchar] (40) DEFAULT ('') NOT NULL , - [user_form_salt] [varchar] (32) DEFAULT ('') NOT NULL , - [user_new] [int] DEFAULT (1) NOT NULL , - [user_reminded] [int] DEFAULT (0) NOT NULL , - [user_reminded_time] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] -GO - -ALTER TABLE [phpbb_users] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_users] PRIMARY KEY CLUSTERED - ( - [user_id] - ) ON [PRIMARY] -GO - -CREATE INDEX [user_birthday] ON [phpbb_users]([user_birthday]) ON [PRIMARY] -GO - -CREATE INDEX [user_email_hash] ON [phpbb_users]([user_email_hash]) ON [PRIMARY] -GO - -CREATE INDEX [user_type] ON [phpbb_users]([user_type]) ON [PRIMARY] -GO - -CREATE UNIQUE INDEX [username_clean] ON [phpbb_users]([username_clean]) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_warnings' -*/ -CREATE TABLE [phpbb_warnings] ( - [warning_id] [int] IDENTITY (1, 1) NOT NULL , - [user_id] [int] DEFAULT (0) NOT NULL , - [post_id] [int] DEFAULT (0) NOT NULL , - [log_id] [int] DEFAULT (0) NOT NULL , - [warning_time] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_warnings] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_warnings] PRIMARY KEY CLUSTERED - ( - [warning_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_words' -*/ -CREATE TABLE [phpbb_words] ( - [word_id] [int] IDENTITY (1, 1) NOT NULL , - [word] [varchar] (255) DEFAULT ('') NOT NULL , - [replacement] [varchar] (255) DEFAULT ('') NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_words] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_words] PRIMARY KEY CLUSTERED - ( - [word_id] - ) ON [PRIMARY] -GO - - -/* - Table: 'phpbb_zebra' -*/ -CREATE TABLE [phpbb_zebra] ( - [user_id] [int] DEFAULT (0) NOT NULL , - [zebra_id] [int] DEFAULT (0) NOT NULL , - [friend] [int] DEFAULT (0) NOT NULL , - [foe] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -ALTER TABLE [phpbb_zebra] WITH NOCHECK ADD - CONSTRAINT [PK_phpbb_zebra] PRIMARY KEY CLUSTERED - ( - [user_id], - [zebra_id] - ) ON [PRIMARY] -GO - - diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index e07a768387..28649dc54c 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -3,1078 +3,3 @@ # To change the contents of this file, edit # phpBB/develop/create_schema_files.php and # run it. -# Table: 'phpbb_attachments' -CREATE TABLE phpbb_attachments ( - attach_id mediumint(8) UNSIGNED NOT NULL auto_increment, - post_msg_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - in_message tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - poster_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - is_orphan tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - physical_filename varbinary(255) DEFAULT '' NOT NULL, - real_filename varbinary(255) DEFAULT '' NOT NULL, - download_count mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - attach_comment blob NOT NULL, - extension varbinary(100) DEFAULT '' NOT NULL, - mimetype varbinary(100) DEFAULT '' NOT NULL, - filesize int(20) UNSIGNED DEFAULT '0' NOT NULL, - filetime int(11) UNSIGNED DEFAULT '0' NOT NULL, - thumbnail tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (attach_id), - KEY filetime (filetime), - KEY post_msg_id (post_msg_id), - KEY topic_id (topic_id), - KEY poster_id (poster_id), - KEY is_orphan (is_orphan) -); - - -# Table: 'phpbb_acl_groups' -CREATE TABLE phpbb_acl_groups ( - group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_option_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_role_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_setting tinyint(2) DEFAULT '0' NOT NULL, - KEY group_id (group_id), - KEY auth_opt_id (auth_option_id), - KEY auth_role_id (auth_role_id) -); - - -# Table: 'phpbb_acl_options' -CREATE TABLE phpbb_acl_options ( - auth_option_id mediumint(8) UNSIGNED NOT NULL auto_increment, - auth_option varbinary(50) DEFAULT '' NOT NULL, - is_global tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - is_local tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - founder_only tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (auth_option_id), - UNIQUE auth_option (auth_option) -); - - -# Table: 'phpbb_acl_roles' -CREATE TABLE phpbb_acl_roles ( - role_id mediumint(8) UNSIGNED NOT NULL auto_increment, - role_name blob NOT NULL, - role_description blob NOT NULL, - role_type varbinary(10) DEFAULT '' NOT NULL, - role_order smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (role_id), - KEY role_type (role_type), - KEY role_order (role_order) -); - - -# Table: 'phpbb_acl_roles_data' -CREATE TABLE phpbb_acl_roles_data ( - role_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_option_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_setting tinyint(2) DEFAULT '0' NOT NULL, - PRIMARY KEY (role_id, auth_option_id), - KEY ath_op_id (auth_option_id) -); - - -# Table: 'phpbb_acl_users' -CREATE TABLE phpbb_acl_users ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_option_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_role_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_setting tinyint(2) DEFAULT '0' NOT NULL, - KEY user_id (user_id), - KEY auth_option_id (auth_option_id), - KEY auth_role_id (auth_role_id) -); - - -# Table: 'phpbb_oauth_tokens' -CREATE TABLE phpbb_oauth_tokens ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - session_id binary(32) DEFAULT '' NOT NULL, - provider varbinary(255) DEFAULT '' NOT NULL, - oauth_token mediumblob NOT NULL, - KEY user_id (user_id), - KEY provider (provider) -); - - -# Table: 'phpbb_oauth_accounts' -CREATE TABLE phpbb_oauth_accounts ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - provider varbinary(255) DEFAULT '' NOT NULL, - oauth_provider_id blob NOT NULL, - PRIMARY KEY (user_id, provider) -); - - -# Table: 'phpbb_banlist' -CREATE TABLE phpbb_banlist ( - ban_id mediumint(8) UNSIGNED NOT NULL auto_increment, - ban_userid mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - ban_ip varbinary(40) DEFAULT '' NOT NULL, - ban_email blob NOT NULL, - ban_start int(11) UNSIGNED DEFAULT '0' NOT NULL, - ban_end int(11) UNSIGNED DEFAULT '0' NOT NULL, - ban_exclude tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - ban_reason blob NOT NULL, - ban_give_reason blob NOT NULL, - PRIMARY KEY (ban_id), - KEY ban_end (ban_end), - KEY ban_user (ban_userid, ban_exclude), - KEY ban_email (ban_email(255), ban_exclude), - KEY ban_ip (ban_ip, ban_exclude) -); - - -# Table: 'phpbb_bbcodes' -CREATE TABLE phpbb_bbcodes ( - bbcode_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - bbcode_tag varbinary(16) DEFAULT '' NOT NULL, - bbcode_helpline blob NOT NULL, - display_on_posting tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - bbcode_match blob NOT NULL, - bbcode_tpl mediumblob NOT NULL, - first_pass_match mediumblob NOT NULL, - first_pass_replace mediumblob NOT NULL, - second_pass_match mediumblob NOT NULL, - second_pass_replace mediumblob NOT NULL, - PRIMARY KEY (bbcode_id), - KEY display_on_post (display_on_posting) -); - - -# Table: 'phpbb_bookmarks' -CREATE TABLE phpbb_bookmarks ( - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (topic_id, user_id) -); - - -# Table: 'phpbb_bots' -CREATE TABLE phpbb_bots ( - bot_id mediumint(8) UNSIGNED NOT NULL auto_increment, - bot_active tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - bot_name blob NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - bot_agent varbinary(255) DEFAULT '' NOT NULL, - bot_ip varbinary(255) DEFAULT '' NOT NULL, - PRIMARY KEY (bot_id), - KEY bot_active (bot_active) -); - - -# Table: 'phpbb_config' -CREATE TABLE phpbb_config ( - config_name varbinary(255) DEFAULT '' NOT NULL, - config_value blob NOT NULL, - is_dynamic tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (config_name), - KEY is_dynamic (is_dynamic) -); - - -# Table: 'phpbb_config_text' -CREATE TABLE phpbb_config_text ( - config_name varbinary(255) DEFAULT '' NOT NULL, - config_value mediumblob NOT NULL, - PRIMARY KEY (config_name) -); - - -# Table: 'phpbb_confirm' -CREATE TABLE phpbb_confirm ( - confirm_id binary(32) DEFAULT '' NOT NULL, - session_id binary(32) DEFAULT '' NOT NULL, - confirm_type tinyint(3) DEFAULT '0' NOT NULL, - code varbinary(8) DEFAULT '' NOT NULL, - seed int(10) UNSIGNED DEFAULT '0' NOT NULL, - attempts mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (session_id, confirm_id), - KEY confirm_type (confirm_type) -); - - -# Table: 'phpbb_disallow' -CREATE TABLE phpbb_disallow ( - disallow_id mediumint(8) UNSIGNED NOT NULL auto_increment, - disallow_username blob NOT NULL, - PRIMARY KEY (disallow_id) -); - - -# Table: 'phpbb_drafts' -CREATE TABLE phpbb_drafts ( - draft_id mediumint(8) UNSIGNED NOT NULL auto_increment, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - save_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - draft_subject blob NOT NULL, - draft_message mediumblob NOT NULL, - PRIMARY KEY (draft_id), - KEY save_time (save_time) -); - - -# Table: 'phpbb_ext' -CREATE TABLE phpbb_ext ( - ext_name varbinary(255) DEFAULT '' NOT NULL, - ext_active tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - ext_state blob NOT NULL, - UNIQUE ext_name (ext_name) -); - - -# Table: 'phpbb_extensions' -CREATE TABLE phpbb_extensions ( - extension_id mediumint(8) UNSIGNED NOT NULL auto_increment, - group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - extension varbinary(100) DEFAULT '' NOT NULL, - PRIMARY KEY (extension_id) -); - - -# Table: 'phpbb_extension_groups' -CREATE TABLE phpbb_extension_groups ( - group_id mediumint(8) UNSIGNED NOT NULL auto_increment, - group_name blob NOT NULL, - cat_id tinyint(2) DEFAULT '0' NOT NULL, - allow_group tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - download_mode tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - upload_icon varbinary(255) DEFAULT '' NOT NULL, - max_filesize int(20) UNSIGNED DEFAULT '0' NOT NULL, - allowed_forums blob NOT NULL, - allow_in_pm tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (group_id) -); - - -# Table: 'phpbb_forums' -CREATE TABLE phpbb_forums ( - forum_id mediumint(8) UNSIGNED NOT NULL auto_increment, - parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - left_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - right_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_parents mediumblob NOT NULL, - forum_name blob NOT NULL, - forum_desc blob NOT NULL, - forum_desc_bitfield varbinary(255) DEFAULT '' NOT NULL, - forum_desc_options int(11) UNSIGNED DEFAULT '7' NOT NULL, - forum_desc_uid varbinary(8) DEFAULT '' NOT NULL, - forum_link blob NOT NULL, - forum_password varbinary(120) DEFAULT '' NOT NULL, - forum_style mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_image varbinary(255) DEFAULT '' NOT NULL, - forum_rules blob NOT NULL, - forum_rules_link blob NOT NULL, - forum_rules_bitfield varbinary(255) DEFAULT '' NOT NULL, - forum_rules_options int(11) UNSIGNED DEFAULT '7' NOT NULL, - forum_rules_uid varbinary(8) DEFAULT '' NOT NULL, - forum_topics_per_page tinyint(4) DEFAULT '0' NOT NULL, - forum_type tinyint(4) DEFAULT '0' NOT NULL, - forum_status tinyint(4) DEFAULT '0' NOT NULL, - forum_posts_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_posts_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_posts_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_topics_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_topics_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_topics_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_last_post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_last_poster_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_last_post_subject blob NOT NULL, - forum_last_post_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - forum_last_poster_name blob NOT NULL, - forum_last_poster_colour varbinary(6) DEFAULT '' NOT NULL, - forum_flags tinyint(4) DEFAULT '32' NOT NULL, - forum_options int(20) UNSIGNED DEFAULT '0' NOT NULL, - display_subforum_list tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - display_on_index tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_indexing tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_icons tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_prune tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - prune_next int(11) UNSIGNED DEFAULT '0' NOT NULL, - prune_days mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - prune_viewed mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - prune_freq mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (forum_id), - KEY left_right_id (left_id, right_id), - KEY forum_lastpost_id (forum_last_post_id) -); - - -# Table: 'phpbb_forums_access' -CREATE TABLE phpbb_forums_access ( - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - session_id binary(32) DEFAULT '' NOT NULL, - PRIMARY KEY (forum_id, user_id, session_id) -); - - -# Table: 'phpbb_forums_track' -CREATE TABLE phpbb_forums_track ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - mark_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id, forum_id) -); - - -# Table: 'phpbb_forums_watch' -CREATE TABLE phpbb_forums_watch ( - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - notify_status tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - KEY forum_id (forum_id), - KEY user_id (user_id), - KEY notify_stat (notify_status) -); - - -# Table: 'phpbb_groups' -CREATE TABLE phpbb_groups ( - group_id mediumint(8) UNSIGNED NOT NULL auto_increment, - group_type tinyint(4) DEFAULT '1' NOT NULL, - group_founder_manage tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - group_skip_auth tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - group_name blob NOT NULL, - group_desc blob NOT NULL, - group_desc_bitfield varbinary(255) DEFAULT '' NOT NULL, - group_desc_options int(11) UNSIGNED DEFAULT '7' NOT NULL, - group_desc_uid varbinary(8) DEFAULT '' NOT NULL, - group_display tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - group_avatar varbinary(255) DEFAULT '' NOT NULL, - group_avatar_type varbinary(255) DEFAULT '' NOT NULL, - group_avatar_width smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - group_avatar_height smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - group_rank mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_colour varbinary(6) DEFAULT '' NOT NULL, - group_sig_chars mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_receive_pm tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - group_message_limit mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_max_recipients mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_legend mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (group_id), - KEY group_legend_name (group_legend, group_name(255)) -); - - -# Table: 'phpbb_icons' -CREATE TABLE phpbb_icons ( - icons_id mediumint(8) UNSIGNED NOT NULL auto_increment, - icons_url varbinary(255) DEFAULT '' NOT NULL, - icons_width tinyint(4) DEFAULT '0' NOT NULL, - icons_height tinyint(4) DEFAULT '0' NOT NULL, - icons_order mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - display_on_posting tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - PRIMARY KEY (icons_id), - KEY display_on_posting (display_on_posting) -); - - -# Table: 'phpbb_lang' -CREATE TABLE phpbb_lang ( - lang_id tinyint(4) NOT NULL auto_increment, - lang_iso varbinary(30) DEFAULT '' NOT NULL, - lang_dir varbinary(30) DEFAULT '' NOT NULL, - lang_english_name blob NOT NULL, - lang_local_name blob NOT NULL, - lang_author blob NOT NULL, - PRIMARY KEY (lang_id), - KEY lang_iso (lang_iso) -); - - -# Table: 'phpbb_log' -CREATE TABLE phpbb_log ( - log_id mediumint(8) UNSIGNED NOT NULL auto_increment, - log_type tinyint(4) DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - reportee_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - log_ip varbinary(40) DEFAULT '' NOT NULL, - log_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - log_operation blob NOT NULL, - log_data mediumblob NOT NULL, - PRIMARY KEY (log_id), - KEY log_type (log_type), - KEY log_time (log_time), - KEY forum_id (forum_id), - KEY topic_id (topic_id), - KEY reportee_id (reportee_id), - KEY user_id (user_id) -); - - -# Table: 'phpbb_login_attempts' -CREATE TABLE phpbb_login_attempts ( - attempt_ip varbinary(40) DEFAULT '' NOT NULL, - attempt_browser varbinary(150) DEFAULT '' NOT NULL, - attempt_forwarded_for varbinary(255) DEFAULT '' NOT NULL, - attempt_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - username blob NOT NULL, - username_clean blob NOT NULL, - KEY att_ip (attempt_ip, attempt_time), - KEY att_for (attempt_forwarded_for, attempt_time), - KEY att_time (attempt_time), - KEY user_id (user_id) -); - - -# Table: 'phpbb_moderator_cache' -CREATE TABLE phpbb_moderator_cache ( - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - username blob NOT NULL, - group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_name blob NOT NULL, - display_on_index tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - KEY disp_idx (display_on_index), - KEY forum_id (forum_id) -); - - -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name varbinary(255) DEFAULT '' NOT NULL, - migration_depends_on blob NOT NULL, - migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_state blob NOT NULL, - migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (migration_name) -); - - -# Table: 'phpbb_modules' -CREATE TABLE phpbb_modules ( - module_id mediumint(8) UNSIGNED NOT NULL auto_increment, - module_enabled tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - module_display tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - module_basename varbinary(255) DEFAULT '' NOT NULL, - module_class varbinary(10) DEFAULT '' NOT NULL, - parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - left_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - right_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - module_langname varbinary(255) DEFAULT '' NOT NULL, - module_mode varbinary(255) DEFAULT '' NOT NULL, - module_auth varbinary(255) DEFAULT '' NOT NULL, - PRIMARY KEY (module_id), - KEY left_right_id (left_id, right_id), - KEY module_enabled (module_enabled), - KEY class_left_id (module_class, left_id) -); - - -# Table: 'phpbb_notification_types' -CREATE TABLE phpbb_notification_types ( - notification_type_id smallint(4) UNSIGNED NOT NULL auto_increment, - notification_type_name varbinary(255) DEFAULT '' NOT NULL, - notification_type_enabled tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - PRIMARY KEY (notification_type_id), - UNIQUE type (notification_type_name) -); - - -# Table: 'phpbb_notifications' -CREATE TABLE phpbb_notifications ( - notification_id int(10) UNSIGNED NOT NULL auto_increment, - notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - item_parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - notification_read tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - notification_time int(11) UNSIGNED DEFAULT '1' NOT NULL, - notification_data blob NOT NULL, - PRIMARY KEY (notification_id), - KEY item_ident (notification_type_id, item_id), - KEY user (user_id, notification_read) -); - - -# Table: 'phpbb_poll_options' -CREATE TABLE phpbb_poll_options ( - poll_option_id tinyint(4) DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - poll_option_text blob NOT NULL, - poll_option_total mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - KEY poll_opt_id (poll_option_id), - KEY topic_id (topic_id) -); - - -# Table: 'phpbb_poll_votes' -CREATE TABLE phpbb_poll_votes ( - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - poll_option_id tinyint(4) DEFAULT '0' NOT NULL, - vote_user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - vote_user_ip varbinary(40) DEFAULT '' NOT NULL, - KEY topic_id (topic_id), - KEY vote_user_id (vote_user_id), - KEY vote_user_ip (vote_user_ip) -); - - -# Table: 'phpbb_posts' -CREATE TABLE phpbb_posts ( - post_id mediumint(8) UNSIGNED NOT NULL auto_increment, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - poster_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - icon_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - poster_ip varbinary(40) DEFAULT '' NOT NULL, - post_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - post_visibility tinyint(3) DEFAULT '0' NOT NULL, - post_reported tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - enable_bbcode tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_smilies tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_magic_url tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_sig tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - post_username blob NOT NULL, - post_subject blob NOT NULL, - post_text mediumblob NOT NULL, - post_checksum varbinary(32) DEFAULT '' NOT NULL, - post_attachment tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - bbcode_bitfield varbinary(255) DEFAULT '' NOT NULL, - bbcode_uid varbinary(8) DEFAULT '' NOT NULL, - post_postcount tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - post_edit_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - post_edit_reason blob NOT NULL, - post_edit_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - post_edit_count smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - post_edit_locked tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - post_delete_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - post_delete_reason blob NOT NULL, - post_delete_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (post_id), - KEY forum_id (forum_id), - KEY topic_id (topic_id), - KEY poster_ip (poster_ip), - KEY poster_id (poster_id), - KEY post_visibility (post_visibility), - KEY post_username (post_username(255)), - KEY tid_post_time (topic_id, post_time) -); - - -# Table: 'phpbb_privmsgs' -CREATE TABLE phpbb_privmsgs ( - msg_id mediumint(8) UNSIGNED NOT NULL auto_increment, - root_level mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - author_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - icon_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - author_ip varbinary(40) DEFAULT '' NOT NULL, - message_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - enable_bbcode tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_smilies tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_magic_url tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_sig tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - message_subject blob NOT NULL, - message_text mediumblob NOT NULL, - message_edit_reason blob NOT NULL, - message_edit_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - message_attachment tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - bbcode_bitfield varbinary(255) DEFAULT '' NOT NULL, - bbcode_uid varbinary(8) DEFAULT '' NOT NULL, - message_edit_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - message_edit_count smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - to_address blob NOT NULL, - bcc_address blob NOT NULL, - message_reported tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (msg_id), - KEY author_ip (author_ip), - KEY message_time (message_time), - KEY author_id (author_id), - KEY root_level (root_level) -); - - -# Table: 'phpbb_privmsgs_folder' -CREATE TABLE phpbb_privmsgs_folder ( - folder_id mediumint(8) UNSIGNED NOT NULL auto_increment, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - folder_name blob NOT NULL, - pm_count mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (folder_id), - KEY user_id (user_id) -); - - -# Table: 'phpbb_privmsgs_rules' -CREATE TABLE phpbb_privmsgs_rules ( - rule_id mediumint(8) UNSIGNED NOT NULL auto_increment, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_check mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_connection mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_string blob NOT NULL, - rule_user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_action mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_folder_id int(11) DEFAULT '0' NOT NULL, - PRIMARY KEY (rule_id), - KEY user_id (user_id) -); - - -# Table: 'phpbb_privmsgs_to' -CREATE TABLE phpbb_privmsgs_to ( - msg_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - author_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - pm_deleted tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - pm_new tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - pm_unread tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - pm_replied tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - pm_marked tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - pm_forwarded tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - folder_id int(11) DEFAULT '0' NOT NULL, - KEY msg_id (msg_id), - KEY author_id (author_id), - KEY usr_flder_id (user_id, folder_id) -); - - -# Table: 'phpbb_profile_fields' -CREATE TABLE phpbb_profile_fields ( - field_id mediumint(8) UNSIGNED NOT NULL auto_increment, - field_name blob NOT NULL, - field_type tinyint(4) DEFAULT '0' NOT NULL, - field_ident varbinary(20) DEFAULT '' NOT NULL, - field_length varbinary(20) DEFAULT '' NOT NULL, - field_minlen varbinary(255) DEFAULT '' NOT NULL, - field_maxlen varbinary(255) DEFAULT '' NOT NULL, - field_novalue blob NOT NULL, - field_default_value blob NOT NULL, - field_validation varbinary(60) DEFAULT '' NOT NULL, - field_required tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_show_novalue tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_show_on_reg tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_show_on_pm tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_show_on_vt tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_show_profile tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_hide tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_no_view tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_active tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_order mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (field_id), - KEY fld_type (field_type), - KEY fld_ordr (field_order) -); - - -# Table: 'phpbb_profile_fields_data' -CREATE TABLE phpbb_profile_fields_data ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id) -); - - -# Table: 'phpbb_profile_fields_lang' -CREATE TABLE phpbb_profile_fields_lang ( - field_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - lang_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - option_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - field_type tinyint(4) DEFAULT '0' NOT NULL, - lang_value blob NOT NULL, - PRIMARY KEY (field_id, lang_id, option_id) -); - - -# Table: 'phpbb_profile_lang' -CREATE TABLE phpbb_profile_lang ( - field_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - lang_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - lang_name blob NOT NULL, - lang_explain blob NOT NULL, - lang_default_value blob NOT NULL, - PRIMARY KEY (field_id, lang_id) -); - - -# Table: 'phpbb_ranks' -CREATE TABLE phpbb_ranks ( - rank_id mediumint(8) UNSIGNED NOT NULL auto_increment, - rank_title blob NOT NULL, - rank_min mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rank_special tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - rank_image varbinary(255) DEFAULT '' NOT NULL, - PRIMARY KEY (rank_id) -); - - -# Table: 'phpbb_reports' -CREATE TABLE phpbb_reports ( - report_id mediumint(8) UNSIGNED NOT NULL auto_increment, - reason_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - pm_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_notify tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - report_closed tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - report_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - report_text mediumblob NOT NULL, - reported_post_text mediumblob NOT NULL, - reported_post_uid varbinary(8) DEFAULT '' NOT NULL, - reported_post_bitfield varbinary(255) DEFAULT '' NOT NULL, - reported_post_enable_magic_url tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - reported_post_enable_smilies tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - reported_post_enable_bbcode tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - PRIMARY KEY (report_id), - KEY post_id (post_id), - KEY pm_id (pm_id) -); - - -# Table: 'phpbb_reports_reasons' -CREATE TABLE phpbb_reports_reasons ( - reason_id smallint(4) UNSIGNED NOT NULL auto_increment, - reason_title blob NOT NULL, - reason_description mediumblob NOT NULL, - reason_order smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (reason_id) -); - - -# Table: 'phpbb_search_results' -CREATE TABLE phpbb_search_results ( - search_key varbinary(32) DEFAULT '' NOT NULL, - search_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - search_keywords mediumblob NOT NULL, - search_authors mediumblob NOT NULL, - PRIMARY KEY (search_key) -); - - -# Table: 'phpbb_search_wordlist' -CREATE TABLE phpbb_search_wordlist ( - word_id mediumint(8) UNSIGNED NOT NULL auto_increment, - word_text blob NOT NULL, - word_common tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - word_count mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (word_id), - UNIQUE wrd_txt (word_text(255)), - KEY wrd_cnt (word_count) -); - - -# Table: 'phpbb_search_wordmatch' -CREATE TABLE phpbb_search_wordmatch ( - post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - word_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - title_match tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - UNIQUE unq_mtch (word_id, post_id, title_match), - KEY word_id (word_id), - KEY post_id (post_id) -); - - -# Table: 'phpbb_sessions' -CREATE TABLE phpbb_sessions ( - session_id binary(32) DEFAULT '' NOT NULL, - session_user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - session_forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - session_last_visit int(11) UNSIGNED DEFAULT '0' NOT NULL, - session_start int(11) UNSIGNED DEFAULT '0' NOT NULL, - session_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - session_ip varbinary(40) DEFAULT '' NOT NULL, - session_browser varbinary(150) DEFAULT '' NOT NULL, - session_forwarded_for varbinary(255) DEFAULT '' NOT NULL, - session_page blob NOT NULL, - session_viewonline tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - session_autologin tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - session_admin tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (session_id), - KEY session_time (session_time), - KEY session_user_id (session_user_id), - KEY session_fid (session_forum_id) -); - - -# Table: 'phpbb_sessions_keys' -CREATE TABLE phpbb_sessions_keys ( - key_id binary(32) DEFAULT '' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - last_ip varbinary(40) DEFAULT '' NOT NULL, - last_login int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (key_id, user_id), - KEY last_login (last_login) -); - - -# Table: 'phpbb_sitelist' -CREATE TABLE phpbb_sitelist ( - site_id mediumint(8) UNSIGNED NOT NULL auto_increment, - site_ip varbinary(40) DEFAULT '' NOT NULL, - site_hostname varbinary(255) DEFAULT '' NOT NULL, - ip_exclude tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (site_id) -); - - -# Table: 'phpbb_smilies' -CREATE TABLE phpbb_smilies ( - smiley_id mediumint(8) UNSIGNED NOT NULL auto_increment, - code varbinary(150) DEFAULT '' NOT NULL, - emotion varbinary(150) DEFAULT '' NOT NULL, - smiley_url varbinary(50) DEFAULT '' NOT NULL, - smiley_width smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - smiley_height smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - smiley_order mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - display_on_posting tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - PRIMARY KEY (smiley_id), - KEY display_on_post (display_on_posting) -); - - -# Table: 'phpbb_styles' -CREATE TABLE phpbb_styles ( - style_id mediumint(8) UNSIGNED NOT NULL auto_increment, - style_name blob NOT NULL, - style_copyright blob NOT NULL, - style_active tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - style_path varbinary(100) DEFAULT '' NOT NULL, - bbcode_bitfield varbinary(255) DEFAULT 'kNg=' NOT NULL, - style_parent_id int(4) UNSIGNED DEFAULT '0' NOT NULL, - style_parent_tree blob NOT NULL, - PRIMARY KEY (style_id), - UNIQUE style_name (style_name(255)) -); - - -# Table: 'phpbb_teampage' -CREATE TABLE phpbb_teampage ( - teampage_id mediumint(8) UNSIGNED NOT NULL auto_increment, - group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - teampage_name blob NOT NULL, - teampage_position mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - teampage_parent mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (teampage_id) -); - - -# Table: 'phpbb_topics' -CREATE TABLE phpbb_topics ( - topic_id mediumint(8) UNSIGNED NOT NULL auto_increment, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - icon_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_attachment tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - topic_visibility tinyint(3) DEFAULT '0' NOT NULL, - topic_reported tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - topic_title blob NOT NULL, - topic_poster mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - topic_time_limit int(11) UNSIGNED DEFAULT '0' NOT NULL, - topic_views mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_posts_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_posts_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_posts_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_status tinyint(3) DEFAULT '0' NOT NULL, - topic_type tinyint(3) DEFAULT '0' NOT NULL, - topic_first_post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_first_poster_name blob NOT NULL, - topic_first_poster_colour varbinary(6) DEFAULT '' NOT NULL, - topic_last_post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_last_poster_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_last_poster_name blob NOT NULL, - topic_last_poster_colour varbinary(6) DEFAULT '' NOT NULL, - topic_last_post_subject blob NOT NULL, - topic_last_post_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - topic_last_view_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - topic_moved_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_bumped tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - topic_bumper mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - poll_title blob NOT NULL, - poll_start int(11) UNSIGNED DEFAULT '0' NOT NULL, - poll_length int(11) UNSIGNED DEFAULT '0' NOT NULL, - poll_max_options tinyint(4) DEFAULT '1' NOT NULL, - poll_last_vote int(11) UNSIGNED DEFAULT '0' NOT NULL, - poll_vote_change tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - topic_delete_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - topic_delete_reason blob NOT NULL, - topic_delete_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (topic_id), - KEY forum_id (forum_id), - KEY forum_id_type (forum_id, topic_type), - KEY last_post_time (topic_last_post_time), - KEY topic_visibility (topic_visibility), - KEY forum_appr_last (forum_id, topic_visibility, topic_last_post_id), - KEY fid_time_moved (forum_id, topic_last_post_time, topic_moved_id) -); - - -# Table: 'phpbb_topics_track' -CREATE TABLE phpbb_topics_track ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - mark_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id, topic_id), - KEY topic_id (topic_id), - KEY forum_id (forum_id) -); - - -# Table: 'phpbb_topics_posted' -CREATE TABLE phpbb_topics_posted ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_posted tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id, topic_id) -); - - -# Table: 'phpbb_topics_watch' -CREATE TABLE phpbb_topics_watch ( - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - notify_status tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - KEY topic_id (topic_id), - KEY user_id (user_id), - KEY notify_stat (notify_status) -); - - -# Table: 'phpbb_user_notifications' -CREATE TABLE phpbb_user_notifications ( - item_type varbinary(255) DEFAULT '' NOT NULL, - item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - method varbinary(255) DEFAULT '' NOT NULL, - notify tinyint(1) UNSIGNED DEFAULT '1' NOT NULL -); - - -# Table: 'phpbb_user_group' -CREATE TABLE phpbb_user_group ( - group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_leader tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - user_pending tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - KEY group_id (group_id), - KEY user_id (user_id), - KEY group_leader (group_leader) -); - - -# Table: 'phpbb_users' -CREATE TABLE phpbb_users ( - user_id mediumint(8) UNSIGNED NOT NULL auto_increment, - user_type tinyint(2) DEFAULT '0' NOT NULL, - group_id mediumint(8) UNSIGNED DEFAULT '3' NOT NULL, - user_permissions mediumblob NOT NULL, - user_perm_from mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_ip varbinary(40) DEFAULT '' NOT NULL, - user_regdate int(11) UNSIGNED DEFAULT '0' NOT NULL, - username blob NOT NULL, - username_clean blob NOT NULL, - user_password varbinary(120) DEFAULT '' NOT NULL, - user_passchg int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_pass_convert tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - user_email blob NOT NULL, - user_email_hash bigint(20) DEFAULT '0' NOT NULL, - user_birthday varbinary(10) DEFAULT '' NOT NULL, - user_lastvisit int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_lastmark int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_lastpost_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_lastpage blob NOT NULL, - user_last_confirm_key varbinary(10) DEFAULT '' NOT NULL, - user_last_search int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_warnings tinyint(4) DEFAULT '0' NOT NULL, - user_last_warning int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_login_attempts tinyint(4) DEFAULT '0' NOT NULL, - user_inactive_reason tinyint(2) DEFAULT '0' NOT NULL, - user_inactive_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_posts mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_lang varbinary(30) DEFAULT '' NOT NULL, - user_timezone varbinary(100) DEFAULT 'UTC' NOT NULL, - user_dateformat varbinary(90) DEFAULT 'd M Y H:i' NOT NULL, - user_style mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_rank mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_colour varbinary(6) DEFAULT '' NOT NULL, - user_new_privmsg int(4) DEFAULT '0' NOT NULL, - user_unread_privmsg int(4) DEFAULT '0' NOT NULL, - user_last_privmsg int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_message_rules tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - user_full_folder int(11) DEFAULT '-3' NOT NULL, - user_emailtime int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_topic_show_days smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - user_topic_sortby_type varbinary(1) DEFAULT 't' NOT NULL, - user_topic_sortby_dir varbinary(1) DEFAULT 'd' NOT NULL, - user_post_show_days smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - user_post_sortby_type varbinary(1) DEFAULT 't' NOT NULL, - user_post_sortby_dir varbinary(1) DEFAULT 'a' NOT NULL, - user_notify tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - user_notify_pm tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_notify_type tinyint(4) DEFAULT '0' NOT NULL, - user_allow_pm tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_allow_viewonline tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_allow_viewemail tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_allow_massemail tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_options int(11) UNSIGNED DEFAULT '230271' NOT NULL, - user_avatar varbinary(255) DEFAULT '' NOT NULL, - user_avatar_type varbinary(255) DEFAULT '' NOT NULL, - user_avatar_width smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - user_avatar_height smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - user_sig mediumblob NOT NULL, - user_sig_bbcode_uid varbinary(8) DEFAULT '' NOT NULL, - user_sig_bbcode_bitfield varbinary(255) DEFAULT '' NOT NULL, - user_from blob NOT NULL, - user_icq varbinary(15) DEFAULT '' NOT NULL, - user_aim blob NOT NULL, - user_yim blob NOT NULL, - user_msnm blob NOT NULL, - user_jabber blob NOT NULL, - user_website blob NOT NULL, - user_occ blob NOT NULL, - user_interests blob NOT NULL, - user_actkey varbinary(32) DEFAULT '' NOT NULL, - user_newpasswd varbinary(120) DEFAULT '' NOT NULL, - user_form_salt varbinary(96) DEFAULT '' NOT NULL, - user_new tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_reminded tinyint(4) DEFAULT '0' NOT NULL, - user_reminded_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id), - KEY user_birthday (user_birthday), - KEY user_email_hash (user_email_hash), - KEY user_type (user_type), - UNIQUE username_clean (username_clean(255)) -); - - -# Table: 'phpbb_warnings' -CREATE TABLE phpbb_warnings ( - warning_id mediumint(8) UNSIGNED NOT NULL auto_increment, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - log_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - warning_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (warning_id) -); - - -# Table: 'phpbb_words' -CREATE TABLE phpbb_words ( - word_id mediumint(8) UNSIGNED NOT NULL auto_increment, - word blob NOT NULL, - replacement blob NOT NULL, - PRIMARY KEY (word_id) -); - - -# Table: 'phpbb_zebra' -CREATE TABLE phpbb_zebra ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - zebra_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - friend tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - foe tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id, zebra_id) -); - - diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index d3ed1ee15e..28649dc54c 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -3,1078 +3,3 @@ # To change the contents of this file, edit # phpBB/develop/create_schema_files.php and # run it. -# Table: 'phpbb_attachments' -CREATE TABLE phpbb_attachments ( - attach_id mediumint(8) UNSIGNED NOT NULL auto_increment, - post_msg_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - in_message tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - poster_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - is_orphan tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - physical_filename varchar(255) DEFAULT '' NOT NULL, - real_filename varchar(255) DEFAULT '' NOT NULL, - download_count mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - attach_comment text NOT NULL, - extension varchar(100) DEFAULT '' NOT NULL, - mimetype varchar(100) DEFAULT '' NOT NULL, - filesize int(20) UNSIGNED DEFAULT '0' NOT NULL, - filetime int(11) UNSIGNED DEFAULT '0' NOT NULL, - thumbnail tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (attach_id), - KEY filetime (filetime), - KEY post_msg_id (post_msg_id), - KEY topic_id (topic_id), - KEY poster_id (poster_id), - KEY is_orphan (is_orphan) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_acl_groups' -CREATE TABLE phpbb_acl_groups ( - group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_option_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_role_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_setting tinyint(2) DEFAULT '0' NOT NULL, - KEY group_id (group_id), - KEY auth_opt_id (auth_option_id), - KEY auth_role_id (auth_role_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_acl_options' -CREATE TABLE phpbb_acl_options ( - auth_option_id mediumint(8) UNSIGNED NOT NULL auto_increment, - auth_option varchar(50) DEFAULT '' NOT NULL, - is_global tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - is_local tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - founder_only tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (auth_option_id), - UNIQUE auth_option (auth_option) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_acl_roles' -CREATE TABLE phpbb_acl_roles ( - role_id mediumint(8) UNSIGNED NOT NULL auto_increment, - role_name varchar(255) DEFAULT '' NOT NULL, - role_description text NOT NULL, - role_type varchar(10) DEFAULT '' NOT NULL, - role_order smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (role_id), - KEY role_type (role_type), - KEY role_order (role_order) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_acl_roles_data' -CREATE TABLE phpbb_acl_roles_data ( - role_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_option_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_setting tinyint(2) DEFAULT '0' NOT NULL, - PRIMARY KEY (role_id, auth_option_id), - KEY ath_op_id (auth_option_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_acl_users' -CREATE TABLE phpbb_acl_users ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_option_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_role_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - auth_setting tinyint(2) DEFAULT '0' NOT NULL, - KEY user_id (user_id), - KEY auth_option_id (auth_option_id), - KEY auth_role_id (auth_role_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_oauth_tokens' -CREATE TABLE phpbb_oauth_tokens ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - session_id char(32) DEFAULT '' NOT NULL, - provider varchar(255) DEFAULT '' NOT NULL, - oauth_token mediumtext NOT NULL, - KEY user_id (user_id), - KEY provider (provider) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_oauth_accounts' -CREATE TABLE phpbb_oauth_accounts ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - provider varchar(255) DEFAULT '' NOT NULL, - oauth_provider_id text NOT NULL, - PRIMARY KEY (user_id, provider) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_banlist' -CREATE TABLE phpbb_banlist ( - ban_id mediumint(8) UNSIGNED NOT NULL auto_increment, - ban_userid mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - ban_ip varchar(40) DEFAULT '' NOT NULL, - ban_email varchar(100) DEFAULT '' NOT NULL, - ban_start int(11) UNSIGNED DEFAULT '0' NOT NULL, - ban_end int(11) UNSIGNED DEFAULT '0' NOT NULL, - ban_exclude tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - ban_reason varchar(255) DEFAULT '' NOT NULL, - ban_give_reason varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (ban_id), - KEY ban_end (ban_end), - KEY ban_user (ban_userid, ban_exclude), - KEY ban_email (ban_email, ban_exclude), - KEY ban_ip (ban_ip, ban_exclude) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_bbcodes' -CREATE TABLE phpbb_bbcodes ( - bbcode_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - bbcode_tag varchar(16) DEFAULT '' NOT NULL, - bbcode_helpline varchar(255) DEFAULT '' NOT NULL, - display_on_posting tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - bbcode_match text NOT NULL, - bbcode_tpl mediumtext NOT NULL, - first_pass_match mediumtext NOT NULL, - first_pass_replace mediumtext NOT NULL, - second_pass_match mediumtext NOT NULL, - second_pass_replace mediumtext NOT NULL, - PRIMARY KEY (bbcode_id), - KEY display_on_post (display_on_posting) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_bookmarks' -CREATE TABLE phpbb_bookmarks ( - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (topic_id, user_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_bots' -CREATE TABLE phpbb_bots ( - bot_id mediumint(8) UNSIGNED NOT NULL auto_increment, - bot_active tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - bot_name varchar(255) DEFAULT '' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - bot_agent varchar(255) DEFAULT '' NOT NULL, - bot_ip varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (bot_id), - KEY bot_active (bot_active) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_config' -CREATE TABLE phpbb_config ( - config_name varchar(255) DEFAULT '' NOT NULL, - config_value varchar(255) DEFAULT '' NOT NULL, - is_dynamic tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (config_name), - KEY is_dynamic (is_dynamic) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_config_text' -CREATE TABLE phpbb_config_text ( - config_name varchar(255) DEFAULT '' NOT NULL, - config_value mediumtext NOT NULL, - PRIMARY KEY (config_name) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_confirm' -CREATE TABLE phpbb_confirm ( - confirm_id char(32) DEFAULT '' NOT NULL, - session_id char(32) DEFAULT '' NOT NULL, - confirm_type tinyint(3) DEFAULT '0' NOT NULL, - code varchar(8) DEFAULT '' NOT NULL, - seed int(10) UNSIGNED DEFAULT '0' NOT NULL, - attempts mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (session_id, confirm_id), - KEY confirm_type (confirm_type) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_disallow' -CREATE TABLE phpbb_disallow ( - disallow_id mediumint(8) UNSIGNED NOT NULL auto_increment, - disallow_username varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (disallow_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_drafts' -CREATE TABLE phpbb_drafts ( - draft_id mediumint(8) UNSIGNED NOT NULL auto_increment, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - save_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - draft_subject varchar(255) DEFAULT '' NOT NULL, - draft_message mediumtext NOT NULL, - PRIMARY KEY (draft_id), - KEY save_time (save_time) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_ext' -CREATE TABLE phpbb_ext ( - ext_name varchar(255) DEFAULT '' NOT NULL, - ext_active tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - ext_state text NOT NULL, - UNIQUE ext_name (ext_name) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_extensions' -CREATE TABLE phpbb_extensions ( - extension_id mediumint(8) UNSIGNED NOT NULL auto_increment, - group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - extension varchar(100) DEFAULT '' NOT NULL, - PRIMARY KEY (extension_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_extension_groups' -CREATE TABLE phpbb_extension_groups ( - group_id mediumint(8) UNSIGNED NOT NULL auto_increment, - group_name varchar(255) DEFAULT '' NOT NULL, - cat_id tinyint(2) DEFAULT '0' NOT NULL, - allow_group tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - download_mode tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - upload_icon varchar(255) DEFAULT '' NOT NULL, - max_filesize int(20) UNSIGNED DEFAULT '0' NOT NULL, - allowed_forums text NOT NULL, - allow_in_pm tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (group_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_forums' -CREATE TABLE phpbb_forums ( - forum_id mediumint(8) UNSIGNED NOT NULL auto_increment, - parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - left_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - right_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_parents mediumtext NOT NULL, - forum_name varchar(255) DEFAULT '' NOT NULL, - forum_desc text NOT NULL, - forum_desc_bitfield varchar(255) DEFAULT '' NOT NULL, - forum_desc_options int(11) UNSIGNED DEFAULT '7' NOT NULL, - forum_desc_uid varchar(8) DEFAULT '' NOT NULL, - forum_link varchar(255) DEFAULT '' NOT NULL, - forum_password varchar(40) DEFAULT '' NOT NULL, - forum_style mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_image varchar(255) DEFAULT '' NOT NULL, - forum_rules text NOT NULL, - forum_rules_link varchar(255) DEFAULT '' NOT NULL, - forum_rules_bitfield varchar(255) DEFAULT '' NOT NULL, - forum_rules_options int(11) UNSIGNED DEFAULT '7' NOT NULL, - forum_rules_uid varchar(8) DEFAULT '' NOT NULL, - forum_topics_per_page tinyint(4) DEFAULT '0' NOT NULL, - forum_type tinyint(4) DEFAULT '0' NOT NULL, - forum_status tinyint(4) DEFAULT '0' NOT NULL, - forum_posts_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_posts_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_posts_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_topics_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_topics_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_topics_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_last_post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_last_poster_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_last_post_subject varchar(255) DEFAULT '' NOT NULL, - forum_last_post_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - forum_last_poster_name varchar(255) DEFAULT '' NOT NULL, - forum_last_poster_colour varchar(6) DEFAULT '' NOT NULL, - forum_flags tinyint(4) DEFAULT '32' NOT NULL, - forum_options int(20) UNSIGNED DEFAULT '0' NOT NULL, - display_subforum_list tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - display_on_index tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_indexing tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_icons tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_prune tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - prune_next int(11) UNSIGNED DEFAULT '0' NOT NULL, - prune_days mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - prune_viewed mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - prune_freq mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (forum_id), - KEY left_right_id (left_id, right_id), - KEY forum_lastpost_id (forum_last_post_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_forums_access' -CREATE TABLE phpbb_forums_access ( - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - session_id char(32) DEFAULT '' NOT NULL, - PRIMARY KEY (forum_id, user_id, session_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_forums_track' -CREATE TABLE phpbb_forums_track ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - mark_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id, forum_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_forums_watch' -CREATE TABLE phpbb_forums_watch ( - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - notify_status tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - KEY forum_id (forum_id), - KEY user_id (user_id), - KEY notify_stat (notify_status) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_groups' -CREATE TABLE phpbb_groups ( - group_id mediumint(8) UNSIGNED NOT NULL auto_increment, - group_type tinyint(4) DEFAULT '1' NOT NULL, - group_founder_manage tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - group_skip_auth tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - group_name varchar(255) DEFAULT '' NOT NULL, - group_desc text NOT NULL, - group_desc_bitfield varchar(255) DEFAULT '' NOT NULL, - group_desc_options int(11) UNSIGNED DEFAULT '7' NOT NULL, - group_desc_uid varchar(8) DEFAULT '' NOT NULL, - group_display tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - group_avatar varchar(255) DEFAULT '' NOT NULL, - group_avatar_type varchar(255) DEFAULT '' NOT NULL, - group_avatar_width smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - group_avatar_height smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - group_rank mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_colour varchar(6) DEFAULT '' NOT NULL, - group_sig_chars mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_receive_pm tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - group_message_limit mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_max_recipients mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_legend mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (group_id), - KEY group_legend_name (group_legend, group_name) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_icons' -CREATE TABLE phpbb_icons ( - icons_id mediumint(8) UNSIGNED NOT NULL auto_increment, - icons_url varchar(255) DEFAULT '' NOT NULL, - icons_width tinyint(4) DEFAULT '0' NOT NULL, - icons_height tinyint(4) DEFAULT '0' NOT NULL, - icons_order mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - display_on_posting tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - PRIMARY KEY (icons_id), - KEY display_on_posting (display_on_posting) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_lang' -CREATE TABLE phpbb_lang ( - lang_id tinyint(4) NOT NULL auto_increment, - lang_iso varchar(30) DEFAULT '' NOT NULL, - lang_dir varchar(30) DEFAULT '' NOT NULL, - lang_english_name varchar(100) DEFAULT '' NOT NULL, - lang_local_name varchar(255) DEFAULT '' NOT NULL, - lang_author varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (lang_id), - KEY lang_iso (lang_iso) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_log' -CREATE TABLE phpbb_log ( - log_id mediumint(8) UNSIGNED NOT NULL auto_increment, - log_type tinyint(4) DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - reportee_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - log_ip varchar(40) DEFAULT '' NOT NULL, - log_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - log_operation text NOT NULL, - log_data mediumtext NOT NULL, - PRIMARY KEY (log_id), - KEY log_type (log_type), - KEY log_time (log_time), - KEY forum_id (forum_id), - KEY topic_id (topic_id), - KEY reportee_id (reportee_id), - KEY user_id (user_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_login_attempts' -CREATE TABLE phpbb_login_attempts ( - attempt_ip varchar(40) DEFAULT '' NOT NULL, - attempt_browser varchar(150) DEFAULT '' NOT NULL, - attempt_forwarded_for varchar(255) DEFAULT '' NOT NULL, - attempt_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - username varchar(255) DEFAULT '0' NOT NULL, - username_clean varchar(255) DEFAULT '0' NOT NULL, - KEY att_ip (attempt_ip, attempt_time), - KEY att_for (attempt_forwarded_for, attempt_time), - KEY att_time (attempt_time), - KEY user_id (user_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_moderator_cache' -CREATE TABLE phpbb_moderator_cache ( - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - username varchar(255) DEFAULT '' NOT NULL, - group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_name varchar(255) DEFAULT '' NOT NULL, - display_on_index tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - KEY disp_idx (display_on_index), - KEY forum_id (forum_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name varchar(255) DEFAULT '' NOT NULL, - migration_depends_on text NOT NULL, - migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_state text NOT NULL, - migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (migration_name) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_modules' -CREATE TABLE phpbb_modules ( - module_id mediumint(8) UNSIGNED NOT NULL auto_increment, - module_enabled tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - module_display tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - module_basename varchar(255) DEFAULT '' NOT NULL, - module_class varchar(10) DEFAULT '' NOT NULL, - parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - left_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - right_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - module_langname varchar(255) DEFAULT '' NOT NULL, - module_mode varchar(255) DEFAULT '' NOT NULL, - module_auth varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (module_id), - KEY left_right_id (left_id, right_id), - KEY module_enabled (module_enabled), - KEY class_left_id (module_class, left_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_notification_types' -CREATE TABLE phpbb_notification_types ( - notification_type_id smallint(4) UNSIGNED NOT NULL auto_increment, - notification_type_name varchar(255) DEFAULT '' NOT NULL, - notification_type_enabled tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - PRIMARY KEY (notification_type_id), - UNIQUE type (notification_type_name) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_notifications' -CREATE TABLE phpbb_notifications ( - notification_id int(10) UNSIGNED NOT NULL auto_increment, - notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - item_parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - notification_read tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - notification_time int(11) UNSIGNED DEFAULT '1' NOT NULL, - notification_data text NOT NULL, - PRIMARY KEY (notification_id), - KEY item_ident (notification_type_id, item_id), - KEY user (user_id, notification_read) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_poll_options' -CREATE TABLE phpbb_poll_options ( - poll_option_id tinyint(4) DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - poll_option_text text NOT NULL, - poll_option_total mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - KEY poll_opt_id (poll_option_id), - KEY topic_id (topic_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_poll_votes' -CREATE TABLE phpbb_poll_votes ( - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - poll_option_id tinyint(4) DEFAULT '0' NOT NULL, - vote_user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - vote_user_ip varchar(40) DEFAULT '' NOT NULL, - KEY topic_id (topic_id), - KEY vote_user_id (vote_user_id), - KEY vote_user_ip (vote_user_ip) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_posts' -CREATE TABLE phpbb_posts ( - post_id mediumint(8) UNSIGNED NOT NULL auto_increment, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - poster_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - icon_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - poster_ip varchar(40) DEFAULT '' NOT NULL, - post_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - post_visibility tinyint(3) DEFAULT '0' NOT NULL, - post_reported tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - enable_bbcode tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_smilies tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_magic_url tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_sig tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - post_username varchar(255) DEFAULT '' NOT NULL, - post_subject varchar(255) DEFAULT '' NOT NULL COLLATE utf8_unicode_ci, - post_text mediumtext NOT NULL, - post_checksum varchar(32) DEFAULT '' NOT NULL, - post_attachment tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - bbcode_bitfield varchar(255) DEFAULT '' NOT NULL, - bbcode_uid varchar(8) DEFAULT '' NOT NULL, - post_postcount tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - post_edit_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - post_edit_reason varchar(255) DEFAULT '' NOT NULL, - post_edit_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - post_edit_count smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - post_edit_locked tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - post_delete_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - post_delete_reason varchar(255) DEFAULT '' NOT NULL, - post_delete_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (post_id), - KEY forum_id (forum_id), - KEY topic_id (topic_id), - KEY poster_ip (poster_ip), - KEY poster_id (poster_id), - KEY post_visibility (post_visibility), - KEY post_username (post_username), - KEY tid_post_time (topic_id, post_time) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_privmsgs' -CREATE TABLE phpbb_privmsgs ( - msg_id mediumint(8) UNSIGNED NOT NULL auto_increment, - root_level mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - author_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - icon_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - author_ip varchar(40) DEFAULT '' NOT NULL, - message_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - enable_bbcode tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_smilies tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_magic_url tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - enable_sig tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - message_subject varchar(255) DEFAULT '' NOT NULL, - message_text mediumtext NOT NULL, - message_edit_reason varchar(255) DEFAULT '' NOT NULL, - message_edit_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - message_attachment tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - bbcode_bitfield varchar(255) DEFAULT '' NOT NULL, - bbcode_uid varchar(8) DEFAULT '' NOT NULL, - message_edit_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - message_edit_count smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - to_address text NOT NULL, - bcc_address text NOT NULL, - message_reported tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (msg_id), - KEY author_ip (author_ip), - KEY message_time (message_time), - KEY author_id (author_id), - KEY root_level (root_level) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_privmsgs_folder' -CREATE TABLE phpbb_privmsgs_folder ( - folder_id mediumint(8) UNSIGNED NOT NULL auto_increment, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - folder_name varchar(255) DEFAULT '' NOT NULL, - pm_count mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (folder_id), - KEY user_id (user_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_privmsgs_rules' -CREATE TABLE phpbb_privmsgs_rules ( - rule_id mediumint(8) UNSIGNED NOT NULL auto_increment, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_check mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_connection mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_string varchar(255) DEFAULT '' NOT NULL, - rule_user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_action mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_folder_id int(11) DEFAULT '0' NOT NULL, - PRIMARY KEY (rule_id), - KEY user_id (user_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_privmsgs_to' -CREATE TABLE phpbb_privmsgs_to ( - msg_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - author_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - pm_deleted tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - pm_new tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - pm_unread tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - pm_replied tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - pm_marked tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - pm_forwarded tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - folder_id int(11) DEFAULT '0' NOT NULL, - KEY msg_id (msg_id), - KEY author_id (author_id), - KEY usr_flder_id (user_id, folder_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_profile_fields' -CREATE TABLE phpbb_profile_fields ( - field_id mediumint(8) UNSIGNED NOT NULL auto_increment, - field_name varchar(255) DEFAULT '' NOT NULL, - field_type tinyint(4) DEFAULT '0' NOT NULL, - field_ident varchar(20) DEFAULT '' NOT NULL, - field_length varchar(20) DEFAULT '' NOT NULL, - field_minlen varchar(255) DEFAULT '' NOT NULL, - field_maxlen varchar(255) DEFAULT '' NOT NULL, - field_novalue varchar(255) DEFAULT '' NOT NULL, - field_default_value varchar(255) DEFAULT '' NOT NULL, - field_validation varchar(20) DEFAULT '' NOT NULL, - field_required tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_show_novalue tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_show_on_reg tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_show_on_pm tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_show_on_vt tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_show_profile tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_hide tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_no_view tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_active tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - field_order mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (field_id), - KEY fld_type (field_type), - KEY fld_ordr (field_order) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_profile_fields_data' -CREATE TABLE phpbb_profile_fields_data ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_profile_fields_lang' -CREATE TABLE phpbb_profile_fields_lang ( - field_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - lang_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - option_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - field_type tinyint(4) DEFAULT '0' NOT NULL, - lang_value varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (field_id, lang_id, option_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_profile_lang' -CREATE TABLE phpbb_profile_lang ( - field_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - lang_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - lang_name varchar(255) DEFAULT '' NOT NULL, - lang_explain text NOT NULL, - lang_default_value varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (field_id, lang_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_ranks' -CREATE TABLE phpbb_ranks ( - rank_id mediumint(8) UNSIGNED NOT NULL auto_increment, - rank_title varchar(255) DEFAULT '' NOT NULL, - rank_min mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rank_special tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - rank_image varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (rank_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_reports' -CREATE TABLE phpbb_reports ( - report_id mediumint(8) UNSIGNED NOT NULL auto_increment, - reason_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - pm_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_notify tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - report_closed tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - report_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - report_text mediumtext NOT NULL, - reported_post_text mediumtext NOT NULL, - reported_post_uid varchar(8) DEFAULT '' NOT NULL, - reported_post_bitfield varchar(255) DEFAULT '' NOT NULL, - reported_post_enable_magic_url tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - reported_post_enable_smilies tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - reported_post_enable_bbcode tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - PRIMARY KEY (report_id), - KEY post_id (post_id), - KEY pm_id (pm_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_reports_reasons' -CREATE TABLE phpbb_reports_reasons ( - reason_id smallint(4) UNSIGNED NOT NULL auto_increment, - reason_title varchar(255) DEFAULT '' NOT NULL, - reason_description mediumtext NOT NULL, - reason_order smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (reason_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_search_results' -CREATE TABLE phpbb_search_results ( - search_key varchar(32) DEFAULT '' NOT NULL, - search_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - search_keywords mediumtext NOT NULL, - search_authors mediumtext NOT NULL, - PRIMARY KEY (search_key) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_search_wordlist' -CREATE TABLE phpbb_search_wordlist ( - word_id mediumint(8) UNSIGNED NOT NULL auto_increment, - word_text varchar(255) DEFAULT '' NOT NULL, - word_common tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - word_count mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (word_id), - UNIQUE wrd_txt (word_text), - KEY wrd_cnt (word_count) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_search_wordmatch' -CREATE TABLE phpbb_search_wordmatch ( - post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - word_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - title_match tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - UNIQUE unq_mtch (word_id, post_id, title_match), - KEY word_id (word_id), - KEY post_id (post_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_sessions' -CREATE TABLE phpbb_sessions ( - session_id char(32) DEFAULT '' NOT NULL, - session_user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - session_forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - session_last_visit int(11) UNSIGNED DEFAULT '0' NOT NULL, - session_start int(11) UNSIGNED DEFAULT '0' NOT NULL, - session_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - session_ip varchar(40) DEFAULT '' NOT NULL, - session_browser varchar(150) DEFAULT '' NOT NULL, - session_forwarded_for varchar(255) DEFAULT '' NOT NULL, - session_page varchar(255) DEFAULT '' NOT NULL, - session_viewonline tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - session_autologin tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - session_admin tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (session_id), - KEY session_time (session_time), - KEY session_user_id (session_user_id), - KEY session_fid (session_forum_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_sessions_keys' -CREATE TABLE phpbb_sessions_keys ( - key_id char(32) DEFAULT '' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - last_ip varchar(40) DEFAULT '' NOT NULL, - last_login int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (key_id, user_id), - KEY last_login (last_login) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_sitelist' -CREATE TABLE phpbb_sitelist ( - site_id mediumint(8) UNSIGNED NOT NULL auto_increment, - site_ip varchar(40) DEFAULT '' NOT NULL, - site_hostname varchar(255) DEFAULT '' NOT NULL, - ip_exclude tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (site_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_smilies' -CREATE TABLE phpbb_smilies ( - smiley_id mediumint(8) UNSIGNED NOT NULL auto_increment, - code varchar(50) DEFAULT '' NOT NULL, - emotion varchar(50) DEFAULT '' NOT NULL, - smiley_url varchar(50) DEFAULT '' NOT NULL, - smiley_width smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - smiley_height smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - smiley_order mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - display_on_posting tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - PRIMARY KEY (smiley_id), - KEY display_on_post (display_on_posting) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_styles' -CREATE TABLE phpbb_styles ( - style_id mediumint(8) UNSIGNED NOT NULL auto_increment, - style_name varchar(255) DEFAULT '' NOT NULL, - style_copyright varchar(255) DEFAULT '' NOT NULL, - style_active tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - style_path varchar(100) DEFAULT '' NOT NULL, - bbcode_bitfield varchar(255) DEFAULT 'kNg=' NOT NULL, - style_parent_id int(4) UNSIGNED DEFAULT '0' NOT NULL, - style_parent_tree text NOT NULL, - PRIMARY KEY (style_id), - UNIQUE style_name (style_name) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_teampage' -CREATE TABLE phpbb_teampage ( - teampage_id mediumint(8) UNSIGNED NOT NULL auto_increment, - group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - teampage_name varchar(255) DEFAULT '' NOT NULL, - teampage_position mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - teampage_parent mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (teampage_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_topics' -CREATE TABLE phpbb_topics ( - topic_id mediumint(8) UNSIGNED NOT NULL auto_increment, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - icon_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_attachment tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - topic_visibility tinyint(3) DEFAULT '0' NOT NULL, - topic_reported tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - topic_title varchar(255) DEFAULT '' NOT NULL COLLATE utf8_unicode_ci, - topic_poster mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - topic_time_limit int(11) UNSIGNED DEFAULT '0' NOT NULL, - topic_views mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_posts_approved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_posts_unapproved mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_posts_softdeleted mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_status tinyint(3) DEFAULT '0' NOT NULL, - topic_type tinyint(3) DEFAULT '0' NOT NULL, - topic_first_post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_first_poster_name varchar(255) DEFAULT '' NOT NULL, - topic_first_poster_colour varchar(6) DEFAULT '' NOT NULL, - topic_last_post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_last_poster_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_last_poster_name varchar(255) DEFAULT '' NOT NULL, - topic_last_poster_colour varchar(6) DEFAULT '' NOT NULL, - topic_last_post_subject varchar(255) DEFAULT '' NOT NULL, - topic_last_post_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - topic_last_view_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - topic_moved_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_bumped tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - topic_bumper mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - poll_title varchar(255) DEFAULT '' NOT NULL, - poll_start int(11) UNSIGNED DEFAULT '0' NOT NULL, - poll_length int(11) UNSIGNED DEFAULT '0' NOT NULL, - poll_max_options tinyint(4) DEFAULT '1' NOT NULL, - poll_last_vote int(11) UNSIGNED DEFAULT '0' NOT NULL, - poll_vote_change tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - topic_delete_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - topic_delete_reason varchar(255) DEFAULT '' NOT NULL, - topic_delete_user mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (topic_id), - KEY forum_id (forum_id), - KEY forum_id_type (forum_id, topic_type), - KEY last_post_time (topic_last_post_time), - KEY topic_visibility (topic_visibility), - KEY forum_appr_last (forum_id, topic_visibility, topic_last_post_id), - KEY fid_time_moved (forum_id, topic_last_post_time, topic_moved_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_topics_track' -CREATE TABLE phpbb_topics_track ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - mark_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id, topic_id), - KEY topic_id (topic_id), - KEY forum_id (forum_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_topics_posted' -CREATE TABLE phpbb_topics_posted ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - topic_posted tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id, topic_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_topics_watch' -CREATE TABLE phpbb_topics_watch ( - topic_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - notify_status tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - KEY topic_id (topic_id), - KEY user_id (user_id), - KEY notify_stat (notify_status) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_user_notifications' -CREATE TABLE phpbb_user_notifications ( - item_type varchar(255) DEFAULT '' NOT NULL, - item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - method varchar(255) DEFAULT '' NOT NULL, - notify tinyint(1) UNSIGNED DEFAULT '1' NOT NULL -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_user_group' -CREATE TABLE phpbb_user_group ( - group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - group_leader tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - user_pending tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - KEY group_id (group_id), - KEY user_id (user_id), - KEY group_leader (group_leader) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_users' -CREATE TABLE phpbb_users ( - user_id mediumint(8) UNSIGNED NOT NULL auto_increment, - user_type tinyint(2) DEFAULT '0' NOT NULL, - group_id mediumint(8) UNSIGNED DEFAULT '3' NOT NULL, - user_permissions mediumtext NOT NULL, - user_perm_from mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_ip varchar(40) DEFAULT '' NOT NULL, - user_regdate int(11) UNSIGNED DEFAULT '0' NOT NULL, - username varchar(255) DEFAULT '' NOT NULL, - username_clean varchar(255) DEFAULT '' NOT NULL, - user_password varchar(40) DEFAULT '' NOT NULL, - user_passchg int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_pass_convert tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - user_email varchar(100) DEFAULT '' NOT NULL, - user_email_hash bigint(20) DEFAULT '0' NOT NULL, - user_birthday varchar(10) DEFAULT '' NOT NULL, - user_lastvisit int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_lastmark int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_lastpost_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_lastpage varchar(200) DEFAULT '' NOT NULL, - user_last_confirm_key varchar(10) DEFAULT '' NOT NULL, - user_last_search int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_warnings tinyint(4) DEFAULT '0' NOT NULL, - user_last_warning int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_login_attempts tinyint(4) DEFAULT '0' NOT NULL, - user_inactive_reason tinyint(2) DEFAULT '0' NOT NULL, - user_inactive_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_posts mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_lang varchar(30) DEFAULT '' NOT NULL, - user_timezone varchar(100) DEFAULT 'UTC' NOT NULL, - user_dateformat varchar(30) DEFAULT 'd M Y H:i' NOT NULL, - user_style mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_rank mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - user_colour varchar(6) DEFAULT '' NOT NULL, - user_new_privmsg int(4) DEFAULT '0' NOT NULL, - user_unread_privmsg int(4) DEFAULT '0' NOT NULL, - user_last_privmsg int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_message_rules tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - user_full_folder int(11) DEFAULT '-3' NOT NULL, - user_emailtime int(11) UNSIGNED DEFAULT '0' NOT NULL, - user_topic_show_days smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - user_topic_sortby_type varchar(1) DEFAULT 't' NOT NULL, - user_topic_sortby_dir varchar(1) DEFAULT 'd' NOT NULL, - user_post_show_days smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - user_post_sortby_type varchar(1) DEFAULT 't' NOT NULL, - user_post_sortby_dir varchar(1) DEFAULT 'a' NOT NULL, - user_notify tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - user_notify_pm tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_notify_type tinyint(4) DEFAULT '0' NOT NULL, - user_allow_pm tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_allow_viewonline tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_allow_viewemail tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_allow_massemail tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_options int(11) UNSIGNED DEFAULT '230271' NOT NULL, - user_avatar varchar(255) DEFAULT '' NOT NULL, - user_avatar_type varchar(255) DEFAULT '' NOT NULL, - user_avatar_width smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - user_avatar_height smallint(4) UNSIGNED DEFAULT '0' NOT NULL, - user_sig mediumtext NOT NULL, - user_sig_bbcode_uid varchar(8) DEFAULT '' NOT NULL, - user_sig_bbcode_bitfield varchar(255) DEFAULT '' NOT NULL, - user_from varchar(100) DEFAULT '' NOT NULL, - user_icq varchar(15) DEFAULT '' NOT NULL, - user_aim varchar(255) DEFAULT '' NOT NULL, - user_yim varchar(255) DEFAULT '' NOT NULL, - user_msnm varchar(255) DEFAULT '' NOT NULL, - user_jabber varchar(255) DEFAULT '' NOT NULL, - user_website varchar(200) DEFAULT '' NOT NULL, - user_occ text NOT NULL, - user_interests text NOT NULL, - user_actkey varchar(32) DEFAULT '' NOT NULL, - user_newpasswd varchar(40) DEFAULT '' NOT NULL, - user_form_salt varchar(32) DEFAULT '' NOT NULL, - user_new tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_reminded tinyint(4) DEFAULT '0' NOT NULL, - user_reminded_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id), - KEY user_birthday (user_birthday), - KEY user_email_hash (user_email_hash), - KEY user_type (user_type), - UNIQUE username_clean (username_clean) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_warnings' -CREATE TABLE phpbb_warnings ( - warning_id mediumint(8) UNSIGNED NOT NULL auto_increment, - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - post_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - log_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - warning_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (warning_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_words' -CREATE TABLE phpbb_words ( - word_id mediumint(8) UNSIGNED NOT NULL auto_increment, - word varchar(255) DEFAULT '' NOT NULL, - replacement varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (word_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - -# Table: 'phpbb_zebra' -CREATE TABLE phpbb_zebra ( - user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - zebra_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - friend tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - foe tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (user_id, zebra_id) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index f32980e378..61f5d5f961 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -43,1923 +43,3 @@ DISCONNECT; CONNECT phpbb/phpbb_password; */ -/* - Table: 'phpbb_attachments' -*/ -CREATE TABLE phpbb_attachments ( - attach_id number(8) NOT NULL, - post_msg_id number(8) DEFAULT '0' NOT NULL, - topic_id number(8) DEFAULT '0' NOT NULL, - in_message number(1) DEFAULT '0' NOT NULL, - poster_id number(8) DEFAULT '0' NOT NULL, - is_orphan number(1) DEFAULT '1' NOT NULL, - physical_filename varchar2(255) DEFAULT '' , - real_filename varchar2(255) DEFAULT '' , - download_count number(8) DEFAULT '0' NOT NULL, - attach_comment clob DEFAULT '' , - extension varchar2(100) DEFAULT '' , - mimetype varchar2(100) DEFAULT '' , - filesize number(20) DEFAULT '0' NOT NULL, - filetime number(11) DEFAULT '0' NOT NULL, - thumbnail number(1) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_attachments PRIMARY KEY (attach_id) -) -/ - -CREATE INDEX phpbb_attachments_filetime ON phpbb_attachments (filetime) -/ -CREATE INDEX phpbb_attachments_post_msg_id ON phpbb_attachments (post_msg_id) -/ -CREATE INDEX phpbb_attachments_topic_id ON phpbb_attachments (topic_id) -/ -CREATE INDEX phpbb_attachments_poster_id ON phpbb_attachments (poster_id) -/ -CREATE INDEX phpbb_attachments_is_orphan ON phpbb_attachments (is_orphan) -/ - -CREATE SEQUENCE phpbb_attachments_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_attachments -BEFORE INSERT ON phpbb_attachments -FOR EACH ROW WHEN ( - new.attach_id IS NULL OR new.attach_id = 0 -) -BEGIN - SELECT phpbb_attachments_seq.nextval - INTO :new.attach_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_acl_groups' -*/ -CREATE TABLE phpbb_acl_groups ( - group_id number(8) DEFAULT '0' NOT NULL, - forum_id number(8) DEFAULT '0' NOT NULL, - auth_option_id number(8) DEFAULT '0' NOT NULL, - auth_role_id number(8) DEFAULT '0' NOT NULL, - auth_setting number(2) DEFAULT '0' NOT NULL -) -/ - -CREATE INDEX phpbb_acl_groups_group_id ON phpbb_acl_groups (group_id) -/ -CREATE INDEX phpbb_acl_groups_auth_opt_id ON phpbb_acl_groups (auth_option_id) -/ -CREATE INDEX phpbb_acl_groups_auth_role_id ON phpbb_acl_groups (auth_role_id) -/ - -/* - Table: 'phpbb_acl_options' -*/ -CREATE TABLE phpbb_acl_options ( - auth_option_id number(8) NOT NULL, - auth_option varchar2(50) DEFAULT '' , - is_global number(1) DEFAULT '0' NOT NULL, - is_local number(1) DEFAULT '0' NOT NULL, - founder_only number(1) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_acl_options PRIMARY KEY (auth_option_id), - CONSTRAINT u_phpbb_auth_option UNIQUE (auth_option) -) -/ - - -CREATE SEQUENCE phpbb_acl_options_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_acl_options -BEFORE INSERT ON phpbb_acl_options -FOR EACH ROW WHEN ( - new.auth_option_id IS NULL OR new.auth_option_id = 0 -) -BEGIN - SELECT phpbb_acl_options_seq.nextval - INTO :new.auth_option_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_acl_roles' -*/ -CREATE TABLE phpbb_acl_roles ( - role_id number(8) NOT NULL, - role_name varchar2(765) DEFAULT '' , - role_description clob DEFAULT '' , - role_type varchar2(10) DEFAULT '' , - role_order number(4) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_acl_roles PRIMARY KEY (role_id) -) -/ - -CREATE INDEX phpbb_acl_roles_role_type ON phpbb_acl_roles (role_type) -/ -CREATE INDEX phpbb_acl_roles_role_order ON phpbb_acl_roles (role_order) -/ - -CREATE SEQUENCE phpbb_acl_roles_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_acl_roles -BEFORE INSERT ON phpbb_acl_roles -FOR EACH ROW WHEN ( - new.role_id IS NULL OR new.role_id = 0 -) -BEGIN - SELECT phpbb_acl_roles_seq.nextval - INTO :new.role_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_acl_roles_data' -*/ -CREATE TABLE phpbb_acl_roles_data ( - role_id number(8) DEFAULT '0' NOT NULL, - auth_option_id number(8) DEFAULT '0' NOT NULL, - auth_setting number(2) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_acl_roles_data PRIMARY KEY (role_id, auth_option_id) -) -/ - -CREATE INDEX phpbb_acl_roles_data_ath_op_id ON phpbb_acl_roles_data (auth_option_id) -/ - -/* - Table: 'phpbb_acl_users' -*/ -CREATE TABLE phpbb_acl_users ( - user_id number(8) DEFAULT '0' NOT NULL, - forum_id number(8) DEFAULT '0' NOT NULL, - auth_option_id number(8) DEFAULT '0' NOT NULL, - auth_role_id number(8) DEFAULT '0' NOT NULL, - auth_setting number(2) DEFAULT '0' NOT NULL -) -/ - -CREATE INDEX phpbb_acl_users_user_id ON phpbb_acl_users (user_id) -/ -CREATE INDEX phpbb_acl_users_auth_option_id ON phpbb_acl_users (auth_option_id) -/ -CREATE INDEX phpbb_acl_users_auth_role_id ON phpbb_acl_users (auth_role_id) -/ - -/* - Table: 'phpbb_oauth_tokens' -*/ -CREATE TABLE phpbb_oauth_tokens ( - user_id number(8) DEFAULT '0' NOT NULL, - session_id char(32) DEFAULT '' , - provider varchar2(255) DEFAULT '' , - oauth_token clob DEFAULT '' -) -/ - -CREATE INDEX phpbb_oauth_tokens_user_id ON phpbb_oauth_tokens (user_id) -/ -CREATE INDEX phpbb_oauth_tokens_provider ON phpbb_oauth_tokens (provider) -/ - -/* - Table: 'phpbb_oauth_accounts' -*/ -CREATE TABLE phpbb_oauth_accounts ( - user_id number(8) DEFAULT '0' NOT NULL, - provider varchar2(255) DEFAULT '' , - oauth_provider_id clob DEFAULT '' , - CONSTRAINT pk_phpbb_oauth_accounts PRIMARY KEY (user_id, provider) -) -/ - - -/* - Table: 'phpbb_banlist' -*/ -CREATE TABLE phpbb_banlist ( - ban_id number(8) NOT NULL, - ban_userid number(8) DEFAULT '0' NOT NULL, - ban_ip varchar2(40) DEFAULT '' , - ban_email varchar2(300) DEFAULT '' , - ban_start number(11) DEFAULT '0' NOT NULL, - ban_end number(11) DEFAULT '0' NOT NULL, - ban_exclude number(1) DEFAULT '0' NOT NULL, - ban_reason varchar2(765) DEFAULT '' , - ban_give_reason varchar2(765) DEFAULT '' , - CONSTRAINT pk_phpbb_banlist PRIMARY KEY (ban_id) -) -/ - -CREATE INDEX phpbb_banlist_ban_end ON phpbb_banlist (ban_end) -/ -CREATE INDEX phpbb_banlist_ban_user ON phpbb_banlist (ban_userid, ban_exclude) -/ -CREATE INDEX phpbb_banlist_ban_email ON phpbb_banlist (ban_email, ban_exclude) -/ -CREATE INDEX phpbb_banlist_ban_ip ON phpbb_banlist (ban_ip, ban_exclude) -/ - -CREATE SEQUENCE phpbb_banlist_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_banlist -BEFORE INSERT ON phpbb_banlist -FOR EACH ROW WHEN ( - new.ban_id IS NULL OR new.ban_id = 0 -) -BEGIN - SELECT phpbb_banlist_seq.nextval - INTO :new.ban_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_bbcodes' -*/ -CREATE TABLE phpbb_bbcodes ( - bbcode_id number(4) DEFAULT '0' NOT NULL, - bbcode_tag varchar2(16) DEFAULT '' , - bbcode_helpline varchar2(765) DEFAULT '' , - display_on_posting number(1) DEFAULT '0' NOT NULL, - bbcode_match clob DEFAULT '' , - bbcode_tpl clob DEFAULT '' , - first_pass_match clob DEFAULT '' , - first_pass_replace clob DEFAULT '' , - second_pass_match clob DEFAULT '' , - second_pass_replace clob DEFAULT '' , - CONSTRAINT pk_phpbb_bbcodes PRIMARY KEY (bbcode_id) -) -/ - -CREATE INDEX phpbb_bbcodes_display_on_post ON phpbb_bbcodes (display_on_posting) -/ - -/* - Table: 'phpbb_bookmarks' -*/ -CREATE TABLE phpbb_bookmarks ( - topic_id number(8) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_bookmarks PRIMARY KEY (topic_id, user_id) -) -/ - - -/* - Table: 'phpbb_bots' -*/ -CREATE TABLE phpbb_bots ( - bot_id number(8) NOT NULL, - bot_active number(1) DEFAULT '1' NOT NULL, - bot_name varchar2(765) DEFAULT '' , - user_id number(8) DEFAULT '0' NOT NULL, - bot_agent varchar2(255) DEFAULT '' , - bot_ip varchar2(255) DEFAULT '' , - CONSTRAINT pk_phpbb_bots PRIMARY KEY (bot_id) -) -/ - -CREATE INDEX phpbb_bots_bot_active ON phpbb_bots (bot_active) -/ - -CREATE SEQUENCE phpbb_bots_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_bots -BEFORE INSERT ON phpbb_bots -FOR EACH ROW WHEN ( - new.bot_id IS NULL OR new.bot_id = 0 -) -BEGIN - SELECT phpbb_bots_seq.nextval - INTO :new.bot_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_config' -*/ -CREATE TABLE phpbb_config ( - config_name varchar2(255) DEFAULT '' , - config_value varchar2(765) DEFAULT '' , - is_dynamic number(1) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_config PRIMARY KEY (config_name) -) -/ - -CREATE INDEX phpbb_config_is_dynamic ON phpbb_config (is_dynamic) -/ - -/* - Table: 'phpbb_config_text' -*/ -CREATE TABLE phpbb_config_text ( - config_name varchar2(255) DEFAULT '' , - config_value clob DEFAULT '' , - CONSTRAINT pk_phpbb_config_text PRIMARY KEY (config_name) -) -/ - - -/* - Table: 'phpbb_confirm' -*/ -CREATE TABLE phpbb_confirm ( - confirm_id char(32) DEFAULT '' , - session_id char(32) DEFAULT '' , - confirm_type number(3) DEFAULT '0' NOT NULL, - code varchar2(8) DEFAULT '' , - seed number(10) DEFAULT '0' NOT NULL, - attempts number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_confirm PRIMARY KEY (session_id, confirm_id) -) -/ - -CREATE INDEX phpbb_confirm_confirm_type ON phpbb_confirm (confirm_type) -/ - -/* - Table: 'phpbb_disallow' -*/ -CREATE TABLE phpbb_disallow ( - disallow_id number(8) NOT NULL, - disallow_username varchar2(765) DEFAULT '' , - CONSTRAINT pk_phpbb_disallow PRIMARY KEY (disallow_id) -) -/ - - -CREATE SEQUENCE phpbb_disallow_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_disallow -BEFORE INSERT ON phpbb_disallow -FOR EACH ROW WHEN ( - new.disallow_id IS NULL OR new.disallow_id = 0 -) -BEGIN - SELECT phpbb_disallow_seq.nextval - INTO :new.disallow_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_drafts' -*/ -CREATE TABLE phpbb_drafts ( - draft_id number(8) NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - topic_id number(8) DEFAULT '0' NOT NULL, - forum_id number(8) DEFAULT '0' NOT NULL, - save_time number(11) DEFAULT '0' NOT NULL, - draft_subject varchar2(765) DEFAULT '' , - draft_message clob DEFAULT '' , - CONSTRAINT pk_phpbb_drafts PRIMARY KEY (draft_id) -) -/ - -CREATE INDEX phpbb_drafts_save_time ON phpbb_drafts (save_time) -/ - -CREATE SEQUENCE phpbb_drafts_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_drafts -BEFORE INSERT ON phpbb_drafts -FOR EACH ROW WHEN ( - new.draft_id IS NULL OR new.draft_id = 0 -) -BEGIN - SELECT phpbb_drafts_seq.nextval - INTO :new.draft_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_ext' -*/ -CREATE TABLE phpbb_ext ( - ext_name varchar2(255) DEFAULT '' , - ext_active number(1) DEFAULT '0' NOT NULL, - ext_state clob DEFAULT '' , - CONSTRAINT u_phpbb_ext_name UNIQUE (ext_name) -) -/ - - -/* - Table: 'phpbb_extensions' -*/ -CREATE TABLE phpbb_extensions ( - extension_id number(8) NOT NULL, - group_id number(8) DEFAULT '0' NOT NULL, - extension varchar2(100) DEFAULT '' , - CONSTRAINT pk_phpbb_extensions PRIMARY KEY (extension_id) -) -/ - - -CREATE SEQUENCE phpbb_extensions_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_extensions -BEFORE INSERT ON phpbb_extensions -FOR EACH ROW WHEN ( - new.extension_id IS NULL OR new.extension_id = 0 -) -BEGIN - SELECT phpbb_extensions_seq.nextval - INTO :new.extension_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_extension_groups' -*/ -CREATE TABLE phpbb_extension_groups ( - group_id number(8) NOT NULL, - group_name varchar2(765) DEFAULT '' , - cat_id number(2) DEFAULT '0' NOT NULL, - allow_group number(1) DEFAULT '0' NOT NULL, - download_mode number(1) DEFAULT '1' NOT NULL, - upload_icon varchar2(255) DEFAULT '' , - max_filesize number(20) DEFAULT '0' NOT NULL, - allowed_forums clob DEFAULT '' , - allow_in_pm number(1) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_extension_groups PRIMARY KEY (group_id) -) -/ - - -CREATE SEQUENCE phpbb_extension_groups_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_extension_groups -BEFORE INSERT ON phpbb_extension_groups -FOR EACH ROW WHEN ( - new.group_id IS NULL OR new.group_id = 0 -) -BEGIN - SELECT phpbb_extension_groups_seq.nextval - INTO :new.group_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_forums' -*/ -CREATE TABLE phpbb_forums ( - forum_id number(8) NOT NULL, - parent_id number(8) DEFAULT '0' NOT NULL, - left_id number(8) DEFAULT '0' NOT NULL, - right_id number(8) DEFAULT '0' NOT NULL, - forum_parents clob DEFAULT '' , - forum_name varchar2(765) DEFAULT '' , - forum_desc clob DEFAULT '' , - forum_desc_bitfield varchar2(255) DEFAULT '' , - forum_desc_options number(11) DEFAULT '7' NOT NULL, - forum_desc_uid varchar2(8) DEFAULT '' , - forum_link varchar2(765) DEFAULT '' , - forum_password varchar2(120) DEFAULT '' , - forum_style number(8) DEFAULT '0' NOT NULL, - forum_image varchar2(255) DEFAULT '' , - forum_rules clob DEFAULT '' , - forum_rules_link varchar2(765) DEFAULT '' , - forum_rules_bitfield varchar2(255) DEFAULT '' , - forum_rules_options number(11) DEFAULT '7' NOT NULL, - forum_rules_uid varchar2(8) DEFAULT '' , - forum_topics_per_page number(4) DEFAULT '0' NOT NULL, - forum_type number(4) DEFAULT '0' NOT NULL, - forum_status number(4) DEFAULT '0' NOT NULL, - forum_posts_approved number(8) DEFAULT '0' NOT NULL, - forum_posts_unapproved number(8) DEFAULT '0' NOT NULL, - forum_posts_softdeleted number(8) DEFAULT '0' NOT NULL, - forum_topics_approved number(8) DEFAULT '0' NOT NULL, - forum_topics_unapproved number(8) DEFAULT '0' NOT NULL, - forum_topics_softdeleted number(8) DEFAULT '0' NOT NULL, - forum_last_post_id number(8) DEFAULT '0' NOT NULL, - forum_last_poster_id number(8) DEFAULT '0' NOT NULL, - forum_last_post_subject varchar2(765) DEFAULT '' , - forum_last_post_time number(11) DEFAULT '0' NOT NULL, - forum_last_poster_name varchar2(765) DEFAULT '' , - forum_last_poster_colour varchar2(6) DEFAULT '' , - forum_flags number(4) DEFAULT '32' NOT NULL, - forum_options number(20) DEFAULT '0' NOT NULL, - display_subforum_list number(1) DEFAULT '1' NOT NULL, - display_on_index number(1) DEFAULT '1' NOT NULL, - enable_indexing number(1) DEFAULT '1' NOT NULL, - enable_icons number(1) DEFAULT '1' NOT NULL, - enable_prune number(1) DEFAULT '0' NOT NULL, - prune_next number(11) DEFAULT '0' NOT NULL, - prune_days number(8) DEFAULT '0' NOT NULL, - prune_viewed number(8) DEFAULT '0' NOT NULL, - prune_freq number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_forums PRIMARY KEY (forum_id) -) -/ - -CREATE INDEX phpbb_forums_left_right_id ON phpbb_forums (left_id, right_id) -/ -CREATE INDEX phpbb_forums_forum_lastpost_id ON phpbb_forums (forum_last_post_id) -/ - -CREATE SEQUENCE phpbb_forums_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_forums -BEFORE INSERT ON phpbb_forums -FOR EACH ROW WHEN ( - new.forum_id IS NULL OR new.forum_id = 0 -) -BEGIN - SELECT phpbb_forums_seq.nextval - INTO :new.forum_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_forums_access' -*/ -CREATE TABLE phpbb_forums_access ( - forum_id number(8) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - session_id char(32) DEFAULT '' , - CONSTRAINT pk_phpbb_forums_access PRIMARY KEY (forum_id, user_id, session_id) -) -/ - - -/* - Table: 'phpbb_forums_track' -*/ -CREATE TABLE phpbb_forums_track ( - user_id number(8) DEFAULT '0' NOT NULL, - forum_id number(8) DEFAULT '0' NOT NULL, - mark_time number(11) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_forums_track PRIMARY KEY (user_id, forum_id) -) -/ - - -/* - Table: 'phpbb_forums_watch' -*/ -CREATE TABLE phpbb_forums_watch ( - forum_id number(8) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - notify_status number(1) DEFAULT '0' NOT NULL -) -/ - -CREATE INDEX phpbb_forums_watch_forum_id ON phpbb_forums_watch (forum_id) -/ -CREATE INDEX phpbb_forums_watch_user_id ON phpbb_forums_watch (user_id) -/ -CREATE INDEX phpbb_forums_watch_notify_stat ON phpbb_forums_watch (notify_status) -/ - -/* - Table: 'phpbb_groups' -*/ -CREATE TABLE phpbb_groups ( - group_id number(8) NOT NULL, - group_type number(4) DEFAULT '1' NOT NULL, - group_founder_manage number(1) DEFAULT '0' NOT NULL, - group_skip_auth number(1) DEFAULT '0' NOT NULL, - group_name varchar2(255) DEFAULT '' , - group_desc clob DEFAULT '' , - group_desc_bitfield varchar2(255) DEFAULT '' , - group_desc_options number(11) DEFAULT '7' NOT NULL, - group_desc_uid varchar2(8) DEFAULT '' , - group_display number(1) DEFAULT '0' NOT NULL, - group_avatar varchar2(255) DEFAULT '' , - group_avatar_type varchar2(255) DEFAULT '' , - group_avatar_width number(4) DEFAULT '0' NOT NULL, - group_avatar_height number(4) DEFAULT '0' NOT NULL, - group_rank number(8) DEFAULT '0' NOT NULL, - group_colour varchar2(6) DEFAULT '' , - group_sig_chars number(8) DEFAULT '0' NOT NULL, - group_receive_pm number(1) DEFAULT '0' NOT NULL, - group_message_limit number(8) DEFAULT '0' NOT NULL, - group_max_recipients number(8) DEFAULT '0' NOT NULL, - group_legend number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_groups PRIMARY KEY (group_id) -) -/ - -CREATE INDEX phpbb_groups_group_legend_name ON phpbb_groups (group_legend, group_name) -/ - -CREATE SEQUENCE phpbb_groups_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_groups -BEFORE INSERT ON phpbb_groups -FOR EACH ROW WHEN ( - new.group_id IS NULL OR new.group_id = 0 -) -BEGIN - SELECT phpbb_groups_seq.nextval - INTO :new.group_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_icons' -*/ -CREATE TABLE phpbb_icons ( - icons_id number(8) NOT NULL, - icons_url varchar2(255) DEFAULT '' , - icons_width number(4) DEFAULT '0' NOT NULL, - icons_height number(4) DEFAULT '0' NOT NULL, - icons_order number(8) DEFAULT '0' NOT NULL, - display_on_posting number(1) DEFAULT '1' NOT NULL, - CONSTRAINT pk_phpbb_icons PRIMARY KEY (icons_id) -) -/ - -CREATE INDEX phpbb_icons_display_on_posting ON phpbb_icons (display_on_posting) -/ - -CREATE SEQUENCE phpbb_icons_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_icons -BEFORE INSERT ON phpbb_icons -FOR EACH ROW WHEN ( - new.icons_id IS NULL OR new.icons_id = 0 -) -BEGIN - SELECT phpbb_icons_seq.nextval - INTO :new.icons_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_lang' -*/ -CREATE TABLE phpbb_lang ( - lang_id number(4) NOT NULL, - lang_iso varchar2(30) DEFAULT '' , - lang_dir varchar2(30) DEFAULT '' , - lang_english_name varchar2(300) DEFAULT '' , - lang_local_name varchar2(765) DEFAULT '' , - lang_author varchar2(765) DEFAULT '' , - CONSTRAINT pk_phpbb_lang PRIMARY KEY (lang_id) -) -/ - -CREATE INDEX phpbb_lang_lang_iso ON phpbb_lang (lang_iso) -/ - -CREATE SEQUENCE phpbb_lang_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_lang -BEFORE INSERT ON phpbb_lang -FOR EACH ROW WHEN ( - new.lang_id IS NULL OR new.lang_id = 0 -) -BEGIN - SELECT phpbb_lang_seq.nextval - INTO :new.lang_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_log' -*/ -CREATE TABLE phpbb_log ( - log_id number(8) NOT NULL, - log_type number(4) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - forum_id number(8) DEFAULT '0' NOT NULL, - topic_id number(8) DEFAULT '0' NOT NULL, - reportee_id number(8) DEFAULT '0' NOT NULL, - log_ip varchar2(40) DEFAULT '' , - log_time number(11) DEFAULT '0' NOT NULL, - log_operation clob DEFAULT '' , - log_data clob DEFAULT '' , - CONSTRAINT pk_phpbb_log PRIMARY KEY (log_id) -) -/ - -CREATE INDEX phpbb_log_log_type ON phpbb_log (log_type) -/ -CREATE INDEX phpbb_log_log_time ON phpbb_log (log_time) -/ -CREATE INDEX phpbb_log_forum_id ON phpbb_log (forum_id) -/ -CREATE INDEX phpbb_log_topic_id ON phpbb_log (topic_id) -/ -CREATE INDEX phpbb_log_reportee_id ON phpbb_log (reportee_id) -/ -CREATE INDEX phpbb_log_user_id ON phpbb_log (user_id) -/ - -CREATE SEQUENCE phpbb_log_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_log -BEFORE INSERT ON phpbb_log -FOR EACH ROW WHEN ( - new.log_id IS NULL OR new.log_id = 0 -) -BEGIN - SELECT phpbb_log_seq.nextval - INTO :new.log_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_login_attempts' -*/ -CREATE TABLE phpbb_login_attempts ( - attempt_ip varchar2(40) DEFAULT '' , - attempt_browser varchar2(150) DEFAULT '' , - attempt_forwarded_for varchar2(255) DEFAULT '' , - attempt_time number(11) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - username varchar2(765) DEFAULT '0' NOT NULL, - username_clean varchar2(255) DEFAULT '0' NOT NULL -) -/ - -CREATE INDEX phpbb_login_attempts_att_ip ON phpbb_login_attempts (attempt_ip, attempt_time) -/ -CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwarded_for, attempt_time) -/ -CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time) -/ -CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id) -/ - -/* - Table: 'phpbb_moderator_cache' -*/ -CREATE TABLE phpbb_moderator_cache ( - forum_id number(8) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - username varchar2(765) DEFAULT '' , - group_id number(8) DEFAULT '0' NOT NULL, - group_name varchar2(765) DEFAULT '' , - display_on_index number(1) DEFAULT '1' NOT NULL -) -/ - -CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache (display_on_index) -/ -CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id) -/ - -/* - Table: 'phpbb_migrations' -*/ -CREATE TABLE phpbb_migrations ( - migration_name varchar2(255) DEFAULT '' , - migration_depends_on clob DEFAULT '' , - migration_schema_done number(1) DEFAULT '0' NOT NULL, - migration_data_done number(1) DEFAULT '0' NOT NULL, - migration_data_state clob DEFAULT '' , - migration_start_time number(11) DEFAULT '0' NOT NULL, - migration_end_time number(11) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_migrations PRIMARY KEY (migration_name) -) -/ - - -/* - Table: 'phpbb_modules' -*/ -CREATE TABLE phpbb_modules ( - module_id number(8) NOT NULL, - module_enabled number(1) DEFAULT '1' NOT NULL, - module_display number(1) DEFAULT '1' NOT NULL, - module_basename varchar2(255) DEFAULT '' , - module_class varchar2(10) DEFAULT '' , - parent_id number(8) DEFAULT '0' NOT NULL, - left_id number(8) DEFAULT '0' NOT NULL, - right_id number(8) DEFAULT '0' NOT NULL, - module_langname varchar2(255) DEFAULT '' , - module_mode varchar2(255) DEFAULT '' , - module_auth varchar2(255) DEFAULT '' , - CONSTRAINT pk_phpbb_modules PRIMARY KEY (module_id) -) -/ - -CREATE INDEX phpbb_modules_left_right_id ON phpbb_modules (left_id, right_id) -/ -CREATE INDEX phpbb_modules_module_enabled ON phpbb_modules (module_enabled) -/ -CREATE INDEX phpbb_modules_class_left_id ON phpbb_modules (module_class, left_id) -/ - -CREATE SEQUENCE phpbb_modules_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_modules -BEFORE INSERT ON phpbb_modules -FOR EACH ROW WHEN ( - new.module_id IS NULL OR new.module_id = 0 -) -BEGIN - SELECT phpbb_modules_seq.nextval - INTO :new.module_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_notification_types' -*/ -CREATE TABLE phpbb_notification_types ( - notification_type_id number(4) NOT NULL, - notification_type_name varchar2(255) DEFAULT '' , - notification_type_enabled number(1) DEFAULT '1' NOT NULL, - CONSTRAINT pk_phpbb_notification_types PRIMARY KEY (notification_type_id), - CONSTRAINT u_phpbb_type UNIQUE (notification_type_name) -) -/ - - -CREATE SEQUENCE phpbb_notification_types_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_notification_types -BEFORE INSERT ON phpbb_notification_types -FOR EACH ROW WHEN ( - new.notification_type_id IS NULL OR new.notification_type_id = 0 -) -BEGIN - SELECT phpbb_notification_types_seq.nextval - INTO :new.notification_type_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_notifications' -*/ -CREATE TABLE phpbb_notifications ( - notification_id number(10) NOT NULL, - notification_type_id number(4) DEFAULT '0' NOT NULL, - item_id number(8) DEFAULT '0' NOT NULL, - item_parent_id number(8) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - notification_read number(1) DEFAULT '0' NOT NULL, - notification_time number(11) DEFAULT '1' NOT NULL, - notification_data clob DEFAULT '' , - CONSTRAINT pk_phpbb_notifications PRIMARY KEY (notification_id) -) -/ - -CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (notification_type_id, item_id) -/ -CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read) -/ - -CREATE SEQUENCE phpbb_notifications_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_notifications -BEFORE INSERT ON phpbb_notifications -FOR EACH ROW WHEN ( - new.notification_id IS NULL OR new.notification_id = 0 -) -BEGIN - SELECT phpbb_notifications_seq.nextval - INTO :new.notification_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_poll_options' -*/ -CREATE TABLE phpbb_poll_options ( - poll_option_id number(4) DEFAULT '0' NOT NULL, - topic_id number(8) DEFAULT '0' NOT NULL, - poll_option_text clob DEFAULT '' , - poll_option_total number(8) DEFAULT '0' NOT NULL -) -/ - -CREATE INDEX phpbb_poll_options_poll_opt_id ON phpbb_poll_options (poll_option_id) -/ -CREATE INDEX phpbb_poll_options_topic_id ON phpbb_poll_options (topic_id) -/ - -/* - Table: 'phpbb_poll_votes' -*/ -CREATE TABLE phpbb_poll_votes ( - topic_id number(8) DEFAULT '0' NOT NULL, - poll_option_id number(4) DEFAULT '0' NOT NULL, - vote_user_id number(8) DEFAULT '0' NOT NULL, - vote_user_ip varchar2(40) DEFAULT '' -) -/ - -CREATE INDEX phpbb_poll_votes_topic_id ON phpbb_poll_votes (topic_id) -/ -CREATE INDEX phpbb_poll_votes_vote_user_id ON phpbb_poll_votes (vote_user_id) -/ -CREATE INDEX phpbb_poll_votes_vote_user_ip ON phpbb_poll_votes (vote_user_ip) -/ - -/* - Table: 'phpbb_posts' -*/ -CREATE TABLE phpbb_posts ( - post_id number(8) NOT NULL, - topic_id number(8) DEFAULT '0' NOT NULL, - forum_id number(8) DEFAULT '0' NOT NULL, - poster_id number(8) DEFAULT '0' NOT NULL, - icon_id number(8) DEFAULT '0' NOT NULL, - poster_ip varchar2(40) DEFAULT '' , - post_time number(11) DEFAULT '0' NOT NULL, - post_visibility number(3) DEFAULT '0' NOT NULL, - post_reported number(1) DEFAULT '0' NOT NULL, - enable_bbcode number(1) DEFAULT '1' NOT NULL, - enable_smilies number(1) DEFAULT '1' NOT NULL, - enable_magic_url number(1) DEFAULT '1' NOT NULL, - enable_sig number(1) DEFAULT '1' NOT NULL, - post_username varchar2(765) DEFAULT '' , - post_subject varchar2(765) DEFAULT '' , - post_text clob DEFAULT '' , - post_checksum varchar2(32) DEFAULT '' , - post_attachment number(1) DEFAULT '0' NOT NULL, - bbcode_bitfield varchar2(255) DEFAULT '' , - bbcode_uid varchar2(8) DEFAULT '' , - post_postcount number(1) DEFAULT '1' NOT NULL, - post_edit_time number(11) DEFAULT '0' NOT NULL, - post_edit_reason varchar2(765) DEFAULT '' , - post_edit_user number(8) DEFAULT '0' NOT NULL, - post_edit_count number(4) DEFAULT '0' NOT NULL, - post_edit_locked number(1) DEFAULT '0' NOT NULL, - post_delete_time number(11) DEFAULT '0' NOT NULL, - post_delete_reason varchar2(765) DEFAULT '' , - post_delete_user number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_posts PRIMARY KEY (post_id) -) -/ - -CREATE INDEX phpbb_posts_forum_id ON phpbb_posts (forum_id) -/ -CREATE INDEX phpbb_posts_topic_id ON phpbb_posts (topic_id) -/ -CREATE INDEX phpbb_posts_poster_ip ON phpbb_posts (poster_ip) -/ -CREATE INDEX phpbb_posts_poster_id ON phpbb_posts (poster_id) -/ -CREATE INDEX phpbb_posts_post_visibility ON phpbb_posts (post_visibility) -/ -CREATE INDEX phpbb_posts_post_username ON phpbb_posts (post_username) -/ -CREATE INDEX phpbb_posts_tid_post_time ON phpbb_posts (topic_id, post_time) -/ - -CREATE SEQUENCE phpbb_posts_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_posts -BEFORE INSERT ON phpbb_posts -FOR EACH ROW WHEN ( - new.post_id IS NULL OR new.post_id = 0 -) -BEGIN - SELECT phpbb_posts_seq.nextval - INTO :new.post_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_privmsgs' -*/ -CREATE TABLE phpbb_privmsgs ( - msg_id number(8) NOT NULL, - root_level number(8) DEFAULT '0' NOT NULL, - author_id number(8) DEFAULT '0' NOT NULL, - icon_id number(8) DEFAULT '0' NOT NULL, - author_ip varchar2(40) DEFAULT '' , - message_time number(11) DEFAULT '0' NOT NULL, - enable_bbcode number(1) DEFAULT '1' NOT NULL, - enable_smilies number(1) DEFAULT '1' NOT NULL, - enable_magic_url number(1) DEFAULT '1' NOT NULL, - enable_sig number(1) DEFAULT '1' NOT NULL, - message_subject varchar2(765) DEFAULT '' , - message_text clob DEFAULT '' , - message_edit_reason varchar2(765) DEFAULT '' , - message_edit_user number(8) DEFAULT '0' NOT NULL, - message_attachment number(1) DEFAULT '0' NOT NULL, - bbcode_bitfield varchar2(255) DEFAULT '' , - bbcode_uid varchar2(8) DEFAULT '' , - message_edit_time number(11) DEFAULT '0' NOT NULL, - message_edit_count number(4) DEFAULT '0' NOT NULL, - to_address clob DEFAULT '' , - bcc_address clob DEFAULT '' , - message_reported number(1) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_privmsgs PRIMARY KEY (msg_id) -) -/ - -CREATE INDEX phpbb_privmsgs_author_ip ON phpbb_privmsgs (author_ip) -/ -CREATE INDEX phpbb_privmsgs_message_time ON phpbb_privmsgs (message_time) -/ -CREATE INDEX phpbb_privmsgs_author_id ON phpbb_privmsgs (author_id) -/ -CREATE INDEX phpbb_privmsgs_root_level ON phpbb_privmsgs (root_level) -/ - -CREATE SEQUENCE phpbb_privmsgs_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_privmsgs -BEFORE INSERT ON phpbb_privmsgs -FOR EACH ROW WHEN ( - new.msg_id IS NULL OR new.msg_id = 0 -) -BEGIN - SELECT phpbb_privmsgs_seq.nextval - INTO :new.msg_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_privmsgs_folder' -*/ -CREATE TABLE phpbb_privmsgs_folder ( - folder_id number(8) NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - folder_name varchar2(765) DEFAULT '' , - pm_count number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_privmsgs_folder PRIMARY KEY (folder_id) -) -/ - -CREATE INDEX phpbb_privmsgs_folder_user_id ON phpbb_privmsgs_folder (user_id) -/ - -CREATE SEQUENCE phpbb_privmsgs_folder_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_privmsgs_folder -BEFORE INSERT ON phpbb_privmsgs_folder -FOR EACH ROW WHEN ( - new.folder_id IS NULL OR new.folder_id = 0 -) -BEGIN - SELECT phpbb_privmsgs_folder_seq.nextval - INTO :new.folder_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_privmsgs_rules' -*/ -CREATE TABLE phpbb_privmsgs_rules ( - rule_id number(8) NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - rule_check number(8) DEFAULT '0' NOT NULL, - rule_connection number(8) DEFAULT '0' NOT NULL, - rule_string varchar2(765) DEFAULT '' , - rule_user_id number(8) DEFAULT '0' NOT NULL, - rule_group_id number(8) DEFAULT '0' NOT NULL, - rule_action number(8) DEFAULT '0' NOT NULL, - rule_folder_id number(11) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_privmsgs_rules PRIMARY KEY (rule_id) -) -/ - -CREATE INDEX phpbb_privmsgs_rules_user_id ON phpbb_privmsgs_rules (user_id) -/ - -CREATE SEQUENCE phpbb_privmsgs_rules_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_privmsgs_rules -BEFORE INSERT ON phpbb_privmsgs_rules -FOR EACH ROW WHEN ( - new.rule_id IS NULL OR new.rule_id = 0 -) -BEGIN - SELECT phpbb_privmsgs_rules_seq.nextval - INTO :new.rule_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_privmsgs_to' -*/ -CREATE TABLE phpbb_privmsgs_to ( - msg_id number(8) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - author_id number(8) DEFAULT '0' NOT NULL, - pm_deleted number(1) DEFAULT '0' NOT NULL, - pm_new number(1) DEFAULT '1' NOT NULL, - pm_unread number(1) DEFAULT '1' NOT NULL, - pm_replied number(1) DEFAULT '0' NOT NULL, - pm_marked number(1) DEFAULT '0' NOT NULL, - pm_forwarded number(1) DEFAULT '0' NOT NULL, - folder_id number(11) DEFAULT '0' NOT NULL -) -/ - -CREATE INDEX phpbb_privmsgs_to_msg_id ON phpbb_privmsgs_to (msg_id) -/ -CREATE INDEX phpbb_privmsgs_to_author_id ON phpbb_privmsgs_to (author_id) -/ -CREATE INDEX phpbb_privmsgs_to_usr_flder_id ON phpbb_privmsgs_to (user_id, folder_id) -/ - -/* - Table: 'phpbb_profile_fields' -*/ -CREATE TABLE phpbb_profile_fields ( - field_id number(8) NOT NULL, - field_name varchar2(765) DEFAULT '' , - field_type number(4) DEFAULT '0' NOT NULL, - field_ident varchar2(20) DEFAULT '' , - field_length varchar2(20) DEFAULT '' , - field_minlen varchar2(255) DEFAULT '' , - field_maxlen varchar2(255) DEFAULT '' , - field_novalue varchar2(765) DEFAULT '' , - field_default_value varchar2(765) DEFAULT '' , - field_validation varchar2(60) DEFAULT '' , - field_required number(1) DEFAULT '0' NOT NULL, - field_show_novalue number(1) DEFAULT '0' NOT NULL, - field_show_on_reg number(1) DEFAULT '0' NOT NULL, - field_show_on_pm number(1) DEFAULT '0' NOT NULL, - field_show_on_vt number(1) DEFAULT '0' NOT NULL, - field_show_profile number(1) DEFAULT '0' NOT NULL, - field_hide number(1) DEFAULT '0' NOT NULL, - field_no_view number(1) DEFAULT '0' NOT NULL, - field_active number(1) DEFAULT '0' NOT NULL, - field_order number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_profile_fields PRIMARY KEY (field_id) -) -/ - -CREATE INDEX phpbb_profile_fields_fld_type ON phpbb_profile_fields (field_type) -/ -CREATE INDEX phpbb_profile_fields_fld_ordr ON phpbb_profile_fields (field_order) -/ - -CREATE SEQUENCE phpbb_profile_fields_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_profile_fields -BEFORE INSERT ON phpbb_profile_fields -FOR EACH ROW WHEN ( - new.field_id IS NULL OR new.field_id = 0 -) -BEGIN - SELECT phpbb_profile_fields_seq.nextval - INTO :new.field_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_profile_fields_data' -*/ -CREATE TABLE phpbb_profile_fields_data ( - user_id number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_profile_fields_data PRIMARY KEY (user_id) -) -/ - - -/* - Table: 'phpbb_profile_fields_lang' -*/ -CREATE TABLE phpbb_profile_fields_lang ( - field_id number(8) DEFAULT '0' NOT NULL, - lang_id number(8) DEFAULT '0' NOT NULL, - option_id number(8) DEFAULT '0' NOT NULL, - field_type number(4) DEFAULT '0' NOT NULL, - lang_value varchar2(765) DEFAULT '' , - CONSTRAINT pk_phpbb_profile_fields_lang PRIMARY KEY (field_id, lang_id, option_id) -) -/ - - -/* - Table: 'phpbb_profile_lang' -*/ -CREATE TABLE phpbb_profile_lang ( - field_id number(8) DEFAULT '0' NOT NULL, - lang_id number(8) DEFAULT '0' NOT NULL, - lang_name varchar2(765) DEFAULT '' , - lang_explain clob DEFAULT '' , - lang_default_value varchar2(765) DEFAULT '' , - CONSTRAINT pk_phpbb_profile_lang PRIMARY KEY (field_id, lang_id) -) -/ - - -/* - Table: 'phpbb_ranks' -*/ -CREATE TABLE phpbb_ranks ( - rank_id number(8) NOT NULL, - rank_title varchar2(765) DEFAULT '' , - rank_min number(8) DEFAULT '0' NOT NULL, - rank_special number(1) DEFAULT '0' NOT NULL, - rank_image varchar2(255) DEFAULT '' , - CONSTRAINT pk_phpbb_ranks PRIMARY KEY (rank_id) -) -/ - - -CREATE SEQUENCE phpbb_ranks_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_ranks -BEFORE INSERT ON phpbb_ranks -FOR EACH ROW WHEN ( - new.rank_id IS NULL OR new.rank_id = 0 -) -BEGIN - SELECT phpbb_ranks_seq.nextval - INTO :new.rank_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_reports' -*/ -CREATE TABLE phpbb_reports ( - report_id number(8) NOT NULL, - reason_id number(4) DEFAULT '0' NOT NULL, - post_id number(8) DEFAULT '0' NOT NULL, - pm_id number(8) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - user_notify number(1) DEFAULT '0' NOT NULL, - report_closed number(1) DEFAULT '0' NOT NULL, - report_time number(11) DEFAULT '0' NOT NULL, - report_text clob DEFAULT '' , - reported_post_text clob DEFAULT '' , - reported_post_uid varchar2(8) DEFAULT '' , - reported_post_bitfield varchar2(255) DEFAULT '' , - reported_post_enable_magic_url number(1) DEFAULT '1' NOT NULL, - reported_post_enable_smilies number(1) DEFAULT '1' NOT NULL, - reported_post_enable_bbcode number(1) DEFAULT '1' NOT NULL, - CONSTRAINT pk_phpbb_reports PRIMARY KEY (report_id) -) -/ - -CREATE INDEX phpbb_reports_post_id ON phpbb_reports (post_id) -/ -CREATE INDEX phpbb_reports_pm_id ON phpbb_reports (pm_id) -/ - -CREATE SEQUENCE phpbb_reports_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_reports -BEFORE INSERT ON phpbb_reports -FOR EACH ROW WHEN ( - new.report_id IS NULL OR new.report_id = 0 -) -BEGIN - SELECT phpbb_reports_seq.nextval - INTO :new.report_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_reports_reasons' -*/ -CREATE TABLE phpbb_reports_reasons ( - reason_id number(4) NOT NULL, - reason_title varchar2(765) DEFAULT '' , - reason_description clob DEFAULT '' , - reason_order number(4) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_reports_reasons PRIMARY KEY (reason_id) -) -/ - - -CREATE SEQUENCE phpbb_reports_reasons_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_reports_reasons -BEFORE INSERT ON phpbb_reports_reasons -FOR EACH ROW WHEN ( - new.reason_id IS NULL OR new.reason_id = 0 -) -BEGIN - SELECT phpbb_reports_reasons_seq.nextval - INTO :new.reason_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_search_results' -*/ -CREATE TABLE phpbb_search_results ( - search_key varchar2(32) DEFAULT '' , - search_time number(11) DEFAULT '0' NOT NULL, - search_keywords clob DEFAULT '' , - search_authors clob DEFAULT '' , - CONSTRAINT pk_phpbb_search_results PRIMARY KEY (search_key) -) -/ - - -/* - Table: 'phpbb_search_wordlist' -*/ -CREATE TABLE phpbb_search_wordlist ( - word_id number(8) NOT NULL, - word_text varchar2(765) DEFAULT '' , - word_common number(1) DEFAULT '0' NOT NULL, - word_count number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_search_wordlist PRIMARY KEY (word_id), - CONSTRAINT u_phpbb_wrd_txt UNIQUE (word_text) -) -/ - -CREATE INDEX phpbb_search_wordlist_wrd_cnt ON phpbb_search_wordlist (word_count) -/ - -CREATE SEQUENCE phpbb_search_wordlist_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_search_wordlist -BEFORE INSERT ON phpbb_search_wordlist -FOR EACH ROW WHEN ( - new.word_id IS NULL OR new.word_id = 0 -) -BEGIN - SELECT phpbb_search_wordlist_seq.nextval - INTO :new.word_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_search_wordmatch' -*/ -CREATE TABLE phpbb_search_wordmatch ( - post_id number(8) DEFAULT '0' NOT NULL, - word_id number(8) DEFAULT '0' NOT NULL, - title_match number(1) DEFAULT '0' NOT NULL, - CONSTRAINT u_phpbb_unq_mtch UNIQUE (word_id, post_id, title_match) -) -/ - -CREATE INDEX phpbb_search_wordmatch_word_id ON phpbb_search_wordmatch (word_id) -/ -CREATE INDEX phpbb_search_wordmatch_post_id ON phpbb_search_wordmatch (post_id) -/ - -/* - Table: 'phpbb_sessions' -*/ -CREATE TABLE phpbb_sessions ( - session_id char(32) DEFAULT '' , - session_user_id number(8) DEFAULT '0' NOT NULL, - session_forum_id number(8) DEFAULT '0' NOT NULL, - session_last_visit number(11) DEFAULT '0' NOT NULL, - session_start number(11) DEFAULT '0' NOT NULL, - session_time number(11) DEFAULT '0' NOT NULL, - session_ip varchar2(40) DEFAULT '' , - session_browser varchar2(150) DEFAULT '' , - session_forwarded_for varchar2(255) DEFAULT '' , - session_page varchar2(765) DEFAULT '' , - session_viewonline number(1) DEFAULT '1' NOT NULL, - session_autologin number(1) DEFAULT '0' NOT NULL, - session_admin number(1) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_sessions PRIMARY KEY (session_id) -) -/ - -CREATE INDEX phpbb_sessions_session_time ON phpbb_sessions (session_time) -/ -CREATE INDEX phpbb_sessions_session_user_id ON phpbb_sessions (session_user_id) -/ -CREATE INDEX phpbb_sessions_session_fid ON phpbb_sessions (session_forum_id) -/ - -/* - Table: 'phpbb_sessions_keys' -*/ -CREATE TABLE phpbb_sessions_keys ( - key_id char(32) DEFAULT '' , - user_id number(8) DEFAULT '0' NOT NULL, - last_ip varchar2(40) DEFAULT '' , - last_login number(11) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_sessions_keys PRIMARY KEY (key_id, user_id) -) -/ - -CREATE INDEX phpbb_sessions_keys_last_login ON phpbb_sessions_keys (last_login) -/ - -/* - Table: 'phpbb_sitelist' -*/ -CREATE TABLE phpbb_sitelist ( - site_id number(8) NOT NULL, - site_ip varchar2(40) DEFAULT '' , - site_hostname varchar2(255) DEFAULT '' , - ip_exclude number(1) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_sitelist PRIMARY KEY (site_id) -) -/ - - -CREATE SEQUENCE phpbb_sitelist_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_sitelist -BEFORE INSERT ON phpbb_sitelist -FOR EACH ROW WHEN ( - new.site_id IS NULL OR new.site_id = 0 -) -BEGIN - SELECT phpbb_sitelist_seq.nextval - INTO :new.site_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_smilies' -*/ -CREATE TABLE phpbb_smilies ( - smiley_id number(8) NOT NULL, - code varchar2(150) DEFAULT '' , - emotion varchar2(150) DEFAULT '' , - smiley_url varchar2(50) DEFAULT '' , - smiley_width number(4) DEFAULT '0' NOT NULL, - smiley_height number(4) DEFAULT '0' NOT NULL, - smiley_order number(8) DEFAULT '0' NOT NULL, - display_on_posting number(1) DEFAULT '1' NOT NULL, - CONSTRAINT pk_phpbb_smilies PRIMARY KEY (smiley_id) -) -/ - -CREATE INDEX phpbb_smilies_display_on_post ON phpbb_smilies (display_on_posting) -/ - -CREATE SEQUENCE phpbb_smilies_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_smilies -BEFORE INSERT ON phpbb_smilies -FOR EACH ROW WHEN ( - new.smiley_id IS NULL OR new.smiley_id = 0 -) -BEGIN - SELECT phpbb_smilies_seq.nextval - INTO :new.smiley_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_styles' -*/ -CREATE TABLE phpbb_styles ( - style_id number(8) NOT NULL, - style_name varchar2(765) DEFAULT '' , - style_copyright varchar2(765) DEFAULT '' , - style_active number(1) DEFAULT '1' NOT NULL, - style_path varchar2(100) DEFAULT '' , - bbcode_bitfield varchar2(255) DEFAULT 'kNg=' NOT NULL, - style_parent_id number(4) DEFAULT '0' NOT NULL, - style_parent_tree clob DEFAULT '' , - CONSTRAINT pk_phpbb_styles PRIMARY KEY (style_id), - CONSTRAINT u_phpbb_style_name UNIQUE (style_name) -) -/ - - -CREATE SEQUENCE phpbb_styles_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_styles -BEFORE INSERT ON phpbb_styles -FOR EACH ROW WHEN ( - new.style_id IS NULL OR new.style_id = 0 -) -BEGIN - SELECT phpbb_styles_seq.nextval - INTO :new.style_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_teampage' -*/ -CREATE TABLE phpbb_teampage ( - teampage_id number(8) NOT NULL, - group_id number(8) DEFAULT '0' NOT NULL, - teampage_name varchar2(765) DEFAULT '' , - teampage_position number(8) DEFAULT '0' NOT NULL, - teampage_parent number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_teampage PRIMARY KEY (teampage_id) -) -/ - - -CREATE SEQUENCE phpbb_teampage_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_teampage -BEFORE INSERT ON phpbb_teampage -FOR EACH ROW WHEN ( - new.teampage_id IS NULL OR new.teampage_id = 0 -) -BEGIN - SELECT phpbb_teampage_seq.nextval - INTO :new.teampage_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_topics' -*/ -CREATE TABLE phpbb_topics ( - topic_id number(8) NOT NULL, - forum_id number(8) DEFAULT '0' NOT NULL, - icon_id number(8) DEFAULT '0' NOT NULL, - topic_attachment number(1) DEFAULT '0' NOT NULL, - topic_visibility number(3) DEFAULT '0' NOT NULL, - topic_reported number(1) DEFAULT '0' NOT NULL, - topic_title varchar2(765) DEFAULT '' , - topic_poster number(8) DEFAULT '0' NOT NULL, - topic_time number(11) DEFAULT '0' NOT NULL, - topic_time_limit number(11) DEFAULT '0' NOT NULL, - topic_views number(8) DEFAULT '0' NOT NULL, - topic_posts_approved number(8) DEFAULT '0' NOT NULL, - topic_posts_unapproved number(8) DEFAULT '0' NOT NULL, - topic_posts_softdeleted number(8) DEFAULT '0' NOT NULL, - topic_status number(3) DEFAULT '0' NOT NULL, - topic_type number(3) DEFAULT '0' NOT NULL, - topic_first_post_id number(8) DEFAULT '0' NOT NULL, - topic_first_poster_name varchar2(765) DEFAULT '' , - topic_first_poster_colour varchar2(6) DEFAULT '' , - topic_last_post_id number(8) DEFAULT '0' NOT NULL, - topic_last_poster_id number(8) DEFAULT '0' NOT NULL, - topic_last_poster_name varchar2(765) DEFAULT '' , - topic_last_poster_colour varchar2(6) DEFAULT '' , - topic_last_post_subject varchar2(765) DEFAULT '' , - topic_last_post_time number(11) DEFAULT '0' NOT NULL, - topic_last_view_time number(11) DEFAULT '0' NOT NULL, - topic_moved_id number(8) DEFAULT '0' NOT NULL, - topic_bumped number(1) DEFAULT '0' NOT NULL, - topic_bumper number(8) DEFAULT '0' NOT NULL, - poll_title varchar2(765) DEFAULT '' , - poll_start number(11) DEFAULT '0' NOT NULL, - poll_length number(11) DEFAULT '0' NOT NULL, - poll_max_options number(4) DEFAULT '1' NOT NULL, - poll_last_vote number(11) DEFAULT '0' NOT NULL, - poll_vote_change number(1) DEFAULT '0' NOT NULL, - topic_delete_time number(11) DEFAULT '0' NOT NULL, - topic_delete_reason varchar2(765) DEFAULT '' , - topic_delete_user number(8) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_topics PRIMARY KEY (topic_id) -) -/ - -CREATE INDEX phpbb_topics_forum_id ON phpbb_topics (forum_id) -/ -CREATE INDEX phpbb_topics_forum_id_type ON phpbb_topics (forum_id, topic_type) -/ -CREATE INDEX phpbb_topics_last_post_time ON phpbb_topics (topic_last_post_time) -/ -CREATE INDEX phpbb_topics_topic_visibility ON phpbb_topics (topic_visibility) -/ -CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics (forum_id, topic_visibility, topic_last_post_id) -/ -CREATE INDEX phpbb_topics_fid_time_moved ON phpbb_topics (forum_id, topic_last_post_time, topic_moved_id) -/ - -CREATE SEQUENCE phpbb_topics_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_topics -BEFORE INSERT ON phpbb_topics -FOR EACH ROW WHEN ( - new.topic_id IS NULL OR new.topic_id = 0 -) -BEGIN - SELECT phpbb_topics_seq.nextval - INTO :new.topic_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_topics_track' -*/ -CREATE TABLE phpbb_topics_track ( - user_id number(8) DEFAULT '0' NOT NULL, - topic_id number(8) DEFAULT '0' NOT NULL, - forum_id number(8) DEFAULT '0' NOT NULL, - mark_time number(11) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_topics_track PRIMARY KEY (user_id, topic_id) -) -/ - -CREATE INDEX phpbb_topics_track_topic_id ON phpbb_topics_track (topic_id) -/ -CREATE INDEX phpbb_topics_track_forum_id ON phpbb_topics_track (forum_id) -/ - -/* - Table: 'phpbb_topics_posted' -*/ -CREATE TABLE phpbb_topics_posted ( - user_id number(8) DEFAULT '0' NOT NULL, - topic_id number(8) DEFAULT '0' NOT NULL, - topic_posted number(1) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_topics_posted PRIMARY KEY (user_id, topic_id) -) -/ - - -/* - Table: 'phpbb_topics_watch' -*/ -CREATE TABLE phpbb_topics_watch ( - topic_id number(8) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - notify_status number(1) DEFAULT '0' NOT NULL -) -/ - -CREATE INDEX phpbb_topics_watch_topic_id ON phpbb_topics_watch (topic_id) -/ -CREATE INDEX phpbb_topics_watch_user_id ON phpbb_topics_watch (user_id) -/ -CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch (notify_status) -/ - -/* - Table: 'phpbb_user_notifications' -*/ -CREATE TABLE phpbb_user_notifications ( - item_type varchar2(255) DEFAULT '' , - item_id number(8) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - method varchar2(255) DEFAULT '' , - notify number(1) DEFAULT '1' NOT NULL -) -/ - - -/* - Table: 'phpbb_user_group' -*/ -CREATE TABLE phpbb_user_group ( - group_id number(8) DEFAULT '0' NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - group_leader number(1) DEFAULT '0' NOT NULL, - user_pending number(1) DEFAULT '1' NOT NULL -) -/ - -CREATE INDEX phpbb_user_group_group_id ON phpbb_user_group (group_id) -/ -CREATE INDEX phpbb_user_group_user_id ON phpbb_user_group (user_id) -/ -CREATE INDEX phpbb_user_group_group_leader ON phpbb_user_group (group_leader) -/ - -/* - Table: 'phpbb_users' -*/ -CREATE TABLE phpbb_users ( - user_id number(8) NOT NULL, - user_type number(2) DEFAULT '0' NOT NULL, - group_id number(8) DEFAULT '3' NOT NULL, - user_permissions clob DEFAULT '' , - user_perm_from number(8) DEFAULT '0' NOT NULL, - user_ip varchar2(40) DEFAULT '' , - user_regdate number(11) DEFAULT '0' NOT NULL, - username varchar2(255) DEFAULT '' , - username_clean varchar2(255) DEFAULT '' , - user_password varchar2(120) DEFAULT '' , - user_passchg number(11) DEFAULT '0' NOT NULL, - user_pass_convert number(1) DEFAULT '0' NOT NULL, - user_email varchar2(300) DEFAULT '' , - user_email_hash number(20) DEFAULT '0' NOT NULL, - user_birthday varchar2(10) DEFAULT '' , - user_lastvisit number(11) DEFAULT '0' NOT NULL, - user_lastmark number(11) DEFAULT '0' NOT NULL, - user_lastpost_time number(11) DEFAULT '0' NOT NULL, - user_lastpage varchar2(600) DEFAULT '' , - user_last_confirm_key varchar2(10) DEFAULT '' , - user_last_search number(11) DEFAULT '0' NOT NULL, - user_warnings number(4) DEFAULT '0' NOT NULL, - user_last_warning number(11) DEFAULT '0' NOT NULL, - user_login_attempts number(4) DEFAULT '0' NOT NULL, - user_inactive_reason number(2) DEFAULT '0' NOT NULL, - user_inactive_time number(11) DEFAULT '0' NOT NULL, - user_posts number(8) DEFAULT '0' NOT NULL, - user_lang varchar2(30) DEFAULT '' , - user_timezone varchar2(100) DEFAULT 'UTC' NOT NULL, - user_dateformat varchar2(90) DEFAULT 'd M Y H:i' NOT NULL, - user_style number(8) DEFAULT '0' NOT NULL, - user_rank number(8) DEFAULT '0' NOT NULL, - user_colour varchar2(6) DEFAULT '' , - user_new_privmsg number(4) DEFAULT '0' NOT NULL, - user_unread_privmsg number(4) DEFAULT '0' NOT NULL, - user_last_privmsg number(11) DEFAULT '0' NOT NULL, - user_message_rules number(1) DEFAULT '0' NOT NULL, - user_full_folder number(11) DEFAULT '-3' NOT NULL, - user_emailtime number(11) DEFAULT '0' NOT NULL, - user_topic_show_days number(4) DEFAULT '0' NOT NULL, - user_topic_sortby_type varchar2(1) DEFAULT 't' NOT NULL, - user_topic_sortby_dir varchar2(1) DEFAULT 'd' NOT NULL, - user_post_show_days number(4) DEFAULT '0' NOT NULL, - user_post_sortby_type varchar2(1) DEFAULT 't' NOT NULL, - user_post_sortby_dir varchar2(1) DEFAULT 'a' NOT NULL, - user_notify number(1) DEFAULT '0' NOT NULL, - user_notify_pm number(1) DEFAULT '1' NOT NULL, - user_notify_type number(4) DEFAULT '0' NOT NULL, - user_allow_pm number(1) DEFAULT '1' NOT NULL, - user_allow_viewonline number(1) DEFAULT '1' NOT NULL, - user_allow_viewemail number(1) DEFAULT '1' NOT NULL, - user_allow_massemail number(1) DEFAULT '1' NOT NULL, - user_options number(11) DEFAULT '230271' NOT NULL, - user_avatar varchar2(255) DEFAULT '' , - user_avatar_type varchar2(255) DEFAULT '' , - user_avatar_width number(4) DEFAULT '0' NOT NULL, - user_avatar_height number(4) DEFAULT '0' NOT NULL, - user_sig clob DEFAULT '' , - user_sig_bbcode_uid varchar2(8) DEFAULT '' , - user_sig_bbcode_bitfield varchar2(255) DEFAULT '' , - user_from varchar2(300) DEFAULT '' , - user_icq varchar2(15) DEFAULT '' , - user_aim varchar2(765) DEFAULT '' , - user_yim varchar2(765) DEFAULT '' , - user_msnm varchar2(765) DEFAULT '' , - user_jabber varchar2(765) DEFAULT '' , - user_website varchar2(600) DEFAULT '' , - user_occ clob DEFAULT '' , - user_interests clob DEFAULT '' , - user_actkey varchar2(32) DEFAULT '' , - user_newpasswd varchar2(120) DEFAULT '' , - user_form_salt varchar2(96) DEFAULT '' , - user_new number(1) DEFAULT '1' NOT NULL, - user_reminded number(4) DEFAULT '0' NOT NULL, - user_reminded_time number(11) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_users PRIMARY KEY (user_id), - CONSTRAINT u_phpbb_username_clean UNIQUE (username_clean) -) -/ - -CREATE INDEX phpbb_users_user_birthday ON phpbb_users (user_birthday) -/ -CREATE INDEX phpbb_users_user_email_hash ON phpbb_users (user_email_hash) -/ -CREATE INDEX phpbb_users_user_type ON phpbb_users (user_type) -/ - -CREATE SEQUENCE phpbb_users_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_users -BEFORE INSERT ON phpbb_users -FOR EACH ROW WHEN ( - new.user_id IS NULL OR new.user_id = 0 -) -BEGIN - SELECT phpbb_users_seq.nextval - INTO :new.user_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_warnings' -*/ -CREATE TABLE phpbb_warnings ( - warning_id number(8) NOT NULL, - user_id number(8) DEFAULT '0' NOT NULL, - post_id number(8) DEFAULT '0' NOT NULL, - log_id number(8) DEFAULT '0' NOT NULL, - warning_time number(11) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_warnings PRIMARY KEY (warning_id) -) -/ - - -CREATE SEQUENCE phpbb_warnings_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_warnings -BEFORE INSERT ON phpbb_warnings -FOR EACH ROW WHEN ( - new.warning_id IS NULL OR new.warning_id = 0 -) -BEGIN - SELECT phpbb_warnings_seq.nextval - INTO :new.warning_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_words' -*/ -CREATE TABLE phpbb_words ( - word_id number(8) NOT NULL, - word varchar2(765) DEFAULT '' , - replacement varchar2(765) DEFAULT '' , - CONSTRAINT pk_phpbb_words PRIMARY KEY (word_id) -) -/ - - -CREATE SEQUENCE phpbb_words_seq -/ - -CREATE OR REPLACE TRIGGER t_phpbb_words -BEFORE INSERT ON phpbb_words -FOR EACH ROW WHEN ( - new.word_id IS NULL OR new.word_id = 0 -) -BEGIN - SELECT phpbb_words_seq.nextval - INTO :new.word_id - FROM dual; -END; -/ - - -/* - Table: 'phpbb_zebra' -*/ -CREATE TABLE phpbb_zebra ( - user_id number(8) DEFAULT '0' NOT NULL, - zebra_id number(8) DEFAULT '0' NOT NULL, - friend number(1) DEFAULT '0' NOT NULL, - foe number(1) DEFAULT '0' NOT NULL, - CONSTRAINT pk_phpbb_zebra PRIMARY KEY (user_id, zebra_id) -) -/ - - diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index 14435898eb..3fc8589844 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -83,1282 +83,5 @@ CREATE OPERATOR =( MERGES, SORT1= <); -/* - Table: 'phpbb_attachments' -*/ -CREATE SEQUENCE phpbb_attachments_seq; - -CREATE TABLE phpbb_attachments ( - attach_id INT4 DEFAULT nextval('phpbb_attachments_seq'), - post_msg_id INT4 DEFAULT '0' NOT NULL CHECK (post_msg_id >= 0), - topic_id INT4 DEFAULT '0' NOT NULL CHECK (topic_id >= 0), - in_message INT2 DEFAULT '0' NOT NULL CHECK (in_message >= 0), - poster_id INT4 DEFAULT '0' NOT NULL CHECK (poster_id >= 0), - is_orphan INT2 DEFAULT '1' NOT NULL CHECK (is_orphan >= 0), - physical_filename varchar(255) DEFAULT '' NOT NULL, - real_filename varchar(255) DEFAULT '' NOT NULL, - download_count INT4 DEFAULT '0' NOT NULL CHECK (download_count >= 0), - attach_comment varchar(4000) DEFAULT '' NOT NULL, - extension varchar(100) DEFAULT '' NOT NULL, - mimetype varchar(100) DEFAULT '' NOT NULL, - filesize INT4 DEFAULT '0' NOT NULL CHECK (filesize >= 0), - filetime INT4 DEFAULT '0' NOT NULL CHECK (filetime >= 0), - thumbnail INT2 DEFAULT '0' NOT NULL CHECK (thumbnail >= 0), - PRIMARY KEY (attach_id) -); - -CREATE INDEX phpbb_attachments_filetime ON phpbb_attachments (filetime); -CREATE INDEX phpbb_attachments_post_msg_id ON phpbb_attachments (post_msg_id); -CREATE INDEX phpbb_attachments_topic_id ON phpbb_attachments (topic_id); -CREATE INDEX phpbb_attachments_poster_id ON phpbb_attachments (poster_id); -CREATE INDEX phpbb_attachments_is_orphan ON phpbb_attachments (is_orphan); - -/* - Table: 'phpbb_acl_groups' -*/ -CREATE TABLE phpbb_acl_groups ( - group_id INT4 DEFAULT '0' NOT NULL CHECK (group_id >= 0), - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - auth_option_id INT4 DEFAULT '0' NOT NULL CHECK (auth_option_id >= 0), - auth_role_id INT4 DEFAULT '0' NOT NULL CHECK (auth_role_id >= 0), - auth_setting INT2 DEFAULT '0' NOT NULL -); - -CREATE INDEX phpbb_acl_groups_group_id ON phpbb_acl_groups (group_id); -CREATE INDEX phpbb_acl_groups_auth_opt_id ON phpbb_acl_groups (auth_option_id); -CREATE INDEX phpbb_acl_groups_auth_role_id ON phpbb_acl_groups (auth_role_id); - -/* - Table: 'phpbb_acl_options' -*/ -CREATE SEQUENCE phpbb_acl_options_seq; - -CREATE TABLE phpbb_acl_options ( - auth_option_id INT4 DEFAULT nextval('phpbb_acl_options_seq'), - auth_option varchar(50) DEFAULT '' NOT NULL, - is_global INT2 DEFAULT '0' NOT NULL CHECK (is_global >= 0), - is_local INT2 DEFAULT '0' NOT NULL CHECK (is_local >= 0), - founder_only INT2 DEFAULT '0' NOT NULL CHECK (founder_only >= 0), - PRIMARY KEY (auth_option_id) -); - -CREATE UNIQUE INDEX phpbb_acl_options_auth_option ON phpbb_acl_options (auth_option); - -/* - Table: 'phpbb_acl_roles' -*/ -CREATE SEQUENCE phpbb_acl_roles_seq; - -CREATE TABLE phpbb_acl_roles ( - role_id INT4 DEFAULT nextval('phpbb_acl_roles_seq'), - role_name varchar(255) DEFAULT '' NOT NULL, - role_description varchar(4000) DEFAULT '' NOT NULL, - role_type varchar(10) DEFAULT '' NOT NULL, - role_order INT2 DEFAULT '0' NOT NULL CHECK (role_order >= 0), - PRIMARY KEY (role_id) -); - -CREATE INDEX phpbb_acl_roles_role_type ON phpbb_acl_roles (role_type); -CREATE INDEX phpbb_acl_roles_role_order ON phpbb_acl_roles (role_order); - -/* - Table: 'phpbb_acl_roles_data' -*/ -CREATE TABLE phpbb_acl_roles_data ( - role_id INT4 DEFAULT '0' NOT NULL CHECK (role_id >= 0), - auth_option_id INT4 DEFAULT '0' NOT NULL CHECK (auth_option_id >= 0), - auth_setting INT2 DEFAULT '0' NOT NULL, - PRIMARY KEY (role_id, auth_option_id) -); - -CREATE INDEX phpbb_acl_roles_data_ath_op_id ON phpbb_acl_roles_data (auth_option_id); - -/* - Table: 'phpbb_acl_users' -*/ -CREATE TABLE phpbb_acl_users ( - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - auth_option_id INT4 DEFAULT '0' NOT NULL CHECK (auth_option_id >= 0), - auth_role_id INT4 DEFAULT '0' NOT NULL CHECK (auth_role_id >= 0), - auth_setting INT2 DEFAULT '0' NOT NULL -); - -CREATE INDEX phpbb_acl_users_user_id ON phpbb_acl_users (user_id); -CREATE INDEX phpbb_acl_users_auth_option_id ON phpbb_acl_users (auth_option_id); -CREATE INDEX phpbb_acl_users_auth_role_id ON phpbb_acl_users (auth_role_id); - -/* - Table: 'phpbb_oauth_tokens' -*/ -CREATE TABLE phpbb_oauth_tokens ( - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - session_id char(32) DEFAULT '' NOT NULL, - provider varchar(255) DEFAULT '' NOT NULL, - oauth_token TEXT DEFAULT '' NOT NULL -); - -CREATE INDEX phpbb_oauth_tokens_user_id ON phpbb_oauth_tokens (user_id); -CREATE INDEX phpbb_oauth_tokens_provider ON phpbb_oauth_tokens (provider); - -/* - Table: 'phpbb_oauth_accounts' -*/ -CREATE TABLE phpbb_oauth_accounts ( - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - provider varchar(255) DEFAULT '' NOT NULL, - oauth_provider_id varchar(4000) DEFAULT '' NOT NULL, - PRIMARY KEY (user_id, provider) -); - - -/* - Table: 'phpbb_banlist' -*/ -CREATE SEQUENCE phpbb_banlist_seq; - -CREATE TABLE phpbb_banlist ( - ban_id INT4 DEFAULT nextval('phpbb_banlist_seq'), - ban_userid INT4 DEFAULT '0' NOT NULL CHECK (ban_userid >= 0), - ban_ip varchar(40) DEFAULT '' NOT NULL, - ban_email varchar(100) DEFAULT '' NOT NULL, - ban_start INT4 DEFAULT '0' NOT NULL CHECK (ban_start >= 0), - ban_end INT4 DEFAULT '0' NOT NULL CHECK (ban_end >= 0), - ban_exclude INT2 DEFAULT '0' NOT NULL CHECK (ban_exclude >= 0), - ban_reason varchar(255) DEFAULT '' NOT NULL, - ban_give_reason varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (ban_id) -); - -CREATE INDEX phpbb_banlist_ban_end ON phpbb_banlist (ban_end); -CREATE INDEX phpbb_banlist_ban_user ON phpbb_banlist (ban_userid, ban_exclude); -CREATE INDEX phpbb_banlist_ban_email ON phpbb_banlist (ban_email, ban_exclude); -CREATE INDEX phpbb_banlist_ban_ip ON phpbb_banlist (ban_ip, ban_exclude); - -/* - Table: 'phpbb_bbcodes' -*/ -CREATE TABLE phpbb_bbcodes ( - bbcode_id INT2 DEFAULT '0' NOT NULL CHECK (bbcode_id >= 0), - bbcode_tag varchar(16) DEFAULT '' NOT NULL, - bbcode_helpline varchar(255) DEFAULT '' NOT NULL, - display_on_posting INT2 DEFAULT '0' NOT NULL CHECK (display_on_posting >= 0), - bbcode_match varchar(4000) DEFAULT '' NOT NULL, - bbcode_tpl TEXT DEFAULT '' NOT NULL, - first_pass_match TEXT DEFAULT '' NOT NULL, - first_pass_replace TEXT DEFAULT '' NOT NULL, - second_pass_match TEXT DEFAULT '' NOT NULL, - second_pass_replace TEXT DEFAULT '' NOT NULL, - PRIMARY KEY (bbcode_id) -); - -CREATE INDEX phpbb_bbcodes_display_on_post ON phpbb_bbcodes (display_on_posting); - -/* - Table: 'phpbb_bookmarks' -*/ -CREATE TABLE phpbb_bookmarks ( - topic_id INT4 DEFAULT '0' NOT NULL CHECK (topic_id >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - PRIMARY KEY (topic_id, user_id) -); - - -/* - Table: 'phpbb_bots' -*/ -CREATE SEQUENCE phpbb_bots_seq; - -CREATE TABLE phpbb_bots ( - bot_id INT4 DEFAULT nextval('phpbb_bots_seq'), - bot_active INT2 DEFAULT '1' NOT NULL CHECK (bot_active >= 0), - bot_name varchar(255) DEFAULT '' NOT NULL, - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - bot_agent varchar(255) DEFAULT '' NOT NULL, - bot_ip varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (bot_id) -); - -CREATE INDEX phpbb_bots_bot_active ON phpbb_bots (bot_active); - -/* - Table: 'phpbb_config' -*/ -CREATE TABLE phpbb_config ( - config_name varchar(255) DEFAULT '' NOT NULL, - config_value varchar(255) DEFAULT '' NOT NULL, - is_dynamic INT2 DEFAULT '0' NOT NULL CHECK (is_dynamic >= 0), - PRIMARY KEY (config_name) -); - -CREATE INDEX phpbb_config_is_dynamic ON phpbb_config (is_dynamic); - -/* - Table: 'phpbb_config_text' -*/ -CREATE TABLE phpbb_config_text ( - config_name varchar(255) DEFAULT '' NOT NULL, - config_value TEXT DEFAULT '' NOT NULL, - PRIMARY KEY (config_name) -); - - -/* - Table: 'phpbb_confirm' -*/ -CREATE TABLE phpbb_confirm ( - confirm_id char(32) DEFAULT '' NOT NULL, - session_id char(32) DEFAULT '' NOT NULL, - confirm_type INT2 DEFAULT '0' NOT NULL, - code varchar(8) DEFAULT '' NOT NULL, - seed INT4 DEFAULT '0' NOT NULL CHECK (seed >= 0), - attempts INT4 DEFAULT '0' NOT NULL CHECK (attempts >= 0), - PRIMARY KEY (session_id, confirm_id) -); - -CREATE INDEX phpbb_confirm_confirm_type ON phpbb_confirm (confirm_type); - -/* - Table: 'phpbb_disallow' -*/ -CREATE SEQUENCE phpbb_disallow_seq; - -CREATE TABLE phpbb_disallow ( - disallow_id INT4 DEFAULT nextval('phpbb_disallow_seq'), - disallow_username varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (disallow_id) -); - - -/* - Table: 'phpbb_drafts' -*/ -CREATE SEQUENCE phpbb_drafts_seq; - -CREATE TABLE phpbb_drafts ( - draft_id INT4 DEFAULT nextval('phpbb_drafts_seq'), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - topic_id INT4 DEFAULT '0' NOT NULL CHECK (topic_id >= 0), - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - save_time INT4 DEFAULT '0' NOT NULL CHECK (save_time >= 0), - draft_subject varchar(255) DEFAULT '' NOT NULL, - draft_message TEXT DEFAULT '' NOT NULL, - PRIMARY KEY (draft_id) -); - -CREATE INDEX phpbb_drafts_save_time ON phpbb_drafts (save_time); - -/* - Table: 'phpbb_ext' -*/ -CREATE TABLE phpbb_ext ( - ext_name varchar(255) DEFAULT '' NOT NULL, - ext_active INT2 DEFAULT '0' NOT NULL CHECK (ext_active >= 0), - ext_state varchar(8000) DEFAULT '' NOT NULL -); - -CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext (ext_name); - -/* - Table: 'phpbb_extensions' -*/ -CREATE SEQUENCE phpbb_extensions_seq; - -CREATE TABLE phpbb_extensions ( - extension_id INT4 DEFAULT nextval('phpbb_extensions_seq'), - group_id INT4 DEFAULT '0' NOT NULL CHECK (group_id >= 0), - extension varchar(100) DEFAULT '' NOT NULL, - PRIMARY KEY (extension_id) -); - - -/* - Table: 'phpbb_extension_groups' -*/ -CREATE SEQUENCE phpbb_extension_groups_seq; - -CREATE TABLE phpbb_extension_groups ( - group_id INT4 DEFAULT nextval('phpbb_extension_groups_seq'), - group_name varchar(255) DEFAULT '' NOT NULL, - cat_id INT2 DEFAULT '0' NOT NULL, - allow_group INT2 DEFAULT '0' NOT NULL CHECK (allow_group >= 0), - download_mode INT2 DEFAULT '1' NOT NULL CHECK (download_mode >= 0), - upload_icon varchar(255) DEFAULT '' NOT NULL, - max_filesize INT4 DEFAULT '0' NOT NULL CHECK (max_filesize >= 0), - allowed_forums varchar(8000) DEFAULT '' NOT NULL, - allow_in_pm INT2 DEFAULT '0' NOT NULL CHECK (allow_in_pm >= 0), - PRIMARY KEY (group_id) -); - - -/* - Table: 'phpbb_forums' -*/ -CREATE SEQUENCE phpbb_forums_seq; - -CREATE TABLE phpbb_forums ( - forum_id INT4 DEFAULT nextval('phpbb_forums_seq'), - parent_id INT4 DEFAULT '0' NOT NULL CHECK (parent_id >= 0), - left_id INT4 DEFAULT '0' NOT NULL CHECK (left_id >= 0), - right_id INT4 DEFAULT '0' NOT NULL CHECK (right_id >= 0), - forum_parents TEXT DEFAULT '' NOT NULL, - forum_name varchar(255) DEFAULT '' NOT NULL, - forum_desc varchar(4000) DEFAULT '' NOT NULL, - forum_desc_bitfield varchar(255) DEFAULT '' NOT NULL, - forum_desc_options INT4 DEFAULT '7' NOT NULL CHECK (forum_desc_options >= 0), - forum_desc_uid varchar(8) DEFAULT '' NOT NULL, - forum_link varchar(255) DEFAULT '' NOT NULL, - forum_password varchar(40) DEFAULT '' NOT NULL, - forum_style INT4 DEFAULT '0' NOT NULL CHECK (forum_style >= 0), - forum_image varchar(255) DEFAULT '' NOT NULL, - forum_rules varchar(4000) DEFAULT '' NOT NULL, - forum_rules_link varchar(255) DEFAULT '' NOT NULL, - forum_rules_bitfield varchar(255) DEFAULT '' NOT NULL, - forum_rules_options INT4 DEFAULT '7' NOT NULL CHECK (forum_rules_options >= 0), - forum_rules_uid varchar(8) DEFAULT '' NOT NULL, - forum_topics_per_page INT2 DEFAULT '0' NOT NULL, - forum_type INT2 DEFAULT '0' NOT NULL, - forum_status INT2 DEFAULT '0' NOT NULL, - forum_posts_approved INT4 DEFAULT '0' NOT NULL CHECK (forum_posts_approved >= 0), - forum_posts_unapproved INT4 DEFAULT '0' NOT NULL CHECK (forum_posts_unapproved >= 0), - forum_posts_softdeleted INT4 DEFAULT '0' NOT NULL CHECK (forum_posts_softdeleted >= 0), - forum_topics_approved INT4 DEFAULT '0' NOT NULL CHECK (forum_topics_approved >= 0), - forum_topics_unapproved INT4 DEFAULT '0' NOT NULL CHECK (forum_topics_unapproved >= 0), - forum_topics_softdeleted INT4 DEFAULT '0' NOT NULL CHECK (forum_topics_softdeleted >= 0), - forum_last_post_id INT4 DEFAULT '0' NOT NULL CHECK (forum_last_post_id >= 0), - forum_last_poster_id INT4 DEFAULT '0' NOT NULL CHECK (forum_last_poster_id >= 0), - forum_last_post_subject varchar(255) DEFAULT '' NOT NULL, - forum_last_post_time INT4 DEFAULT '0' NOT NULL CHECK (forum_last_post_time >= 0), - forum_last_poster_name varchar(255) DEFAULT '' NOT NULL, - forum_last_poster_colour varchar(6) DEFAULT '' NOT NULL, - forum_flags INT2 DEFAULT '32' NOT NULL, - forum_options INT4 DEFAULT '0' NOT NULL CHECK (forum_options >= 0), - display_subforum_list INT2 DEFAULT '1' NOT NULL CHECK (display_subforum_list >= 0), - display_on_index INT2 DEFAULT '1' NOT NULL CHECK (display_on_index >= 0), - enable_indexing INT2 DEFAULT '1' NOT NULL CHECK (enable_indexing >= 0), - enable_icons INT2 DEFAULT '1' NOT NULL CHECK (enable_icons >= 0), - enable_prune INT2 DEFAULT '0' NOT NULL CHECK (enable_prune >= 0), - prune_next INT4 DEFAULT '0' NOT NULL CHECK (prune_next >= 0), - prune_days INT4 DEFAULT '0' NOT NULL CHECK (prune_days >= 0), - prune_viewed INT4 DEFAULT '0' NOT NULL CHECK (prune_viewed >= 0), - prune_freq INT4 DEFAULT '0' NOT NULL CHECK (prune_freq >= 0), - PRIMARY KEY (forum_id) -); - -CREATE INDEX phpbb_forums_left_right_id ON phpbb_forums (left_id, right_id); -CREATE INDEX phpbb_forums_forum_lastpost_id ON phpbb_forums (forum_last_post_id); - -/* - Table: 'phpbb_forums_access' -*/ -CREATE TABLE phpbb_forums_access ( - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - session_id char(32) DEFAULT '' NOT NULL, - PRIMARY KEY (forum_id, user_id, session_id) -); - - -/* - Table: 'phpbb_forums_track' -*/ -CREATE TABLE phpbb_forums_track ( - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - mark_time INT4 DEFAULT '0' NOT NULL CHECK (mark_time >= 0), - PRIMARY KEY (user_id, forum_id) -); - - -/* - Table: 'phpbb_forums_watch' -*/ -CREATE TABLE phpbb_forums_watch ( - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - notify_status INT2 DEFAULT '0' NOT NULL CHECK (notify_status >= 0) -); - -CREATE INDEX phpbb_forums_watch_forum_id ON phpbb_forums_watch (forum_id); -CREATE INDEX phpbb_forums_watch_user_id ON phpbb_forums_watch (user_id); -CREATE INDEX phpbb_forums_watch_notify_stat ON phpbb_forums_watch (notify_status); - -/* - Table: 'phpbb_groups' -*/ -CREATE SEQUENCE phpbb_groups_seq; - -CREATE TABLE phpbb_groups ( - group_id INT4 DEFAULT nextval('phpbb_groups_seq'), - group_type INT2 DEFAULT '1' NOT NULL, - group_founder_manage INT2 DEFAULT '0' NOT NULL CHECK (group_founder_manage >= 0), - group_skip_auth INT2 DEFAULT '0' NOT NULL CHECK (group_skip_auth >= 0), - group_name varchar_ci DEFAULT '' NOT NULL, - group_desc varchar(4000) DEFAULT '' NOT NULL, - group_desc_bitfield varchar(255) DEFAULT '' NOT NULL, - group_desc_options INT4 DEFAULT '7' NOT NULL CHECK (group_desc_options >= 0), - group_desc_uid varchar(8) DEFAULT '' NOT NULL, - group_display INT2 DEFAULT '0' NOT NULL CHECK (group_display >= 0), - group_avatar varchar(255) DEFAULT '' NOT NULL, - group_avatar_type varchar(255) DEFAULT '' NOT NULL, - group_avatar_width INT2 DEFAULT '0' NOT NULL CHECK (group_avatar_width >= 0), - group_avatar_height INT2 DEFAULT '0' NOT NULL CHECK (group_avatar_height >= 0), - group_rank INT4 DEFAULT '0' NOT NULL CHECK (group_rank >= 0), - group_colour varchar(6) DEFAULT '' NOT NULL, - group_sig_chars INT4 DEFAULT '0' NOT NULL CHECK (group_sig_chars >= 0), - group_receive_pm INT2 DEFAULT '0' NOT NULL CHECK (group_receive_pm >= 0), - group_message_limit INT4 DEFAULT '0' NOT NULL CHECK (group_message_limit >= 0), - group_max_recipients INT4 DEFAULT '0' NOT NULL CHECK (group_max_recipients >= 0), - group_legend INT4 DEFAULT '0' NOT NULL CHECK (group_legend >= 0), - PRIMARY KEY (group_id) -); - -CREATE INDEX phpbb_groups_group_legend_name ON phpbb_groups (group_legend, group_name); - -/* - Table: 'phpbb_icons' -*/ -CREATE SEQUENCE phpbb_icons_seq; - -CREATE TABLE phpbb_icons ( - icons_id INT4 DEFAULT nextval('phpbb_icons_seq'), - icons_url varchar(255) DEFAULT '' NOT NULL, - icons_width INT2 DEFAULT '0' NOT NULL, - icons_height INT2 DEFAULT '0' NOT NULL, - icons_order INT4 DEFAULT '0' NOT NULL CHECK (icons_order >= 0), - display_on_posting INT2 DEFAULT '1' NOT NULL CHECK (display_on_posting >= 0), - PRIMARY KEY (icons_id) -); - -CREATE INDEX phpbb_icons_display_on_posting ON phpbb_icons (display_on_posting); - -/* - Table: 'phpbb_lang' -*/ -CREATE SEQUENCE phpbb_lang_seq; - -CREATE TABLE phpbb_lang ( - lang_id INT2 DEFAULT nextval('phpbb_lang_seq'), - lang_iso varchar(30) DEFAULT '' NOT NULL, - lang_dir varchar(30) DEFAULT '' NOT NULL, - lang_english_name varchar(100) DEFAULT '' NOT NULL, - lang_local_name varchar(255) DEFAULT '' NOT NULL, - lang_author varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (lang_id) -); - -CREATE INDEX phpbb_lang_lang_iso ON phpbb_lang (lang_iso); - -/* - Table: 'phpbb_log' -*/ -CREATE SEQUENCE phpbb_log_seq; - -CREATE TABLE phpbb_log ( - log_id INT4 DEFAULT nextval('phpbb_log_seq'), - log_type INT2 DEFAULT '0' NOT NULL, - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - topic_id INT4 DEFAULT '0' NOT NULL CHECK (topic_id >= 0), - reportee_id INT4 DEFAULT '0' NOT NULL CHECK (reportee_id >= 0), - log_ip varchar(40) DEFAULT '' NOT NULL, - log_time INT4 DEFAULT '0' NOT NULL CHECK (log_time >= 0), - log_operation varchar(4000) DEFAULT '' NOT NULL, - log_data TEXT DEFAULT '' NOT NULL, - PRIMARY KEY (log_id) -); - -CREATE INDEX phpbb_log_log_type ON phpbb_log (log_type); -CREATE INDEX phpbb_log_log_time ON phpbb_log (log_time); -CREATE INDEX phpbb_log_forum_id ON phpbb_log (forum_id); -CREATE INDEX phpbb_log_topic_id ON phpbb_log (topic_id); -CREATE INDEX phpbb_log_reportee_id ON phpbb_log (reportee_id); -CREATE INDEX phpbb_log_user_id ON phpbb_log (user_id); - -/* - Table: 'phpbb_login_attempts' -*/ -CREATE TABLE phpbb_login_attempts ( - attempt_ip varchar(40) DEFAULT '' NOT NULL, - attempt_browser varchar(150) DEFAULT '' NOT NULL, - attempt_forwarded_for varchar(255) DEFAULT '' NOT NULL, - attempt_time INT4 DEFAULT '0' NOT NULL CHECK (attempt_time >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - username varchar(255) DEFAULT '0' NOT NULL, - username_clean varchar_ci DEFAULT '0' NOT NULL -); - -CREATE INDEX phpbb_login_attempts_att_ip ON phpbb_login_attempts (attempt_ip, attempt_time); -CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwarded_for, attempt_time); -CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); -CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); - -/* - Table: 'phpbb_moderator_cache' -*/ -CREATE TABLE phpbb_moderator_cache ( - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - username varchar(255) DEFAULT '' NOT NULL, - group_id INT4 DEFAULT '0' NOT NULL CHECK (group_id >= 0), - group_name varchar(255) DEFAULT '' NOT NULL, - display_on_index INT2 DEFAULT '1' NOT NULL CHECK (display_on_index >= 0) -); - -CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache (display_on_index); -CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id); - -/* - Table: 'phpbb_migrations' -*/ -CREATE TABLE phpbb_migrations ( - migration_name varchar(255) DEFAULT '' NOT NULL, - migration_depends_on varchar(8000) DEFAULT '' NOT NULL, - migration_schema_done INT2 DEFAULT '0' NOT NULL CHECK (migration_schema_done >= 0), - migration_data_done INT2 DEFAULT '0' NOT NULL CHECK (migration_data_done >= 0), - migration_data_state varchar(8000) DEFAULT '' NOT NULL, - migration_start_time INT4 DEFAULT '0' NOT NULL CHECK (migration_start_time >= 0), - migration_end_time INT4 DEFAULT '0' NOT NULL CHECK (migration_end_time >= 0), - PRIMARY KEY (migration_name) -); - - -/* - Table: 'phpbb_modules' -*/ -CREATE SEQUENCE phpbb_modules_seq; - -CREATE TABLE phpbb_modules ( - module_id INT4 DEFAULT nextval('phpbb_modules_seq'), - module_enabled INT2 DEFAULT '1' NOT NULL CHECK (module_enabled >= 0), - module_display INT2 DEFAULT '1' NOT NULL CHECK (module_display >= 0), - module_basename varchar(255) DEFAULT '' NOT NULL, - module_class varchar(10) DEFAULT '' NOT NULL, - parent_id INT4 DEFAULT '0' NOT NULL CHECK (parent_id >= 0), - left_id INT4 DEFAULT '0' NOT NULL CHECK (left_id >= 0), - right_id INT4 DEFAULT '0' NOT NULL CHECK (right_id >= 0), - module_langname varchar(255) DEFAULT '' NOT NULL, - module_mode varchar(255) DEFAULT '' NOT NULL, - module_auth varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (module_id) -); - -CREATE INDEX phpbb_modules_left_right_id ON phpbb_modules (left_id, right_id); -CREATE INDEX phpbb_modules_module_enabled ON phpbb_modules (module_enabled); -CREATE INDEX phpbb_modules_class_left_id ON phpbb_modules (module_class, left_id); - -/* - Table: 'phpbb_notification_types' -*/ -CREATE SEQUENCE phpbb_notification_types_seq; - -CREATE TABLE phpbb_notification_types ( - notification_type_id INT2 DEFAULT nextval('phpbb_notification_types_seq'), - notification_type_name varchar(255) DEFAULT '' NOT NULL, - notification_type_enabled INT2 DEFAULT '1' NOT NULL CHECK (notification_type_enabled >= 0), - PRIMARY KEY (notification_type_id) -); - -CREATE UNIQUE INDEX phpbb_notification_types_type ON phpbb_notification_types (notification_type_name); - -/* - Table: 'phpbb_notifications' -*/ -CREATE SEQUENCE phpbb_notifications_seq; - -CREATE TABLE phpbb_notifications ( - notification_id INT4 DEFAULT nextval('phpbb_notifications_seq'), - notification_type_id INT2 DEFAULT '0' NOT NULL CHECK (notification_type_id >= 0), - item_id INT4 DEFAULT '0' NOT NULL CHECK (item_id >= 0), - item_parent_id INT4 DEFAULT '0' NOT NULL CHECK (item_parent_id >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - notification_read INT2 DEFAULT '0' NOT NULL CHECK (notification_read >= 0), - notification_time INT4 DEFAULT '1' NOT NULL CHECK (notification_time >= 0), - notification_data varchar(4000) DEFAULT '' NOT NULL, - PRIMARY KEY (notification_id) -); - -CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (notification_type_id, item_id); -CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read); - -/* - Table: 'phpbb_poll_options' -*/ -CREATE TABLE phpbb_poll_options ( - poll_option_id INT2 DEFAULT '0' NOT NULL, - topic_id INT4 DEFAULT '0' NOT NULL CHECK (topic_id >= 0), - poll_option_text varchar(4000) DEFAULT '' NOT NULL, - poll_option_total INT4 DEFAULT '0' NOT NULL CHECK (poll_option_total >= 0) -); - -CREATE INDEX phpbb_poll_options_poll_opt_id ON phpbb_poll_options (poll_option_id); -CREATE INDEX phpbb_poll_options_topic_id ON phpbb_poll_options (topic_id); - -/* - Table: 'phpbb_poll_votes' -*/ -CREATE TABLE phpbb_poll_votes ( - topic_id INT4 DEFAULT '0' NOT NULL CHECK (topic_id >= 0), - poll_option_id INT2 DEFAULT '0' NOT NULL, - vote_user_id INT4 DEFAULT '0' NOT NULL CHECK (vote_user_id >= 0), - vote_user_ip varchar(40) DEFAULT '' NOT NULL -); - -CREATE INDEX phpbb_poll_votes_topic_id ON phpbb_poll_votes (topic_id); -CREATE INDEX phpbb_poll_votes_vote_user_id ON phpbb_poll_votes (vote_user_id); -CREATE INDEX phpbb_poll_votes_vote_user_ip ON phpbb_poll_votes (vote_user_ip); - -/* - Table: 'phpbb_posts' -*/ -CREATE SEQUENCE phpbb_posts_seq; - -CREATE TABLE phpbb_posts ( - post_id INT4 DEFAULT nextval('phpbb_posts_seq'), - topic_id INT4 DEFAULT '0' NOT NULL CHECK (topic_id >= 0), - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - poster_id INT4 DEFAULT '0' NOT NULL CHECK (poster_id >= 0), - icon_id INT4 DEFAULT '0' NOT NULL CHECK (icon_id >= 0), - poster_ip varchar(40) DEFAULT '' NOT NULL, - post_time INT4 DEFAULT '0' NOT NULL CHECK (post_time >= 0), - post_visibility INT2 DEFAULT '0' NOT NULL, - post_reported INT2 DEFAULT '0' NOT NULL CHECK (post_reported >= 0), - enable_bbcode INT2 DEFAULT '1' NOT NULL CHECK (enable_bbcode >= 0), - enable_smilies INT2 DEFAULT '1' NOT NULL CHECK (enable_smilies >= 0), - enable_magic_url INT2 DEFAULT '1' NOT NULL CHECK (enable_magic_url >= 0), - enable_sig INT2 DEFAULT '1' NOT NULL CHECK (enable_sig >= 0), - post_username varchar(255) DEFAULT '' NOT NULL, - post_subject varchar(255) DEFAULT '' NOT NULL, - post_text TEXT DEFAULT '' NOT NULL, - post_checksum varchar(32) DEFAULT '' NOT NULL, - post_attachment INT2 DEFAULT '0' NOT NULL CHECK (post_attachment >= 0), - bbcode_bitfield varchar(255) DEFAULT '' NOT NULL, - bbcode_uid varchar(8) DEFAULT '' NOT NULL, - post_postcount INT2 DEFAULT '1' NOT NULL CHECK (post_postcount >= 0), - post_edit_time INT4 DEFAULT '0' NOT NULL CHECK (post_edit_time >= 0), - post_edit_reason varchar(255) DEFAULT '' NOT NULL, - post_edit_user INT4 DEFAULT '0' NOT NULL CHECK (post_edit_user >= 0), - post_edit_count INT2 DEFAULT '0' NOT NULL CHECK (post_edit_count >= 0), - post_edit_locked INT2 DEFAULT '0' NOT NULL CHECK (post_edit_locked >= 0), - post_delete_time INT4 DEFAULT '0' NOT NULL CHECK (post_delete_time >= 0), - post_delete_reason varchar(255) DEFAULT '' NOT NULL, - post_delete_user INT4 DEFAULT '0' NOT NULL CHECK (post_delete_user >= 0), - PRIMARY KEY (post_id) -); - -CREATE INDEX phpbb_posts_forum_id ON phpbb_posts (forum_id); -CREATE INDEX phpbb_posts_topic_id ON phpbb_posts (topic_id); -CREATE INDEX phpbb_posts_poster_ip ON phpbb_posts (poster_ip); -CREATE INDEX phpbb_posts_poster_id ON phpbb_posts (poster_id); -CREATE INDEX phpbb_posts_post_visibility ON phpbb_posts (post_visibility); -CREATE INDEX phpbb_posts_post_username ON phpbb_posts (post_username); -CREATE INDEX phpbb_posts_tid_post_time ON phpbb_posts (topic_id, post_time); - -/* - Table: 'phpbb_privmsgs' -*/ -CREATE SEQUENCE phpbb_privmsgs_seq; - -CREATE TABLE phpbb_privmsgs ( - msg_id INT4 DEFAULT nextval('phpbb_privmsgs_seq'), - root_level INT4 DEFAULT '0' NOT NULL CHECK (root_level >= 0), - author_id INT4 DEFAULT '0' NOT NULL CHECK (author_id >= 0), - icon_id INT4 DEFAULT '0' NOT NULL CHECK (icon_id >= 0), - author_ip varchar(40) DEFAULT '' NOT NULL, - message_time INT4 DEFAULT '0' NOT NULL CHECK (message_time >= 0), - enable_bbcode INT2 DEFAULT '1' NOT NULL CHECK (enable_bbcode >= 0), - enable_smilies INT2 DEFAULT '1' NOT NULL CHECK (enable_smilies >= 0), - enable_magic_url INT2 DEFAULT '1' NOT NULL CHECK (enable_magic_url >= 0), - enable_sig INT2 DEFAULT '1' NOT NULL CHECK (enable_sig >= 0), - message_subject varchar(255) DEFAULT '' NOT NULL, - message_text TEXT DEFAULT '' NOT NULL, - message_edit_reason varchar(255) DEFAULT '' NOT NULL, - message_edit_user INT4 DEFAULT '0' NOT NULL CHECK (message_edit_user >= 0), - message_attachment INT2 DEFAULT '0' NOT NULL CHECK (message_attachment >= 0), - bbcode_bitfield varchar(255) DEFAULT '' NOT NULL, - bbcode_uid varchar(8) DEFAULT '' NOT NULL, - message_edit_time INT4 DEFAULT '0' NOT NULL CHECK (message_edit_time >= 0), - message_edit_count INT2 DEFAULT '0' NOT NULL CHECK (message_edit_count >= 0), - to_address varchar(4000) DEFAULT '' NOT NULL, - bcc_address varchar(4000) DEFAULT '' NOT NULL, - message_reported INT2 DEFAULT '0' NOT NULL CHECK (message_reported >= 0), - PRIMARY KEY (msg_id) -); - -CREATE INDEX phpbb_privmsgs_author_ip ON phpbb_privmsgs (author_ip); -CREATE INDEX phpbb_privmsgs_message_time ON phpbb_privmsgs (message_time); -CREATE INDEX phpbb_privmsgs_author_id ON phpbb_privmsgs (author_id); -CREATE INDEX phpbb_privmsgs_root_level ON phpbb_privmsgs (root_level); - -/* - Table: 'phpbb_privmsgs_folder' -*/ -CREATE SEQUENCE phpbb_privmsgs_folder_seq; - -CREATE TABLE phpbb_privmsgs_folder ( - folder_id INT4 DEFAULT nextval('phpbb_privmsgs_folder_seq'), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - folder_name varchar(255) DEFAULT '' NOT NULL, - pm_count INT4 DEFAULT '0' NOT NULL CHECK (pm_count >= 0), - PRIMARY KEY (folder_id) -); - -CREATE INDEX phpbb_privmsgs_folder_user_id ON phpbb_privmsgs_folder (user_id); - -/* - Table: 'phpbb_privmsgs_rules' -*/ -CREATE SEQUENCE phpbb_privmsgs_rules_seq; - -CREATE TABLE phpbb_privmsgs_rules ( - rule_id INT4 DEFAULT nextval('phpbb_privmsgs_rules_seq'), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - rule_check INT4 DEFAULT '0' NOT NULL CHECK (rule_check >= 0), - rule_connection INT4 DEFAULT '0' NOT NULL CHECK (rule_connection >= 0), - rule_string varchar(255) DEFAULT '' NOT NULL, - rule_user_id INT4 DEFAULT '0' NOT NULL CHECK (rule_user_id >= 0), - rule_group_id INT4 DEFAULT '0' NOT NULL CHECK (rule_group_id >= 0), - rule_action INT4 DEFAULT '0' NOT NULL CHECK (rule_action >= 0), - rule_folder_id INT4 DEFAULT '0' NOT NULL, - PRIMARY KEY (rule_id) -); - -CREATE INDEX phpbb_privmsgs_rules_user_id ON phpbb_privmsgs_rules (user_id); - -/* - Table: 'phpbb_privmsgs_to' -*/ -CREATE TABLE phpbb_privmsgs_to ( - msg_id INT4 DEFAULT '0' NOT NULL CHECK (msg_id >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - author_id INT4 DEFAULT '0' NOT NULL CHECK (author_id >= 0), - pm_deleted INT2 DEFAULT '0' NOT NULL CHECK (pm_deleted >= 0), - pm_new INT2 DEFAULT '1' NOT NULL CHECK (pm_new >= 0), - pm_unread INT2 DEFAULT '1' NOT NULL CHECK (pm_unread >= 0), - pm_replied INT2 DEFAULT '0' NOT NULL CHECK (pm_replied >= 0), - pm_marked INT2 DEFAULT '0' NOT NULL CHECK (pm_marked >= 0), - pm_forwarded INT2 DEFAULT '0' NOT NULL CHECK (pm_forwarded >= 0), - folder_id INT4 DEFAULT '0' NOT NULL -); - -CREATE INDEX phpbb_privmsgs_to_msg_id ON phpbb_privmsgs_to (msg_id); -CREATE INDEX phpbb_privmsgs_to_author_id ON phpbb_privmsgs_to (author_id); -CREATE INDEX phpbb_privmsgs_to_usr_flder_id ON phpbb_privmsgs_to (user_id, folder_id); - -/* - Table: 'phpbb_profile_fields' -*/ -CREATE SEQUENCE phpbb_profile_fields_seq; - -CREATE TABLE phpbb_profile_fields ( - field_id INT4 DEFAULT nextval('phpbb_profile_fields_seq'), - field_name varchar(255) DEFAULT '' NOT NULL, - field_type INT2 DEFAULT '0' NOT NULL, - field_ident varchar(20) DEFAULT '' NOT NULL, - field_length varchar(20) DEFAULT '' NOT NULL, - field_minlen varchar(255) DEFAULT '' NOT NULL, - field_maxlen varchar(255) DEFAULT '' NOT NULL, - field_novalue varchar(255) DEFAULT '' NOT NULL, - field_default_value varchar(255) DEFAULT '' NOT NULL, - field_validation varchar(20) DEFAULT '' NOT NULL, - field_required INT2 DEFAULT '0' NOT NULL CHECK (field_required >= 0), - field_show_novalue INT2 DEFAULT '0' NOT NULL CHECK (field_show_novalue >= 0), - field_show_on_reg INT2 DEFAULT '0' NOT NULL CHECK (field_show_on_reg >= 0), - field_show_on_pm INT2 DEFAULT '0' NOT NULL CHECK (field_show_on_pm >= 0), - field_show_on_vt INT2 DEFAULT '0' NOT NULL CHECK (field_show_on_vt >= 0), - field_show_profile INT2 DEFAULT '0' NOT NULL CHECK (field_show_profile >= 0), - field_hide INT2 DEFAULT '0' NOT NULL CHECK (field_hide >= 0), - field_no_view INT2 DEFAULT '0' NOT NULL CHECK (field_no_view >= 0), - field_active INT2 DEFAULT '0' NOT NULL CHECK (field_active >= 0), - field_order INT4 DEFAULT '0' NOT NULL CHECK (field_order >= 0), - PRIMARY KEY (field_id) -); - -CREATE INDEX phpbb_profile_fields_fld_type ON phpbb_profile_fields (field_type); -CREATE INDEX phpbb_profile_fields_fld_ordr ON phpbb_profile_fields (field_order); - -/* - Table: 'phpbb_profile_fields_data' -*/ -CREATE TABLE phpbb_profile_fields_data ( - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - PRIMARY KEY (user_id) -); - - -/* - Table: 'phpbb_profile_fields_lang' -*/ -CREATE TABLE phpbb_profile_fields_lang ( - field_id INT4 DEFAULT '0' NOT NULL CHECK (field_id >= 0), - lang_id INT4 DEFAULT '0' NOT NULL CHECK (lang_id >= 0), - option_id INT4 DEFAULT '0' NOT NULL CHECK (option_id >= 0), - field_type INT2 DEFAULT '0' NOT NULL, - lang_value varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (field_id, lang_id, option_id) -); - - -/* - Table: 'phpbb_profile_lang' -*/ -CREATE TABLE phpbb_profile_lang ( - field_id INT4 DEFAULT '0' NOT NULL CHECK (field_id >= 0), - lang_id INT4 DEFAULT '0' NOT NULL CHECK (lang_id >= 0), - lang_name varchar(255) DEFAULT '' NOT NULL, - lang_explain varchar(4000) DEFAULT '' NOT NULL, - lang_default_value varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (field_id, lang_id) -); - - -/* - Table: 'phpbb_ranks' -*/ -CREATE SEQUENCE phpbb_ranks_seq; - -CREATE TABLE phpbb_ranks ( - rank_id INT4 DEFAULT nextval('phpbb_ranks_seq'), - rank_title varchar(255) DEFAULT '' NOT NULL, - rank_min INT4 DEFAULT '0' NOT NULL CHECK (rank_min >= 0), - rank_special INT2 DEFAULT '0' NOT NULL CHECK (rank_special >= 0), - rank_image varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (rank_id) -); - - -/* - Table: 'phpbb_reports' -*/ -CREATE SEQUENCE phpbb_reports_seq; - -CREATE TABLE phpbb_reports ( - report_id INT4 DEFAULT nextval('phpbb_reports_seq'), - reason_id INT2 DEFAULT '0' NOT NULL CHECK (reason_id >= 0), - post_id INT4 DEFAULT '0' NOT NULL CHECK (post_id >= 0), - pm_id INT4 DEFAULT '0' NOT NULL CHECK (pm_id >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - user_notify INT2 DEFAULT '0' NOT NULL CHECK (user_notify >= 0), - report_closed INT2 DEFAULT '0' NOT NULL CHECK (report_closed >= 0), - report_time INT4 DEFAULT '0' NOT NULL CHECK (report_time >= 0), - report_text TEXT DEFAULT '' NOT NULL, - reported_post_text TEXT DEFAULT '' NOT NULL, - reported_post_uid varchar(8) DEFAULT '' NOT NULL, - reported_post_bitfield varchar(255) DEFAULT '' NOT NULL, - reported_post_enable_magic_url INT2 DEFAULT '1' NOT NULL CHECK (reported_post_enable_magic_url >= 0), - reported_post_enable_smilies INT2 DEFAULT '1' NOT NULL CHECK (reported_post_enable_smilies >= 0), - reported_post_enable_bbcode INT2 DEFAULT '1' NOT NULL CHECK (reported_post_enable_bbcode >= 0), - PRIMARY KEY (report_id) -); - -CREATE INDEX phpbb_reports_post_id ON phpbb_reports (post_id); -CREATE INDEX phpbb_reports_pm_id ON phpbb_reports (pm_id); - -/* - Table: 'phpbb_reports_reasons' -*/ -CREATE SEQUENCE phpbb_reports_reasons_seq; - -CREATE TABLE phpbb_reports_reasons ( - reason_id INT2 DEFAULT nextval('phpbb_reports_reasons_seq'), - reason_title varchar(255) DEFAULT '' NOT NULL, - reason_description TEXT DEFAULT '' NOT NULL, - reason_order INT2 DEFAULT '0' NOT NULL CHECK (reason_order >= 0), - PRIMARY KEY (reason_id) -); - - -/* - Table: 'phpbb_search_results' -*/ -CREATE TABLE phpbb_search_results ( - search_key varchar(32) DEFAULT '' NOT NULL, - search_time INT4 DEFAULT '0' NOT NULL CHECK (search_time >= 0), - search_keywords TEXT DEFAULT '' NOT NULL, - search_authors TEXT DEFAULT '' NOT NULL, - PRIMARY KEY (search_key) -); - - -/* - Table: 'phpbb_search_wordlist' -*/ -CREATE SEQUENCE phpbb_search_wordlist_seq; - -CREATE TABLE phpbb_search_wordlist ( - word_id INT4 DEFAULT nextval('phpbb_search_wordlist_seq'), - word_text varchar(255) DEFAULT '' NOT NULL, - word_common INT2 DEFAULT '0' NOT NULL CHECK (word_common >= 0), - word_count INT4 DEFAULT '0' NOT NULL CHECK (word_count >= 0), - PRIMARY KEY (word_id) -); - -CREATE UNIQUE INDEX phpbb_search_wordlist_wrd_txt ON phpbb_search_wordlist (word_text); -CREATE INDEX phpbb_search_wordlist_wrd_cnt ON phpbb_search_wordlist (word_count); - -/* - Table: 'phpbb_search_wordmatch' -*/ -CREATE TABLE phpbb_search_wordmatch ( - post_id INT4 DEFAULT '0' NOT NULL CHECK (post_id >= 0), - word_id INT4 DEFAULT '0' NOT NULL CHECK (word_id >= 0), - title_match INT2 DEFAULT '0' NOT NULL CHECK (title_match >= 0) -); - -CREATE UNIQUE INDEX phpbb_search_wordmatch_unq_mtch ON phpbb_search_wordmatch (word_id, post_id, title_match); -CREATE INDEX phpbb_search_wordmatch_word_id ON phpbb_search_wordmatch (word_id); -CREATE INDEX phpbb_search_wordmatch_post_id ON phpbb_search_wordmatch (post_id); - -/* - Table: 'phpbb_sessions' -*/ -CREATE TABLE phpbb_sessions ( - session_id char(32) DEFAULT '' NOT NULL, - session_user_id INT4 DEFAULT '0' NOT NULL CHECK (session_user_id >= 0), - session_forum_id INT4 DEFAULT '0' NOT NULL CHECK (session_forum_id >= 0), - session_last_visit INT4 DEFAULT '0' NOT NULL CHECK (session_last_visit >= 0), - session_start INT4 DEFAULT '0' NOT NULL CHECK (session_start >= 0), - session_time INT4 DEFAULT '0' NOT NULL CHECK (session_time >= 0), - session_ip varchar(40) DEFAULT '' NOT NULL, - session_browser varchar(150) DEFAULT '' NOT NULL, - session_forwarded_for varchar(255) DEFAULT '' NOT NULL, - session_page varchar(255) DEFAULT '' NOT NULL, - session_viewonline INT2 DEFAULT '1' NOT NULL CHECK (session_viewonline >= 0), - session_autologin INT2 DEFAULT '0' NOT NULL CHECK (session_autologin >= 0), - session_admin INT2 DEFAULT '0' NOT NULL CHECK (session_admin >= 0), - PRIMARY KEY (session_id) -); - -CREATE INDEX phpbb_sessions_session_time ON phpbb_sessions (session_time); -CREATE INDEX phpbb_sessions_session_user_id ON phpbb_sessions (session_user_id); -CREATE INDEX phpbb_sessions_session_fid ON phpbb_sessions (session_forum_id); - -/* - Table: 'phpbb_sessions_keys' -*/ -CREATE TABLE phpbb_sessions_keys ( - key_id char(32) DEFAULT '' NOT NULL, - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - last_ip varchar(40) DEFAULT '' NOT NULL, - last_login INT4 DEFAULT '0' NOT NULL CHECK (last_login >= 0), - PRIMARY KEY (key_id, user_id) -); - -CREATE INDEX phpbb_sessions_keys_last_login ON phpbb_sessions_keys (last_login); - -/* - Table: 'phpbb_sitelist' -*/ -CREATE SEQUENCE phpbb_sitelist_seq; - -CREATE TABLE phpbb_sitelist ( - site_id INT4 DEFAULT nextval('phpbb_sitelist_seq'), - site_ip varchar(40) DEFAULT '' NOT NULL, - site_hostname varchar(255) DEFAULT '' NOT NULL, - ip_exclude INT2 DEFAULT '0' NOT NULL CHECK (ip_exclude >= 0), - PRIMARY KEY (site_id) -); - - -/* - Table: 'phpbb_smilies' -*/ -CREATE SEQUENCE phpbb_smilies_seq; - -CREATE TABLE phpbb_smilies ( - smiley_id INT4 DEFAULT nextval('phpbb_smilies_seq'), - code varchar(50) DEFAULT '' NOT NULL, - emotion varchar(50) DEFAULT '' NOT NULL, - smiley_url varchar(50) DEFAULT '' NOT NULL, - smiley_width INT2 DEFAULT '0' NOT NULL CHECK (smiley_width >= 0), - smiley_height INT2 DEFAULT '0' NOT NULL CHECK (smiley_height >= 0), - smiley_order INT4 DEFAULT '0' NOT NULL CHECK (smiley_order >= 0), - display_on_posting INT2 DEFAULT '1' NOT NULL CHECK (display_on_posting >= 0), - PRIMARY KEY (smiley_id) -); - -CREATE INDEX phpbb_smilies_display_on_post ON phpbb_smilies (display_on_posting); - -/* - Table: 'phpbb_styles' -*/ -CREATE SEQUENCE phpbb_styles_seq; - -CREATE TABLE phpbb_styles ( - style_id INT4 DEFAULT nextval('phpbb_styles_seq'), - style_name varchar(255) DEFAULT '' NOT NULL, - style_copyright varchar(255) DEFAULT '' NOT NULL, - style_active INT2 DEFAULT '1' NOT NULL CHECK (style_active >= 0), - style_path varchar(100) DEFAULT '' NOT NULL, - bbcode_bitfield varchar(255) DEFAULT 'kNg=' NOT NULL, - style_parent_id INT4 DEFAULT '0' NOT NULL CHECK (style_parent_id >= 0), - style_parent_tree varchar(8000) DEFAULT '' NOT NULL, - PRIMARY KEY (style_id) -); - -CREATE UNIQUE INDEX phpbb_styles_style_name ON phpbb_styles (style_name); - -/* - Table: 'phpbb_teampage' -*/ -CREATE SEQUENCE phpbb_teampage_seq; - -CREATE TABLE phpbb_teampage ( - teampage_id INT4 DEFAULT nextval('phpbb_teampage_seq'), - group_id INT4 DEFAULT '0' NOT NULL CHECK (group_id >= 0), - teampage_name varchar(255) DEFAULT '' NOT NULL, - teampage_position INT4 DEFAULT '0' NOT NULL CHECK (teampage_position >= 0), - teampage_parent INT4 DEFAULT '0' NOT NULL CHECK (teampage_parent >= 0), - PRIMARY KEY (teampage_id) -); - - -/* - Table: 'phpbb_topics' -*/ -CREATE SEQUENCE phpbb_topics_seq; - -CREATE TABLE phpbb_topics ( - topic_id INT4 DEFAULT nextval('phpbb_topics_seq'), - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - icon_id INT4 DEFAULT '0' NOT NULL CHECK (icon_id >= 0), - topic_attachment INT2 DEFAULT '0' NOT NULL CHECK (topic_attachment >= 0), - topic_visibility INT2 DEFAULT '0' NOT NULL, - topic_reported INT2 DEFAULT '0' NOT NULL CHECK (topic_reported >= 0), - topic_title varchar(255) DEFAULT '' NOT NULL, - topic_poster INT4 DEFAULT '0' NOT NULL CHECK (topic_poster >= 0), - topic_time INT4 DEFAULT '0' NOT NULL CHECK (topic_time >= 0), - topic_time_limit INT4 DEFAULT '0' NOT NULL CHECK (topic_time_limit >= 0), - topic_views INT4 DEFAULT '0' NOT NULL CHECK (topic_views >= 0), - topic_posts_approved INT4 DEFAULT '0' NOT NULL CHECK (topic_posts_approved >= 0), - topic_posts_unapproved INT4 DEFAULT '0' NOT NULL CHECK (topic_posts_unapproved >= 0), - topic_posts_softdeleted INT4 DEFAULT '0' NOT NULL CHECK (topic_posts_softdeleted >= 0), - topic_status INT2 DEFAULT '0' NOT NULL, - topic_type INT2 DEFAULT '0' NOT NULL, - topic_first_post_id INT4 DEFAULT '0' NOT NULL CHECK (topic_first_post_id >= 0), - topic_first_poster_name varchar(255) DEFAULT '' NOT NULL, - topic_first_poster_colour varchar(6) DEFAULT '' NOT NULL, - topic_last_post_id INT4 DEFAULT '0' NOT NULL CHECK (topic_last_post_id >= 0), - topic_last_poster_id INT4 DEFAULT '0' NOT NULL CHECK (topic_last_poster_id >= 0), - topic_last_poster_name varchar(255) DEFAULT '' NOT NULL, - topic_last_poster_colour varchar(6) DEFAULT '' NOT NULL, - topic_last_post_subject varchar(255) DEFAULT '' NOT NULL, - topic_last_post_time INT4 DEFAULT '0' NOT NULL CHECK (topic_last_post_time >= 0), - topic_last_view_time INT4 DEFAULT '0' NOT NULL CHECK (topic_last_view_time >= 0), - topic_moved_id INT4 DEFAULT '0' NOT NULL CHECK (topic_moved_id >= 0), - topic_bumped INT2 DEFAULT '0' NOT NULL CHECK (topic_bumped >= 0), - topic_bumper INT4 DEFAULT '0' NOT NULL CHECK (topic_bumper >= 0), - poll_title varchar(255) DEFAULT '' NOT NULL, - poll_start INT4 DEFAULT '0' NOT NULL CHECK (poll_start >= 0), - poll_length INT4 DEFAULT '0' NOT NULL CHECK (poll_length >= 0), - poll_max_options INT2 DEFAULT '1' NOT NULL, - poll_last_vote INT4 DEFAULT '0' NOT NULL CHECK (poll_last_vote >= 0), - poll_vote_change INT2 DEFAULT '0' NOT NULL CHECK (poll_vote_change >= 0), - topic_delete_time INT4 DEFAULT '0' NOT NULL CHECK (topic_delete_time >= 0), - topic_delete_reason varchar(255) DEFAULT '' NOT NULL, - topic_delete_user INT4 DEFAULT '0' NOT NULL CHECK (topic_delete_user >= 0), - PRIMARY KEY (topic_id) -); - -CREATE INDEX phpbb_topics_forum_id ON phpbb_topics (forum_id); -CREATE INDEX phpbb_topics_forum_id_type ON phpbb_topics (forum_id, topic_type); -CREATE INDEX phpbb_topics_last_post_time ON phpbb_topics (topic_last_post_time); -CREATE INDEX phpbb_topics_topic_visibility ON phpbb_topics (topic_visibility); -CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics (forum_id, topic_visibility, topic_last_post_id); -CREATE INDEX phpbb_topics_fid_time_moved ON phpbb_topics (forum_id, topic_last_post_time, topic_moved_id); - -/* - Table: 'phpbb_topics_track' -*/ -CREATE TABLE phpbb_topics_track ( - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - topic_id INT4 DEFAULT '0' NOT NULL CHECK (topic_id >= 0), - forum_id INT4 DEFAULT '0' NOT NULL CHECK (forum_id >= 0), - mark_time INT4 DEFAULT '0' NOT NULL CHECK (mark_time >= 0), - PRIMARY KEY (user_id, topic_id) -); - -CREATE INDEX phpbb_topics_track_topic_id ON phpbb_topics_track (topic_id); -CREATE INDEX phpbb_topics_track_forum_id ON phpbb_topics_track (forum_id); - -/* - Table: 'phpbb_topics_posted' -*/ -CREATE TABLE phpbb_topics_posted ( - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - topic_id INT4 DEFAULT '0' NOT NULL CHECK (topic_id >= 0), - topic_posted INT2 DEFAULT '0' NOT NULL CHECK (topic_posted >= 0), - PRIMARY KEY (user_id, topic_id) -); - - -/* - Table: 'phpbb_topics_watch' -*/ -CREATE TABLE phpbb_topics_watch ( - topic_id INT4 DEFAULT '0' NOT NULL CHECK (topic_id >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - notify_status INT2 DEFAULT '0' NOT NULL CHECK (notify_status >= 0) -); - -CREATE INDEX phpbb_topics_watch_topic_id ON phpbb_topics_watch (topic_id); -CREATE INDEX phpbb_topics_watch_user_id ON phpbb_topics_watch (user_id); -CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch (notify_status); - -/* - Table: 'phpbb_user_notifications' -*/ -CREATE TABLE phpbb_user_notifications ( - item_type varchar(255) DEFAULT '' NOT NULL, - item_id INT4 DEFAULT '0' NOT NULL CHECK (item_id >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - method varchar(255) DEFAULT '' NOT NULL, - notify INT2 DEFAULT '1' NOT NULL CHECK (notify >= 0) -); - - -/* - Table: 'phpbb_user_group' -*/ -CREATE TABLE phpbb_user_group ( - group_id INT4 DEFAULT '0' NOT NULL CHECK (group_id >= 0), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - group_leader INT2 DEFAULT '0' NOT NULL CHECK (group_leader >= 0), - user_pending INT2 DEFAULT '1' NOT NULL CHECK (user_pending >= 0) -); - -CREATE INDEX phpbb_user_group_group_id ON phpbb_user_group (group_id); -CREATE INDEX phpbb_user_group_user_id ON phpbb_user_group (user_id); -CREATE INDEX phpbb_user_group_group_leader ON phpbb_user_group (group_leader); - -/* - Table: 'phpbb_users' -*/ -CREATE SEQUENCE phpbb_users_seq; - -CREATE TABLE phpbb_users ( - user_id INT4 DEFAULT nextval('phpbb_users_seq'), - user_type INT2 DEFAULT '0' NOT NULL, - group_id INT4 DEFAULT '3' NOT NULL CHECK (group_id >= 0), - user_permissions TEXT DEFAULT '' NOT NULL, - user_perm_from INT4 DEFAULT '0' NOT NULL CHECK (user_perm_from >= 0), - user_ip varchar(40) DEFAULT '' NOT NULL, - user_regdate INT4 DEFAULT '0' NOT NULL CHECK (user_regdate >= 0), - username varchar_ci DEFAULT '' NOT NULL, - username_clean varchar_ci DEFAULT '' NOT NULL, - user_password varchar(40) DEFAULT '' NOT NULL, - user_passchg INT4 DEFAULT '0' NOT NULL CHECK (user_passchg >= 0), - user_pass_convert INT2 DEFAULT '0' NOT NULL CHECK (user_pass_convert >= 0), - user_email varchar(100) DEFAULT '' NOT NULL, - user_email_hash INT8 DEFAULT '0' NOT NULL, - user_birthday varchar(10) DEFAULT '' NOT NULL, - user_lastvisit INT4 DEFAULT '0' NOT NULL CHECK (user_lastvisit >= 0), - user_lastmark INT4 DEFAULT '0' NOT NULL CHECK (user_lastmark >= 0), - user_lastpost_time INT4 DEFAULT '0' NOT NULL CHECK (user_lastpost_time >= 0), - user_lastpage varchar(200) DEFAULT '' NOT NULL, - user_last_confirm_key varchar(10) DEFAULT '' NOT NULL, - user_last_search INT4 DEFAULT '0' NOT NULL CHECK (user_last_search >= 0), - user_warnings INT2 DEFAULT '0' NOT NULL, - user_last_warning INT4 DEFAULT '0' NOT NULL CHECK (user_last_warning >= 0), - user_login_attempts INT2 DEFAULT '0' NOT NULL, - user_inactive_reason INT2 DEFAULT '0' NOT NULL, - user_inactive_time INT4 DEFAULT '0' NOT NULL CHECK (user_inactive_time >= 0), - user_posts INT4 DEFAULT '0' NOT NULL CHECK (user_posts >= 0), - user_lang varchar(30) DEFAULT '' NOT NULL, - user_timezone varchar(100) DEFAULT 'UTC' NOT NULL, - user_dateformat varchar(30) DEFAULT 'd M Y H:i' NOT NULL, - user_style INT4 DEFAULT '0' NOT NULL CHECK (user_style >= 0), - user_rank INT4 DEFAULT '0' NOT NULL CHECK (user_rank >= 0), - user_colour varchar(6) DEFAULT '' NOT NULL, - user_new_privmsg INT4 DEFAULT '0' NOT NULL, - user_unread_privmsg INT4 DEFAULT '0' NOT NULL, - user_last_privmsg INT4 DEFAULT '0' NOT NULL CHECK (user_last_privmsg >= 0), - user_message_rules INT2 DEFAULT '0' NOT NULL CHECK (user_message_rules >= 0), - user_full_folder INT4 DEFAULT '-3' NOT NULL, - user_emailtime INT4 DEFAULT '0' NOT NULL CHECK (user_emailtime >= 0), - user_topic_show_days INT2 DEFAULT '0' NOT NULL CHECK (user_topic_show_days >= 0), - user_topic_sortby_type varchar(1) DEFAULT 't' NOT NULL, - user_topic_sortby_dir varchar(1) DEFAULT 'd' NOT NULL, - user_post_show_days INT2 DEFAULT '0' NOT NULL CHECK (user_post_show_days >= 0), - user_post_sortby_type varchar(1) DEFAULT 't' NOT NULL, - user_post_sortby_dir varchar(1) DEFAULT 'a' NOT NULL, - user_notify INT2 DEFAULT '0' NOT NULL CHECK (user_notify >= 0), - user_notify_pm INT2 DEFAULT '1' NOT NULL CHECK (user_notify_pm >= 0), - user_notify_type INT2 DEFAULT '0' NOT NULL, - user_allow_pm INT2 DEFAULT '1' NOT NULL CHECK (user_allow_pm >= 0), - user_allow_viewonline INT2 DEFAULT '1' NOT NULL CHECK (user_allow_viewonline >= 0), - user_allow_viewemail INT2 DEFAULT '1' NOT NULL CHECK (user_allow_viewemail >= 0), - user_allow_massemail INT2 DEFAULT '1' NOT NULL CHECK (user_allow_massemail >= 0), - user_options INT4 DEFAULT '230271' NOT NULL CHECK (user_options >= 0), - user_avatar varchar(255) DEFAULT '' NOT NULL, - user_avatar_type varchar(255) DEFAULT '' NOT NULL, - user_avatar_width INT2 DEFAULT '0' NOT NULL CHECK (user_avatar_width >= 0), - user_avatar_height INT2 DEFAULT '0' NOT NULL CHECK (user_avatar_height >= 0), - user_sig TEXT DEFAULT '' NOT NULL, - user_sig_bbcode_uid varchar(8) DEFAULT '' NOT NULL, - user_sig_bbcode_bitfield varchar(255) DEFAULT '' NOT NULL, - user_from varchar(100) DEFAULT '' NOT NULL, - user_icq varchar(15) DEFAULT '' NOT NULL, - user_aim varchar(255) DEFAULT '' NOT NULL, - user_yim varchar(255) DEFAULT '' NOT NULL, - user_msnm varchar(255) DEFAULT '' NOT NULL, - user_jabber varchar(255) DEFAULT '' NOT NULL, - user_website varchar(200) DEFAULT '' NOT NULL, - user_occ varchar(4000) DEFAULT '' NOT NULL, - user_interests varchar(4000) DEFAULT '' NOT NULL, - user_actkey varchar(32) DEFAULT '' NOT NULL, - user_newpasswd varchar(40) DEFAULT '' NOT NULL, - user_form_salt varchar(32) DEFAULT '' NOT NULL, - user_new INT2 DEFAULT '1' NOT NULL CHECK (user_new >= 0), - user_reminded INT2 DEFAULT '0' NOT NULL, - user_reminded_time INT4 DEFAULT '0' NOT NULL CHECK (user_reminded_time >= 0), - PRIMARY KEY (user_id) -); - -CREATE INDEX phpbb_users_user_birthday ON phpbb_users (user_birthday); -CREATE INDEX phpbb_users_user_email_hash ON phpbb_users (user_email_hash); -CREATE INDEX phpbb_users_user_type ON phpbb_users (user_type); -CREATE UNIQUE INDEX phpbb_users_username_clean ON phpbb_users (username_clean); - -/* - Table: 'phpbb_warnings' -*/ -CREATE SEQUENCE phpbb_warnings_seq; - -CREATE TABLE phpbb_warnings ( - warning_id INT4 DEFAULT nextval('phpbb_warnings_seq'), - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - post_id INT4 DEFAULT '0' NOT NULL CHECK (post_id >= 0), - log_id INT4 DEFAULT '0' NOT NULL CHECK (log_id >= 0), - warning_time INT4 DEFAULT '0' NOT NULL CHECK (warning_time >= 0), - PRIMARY KEY (warning_id) -); - - -/* - Table: 'phpbb_words' -*/ -CREATE SEQUENCE phpbb_words_seq; - -CREATE TABLE phpbb_words ( - word_id INT4 DEFAULT nextval('phpbb_words_seq'), - word varchar(255) DEFAULT '' NOT NULL, - replacement varchar(255) DEFAULT '' NOT NULL, - PRIMARY KEY (word_id) -); - - -/* - Table: 'phpbb_zebra' -*/ -CREATE TABLE phpbb_zebra ( - user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), - zebra_id INT4 DEFAULT '0' NOT NULL CHECK (zebra_id >= 0), - friend INT2 DEFAULT '0' NOT NULL CHECK (friend >= 0), - foe INT2 DEFAULT '0' NOT NULL CHECK (foe >= 0), - PRIMARY KEY (user_id, zebra_id) -); - - +COMMIT; -COMMIT;
\ No newline at end of file diff --git a/phpBB/install/schemas/schema.json b/phpBB/install/schemas/schema.json new file mode 100644 index 0000000000..176691f1a6 --- /dev/null +++ b/phpBB/install/schemas/schema.json @@ -0,0 +1,3340 @@ +{ + "phpbb_acl_groups": { + "COLUMNS": { + "group_id": [ + "UINT", + 0 + ], + "forum_id": [ + "UINT", + 0 + ], + "auth_option_id": [ + "UINT", + 0 + ], + "auth_role_id": [ + "UINT", + 0 + ], + "auth_setting": [ + "TINT:2", + 0 + ] + }, + "KEYS": { + "group_id": [ + "INDEX", + "group_id" + ], + "auth_opt_id": [ + "INDEX", + "auth_option_id" + ], + "auth_role_id": [ + "INDEX", + "auth_role_id" + ] + } + }, + "phpbb_acl_options": { + "COLUMNS": { + "auth_option_id": [ + "UINT", + null, + "auto_increment" + ], + "auth_option": [ + "VCHAR:50", + "" + ], + "is_global": [ + "BOOL", + 0 + ], + "is_local": [ + "BOOL", + 0 + ], + "founder_only": [ + "BOOL", + 0 + ] + }, + "PRIMARY_KEY": "auth_option_id", + "KEYS": { + "auth_option": [ + "UNIQUE", + [ + "auth_option" + ] + ] + } + }, + "phpbb_acl_roles": { + "COLUMNS": { + "role_id": [ + "UINT", + null, + "auto_increment" + ], + "role_name": [ + "VCHAR_UNI", + "" + ], + "role_description": [ + "TEXT_UNI", + "" + ], + "role_type": [ + "VCHAR:10", + "" + ], + "role_order": [ + "USINT", + 0 + ] + }, + "PRIMARY_KEY": "role_id", + "KEYS": { + "role_type": [ + "INDEX", + "role_type" + ], + "role_order": [ + "INDEX", + "role_order" + ] + } + }, + "phpbb_acl_roles_data": { + "COLUMNS": { + "role_id": [ + "UINT", + 0 + ], + "auth_option_id": [ + "UINT", + 0 + ], + "auth_setting": [ + "TINT:2", + 0 + ] + }, + "PRIMARY_KEY": [ + "role_id", + "auth_option_id" + ], + "KEYS": { + "ath_op_id": [ + "INDEX", + "auth_option_id" + ] + } + }, + "phpbb_acl_users": { + "COLUMNS": { + "user_id": [ + "UINT", + 0 + ], + "forum_id": [ + "UINT", + 0 + ], + "auth_option_id": [ + "UINT", + 0 + ], + "auth_role_id": [ + "UINT", + 0 + ], + "auth_setting": [ + "TINT:2", + 0 + ] + }, + "KEYS": { + "user_id": [ + "INDEX", + "user_id" + ], + "auth_option_id": [ + "INDEX", + "auth_option_id" + ], + "auth_role_id": [ + "INDEX", + "auth_role_id" + ] + } + }, + "phpbb_attachments": { + "COLUMNS": { + "attach_id": [ + "UINT", + null, + "auto_increment" + ], + "post_msg_id": [ + "UINT", + 0 + ], + "topic_id": [ + "UINT", + 0 + ], + "in_message": [ + "BOOL", + 0 + ], + "poster_id": [ + "UINT", + 0 + ], + "is_orphan": [ + "BOOL", + 1 + ], + "physical_filename": [ + "VCHAR", + "" + ], + "real_filename": [ + "VCHAR", + "" + ], + "download_count": [ + "UINT", + 0 + ], + "attach_comment": [ + "TEXT_UNI", + "" + ], + "extension": [ + "VCHAR:100", + "" + ], + "mimetype": [ + "VCHAR:100", + "" + ], + "filesize": [ + "UINT:20", + 0 + ], + "filetime": [ + "TIMESTAMP", + 0 + ], + "thumbnail": [ + "BOOL", + 0 + ] + }, + "PRIMARY_KEY": "attach_id", + "KEYS": { + "filetime": [ + "INDEX", + "filetime" + ], + "post_msg_id": [ + "INDEX", + "post_msg_id" + ], + "topic_id": [ + "INDEX", + "topic_id" + ], + "poster_id": [ + "INDEX", + "poster_id" + ], + "is_orphan": [ + "INDEX", + "is_orphan" + ] + } + }, + "phpbb_banlist": { + "COLUMNS": { + "ban_id": [ + "UINT", + null, + "auto_increment" + ], + "ban_userid": [ + "UINT", + 0 + ], + "ban_ip": [ + "VCHAR:40", + "" + ], + "ban_email": [ + "VCHAR_UNI:100", + "" + ], + "ban_start": [ + "TIMESTAMP", + 0 + ], + "ban_end": [ + "TIMESTAMP", + 0 + ], + "ban_exclude": [ + "BOOL", + 0 + ], + "ban_reason": [ + "VCHAR_UNI", + "" + ], + "ban_give_reason": [ + "VCHAR_UNI", + "" + ] + }, + "PRIMARY_KEY": "ban_id", + "KEYS": { + "ban_end": [ + "INDEX", + "ban_end" + ], + "ban_user": [ + "INDEX", + [ + "ban_userid", + "ban_exclude" + ] + ], + "ban_email": [ + "INDEX", + [ + "ban_email", + "ban_exclude" + ] + ], + "ban_ip": [ + "INDEX", + [ + "ban_ip", + "ban_exclude" + ] + ] + } + }, + "phpbb_bbcodes": { + "COLUMNS": { + "bbcode_id": [ + "USINT", + 0 + ], + "bbcode_tag": [ + "VCHAR:16", + "" + ], + "bbcode_helpline": [ + "VCHAR_UNI", + "" + ], + "display_on_posting": [ + "BOOL", + 0 + ], + "bbcode_match": [ + "TEXT_UNI", + "" + ], + "bbcode_tpl": [ + "MTEXT_UNI", + "" + ], + "first_pass_match": [ + "MTEXT_UNI", + "" + ], + "first_pass_replace": [ + "MTEXT_UNI", + "" + ], + "second_pass_match": [ + "MTEXT_UNI", + "" + ], + "second_pass_replace": [ + "MTEXT_UNI", + "" + ] + }, + "PRIMARY_KEY": "bbcode_id", + "KEYS": { + "display_on_post": [ + "INDEX", + "display_on_posting" + ] + } + }, + "phpbb_bookmarks": { + "COLUMNS": { + "topic_id": [ + "UINT", + 0 + ], + "user_id": [ + "UINT", + 0 + ] + }, + "PRIMARY_KEY": [ + "topic_id", + "user_id" + ] + }, + "phpbb_bots": { + "COLUMNS": { + "bot_id": [ + "UINT", + null, + "auto_increment" + ], + "bot_active": [ + "BOOL", + 1 + ], + "bot_name": [ + "STEXT_UNI", + "" + ], + "user_id": [ + "UINT", + 0 + ], + "bot_agent": [ + "VCHAR", + "" + ], + "bot_ip": [ + "VCHAR", + "" + ] + }, + "PRIMARY_KEY": "bot_id", + "KEYS": { + "bot_active": [ + "INDEX", + "bot_active" + ] + } + }, + "phpbb_config": { + "COLUMNS": { + "config_name": [ + "VCHAR", + "" + ], + "config_value": [ + "VCHAR_UNI", + "" + ], + "is_dynamic": [ + "BOOL", + 0 + ] + }, + "PRIMARY_KEY": "config_name", + "KEYS": { + "is_dynamic": [ + "INDEX", + "is_dynamic" + ] + } + }, + "phpbb_config_text": { + "COLUMNS": { + "config_name": [ + "VCHAR", + "" + ], + "config_value": [ + "MTEXT", + "" + ] + }, + "PRIMARY_KEY": "config_name" + }, + "phpbb_confirm": { + "COLUMNS": { + "confirm_id": [ + "CHAR:32", + "" + ], + "session_id": [ + "CHAR:32", + "" + ], + "confirm_type": [ + "TINT:3", + 0 + ], + "code": [ + "VCHAR:8", + "" + ], + "seed": [ + "UINT:10", + 0 + ], + "attempts": [ + "UINT", + 0 + ] + }, + "PRIMARY_KEY": [ + "session_id", + "confirm_id" + ], + "KEYS": { + "confirm_type": [ + "INDEX", + "confirm_type" + ] + } + }, + "phpbb_disallow": { + "COLUMNS": { + "disallow_id": [ + "UINT", + null, + "auto_increment" + ], + "disallow_username": [ + "VCHAR_UNI:255", + "" + ] + }, + "PRIMARY_KEY": "disallow_id" + }, + "phpbb_drafts": { + "COLUMNS": { + "draft_id": [ + "UINT", + null, + "auto_increment" + ], + "user_id": [ + "UINT", + 0 + ], + "topic_id": [ + "UINT", + 0 + ], + "forum_id": [ + "UINT", + 0 + ], + "save_time": [ + "TIMESTAMP", + 0 + ], + "draft_subject": [ + "STEXT_UNI", + "" + ], + "draft_message": [ + "MTEXT_UNI", + "" + ] + }, + "PRIMARY_KEY": "draft_id", + "KEYS": { + "save_time": [ + "INDEX", + "save_time" + ] + } + }, + "phpbb_ext": { + "COLUMNS": { + "ext_name": [ + "VCHAR", + "" + ], + "ext_active": [ + "BOOL", + 0 + ], + "ext_state": [ + "TEXT", + "" + ] + }, + "KEYS": { + "ext_name": [ + "UNIQUE", + "ext_name" + ] + } + }, + "phpbb_extension_groups": { + "COLUMNS": { + "group_id": [ + "UINT", + null, + "auto_increment" + ], + "group_name": [ + "VCHAR_UNI", + "" + ], + "cat_id": [ + "TINT:2", + 0 + ], + "allow_group": [ + "BOOL", + 0 + ], + "download_mode": [ + "BOOL", + 1 + ], + "upload_icon": [ + "VCHAR", + "" + ], + "max_filesize": [ + "UINT:20", + 0 + ], + "allowed_forums": [ + "TEXT", + "" + ], + "allow_in_pm": [ + "BOOL", + 0 + ] + }, + "PRIMARY_KEY": "group_id" + }, + "phpbb_extensions": { + "COLUMNS": { + "extension_id": [ + "UINT", + null, + "auto_increment" + ], + "group_id": [ + "UINT", + 0 + ], + "extension": [ + "VCHAR:100", + "" + ] + }, + "PRIMARY_KEY": "extension_id" + }, + "phpbb_forums": { + "COLUMNS": { + "forum_id": [ + "UINT", + null, + "auto_increment" + ], + "parent_id": [ + "UINT", + 0 + ], + "left_id": [ + "UINT", + 0 + ], + "right_id": [ + "UINT", + 0 + ], + "forum_parents": [ + "MTEXT", + "" + ], + "forum_name": [ + "STEXT_UNI", + "" + ], + "forum_desc": [ + "TEXT_UNI", + "" + ], + "forum_desc_bitfield": [ + "VCHAR:255", + "" + ], + "forum_desc_options": [ + "UINT:11", + 7 + ], + "forum_desc_uid": [ + "VCHAR:8", + "" + ], + "forum_link": [ + "VCHAR_UNI", + "" + ], + "forum_password": [ + "VCHAR:255", + "" + ], + "forum_style": [ + "UINT", + 0 + ], + "forum_image": [ + "VCHAR", + "" + ], + "forum_rules": [ + "TEXT_UNI", + "" + ], + "forum_rules_link": [ + "VCHAR_UNI", + "" + ], + "forum_rules_bitfield": [ + "VCHAR:255", + "" + ], + "forum_rules_options": [ + "UINT:11", + 7 + ], + "forum_rules_uid": [ + "VCHAR:8", + "" + ], + "forum_topics_per_page": [ + "TINT:4", + 0 + ], + "forum_type": [ + "TINT:4", + 0 + ], + "forum_status": [ + "TINT:4", + 0 + ], + "forum_last_post_id": [ + "UINT", + 0 + ], + "forum_last_poster_id": [ + "UINT", + 0 + ], + "forum_last_post_subject": [ + "STEXT_UNI", + "" + ], + "forum_last_post_time": [ + "TIMESTAMP", + 0 + ], + "forum_last_poster_name": [ + "VCHAR_UNI", + "" + ], + "forum_last_poster_colour": [ + "VCHAR:6", + "" + ], + "forum_flags": [ + "TINT:4", + 32 + ], + "display_on_index": [ + "BOOL", + 1 + ], + "enable_indexing": [ + "BOOL", + 1 + ], + "enable_icons": [ + "BOOL", + 1 + ], + "enable_prune": [ + "BOOL", + 0 + ], + "prune_next": [ + "TIMESTAMP", + 0 + ], + "prune_days": [ + "UINT", + 0 + ], + "prune_viewed": [ + "UINT", + 0 + ], + "prune_freq": [ + "UINT", + 0 + ], + "display_subforum_list": [ + "BOOL", + 1 + ], + "forum_options": [ + "UINT:20", + 0 + ], + "enable_shadow_prune": [ + "BOOL", + 0 + ], + "prune_shadow_days": [ + "UINT", + 7 + ], + "prune_shadow_freq": [ + "UINT", + 1 + ], + "prune_shadow_next": [ + "INT:11", + 0 + ], + "forum_posts_approved": [ + "UINT", + 0 + ], + "forum_posts_unapproved": [ + "UINT", + 0 + ], + "forum_posts_softdeleted": [ + "UINT", + 0 + ], + "forum_topics_approved": [ + "UINT", + 0 + ], + "forum_topics_unapproved": [ + "UINT", + 0 + ], + "forum_topics_softdeleted": [ + "UINT", + 0 + ] + }, + "PRIMARY_KEY": "forum_id", + "KEYS": { + "left_right_id": [ + "INDEX", + [ + "left_id", + "right_id" + ] + ], + "forum_lastpost_id": [ + "INDEX", + "forum_last_post_id" + ] + } + }, + "phpbb_forums_access": { + "COLUMNS": { + "forum_id": [ + "UINT", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "session_id": [ + "CHAR:32", + "" + ] + }, + "PRIMARY_KEY": [ + "forum_id", + "user_id", + "session_id" + ] + }, + "phpbb_forums_track": { + "COLUMNS": { + "user_id": [ + "UINT", + 0 + ], + "forum_id": [ + "UINT", + 0 + ], + "mark_time": [ + "TIMESTAMP", + 0 + ] + }, + "PRIMARY_KEY": [ + "user_id", + "forum_id" + ] + }, + "phpbb_forums_watch": { + "COLUMNS": { + "forum_id": [ + "UINT", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "notify_status": [ + "BOOL", + 0 + ] + }, + "KEYS": { + "forum_id": [ + "INDEX", + "forum_id" + ], + "user_id": [ + "INDEX", + "user_id" + ], + "notify_stat": [ + "INDEX", + "notify_status" + ] + } + }, + "phpbb_groups": { + "COLUMNS": { + "group_id": [ + "UINT", + null, + "auto_increment" + ], + "group_type": [ + "TINT:4", + 1 + ], + "group_founder_manage": [ + "BOOL", + 0 + ], + "group_name": [ + "VCHAR_CI", + "" + ], + "group_desc": [ + "TEXT_UNI", + "" + ], + "group_desc_bitfield": [ + "VCHAR:255", + "" + ], + "group_desc_options": [ + "UINT:11", + 7 + ], + "group_desc_uid": [ + "VCHAR:8", + "" + ], + "group_display": [ + "BOOL", + 0 + ], + "group_avatar": [ + "VCHAR", + "" + ], + "group_avatar_type": [ + "VCHAR:255", + "" + ], + "group_avatar_width": [ + "USINT", + 0 + ], + "group_avatar_height": [ + "USINT", + 0 + ], + "group_rank": [ + "UINT", + 0 + ], + "group_colour": [ + "VCHAR:6", + "" + ], + "group_sig_chars": [ + "UINT", + 0 + ], + "group_receive_pm": [ + "BOOL", + 0 + ], + "group_message_limit": [ + "UINT", + 0 + ], + "group_legend": [ + "UINT", + 0 + ], + "group_max_recipients": [ + "UINT", + 0 + ], + "group_skip_auth": { + "0": "BOOL", + "1": 0, + "after": "group_founder_manage" + } + }, + "PRIMARY_KEY": "group_id", + "KEYS": { + "group_legend_name": [ + "INDEX", + [ + "group_legend", + "group_name" + ] + ] + } + }, + "phpbb_icons": { + "COLUMNS": { + "icons_id": [ + "UINT", + null, + "auto_increment" + ], + "icons_url": [ + "VCHAR", + "" + ], + "icons_width": [ + "TINT:4", + 0 + ], + "icons_height": [ + "TINT:4", + 0 + ], + "icons_order": [ + "UINT", + 0 + ], + "display_on_posting": [ + "BOOL", + 1 + ] + }, + "PRIMARY_KEY": "icons_id", + "KEYS": { + "display_on_posting": [ + "INDEX", + "display_on_posting" + ] + } + }, + "phpbb_lang": { + "COLUMNS": { + "lang_id": [ + "TINT:4", + null, + "auto_increment" + ], + "lang_iso": [ + "VCHAR:30", + "" + ], + "lang_dir": [ + "VCHAR:30", + "" + ], + "lang_english_name": [ + "VCHAR_UNI:100", + "" + ], + "lang_local_name": [ + "VCHAR_UNI:255", + "" + ], + "lang_author": [ + "VCHAR_UNI:255", + "" + ] + }, + "PRIMARY_KEY": "lang_id", + "KEYS": { + "lang_iso": [ + "INDEX", + "lang_iso" + ] + } + }, + "phpbb_log": { + "COLUMNS": { + "log_id": [ + "UINT", + null, + "auto_increment" + ], + "log_type": [ + "TINT:4", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "forum_id": [ + "UINT", + 0 + ], + "topic_id": [ + "UINT", + 0 + ], + "reportee_id": [ + "UINT", + 0 + ], + "log_ip": [ + "VCHAR:40", + "" + ], + "log_time": [ + "TIMESTAMP", + 0 + ], + "log_operation": [ + "TEXT_UNI", + "" + ], + "log_data": [ + "MTEXT_UNI", + "" + ] + }, + "PRIMARY_KEY": "log_id", + "KEYS": { + "log_type": [ + "INDEX", + "log_type" + ], + "forum_id": [ + "INDEX", + "forum_id" + ], + "topic_id": [ + "INDEX", + "topic_id" + ], + "reportee_id": [ + "INDEX", + "reportee_id" + ], + "user_id": [ + "INDEX", + "user_id" + ] + } + }, + "phpbb_login_attempts": { + "COLUMNS": { + "attempt_ip": [ + "VCHAR:40", + "" + ], + "attempt_browser": [ + "VCHAR:150", + "" + ], + "attempt_forwarded_for": [ + "VCHAR:255", + "" + ], + "attempt_time": [ + "TIMESTAMP", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "username": [ + "VCHAR_UNI:255", + 0 + ], + "username_clean": [ + "VCHAR_CI", + 0 + ] + }, + "KEYS": { + "att_ip": [ + "INDEX", + [ + "attempt_ip", + "attempt_time" + ] + ], + "att_for": [ + "INDEX", + [ + "attempt_forwarded_for", + "attempt_time" + ] + ], + "att_time": [ + "INDEX", + [ + "attempt_time" + ] + ], + "user_id": [ + "INDEX", + "user_id" + ] + } + }, + "phpbb_migrations": { + "COLUMNS": { + "migration_name": [ + "VCHAR", + "" + ], + "migration_depends_on": [ + "TEXT", + "" + ], + "migration_schema_done": [ + "BOOL", + 0 + ], + "migration_data_done": [ + "BOOL", + 0 + ], + "migration_data_state": [ + "TEXT", + "" + ], + "migration_start_time": [ + "TIMESTAMP", + 0 + ], + "migration_end_time": [ + "TIMESTAMP", + 0 + ] + }, + "PRIMARY_KEY": "migration_name" + }, + "phpbb_moderator_cache": { + "COLUMNS": { + "forum_id": [ + "UINT", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "username": [ + "VCHAR_UNI:255", + "" + ], + "group_id": [ + "UINT", + 0 + ], + "group_name": [ + "VCHAR_UNI", + "" + ], + "display_on_index": [ + "BOOL", + 1 + ] + }, + "KEYS": { + "disp_idx": [ + "INDEX", + "display_on_index" + ], + "forum_id": [ + "INDEX", + "forum_id" + ] + } + }, + "phpbb_modules": { + "COLUMNS": { + "module_id": [ + "UINT", + null, + "auto_increment" + ], + "module_enabled": [ + "BOOL", + 1 + ], + "module_display": [ + "BOOL", + 1 + ], + "module_basename": [ + "VCHAR", + "" + ], + "module_class": [ + "VCHAR:10", + "" + ], + "parent_id": [ + "UINT", + 0 + ], + "left_id": [ + "UINT", + 0 + ], + "right_id": [ + "UINT", + 0 + ], + "module_langname": [ + "VCHAR", + "" + ], + "module_mode": [ + "VCHAR", + "" + ], + "module_auth": [ + "VCHAR", + "" + ] + }, + "PRIMARY_KEY": "module_id", + "KEYS": { + "left_right_id": [ + "INDEX", + [ + "left_id", + "right_id" + ] + ], + "module_enabled": [ + "INDEX", + "module_enabled" + ], + "class_left_id": [ + "INDEX", + [ + "module_class", + "left_id" + ] + ] + } + }, + "phpbb_notification_types": { + "COLUMNS": { + "notification_type_id": [ + "USINT", + null, + "auto_increment" + ], + "notification_type_name": [ + "VCHAR:255", + "" + ], + "notification_type_enabled": [ + "BOOL", + 1 + ] + }, + "PRIMARY_KEY": [ + "notification_type_id" + ], + "KEYS": { + "type": [ + "UNIQUE", + [ + "notification_type_name" + ] + ] + } + }, + "phpbb_notifications": { + "COLUMNS": { + "notification_id": [ + "UINT:10", + null, + "auto_increment" + ], + "notification_type_id": [ + "USINT", + 0 + ], + "item_id": [ + "UINT", + 0 + ], + "item_parent_id": [ + "UINT", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "notification_read": [ + "BOOL", + 0 + ], + "notification_time": [ + "TIMESTAMP", + 1 + ], + "notification_data": [ + "TEXT_UNI", + "" + ] + }, + "PRIMARY_KEY": "notification_id", + "KEYS": { + "item_ident": [ + "INDEX", + [ + "notification_type_id", + "item_id" + ] + ], + "user": [ + "INDEX", + [ + "user_id", + "notification_read" + ] + ] + } + }, + "phpbb_oauth_accounts": { + "COLUMNS": { + "user_id": [ + "UINT", + 0 + ], + "provider": [ + "VCHAR", + "" + ], + "oauth_provider_id": [ + "TEXT_UNI", + "" + ] + }, + "PRIMARY_KEY": [ + "user_id", + "provider" + ] + }, + "phpbb_oauth_tokens": { + "COLUMNS": { + "user_id": [ + "UINT", + 0 + ], + "session_id": [ + "CHAR:32", + "" + ], + "provider": [ + "VCHAR", + "" + ], + "oauth_token": [ + "MTEXT", + "" + ] + }, + "KEYS": { + "user_id": [ + "INDEX", + "user_id" + ], + "provider": [ + "INDEX", + "provider" + ] + } + }, + "phpbb_poll_options": { + "COLUMNS": { + "poll_option_id": [ + "TINT:4", + 0 + ], + "topic_id": [ + "UINT", + 0 + ], + "poll_option_text": [ + "TEXT_UNI", + "" + ], + "poll_option_total": [ + "UINT", + 0 + ] + }, + "KEYS": { + "poll_opt_id": [ + "INDEX", + "poll_option_id" + ], + "topic_id": [ + "INDEX", + "topic_id" + ] + } + }, + "phpbb_poll_votes": { + "COLUMNS": { + "topic_id": [ + "UINT", + 0 + ], + "poll_option_id": [ + "TINT:4", + 0 + ], + "vote_user_id": [ + "UINT", + 0 + ], + "vote_user_ip": [ + "VCHAR:40", + "" + ] + }, + "KEYS": { + "topic_id": [ + "INDEX", + "topic_id" + ], + "vote_user_id": [ + "INDEX", + "vote_user_id" + ], + "vote_user_ip": [ + "INDEX", + "vote_user_ip" + ] + } + }, + "phpbb_posts": { + "COLUMNS": { + "post_id": [ + "UINT", + null, + "auto_increment" + ], + "topic_id": [ + "UINT", + 0 + ], + "forum_id": [ + "UINT", + 0 + ], + "poster_id": [ + "UINT", + 0 + ], + "icon_id": [ + "UINT", + 0 + ], + "poster_ip": [ + "VCHAR:40", + "" + ], + "post_time": [ + "TIMESTAMP", + 0 + ], + "post_reported": [ + "BOOL", + 0 + ], + "enable_bbcode": [ + "BOOL", + 1 + ], + "enable_smilies": [ + "BOOL", + 1 + ], + "enable_magic_url": [ + "BOOL", + 1 + ], + "enable_sig": [ + "BOOL", + 1 + ], + "post_username": [ + "VCHAR_UNI:255", + "" + ], + "post_subject": [ + "STEXT_UNI", + "", + "true_sort" + ], + "post_text": [ + "MTEXT_UNI", + "" + ], + "post_checksum": [ + "VCHAR:32", + "" + ], + "post_attachment": [ + "BOOL", + 0 + ], + "bbcode_bitfield": [ + "VCHAR:255", + "" + ], + "bbcode_uid": [ + "VCHAR:8", + "" + ], + "post_postcount": [ + "BOOL", + 1 + ], + "post_edit_time": [ + "TIMESTAMP", + 0 + ], + "post_edit_reason": [ + "STEXT_UNI", + "" + ], + "post_edit_user": [ + "UINT", + 0 + ], + "post_edit_count": [ + "USINT", + 0 + ], + "post_edit_locked": [ + "BOOL", + 0 + ], + "post_visibility": [ + "TINT:3", + 0 + ], + "post_delete_time": [ + "TIMESTAMP", + 0 + ], + "post_delete_reason": [ + "STEXT_UNI", + "" + ], + "post_delete_user": [ + "UINT", + 0 + ] + }, + "PRIMARY_KEY": "post_id", + "KEYS": { + "forum_id": [ + "INDEX", + "forum_id" + ], + "topic_id": [ + "INDEX", + "topic_id" + ], + "poster_ip": [ + "INDEX", + "poster_ip" + ], + "poster_id": [ + "INDEX", + "poster_id" + ], + "tid_post_time": [ + "INDEX", + [ + "topic_id", + "post_time" + ] + ], + "post_username": [ + "INDEX", + [ + "post_username:255" + ] + ], + "post_visibility": [ + "INDEX", + [ + "post_visibility" + ] + ] + } + }, + "phpbb_privmsgs": { + "COLUMNS": { + "msg_id": [ + "UINT", + null, + "auto_increment" + ], + "root_level": [ + "UINT", + 0 + ], + "author_id": [ + "UINT", + 0 + ], + "icon_id": [ + "UINT", + 0 + ], + "author_ip": [ + "VCHAR:40", + "" + ], + "message_time": [ + "TIMESTAMP", + 0 + ], + "enable_bbcode": [ + "BOOL", + 1 + ], + "enable_smilies": [ + "BOOL", + 1 + ], + "enable_magic_url": [ + "BOOL", + 1 + ], + "enable_sig": [ + "BOOL", + 1 + ], + "message_subject": [ + "STEXT_UNI", + "" + ], + "message_text": [ + "MTEXT_UNI", + "" + ], + "message_edit_reason": [ + "STEXT_UNI", + "" + ], + "message_edit_user": [ + "UINT", + 0 + ], + "message_attachment": [ + "BOOL", + 0 + ], + "bbcode_bitfield": [ + "VCHAR:255", + "" + ], + "bbcode_uid": [ + "VCHAR:8", + "" + ], + "message_edit_time": [ + "TIMESTAMP", + 0 + ], + "message_edit_count": [ + "USINT", + 0 + ], + "to_address": [ + "TEXT_UNI", + "" + ], + "bcc_address": [ + "TEXT_UNI", + "" + ], + "message_reported": [ + "BOOL", + 0 + ] + }, + "PRIMARY_KEY": "msg_id", + "KEYS": { + "author_ip": [ + "INDEX", + "author_ip" + ], + "message_time": [ + "INDEX", + "message_time" + ], + "author_id": [ + "INDEX", + "author_id" + ], + "root_level": [ + "INDEX", + "root_level" + ] + } + }, + "phpbb_privmsgs_folder": { + "COLUMNS": { + "folder_id": [ + "UINT", + null, + "auto_increment" + ], + "user_id": [ + "UINT", + 0 + ], + "folder_name": [ + "VCHAR_UNI", + "" + ], + "pm_count": [ + "UINT", + 0 + ] + }, + "PRIMARY_KEY": "folder_id", + "KEYS": { + "user_id": [ + "INDEX", + "user_id" + ] + } + }, + "phpbb_privmsgs_rules": { + "COLUMNS": { + "rule_id": [ + "UINT", + null, + "auto_increment" + ], + "user_id": [ + "UINT", + 0 + ], + "rule_check": [ + "UINT", + 0 + ], + "rule_connection": [ + "UINT", + 0 + ], + "rule_string": [ + "VCHAR_UNI", + "" + ], + "rule_user_id": [ + "UINT", + 0 + ], + "rule_group_id": [ + "UINT", + 0 + ], + "rule_action": [ + "UINT", + 0 + ], + "rule_folder_id": [ + "INT:11", + 0 + ] + }, + "PRIMARY_KEY": "rule_id", + "KEYS": { + "user_id": [ + "INDEX", + "user_id" + ] + } + }, + "phpbb_privmsgs_to": { + "COLUMNS": { + "msg_id": [ + "UINT", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "author_id": [ + "UINT", + 0 + ], + "pm_deleted": [ + "BOOL", + 0 + ], + "pm_new": [ + "BOOL", + 1 + ], + "pm_unread": [ + "BOOL", + 1 + ], + "pm_replied": [ + "BOOL", + 0 + ], + "pm_marked": [ + "BOOL", + 0 + ], + "pm_forwarded": [ + "BOOL", + 0 + ], + "folder_id": [ + "INT:11", + 0 + ] + }, + "KEYS": { + "msg_id": [ + "INDEX", + "msg_id" + ], + "author_id": [ + "INDEX", + "author_id" + ], + "usr_flder_id": [ + "INDEX", + [ + "user_id", + "folder_id" + ] + ] + } + }, + "phpbb_profile_fields": { + "COLUMNS": { + "field_id": [ + "UINT", + null, + "auto_increment" + ], + "field_name": [ + "VCHAR_UNI", + "" + ], + "field_type": [ + "VCHAR:100", + "" + ], + "field_ident": [ + "VCHAR:20", + "" + ], + "field_length": [ + "VCHAR:20", + "" + ], + "field_minlen": [ + "VCHAR", + "" + ], + "field_maxlen": [ + "VCHAR", + "" + ], + "field_novalue": [ + "VCHAR_UNI", + "" + ], + "field_default_value": [ + "VCHAR_UNI", + "" + ], + "field_validation": [ + "VCHAR_UNI:20", + "" + ], + "field_required": [ + "BOOL", + 0 + ], + "field_show_on_reg": [ + "BOOL", + 0 + ], + "field_hide": [ + "BOOL", + 0 + ], + "field_no_view": [ + "BOOL", + 0 + ], + "field_active": [ + "BOOL", + 0 + ], + "field_order": [ + "UINT", + 0 + ], + "field_show_profile": [ + "BOOL", + 0 + ], + "field_show_on_vt": [ + "BOOL", + 0 + ], + "field_show_novalue": [ + "BOOL", + 0 + ], + "field_show_on_pm": [ + "BOOL", + 0 + ], + "field_show_on_ml": [ + "BOOL", + 0 + ], + "field_is_contact": [ + "BOOL", + 0 + ], + "field_contact_desc": [ + "VCHAR", + "" + ], + "field_contact_url": [ + "VCHAR", + "" + ] + }, + "PRIMARY_KEY": "field_id", + "KEYS": { + "fld_type": [ + "INDEX", + "field_type" + ], + "fld_ordr": [ + "INDEX", + "field_order" + ] + } + }, + "phpbb_profile_fields_data": { + "COLUMNS": { + "user_id": [ + "UINT", + 0 + ], + "pf_phpbb_interests": [ + "MTEXT", + "" + ], + "pf_phpbb_occupation": [ + "MTEXT", + "" + ], + "pf_phpbb_icq": [ + "VCHAR", + "" + ], + "pf_phpbb_location": [ + "VCHAR", + "" + ], + "pf_phpbb_website": [ + "VCHAR", + "" + ], + "pf_phpbb_wlm": [ + "VCHAR", + "" + ], + "pf_phpbb_yahoo": [ + "VCHAR", + "" + ], + "pf_phpbb_aol": [ + "VCHAR", + "" + ] + }, + "PRIMARY_KEY": "user_id" + }, + "phpbb_profile_fields_lang": { + "COLUMNS": { + "field_id": [ + "UINT", + 0 + ], + "lang_id": [ + "UINT", + 0 + ], + "option_id": [ + "UINT", + 0 + ], + "field_type": [ + "VCHAR:100", + "" + ], + "lang_value": [ + "VCHAR_UNI", + "" + ] + }, + "PRIMARY_KEY": [ + "field_id", + "lang_id", + "option_id" + ] + }, + "phpbb_profile_lang": { + "COLUMNS": { + "field_id": [ + "UINT", + 0 + ], + "lang_id": [ + "UINT", + 0 + ], + "lang_name": [ + "VCHAR_UNI", + "" + ], + "lang_explain": [ + "TEXT_UNI", + "" + ], + "lang_default_value": [ + "VCHAR_UNI", + "" + ] + }, + "PRIMARY_KEY": [ + "field_id", + "lang_id" + ] + }, + "phpbb_ranks": { + "COLUMNS": { + "rank_id": [ + "UINT", + null, + "auto_increment" + ], + "rank_title": [ + "VCHAR_UNI", + "" + ], + "rank_min": [ + "UINT", + 0 + ], + "rank_special": [ + "BOOL", + 0 + ], + "rank_image": [ + "VCHAR", + "" + ] + }, + "PRIMARY_KEY": "rank_id" + }, + "phpbb_reports": { + "COLUMNS": { + "report_id": [ + "UINT", + null, + "auto_increment" + ], + "reason_id": [ + "USINT", + 0 + ], + "post_id": [ + "UINT", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "user_notify": [ + "BOOL", + 0 + ], + "report_closed": [ + "BOOL", + 0 + ], + "report_time": [ + "TIMESTAMP", + 0 + ], + "report_text": [ + "MTEXT_UNI", + "" + ], + "pm_id": [ + "UINT", + 0 + ], + "reported_post_enable_bbcode": [ + "BOOL", + 1 + ], + "reported_post_enable_smilies": [ + "BOOL", + 1 + ], + "reported_post_enable_magic_url": [ + "BOOL", + 1 + ], + "reported_post_text": [ + "MTEXT_UNI", + "" + ], + "reported_post_uid": [ + "VCHAR:8", + "" + ], + "reported_post_bitfield": [ + "VCHAR:255", + "" + ] + }, + "PRIMARY_KEY": "report_id", + "KEYS": { + "post_id": [ + "INDEX", + [ + "post_id" + ] + ], + "pm_id": [ + "INDEX", + [ + "pm_id" + ] + ] + } + }, + "phpbb_reports_reasons": { + "COLUMNS": { + "reason_id": [ + "USINT", + null, + "auto_increment" + ], + "reason_title": [ + "VCHAR_UNI", + "" + ], + "reason_description": [ + "MTEXT_UNI", + "" + ], + "reason_order": [ + "USINT", + 0 + ] + }, + "PRIMARY_KEY": "reason_id" + }, + "phpbb_search_results": { + "COLUMNS": { + "search_key": [ + "VCHAR:32", + "" + ], + "search_time": [ + "TIMESTAMP", + 0 + ], + "search_keywords": [ + "MTEXT_UNI", + "" + ], + "search_authors": [ + "MTEXT", + "" + ] + }, + "PRIMARY_KEY": "search_key" + }, + "phpbb_search_wordlist": { + "COLUMNS": { + "word_id": [ + "UINT", + null, + "auto_increment" + ], + "word_text": [ + "VCHAR_UNI", + "" + ], + "word_common": [ + "BOOL", + 0 + ], + "word_count": [ + "UINT", + 0 + ] + }, + "PRIMARY_KEY": "word_id", + "KEYS": { + "wrd_txt": [ + "UNIQUE", + "word_text" + ], + "wrd_cnt": [ + "INDEX", + "word_count" + ] + } + }, + "phpbb_search_wordmatch": { + "COLUMNS": { + "post_id": [ + "UINT", + 0 + ], + "word_id": [ + "UINT", + 0 + ], + "title_match": [ + "BOOL", + 0 + ] + }, + "KEYS": { + "unq_mtch": [ + "UNIQUE", + [ + "word_id", + "post_id", + "title_match" + ] + ], + "word_id": [ + "INDEX", + "word_id" + ], + "post_id": [ + "INDEX", + "post_id" + ] + } + }, + "phpbb_sessions": { + "COLUMNS": { + "session_id": [ + "CHAR:32", + "" + ], + "session_user_id": [ + "UINT", + 0 + ], + "session_last_visit": [ + "TIMESTAMP", + 0 + ], + "session_start": [ + "TIMESTAMP", + 0 + ], + "session_time": [ + "TIMESTAMP", + 0 + ], + "session_ip": [ + "VCHAR:40", + "" + ], + "session_browser": [ + "VCHAR:150", + "" + ], + "session_forwarded_for": [ + "VCHAR:255", + "" + ], + "session_page": [ + "VCHAR_UNI", + "" + ], + "session_viewonline": [ + "BOOL", + 1 + ], + "session_autologin": [ + "BOOL", + 0 + ], + "session_admin": [ + "BOOL", + 0 + ], + "session_forum_id": [ + "UINT", + 0 + ] + }, + "PRIMARY_KEY": "session_id", + "KEYS": { + "session_time": [ + "INDEX", + "session_time" + ], + "session_user_id": [ + "INDEX", + "session_user_id" + ], + "session_fid": [ + "INDEX", + [ + "session_forum_id" + ] + ] + } + }, + "phpbb_sessions_keys": { + "COLUMNS": { + "key_id": [ + "CHAR:32", + "" + ], + "user_id": [ + "UINT", + 0 + ], + "last_ip": [ + "VCHAR:40", + "" + ], + "last_login": [ + "TIMESTAMP", + 0 + ] + }, + "PRIMARY_KEY": [ + "key_id", + "user_id" + ], + "KEYS": { + "last_login": [ + "INDEX", + "last_login" + ] + } + }, + "phpbb_sitelist": { + "COLUMNS": { + "site_id": [ + "UINT", + null, + "auto_increment" + ], + "site_ip": [ + "VCHAR:40", + "" + ], + "site_hostname": [ + "VCHAR", + "" + ], + "ip_exclude": [ + "BOOL", + 0 + ] + }, + "PRIMARY_KEY": "site_id" + }, + "phpbb_smilies": { + "COLUMNS": { + "smiley_id": [ + "UINT", + null, + "auto_increment" + ], + "code": [ + "VCHAR_UNI:50", + "" + ], + "emotion": [ + "VCHAR_UNI:50", + "" + ], + "smiley_url": [ + "VCHAR:50", + "" + ], + "smiley_width": [ + "USINT", + 0 + ], + "smiley_height": [ + "USINT", + 0 + ], + "smiley_order": [ + "UINT", + 0 + ], + "display_on_posting": [ + "BOOL", + 1 + ] + }, + "PRIMARY_KEY": "smiley_id", + "KEYS": { + "display_on_post": [ + "INDEX", + "display_on_posting" + ] + } + }, + "phpbb_styles": { + "COLUMNS": { + "style_id": [ + "UINT", + null, + "auto_increment" + ], + "style_name": [ + "VCHAR_UNI:255", + "" + ], + "style_copyright": [ + "VCHAR_UNI", + "" + ], + "style_active": [ + "BOOL", + 1 + ], + "style_path": [ + "VCHAR:100", + "" + ], + "bbcode_bitfield": [ + "VCHAR:255", + "kNg=" + ], + "style_parent_id": [ + "UINT:4", + 0 + ], + "style_parent_tree": [ + "TEXT", + "" + ] + }, + "PRIMARY_KEY": "style_id", + "KEYS": { + "style_name": [ + "UNIQUE", + "style_name" + ] + } + }, + "phpbb_teampage": { + "COLUMNS": { + "teampage_id": [ + "UINT", + null, + "auto_increment" + ], + "group_id": [ + "UINT", + 0 + ], + "teampage_name": [ + "VCHAR_UNI:255", + "" + ], + "teampage_position": [ + "UINT", + 0 + ], + "teampage_parent": [ + "UINT", + 0 + ] + }, + "PRIMARY_KEY": "teampage_id" + }, + "phpbb_topics": { + "COLUMNS": { + "topic_id": [ + "UINT", + null, + "auto_increment" + ], + "forum_id": [ + "UINT", + 0 + ], + "icon_id": [ + "UINT", + 0 + ], + "topic_attachment": [ + "BOOL", + 0 + ], + "topic_reported": [ + "BOOL", + 0 + ], + "topic_title": [ + "STEXT_UNI", + "", + "true_sort" + ], + "topic_poster": [ + "UINT", + 0 + ], + "topic_time": [ + "TIMESTAMP", + 0 + ], + "topic_time_limit": [ + "TIMESTAMP", + 0 + ], + "topic_views": [ + "UINT", + 0 + ], + "topic_status": [ + "TINT:3", + 0 + ], + "topic_type": [ + "TINT:3", + 0 + ], + "topic_first_post_id": [ + "UINT", + 0 + ], + "topic_first_poster_name": [ + "VCHAR_UNI", + "" + ], + "topic_first_poster_colour": [ + "VCHAR:6", + "" + ], + "topic_last_post_id": [ + "UINT", + 0 + ], + "topic_last_poster_id": [ + "UINT", + 0 + ], + "topic_last_poster_name": [ + "VCHAR_UNI", + "" + ], + "topic_last_poster_colour": [ + "VCHAR:6", + "" + ], + "topic_last_post_subject": [ + "STEXT_UNI", + "" + ], + "topic_last_post_time": [ + "TIMESTAMP", + 0 + ], + "topic_last_view_time": [ + "TIMESTAMP", + 0 + ], + "topic_moved_id": [ + "UINT", + 0 + ], + "topic_bumped": [ + "BOOL", + 0 + ], + "topic_bumper": [ + "UINT", + 0 + ], + "poll_title": [ + "STEXT_UNI", + "" + ], + "poll_start": [ + "TIMESTAMP", + 0 + ], + "poll_length": [ + "TIMESTAMP", + 0 + ], + "poll_max_options": [ + "TINT:4", + 1 + ], + "poll_last_vote": [ + "TIMESTAMP", + 0 + ], + "poll_vote_change": [ + "BOOL", + 0 + ], + "topic_visibility": [ + "TINT:3", + 0 + ], + "topic_delete_time": [ + "TIMESTAMP", + 0 + ], + "topic_delete_reason": [ + "STEXT_UNI", + "" + ], + "topic_delete_user": [ + "UINT", + 0 + ], + "topic_posts_approved": [ + "UINT", + 0 + ], + "topic_posts_unapproved": [ + "UINT", + 0 + ], + "topic_posts_softdeleted": [ + "UINT", + 0 + ] + }, + "PRIMARY_KEY": "topic_id", + "KEYS": { + "forum_id": [ + "INDEX", + "forum_id" + ], + "forum_id_type": [ + "INDEX", + [ + "forum_id", + "topic_type" + ] + ], + "last_post_time": [ + "INDEX", + "topic_last_post_time" + ], + "fid_time_moved": [ + "INDEX", + [ + "forum_id", + "topic_last_post_time", + "topic_moved_id" + ] + ], + "topic_visibility": [ + "INDEX", + [ + "topic_visibility" + ] + ], + "forum_vis_last": [ + "INDEX", + [ + "forum_id", + "topic_visibility", + "topic_last_post_id" + ] + ] + } + }, + "phpbb_topics_posted": { + "COLUMNS": { + "user_id": [ + "UINT", + 0 + ], + "topic_id": [ + "UINT", + 0 + ], + "topic_posted": [ + "BOOL", + 0 + ] + }, + "PRIMARY_KEY": [ + "user_id", + "topic_id" + ] + }, + "phpbb_topics_track": { + "COLUMNS": { + "user_id": [ + "UINT", + 0 + ], + "topic_id": [ + "UINT", + 0 + ], + "forum_id": [ + "UINT", + 0 + ], + "mark_time": [ + "TIMESTAMP", + 0 + ] + }, + "PRIMARY_KEY": [ + "user_id", + "topic_id" + ], + "KEYS": { + "forum_id": [ + "INDEX", + "forum_id" + ], + "topic_id": [ + "INDEX", + [ + "topic_id" + ] + ] + } + }, + "phpbb_topics_watch": { + "COLUMNS": { + "topic_id": [ + "UINT", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "notify_status": [ + "BOOL", + 0 + ] + }, + "KEYS": { + "topic_id": [ + "INDEX", + "topic_id" + ], + "user_id": [ + "INDEX", + "user_id" + ], + "notify_stat": [ + "INDEX", + "notify_status" + ] + } + }, + "phpbb_user_group": { + "COLUMNS": { + "group_id": [ + "UINT", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "group_leader": [ + "BOOL", + 0 + ], + "user_pending": [ + "BOOL", + 1 + ] + }, + "KEYS": { + "group_id": [ + "INDEX", + "group_id" + ], + "user_id": [ + "INDEX", + "user_id" + ], + "group_leader": [ + "INDEX", + "group_leader" + ] + } + }, + "phpbb_user_notifications": { + "COLUMNS": { + "item_type": [ + "VCHAR:255", + "" + ], + "item_id": [ + "UINT", + 0 + ], + "user_id": [ + "UINT", + 0 + ], + "method": [ + "VCHAR:255", + "" + ], + "notify": [ + "BOOL", + 1 + ] + } + }, + "phpbb_users": { + "COLUMNS": { + "user_id": [ + "UINT", + null, + "auto_increment" + ], + "user_type": [ + "TINT:2", + 0 + ], + "group_id": [ + "UINT", + 3 + ], + "user_permissions": [ + "MTEXT", + "" + ], + "user_perm_from": [ + "UINT", + 0 + ], + "user_ip": [ + "VCHAR:40", + "" + ], + "user_regdate": [ + "TIMESTAMP", + 0 + ], + "username": [ + "VCHAR_CI", + "" + ], + "username_clean": [ + "VCHAR_CI", + "" + ], + "user_password": [ + "VCHAR:255", + "" + ], + "user_passchg": [ + "TIMESTAMP", + 0 + ], + "user_pass_convert": [ + "BOOL", + 0 + ], + "user_email": [ + "VCHAR_UNI:100", + "" + ], + "user_email_hash": [ + "BINT", + 0 + ], + "user_birthday": [ + "VCHAR:10", + "" + ], + "user_lastvisit": [ + "TIMESTAMP", + 0 + ], + "user_lastmark": [ + "TIMESTAMP", + 0 + ], + "user_lastpost_time": [ + "TIMESTAMP", + 0 + ], + "user_lastpage": [ + "VCHAR_UNI:200", + "" + ], + "user_last_confirm_key": [ + "VCHAR:10", + "" + ], + "user_last_search": [ + "TIMESTAMP", + 0 + ], + "user_warnings": [ + "TINT:4", + 0 + ], + "user_last_warning": [ + "TIMESTAMP", + 0 + ], + "user_login_attempts": [ + "TINT:4", + 0 + ], + "user_inactive_reason": [ + "TINT:2", + 0 + ], + "user_inactive_time": [ + "TIMESTAMP", + 0 + ], + "user_posts": [ + "UINT", + 0 + ], + "user_lang": [ + "VCHAR:30", + "" + ], + "user_timezone": [ + "VCHAR:100", + "" + ], + "user_dateformat": [ + "VCHAR_UNI:30", + "d M Y H:i" + ], + "user_style": [ + "UINT", + 0 + ], + "user_rank": [ + "UINT", + 0 + ], + "user_colour": [ + "VCHAR:6", + "" + ], + "user_new_privmsg": [ + "INT:4", + 0 + ], + "user_unread_privmsg": [ + "INT:4", + 0 + ], + "user_last_privmsg": [ + "TIMESTAMP", + 0 + ], + "user_message_rules": [ + "BOOL", + 0 + ], + "user_full_folder": [ + "INT:11", + -3 + ], + "user_emailtime": [ + "TIMESTAMP", + 0 + ], + "user_topic_show_days": [ + "USINT", + 0 + ], + "user_topic_sortby_type": [ + "VCHAR:1", + "t" + ], + "user_topic_sortby_dir": [ + "VCHAR:1", + "d" + ], + "user_post_show_days": [ + "USINT", + 0 + ], + "user_post_sortby_type": [ + "VCHAR:1", + "t" + ], + "user_post_sortby_dir": [ + "VCHAR:1", + "a" + ], + "user_notify": [ + "BOOL", + 0 + ], + "user_notify_pm": [ + "BOOL", + 1 + ], + "user_notify_type": [ + "TINT:4", + 0 + ], + "user_allow_pm": [ + "BOOL", + 1 + ], + "user_allow_viewonline": [ + "BOOL", + 1 + ], + "user_allow_viewemail": [ + "BOOL", + 1 + ], + "user_allow_massemail": [ + "BOOL", + 1 + ], + "user_options": [ + "UINT:11", + 230271 + ], + "user_avatar": [ + "VCHAR", + "" + ], + "user_avatar_type": [ + "VCHAR:255", + "" + ], + "user_avatar_width": [ + "USINT", + 0 + ], + "user_avatar_height": [ + "USINT", + 0 + ], + "user_sig": [ + "MTEXT_UNI", + "" + ], + "user_sig_bbcode_uid": [ + "VCHAR:8", + "" + ], + "user_sig_bbcode_bitfield": [ + "VCHAR:255", + "" + ], + "user_jabber": [ + "VCHAR_UNI", + "" + ], + "user_actkey": [ + "VCHAR:32", + "" + ], + "user_newpasswd": [ + "VCHAR:255", + "" + ], + "user_form_salt": [ + "VCHAR_UNI:32", + "" + ], + "user_new": [ + "BOOL", + 1 + ], + "user_reminded": [ + "TINT:4", + 0 + ], + "user_reminded_time": [ + "TIMESTAMP", + 0 + ] + }, + "PRIMARY_KEY": "user_id", + "KEYS": { + "user_birthday": [ + "INDEX", + "user_birthday" + ], + "user_email_hash": [ + "INDEX", + "user_email_hash" + ], + "user_type": [ + "INDEX", + "user_type" + ], + "username_clean": [ + "UNIQUE", + "username_clean" + ] + } + }, + "phpbb_warnings": { + "COLUMNS": { + "warning_id": [ + "UINT", + null, + "auto_increment" + ], + "user_id": [ + "UINT", + 0 + ], + "post_id": [ + "UINT", + 0 + ], + "log_id": [ + "UINT", + 0 + ], + "warning_time": [ + "TIMESTAMP", + 0 + ] + }, + "PRIMARY_KEY": "warning_id" + }, + "phpbb_words": { + "COLUMNS": { + "word_id": [ + "UINT", + null, + "auto_increment" + ], + "word": [ + "VCHAR_UNI", + "" + ], + "replacement": [ + "VCHAR_UNI", + "" + ] + }, + "PRIMARY_KEY": "word_id" + }, + "phpbb_zebra": { + "COLUMNS": { + "user_id": [ + "UINT", + 0 + ], + "zebra_id": [ + "UINT", + 0 + ], + "friend": [ + "BOOL", + 0 + ], + "foe": [ + "BOOL", + 0 + ] + }, + "PRIMARY_KEY": [ + "user_id", + "zebra_id" + ] + } +}
\ No newline at end of file diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 70138f35fd..fbf1374346 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -17,6 +17,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_remot INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_bbcode', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_birthdays', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_bookmarks', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_cdn', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_emailreuse', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_password_reset', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_forum_notify', '1'); @@ -55,6 +56,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_min_width', INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_path', 'images/avatars/upload'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_salt', 'phpbb_avatar'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact', 'contact@yourdomain.tld'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact_name', ''); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_disable', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_disable_msg', ''); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email', 'address@yourdomain.tld'); @@ -170,14 +172,13 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('limit_load', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('limit_search_load', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_anon_lastread', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_birthdays', '1'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_memberlist', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_pm', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_memberlist', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_pm', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_viewprofile', '1'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_viewtopic', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_viewtopic', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_db_lastread', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_db_track', '1'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_jquery_cdn', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_jumpbox', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_moderators', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_notifications', '1'); @@ -222,6 +223,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('new_member_post_li INSERT INTO phpbb_config (config_name, config_value) VALUES ('new_member_group_default', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('override_user_style', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('pass_complex', 'PASS_TYPE_ANY'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('plupload_salt', 'phpbb_plupload'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('pm_edit_time', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('pm_max_boxes', '4'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('pm_max_msgs', '50'); @@ -230,6 +232,8 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('posts_per_page', ' INSERT INTO phpbb_config (config_name, config_value) VALUES ('print_pm', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('queue_interval', '60'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('ranks_path', 'images/ranks'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('read_notification_expire_days', '30'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('read_notification_gc', '86400'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('require_activation', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('referer_validation', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('script_path', ''); @@ -237,7 +241,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_block_size' INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_gc', '7200'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_interval', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_anonymous_interval', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_type', 'phpbb\search\fulltext_native'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_type', '\phpbb\search\fulltext_native'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_store_results', '1800'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('secure_allow_deny', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('secure_allow_empty_referer', '1'); @@ -266,7 +270,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0 INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.1.0-dev'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.1.0-b3-dev'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400'); @@ -281,8 +285,10 @@ INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_fi INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_posts', '1', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_topics', '1', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_users', '1', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('plupload_last_gc', '0', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('rand_seed', '0', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('rand_seed_last_update', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('read_notification_last_gc', '0', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('record_online_date', '0', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('record_online_users', '0', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('search_indexing_state', '', 1); @@ -462,10 +468,10 @@ INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts_approved, forum_posts_unapproved, forum_posts_softdeleted, forum_topics_approved, forum_topics_unapproved, forum_topics_softdeleted, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_subject, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents, forum_flags) VALUES ('{L_FORUMS_TEST_FORUM_TITLE}', '{L_FORUMS_TEST_FORUM_DESC}', 2, 3, 1, 1, 1, 0, 0, 1, 0, 0, 1, 2, 'Admin', 'AA0000', '{L_TOPICS_TOPIC_TITLE}', 972086460, '', '', '', '', '', '', '', 0, 0, '', 48); # -- Users / Anonymous user -INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_from, user_icq, user_aim, user_yim, user_msnm, user_jabber, user_website, user_occ, user_interests, user_actkey, user_newpasswd, user_allow_massemail) VALUES (2, 1, 'Anonymous', 'anonymous', 0, '', '', 'en', 1, 0, '', 0, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0); +INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_jabber, user_actkey, user_newpasswd, user_allow_massemail) VALUES (2, 1, 'Anonymous', 'anonymous', 0, '', '', 'en', 1, 0, '', 0, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', 0); # -- username: Admin password: admin (change this or remove it once everything is working!) -INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_from, user_icq, user_aim, user_yim, user_msnm, user_jabber, user_website, user_occ, user_interests, user_actkey, user_newpasswd) VALUES (3, 5, 'Admin', 'admin', 0, '21232f297a57a5a743894a0e4a801fc3', 'admin@yourdomain.com', 'en', 1, 1, 'AA0000', 1, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', '', '', '', '', '', '', '', ''); +INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_jabber, user_actkey, user_newpasswd) VALUES (3, 5, 'Admin', 'admin', 0, '21232f297a57a5a743894a0e4a801fc3', 'admin@yourdomain.com', 'en', 1, 1, 'AA0000', 1, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', ''); # -- Groups INSERT INTO phpbb_groups (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('GUESTS', 3, 0, '', 0, '', '', '', 5); @@ -617,7 +623,7 @@ INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, # Bots having bot access INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (6, 2, 0, 19, 0); -# NEW MEMBERS aren't allowed to PM +# NEW MEMBERS are not allowed to send private messages INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (7, 0, 0, 23, 0); # NEW MEMBERS on the queue @@ -782,6 +788,16 @@ INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'mp3'); INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'ogg'); INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'ogm'); +# Add default profile fields +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_location', 'profilefields.type.string', 'phpbb_location', '20', '2', '100', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, '', ''); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_website', 'profilefields.type.url', 'phpbb_website', '40', '12', '255', '', '', '', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 2, 1, 'VISIT_WEBSITE', '%s'); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_interests', 'profilefields.type.text', 'phpbb_interests', '3|30', '2', '500', '', '', '.*', 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, '', ''); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_occupation', 'profilefields.type.text', 'phpbb_occupation', '3|30', '2', '500', '', '', '.*', 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, '', ''); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_aol', 'profilefields.type.string', 'phpbb_aol', '40', '5', '255', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 5, 1, '', ''); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_icq', 'profilefields.type.string', 'phpbb_icq', '20', '3', '15', '', '', '[0-9]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 6, 1, 'SEND_ICQ_MESSAGE', 'https://www.icq.com/people/%s/'); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_wlm', 'profilefields.type.string', 'phpbb_wlm', '40', '5', '255', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 7, 1, '', ''); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_yahoo', 'profilefields.type.string', 'phpbb_yahoo', '40', '5', '255', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 8, 1, 'SEND_YIM_MESSAGE', 'http://edit.yahoo.com/config/send_webmesg?.target=%s&.src=pg'); + # User Notification Options (for first user) INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('post', 0, 2, ''); INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('post', 0, 2, 'email'); diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index de88900f06..28649dc54c 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -3,1048 +3,3 @@ # To change the contents of this file, edit # phpBB/develop/create_schema_files.php and # run it. -BEGIN TRANSACTION; - -# Table: 'phpbb_attachments' -CREATE TABLE phpbb_attachments ( - attach_id INTEGER PRIMARY KEY NOT NULL , - post_msg_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - in_message INTEGER UNSIGNED NOT NULL DEFAULT '0', - poster_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - is_orphan INTEGER UNSIGNED NOT NULL DEFAULT '1', - physical_filename varchar(255) NOT NULL DEFAULT '', - real_filename varchar(255) NOT NULL DEFAULT '', - download_count INTEGER UNSIGNED NOT NULL DEFAULT '0', - attach_comment text(65535) NOT NULL DEFAULT '', - extension varchar(100) NOT NULL DEFAULT '', - mimetype varchar(100) NOT NULL DEFAULT '', - filesize INTEGER UNSIGNED NOT NULL DEFAULT '0', - filetime INTEGER UNSIGNED NOT NULL DEFAULT '0', - thumbnail INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_attachments_filetime ON phpbb_attachments (filetime); -CREATE INDEX phpbb_attachments_post_msg_id ON phpbb_attachments (post_msg_id); -CREATE INDEX phpbb_attachments_topic_id ON phpbb_attachments (topic_id); -CREATE INDEX phpbb_attachments_poster_id ON phpbb_attachments (poster_id); -CREATE INDEX phpbb_attachments_is_orphan ON phpbb_attachments (is_orphan); - -# Table: 'phpbb_acl_groups' -CREATE TABLE phpbb_acl_groups ( - group_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - auth_option_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - auth_role_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - auth_setting tinyint(2) NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_acl_groups_group_id ON phpbb_acl_groups (group_id); -CREATE INDEX phpbb_acl_groups_auth_opt_id ON phpbb_acl_groups (auth_option_id); -CREATE INDEX phpbb_acl_groups_auth_role_id ON phpbb_acl_groups (auth_role_id); - -# Table: 'phpbb_acl_options' -CREATE TABLE phpbb_acl_options ( - auth_option_id INTEGER PRIMARY KEY NOT NULL , - auth_option varchar(50) NOT NULL DEFAULT '', - is_global INTEGER UNSIGNED NOT NULL DEFAULT '0', - is_local INTEGER UNSIGNED NOT NULL DEFAULT '0', - founder_only INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE UNIQUE INDEX phpbb_acl_options_auth_option ON phpbb_acl_options (auth_option); - -# Table: 'phpbb_acl_roles' -CREATE TABLE phpbb_acl_roles ( - role_id INTEGER PRIMARY KEY NOT NULL , - role_name varchar(255) NOT NULL DEFAULT '', - role_description text(65535) NOT NULL DEFAULT '', - role_type varchar(10) NOT NULL DEFAULT '', - role_order INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_acl_roles_role_type ON phpbb_acl_roles (role_type); -CREATE INDEX phpbb_acl_roles_role_order ON phpbb_acl_roles (role_order); - -# Table: 'phpbb_acl_roles_data' -CREATE TABLE phpbb_acl_roles_data ( - role_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - auth_option_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - auth_setting tinyint(2) NOT NULL DEFAULT '0', - PRIMARY KEY (role_id, auth_option_id) -); - -CREATE INDEX phpbb_acl_roles_data_ath_op_id ON phpbb_acl_roles_data (auth_option_id); - -# Table: 'phpbb_acl_users' -CREATE TABLE phpbb_acl_users ( - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - auth_option_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - auth_role_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - auth_setting tinyint(2) NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_acl_users_user_id ON phpbb_acl_users (user_id); -CREATE INDEX phpbb_acl_users_auth_option_id ON phpbb_acl_users (auth_option_id); -CREATE INDEX phpbb_acl_users_auth_role_id ON phpbb_acl_users (auth_role_id); - -# Table: 'phpbb_oauth_tokens' -CREATE TABLE phpbb_oauth_tokens ( - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - session_id char(32) NOT NULL DEFAULT '', - provider varchar(255) NOT NULL DEFAULT '', - oauth_token mediumtext(16777215) NOT NULL DEFAULT '' -); - -CREATE INDEX phpbb_oauth_tokens_user_id ON phpbb_oauth_tokens (user_id); -CREATE INDEX phpbb_oauth_tokens_provider ON phpbb_oauth_tokens (provider); - -# Table: 'phpbb_oauth_accounts' -CREATE TABLE phpbb_oauth_accounts ( - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - provider varchar(255) NOT NULL DEFAULT '', - oauth_provider_id text(65535) NOT NULL DEFAULT '', - PRIMARY KEY (user_id, provider) -); - - -# Table: 'phpbb_banlist' -CREATE TABLE phpbb_banlist ( - ban_id INTEGER PRIMARY KEY NOT NULL , - ban_userid INTEGER UNSIGNED NOT NULL DEFAULT '0', - ban_ip varchar(40) NOT NULL DEFAULT '', - ban_email varchar(100) NOT NULL DEFAULT '', - ban_start INTEGER UNSIGNED NOT NULL DEFAULT '0', - ban_end INTEGER UNSIGNED NOT NULL DEFAULT '0', - ban_exclude INTEGER UNSIGNED NOT NULL DEFAULT '0', - ban_reason varchar(255) NOT NULL DEFAULT '', - ban_give_reason varchar(255) NOT NULL DEFAULT '' -); - -CREATE INDEX phpbb_banlist_ban_end ON phpbb_banlist (ban_end); -CREATE INDEX phpbb_banlist_ban_user ON phpbb_banlist (ban_userid, ban_exclude); -CREATE INDEX phpbb_banlist_ban_email ON phpbb_banlist (ban_email, ban_exclude); -CREATE INDEX phpbb_banlist_ban_ip ON phpbb_banlist (ban_ip, ban_exclude); - -# Table: 'phpbb_bbcodes' -CREATE TABLE phpbb_bbcodes ( - bbcode_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - bbcode_tag varchar(16) NOT NULL DEFAULT '', - bbcode_helpline varchar(255) NOT NULL DEFAULT '', - display_on_posting INTEGER UNSIGNED NOT NULL DEFAULT '0', - bbcode_match text(65535) NOT NULL DEFAULT '', - bbcode_tpl mediumtext(16777215) NOT NULL DEFAULT '', - first_pass_match mediumtext(16777215) NOT NULL DEFAULT '', - first_pass_replace mediumtext(16777215) NOT NULL DEFAULT '', - second_pass_match mediumtext(16777215) NOT NULL DEFAULT '', - second_pass_replace mediumtext(16777215) NOT NULL DEFAULT '', - PRIMARY KEY (bbcode_id) -); - -CREATE INDEX phpbb_bbcodes_display_on_post ON phpbb_bbcodes (display_on_posting); - -# Table: 'phpbb_bookmarks' -CREATE TABLE phpbb_bookmarks ( - topic_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (topic_id, user_id) -); - - -# Table: 'phpbb_bots' -CREATE TABLE phpbb_bots ( - bot_id INTEGER PRIMARY KEY NOT NULL , - bot_active INTEGER UNSIGNED NOT NULL DEFAULT '1', - bot_name text(65535) NOT NULL DEFAULT '', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - bot_agent varchar(255) NOT NULL DEFAULT '', - bot_ip varchar(255) NOT NULL DEFAULT '' -); - -CREATE INDEX phpbb_bots_bot_active ON phpbb_bots (bot_active); - -# Table: 'phpbb_config' -CREATE TABLE phpbb_config ( - config_name varchar(255) NOT NULL DEFAULT '', - config_value varchar(255) NOT NULL DEFAULT '', - is_dynamic INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (config_name) -); - -CREATE INDEX phpbb_config_is_dynamic ON phpbb_config (is_dynamic); - -# Table: 'phpbb_config_text' -CREATE TABLE phpbb_config_text ( - config_name varchar(255) NOT NULL DEFAULT '', - config_value mediumtext(16777215) NOT NULL DEFAULT '', - PRIMARY KEY (config_name) -); - - -# Table: 'phpbb_confirm' -CREATE TABLE phpbb_confirm ( - confirm_id char(32) NOT NULL DEFAULT '', - session_id char(32) NOT NULL DEFAULT '', - confirm_type tinyint(3) NOT NULL DEFAULT '0', - code varchar(8) NOT NULL DEFAULT '', - seed INTEGER UNSIGNED NOT NULL DEFAULT '0', - attempts INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (session_id, confirm_id) -); - -CREATE INDEX phpbb_confirm_confirm_type ON phpbb_confirm (confirm_type); - -# Table: 'phpbb_disallow' -CREATE TABLE phpbb_disallow ( - disallow_id INTEGER PRIMARY KEY NOT NULL , - disallow_username varchar(255) NOT NULL DEFAULT '' -); - - -# Table: 'phpbb_drafts' -CREATE TABLE phpbb_drafts ( - draft_id INTEGER PRIMARY KEY NOT NULL , - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - save_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - draft_subject text(65535) NOT NULL DEFAULT '', - draft_message mediumtext(16777215) NOT NULL DEFAULT '' -); - -CREATE INDEX phpbb_drafts_save_time ON phpbb_drafts (save_time); - -# Table: 'phpbb_ext' -CREATE TABLE phpbb_ext ( - ext_name varchar(255) NOT NULL DEFAULT '', - ext_active INTEGER UNSIGNED NOT NULL DEFAULT '0', - ext_state text(65535) NOT NULL DEFAULT '' -); - -CREATE UNIQUE INDEX phpbb_ext_ext_name ON phpbb_ext (ext_name); - -# Table: 'phpbb_extensions' -CREATE TABLE phpbb_extensions ( - extension_id INTEGER PRIMARY KEY NOT NULL , - group_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - extension varchar(100) NOT NULL DEFAULT '' -); - - -# Table: 'phpbb_extension_groups' -CREATE TABLE phpbb_extension_groups ( - group_id INTEGER PRIMARY KEY NOT NULL , - group_name varchar(255) NOT NULL DEFAULT '', - cat_id tinyint(2) NOT NULL DEFAULT '0', - allow_group INTEGER UNSIGNED NOT NULL DEFAULT '0', - download_mode INTEGER UNSIGNED NOT NULL DEFAULT '1', - upload_icon varchar(255) NOT NULL DEFAULT '', - max_filesize INTEGER UNSIGNED NOT NULL DEFAULT '0', - allowed_forums text(65535) NOT NULL DEFAULT '', - allow_in_pm INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - - -# Table: 'phpbb_forums' -CREATE TABLE phpbb_forums ( - forum_id INTEGER PRIMARY KEY NOT NULL , - parent_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - left_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - right_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_parents mediumtext(16777215) NOT NULL DEFAULT '', - forum_name text(65535) NOT NULL DEFAULT '', - forum_desc text(65535) NOT NULL DEFAULT '', - forum_desc_bitfield varchar(255) NOT NULL DEFAULT '', - forum_desc_options INTEGER UNSIGNED NOT NULL DEFAULT '7', - forum_desc_uid varchar(8) NOT NULL DEFAULT '', - forum_link varchar(255) NOT NULL DEFAULT '', - forum_password varchar(40) NOT NULL DEFAULT '', - forum_style INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_image varchar(255) NOT NULL DEFAULT '', - forum_rules text(65535) NOT NULL DEFAULT '', - forum_rules_link varchar(255) NOT NULL DEFAULT '', - forum_rules_bitfield varchar(255) NOT NULL DEFAULT '', - forum_rules_options INTEGER UNSIGNED NOT NULL DEFAULT '7', - forum_rules_uid varchar(8) NOT NULL DEFAULT '', - forum_topics_per_page tinyint(4) NOT NULL DEFAULT '0', - forum_type tinyint(4) NOT NULL DEFAULT '0', - forum_status tinyint(4) NOT NULL DEFAULT '0', - forum_posts_approved INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_posts_unapproved INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_posts_softdeleted INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_topics_approved INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_topics_unapproved INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_topics_softdeleted INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_last_post_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_last_poster_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_last_post_subject text(65535) NOT NULL DEFAULT '', - forum_last_post_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_last_poster_name varchar(255) NOT NULL DEFAULT '', - forum_last_poster_colour varchar(6) NOT NULL DEFAULT '', - forum_flags tinyint(4) NOT NULL DEFAULT '32', - forum_options INTEGER UNSIGNED NOT NULL DEFAULT '0', - display_subforum_list INTEGER UNSIGNED NOT NULL DEFAULT '1', - display_on_index INTEGER UNSIGNED NOT NULL DEFAULT '1', - enable_indexing INTEGER UNSIGNED NOT NULL DEFAULT '1', - enable_icons INTEGER UNSIGNED NOT NULL DEFAULT '1', - enable_prune INTEGER UNSIGNED NOT NULL DEFAULT '0', - prune_next INTEGER UNSIGNED NOT NULL DEFAULT '0', - prune_days INTEGER UNSIGNED NOT NULL DEFAULT '0', - prune_viewed INTEGER UNSIGNED NOT NULL DEFAULT '0', - prune_freq INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_forums_left_right_id ON phpbb_forums (left_id, right_id); -CREATE INDEX phpbb_forums_forum_lastpost_id ON phpbb_forums (forum_last_post_id); - -# Table: 'phpbb_forums_access' -CREATE TABLE phpbb_forums_access ( - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - session_id char(32) NOT NULL DEFAULT '', - PRIMARY KEY (forum_id, user_id, session_id) -); - - -# Table: 'phpbb_forums_track' -CREATE TABLE phpbb_forums_track ( - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - mark_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (user_id, forum_id) -); - - -# Table: 'phpbb_forums_watch' -CREATE TABLE phpbb_forums_watch ( - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - notify_status INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_forums_watch_forum_id ON phpbb_forums_watch (forum_id); -CREATE INDEX phpbb_forums_watch_user_id ON phpbb_forums_watch (user_id); -CREATE INDEX phpbb_forums_watch_notify_stat ON phpbb_forums_watch (notify_status); - -# Table: 'phpbb_groups' -CREATE TABLE phpbb_groups ( - group_id INTEGER PRIMARY KEY NOT NULL , - group_type tinyint(4) NOT NULL DEFAULT '1', - group_founder_manage INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_skip_auth INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_name varchar(255) NOT NULL DEFAULT '', - group_desc text(65535) NOT NULL DEFAULT '', - group_desc_bitfield varchar(255) NOT NULL DEFAULT '', - group_desc_options INTEGER UNSIGNED NOT NULL DEFAULT '7', - group_desc_uid varchar(8) NOT NULL DEFAULT '', - group_display INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_avatar varchar(255) NOT NULL DEFAULT '', - group_avatar_type varchar(255) NOT NULL DEFAULT '', - group_avatar_width INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_avatar_height INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_rank INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_colour varchar(6) NOT NULL DEFAULT '', - group_sig_chars INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_receive_pm INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_message_limit INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_max_recipients INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_legend INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_groups_group_legend_name ON phpbb_groups (group_legend, group_name); - -# Table: 'phpbb_icons' -CREATE TABLE phpbb_icons ( - icons_id INTEGER PRIMARY KEY NOT NULL , - icons_url varchar(255) NOT NULL DEFAULT '', - icons_width tinyint(4) NOT NULL DEFAULT '0', - icons_height tinyint(4) NOT NULL DEFAULT '0', - icons_order INTEGER UNSIGNED NOT NULL DEFAULT '0', - display_on_posting INTEGER UNSIGNED NOT NULL DEFAULT '1' -); - -CREATE INDEX phpbb_icons_display_on_posting ON phpbb_icons (display_on_posting); - -# Table: 'phpbb_lang' -CREATE TABLE phpbb_lang ( - lang_id INTEGER PRIMARY KEY NOT NULL , - lang_iso varchar(30) NOT NULL DEFAULT '', - lang_dir varchar(30) NOT NULL DEFAULT '', - lang_english_name varchar(100) NOT NULL DEFAULT '', - lang_local_name varchar(255) NOT NULL DEFAULT '', - lang_author varchar(255) NOT NULL DEFAULT '' -); - -CREATE INDEX phpbb_lang_lang_iso ON phpbb_lang (lang_iso); - -# Table: 'phpbb_log' -CREATE TABLE phpbb_log ( - log_id INTEGER PRIMARY KEY NOT NULL , - log_type tinyint(4) NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - reportee_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - log_ip varchar(40) NOT NULL DEFAULT '', - log_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - log_operation text(65535) NOT NULL DEFAULT '', - log_data mediumtext(16777215) NOT NULL DEFAULT '' -); - -CREATE INDEX phpbb_log_log_type ON phpbb_log (log_type); -CREATE INDEX phpbb_log_log_time ON phpbb_log (log_time); -CREATE INDEX phpbb_log_forum_id ON phpbb_log (forum_id); -CREATE INDEX phpbb_log_topic_id ON phpbb_log (topic_id); -CREATE INDEX phpbb_log_reportee_id ON phpbb_log (reportee_id); -CREATE INDEX phpbb_log_user_id ON phpbb_log (user_id); - -# Table: 'phpbb_login_attempts' -CREATE TABLE phpbb_login_attempts ( - attempt_ip varchar(40) NOT NULL DEFAULT '', - attempt_browser varchar(150) NOT NULL DEFAULT '', - attempt_forwarded_for varchar(255) NOT NULL DEFAULT '', - attempt_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - username varchar(255) NOT NULL DEFAULT '0', - username_clean varchar(255) NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_login_attempts_att_ip ON phpbb_login_attempts (attempt_ip, attempt_time); -CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwarded_for, attempt_time); -CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); -CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); - -# Table: 'phpbb_moderator_cache' -CREATE TABLE phpbb_moderator_cache ( - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - username varchar(255) NOT NULL DEFAULT '', - group_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_name varchar(255) NOT NULL DEFAULT '', - display_on_index INTEGER UNSIGNED NOT NULL DEFAULT '1' -); - -CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache (display_on_index); -CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id); - -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name varchar(255) NOT NULL DEFAULT '', - migration_depends_on text(65535) NOT NULL DEFAULT '', - migration_schema_done INTEGER UNSIGNED NOT NULL DEFAULT '0', - migration_data_done INTEGER UNSIGNED NOT NULL DEFAULT '0', - migration_data_state text(65535) NOT NULL DEFAULT '', - migration_start_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - migration_end_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (migration_name) -); - - -# Table: 'phpbb_modules' -CREATE TABLE phpbb_modules ( - module_id INTEGER PRIMARY KEY NOT NULL , - module_enabled INTEGER UNSIGNED NOT NULL DEFAULT '1', - module_display INTEGER UNSIGNED NOT NULL DEFAULT '1', - module_basename varchar(255) NOT NULL DEFAULT '', - module_class varchar(10) NOT NULL DEFAULT '', - parent_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - left_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - right_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - module_langname varchar(255) NOT NULL DEFAULT '', - module_mode varchar(255) NOT NULL DEFAULT '', - module_auth varchar(255) NOT NULL DEFAULT '' -); - -CREATE INDEX phpbb_modules_left_right_id ON phpbb_modules (left_id, right_id); -CREATE INDEX phpbb_modules_module_enabled ON phpbb_modules (module_enabled); -CREATE INDEX phpbb_modules_class_left_id ON phpbb_modules (module_class, left_id); - -# Table: 'phpbb_notification_types' -CREATE TABLE phpbb_notification_types ( - notification_type_id INTEGER PRIMARY KEY NOT NULL , - notification_type_name varchar(255) NOT NULL DEFAULT '', - notification_type_enabled INTEGER UNSIGNED NOT NULL DEFAULT '1' -); - -CREATE UNIQUE INDEX phpbb_notification_types_type ON phpbb_notification_types (notification_type_name); - -# Table: 'phpbb_notifications' -CREATE TABLE phpbb_notifications ( - notification_id INTEGER PRIMARY KEY NOT NULL , - notification_type_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - item_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - item_parent_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - notification_read INTEGER UNSIGNED NOT NULL DEFAULT '0', - notification_time INTEGER UNSIGNED NOT NULL DEFAULT '1', - notification_data text(65535) NOT NULL DEFAULT '' -); - -CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (notification_type_id, item_id); -CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read); - -# Table: 'phpbb_poll_options' -CREATE TABLE phpbb_poll_options ( - poll_option_id tinyint(4) NOT NULL DEFAULT '0', - topic_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - poll_option_text text(65535) NOT NULL DEFAULT '', - poll_option_total INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_poll_options_poll_opt_id ON phpbb_poll_options (poll_option_id); -CREATE INDEX phpbb_poll_options_topic_id ON phpbb_poll_options (topic_id); - -# Table: 'phpbb_poll_votes' -CREATE TABLE phpbb_poll_votes ( - topic_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - poll_option_id tinyint(4) NOT NULL DEFAULT '0', - vote_user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - vote_user_ip varchar(40) NOT NULL DEFAULT '' -); - -CREATE INDEX phpbb_poll_votes_topic_id ON phpbb_poll_votes (topic_id); -CREATE INDEX phpbb_poll_votes_vote_user_id ON phpbb_poll_votes (vote_user_id); -CREATE INDEX phpbb_poll_votes_vote_user_ip ON phpbb_poll_votes (vote_user_ip); - -# Table: 'phpbb_posts' -CREATE TABLE phpbb_posts ( - post_id INTEGER PRIMARY KEY NOT NULL , - topic_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - poster_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - icon_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - poster_ip varchar(40) NOT NULL DEFAULT '', - post_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - post_visibility tinyint(3) NOT NULL DEFAULT '0', - post_reported INTEGER UNSIGNED NOT NULL DEFAULT '0', - enable_bbcode INTEGER UNSIGNED NOT NULL DEFAULT '1', - enable_smilies INTEGER UNSIGNED NOT NULL DEFAULT '1', - enable_magic_url INTEGER UNSIGNED NOT NULL DEFAULT '1', - enable_sig INTEGER UNSIGNED NOT NULL DEFAULT '1', - post_username varchar(255) NOT NULL DEFAULT '', - post_subject text(65535) NOT NULL DEFAULT '', - post_text mediumtext(16777215) NOT NULL DEFAULT '', - post_checksum varchar(32) NOT NULL DEFAULT '', - post_attachment INTEGER UNSIGNED NOT NULL DEFAULT '0', - bbcode_bitfield varchar(255) NOT NULL DEFAULT '', - bbcode_uid varchar(8) NOT NULL DEFAULT '', - post_postcount INTEGER UNSIGNED NOT NULL DEFAULT '1', - post_edit_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - post_edit_reason text(65535) NOT NULL DEFAULT '', - post_edit_user INTEGER UNSIGNED NOT NULL DEFAULT '0', - post_edit_count INTEGER UNSIGNED NOT NULL DEFAULT '0', - post_edit_locked INTEGER UNSIGNED NOT NULL DEFAULT '0', - post_delete_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - post_delete_reason text(65535) NOT NULL DEFAULT '', - post_delete_user INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_posts_forum_id ON phpbb_posts (forum_id); -CREATE INDEX phpbb_posts_topic_id ON phpbb_posts (topic_id); -CREATE INDEX phpbb_posts_poster_ip ON phpbb_posts (poster_ip); -CREATE INDEX phpbb_posts_poster_id ON phpbb_posts (poster_id); -CREATE INDEX phpbb_posts_post_visibility ON phpbb_posts (post_visibility); -CREATE INDEX phpbb_posts_post_username ON phpbb_posts (post_username); -CREATE INDEX phpbb_posts_tid_post_time ON phpbb_posts (topic_id, post_time); - -# Table: 'phpbb_privmsgs' -CREATE TABLE phpbb_privmsgs ( - msg_id INTEGER PRIMARY KEY NOT NULL , - root_level INTEGER UNSIGNED NOT NULL DEFAULT '0', - author_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - icon_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - author_ip varchar(40) NOT NULL DEFAULT '', - message_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - enable_bbcode INTEGER UNSIGNED NOT NULL DEFAULT '1', - enable_smilies INTEGER UNSIGNED NOT NULL DEFAULT '1', - enable_magic_url INTEGER UNSIGNED NOT NULL DEFAULT '1', - enable_sig INTEGER UNSIGNED NOT NULL DEFAULT '1', - message_subject text(65535) NOT NULL DEFAULT '', - message_text mediumtext(16777215) NOT NULL DEFAULT '', - message_edit_reason text(65535) NOT NULL DEFAULT '', - message_edit_user INTEGER UNSIGNED NOT NULL DEFAULT '0', - message_attachment INTEGER UNSIGNED NOT NULL DEFAULT '0', - bbcode_bitfield varchar(255) NOT NULL DEFAULT '', - bbcode_uid varchar(8) NOT NULL DEFAULT '', - message_edit_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - message_edit_count INTEGER UNSIGNED NOT NULL DEFAULT '0', - to_address text(65535) NOT NULL DEFAULT '', - bcc_address text(65535) NOT NULL DEFAULT '', - message_reported INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_privmsgs_author_ip ON phpbb_privmsgs (author_ip); -CREATE INDEX phpbb_privmsgs_message_time ON phpbb_privmsgs (message_time); -CREATE INDEX phpbb_privmsgs_author_id ON phpbb_privmsgs (author_id); -CREATE INDEX phpbb_privmsgs_root_level ON phpbb_privmsgs (root_level); - -# Table: 'phpbb_privmsgs_folder' -CREATE TABLE phpbb_privmsgs_folder ( - folder_id INTEGER PRIMARY KEY NOT NULL , - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - folder_name varchar(255) NOT NULL DEFAULT '', - pm_count INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_privmsgs_folder_user_id ON phpbb_privmsgs_folder (user_id); - -# Table: 'phpbb_privmsgs_rules' -CREATE TABLE phpbb_privmsgs_rules ( - rule_id INTEGER PRIMARY KEY NOT NULL , - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - rule_check INTEGER UNSIGNED NOT NULL DEFAULT '0', - rule_connection INTEGER UNSIGNED NOT NULL DEFAULT '0', - rule_string varchar(255) NOT NULL DEFAULT '', - rule_user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - rule_group_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - rule_action INTEGER UNSIGNED NOT NULL DEFAULT '0', - rule_folder_id int(11) NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_privmsgs_rules_user_id ON phpbb_privmsgs_rules (user_id); - -# Table: 'phpbb_privmsgs_to' -CREATE TABLE phpbb_privmsgs_to ( - msg_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - author_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - pm_deleted INTEGER UNSIGNED NOT NULL DEFAULT '0', - pm_new INTEGER UNSIGNED NOT NULL DEFAULT '1', - pm_unread INTEGER UNSIGNED NOT NULL DEFAULT '1', - pm_replied INTEGER UNSIGNED NOT NULL DEFAULT '0', - pm_marked INTEGER UNSIGNED NOT NULL DEFAULT '0', - pm_forwarded INTEGER UNSIGNED NOT NULL DEFAULT '0', - folder_id int(11) NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_privmsgs_to_msg_id ON phpbb_privmsgs_to (msg_id); -CREATE INDEX phpbb_privmsgs_to_author_id ON phpbb_privmsgs_to (author_id); -CREATE INDEX phpbb_privmsgs_to_usr_flder_id ON phpbb_privmsgs_to (user_id, folder_id); - -# Table: 'phpbb_profile_fields' -CREATE TABLE phpbb_profile_fields ( - field_id INTEGER PRIMARY KEY NOT NULL , - field_name varchar(255) NOT NULL DEFAULT '', - field_type tinyint(4) NOT NULL DEFAULT '0', - field_ident varchar(20) NOT NULL DEFAULT '', - field_length varchar(20) NOT NULL DEFAULT '', - field_minlen varchar(255) NOT NULL DEFAULT '', - field_maxlen varchar(255) NOT NULL DEFAULT '', - field_novalue varchar(255) NOT NULL DEFAULT '', - field_default_value varchar(255) NOT NULL DEFAULT '', - field_validation varchar(20) NOT NULL DEFAULT '', - field_required INTEGER UNSIGNED NOT NULL DEFAULT '0', - field_show_novalue INTEGER UNSIGNED NOT NULL DEFAULT '0', - field_show_on_reg INTEGER UNSIGNED NOT NULL DEFAULT '0', - field_show_on_pm INTEGER UNSIGNED NOT NULL DEFAULT '0', - field_show_on_vt INTEGER UNSIGNED NOT NULL DEFAULT '0', - field_show_profile INTEGER UNSIGNED NOT NULL DEFAULT '0', - field_hide INTEGER UNSIGNED NOT NULL DEFAULT '0', - field_no_view INTEGER UNSIGNED NOT NULL DEFAULT '0', - field_active INTEGER UNSIGNED NOT NULL DEFAULT '0', - field_order INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_profile_fields_fld_type ON phpbb_profile_fields (field_type); -CREATE INDEX phpbb_profile_fields_fld_ordr ON phpbb_profile_fields (field_order); - -# Table: 'phpbb_profile_fields_data' -CREATE TABLE phpbb_profile_fields_data ( - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (user_id) -); - - -# Table: 'phpbb_profile_fields_lang' -CREATE TABLE phpbb_profile_fields_lang ( - field_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - lang_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - option_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - field_type tinyint(4) NOT NULL DEFAULT '0', - lang_value varchar(255) NOT NULL DEFAULT '', - PRIMARY KEY (field_id, lang_id, option_id) -); - - -# Table: 'phpbb_profile_lang' -CREATE TABLE phpbb_profile_lang ( - field_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - lang_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - lang_name varchar(255) NOT NULL DEFAULT '', - lang_explain text(65535) NOT NULL DEFAULT '', - lang_default_value varchar(255) NOT NULL DEFAULT '', - PRIMARY KEY (field_id, lang_id) -); - - -# Table: 'phpbb_ranks' -CREATE TABLE phpbb_ranks ( - rank_id INTEGER PRIMARY KEY NOT NULL , - rank_title varchar(255) NOT NULL DEFAULT '', - rank_min INTEGER UNSIGNED NOT NULL DEFAULT '0', - rank_special INTEGER UNSIGNED NOT NULL DEFAULT '0', - rank_image varchar(255) NOT NULL DEFAULT '' -); - - -# Table: 'phpbb_reports' -CREATE TABLE phpbb_reports ( - report_id INTEGER PRIMARY KEY NOT NULL , - reason_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - post_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - pm_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_notify INTEGER UNSIGNED NOT NULL DEFAULT '0', - report_closed INTEGER UNSIGNED NOT NULL DEFAULT '0', - report_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - report_text mediumtext(16777215) NOT NULL DEFAULT '', - reported_post_text mediumtext(16777215) NOT NULL DEFAULT '', - reported_post_uid varchar(8) NOT NULL DEFAULT '', - reported_post_bitfield varchar(255) NOT NULL DEFAULT '', - reported_post_enable_magic_url INTEGER UNSIGNED NOT NULL DEFAULT '1', - reported_post_enable_smilies INTEGER UNSIGNED NOT NULL DEFAULT '1', - reported_post_enable_bbcode INTEGER UNSIGNED NOT NULL DEFAULT '1' -); - -CREATE INDEX phpbb_reports_post_id ON phpbb_reports (post_id); -CREATE INDEX phpbb_reports_pm_id ON phpbb_reports (pm_id); - -# Table: 'phpbb_reports_reasons' -CREATE TABLE phpbb_reports_reasons ( - reason_id INTEGER PRIMARY KEY NOT NULL , - reason_title varchar(255) NOT NULL DEFAULT '', - reason_description mediumtext(16777215) NOT NULL DEFAULT '', - reason_order INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - - -# Table: 'phpbb_search_results' -CREATE TABLE phpbb_search_results ( - search_key varchar(32) NOT NULL DEFAULT '', - search_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - search_keywords mediumtext(16777215) NOT NULL DEFAULT '', - search_authors mediumtext(16777215) NOT NULL DEFAULT '', - PRIMARY KEY (search_key) -); - - -# Table: 'phpbb_search_wordlist' -CREATE TABLE phpbb_search_wordlist ( - word_id INTEGER PRIMARY KEY NOT NULL , - word_text varchar(255) NOT NULL DEFAULT '', - word_common INTEGER UNSIGNED NOT NULL DEFAULT '0', - word_count INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE UNIQUE INDEX phpbb_search_wordlist_wrd_txt ON phpbb_search_wordlist (word_text); -CREATE INDEX phpbb_search_wordlist_wrd_cnt ON phpbb_search_wordlist (word_count); - -# Table: 'phpbb_search_wordmatch' -CREATE TABLE phpbb_search_wordmatch ( - post_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - word_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - title_match INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE UNIQUE INDEX phpbb_search_wordmatch_unq_mtch ON phpbb_search_wordmatch (word_id, post_id, title_match); -CREATE INDEX phpbb_search_wordmatch_word_id ON phpbb_search_wordmatch (word_id); -CREATE INDEX phpbb_search_wordmatch_post_id ON phpbb_search_wordmatch (post_id); - -# Table: 'phpbb_sessions' -CREATE TABLE phpbb_sessions ( - session_id char(32) NOT NULL DEFAULT '', - session_user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - session_forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - session_last_visit INTEGER UNSIGNED NOT NULL DEFAULT '0', - session_start INTEGER UNSIGNED NOT NULL DEFAULT '0', - session_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - session_ip varchar(40) NOT NULL DEFAULT '', - session_browser varchar(150) NOT NULL DEFAULT '', - session_forwarded_for varchar(255) NOT NULL DEFAULT '', - session_page varchar(255) NOT NULL DEFAULT '', - session_viewonline INTEGER UNSIGNED NOT NULL DEFAULT '1', - session_autologin INTEGER UNSIGNED NOT NULL DEFAULT '0', - session_admin INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (session_id) -); - -CREATE INDEX phpbb_sessions_session_time ON phpbb_sessions (session_time); -CREATE INDEX phpbb_sessions_session_user_id ON phpbb_sessions (session_user_id); -CREATE INDEX phpbb_sessions_session_fid ON phpbb_sessions (session_forum_id); - -# Table: 'phpbb_sessions_keys' -CREATE TABLE phpbb_sessions_keys ( - key_id char(32) NOT NULL DEFAULT '', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - last_ip varchar(40) NOT NULL DEFAULT '', - last_login INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (key_id, user_id) -); - -CREATE INDEX phpbb_sessions_keys_last_login ON phpbb_sessions_keys (last_login); - -# Table: 'phpbb_sitelist' -CREATE TABLE phpbb_sitelist ( - site_id INTEGER PRIMARY KEY NOT NULL , - site_ip varchar(40) NOT NULL DEFAULT '', - site_hostname varchar(255) NOT NULL DEFAULT '', - ip_exclude INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - - -# Table: 'phpbb_smilies' -CREATE TABLE phpbb_smilies ( - smiley_id INTEGER PRIMARY KEY NOT NULL , - code varchar(50) NOT NULL DEFAULT '', - emotion varchar(50) NOT NULL DEFAULT '', - smiley_url varchar(50) NOT NULL DEFAULT '', - smiley_width INTEGER UNSIGNED NOT NULL DEFAULT '0', - smiley_height INTEGER UNSIGNED NOT NULL DEFAULT '0', - smiley_order INTEGER UNSIGNED NOT NULL DEFAULT '0', - display_on_posting INTEGER UNSIGNED NOT NULL DEFAULT '1' -); - -CREATE INDEX phpbb_smilies_display_on_post ON phpbb_smilies (display_on_posting); - -# Table: 'phpbb_styles' -CREATE TABLE phpbb_styles ( - style_id INTEGER PRIMARY KEY NOT NULL , - style_name varchar(255) NOT NULL DEFAULT '', - style_copyright varchar(255) NOT NULL DEFAULT '', - style_active INTEGER UNSIGNED NOT NULL DEFAULT '1', - style_path varchar(100) NOT NULL DEFAULT '', - bbcode_bitfield varchar(255) NOT NULL DEFAULT 'kNg=', - style_parent_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - style_parent_tree text(65535) NOT NULL DEFAULT '' -); - -CREATE UNIQUE INDEX phpbb_styles_style_name ON phpbb_styles (style_name); - -# Table: 'phpbb_teampage' -CREATE TABLE phpbb_teampage ( - teampage_id INTEGER PRIMARY KEY NOT NULL , - group_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - teampage_name varchar(255) NOT NULL DEFAULT '', - teampage_position INTEGER UNSIGNED NOT NULL DEFAULT '0', - teampage_parent INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - - -# Table: 'phpbb_topics' -CREATE TABLE phpbb_topics ( - topic_id INTEGER PRIMARY KEY NOT NULL , - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - icon_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_attachment INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_visibility tinyint(3) NOT NULL DEFAULT '0', - topic_reported INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_title text(65535) NOT NULL DEFAULT '', - topic_poster INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_time_limit INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_views INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_posts_approved INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_posts_unapproved INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_posts_softdeleted INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_status tinyint(3) NOT NULL DEFAULT '0', - topic_type tinyint(3) NOT NULL DEFAULT '0', - topic_first_post_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_first_poster_name varchar(255) NOT NULL DEFAULT '', - topic_first_poster_colour varchar(6) NOT NULL DEFAULT '', - topic_last_post_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_last_poster_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_last_poster_name varchar(255) NOT NULL DEFAULT '', - topic_last_poster_colour varchar(6) NOT NULL DEFAULT '', - topic_last_post_subject text(65535) NOT NULL DEFAULT '', - topic_last_post_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_last_view_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_moved_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_bumped INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_bumper INTEGER UNSIGNED NOT NULL DEFAULT '0', - poll_title text(65535) NOT NULL DEFAULT '', - poll_start INTEGER UNSIGNED NOT NULL DEFAULT '0', - poll_length INTEGER UNSIGNED NOT NULL DEFAULT '0', - poll_max_options tinyint(4) NOT NULL DEFAULT '1', - poll_last_vote INTEGER UNSIGNED NOT NULL DEFAULT '0', - poll_vote_change INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_delete_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_delete_reason text(65535) NOT NULL DEFAULT '', - topic_delete_user INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_topics_forum_id ON phpbb_topics (forum_id); -CREATE INDEX phpbb_topics_forum_id_type ON phpbb_topics (forum_id, topic_type); -CREATE INDEX phpbb_topics_last_post_time ON phpbb_topics (topic_last_post_time); -CREATE INDEX phpbb_topics_topic_visibility ON phpbb_topics (topic_visibility); -CREATE INDEX phpbb_topics_forum_appr_last ON phpbb_topics (forum_id, topic_visibility, topic_last_post_id); -CREATE INDEX phpbb_topics_fid_time_moved ON phpbb_topics (forum_id, topic_last_post_time, topic_moved_id); - -# Table: 'phpbb_topics_track' -CREATE TABLE phpbb_topics_track ( - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - mark_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (user_id, topic_id) -); - -CREATE INDEX phpbb_topics_track_topic_id ON phpbb_topics_track (topic_id); -CREATE INDEX phpbb_topics_track_forum_id ON phpbb_topics_track (forum_id); - -# Table: 'phpbb_topics_posted' -CREATE TABLE phpbb_topics_posted ( - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - topic_posted INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (user_id, topic_id) -); - - -# Table: 'phpbb_topics_watch' -CREATE TABLE phpbb_topics_watch ( - topic_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - notify_status INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_topics_watch_topic_id ON phpbb_topics_watch (topic_id); -CREATE INDEX phpbb_topics_watch_user_id ON phpbb_topics_watch (user_id); -CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch (notify_status); - -# Table: 'phpbb_user_notifications' -CREATE TABLE phpbb_user_notifications ( - item_type varchar(255) NOT NULL DEFAULT '', - item_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - method varchar(255) NOT NULL DEFAULT '', - notify INTEGER UNSIGNED NOT NULL DEFAULT '1' -); - - -# Table: 'phpbb_user_group' -CREATE TABLE phpbb_user_group ( - group_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - group_leader INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_pending INTEGER UNSIGNED NOT NULL DEFAULT '1' -); - -CREATE INDEX phpbb_user_group_group_id ON phpbb_user_group (group_id); -CREATE INDEX phpbb_user_group_user_id ON phpbb_user_group (user_id); -CREATE INDEX phpbb_user_group_group_leader ON phpbb_user_group (group_leader); - -# Table: 'phpbb_users' -CREATE TABLE phpbb_users ( - user_id INTEGER PRIMARY KEY NOT NULL , - user_type tinyint(2) NOT NULL DEFAULT '0', - group_id INTEGER UNSIGNED NOT NULL DEFAULT '3', - user_permissions mediumtext(16777215) NOT NULL DEFAULT '', - user_perm_from INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_ip varchar(40) NOT NULL DEFAULT '', - user_regdate INTEGER UNSIGNED NOT NULL DEFAULT '0', - username varchar(255) NOT NULL DEFAULT '', - username_clean varchar(255) NOT NULL DEFAULT '', - user_password varchar(40) NOT NULL DEFAULT '', - user_passchg INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_pass_convert INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_email varchar(100) NOT NULL DEFAULT '', - user_email_hash bigint(20) NOT NULL DEFAULT '0', - user_birthday varchar(10) NOT NULL DEFAULT '', - user_lastvisit INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_lastmark INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_lastpost_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_lastpage varchar(200) NOT NULL DEFAULT '', - user_last_confirm_key varchar(10) NOT NULL DEFAULT '', - user_last_search INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_warnings tinyint(4) NOT NULL DEFAULT '0', - user_last_warning INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_login_attempts tinyint(4) NOT NULL DEFAULT '0', - user_inactive_reason tinyint(2) NOT NULL DEFAULT '0', - user_inactive_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_posts INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_lang varchar(30) NOT NULL DEFAULT '', - user_timezone varchar(100) NOT NULL DEFAULT 'UTC', - user_dateformat varchar(30) NOT NULL DEFAULT 'd M Y H:i', - user_style INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_rank INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_colour varchar(6) NOT NULL DEFAULT '', - user_new_privmsg int(4) NOT NULL DEFAULT '0', - user_unread_privmsg int(4) NOT NULL DEFAULT '0', - user_last_privmsg INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_message_rules INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_full_folder int(11) NOT NULL DEFAULT '-3', - user_emailtime INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_topic_show_days INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_topic_sortby_type varchar(1) NOT NULL DEFAULT 't', - user_topic_sortby_dir varchar(1) NOT NULL DEFAULT 'd', - user_post_show_days INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_post_sortby_type varchar(1) NOT NULL DEFAULT 't', - user_post_sortby_dir varchar(1) NOT NULL DEFAULT 'a', - user_notify INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_notify_pm INTEGER UNSIGNED NOT NULL DEFAULT '1', - user_notify_type tinyint(4) NOT NULL DEFAULT '0', - user_allow_pm INTEGER UNSIGNED NOT NULL DEFAULT '1', - user_allow_viewonline INTEGER UNSIGNED NOT NULL DEFAULT '1', - user_allow_viewemail INTEGER UNSIGNED NOT NULL DEFAULT '1', - user_allow_massemail INTEGER UNSIGNED NOT NULL DEFAULT '1', - user_options INTEGER UNSIGNED NOT NULL DEFAULT '230271', - user_avatar varchar(255) NOT NULL DEFAULT '', - user_avatar_type varchar(255) NOT NULL DEFAULT '', - user_avatar_width INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_avatar_height INTEGER UNSIGNED NOT NULL DEFAULT '0', - user_sig mediumtext(16777215) NOT NULL DEFAULT '', - user_sig_bbcode_uid varchar(8) NOT NULL DEFAULT '', - user_sig_bbcode_bitfield varchar(255) NOT NULL DEFAULT '', - user_from varchar(100) NOT NULL DEFAULT '', - user_icq varchar(15) NOT NULL DEFAULT '', - user_aim varchar(255) NOT NULL DEFAULT '', - user_yim varchar(255) NOT NULL DEFAULT '', - user_msnm varchar(255) NOT NULL DEFAULT '', - user_jabber varchar(255) NOT NULL DEFAULT '', - user_website varchar(200) NOT NULL DEFAULT '', - user_occ text(65535) NOT NULL DEFAULT '', - user_interests text(65535) NOT NULL DEFAULT '', - user_actkey varchar(32) NOT NULL DEFAULT '', - user_newpasswd varchar(40) NOT NULL DEFAULT '', - user_form_salt varchar(32) NOT NULL DEFAULT '', - user_new INTEGER UNSIGNED NOT NULL DEFAULT '1', - user_reminded tinyint(4) NOT NULL DEFAULT '0', - user_reminded_time INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE INDEX phpbb_users_user_birthday ON phpbb_users (user_birthday); -CREATE INDEX phpbb_users_user_email_hash ON phpbb_users (user_email_hash); -CREATE INDEX phpbb_users_user_type ON phpbb_users (user_type); -CREATE UNIQUE INDEX phpbb_users_username_clean ON phpbb_users (username_clean); - -# Table: 'phpbb_warnings' -CREATE TABLE phpbb_warnings ( - warning_id INTEGER PRIMARY KEY NOT NULL , - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - post_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - log_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - warning_time INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - - -# Table: 'phpbb_words' -CREATE TABLE phpbb_words ( - word_id INTEGER PRIMARY KEY NOT NULL , - word varchar(255) NOT NULL DEFAULT '', - replacement varchar(255) NOT NULL DEFAULT '' -); - - -# Table: 'phpbb_zebra' -CREATE TABLE phpbb_zebra ( - user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - zebra_id INTEGER UNSIGNED NOT NULL DEFAULT '0', - friend INTEGER UNSIGNED NOT NULL DEFAULT '0', - foe INTEGER UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (user_id, zebra_id) -); - - - -COMMIT;
\ No newline at end of file diff --git a/phpBB/language/en/acp/attachments.php b/phpBB/language/en/acp/attachments.php index c7d68d29c2..6ca2865383 100644 --- a/phpBB/language/en/acp/attachments.php +++ b/phpBB/language/en/acp/attachments.php @@ -107,6 +107,9 @@ $lang = array_merge($lang, array( 'EXT_GROUP_REAL_MEDIA' => 'Real Media', 'EXT_GROUP_WINDOWS_MEDIA' => 'Windows Media', + 'FILES_GONE' => 'Some of the attachments you selected for deletion do not exist. They may have been already deleted. Attachments that did exist were deleted.', + 'FILES_STATS_WRONG' => 'Your file statistics are likely inaccurate and need to be resynchronised. Actual values: number of attachments = %1$d, total size of attachments = %2$s.<br />Click %3$shere%4$s to resynchronise them.', + 'GO_TO_EXTENSIONS' => 'Go to extension management screen', 'GROUP_NAME' => 'Group name', @@ -130,6 +133,7 @@ $lang = array_merge($lang, array( 'NOT_ALLOWED_IN_PM' => 'Only allowed in posts', 'NOT_ALLOWED_IN_PM_POST' => 'Not allowed', 'NOT_ASSIGNED' => 'Not assigned', + 'NO_ATTACHMENTS' => 'No attachments found for this period.', 'NO_EXT_GROUP' => 'None', 'NO_EXT_GROUP_NAME' => 'No group name entered', 'NO_EXT_GROUP_SPECIFIED' => 'No extension group specified.', @@ -143,8 +147,9 @@ $lang = array_merge($lang, array( 'ORDER_ALLOW_DENY' => 'Allow', 'ORDER_DENY_ALLOW' => 'Deny', - 'REMOVE_ALLOWED_IPS' => 'Remove or un-exclude <em>allowed</em> IPs/hostnames', - 'REMOVE_DISALLOWED_IPS' => 'Remove or un-exclude <em>disallowed</em> IPs/hostnames', + 'REMOVE_ALLOWED_IPS' => 'Remove or un-exclude <em>allowed</em> IPs/hostnames', + 'REMOVE_DISALLOWED_IPS' => 'Remove or un-exclude <em>disallowed</em> IPs/hostnames', + 'RESYNC_FILES_STATS_CONFIRM' => 'Are you sure you wish to resynchronise file statistics?', 'SEARCH_IMAGICK' => 'Search for Imagemagick', 'SECURE_ALLOW_DENY' => 'Allow/Deny list', diff --git a/phpBB/language/en/acp/ban.php b/phpBB/language/en/acp/ban.php index 2dc0489030..68a68ebe54 100644 --- a/phpBB/language/en/acp/ban.php +++ b/phpBB/language/en/acp/ban.php @@ -73,10 +73,10 @@ $lang = array_merge($lang, array( 'PERMANENT' => 'Permanent', 'UNTIL' => 'Until', - 'USER_BAN' => 'Ban one or more usernames', + 'USER_BAN' => 'Ban one or more users by username', 'USER_BAN_EXCLUDE_EXPLAIN' => 'Enable this to exclude the entered users from all current bans.', 'USER_BAN_EXPLAIN' => 'You can ban multiple users in one go by entering each name on a new line. Use the <span style="text-decoration: underline;">Find a member</span> facility to look up and add one or more users automatically.', 'USER_NO_BANNED' => 'No banned usernames', - 'USER_UNBAN' => 'Un-ban or un-exclude usernames', + 'USER_UNBAN' => 'Un-ban or un-exclude users by username', 'USER_UNBAN_EXPLAIN' => 'You can unban (or un-exclude) multiple users in one go using the appropriate combination of mouse and keyboard for your computer and browser. Excluded users are emphasised.', )); diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index f786374ba6..e21d959e40 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -45,7 +45,7 @@ $lang = array_merge($lang, array( 'DEFAULT_LANGUAGE' => 'Default language', 'DEFAULT_STYLE' => 'Default style', 'DISABLE_BOARD' => 'Disable board', - 'DISABLE_BOARD_EXPLAIN' => 'This will make the board unavailable to users. You can also enter a short (255 character) message to display if you wish.', + 'DISABLE_BOARD_EXPLAIN' => 'This will make the board unavailable to users who are neither administrators nor moderators. You can also enter a short (255 character) message to display if you wish.', 'DISPLAY_LAST_SUBJECT' => 'Display subject of last added post on forum list', 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'The subject of the last added post will be displayed in the forum list with a hyperlink to the post. Subjects from password protected forums and forums in which user doesn’t have read access are not shown.', 'OVERRIDE_STYLE' => 'Override user style', @@ -111,7 +111,7 @@ $lang = array_merge($lang, array( 'AVATAR_GALLERY_PATH' => 'Avatar gallery path', 'AVATAR_GALLERY_PATH_EXPLAIN' => 'Path under your phpBB root directory for pre-loaded images, e.g. <samp>images/avatars/gallery</samp>.', 'AVATAR_STORAGE_PATH' => 'Avatar storage path', - 'AVATAR_STORAGE_PATH_EXPLAIN' => 'Path under your phpBB root directory, e.g. <samp>images/avatars/upload</samp>.', + 'AVATAR_STORAGE_PATH_EXPLAIN' => 'Path under your phpBB root directory, e.g. <samp>images/avatars/upload</samp>.<br />Avatar uploading <strong>will not be available</strong> if this path is not writable.', 'MAX_AVATAR_SIZE' => 'Maximum avatar dimensions', 'MAX_AVATAR_SIZE_EXPLAIN' => 'Width x Height in pixels.', 'MAX_FILESIZE' => 'Maximum avatar file size', @@ -354,6 +354,8 @@ $lang = array_merge($lang, array( $lang = array_merge($lang, array( 'ACP_LOAD_SETTINGS_EXPLAIN' => 'Here you can enable and disable certain board functions to reduce the amount of processing required. On most servers there is no need to disable any functions. However on certain systems or in shared hosting environments it may be beneficial to disable capabilities you do not really need. You can also specify limits for system load and active sessions beyond which the board will go offline.', + 'ALLOW_CDN' => 'Allow usage of third party content delivery networks', + 'ALLOW_CDN_EXPLAIN' => 'If this setting is enabled, some files will be served from external third party servers instead of your server. This reduces the network bandwidth required by your server, but may present a privacy issue for some board administrators. In a default phpBB installation, this includes loading “jQuery” and the font “Open Sans” from Google’s content delivery network.', 'CUSTOM_PROFILE_FIELDS' => 'Custom profile fields', 'LIMIT_LOAD' => 'Limit system load', 'LIMIT_LOAD_EXPLAIN' => 'If the system’s 1-minute load average exceeds this value the board will automatically go offline. A value of 1.0 equals ~100% utilisation of one processor. This only functions on UNIX based servers and where this information is accessible. The value here resets itself to 0 if phpBB was unable to get the load limit.', @@ -363,8 +365,6 @@ $lang = array_merge($lang, array( 'LOAD_CPF_PM' => 'Display custom profile fields in private messages', 'LOAD_CPF_VIEWPROFILE' => 'Display custom profile fields in user profiles', 'LOAD_CPF_VIEWTOPIC' => 'Display custom profile fields on topic pages', - 'LOAD_JQUERY_CDN' => 'Serve jQuery using Google’s CDN', - 'LOAD_JQUERY_CDN_EXPLAIN' => 'If this setting is enabled, jQuery will be served from Google’s AJAX API CDN instead of the copy included with phpBB on your server. If the CDN fails, phpBB will attempt to fall back to the copy included with phpBB.', 'LOAD_USER_ACTIVITY' => 'Show user’s activity', 'LOAD_USER_ACTIVITY_EXPLAIN' => 'Displays active topic/forum in user profiles and user control panel. It is recommended to disable this on boards with more than one million posts.', 'READ_NOTIFICATION_EXPIRE_DAYS' => 'Read Notification Expiration', @@ -524,6 +524,8 @@ $lang = array_merge($lang, array( 'BOARD_HIDE_EMAILS_EXPLAIN' => 'This function keeps email addresses completely private.', 'CONTACT_EMAIL' => 'Contact email address', 'CONTACT_EMAIL_EXPLAIN' => 'This address will be used whenever a specific contact point is needed, e.g. spam, error output, etc. It will always be used as the <samp>From</samp> and <samp>Reply-To</samp> address in emails.', + 'CONTACT_EMAIL_NAME' => 'Contact name', + 'CONTACT_EMAIL_NAME_EXPLAIN' => 'This is the contact name that e-mail recipients will see. If you don’t want to have a contact name, leave this field empty.', 'EMAIL_FUNCTION_NAME' => 'Email function name', 'EMAIL_FUNCTION_NAME_EXPLAIN' => 'The email function used to send mails through PHP.', 'EMAIL_PACKAGE_SIZE' => 'Email package size', diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index 9c470efcd9..6f6a5f901f 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -49,7 +49,7 @@ $lang = array_merge($lang, array( 'ACP_BAN' => 'Banning', 'ACP_BAN_EMAILS' => 'Ban emails', 'ACP_BAN_IPS' => 'Ban IPs', - 'ACP_BAN_USERNAMES' => 'Ban usernames', + 'ACP_BAN_USERNAMES' => 'Ban users', 'ACP_BBCODES' => 'BBCodes', 'ACP_BOARD_CONFIGURATION' => 'Board configuration', 'ACP_BOARD_FEATURES' => 'Board features', @@ -61,7 +61,7 @@ $lang = array_merge($lang, array( 'ACP_CAT_CUSTOMISE' => 'Customise', 'ACP_CAT_DATABASE' => 'Database', - 'ACP_CAT_DOT_MODS' => '.MODs', + 'ACP_CAT_DOT_MODS' => 'Extensions', 'ACP_CAT_FORUMS' => 'Forums', 'ACP_CAT_GENERAL' => 'General', 'ACP_CAT_MAINTENANCE' => 'Maintenance', @@ -83,8 +83,7 @@ $lang = array_merge($lang, array( 'ACP_EMAIL_SETTINGS' => 'Email settings', 'ACP_EXTENSION_GROUPS' => 'Manage attachment extension groups', 'ACP_EXTENSION_MANAGEMENT' => 'Extension management', - 'ACP_EXTENSIONS' => 'Extensions', - + 'ACP_EXTENSIONS' => 'Manage extensions', 'ACP_FORUM_BASED_PERMISSIONS' => 'Forum based permissions', 'ACP_FORUM_LOGS' => 'Forum logs', @@ -241,9 +240,6 @@ $lang = array_merge($lang, array( 'EXPORT_DOWNLOAD' => 'Download', 'EXPORT_STORE' => 'Store', - 'FILES_GONE' => 'Some of the attachments you selected for deletion do not exist. They may have been already deleted. Attachments that did exist were deleted.', - 'FILES_STATS_WRONG' => 'Your files statistics are probably inaccurate and need to be resynchronised. Actual values: number of attachments = %1$d, total size of attachments = %2$s.', - 'GENERAL_OPTIONS' => 'General options', 'GENERAL_SETTINGS' => 'General settings', 'GLOBAL_MASK' => 'Global permission mask', @@ -286,9 +282,6 @@ $lang = array_merge($lang, array( 'REMIND' => 'Remind', 'RESYNC' => 'Resynchronise', - 'RESYNC_FILES_STATS' => 'Resynchronise files statistics', - 'RESYNC_FILES_STATS_EXPLAIN' => 'Recalculates the total number and size of files attached to posts and private messages.', - 'RETURN_TO' => 'Return to…', 'SELECT_ANONYMOUS' => 'Select anonymous user', 'SELECT_OPTION' => 'Select option', @@ -361,6 +354,7 @@ $lang = array_merge($lang, array( 'GZIP_COMPRESSION' => 'GZip compression', + 'NO_SEARCH_INDEX' => 'The selected search backend does not have a search index.<br />Please create the index for “%1$s” in the %2$ssearch index%3$s section.', 'NOT_AVAILABLE' => 'Not available', 'NUMBER_FILES' => 'Number of attachments', 'NUMBER_POSTS' => 'Number of posts', @@ -388,7 +382,6 @@ $lang = array_merge($lang, array( 'RESET_ONLINE' => 'Reset most users ever online', 'RESET_ONLINE_CONFIRM' => 'Are you sure you wish to reset the most users ever online counter?', 'RESET_ONLINE_SUCCESS' => 'Most users ever online reset', - 'RESYNC_FILES_STATS_CONFIRM' => 'Are you sure you wish to resynchronise files statistics?', 'RESYNC_POSTCOUNTS' => 'Resynchronise post counts', 'RESYNC_POSTCOUNTS_EXPLAIN' => 'Only existing posts will be taken into consideration. Pruned posts will not be counted.', 'RESYNC_POSTCOUNTS_CONFIRM' => 'Are you sure you wish to resynchronise post counts?', @@ -557,7 +550,7 @@ $lang = array_merge($lang, array( 'LOG_PM_REPORT_CLOSED' => '<strong>Closed PM report</strong><br />» %s', 'LOG_PM_REPORT_DELETED' => '<strong>Deleted PM report</strong><br />» %s', 'LOG_POST_APPROVED' => '<strong>Approved post</strong><br />» %s', - 'LOG_POST_DISAPPROVED' => '<strong>Disapproved post “%1$s” with the following reason</strong><br />» %2$s', + 'LOG_POST_DISAPPROVED' => '<strong>Disapproved post “%1$s” written by “%3$s” for the following reason</strong><br />» %2$s', 'LOG_POST_EDITED' => '<strong>Edited post “%1$s” written by</strong><br />» %2$s', 'LOG_POST_RESTORED' => '<strong>Restored post</strong><br />» %s', 'LOG_REPORT_CLOSED' => '<strong>Closed report</strong><br />» %s', @@ -570,7 +563,7 @@ $lang = array_merge($lang, array( 'LOG_TOPIC_APPROVED' => '<strong>Approved topic</strong><br />» %s', 'LOG_TOPIC_RESTORED' => '<strong>Restored topic</strong><br />» %s', - 'LOG_TOPIC_DISAPPROVED' => '<strong>Disapproved topic “%1$s” with the following reason</strong><br />%2$s', + 'LOG_TOPIC_DISAPPROVED' => '<strong>Disapproved topic “%1$s” written by “%3$s” for the following reason</strong><br />» %2$s', 'LOG_TOPIC_RESYNC' => '<strong>Resynchronised topic counters</strong><br />» %s', 'LOG_TOPIC_TYPE_CHANGED' => '<strong>Changed topic type</strong><br />» %s', 'LOG_UNLOCK' => '<strong>Unlocked topic</strong><br />» %s', @@ -666,6 +659,8 @@ $lang = array_merge($lang, array( 'LOG_U_ROLE_EDIT' => '<strong>User role edited</strong><br />» %s', 'LOG_U_ROLE_REMOVED' => '<strong>User role removed</strong><br />» %s', + 'LOG_PLUPLOAD_TIDY_FAILED' => '<strong>Unable to open %1$s for tidying, check permissions.</strong><br />Exception: %2$s<br />Trace: %3$s', + 'LOG_PROFILE_FIELD_ACTIVATE' => '<strong>Profile field activated</strong><br />» %s', 'LOG_PROFILE_FIELD_CREATE' => '<strong>Profile field added</strong><br />» %s', 'LOG_PROFILE_FIELD_DEACTIVATE' => '<strong>Profile field deactivated</strong><br />» %s', @@ -674,6 +669,7 @@ $lang = array_merge($lang, array( 'LOG_PRUNE' => '<strong>Pruned forums</strong><br />» %s', 'LOG_AUTO_PRUNE' => '<strong>Auto-pruned forums</strong><br />» %s', + 'LOG_PRUNE_SHADOW' => '<strong>Auto-pruned shadow topics</strong><br />» %s', 'LOG_PRUNE_USER_DEAC' => '<strong>Users deactivated</strong><br />» %s', 'LOG_PRUNE_USER_DEL_DEL' => '<strong>Users pruned and posts deleted</strong><br />» %s', 'LOG_PRUNE_USER_DEL_ANON' => '<strong>Users pruned and posts retained</strong><br />» %s', @@ -681,7 +677,6 @@ $lang = array_merge($lang, array( 'LOG_PURGE_CACHE' => '<strong>Purged cache</strong>', 'LOG_PURGE_SESSIONS' => '<strong>Purged sessions</strong>', - 'LOG_RANK_ADDED' => '<strong>Added new rank</strong><br />» %s', 'LOG_RANK_REMOVED' => '<strong>Removed rank</strong><br />» %s', 'LOG_RANK_UPDATED' => '<strong>Updated rank</strong><br />» %s', @@ -693,7 +688,7 @@ $lang = array_merge($lang, array( 'LOG_REFERER_INVALID' => '<strong>Referer validation failed</strong><br />»Referer was “<em>%1$s</em>”. The request was rejected and the session killed.', 'LOG_RESET_DATE' => '<strong>Board start date reset</strong>', 'LOG_RESET_ONLINE' => '<strong>Most users online reset</strong>', - 'LOG_RESYNC_FILES_STATS' => '<strong>Files statistics resynchronised</strong>', + 'LOG_RESYNC_FILES_STATS' => '<strong>File statistics resynchronised</strong>', 'LOG_RESYNC_POSTCOUNTS' => '<strong>User post counts resynchronised</strong>', 'LOG_RESYNC_POST_MARKING' => '<strong>Dotted topics resynchronised</strong>', 'LOG_RESYNC_STATS' => '<strong>Post, topic and user statistics resynchronised</strong>', @@ -773,7 +768,10 @@ $lang = array_merge($lang, array( 'LOG_USER_GROUP_RESIGN' => '<strong>User resigned membership from group</strong><br />» %s', 'LOG_WARNING_DELETED' => '<strong>Deleted user warning</strong><br />» %s', - 'LOG_WARNINGS_DELETED' => '<strong>Deleted %2$s user warnings</strong><br />» %1$s', // Example: '<strong>Deleted 2 user warnings</strong><br />» username' + 'LOG_WARNINGS_DELETED' => array( + 1 => '<strong>Deleted user warning</strong><br />» %1$s', + 2 => '<strong>Deleted %2$d user warnings</strong><br />» %1$s', // Example: '<strong>Deleted 2 user warnings</strong><br />» username' + ), 'LOG_WARNINGS_DELETED_ALL' => '<strong>Deleted all user warnings</strong><br />» %s', 'LOG_WORD_ADD' => '<strong>Added word censor</strong><br />» %s', diff --git a/phpBB/language/en/acp/extensions.php b/phpBB/language/en/acp/extensions.php index 0adaff10c8..39881668c4 100644 --- a/phpBB/language/en/acp/extensions.php +++ b/phpBB/language/en/acp/extensions.php @@ -33,53 +33,58 @@ if (empty($lang) || !is_array($lang)) // equally where a string contains only two placeholders which are used to wrap text // in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine - $lang = array_merge($lang, array( 'EXTENSION' => 'Extension', 'EXTENSIONS' => 'Extensions', 'EXTENSIONS_ADMIN' => 'Extensions Manager', 'EXTENSIONS_EXPLAIN' => 'The Extensions Manager is a tool in your phpBB Board which allows you to manage all of your extensions statuses and view information about them.', - 'EXTENSION_INVALID_LIST' => 'The "%s" extension is not valid.<br /><p>%s</p>', + 'EXTENSION_INVALID_LIST' => 'The “%s” extension is not valid.<br />%s<br /><br />', 'EXTENSION_NOT_AVAILABLE' => 'The selected extension is not available for this board, please verify your phpBB and PHP versions are allowed (see the details page).', + 'EXTENSION_DIR_INVALID' => 'The selected extension has an invalid directory structure and cannot be enabled.', 'DETAILS' => 'Details', - 'AVAILABLE' => 'Available', - 'ENABLED' => 'Enabled', - 'DISABLED' => 'Disabled', - 'PURGED' => 'Purged', - 'UPLOADED' => 'Uploaded', + 'EXTENSIONS_DISABLED' => 'Disabled Extensions', + 'EXTENSIONS_ENABLED' => 'Enabled Extensions', - 'ENABLE' => 'Enable', - 'DISABLE' => 'Disable', - 'PURGE' => 'Purge', + 'EXTENSION_DELETE_DATA' => 'Delete data', + 'EXTENSION_DISABLE' => 'Disable', + 'EXTENSION_ENABLE' => 'Enable', - 'ENABLE_EXPLAIN' => 'Enabling an extension allows you to use it on your board.', - 'DISABLE_EXPLAIN' => 'Disabling an extension retains its files and settings but removes any functionality added by the extension.', - 'PURGE_EXPLAIN' => 'Purging an extension clears an extensions data while retaining its files.', - 'DELETE_EXPLAIN' => 'Deleting an extension removes all of its files and settings. Log entries will remain, although any language variables added by the extension will not be available.', + 'EXTENSION_DELETE_DATA_EXPLAIN' => 'Deleting an extension’s data removes all of its data and settings. The extension files are retained so it can be enabled again.', + 'EXTENSION_DISABLE_EXPLAIN' => 'Disabling an extension retains its files, data and settings but removes any functionality added by the extension.', + 'EXTENSION_ENABLE_EXPLAIN' => 'Enabling an extension allows you to use it on your board.', - 'DISABLE_IN_PROGRESS' => 'The extension is currently being disabled, please do not leave this page or refresh until it is completed.', - 'ENABLE_IN_PROGRESS' => 'The extension is currently being installed, please do not leave this page or refresh until it is completed.', - 'PURGE_IN_PROGRESS' => 'The extension is currently being purged, please do not leave this page or refresh until it is completed.', - 'ENABLE_SUCCESS' => 'The extension was enabled successfully', - 'DISABLE_SUCCESS' => 'The extension was disabled successfully', - 'PURGE_SUCCESS' => 'The extension was purged successfully', + 'EXTENSION_DELETE_DATA_IN_PROGRESS' => 'The extension’s data is currently being deleted. Please do not leave or refresh this page until it is completed.', + 'EXTENSION_DISABLE_IN_PROGRESS' => 'The extension is currently being disabled. Please do not leave or refresh this page until it is completed.', + 'EXTENSION_ENABLE_IN_PROGRESS' => 'The extension is currently being enabled. Please do not leave or refresh this page until it is completed.', - 'ENABLE_FAIL' => 'The extension could not be enabled', - 'DISABLE_FAIL' => 'The extension could not be disabled', - 'PURGE_FAIL' => 'The extension could not be purged', + 'EXTENSION_DELETE_DATA_SUCCESS' => 'The extension’s data was deleted successfully', + 'EXTENSION_DISABLE_SUCCESS' => 'The extension was disabled successfully', + 'EXTENSION_ENABLE_SUCCESS' => 'The extension was enabled successfully', - 'EXTENSION_NAME' => 'Extension Name', - 'EXTENSION_ACTIONS' => 'Actions', - 'EXTENSION_OPTIONS' => 'Options', + 'EXTENSION_NAME' => 'Extension Name', + 'EXTENSION_ACTIONS' => 'Actions', + 'EXTENSION_OPTIONS' => 'Options', + 'EXTENSION_UPDATE_HEADLINE' => 'Updating an extension', + 'EXTENSION_UPDATE_EXPLAIN' => '<ol> + <li>Disable the extension</li> + <li>Delete the extension’s files from the filesystem</li> + <li>Upload the new files</li> + <li>Enable the extension</li> + </ol>', + 'EXTENSION_REMOVE_HEADLINE' => 'Completly removing an extension from your board', + 'EXTENSION_REMOVE_EXPLAIN' => '<ol> + <li>Disable the extension</li> + <li>Delete the extension’s data</li> + <li>Delete the extension’s files from the filesystem</li> + </ol>', - 'ENABLE_CONFIRM' => 'Are you sure that you wish to enable this extension?', - 'DISABLE_CONFIRM' => 'Are you sure that you wish to disable this extension?', - 'PURGE_CONFIRM' => 'Are you sure that you wish to purge this extension's data? This will remove all settings stored for this extension and cannot be undone!', + 'EXTENSION_DELETE_DATA_CONFIRM' => 'Are you sure that you wish to delete the data associated with “%s”?<br /><br />This removes all of its data and settings and cannot be undone!', + 'EXTENSION_DISABLE_CONFIRM' => 'Are you sure that you wish to disable the “%s” extension?', + 'EXTENSION_ENABLE_CONFIRM' => 'Are you sure that you wish to enable the “%s” extension?', - 'WARNING' => 'Warning', - 'RETURN' => 'Return', + 'RETURN_TO_EXTENSION_LIST' => 'Return to the extension list', 'EXT_DETAILS' => 'Extension Details', 'DISPLAY_NAME' => 'Display Name', @@ -90,7 +95,7 @@ $lang = array_merge($lang, array( 'HOMEPAGE' => 'Homepage', 'PATH' => 'File Path', 'TIME' => 'Release Time', - 'LICENCE' => 'Licence', + 'LICENSE' => 'Licence', 'REQUIREMENTS' => 'Requirements', 'PHPBB_VERSION' => 'phpBB Version', diff --git a/phpBB/language/en/acp/forums.php b/phpBB/language/en/acp/forums.php index 756cb7ae0f..d64380b6b6 100644 --- a/phpBB/language/en/acp/forums.php +++ b/phpBB/language/en/acp/forums.php @@ -101,6 +101,8 @@ $lang = array_merge($lang, array( 'FORUM_PASSWORD_OLD' => 'The forum password is using an old hashing method and should be changed.', 'FORUM_PASSWORD_MISMATCH' => 'The passwords you entered did not match.', 'FORUM_PRUNE_SETTINGS' => 'Forum prune settings', + 'FORUM_PRUNE_SHADOW' => 'Enable auto-pruning of shadow topics', + 'FORUM_PRUNE_SHADOW_EXPLAIN' => 'Prunes the forum of shadow topics, set the frequency/age parameters below.', 'FORUM_RESYNCED' => 'Forum “%s” successfully resynced', 'FORUM_RULES_EXPLAIN' => 'Forum rules are displayed at any page within the given forum.', 'FORUM_RULES_LINK' => 'Link to forum rules', diff --git a/phpBB/language/en/acp/permissions.php b/phpBB/language/en/acp/permissions.php index 709836e828..36af461f87 100644 --- a/phpBB/language/en/acp/permissions.php +++ b/phpBB/language/en/acp/permissions.php @@ -57,7 +57,7 @@ $lang = array_merge($lang, array( 'ACL_NEVER' => 'Never', 'ACL_SET' => 'Setting permissions', - 'ACL_SET_EXPLAIN' => 'Permissions are based on a simple <samp>YES</samp>/<samp>NO</samp> system. Setting an option to <samp>NEVER</samp> for a user or usergroup overrides any other value assigned to it. If you do not wish to assign a value for an option for this user or group select <samp>NO</samp>. If values are assigned for this option elsewhere they will be used in preference, else <samp>NEVER</samp> is assumed. All objects marked (with the checkbox in front of them) will copy the permission set you defined.', + 'ACL_SET_EXPLAIN' => 'Permissions are based on a simple <strong>YES</strong>/<strong>NO</strong> system. Setting an option to <strong>NEVER</strong> for a user or usergroup overrides any other value assigned to it. If you do not wish to assign a value for an option for this user or group select <strong>NO</strong>. If values are assigned for this option elsewhere they will be used in preference, else <strong>NEVER</strong> is assumed. All objects marked (with the checkbox in front of them) will copy the permission set you defined.', 'ACL_SETTING' => 'Setting', 'ACL_TYPE_A_' => 'Administrative permissions', @@ -100,10 +100,10 @@ $lang = array_merge($lang, array( 'ADD_USERS' => 'Add users', 'ADVANCED_PERMISSIONS' => 'Advanced Permissions', 'ALL_GROUPS' => 'Select all groups', - 'ALL_NEVER' => 'All <samp>NEVER</samp>', - 'ALL_NO' => 'All <samp>NO</samp>', + 'ALL_NEVER' => 'All <strong>NEVER</strong>', + 'ALL_NO' => 'All <strong>NO</strong>', 'ALL_USERS' => 'Select all users', - 'ALL_YES' => 'All <samp>YES</samp>', + 'ALL_YES' => 'All <strong>YES</strong>', 'APPLY_ALL_PERMISSIONS' => 'Apply all permissions', 'APPLY_PERMISSIONS' => 'Apply permissions', 'APPLY_PERMISSIONS_EXPLAIN' => 'The permissions and role defined for this item will only be applied to this item and all checked items.', @@ -137,7 +137,7 @@ $lang = array_merge($lang, array( 'NO_AUTH_SETTING_FOUND' => 'Permission settings not defined.', 'NO_ROLE_ASSIGNED' => 'No role assigned…', - 'NO_ROLE_ASSIGNED_EXPLAIN' => 'Setting to this role does not change permissions on the right. If you want to unset/remove all permissions you should use the “All <samp>NO</samp>” link.', + 'NO_ROLE_ASSIGNED_EXPLAIN' => 'Setting to this role does not change permissions on the right. If you want to unset/remove all permissions you should use the “All <strong>NO</strong>” link.', 'NO_ROLE_AVAILABLE' => 'No role available', 'NO_ROLE_NAME_SPECIFIED' => 'Please give the role a name.', 'NO_ROLE_SELECTED' => 'Role could not be found.', @@ -182,7 +182,6 @@ $lang = array_merge($lang, array( 'ROLE_USER_STANDARD' => 'Standard Features', 'ROLE_USER_NEW_MEMBER' => 'Newly Registered User Features', - 'ROLE_DESCRIPTION_ADMIN_FORUM' => 'Can access the forum management and forum permission settings.', 'ROLE_DESCRIPTION_ADMIN_FULL' => 'Has access to all administrative functions of this board.<br />Not recommended.', 'ROLE_DESCRIPTION_ADMIN_STANDARD' => 'Has access to most administrative features but is not allowed to use server or system related tools.', @@ -196,7 +195,7 @@ $lang = array_merge($lang, array( 'ROLE_DESCRIPTION_FORUM_POLLS' => 'Like Standard Access but can also create polls.', 'ROLE_DESCRIPTION_FORUM_READONLY' => 'Can read the forum, but cannot create new topics or reply to posts.', 'ROLE_DESCRIPTION_FORUM_STANDARD' => 'Can use most forum features including attachments and deleting own topics, but cannot lock own topics, and cannot create polls.', - 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER' => 'A role for members of the special newly registered users group; contains <samp>NEVER</samp> permissions to lock features for new users.', + 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER' => 'A role for members of the special newly registered users group; contains <strong>NEVER</strong> permissions to lock features for new users.', 'ROLE_DESCRIPTION_MOD_FULL' => 'Can use all moderating features, including banning.', 'ROLE_DESCRIPTION_MOD_QUEUE' => 'Can use the Moderation Queue to validate and edit posts, but nothing else.', 'ROLE_DESCRIPTION_MOD_SIMPLE' => 'Can only use basic topic actions. Cannot send warnings or use moderation queue.', @@ -206,7 +205,7 @@ $lang = array_merge($lang, array( 'ROLE_DESCRIPTION_USER_NOAVATAR' => 'Has a limited feature set and is not allowed to use the Avatar feature.', 'ROLE_DESCRIPTION_USER_NOPM' => 'Has a limited feature set, and is not allowed to use Private Messages.', 'ROLE_DESCRIPTION_USER_STANDARD' => 'Can access most but not all user features. Cannot change user name or ignore the flood limit, for instance.', - 'ROLE_DESCRIPTION_USER_NEW_MEMBER' => 'A role for members of the special newly registered users group; contains <samp>NEVER</samp> permissions to lock features for new users.', + 'ROLE_DESCRIPTION_USER_NEW_MEMBER' => 'A role for members of the special newly registered users group; contains <strong>NEVER</strong> permissions to lock features for new users.', 'ROLE_DESCRIPTION_EXPLAIN' => 'You are able to enter a short explanation of what the role is doing or for what it is meant for. The text you enter here will be displayed within the permissions screens too.', 'ROLE_DESCRIPTION_LONG' => 'The role description is too long, please limit it to 4000 characters.', @@ -227,48 +226,48 @@ $lang = array_merge($lang, array( 'SET_USERS_PERMISSIONS' => 'Set user permissions', 'SET_USERS_FORUM_PERMISSIONS' => 'Set user forum permissions', - 'TRACE_DEFAULT' => 'By default every permission is <samp>NO</samp> (unset). So the permission can be overwritten by other settings.', + 'TRACE_DEFAULT' => 'By default every permission is <strong>NO</strong> (unset). So the permission can be overwritten by other settings.', 'TRACE_FOR' => 'Trace for', 'TRACE_GLOBAL_SETTING' => '%s (global)', - 'TRACE_GROUP_NEVER_TOTAL_NEVER' => 'This group’s permission is set to <samp>NEVER</samp> like the total result so the old result is kept.', - 'TRACE_GROUP_NEVER_TOTAL_NEVER_LOCAL' => 'This group’s permission for this forum is set to <samp>NEVER</samp> like the total result so the old result is kept.', - 'TRACE_GROUP_NEVER_TOTAL_NO' => 'This group’s permission is set to <samp>NEVER</samp> which becomes the new total value because it wasn’t set yet (set to <samp>NO</samp>).', - 'TRACE_GROUP_NEVER_TOTAL_NO_LOCAL' => 'This group’s permission for this forum is set to <samp>NEVER</samp> which becomes the new total value because it wasn’t set yet (set to <samp>NO</samp>).', - 'TRACE_GROUP_NEVER_TOTAL_YES' => 'This group’s permission is set to <samp>NEVER</samp> which overwrites the total <samp>YES</samp> to a <samp>NEVER</samp> for this user.', - 'TRACE_GROUP_NEVER_TOTAL_YES_LOCAL' => 'This group’s permission for this forum is set to <samp>NEVER</samp> which overwrites the total <samp>YES</samp> to a <samp>NEVER</samp> for this user.', - 'TRACE_GROUP_NO' => 'The permission is <samp>NO</samp> for this group so the old total value is kept.', - 'TRACE_GROUP_NO_LOCAL' => 'The permission is <samp>NO</samp> for this group within this forum so the old total value is kept.', - 'TRACE_GROUP_YES_TOTAL_NEVER' => 'This group’s permission is set to <samp>YES</samp> but the total <samp>NEVER</samp> cannot be overwritten.', - 'TRACE_GROUP_YES_TOTAL_NEVER_LOCAL' => 'This group’s permission for this forum is set to <samp>YES</samp> but the total <samp>NEVER</samp> cannot be overwritten.', - 'TRACE_GROUP_YES_TOTAL_NO' => 'This group’s permission is set to <samp>YES</samp> which becomes the new total value because it wasn’t set yet (set to <samp>NO</samp>).', - 'TRACE_GROUP_YES_TOTAL_NO_LOCAL' => 'This group’s permission for this forum is set to <samp>YES</samp> which becomes the new total value because it wasn’t set yet (set to <samp>NO</samp>).', - 'TRACE_GROUP_YES_TOTAL_YES' => 'This group’s permission is set to <samp>YES</samp> and the total permission is already set to <samp>YES</samp>, so the total result is kept.', - 'TRACE_GROUP_YES_TOTAL_YES_LOCAL' => 'This group’s permission for this forum is set to <samp>YES</samp> and the total permission is already set to <samp>YES</samp>, so the total result is kept.', + 'TRACE_GROUP_NEVER_TOTAL_NEVER' => 'This group’s permission is set to <strong>NEVER</strong> like the total result so the old result is kept.', + 'TRACE_GROUP_NEVER_TOTAL_NEVER_LOCAL' => 'This group’s permission for this forum is set to <strong>NEVER</strong> like the total result so the old result is kept.', + 'TRACE_GROUP_NEVER_TOTAL_NO' => 'This group’s permission is set to <strong>NEVER</strong> which becomes the new total value because it wasn’t set yet (set to <strong>NO</strong>).', + 'TRACE_GROUP_NEVER_TOTAL_NO_LOCAL' => 'This group’s permission for this forum is set to <strong>NEVER</strong> which becomes the new total value because it wasn’t set yet (set to <strong>NO</strong>).', + 'TRACE_GROUP_NEVER_TOTAL_YES' => 'This group’s permission is set to <strong>NEVER</strong> which overwrites the total <strong>YES</strong> to a <strong>NEVER</strong> for this user.', + 'TRACE_GROUP_NEVER_TOTAL_YES_LOCAL' => 'This group’s permission for this forum is set to <strong>NEVER</strong> which overwrites the total <strong>YES</strong> to a <strong>NEVER</strong> for this user.', + 'TRACE_GROUP_NO' => 'The permission is <strong>NO</strong> for this group so the old total value is kept.', + 'TRACE_GROUP_NO_LOCAL' => 'The permission is <strong>NO</strong> for this group within this forum so the old total value is kept.', + 'TRACE_GROUP_YES_TOTAL_NEVER' => 'This group’s permission is set to <strong>YES</strong> but the total <strong>NEVER</strong> cannot be overwritten.', + 'TRACE_GROUP_YES_TOTAL_NEVER_LOCAL' => 'This group’s permission for this forum is set to <strong>YES</strong> but the total <strong>NEVER</strong> cannot be overwritten.', + 'TRACE_GROUP_YES_TOTAL_NO' => 'This group’s permission is set to <strong>YES</strong> which becomes the new total value because it wasn’t set yet (set to <strong>NO</strong>).', + 'TRACE_GROUP_YES_TOTAL_NO_LOCAL' => 'This group’s permission for this forum is set to <strong>YES</strong> which becomes the new total value because it wasn’t set yet (set to <strong>NO</strong>).', + 'TRACE_GROUP_YES_TOTAL_YES' => 'This group’s permission is set to <strong>YES</strong> and the total permission is already set to <strong>YES</strong>, so the total result is kept.', + 'TRACE_GROUP_YES_TOTAL_YES_LOCAL' => 'This group’s permission for this forum is set to <strong>YES</strong> and the total permission is already set to <strong>YES</strong>, so the total result is kept.', 'TRACE_PERMISSION' => 'Trace permission - %s', 'TRACE_RESULT' => 'Trace result', 'TRACE_SETTING' => 'Trace setting', - 'TRACE_USER_GLOBAL_YES_TOTAL_YES' => 'The forum independent user permission evaluates to <samp>YES</samp> but the total permission is already set to <samp>YES</samp>, so the total result is kept. %sTrace global permission%s', - 'TRACE_USER_GLOBAL_YES_TOTAL_NEVER' => 'The forum independent user permission evaluates to <samp>YES</samp> which overwrites the current local result <samp>NEVER</samp>. %sTrace global permission%s', - 'TRACE_USER_GLOBAL_NEVER_TOTAL_KEPT' => 'The forum independent user permission evaluates to <samp>NEVER</samp> which doesn’t influence the local permission. %sTrace global permission%s', - - 'TRACE_USER_FOUNDER' => 'The user is a founder, therefore admin permissions are always set to <samp>YES</samp>.', - 'TRACE_USER_KEPT' => 'The user’s permission is <samp>NO</samp> so the old total value is kept.', - 'TRACE_USER_KEPT_LOCAL' => 'The user’s permission for this forum is <samp>NO</samp> so the old total value is kept.', - 'TRACE_USER_NEVER_TOTAL_NEVER' => 'The user’s permission is set to <samp>NEVER</samp> and the total value is set to <samp>NEVER</samp>, so nothing is changed.', - 'TRACE_USER_NEVER_TOTAL_NEVER_LOCAL' => 'The user’s permission for this forum is set to <samp>NEVER</samp> and the total value is set to <samp>NEVER</samp>, so nothing is changed.', - 'TRACE_USER_NEVER_TOTAL_NO' => 'The user’s permission is set to <samp>NEVER</samp> which becomes the total value because it was set to NO.', - 'TRACE_USER_NEVER_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is set to <samp>NEVER</samp> which becomes the total value because it was set to NO.', - 'TRACE_USER_NEVER_TOTAL_YES' => 'The user’s permission is set to <samp>NEVER</samp> and overwrites the previous <samp>YES</samp>.', - 'TRACE_USER_NEVER_TOTAL_YES_LOCAL' => 'The user’s permission for this forum is set to <samp>NEVER</samp> and overwrites the previous <samp>YES</samp>.', - 'TRACE_USER_NO_TOTAL_NO' => 'The user’s permission is <samp>NO</samp> and the total value was set to NO so it defaults to <samp>NEVER</samp>.', - 'TRACE_USER_NO_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is <samp>NO</samp> and the total value was set to NO so it defaults to <samp>NEVER</samp>.', - 'TRACE_USER_YES_TOTAL_NEVER' => 'The user’s permission is set to <samp>YES</samp> but the total <samp>NEVER</samp> cannot be overwritten.', - 'TRACE_USER_YES_TOTAL_NEVER_LOCAL' => 'The user’s permission for this forum is set to <samp>YES</samp> but the total <samp>NEVER</samp> cannot be overwritten.', - 'TRACE_USER_YES_TOTAL_NO' => 'The user’s permission is set to <samp>YES</samp> which becomes the total value because it was set to <samp>NO</samp>.', - 'TRACE_USER_YES_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is set to <samp>YES</samp> which becomes the total value because it was set to <samp>NO</samp>.', - 'TRACE_USER_YES_TOTAL_YES' => 'The user’s permission is set to <samp>YES</samp> and the total value is set to <samp>YES</samp>, so nothing is changed.', - 'TRACE_USER_YES_TOTAL_YES_LOCAL' => 'The user’s permission for this forum is set to <samp>YES</samp> and the total value is set to <samp>YES</samp>, so nothing is changed.', + 'TRACE_USER_GLOBAL_YES_TOTAL_YES' => 'The forum independent user permission evaluates to <strong>YES</strong> but the total permission is already set to <strong>YES</strong>, so the total result is kept. %sTrace global permission%s', + 'TRACE_USER_GLOBAL_YES_TOTAL_NEVER' => 'The forum independent user permission evaluates to <strong>YES</strong> which overwrites the current local result <strong>NEVER</strong>. %sTrace global permission%s', + 'TRACE_USER_GLOBAL_NEVER_TOTAL_KEPT' => 'The forum independent user permission evaluates to <strong>NEVER</strong> which doesn’t influence the local permission. %sTrace global permission%s', + + 'TRACE_USER_FOUNDER' => 'The user is a founder, therefore admin permissions are always set to <strong>YES</strong>.', + 'TRACE_USER_KEPT' => 'The user’s permission is <strong>NO</strong> so the old total value is kept.', + 'TRACE_USER_KEPT_LOCAL' => 'The user’s permission for this forum is <strong>NO</strong> so the old total value is kept.', + 'TRACE_USER_NEVER_TOTAL_NEVER' => 'The user’s permission is set to <strong>NEVER</strong> and the total value is set to <strong>NEVER</strong>, so nothing is changed.', + 'TRACE_USER_NEVER_TOTAL_NEVER_LOCAL' => 'The user’s permission for this forum is set to <strong>NEVER</strong> and the total value is set to <strong>NEVER</strong>, so nothing is changed.', + 'TRACE_USER_NEVER_TOTAL_NO' => 'The user’s permission is set to <strong>NEVER</strong> which becomes the total value because it was set to NO.', + 'TRACE_USER_NEVER_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is set to <strong>NEVER</strong> which becomes the total value because it was set to NO.', + 'TRACE_USER_NEVER_TOTAL_YES' => 'The user’s permission is set to <strong>NEVER</strong> and overwrites the previous <strong>YES</strong>.', + 'TRACE_USER_NEVER_TOTAL_YES_LOCAL' => 'The user’s permission for this forum is set to <strong>NEVER</strong> and overwrites the previous <strong>YES</strong>.', + 'TRACE_USER_NO_TOTAL_NO' => 'The user’s permission is <strong>NO</strong> and the total value was set to NO so it defaults to <strong>NEVER</strong>.', + 'TRACE_USER_NO_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is <strong>NO</strong> and the total value was set to NO so it defaults to <strong>NEVER</strong>.', + 'TRACE_USER_YES_TOTAL_NEVER' => 'The user’s permission is set to <strong>YES</strong> but the total <strong>NEVER</strong> cannot be overwritten.', + 'TRACE_USER_YES_TOTAL_NEVER_LOCAL' => 'The user’s permission for this forum is set to <strong>YES</strong> but the total <strong>NEVER</strong> cannot be overwritten.', + 'TRACE_USER_YES_TOTAL_NO' => 'The user’s permission is set to <strong>YES</strong> which becomes the total value because it was set to <strong>NO</strong>.', + 'TRACE_USER_YES_TOTAL_NO_LOCAL' => 'The user’s permission for this forum is set to <strong>YES</strong> which becomes the total value because it was set to <strong>NO</strong>.', + 'TRACE_USER_YES_TOTAL_YES' => 'The user’s permission is set to <strong>YES</strong> and the total value is set to <strong>YES</strong>, so nothing is changed.', + 'TRACE_USER_YES_TOTAL_YES_LOCAL' => 'The user’s permission for this forum is set to <strong>YES</strong> and the total value is set to <strong>YES</strong>, so nothing is changed.', 'TRACE_WHO' => 'Who', 'TRACE_TOTAL' => 'Total', diff --git a/phpBB/language/en/acp/posting.php b/phpBB/language/en/acp/posting.php index ea3eadb0dd..cf570d844f 100644 --- a/phpBB/language/en/acp/posting.php +++ b/phpBB/language/en/acp/posting.php @@ -85,8 +85,8 @@ $lang = array_merge($lang, array( 'URL' => 'A valid URL using any protocol (http, ftp, etc… cannot be used for javascript exploits). If none is given, “http://” is prefixed to the string.', 'LOCAL_URL' => 'A local URL. The URL must be relative to the topic page and cannot contain a server name or protocol, as links are prefixed with “%s”', 'RELATIVE_URL' => 'A relative URL. You can use this to match parts of a URL, but be careful: a full URL is a valid relative URL. When you want to use relative URLs of your board, use the LOCAL_URL token.', - 'COLOR' => 'A HTML colour, can be either in the numeric form <samp>#FF1234</samp> or a <a href="http://www.w3.org/TR/CSS21/syndata.html#value-def-color">CSS colour keyword</a> such as <samp>fuchsia</samp> or <samp>InactiveBorder</samp>' - ) + 'COLOR' => 'A HTML colour, can be either in the numeric form <samp>#FF1234</samp> or a <a href="http://www.w3.org/TR/CSS21/syndata.html#value-def-color">CSS colour keyword</a> such as <samp>fuchsia</samp> or <samp>InactiveBorder</samp>', + ), )); // Smilies and topic icons @@ -109,8 +109,6 @@ $lang = array_merge($lang, array( 'DISPLAY_POSTING' => 'On posting page', 'DISPLAY_POSTING_NO' => 'Not on posting page', - - 'EDIT_ICONS' => 'Edit icons', 'EDIT_SMILIES' => 'Edit smilies', 'EMOTION' => 'Emotion', diff --git a/phpBB/language/en/acp/profile.php b/phpBB/language/en/acp/profile.php index 8509845860..dc42693ca7 100644 --- a/phpBB/language/en/acp/profile.php +++ b/phpBB/language/en/acp/profile.php @@ -39,6 +39,7 @@ $lang = array_merge($lang, array( 'ADDED_PROFILE_FIELD' => 'Successfully added custom profile field.', 'ALPHA_ONLY' => 'Alphanumeric only', 'ALPHA_SPACERS' => 'Alphanumeric and spacers', + 'ALPHA_UNDERSCORE' => 'Alphanumeric and underscores', 'ALWAYS_TODAY' => 'Always the current date', 'BOOL_ENTRIES_EXPLAIN' => 'Enter your options now', @@ -65,6 +66,8 @@ $lang = array_merge($lang, array( 'DISPLAY_AT_PROFILE_EXPLAIN' => 'The user is able to change this profile field within the user control panel.', 'DISPLAY_AT_REGISTER' => 'Display on registration screen', 'DISPLAY_AT_REGISTER_EXPLAIN' => 'If this option is enabled, the field will be displayed on registration.', + 'DISPLAY_ON_MEMBERLIST' => 'Display on memberlist screen', + 'DISPLAY_ON_MEMBERLIST_EXPLAIN' => 'If this option is enabled, the field will be displayed in the user rows on the memberlist screen.', 'DISPLAY_ON_PM' => 'Display on view pm screen', 'DISPLAY_ON_PM_EXPLAIN' => 'If this option is enabled, the field will be displayed in the mini-profile on the pm screen.', 'DISPLAY_ON_VT' => 'Display on viewtopic screen', @@ -80,6 +83,8 @@ $lang = array_merge($lang, array( 'EVERYTHING_OK' => 'Everything OK', 'FIELD_BOOL' => 'Boolean (Yes/No)', + 'FIELD_CONTACT_DESC' => 'Contact description', + 'FIELD_CONTACT_URL' => 'Contact link', 'FIELD_DATE' => 'Date', 'FIELD_DESCRIPTION' => 'Field description', 'FIELD_DESCRIPTION_EXPLAIN' => 'The explanation for this field presented to the user.', @@ -88,12 +93,15 @@ $lang = array_merge($lang, array( 'FIELD_IDENT_ALREADY_EXIST' => 'The chosen field identification already exist. Please choose another name.', 'FIELD_IDENT_EXPLAIN' => 'The field identification is a name to identify the profile field within the database and the templates.', 'FIELD_INT' => 'Numbers', + 'FIELD_IS_CONTACT' => 'Display field as a contact field', + 'FIELD_IS_CONTACT_EXPLAIN' => 'Contact fields are displayed with in the contact section of the user profile and are displayed differently in the mini profile next to posts and private messages.', 'FIELD_LENGTH' => 'Length of input box', 'FIELD_NOT_FOUND' => 'Profile field not found.', 'FIELD_STRING' => 'Single text field', 'FIELD_TEXT' => 'Textarea', 'FIELD_TYPE' => 'Field type', 'FIELD_TYPE_EXPLAIN' => 'You are not able to change the field type later.', + 'FIELD_URL' => 'URL (Link)', 'FIELD_VALIDATION' => 'Field validation', 'FIRST_OPTION' => 'First option', diff --git a/phpBB/language/en/acp/prune.php b/phpBB/language/en/acp/prune.php index 3e890182c0..7134efd765 100644 --- a/phpBB/language/en/acp/prune.php +++ b/phpBB/language/en/acp/prune.php @@ -52,6 +52,7 @@ $lang = array_merge($lang, array( 'POSTS_ON_QUEUE' => 'Posts Awaiting Approval', 'PRUNE_USERS_GROUP_EXPLAIN' => 'Limit to users within the selected group.', + 'PRUNE_USERS_GROUP_NONE' => 'All groups', 'PRUNE_USERS_LIST' => 'Users to be pruned', 'PRUNE_USERS_LIST_DELETE' => 'With the selected critera for pruning users the following accounts will be removed. You can remove individual users from the deletion list by unchecking the box next to their username.', 'PRUNE_USERS_LIST_DEACTIVATE' => 'With the selected critera for pruning users the following accounts will be deactivated. You can remove individual users from the deactivation list by unchecking the box next to their username.', diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php index e7954ff148..76b1d5e7dd 100644 --- a/phpBB/language/en/acp/styles.php +++ b/phpBB/language/en/acp/styles.php @@ -36,337 +36,48 @@ if (empty($lang) || !is_array($lang)) $lang = array_merge($lang, array( 'ACP_STYLES_EXPLAIN' => 'Here you can manage the available styles on your board. You may alter existing styles, delete, deactivate, reactivate, install new ones. You can also see what a style will look like using the preview function. Also listed is the total user count for each style, note that overriding user styles will not be reflected here.', - 'ADD_TEMPLATE' => 'Create template', - 'ADD_TEMPLATE_EXPLAIN' => 'Here you can add a new template. Depending on your server configuration and file permissions you may have additional options here. For example you may be able to base this template set on an existing one. You may also be able to upload or import (from the store directory) a template archive. If you upload or import an archive the template name can be optionally taken from the archive name (to do this leave the template name blank).', - 'ARCHIVE_FORMAT' => 'Archive file type', - 'AUTOMATIC_EXPLAIN' => 'Leave blank to attempt automatic detection.', - 'BACKGROUND' => 'Background', - 'BACKGROUND_COLOUR' => 'Background colour', - 'BACKGROUND_IMAGE' => 'Background image', - 'BACKGROUND_REPEAT' => 'Background repeat', - 'BOLD' => 'Bold', - - 'CACHE' => 'Cache', - 'CACHE_CACHED' => 'Cached', - 'CACHE_FILENAME' => 'Template file', - 'CACHE_FILESIZE' => 'File size', - 'CACHE_MODIFIED' => 'Modified', 'CANNOT_BE_INSTALLED' => 'Cannot be installed', - 'CONFIRM_TEMPLATE_CLEAR_CACHE' => 'Are you sure you wish to clear all cached versions of your template files?', - 'CONFIRM_DELETE_STYLES' => 'Are you sure you wish to delete selected styles?', 'CONFIRM_UNINSTALL_STYLES' => 'Are you sure you wish to uninstall selected styles?', 'COPYRIGHT' => 'Copyright', - 'CREATE_STYLE' => 'Create new style', - 'CREATE_TEMPLATE' => 'Create new template set', - 'CREATE_THEME' => 'Create new theme', - 'CURRENT_IMAGE' => 'Current image', 'DEACTIVATE_DEFAULT' => 'You cannot deactivate the default style.', 'DELETE_FROM_FS' => 'Delete from filesystem', - 'DELETE_STYLE' => 'Delete style', - 'DELETE_STYLE_EXPLAIN' => 'Here you can remove the selected style. Take care in deleting styles, there is no undo capability.', 'DELETE_STYLE_FILES_FAILED' => 'Error deleting files for style "%s".', 'DELETE_STYLE_FILES_SUCCESS' => 'Files for style "%s" have been deleted.', - 'DELETE_TEMPLATE' => 'Delete template', - 'DELETE_TEMPLATE_EXPLAIN' => 'Here you can remove the selected template set from the database. Please note that there is no undo capability. It is recommended that you first export your set for possible future use.', 'DETAILS' => 'Details', - 'DIMENSIONS_EXPLAIN' => 'Selecting yes here will include width/height parameters.', - - - 'EDIT_DETAILS_STYLE' => 'Edit style', - 'EDIT_DETAILS_STYLE_EXPLAIN' => 'Using the form below you can modify this existing style. You may alter the combination of template and theme which define the style itself. You may also make the style the default one.', - 'EDIT_DETAILS_TEMPLATE' => 'Edit template details', - 'EDIT_DETAILS_TEMPLATE_EXPLAIN' => 'Here you can edit certain template details such as its name.', - 'EDIT_DETAILS_THEME' => 'Edit theme details', - 'EDIT_DETAILS_THEME_EXPLAIN' => 'Here you can edit certain theme details such as its name.', - 'EDIT_TEMPLATE' => 'Edit template', - 'EDIT_TEMPLATE_EXPLAIN' => 'Here you can edit your template set directly. Please remember that these edits are permanent and cannot be undone once submitted. Please take care when editing your template set, remember to close all replacement variable terms {XXXX} and conditional statements.', - 'EDIT_THEME' => 'Edit theme', - 'EDIT_THEME_EXPLAIN' => 'Here you can edit the selected theme, changing colours, images, etc.', - 'EDITOR_DISABLED' => 'The template editor is disabled.', - 'EXPORT' => 'Export', - - 'FOREGROUND' => 'Foreground', - 'FONT_COLOUR' => 'Font colour', - 'FONT_FACE' => 'Font face', - 'FONT_FACE_EXPLAIN' => 'You can specify multiple fonts separated by commas. If a user doesn’t have the first font installed the first other working font will be chosen.', - 'FONT_SIZE' => 'Font size', - - 'GLOBAL_IMAGES' => 'Global', - - 'HIDE_CSS' => 'Hide raw CSS', - - 'IMAGE_WIDTH' => 'Image width', - 'IMAGE_HEIGHT' => 'Image height', - 'IMAGE' => 'Image', - 'IMAGE_NAME' => 'Image name', - 'IMAGE_PARAMETER' => 'Parameter', - 'IMAGE_VALUE' => 'Value', - - 'ITALIC' => 'Italic', - - 'IMG_CAT_BUTTONS' => 'Localised buttons', - 'IMG_CAT_CUSTOM' => 'Custom images', - 'IMG_CAT_FOLDERS' => 'Topic icons', - 'IMG_CAT_FORUMS' => 'Forum icons', - 'IMG_CAT_ICONS' => 'General icons', - 'IMG_CAT_LOGOS' => 'Logos', - 'IMG_CAT_POLLS' => 'Polling images', - 'IMG_CAT_UI' => 'General user interface elements', - 'IMG_CAT_USER' => 'Additional images', - - 'IMG_SITE_LOGO' => 'Main logo', - 'IMG_UPLOAD_BAR' => 'Upload progress bar', - 'IMG_POLL_LEFT' => 'Poll left end', - 'IMG_POLL_CENTER' => 'Poll centre', - 'IMG_POLL_RIGHT' => 'Poll right end', - 'IMG_ICON_FRIEND' => 'Add as friend', - 'IMG_ICON_FOE' => 'Add as foe', - - 'IMG_FORUM_LINK' => 'Forum link', - 'IMG_FORUM_READ' => 'Forum', - 'IMG_FORUM_READ_LOCKED' => 'Forum locked', - 'IMG_FORUM_READ_SUBFORUM' => 'Subforum', - 'IMG_FORUM_UNREAD' => 'Forum unread posts', - 'IMG_FORUM_UNREAD_LOCKED' => 'Forum unread posts locked', - 'IMG_FORUM_UNREAD_SUBFORUM' => 'Subforum unread posts', - 'IMG_SUBFORUM_READ' => 'Legend subforum', - 'IMG_SUBFORUM_UNREAD' => 'Legend subforum unread posts', - - 'IMG_TOPIC_MOVED' => 'Topic moved', - - 'IMG_TOPIC_READ' => 'Topic', - 'IMG_TOPIC_READ_MINE' => 'Topic posted to', - 'IMG_TOPIC_READ_HOT' => 'Topic popular', - 'IMG_TOPIC_READ_HOT_MINE' => 'Topic popular posted to', - 'IMG_TOPIC_READ_LOCKED' => 'Topic locked', - 'IMG_TOPIC_READ_LOCKED_MINE' => 'Topic locked posted to', - - 'IMG_TOPIC_UNREAD' => 'Topic unread posts', - 'IMG_TOPIC_UNREAD_MINE' => 'Topic posted to unread', - 'IMG_TOPIC_UNREAD_HOT' => 'Topic popular unread posts', - 'IMG_TOPIC_UNREAD_HOT_MINE' => 'Topic popular posted to unread', - 'IMG_TOPIC_UNREAD_LOCKED' => 'Topic locked unread', - 'IMG_TOPIC_UNREAD_LOCKED_MINE' => 'Topic locked posted to unread', - - 'IMG_STICKY_READ' => 'Sticky topic', - 'IMG_STICKY_READ_MINE' => 'Sticky topic posted to', - 'IMG_STICKY_READ_LOCKED' => 'Sticky topic locked', - 'IMG_STICKY_READ_LOCKED_MINE' => 'Sticky topic locked posted to', - 'IMG_STICKY_UNREAD' => 'Sticky topic unread posts', - 'IMG_STICKY_UNREAD_MINE' => 'Sticky topic posted to unread', - 'IMG_STICKY_UNREAD_LOCKED' => 'Sticky topic locked unread posts', - 'IMG_STICKY_UNREAD_LOCKED_MINE' => 'Sticky topic locked posted to unread', - - 'IMG_ANNOUNCE_READ' => 'Announcement', - 'IMG_ANNOUNCE_READ_MINE' => 'Announcement posted to', - 'IMG_ANNOUNCE_READ_LOCKED' => 'Announcement locked', - 'IMG_ANNOUNCE_READ_LOCKED_MINE' => 'Announcement locked posted to', - 'IMG_ANNOUNCE_UNREAD' => 'Announcement unread posts', - 'IMG_ANNOUNCE_UNREAD_MINE' => 'Announcement posted to unread', - 'IMG_ANNOUNCE_UNREAD_LOCKED' => 'Announcement locked unread posts', - 'IMG_ANNOUNCE_UNREAD_LOCKED_MINE' => 'Announcement locked posted to unread', - 'IMG_GLOBAL_READ' => 'Global', - 'IMG_GLOBAL_READ_MINE' => 'Global posted to', - 'IMG_GLOBAL_READ_LOCKED' => 'Global locked', - 'IMG_GLOBAL_READ_LOCKED_MINE' => 'Global locked posted to', - 'IMG_GLOBAL_UNREAD' => 'Global unread posts', - 'IMG_GLOBAL_UNREAD_MINE' => 'Global posted to unread', - 'IMG_GLOBAL_UNREAD_LOCKED' => 'Global locked unread posts', - 'IMG_GLOBAL_UNREAD_LOCKED_MINE' => 'Global locked posted to unread', - - 'IMG_PM_READ' => 'Read private message', - 'IMG_PM_UNREAD' => 'Unread private message', - - 'IMG_ICON_BACK_TOP' => 'Top', - - 'IMG_ICON_CONTACT_AIM' => 'AIM', - 'IMG_ICON_CONTACT_EMAIL' => 'Send email', - 'IMG_ICON_CONTACT_ICQ' => 'ICQ', - 'IMG_ICON_CONTACT_JABBER' => 'Jabber', - 'IMG_ICON_CONTACT_MSNM' => 'WLM', - 'IMG_ICON_CONTACT_PM' => 'Send message', - 'IMG_ICON_CONTACT_YAHOO' => 'YIM', - 'IMG_ICON_CONTACT_WWW' => 'Website', - - 'IMG_ICON_POST_DELETE' => 'Delete post', - 'IMG_ICON_POST_EDIT' => 'Edit post', - 'IMG_ICON_POST_INFO' => 'Show post details', - 'IMG_ICON_POST_QUOTE' => 'Quote post', - 'IMG_ICON_POST_REPORT' => 'Report post', - 'IMG_ICON_POST_TARGET' => 'Minipost', - 'IMG_ICON_POST_TARGET_UNREAD' => 'New minipost', - - - 'IMG_ICON_TOPIC_ATTACH' => 'Attachment', - 'IMG_ICON_TOPIC_LATEST' => 'Last post', - 'IMG_ICON_TOPIC_NEWEST' => 'Last unread post', - 'IMG_ICON_TOPIC_REPORTED' => 'Post reported', - 'IMG_ICON_TOPIC_UNAPPROVED' => 'Post unapproved', - - 'IMG_ICON_USER_ONLINE' => 'User online', - 'IMG_ICON_USER_OFFLINE' => 'User offline', - 'IMG_ICON_USER_PROFILE' => 'Show profile', - 'IMG_ICON_USER_SEARCH' => 'Search posts', - 'IMG_ICON_USER_WARN' => 'Warn user', - - 'IMG_BUTTON_PM_FORWARD' => 'Forward private message', - 'IMG_BUTTON_PM_NEW' => 'New private message', - 'IMG_BUTTON_PM_REPLY' => 'Reply private message', - 'IMG_BUTTON_TOPIC_LOCKED' => 'Topic locked', - 'IMG_BUTTON_TOPIC_NEW' => 'New topic', - 'IMG_BUTTON_TOPIC_REPLY' => 'Reply topic', - - 'IMG_USER_ICON1' => 'User defined image 1', - 'IMG_USER_ICON2' => 'User defined image 2', - 'IMG_USER_ICON3' => 'User defined image 3', - 'IMG_USER_ICON4' => 'User defined image 4', - 'IMG_USER_ICON5' => 'User defined image 5', - 'IMG_USER_ICON6' => 'User defined image 6', - 'IMG_USER_ICON7' => 'User defined image 7', - 'IMG_USER_ICON8' => 'User defined image 8', - 'IMG_USER_ICON9' => 'User defined image 9', - 'IMG_USER_ICON10' => 'User defined image 10', - - 'INACTIVE_STYLES' => 'Inactive styles', - 'INCLUDE_DIMENSIONS' => 'Include dimensions', - 'INCLUDE_TEMPLATE' => 'Include template', - 'INCLUDE_THEME' => 'Include theme', 'INHERITING_FROM' => 'Inherits from', 'INSTALL_STYLE' => 'Install style', 'INSTALL_STYLES' => 'Install styles', 'INSTALL_STYLES_EXPLAIN' => 'Here you can install new styles.<br />If you cannot find a specific style in list below, check to make sure style is already installed. If it is not installed, check if it was uploaded correctly.', - 'INSTALLED_STYLE' => 'Installed styles', 'INVALID_STYLE_ID' => 'Invalid style ID.', - 'LINE_SPACING' => 'Line spacing', - 'LOCALISED_IMAGES' => 'Localised', - - 'NO_CLASS' => 'Cannot find class in stylesheet.', - 'NO_IMAGE' => 'No image', - 'NO_IMAGE_ERROR' => 'Cannot find image on filesystem.', 'NO_MATCHING_STYLES_FOUND' => 'No styles match your query.', - 'NO_STYLE' => 'Cannot find style on filesystem.', - 'NO_TEMPLATE' => 'Cannot find template on filesystem.', - 'NO_THEME' => 'Cannot find theme on filesystem.', 'NO_UNINSTALLED_STYLE' => 'No uninstalled styles detected.', - 'NO_UNIT' => 'None', - - 'ONLY_STYLE' => 'This is the only remaining style, you cannot delete it.', - 'PARENT_STYLE_NOT_FOUND' => 'Parent style was not found. This style may not work correctly. Please uninstall it.', 'PURGED_CACHE' => 'Cache was purged.', - 'REFRESH' => 'Refresh', - 'REPEAT_NO' => 'None', - 'REPEAT_X' => 'Only horizontally', - 'REPEAT_Y' => 'Only vertically', - 'REPEAT_ALL' => 'Both directions', - 'REPLACE_STYLE' => 'Replace style with', - 'REPLACE_STYLE_EXPLAIN' => 'This style will replace the one being deleted for members that use it.', - 'REPLACE_TEMPLATE' => 'Replace template with', - 'REPLACE_TEMPLATE_EXPLAIN' => 'This template set will replace the one you are deleting in any styles that use it.', - 'REPLACE_THEME' => 'Replace theme with', - 'REPLACE_THEME_EXPLAIN' => 'This theme will replace the one you are deleting in any styles that use it.', - 'REPLACE_WITH_OPTION' => 'Replace with “%s”', 'REQUIRES_STYLE' => 'This style requires the style "%s" to be installed.', - 'SELECT_IMAGE' => 'Select image', - 'SELECT_TEMPLATE' => 'Select template file', - 'SELECT_THEME' => 'Select theme file', - 'SELECTED_IMAGE' => 'Selected image', - 'SELECTED_TEMPLATE' => 'Selected template', - 'SELECTED_TEMPLATE_FILE' => 'Selected template file', - 'SELECTED_THEME' => 'Selected theme', - 'SELECTED_THEME_FILE' => 'Selected theme file', - 'STORE_FILESYSTEM' => 'Filesystem', 'STYLE_ACTIVATE' => 'Activate', - 'STYLE_ACTIVATED' => 'Style activated successfully', 'STYLE_ACTIVE' => 'Active', - 'STYLE_ADDED' => 'Style added successfully.', 'STYLE_DEACTIVATE' => 'Deactivate', - 'STYLE_DEACTIVATED' => 'Style deactivated successfully', 'STYLE_DEFAULT' => 'Make default style', - 'STYLE_DEFAULT_CHANGE' => 'Change default style', 'STYLE_DEFAULT_CHANGE_INACTIVE' => 'You must activate style before making it default style.', - 'STYLE_DELETED' => 'Style "%s" deleted successfully.', - 'STYLE_DETAILS_UPDATED' => 'Style edited successfully.', - 'STYLE_ERR_ARCHIVE' => 'Please select an archive method.', - 'STYLE_ERR_COPY_LONG' => 'The copyright can be no longer than 60 characters.', 'STYLE_ERR_INVALID_PARENT' => 'Invalid parent style.', - 'STYLE_ERR_MORE_ELEMENTS' => 'You must select at least one style element.', - 'STYLE_ERR_NAME_CHARS' => 'The style name can only contain alphanumeric characters, -, +, _ and space.', 'STYLE_ERR_NAME_EXIST' => 'A style with that name already exists.', - 'STYLE_ERR_NAME_LONG' => 'The style name can be no longer than 30 characters.', - 'STYLE_ERR_NOT_STYLE' => 'The imported or uploaded file did not contain a valid style archive.', 'STYLE_ERR_STYLE_NAME' => 'You must supply a name for this style.', - 'STYLE_EXPORT' => 'Export style', - 'STYLE_EXPORT_EXPLAIN' => 'Here you can export a style in the form of an archive. A style does not need to contain all elements but it must contain at least one. For example if you have created a new theme for a commonly used template you could simply export the theme and omit the template. You may select whether to download the file directly or to place it in your store folder for download later or via FTP.', - 'STYLE_EXPORTED' => 'Style exported successfully and stored in %s.', 'STYLE_INSTALLED' => 'Style "%s" has been installed.', - 'STYLE_INSTALLED_EDIT_DETAILS' => '<a href="%s">Click here</a> to edit style details or to change default style.', 'STYLE_INSTALLED_RETURN_STYLES' => '<a href="%s">Click here</a> to return to installed styles list.', 'STYLE_INSTALLED_RETURN_UNINSTALLED' => '<a href="%s">Click here</a> to install more styles.', 'STYLE_NAME' => 'Style name', 'STYLE_NOT_INSTALLED' => 'Style "%s" was not installed.', - 'STYLE_PATH' => 'Style path:', - 'STYLE_PARENT' => 'Parent style:', - 'STYLE_TEMPLATE' => 'Template', - 'STYLE_THEME' => 'Theme', + 'STYLE_PATH' => 'Style path', 'STYLE_UNINSTALL' => 'Uninstall', 'STYLE_UNINSTALL_DEPENDENT' => 'Style "%s" cannot be uninstalled because it has one or more child styles.', 'STYLE_UNINSTALLED' => 'Style "%s" uninstalled successfully.', 'STYLE_USED_BY' => 'Used by (including robots)', - 'TEMPLATE_ADDED' => 'Template set added.', - 'TEMPLATE_CACHE' => 'Template cache', - 'TEMPLATE_CACHE_EXPLAIN' => 'By default phpBB caches the compiled version of its templates. This decreases the load on the server each time a page is viewed and thus may reduce the page generation time. Here you can view the cache status of each file and delete individual files or the entire cache.', - 'TEMPLATE_CACHE_CLEARED' => 'Template cache cleared successfully.', - 'TEMPLATE_CACHE_EMPTY' => 'There are no cached templates.', - 'TEMPLATE_DELETED_FS' => 'Template set removed from database but files remain on the filesystem.', - 'TEMPLATE_DETAILS_UPDATED' => 'Template details successfully updated.', - 'TEMPLATE_EDITOR' => 'Raw HTML template editor', - 'TEMPLATE_EDITOR_HEIGHT' => 'Template editor height', - 'TEMPLATE_ERR_ARCHIVE' => 'Please select an archive method.', - 'TEMPLATE_ERR_CACHE_READ' => 'The cache directory used to store cached versions of template files could not be opened.', - 'TEMPLATE_ERR_COPY_LONG' => 'The copyright can be no longer than 60 characters.', - 'TEMPLATE_ERR_NAME_CHARS' => 'The template name can only contain alphanumeric characters, -, +, _ and space.', - 'TEMPLATE_ERR_NAME_LONG' => 'The template name can be no longer than 30 characters.', - 'TEMPLATE_ERR_STYLE_NAME' => 'You must supply a name for this template.', - 'TEMPLATE_EXPORT_EXPLAIN' => 'Here you can export a template set in the form of an archive. This archive will contain all the files necessary to install the templates on another board. You may select whether to download the file directly or to place it in your store folder for download later or via FTP.', - 'TEMPLATE_EXPORTED' => 'Templates exported successfully and stored in %s.', - 'TEMPLATE_FILE' => 'Template file', - 'TEMPLATE_FILE_UPDATED' => 'Template file updated successfully.', - 'TEMPLATE_NAME' => 'Template name', - 'TEMPLATE_FILE_NOT_WRITABLE'=> 'Unable to write to template file %s. Please check the permissions for the directory and the files.', - - 'THEME_ADDED' => 'New theme added.', - 'THEME_CLASS_ADDED' => 'Custom class added successfully.', - 'THEME_DELETED' => 'Theme deleted successfully.', - 'THEME_DELETED_FS' => 'Theme removed from database but files remain on the filesystem.', - 'THEME_DETAILS_UPDATED' => 'Theme details successfully updated.', - 'THEME_EDITOR' => 'Theme editor', - 'THEME_EDITOR_HEIGHT' => 'Theme editor height', - 'THEME_ERR_ARCHIVE' => 'Please select an archive method.', - 'THEME_ERR_CLASS_CHARS' => 'Only alphanumeric characters plus ., :, -, _ and # are valid in class names.', - 'THEME_ERR_COPY_LONG' => 'The copyright can be no longer than 60 characters.', - 'THEME_ERR_NAME_CHARS' => 'The theme name can only contain alphanumeric characters, -, +, _ and space.', - 'THEME_ERR_NAME_EXIST' => 'A theme with that name already exists.', - 'THEME_ERR_NAME_LONG' => 'The theme name can be no longer than 30 characters.', - 'THEME_ERR_NOT_THEME' => 'The archive you specified does not contain a valid theme.', - 'THEME_ERR_STYLE_NAME' => 'You must supply a name for this theme.', - 'THEME_FILE' => 'Theme file', - 'THEME_FILE_NOT_WRITABLE' => 'Unable to write to theme file %s. Please check the permissions for the directory and the files.', - 'THEME_EXPORT' => 'Export Theme', - 'THEME_EXPORT_EXPLAIN' => 'Here you can export a theme in the form of an archive. This archive will contain all the data necessary to install the theme on another board. You may select whether to download the file directly or to place it in your store folder for download later or via FTP.', - 'THEME_EXPORTED' => 'Theme exported successfully and stored in %s.', - 'THEME_NAME' => 'Theme name', - 'THEME_UPDATED' => 'Theme updated successfully.', - - 'UNDERLINE' => 'Underline', 'UNINSTALL_DEFAULT' => 'You cannot uninstall the default style.', - 'UNSET' => 'Undefined', - )); diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php index 865a2a0371..9faf1d0de9 100644 --- a/phpBB/language/en/acp/users.php +++ b/phpBB/language/en/acp/users.php @@ -51,6 +51,7 @@ $lang = array_merge($lang, array( 'CANNOT_FORCE_REACT_FOUNDER' => 'You are not allowed to force reactivation on founder accounts.', 'CANNOT_FORCE_REACT_YOURSELF' => 'You are not allowed to force reactivation of your own account.', 'CANNOT_REMOVE_ANONYMOUS' => 'You are not able to remove the guest user account.', + 'CANNOT_REMOVE_FOUNDER' => 'You are not allowed to remove founder accounts.', 'CANNOT_REMOVE_YOURSELF' => 'You are not allowed to remove your own user account.', 'CANNOT_SET_FOUNDER_IGNORED' => 'You are not able to promote ignored users to be founders.', 'CANNOT_SET_FOUNDER_INACTIVE' => 'You need to activate users before you promote them to founders, only activated users are able to be promoted.', diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index e5c0478d98..569ec776f5 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -62,6 +62,7 @@ $lang = array_merge($lang, array( 'ACCOUNT_DEACTIVATED' => 'Your account has been manually deactivated and is only able to be reactivated by an administrator.', 'ACCOUNT_NOT_ACTIVATED' => 'Your account has not been activated yet.', 'ACP' => 'Administration Control Panel', + 'ACP_SHORT' => 'Administer', 'ACTIVE' => 'active', 'ACTIVE_ERROR' => 'The specified username is currently inactive. If you have problems activating your account, please contact a board administrator.', 'ADMINISTRATOR' => 'Administrator', @@ -142,6 +143,7 @@ $lang = array_merge($lang, array( 'BUTTON_QUOTE' => 'Quote', 'BUTTON_TOPIC_LOCKED' => 'Locked', 'BYTES' => 'Bytes', + 'BYTES_SHORT' => 'B', 'CANCEL' => 'Cancel', 'CHANGE' => 'Change', @@ -152,7 +154,6 @@ $lang = array_merge($lang, array( 1 => '%d character', 2 => '%d characters', ), - 'CLICK_VIEW_PRIVMSG' => '%sGo to your inbox%s', 'COLLAPSE_VIEW' => 'Collapse view', 'CLOSE_WINDOW' => 'Close window', 'COLOUR_SWATCH' => 'Colour swatch', @@ -209,8 +210,6 @@ $lang = array_merge($lang, array( 'ERR_CONNECTING_SERVER' => 'Error connecting to the server.', 'ERR_JAB_AUTH' => 'Could not authorise on Jabber server.', 'ERR_JAB_CONNECT' => 'Could not connect to Jabber server.', - 'ERR_TEMPLATE_EVENT_LOCATION' => 'The specified template event location <em>[%s]</em> is improperly formatted.', - 'ERR_TEMPLATE_COMPILATION' => 'The file could not be compiled: %s', 'ERR_UNABLE_TO_LOGIN' => 'The specified username or password is incorrect.', 'ERR_UNWATCHING' => 'An error occurred while trying to unsubscribe.', 'ERR_WATCHING' => 'An error occurred while trying to subscribe.', @@ -279,6 +278,8 @@ $lang = array_merge($lang, array( 'GB' => 'GB', 'GIB' => 'GiB', 'GO' => 'Go', + 'GOTO_FIRST_POST' => 'Go to first post', + 'GOTO_LAST_POST' => 'Go to last post', 'GOTO_PAGE' => 'Go to page', 'GROUP' => 'Group', 'GROUPS' => 'Groups', @@ -316,7 +317,6 @@ $lang = array_merge($lang, array( 'HOME' => 'Home', 'ICQ' => 'ICQ', - 'ICQ_STATUS' => 'ICQ status', 'IF' => 'If', 'IMAGE' => 'Image', 'IMAGE_FILETYPE_INVALID' => 'Image file type %d for mimetype %s not supported.', @@ -368,6 +368,7 @@ $lang = array_merge($lang, array( 'LOGIN_VIEWFORUM' => 'The board requires you to be registered and logged in to view this forum.', 'LOGIN_EXPLAIN_EDIT' => 'In order to edit posts in this forum you have to be registered and logged in.', 'LOGIN_EXPLAIN_VIEWONLINE' => 'In order to view the online list you have to be registered and logged in.', + 'LOGIN_REQUIRED' => 'You need to login to perform this action.', 'LOGOUT' => 'Logout', 'LOGOUT_USER' => 'Logout [ %s ]', 'LOG_ME_IN' => 'Remember me', @@ -375,12 +376,14 @@ $lang = array_merge($lang, array( 'MAIN' => 'Main', 'MARK' => 'Mark', 'MARK_ALL' => 'Mark all', + 'MARK_ALL_READ' => 'Mark all read', 'MARK_FORUMS_READ' => 'Mark forums read', 'MARK_READ' => 'Mark read', 'MARK_SUBFORUMS_READ' => 'Mark subforums read', 'MB' => 'MB', 'MIB' => 'MiB', 'MCP' => 'Moderator Control Panel', + 'MCP_SHORT' => 'Moderate', 'MEMBERLIST' => 'Members', 'MEMBERLIST_EXPLAIN' => 'View complete list of members', 'MERGE' => 'Merge', @@ -388,23 +391,25 @@ $lang = array_merge($lang, array( 'MERGE_TOPIC' => 'Merge topic', 'MESSAGE' => 'Message', 'MESSAGES' => 'Messages', + 'MESSAGES_COUNT' => array( + 1 => '%d message', + 2 => '%d messages', + ), 'MESSAGE_BODY' => 'Message body', 'MINUTES' => 'Minutes', 'MODERATE' => 'Moderate', 'MODERATOR' => 'Moderator', 'MODERATORS' => 'Moderators', + 'MODULE_NOT_ACCESS' => 'Module not accessible', + 'MODULE_NOT_FIND' => 'Cannot find module %s', + 'MODULE_FILE_INCORRECT_CLASS' => 'Module file %s does not contain correct class [%s]', 'MONTH' => 'Month', 'MOVE' => 'Move', - 'MSNM' => 'WLM', 'NA' => 'N/A', 'NEWEST_USER' => 'Our newest member <strong>%s</strong>', 'NEW_MESSAGE' => 'New message', 'NEW_MESSAGES' => 'New messages', - 'NEW_PMS' => array( - 1 => '<strong>%d</strong> new message', - 2 => '<strong>%d</strong> new messages', - ), 'NEW_POST' => 'New post', // Not used anymore 'NEW_POSTS' => 'New posts', // Not used anymore 'NEXT' => 'Next', // Used in pagination @@ -417,20 +422,31 @@ $lang = array_merge($lang, array( 'NOT_WATCHING_FORUM' => 'You are no longer subscribed to updates on this forum.', 'NOT_WATCHING_TOPIC' => 'You are no longer subscribed to this topic.', 'NOTIFICATIONS' => 'Notifications', - 'NOTIFICATIONS_COUNT' => array( - 0 => '%d Notifications', - 1 => '<strong>%d</strong> Notification', - 2 => '<strong>%d</strong> Notifications', + // This applies for NOTIFICATION_BOOKMARK and NOTIFICATION_POST. + // %1$s will return a list of users that's concatenated using "," and "and" - see STRING_LIST + // Once the user count reaches 5 users or more, the list is trimmed using NOTIFICATION_X_OTHERS + // Once the user count reaches 20 users or more, the list is trimmed using NOTIFICATION_MANY_OTHERS + // Examples: + // A replied... + // A and B replied... + // A, B and C replied... + // A, B, C and 2 others replied... + // A, B, C and others replied... + 'NOTIFICATION_BOOKMARK' => array( + 1 => '%1$s replied to the topic “%2$s” you have bookmarked.', ), - 'NOTIFICATION_BOOKMARK' => '%1$s replied to the topic "%2$s" you have bookmarked.', 'NOTIFICATION_GROUP_REQUEST' => '%1$s is requesting to join the group %2$s.', 'NOTIFICATION_GROUP_REQUEST_APPROVED' => 'Your request to join the group %1$s has been approved.', 'NOTIFICATION_PM' => '%1$s sent you a Private Message "%2$s".', - 'NOTIFICATION_POST' => '%1$s replied to the topic "%2$s".', + 'NOTIFICATION_POST' => array( + 1 => '%1$s replied to the topic “%2$s”.', + ), 'NOTIFICATION_POST_APPROVED' => 'Your post was approved "%2$s".', 'NOTIFICATION_POST_DISAPPROVED' => 'Your post "%1$s" was disapproved for reason: "%2$s".', 'NOTIFICATION_POST_IN_QUEUE' => 'A new post titled "%2$s" was posted by %1$s and needs approval.', - 'NOTIFICATION_QUOTE' => '%1$s quoted you in the post "%2$s".', + 'NOTIFICATION_QUOTE' => array( + 1 => '%1$s quoted you in the post “%2$s”.', + ), 'NOTIFICATION_REPORT_PM' => '%1$s reported a Private Message "%2$s" for reason: "%3$s".', 'NOTIFICATION_REPORT_POST' => '%1$s reported a post "%2$s" for reason: "%3$s".', 'NOTIFICATION_REPORT_CLOSED' => '%1$s closed the report you made for "%2$s".', @@ -439,6 +455,12 @@ $lang = array_merge($lang, array( 'NOTIFICATION_TOPIC_DISAPPROVED' => 'Your topic "%1$s" was disapproved for reason: "%2$s".', 'NOTIFICATION_TOPIC_IN_QUEUE' => 'A new topic titled "%2$s" was posted by %1$s and needs approval.', 'NOTIFICATION_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.', + 'NOTIFICATION_ADMIN_ACTIVATE_USER' => 'The user “%1$s” is newly registered and requires activation.', + // Used in conjuction with NOTIFICATION_BOOKMARK and NOTIFICATION_POST. + 'NOTIFICATION_MANY_OTHERS' => 'others', + 'NOTIFICATION_X_OTHERS' => array( + 2 => '%d others', + ), 'NOTIFY_ADMIN' => 'Please notify the board administrator or webmaster.', 'NOTIFY_ADMIN_EMAIL' => 'Please notify the board administrator or webmaster: <a href="mailto:%1$s">%1$s</a>', 'NO_ACCESS_ATTACHMENT' => 'You are not allowed to access this file.', @@ -594,7 +616,8 @@ $lang = array_merge($lang, array( 'RETURN_FORUM' => '%sReturn to the forum last visited%s', 'RETURN_PAGE' => '%sReturn to the previous page%s', 'RETURN_TOPIC' => '%sReturn to the topic last visited%s', - 'RETURN_TO' => 'Return to', + 'RETURN_TO' => 'Return to “%s”', + 'RETURN_TO_INDEX' => 'Return to Board Index', 'FEED' => 'Feed', 'FEED_NEWS' => 'News', 'FEED_TOPICS_ACTIVE' => 'Active Topics', @@ -661,6 +684,8 @@ $lang = array_merge($lang, array( 'START_WATCHING_TOPIC' => 'Subscribe topic', 'STOP_WATCHING_FORUM' => 'Unsubscribe forum', 'STOP_WATCHING_TOPIC' => 'Unsubscribe topic', + 'STRING_LIST_MULTI' => '%1$s, and %2$s', + 'STRING_LIST_SIMPLE' => '%1$s and %2$s', 'SUBFORUM' => 'Subforum', 'SUBFORUMS' => 'Subforums', 'SUBJECT' => 'Subject', @@ -679,43 +704,27 @@ $lang = array_merge($lang, array( 'TOO_LONG' => 'The value you entered is too long.', - 'TOO_LONG_AIM' => 'The screenname you entered is too long.', 'TOO_LONG_CONFIRM_CODE' => 'The confirm code you entered is too long.', 'TOO_LONG_DATEFORMAT' => 'The date format you entered is too long.', - 'TOO_LONG_ICQ' => 'The ICQ number you entered is too long.', - 'TOO_LONG_INTERESTS' => 'The interests you entered is too long.', 'TOO_LONG_JABBER' => 'The Jabber account name you entered is too long.', - 'TOO_LONG_LOCATION' => 'The location you entered is too long.', - 'TOO_LONG_MSN' => 'The WLM name you entered is too long.', 'TOO_LONG_NEW_PASSWORD' => 'The password you entered is too long.', - 'TOO_LONG_OCCUPATION' => 'The occupation you entered is too long.', 'TOO_LONG_PASSWORD_CONFIRM' => 'The password confirmation you entered is too long.', 'TOO_LONG_USER_PASSWORD' => 'The password you entered is too long.', 'TOO_LONG_USERNAME' => 'The username you entered is too long.', 'TOO_LONG_EMAIL' => 'The email address you entered is too long.', - 'TOO_LONG_WEBSITE' => 'The website address you entered is too long.', - 'TOO_LONG_YIM' => 'The Yahoo! Messenger name you entered is too long.', 'TOO_MANY_VOTE_OPTIONS' => 'You have tried to vote for too many options.', 'TOO_SHORT' => 'The value you entered is too short.', - 'TOO_SHORT_AIM' => 'The screenname you entered is too short.', 'TOO_SHORT_CONFIRM_CODE' => 'The confirm code you entered is too short.', 'TOO_SHORT_DATEFORMAT' => 'The date format you entered is too short.', - 'TOO_SHORT_ICQ' => 'The ICQ number you entered is too short.', - 'TOO_SHORT_INTERESTS' => 'The interests you entered is too short.', 'TOO_SHORT_JABBER' => 'The Jabber account name you entered is too short.', - 'TOO_SHORT_LOCATION' => 'The location you entered is too short.', - 'TOO_SHORT_MSN' => 'The WLM name you entered is too short.', 'TOO_SHORT_NEW_PASSWORD' => 'The password you entered is too short.', - 'TOO_SHORT_OCCUPATION' => 'The occupation you entered is too short.', 'TOO_SHORT_PASSWORD_CONFIRM' => 'The password confirmation you entered is too short.', 'TOO_SHORT_USER_PASSWORD' => 'The password you entered is too short.', 'TOO_SHORT_USERNAME' => 'The username you entered is too short.', 'TOO_SHORT_EMAIL' => 'The email address you entered is too short.', - 'TOO_SHORT_WEBSITE' => 'The website address you entered is too short.', - 'TOO_SHORT_YIM' => 'The Yahoo! Messenger name you entered is too short.', 'TOO_SMALL' => 'The value you entered is too small.', 'TOO_SMALL_MAX_RECIPIENTS' => 'The value of <strong>Maximum number of allowed recipients per private message</strong> setting you entered is too small.', @@ -752,15 +761,11 @@ $lang = array_merge($lang, array( ), 'TRACKED_PHP_ERROR' => 'Tracked PHP errors: %s', - 'UNABLE_GET_IMAGE_SIZE' => 'It was not possible to determine the dimensions of the image.', + 'UNABLE_GET_IMAGE_SIZE' => 'It was not possible to determine the dimensions of the image. Please verify that the URL you entered is correct.', 'UNABLE_TO_DELIVER_FILE'=> 'Unable to deliver file.', 'UNKNOWN_BROWSER' => 'Unknown browser', 'UNMARK_ALL' => 'Unmark all', 'UNREAD_MESSAGES' => 'Unread messages', - 'UNREAD_PMS' => array( - 1 => '<strong>%d</strong> unread message', - 2 => '<strong>%d</strong> unread messages', - ), 'UNREAD_POST' => 'Unread post', 'UNREAD_POSTS' => 'Unread posts', 'UNWATCH_FORUM_CONFIRM' => 'Are you sure you wish to unsubscribe from this forum?', @@ -832,23 +837,19 @@ $lang = array_merge($lang, array( 'WEBSITE' => 'Website', 'WHOIS' => 'Whois', 'WHO_IS_ONLINE' => 'Who is online', + 'WLM' => 'WLM', 'WRONG_PASSWORD' => 'You entered an incorrect password.', 'WRONG_DATA_COLOUR' => 'The colour value you entered is invalid.', - 'WRONG_DATA_ICQ' => 'The number you entered is not a valid ICQ number.', 'WRONG_DATA_JABBER' => 'The name you entered is not a valid Jabber account name.', 'WRONG_DATA_LANG' => 'The language you specified is not valid.', - 'WRONG_DATA_WEBSITE' => 'The website address has to be a valid URL, including the protocol. For example http://www.example.com/.', 'WROTE' => 'wrote', + 'YAHOO' => 'Yahoo Messenger', 'YEAR' => 'Year', 'YEAR_MONTH_DAY' => '(YYYY-MM-DD)', 'YES' => 'Yes', - 'YIM' => 'YIM', 'YOU_LAST_VISIT' => 'Last visit was: %s', - 'YOU_NEW_PM' => 'A new private message is waiting for you in your Inbox.', - 'YOU_NEW_PMS' => 'New private messages are waiting for you in your Inbox.', - 'YOU_NO_NEW_PM' => 'No new private messages are waiting for you.', 'datetime' => array( 'TODAY' => 'Today', @@ -906,6 +907,8 @@ $lang = array_merge($lang, array( // Timezones can be translated. We use this for the Etc/GMT timezones here, // because they are named invers to their offset. 'timezones' => array( + 'UTC' => 'UTC', + 'Etc/GMT-12' => 'GMT+12', 'Etc/GMT-11' => 'GMT+11', 'Etc/GMT-10' => 'GMT+10', @@ -930,6 +933,436 @@ $lang = array_merge($lang, array( 'Etc/GMT+10' => 'GMT-10', 'Etc/GMT+11' => 'GMT-11', 'Etc/GMT+12' => 'GMT-12', + + 'Africa/Abidjan' => 'Africa/Abidjan', + 'Africa/Accra' => 'Africa/Accra', + 'Africa/Addis_Ababa' => 'Africa/Addis Ababa', + 'Africa/Algiers' => 'Africa/Algiers', + 'Africa/Asmara' => 'Africa/Asmara', + 'Africa/Bamako' => 'Africa/Bamako', + 'Africa/Bangui' => 'Africa/Bangui', + 'Africa/Banjul' => 'Africa/Banjul', + 'Africa/Bissau' => 'Africa/Bissau', + 'Africa/Blantyre' => 'Africa/Blantyre', + 'Africa/Brazzaville' => 'Africa/Brazzaville', + 'Africa/Bujumbura' => 'Africa/Bujumbura', + 'Africa/Cairo' => 'Africa/Cairo', + 'Africa/Casablanca' => 'Africa/Casablanca', + 'Africa/Ceuta' => 'Africa/Ceuta', + 'Africa/Conakry' => 'Africa/Conakry', + 'Africa/Dakar' => 'Africa/Dakar', + 'Africa/Dar_es_Salaam' => 'Africa/Dar es Salaam', + 'Africa/Djibouti' => 'Africa/Djibouti', + 'Africa/Douala' => 'Africa/Douala', + 'Africa/El_Aaiun' => 'Africa/El Aaiun', + 'Africa/Freetown' => 'Africa/Freetown', + 'Africa/Gaborone' => 'Africa/Gaborone', + 'Africa/Harare' => 'Africa/Harare', + 'Africa/Johannesburg' => 'Africa/Johannesburg', + 'Africa/Juba' => 'Africa/Juba', + 'Africa/Kampala' => 'Africa/Kampala', + 'Africa/Khartoum' => 'Africa/Khartoum', + 'Africa/Kigali' => 'Africa/Kigali', + 'Africa/Kinshasa' => 'Africa/Kinshasa', + 'Africa/Lagos' => 'Africa/Lagos', + 'Africa/Libreville' => 'Africa/Libreville', + 'Africa/Lome' => 'Africa/Lome', + 'Africa/Luanda' => 'Africa/Luanda', + 'Africa/Lubumbashi' => 'Africa/Lubumbashi', + 'Africa/Lusaka' => 'Africa/Lusaka', + 'Africa/Malabo' => 'Africa/Malabo', + 'Africa/Maputo' => 'Africa/Maputo', + 'Africa/Maseru' => 'Africa/Maseru', + 'Africa/Mbabane' => 'Africa/Mbabane', + 'Africa/Mogadishu' => 'Africa/Mogadishu', + 'Africa/Monrovia' => 'Africa/Monrovia', + 'Africa/Nairobi' => 'Africa/Nairobi', + 'Africa/Ndjamena' => 'Africa/Ndjamena', + 'Africa/Niamey' => 'Africa/Niamey', + 'Africa/Nouakchott' => 'Africa/Nouakchott', + 'Africa/Ouagadougou' => 'Africa/Ouagadougou', + 'Africa/Porto-Novo' => 'Africa/Porto-Novo', + 'Africa/Sao_Tome' => 'Africa/Sao Tome', + 'Africa/Tripoli' => 'Africa/Tripoli', + 'Africa/Tunis' => 'Africa/Tunis', + 'Africa/Windhoek' => 'Africa/Windhoek', + + 'America/Adak' => 'America/Adak', + 'America/Anchorage' => 'America/Anchorage', + 'America/Anguilla' => 'America/Anguilla', + 'America/Antigua' => 'America/Antigua', + 'America/Araguaina' => 'America/Araguaina', + + 'America/Argentina/Buenos_Aires' => 'America/Argentina/Buenos Aires', + 'America/Argentina/Catamarca' => 'America/Argentina/Catamarca', + 'America/Argentina/Cordoba' => 'America/Argentina/Cordoba', + 'America/Argentina/Jujuy' => 'America/Argentina/Jujuy', + 'America/Argentina/La_Rioja' => 'America/Argentina/La Rioja', + 'America/Argentina/Mendoza' => 'America/Argentina/Mendoza', + 'America/Argentina/Rio_Gallegos' => 'America/Argentina/Rio Gallegos', + 'America/Argentina/Salta' => 'America/Argentina/Salta', + 'America/Argentina/San_Juan' => 'America/Argentina/San Juan', + 'America/Argentina/San_Luis' => 'America/Argentina/San Luis', + 'America/Argentina/Tucuman' => 'America/Argentina/Tucuman', + 'America/Argentina/Ushuaia' => 'America/Argentina/Ushuaia', + + 'America/Aruba' => 'America/Aruba', + 'America/Asuncion' => 'America/Asuncion', + 'America/Atikokan' => 'America/Atikokan', + 'America/Bahia' => 'America/Bahia', + 'America/Bahia_Banderas' => 'America/Bahia Banderas', + 'America/Barbados' => 'America/Barbados', + 'America/Belem' => 'America/Belem', + 'America/Belize' => 'America/Belize', + 'America/Blanc-Sablon' => 'America/Blanc-Sablon', + 'America/Boa_Vista' => 'America/Boa Vista', + 'America/Bogota' => 'America/Bogota', + 'America/Boise' => 'America/Boise', + 'America/Cambridge_Bay' => 'America/Cambridge Bay', + 'America/Campo_Grande' => 'America/Campo Grande', + 'America/Cancun' => 'America/Cancun', + 'America/Caracas' => 'America/Caracas', + 'America/Cayenne' => 'America/Cayenne', + 'America/Cayman' => 'America/Cayman', + 'America/Chicago' => 'America/Chicago', + 'America/Chihuahua' => 'America/Chihuahua', + 'America/Costa_Rica' => 'America/Costa Rica', + 'America/Creston' => 'America/Creston', + 'America/Cuiaba' => 'America/Cuiaba', + 'America/Curacao' => 'America/Curacao', + 'America/Danmarkshavn' => 'America/Danmarkshavn', + 'America/Dawson' => 'America/Dawson', + 'America/Dawson_Creek' => 'America/Dawson Creek', + 'America/Denver' => 'America/Denver', + 'America/Detroit' => 'America/Detroit', + 'America/Dominica' => 'America/Dominica', + 'America/Edmonton' => 'America/Edmonton', + 'America/Eirunepe' => 'America/Eirunepe', + 'America/El_Salvador' => 'America/El Salvador', + 'America/Fortaleza' => 'America/Fortaleza', + 'America/Glace_Bay' => 'America/Glace Bay', + 'America/Godthab' => 'America/Godthab', + 'America/Goose_Bay' => 'America/Goose Bay', + 'America/Grand_Turk' => 'America/Grand Turk', + 'America/Grenada' => 'America/Grenada', + 'America/Guadeloupe' => 'America/Guadeloupe', + 'America/Guatemala' => 'America/Guatemala', + 'America/Guayaquil' => 'America/Guayaquil', + 'America/Guyana' => 'America/Guyana', + 'America/Halifax' => 'America/Halifax', + 'America/Havana' => 'America/Havana', + 'America/Hermosillo' => 'America/Hermosillo', + 'America/Indiana/Indianapolis' => 'America/Indiana/Indianapolis', + 'America/Indiana/Knox' => 'America/Indiana/Knox', + 'America/Indiana/Marengo' => 'America/Indiana/Marengo', + 'America/Indiana/Petersburg' => 'America/Indiana/Petersburg', + 'America/Indiana/Tell_City' => 'America/Indiana/Tell City', + 'America/Indiana/Vevay' => 'America/Indiana/Vevay', + 'America/Indiana/Vincennes' => 'America/Indiana/Vincennes', + 'America/Indiana/Winamac' => 'America/Indiana/Winamac', + 'America/Inuvik' => 'America/Inuvik', + 'America/Iqaluit' => 'America/Iqaluit', + 'America/Jamaica' => 'America/Jamaica', + 'America/Juneau' => 'America/Juneau', + 'America/Kentucky/Louisville' => 'America/Kentucky/Louisville', + 'America/Kentucky/Monticello' => 'America/Kentucky/Monticello', + 'America/Kralendijk' => 'America/Kralendijk', + 'America/La_Paz' => 'America/La Paz', + 'America/Lima' => 'America/Lima', + 'America/Los_Angeles' => 'America/Los Angeles', + 'America/Lower_Princes' => 'America/Lower Princes', + 'America/Maceio' => 'America/Maceio', + 'America/Managua' => 'America/Managua', + 'America/Manaus' => 'America/Manaus', + 'America/Marigot' => 'America/Marigot', + 'America/Martinique' => 'America/Martinique', + 'America/Matamoros' => 'America/Matamoros', + 'America/Mazatlan' => 'America/Mazatlan', + 'America/Menominee' => 'America/Menominee', + 'America/Merida' => 'America/Merida', + 'America/Metlakatla' => 'America/Metlakatla', + 'America/Mexico_City' => 'America/Mexico City', + 'America/Miquelon' => 'America/Miquelon', + 'America/Moncton' => 'America/Moncton', + 'America/Monterrey' => 'America/Monterrey', + 'America/Montevideo' => 'America/Montevideo', + 'America/Montreal' => 'America/Montreal', + 'America/Montserrat' => 'America/Montserrat', + 'America/Nassau' => 'America/Nassau', + 'America/New_York' => 'America/New York', + 'America/Nipigon' => 'America/Nipigon', + 'America/Nome' => 'America/Nome', + 'America/Noronha' => 'America/Noronha', + 'America/North_Dakota/Beulah' => 'America/North Dakota/Beulah', + 'America/North_Dakota/Center' => 'America/North Dakota/Center', + 'America/North_Dakota/New_Salem' => 'America/North Dakota/New Salem', + 'America/Ojinaga' => 'America/Ojinaga', + 'America/Panama' => 'America/Panama', + 'America/Pangnirtung' => 'America/Pangnirtung', + 'America/Paramaribo' => 'America/Paramaribo', + 'America/Phoenix' => 'America/Phoenix', + 'America/Port-au-Prince' => 'America/Port-au-Prince', + 'America/Port_of_Spain' => 'America/Port of Spain', + 'America/Porto_Velho' => 'America/Porto Velho', + 'America/Puerto_Rico' => 'America/Puerto Rico', + 'America/Rainy_River' => 'America/Rainy River', + 'America/Rankin_Inlet' => 'America/Rankin Inlet', + 'America/Recife' => 'America/Recife', + 'America/Regina' => 'America/Regina', + 'America/Resolute' => 'America/Resolute', + 'America/Rio_Branco' => 'America/Rio Branco', + 'America/Santa_Isabel' => 'America/Santa Isabel', + 'America/Santarem' => 'America/Santarem', + 'America/Santiago' => 'America/Santiago', + 'America/Santo_Domingo' => 'America/Santo Domingo', + 'America/Sao_Paulo' => 'America/Sao Paulo', + 'America/Scoresbysund' => 'America/Scoresbysund', + 'America/Shiprock' => 'America/Shiprock', + 'America/Sitka' => 'America/Sitka', + 'America/St_Barthelemy' => 'America/St. Barthelemy', + 'America/St_Johns' => 'America/St. Johns', + 'America/St_Kitts' => 'America/St. Kitts', + 'America/St_Lucia' => 'America/St. Lucia', + 'America/St_Thomas' => 'America/St. Thomas', + 'America/St_Vincent' => 'America/St. Vincent', + 'America/Swift_Current' => 'America/Swift Current', + 'America/Tegucigalpa' => 'America/Tegucigalpa', + 'America/Thule' => 'America/Thule', + 'America/Thunder_Bay' => 'America/Thunder Bay', + 'America/Tijuana' => 'America/Tijuana', + 'America/Toronto' => 'America/Toronto', + 'America/Tortola' => 'America/Tortola', + 'America/Vancouver' => 'America/Vancouver', + 'America/Whitehorse' => 'America/Whitehorse', + 'America/Winnipeg' => 'America/Winnipeg', + 'America/Yakutat' => 'America/Yakutat', + 'America/Yellowknife' => 'America/Yellowknife', + + 'Antarctica/Casey' => 'Antarctica/Casey', + 'Antarctica/Davis' => 'Antarctica/Davis', + 'Antarctica/DumontDUrville' => 'Antarctica/DumontDUrville', + 'Antarctica/Macquarie' => 'Antarctica/Macquarie', + 'Antarctica/Mawson' => 'Antarctica/Mawson', + 'Antarctica/McMurdo' => 'Antarctica/McMurdo', + 'Antarctica/Palmer' => 'Antarctica/Palmer', + 'Antarctica/Rothera' => 'Antarctica/Rothera', + 'Antarctica/South_Pole' => 'Antarctica/South Pole', + 'Antarctica/Syowa' => 'Antarctica/Syowa', + 'Antarctica/Vostok' => 'Antarctica/Vostok', + + 'Arctic/Longyearbyen' => 'Arctic/Longyearbyen', + + 'Asia/Aden' => 'Asia/Aden', + 'Asia/Almaty' => 'Asia/Almaty', + 'Asia/Amman' => 'Asia/Amman', + 'Asia/Anadyr' => 'Asia/Anadyr', + 'Asia/Aqtau' => 'Asia/Aqtau', + 'Asia/Aqtobe' => 'Asia/Aqtobe', + 'Asia/Ashgabat' => 'Asia/Ashgabat', + 'Asia/Baghdad' => 'Asia/Baghdad', + 'Asia/Bahrain' => 'Asia/Bahrain', + 'Asia/Baku' => 'Asia/Baku', + 'Asia/Bangkok' => 'Asia/Bangkok', + 'Asia/Beirut' => 'Asia/Beirut', + 'Asia/Bishkek' => 'Asia/Bishkek', + 'Asia/Brunei' => 'Asia/Brunei', + 'Asia/Choibalsan' => 'Asia/Choibalsan', + 'Asia/Chongqing' => 'Asia/Chongqing', + 'Asia/Colombo' => 'Asia/Colombo', + 'Asia/Damascus' => 'Asia/Damascus', + 'Asia/Dhaka' => 'Asia/Dhaka', + 'Asia/Dili' => 'Asia/Dili', + 'Asia/Dubai' => 'Asia/Dubai', + 'Asia/Dushanbe' => 'Asia/Dushanbe', + 'Asia/Gaza' => 'Asia/Gaza', + 'Asia/Harbin' => 'Asia/Harbin', + 'Asia/Hebron' => 'Asia/Hebron', + 'Asia/Ho_Chi_Minh' => 'Asia/Ho Chi Minh', + 'Asia/Hong_Kong' => 'Asia/Hong Kong', + 'Asia/Hovd' => 'Asia/Hovd', + 'Asia/Irkutsk' => 'Asia/Irkutsk', + 'Asia/Jakarta' => 'Asia/Jakarta', + 'Asia/Jayapura' => 'Asia/Jayapura', + 'Asia/Jerusalem' => 'Asia/Jerusalem', + 'Asia/Kabul' => 'Asia/Kabul', + 'Asia/Kamchatka' => 'Asia/Kamchatka', + 'Asia/Karachi' => 'Asia/Karachi', + 'Asia/Kashgar' => 'Asia/Kashgar', + 'Asia/Kathmandu' => 'Asia/Kathmandu', + 'Asia/Khandyga' => 'Asia/Khandyga', + 'Asia/Kolkata' => 'Asia/Kolkata', + 'Asia/Krasnoyarsk' => 'Asia/Krasnoyarsk', + 'Asia/Kuala_Lumpur' => 'Asia/Kuala Lumpur', + 'Asia/Kuching' => 'Asia/Kuching', + 'Asia/Kuwait' => 'Asia/Kuwait', + 'Asia/Macau' => 'Asia/Macau', + 'Asia/Magadan' => 'Asia/Magadan', + 'Asia/Makassar' => 'Asia/Makassar', + 'Asia/Manila' => 'Asia/Manila', + 'Asia/Muscat' => 'Asia/Muscat', + 'Asia/Nicosia' => 'Asia/Nicosia', + 'Asia/Novokuznetsk' => 'Asia/Novokuznetsk', + 'Asia/Novosibirsk' => 'Asia/Novosibirsk', + 'Asia/Omsk' => 'Asia/Omsk', + 'Asia/Oral' => 'Asia/Oral', + 'Asia/Phnom_Penh' => 'Asia/Phnom Penh', + 'Asia/Pontianak' => 'Asia/Pontianak', + 'Asia/Pyongyang' => 'Asia/Pyongyang', + 'Asia/Qatar' => 'Asia/Qatar', + 'Asia/Qyzylorda' => 'Asia/Qyzylorda', + 'Asia/Rangoon' => 'Asia/Rangoon', + 'Asia/Riyadh' => 'Asia/Riyadh', + 'Asia/Sakhalin' => 'Asia/Sakhalin', + 'Asia/Samarkand' => 'Asia/Samarkand', + 'Asia/Seoul' => 'Asia/Seoul', + 'Asia/Shanghai' => 'Asia/Shanghai', + 'Asia/Singapore' => 'Asia/Singapore', + 'Asia/Taipei' => 'Asia/Taipei', + 'Asia/Tashkent' => 'Asia/Tashkent', + 'Asia/Tbilisi' => 'Asia/Tbilisi', + 'Asia/Tehran' => 'Asia/Tehran', + 'Asia/Thimphu' => 'Asia/Thimphu', + 'Asia/Tokyo' => 'Asia/Tokyo', + 'Asia/Ulaanbaatar' => 'Asia/Ulaanbaatar', + 'Asia/Urumqi' => 'Asia/Urumqi', + 'Asia/Ust-Nera' => 'Asia/Ust-Nera', + 'Asia/Vientiane' => 'Asia/Vientiane', + 'Asia/Vladivostok' => 'Asia/Vladivostok', + 'Asia/Yakutsk' => 'Asia/Yakutsk', + 'Asia/Yekaterinburg' => 'Asia/Yekaterinburg', + 'Asia/Yerevan' => 'Asia/Yerevan', + + 'Atlantic/Azores' => 'Atlantic/Azores', + 'Atlantic/Bermuda' => 'Atlantic/Bermuda', + 'Atlantic/Canary' => 'Atlantic/Canary', + 'Atlantic/Cape_Verde' => 'Atlantic/Cape Verde', + 'Atlantic/Faroe' => 'Atlantic/Faroe', + 'Atlantic/Madeira' => 'Atlantic/Madeira', + 'Atlantic/Reykjavik' => 'Atlantic/Reykjavik', + 'Atlantic/South_Georgia' => 'Atlantic/South Georgia', + 'Atlantic/St_Helena' => 'Atlantic/St. Helena', + 'Atlantic/Stanley' => 'Atlantic/Stanley', + + 'Australia/Adelaide' => 'Australia/Adelaide', + 'Australia/Brisbane' => 'Australia/Brisbane', + 'Australia/Broken_Hill' => 'Australia/Broken Hill', + 'Australia/Currie' => 'Australia/Currie', + 'Australia/Darwin' => 'Australia/Darwin', + 'Australia/Eucla' => 'Australia/Eucla', + 'Australia/Hobart' => 'Australia/Hobart', + 'Australia/Lindeman' => 'Australia/Lindeman', + 'Australia/Lord_Howe' => 'Australia/Lord Howe', + 'Australia/Melbourne' => 'Australia/Melbourne', + 'Australia/Perth' => 'Australia/Perth', + 'Australia/Sydney' => 'Australia/Sydney', + + 'Europe/Amsterdam' => 'Europe/Amsterdam', + 'Europe/Andorra' => 'Europe/Andorra', + 'Europe/Athens' => 'Europe/Athens', + 'Europe/Belgrade' => 'Europe/Belgrade', + 'Europe/Berlin' => 'Europe/Berlin', + 'Europe/Bratislava' => 'Europe/Bratislava', + 'Europe/Brussels' => 'Europe/Brussels', + 'Europe/Bucharest' => 'Europe/Bucharest', + 'Europe/Budapest' => 'Europe/Budapest', + 'Europe/Busingen' => 'Europe/Busingen', + 'Europe/Chisinau' => 'Europe/Chisinau', + 'Europe/Copenhagen' => 'Europe/Copenhagen', + 'Europe/Dublin' => 'Europe/Dublin', + 'Europe/Gibraltar' => 'Europe/Gibraltar', + 'Europe/Guernsey' => 'Europe/Guernsey', + 'Europe/Helsinki' => 'Europe/Helsinki', + 'Europe/Isle_of_Man' => 'Europe/Isle of Man', + 'Europe/Istanbul' => 'Europe/Istanbul', + 'Europe/Jersey' => 'Europe/Jersey', + 'Europe/Kaliningrad' => 'Europe/Kaliningrad', + 'Europe/Kiev' => 'Europe/Kiev', + 'Europe/Lisbon' => 'Europe/Lisbon', + 'Europe/Ljubljana' => 'Europe/Ljubljana', + 'Europe/London' => 'Europe/London', + 'Europe/Luxembourg' => 'Europe/Luxembourg', + 'Europe/Madrid' => 'Europe/Madrid', + 'Europe/Malta' => 'Europe/Malta', + 'Europe/Mariehamn' => 'Europe/Mariehamn', + 'Europe/Minsk' => 'Europe/Minsk', + 'Europe/Monaco' => 'Europe/Monaco', + 'Europe/Moscow' => 'Europe/Moscow', + 'Europe/Oslo' => 'Europe/Oslo', + 'Europe/Paris' => 'Europe/Paris', + 'Europe/Podgorica' => 'Europe/Podgorica', + 'Europe/Prague' => 'Europe/Prague', + 'Europe/Riga' => 'Europe/Riga', + 'Europe/Rome' => 'Europe/Rome', + 'Europe/Samara' => 'Europe/Samara', + 'Europe/San_Marino' => 'Europe/San Marino', + 'Europe/Sarajevo' => 'Europe/Sarajevo', + 'Europe/Simferopol' => 'Europe/Simferopol', + 'Europe/Skopje' => 'Europe/Skopje', + 'Europe/Sofia' => 'Europe/Sofia', + 'Europe/Stockholm' => 'Europe/Stockholm', + 'Europe/Tallinn' => 'Europe/Tallinn', + 'Europe/Tirane' => 'Europe/Tirane', + 'Europe/Uzhgorod' => 'Europe/Uzhgorod', + 'Europe/Vaduz' => 'Europe/Vaduz', + 'Europe/Vatican' => 'Europe/Vatican', + 'Europe/Vienna' => 'Europe/Vienna', + 'Europe/Vilnius' => 'Europe/Vilnius', + 'Europe/Volgograd' => 'Europe/Volgograd', + 'Europe/Warsaw' => 'Europe/Warsaw', + 'Europe/Zagreb' => 'Europe/Zagreb', + 'Europe/Zaporozhye' => 'Europe/Zaporozhye', + 'Europe/Zurich' => 'Europe/Zurich', + + 'Indian/Antananarivo' => 'Indian/Antananarivo', + 'Indian/Chagos' => 'Indian/Chagos', + 'Indian/Christmas' => 'Indian/Christmas', + 'Indian/Cocos' => 'Indian/Cocos', + 'Indian/Comoro' => 'Indian/Comoro', + 'Indian/Kerguelen' => 'Indian/Kerguelen', + 'Indian/Mahe' => 'Indian/Mahe', + 'Indian/Maldives' => 'Indian/Maldives', + 'Indian/Mauritius' => 'Indian/Mauritius', + 'Indian/Mayotte' => 'Indian/Mayotte', + 'Indian/Reunion' => 'Indian/Reunion', + + 'Pacific/Apia' => 'Pacific/Apia', + 'Pacific/Auckland' => 'Pacific/Auckland', + 'Pacific/Chatham' => 'Pacific/Chatham', + 'Pacific/Chuuk' => 'Pacific/Chuuk', + 'Pacific/Easter' => 'Pacific/Easter', + 'Pacific/Efate' => 'Pacific/Efate', + 'Pacific/Enderbury' => 'Pacific/Enderbury', + 'Pacific/Fakaofo' => 'Pacific/Fakaofo', + 'Pacific/Fiji' => 'Pacific/Fiji', + 'Pacific/Funafuti' => 'Pacific/Funafuti', + 'Pacific/Galapagos' => 'Pacific/Galapagos', + 'Pacific/Gambier' => 'Pacific/Gambier', + 'Pacific/Guadalcanal' => 'Pacific/Guadalcanal', + 'Pacific/Guam' => 'Pacific/Guam', + 'Pacific/Honolulu' => 'Pacific/Honolulu', + 'Pacific/Johnston' => 'Pacific/Johnston', + 'Pacific/Kiritimati' => 'Pacific/Kiritimati', + 'Pacific/Kosrae' => 'Pacific/Kosrae', + 'Pacific/Kwajalein' => 'Pacific/Kwajalein', + 'Pacific/Majuro' => 'Pacific/Majuro', + 'Pacific/Marquesas' => 'Pacific/Marquesas', + 'Pacific/Midway' => 'Pacific/Midway', + 'Pacific/Nauru' => 'Pacific/Nauru', + 'Pacific/Niue' => 'Pacific/Niue', + 'Pacific/Norfolk' => 'Pacific/Norfolk', + 'Pacific/Noumea' => 'Pacific/Noumea', + 'Pacific/Pago_Pago' => 'Pacific/Pago Pago', + 'Pacific/Palau' => 'Pacific/Palau', + 'Pacific/Pitcairn' => 'Pacific/Pitcairn', + 'Pacific/Pohnpei' => 'Pacific/Pohnpei', + 'Pacific/Port_Moresby' => 'Pacific/Port Moresby', + 'Pacific/Rarotonga' => 'Pacific/Rarotonga', + 'Pacific/Saipan' => 'Pacific/Saipan', + 'Pacific/Tahiti' => 'Pacific/Tahiti', + 'Pacific/Tarawa' => 'Pacific/Tarawa', + 'Pacific/Tongatapu' => 'Pacific/Tongatapu', + 'Pacific/Wake' => 'Pacific/Wake', + 'Pacific/Wallis' => 'Pacific/Wallis', ), // The value is only an example and will get replaced by the current time on view @@ -940,7 +1373,7 @@ $lang = array_merge($lang, array( 'D M d, Y g:i a' => 'Mon Jan 01, 2007 1:37 pm', 'F jS, Y, g:i a' => 'January 1st, 2007, 1:37 pm', '|d M Y|, H:i' => 'Today, 13:37 / 01 Jan 2007, 13:37', - '|F jS, Y|, g:i a' => 'Today, 1:37 pm / January 1st, 2007, 1:37 pm' + '|F jS, Y|, g:i a' => 'Today, 1:37 pm / January 1st, 2007, 1:37 pm', ), // The default dateformat which will be used on new installs in this language diff --git a/phpBB/language/en/email/admin_activate.txt b/phpBB/language/en/email/admin_activate.txt index 8b11f1b450..a53ab1269e 100644 --- a/phpBB/language/en/email/admin_activate.txt +++ b/phpBB/language/en/email/admin_activate.txt @@ -10,5 +10,4 @@ Use this link to view the user's profile: Use this link to activate the account: {U_ACTIVATE} - -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/admin_send_email.txt b/phpBB/language/en/email/admin_send_email.txt index b778496258..7345a040fd 100644 --- a/phpBB/language/en/email/admin_send_email.txt +++ b/phpBB/language/en/email/admin_send_email.txt @@ -10,5 +10,4 @@ Message sent to you follows: {MESSAGE} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/admin_welcome_activated.txt b/phpBB/language/en/email/admin_welcome_activated.txt index cfdb69bdcb..2e136ac530 100644 --- a/phpBB/language/en/email/admin_welcome_activated.txt +++ b/phpBB/language/en/email/admin_welcome_activated.txt @@ -6,4 +6,4 @@ Your account on "{SITENAME}" has been activated by an administrator, you may log Your password has been securely stored in our database and cannot be retrieved. In the event that it is forgotten, you will be able to reset it using the email address associated with your account. -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/admin_welcome_inactive.txt b/phpBB/language/en/email/admin_welcome_inactive.txt index 8605956318..f9a57b9fe3 100644 --- a/phpBB/language/en/email/admin_welcome_inactive.txt +++ b/phpBB/language/en/email/admin_welcome_inactive.txt @@ -16,4 +16,4 @@ Your password has been securely stored in our database and cannot be retrieved. Thank you for registering. -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/email_notify.txt b/phpBB/language/en/email/email_notify.txt index 725b52f0cc..43c9098a4f 100644 --- a/phpBB/language/en/email/email_notify.txt +++ b/phpBB/language/en/email/email_notify.txt @@ -14,4 +14,4 @@ A message from {FROM_USERNAME} may also be included below. Please note that this ---------- -{MESSAGE}
\ No newline at end of file +{MESSAGE} diff --git a/phpBB/language/en/email/installed.txt b/phpBB/language/en/email/installed.txt index 8f63d07635..93444581f2 100644 --- a/phpBB/language/en/email/installed.txt +++ b/phpBB/language/en/email/installed.txt @@ -16,4 +16,4 @@ Useful information regarding the phpBB software can be found in the docs folder In order to keep your board safe and secure, we highly recommended keeping current with software releases. For your convenience, a mailing list is available at the page referenced above. -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/pm_report_closed.txt b/phpBB/language/en/email/pm_report_closed.txt index 1b9f4a6658..0202b9d374 100644 --- a/phpBB/language/en/email/pm_report_closed.txt +++ b/phpBB/language/en/email/pm_report_closed.txt @@ -4,5 +4,4 @@ Hello {USERNAME}, You are receiving this notification because the report you filed regarding the private message "{PM_SUBJECT}" at "{SITENAME}" has been tended to by a moderator or administrator. The report is now closed. If you have further questions, please contact {CLOSER_NAME} by private message. - -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/pm_report_deleted.txt b/phpBB/language/en/email/pm_report_deleted.txt index a868837841..991ed59f31 100644 --- a/phpBB/language/en/email/pm_report_deleted.txt +++ b/phpBB/language/en/email/pm_report_deleted.txt @@ -4,5 +4,4 @@ Hello {USERNAME}, You are receiving this notification because the report you filed regarding the private message "{PM_SUBJECT}" at "{SITENAME}" was deleted by a moderator or administrator. - -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/post_approved.txt b/phpBB/language/en/email/post_approved.txt index a02dba142a..854d785f5f 100644 --- a/phpBB/language/en/email/post_approved.txt +++ b/phpBB/language/en/email/post_approved.txt @@ -10,4 +10,4 @@ If you want to view the post, click the following link: If you want to view the topic, click the following link: {U_VIEW_TOPIC} -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/short/post_approved.txt b/phpBB/language/en/email/short/post_approved.txt index a02dba142a..854d785f5f 100644 --- a/phpBB/language/en/email/short/post_approved.txt +++ b/phpBB/language/en/email/short/post_approved.txt @@ -10,4 +10,4 @@ If you want to view the post, click the following link: If you want to view the topic, click the following link: {U_VIEW_TOPIC} -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/topic_notify.txt b/phpBB/language/en/email/topic_notify.txt index 529478eae2..d5272d7416 100644 --- a/phpBB/language/en/email/topic_notify.txt +++ b/phpBB/language/en/email/topic_notify.txt @@ -2,7 +2,7 @@ Subject: Topic reply notification - "{TOPIC_TITLE}" Hello {USERNAME}, -You are receiving this notification because you are watching the topic "{TOPIC_TITLE}" at "{SITENAME}". This topic has received a reply<!-- IF AUTHOR_NAME !== '' --> by {AUTHOR_NAME}<!-- ENDIF --> since your last visit. You can use the following link to view the replies made, no more notifications will be sent until you visit the topic. +You are receiving this notification because you are watching the topic "{TOPIC_TITLE}" at "{SITENAME}". This topic has received a reply<!-- IF AUTHOR_NAME !== '' --> by {AUTHOR_NAME}<!-- ENDIF --> since your last visit. No more notifications will be sent until you visit the topic. If you want to view the newest post made since your last visit, click the following link: {U_NEWEST_POST} @@ -14,7 +14,6 @@ If you want to view the forum, click the following link: {U_FORUM} If you no longer wish to watch this topic you can either click the "Unsubscribe topic" link found at the bottom of the topic above, or by clicking the following link: - {U_STOP_WATCHING_TOPIC} {EMAIL_SIG} diff --git a/phpBB/language/en/email/user_activate.txt b/phpBB/language/en/email/user_activate.txt index 7d7960c4c5..b949b68651 100644 --- a/phpBB/language/en/email/user_activate.txt +++ b/phpBB/language/en/email/user_activate.txt @@ -6,4 +6,4 @@ Your account on "{SITENAME}" has been deactivated, most likely due to changes ma {U_ACTIVATE} -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/user_activate_inactive.txt b/phpBB/language/en/email/user_activate_inactive.txt index a90773d48c..7743420698 100644 --- a/phpBB/language/en/email/user_activate_inactive.txt +++ b/phpBB/language/en/email/user_activate_inactive.txt @@ -4,4 +4,4 @@ Hello {USERNAME}, Your account on "{SITENAME}" has been deactivated, most likely due to changes made to your profile. The administrator of the board will need to activate it before you can log in. You will receive another notification when this has occurred. -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/user_activate_passwd.txt b/phpBB/language/en/email/user_activate_passwd.txt index 695be115f8..965d5a552c 100644 --- a/phpBB/language/en/email/user_activate_passwd.txt +++ b/phpBB/language/en/email/user_activate_passwd.txt @@ -14,4 +14,4 @@ Password: {PASSWORD} You can of course change this password yourself via the profile page. If you have any difficulties please contact the board administrator. -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/user_reactivate_account.txt b/phpBB/language/en/email/user_reactivate_account.txt index 385c09f4c5..7564b0a8e4 100644 --- a/phpBB/language/en/email/user_reactivate_account.txt +++ b/phpBB/language/en/email/user_reactivate_account.txt @@ -15,4 +15,4 @@ Please visit the following link to reactivate your account: {U_ACTIVATE} -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/user_remind_inactive.txt b/phpBB/language/en/email/user_remind_inactive.txt index 1ba28329f6..1f136b56f2 100644 --- a/phpBB/language/en/email/user_remind_inactive.txt +++ b/phpBB/language/en/email/user_remind_inactive.txt @@ -8,4 +8,4 @@ This notification is a reminder that your account at "{SITENAME}", created on {R Thank you for registering at "{SITENAME}", we look forward to your participation. -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/user_resend_inactive.txt b/phpBB/language/en/email/user_resend_inactive.txt index b9b95ce9e5..d975a07b13 100644 --- a/phpBB/language/en/email/user_resend_inactive.txt +++ b/phpBB/language/en/email/user_resend_inactive.txt @@ -16,4 +16,4 @@ Please visit the following link in order to activate your account: Thank you for registering. -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/user_welcome.txt b/phpBB/language/en/email/user_welcome.txt index aaead86afc..f299b7b23e 100644 --- a/phpBB/language/en/email/user_welcome.txt +++ b/phpBB/language/en/email/user_welcome.txt @@ -14,4 +14,4 @@ Your password has been securely stored in our database and cannot be retrieved. Thank you for registering. -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/user_welcome_inactive.txt b/phpBB/language/en/email/user_welcome_inactive.txt index 5cbb3af3de..b4300d0032 100644 --- a/phpBB/language/en/email/user_welcome_inactive.txt +++ b/phpBB/language/en/email/user_welcome_inactive.txt @@ -18,4 +18,4 @@ Your password has been securely stored in our database and cannot be retrieved. Thank you for registering. -{EMAIL_SIG}
\ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/groups.php b/phpBB/language/en/groups.php index 6155d34a8c..c36d87f793 100644 --- a/phpBB/language/en/groups.php +++ b/phpBB/language/en/groups.php @@ -81,7 +81,7 @@ $lang = array_merge($lang, array( 'NOT_LEADER_OF_GROUP' => 'The requested operation cannot be taken because you are not a leader of the selected group.', 'NOT_MEMBER_OF_GROUP' => 'The requested operation cannot be taken because you are not a member of the selected group or your membership has not been approved yet.', 'NOT_RESIGN_FROM_DEFAULT_GROUP' => 'You are not allowed to resign from your default group.', - + 'PRIMARY_GROUP' => 'Primary group', 'REMOVE_SELECTED' => 'Remove selected', diff --git a/phpBB/language/en/help_bbcode.php b/phpBB/language/en/help_bbcode.php index e0cda9df04..61263752b2 100644 --- a/phpBB/language/en/help_bbcode.php +++ b/phpBB/language/en/help_bbcode.php @@ -88,7 +88,7 @@ $help = array( ), array( 0 => 'Linking to another site', - 1 => 'phpBB BBCode supports a number of ways of creating URIs (Uniform Resource Indicators) better known as URLs.<ul><li>The first of these uses the <strong>[url=][/url]</strong> tag, whatever you type after the = sign will cause the contents of that tag to act as a URL. For example to link to phpBB.com you could use:<br /><br /><strong>[url=http://www.phpbb.com/]</strong>Visit phpBB!<strong>[/url]</strong><br /><br />This would generate the following link, <a href="http://www.phpbb.com/">Visit phpBB!</a> Please notice that the link opens in the same window or a new window depending on the users browser preferences.</li><li>If you want the URL itself displayed as the link you can do this by simply using:<br /><br /><strong>[url]</strong>http://www.phpbb.com/<strong>[/url]</strong><br /><br />This would generate the following link, <a href="http://www.phpbb.com/">http://www.phpbb.com/</a></li><li>Additionally, phpBB features something called <i>Magic Links</i>, this will turn any syntactically correct URL into a link without you needing to specify any tags or even the leading http://. For example typing www.phpbb.com into your message will automatically lead to <a href="http://www.phpbb.com/">www.phpbb.com</a> being output when you view the message.</li><li>The same thing applies equally to email addresses, you can either specify an address explicitly for example:<br /><br /><strong>[email]</strong>no.one@domain.adr<strong>[/email]</strong><br /><br />which will output <a href="mailto:no.one@domain.adr">no.one@domain.adr</a> or you can just type no.one@domain.adr into your message and it will be automatically converted when you view.</li></ul>As with all the BBCode tags you can wrap URLs around any of the other tags such as <strong>[img][/img]</strong> (see next entry), <strong>[b][/b]</strong>, etc. As with the formatting tags it is up to you to ensure the correct open and close order is following, for example:<br /><br /><strong>[url=http://www.google.com/][img]</strong>http://www.google.com/intl/en_ALL/images/logo.gif<strong>[/url][/img]</strong><br /><br />is <span style="text-decoration: underline">not</span> correct which may lead to your post being deleted so take care.' + 1 => 'phpBB BBCode supports a number of ways of creating URIs (Uniform Resource Indicators) better known as URLs.<ul><li>The first of these uses the <strong>[url=][/url]</strong> tag, whatever you type after the = sign will cause the contents of that tag to act as a URL. For example to link to phpBB.com you could use:<br /><br /><strong>[url=http://www.phpbb.com/]</strong>Visit phpBB!<strong>[/url]</strong><br /><br />This would generate the following link, <a href="http://www.phpbb.com/">Visit phpBB!</a> Please notice that the link opens in the same window or a new window depending on the users browser preferences.</li><li>If you want the URL itself displayed as the link you can do this by simply using:<br /><br /><strong>[url]</strong>http://www.phpbb.com/<strong>[/url]</strong><br /><br />This would generate the following link, <a href="http://www.phpbb.com/">http://www.phpbb.com/</a></li><li>Additionally, phpBB features something called <i>Magic Links</i>, this will turn any syntactically correct URL into a link without you needing to specify any tags or even the leading http://. For example typing www.phpbb.com into your message will automatically lead to <a href="http://www.phpbb.com/">www.phpbb.com</a> being output when you view the message.</li><li>The same thing applies equally to email addresses, you can either specify an address explicitly for example:<br /><br /><strong>[email]</strong>no.one@domain.adr<strong>[/email]</strong><br /><br />which will output <a href="mailto:no.one@domain.adr">no.one@domain.adr</a> or you can just type no.one@domain.adr into your message and it will be automatically converted when you view.</li></ul>As with all the BBCode tags you can wrap URLs around any of the other tags such as <strong>[img][/img]</strong> (see next entry), <strong>[b][/b]</strong>, etc. As with the formatting tags it is up to you to ensure the correct open and close order is following, for example:<br /><br /><strong>[url=http://www.phpbb.com/][img]</strong>http://www.phpbb.com/theme/images/logos/blue/160x52.png<strong>[/url][/img]</strong><br /><br />is <span style="text-decoration: underline">not</span> correct which may lead to your post being deleted so take care.' ), array( 0 => '--', @@ -96,7 +96,7 @@ $help = array( ), array( 0 => 'Adding an image to a post', - 1 => 'phpBB BBCode incorporates a tag for including images in your posts. Two very important things to remember when using this tag are: many users do not appreciate lots of images being shown in posts and secondly the image you display must already be available on the internet (it cannot exist only on your computer for example, unless you run a webserver!). To display an image you must surround the URL pointing to the image with <strong>[img][/img]</strong> tags. For example:<br /><br /><strong>[img]</strong>http://www.google.com/intl/en_ALL/images/logo.gif<strong>[/img]</strong><br /><br />As noted in the URL section above you can wrap an image in a <strong>[url][/url]</strong> tag if you wish, e.g.<br /><br /><strong>[url=http://www.google.com/][img]</strong>http://www.google.com/intl/en_ALL/images/logo.gif<strong>[/img][/url]</strong><br /><br />would generate:<br /><br /><a href="http://www.google.com/"><img src="http://www.google.com/intl/en_ALL/images/logo.gif" alt="" /></a>' + 1 => 'phpBB BBCode incorporates a tag for including images in your posts. Two very important things to remember when using this tag are: many users do not appreciate lots of images being shown in posts and secondly the image you display must already be available on the internet (it cannot exist only on your computer for example, unless you run a webserver!). To display an image you must surround the URL pointing to the image with <strong>[img][/img]</strong> tags. For example:<br /><br /><strong>[img]</strong>http://www.phpbb.com/theme/images/logos/blue/160x52.png<strong>[/img]</strong><br /><br />As noted in the URL section above you can wrap an image in a <strong>[url][/url]</strong> tag if you wish, e.g.<br /><br /><strong>[url=http://www.phpbb.com/][img]</strong>http://www.phpbb.com/theme/images/logos/blue/160x52.png<strong>[/img][/url]</strong><br /><br />would generate:<br /><br /><a href="http://www.phpbb.com/"><img src="http://www.phpbb.com/theme/images/logos/blue/160x52.png" alt="" /></a>' ), array( 0 => 'Adding attachments into a post', @@ -109,5 +109,5 @@ $help = array( array( 0 => 'Can I add my own tags?', 1 => 'If you are an administrator on this board and have the proper permissions, you can add further BBCodes through the Custom BBCodes section.' - ) + ), ); diff --git a/phpBB/language/en/help_faq.php b/phpBB/language/en/help_faq.php index 94e6622685..d803ec91e4 100644 --- a/phpBB/language/en/help_faq.php +++ b/phpBB/language/en/help_faq.php @@ -337,5 +337,5 @@ $help = array( array( 0 => 'Who do I contact about abusive and/or legal matters related to this board?', 1 => 'Any of the administrators listed on the “The team” page should be an appropriate point of contact for your complaints. If this still gets no response then you should contact the owner of the domain (do a <a href="http://www.google.com/search?q=whois">whois lookup</a>) or, if this is running on a free service (e.g. Yahoo!, free.fr, f2s.com, etc.), the management or abuse department of that service. Please note that the phpBB Group has <strong>absolutely no jurisdiction</strong> and cannot in any way be held liable over how, where or by whom this board is used. Do not contact the phpBB Group in relation to any legal (cease and desist, liable, defamatory comment, etc.) matter <strong>not directly related</strong> to the phpBB.com website or the discrete software of phpBB itself. If you do email phpBB Group <strong>about any third party</strong> use of this software then you should expect a terse response or no response at all.' - ) + ), ); diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php index 03c9562983..081361f661 100644 --- a/phpBB/language/en/install.php +++ b/phpBB/language/en/install.php @@ -490,6 +490,7 @@ $lang = array_merge($lang, array( 'PREVIOUS_VERSION' => 'Previous version', 'PROGRESS' => 'Progress', + 'RELEASE_ANNOUNCEMENT' => 'Announcement', 'RESULT' => 'Result', 'RUN_DATABASE_SCRIPT' => 'Update my database now', @@ -532,7 +533,7 @@ $lang = array_merge($lang, array( <h1>Release announcement</h1> - <p>Please read <a href="%1$s" title="%1$s"><strong>the release announcement for the latest version</strong></a> before you continue your update process, it may contain useful information. It also contains full download links as well as the change log.</p> + <p>Please read the release announcement for the latest version before you continue your update process, it may contain useful information. It also contains full download links as well as the change log.</p> <br /> @@ -547,17 +548,11 @@ $lang = array_merge($lang, array( </ul> <p>Once uploaded your board will be offline for normal users due to the install directory you uploaded now present.<br /><br /> - <strong><a href="%2$s" title="%2$s">Now start the update process by pointing your browser to the install folder</a>.</strong><br /> + <strong><a href="%1$s" title="%1$s">Now start the update process by pointing your browser to the install folder</a>.</strong><br /> <br /> You will then be guided through the update process. You will be notified once the update is complete. </p> ', - 'UPDATE_INSTRUCTIONS_INCOMPLETE' => ' - - <h1>Incomplete update detected</h1> - - <p>phpBB detected an incomplete automatic update. Please make sure you followed every step within the automatic update tool. Below you will find the link again, or go directly to your install directory.</p> - ', 'UPDATE_METHOD' => 'Update method', 'UPDATE_METHOD_EXPLAIN' => 'You are now able to choose your preferred update method. Using the FTP upload will present you with a form you need to enter your FTP account details into. With this method the files will be automatically moved to the new location and backups of the old files being created by appending .bak to the filename. If you choose to download the modified files you are able to unpack and upload them to their correct location manually later.', 'UPDATE_REQUIRES_FILE' => 'The updater requires that the following file is present: %s', @@ -567,7 +562,6 @@ $lang = array_merge($lang, array( 'UPDATING_DATA' => 'Updating data', 'UPDATING_TO_LATEST_STABLE' => 'Updating database to latest stable release', 'UPDATED_VERSION' => 'Updated version', - 'UPGRADE_INSTRUCTIONS' => 'A new feature release <strong>%1$s</strong> is available. Please read <a href="%2$s" title="%2$s"><strong>the release announcement</strong></a> to learn about what it has to offer, and how to upgrade.', 'UPLOAD_METHOD' => 'Upload method', 'UPDATE_DB_SUCCESS' => 'Database update was successful.', diff --git a/phpBB/language/en/mcp.php b/phpBB/language/en/mcp.php index b75e0ea495..dffa40db2f 100644 --- a/phpBB/language/en/mcp.php +++ b/phpBB/language/en/mcp.php @@ -426,6 +426,6 @@ $lang = array_merge($lang, array( 'SPAM' => 'The reported message has the only purpose to advertise for a website or another product.', 'OFF_TOPIC' => 'The reported message is off topic.', 'OTHER' => 'The reported message does not fit into any other category, please use the further information field.', - ) + ), ), )); diff --git a/phpBB/language/en/memberlist.php b/phpBB/language/en/memberlist.php index ec21e8e904..95efe35b7d 100644 --- a/phpBB/language/en/memberlist.php +++ b/phpBB/language/en/memberlist.php @@ -71,16 +71,10 @@ $lang = array_merge($lang, array( 'HIDE_MEMBER_SEARCH' => 'Hide member search', 'IM_ADD_CONTACT' => 'Add Contact', - 'IM_AIM' => 'Please note that you need AOL Instant Messenger installed to use this.', - 'IM_AIM_EXPRESS' => 'AIM Express', 'IM_DOWNLOAD_APP' => 'Download application', - 'IM_ICQ' => 'Please note that users may have selected to not receive unsolicited instant messages.', 'IM_JABBER' => 'Please note that users may have selected to not receive unsolicited instant messages.', 'IM_JABBER_SUBJECT' => 'This is an automated message please do not reply! Message from user %1$s at %2$s.', 'IM_MESSAGE' => 'Your message', - 'IM_MSNM' => 'Please note that you need Windows Live Messenger installed to use this.', - 'IM_MSNM_BROWSER' => 'Your browser does not support this.', - 'IM_MSNM_CONNECT' => 'WLM is not connected.\nYou have to connect to WLM to continue.', 'IM_NAME' => 'Your Name', 'IM_NO_DATA' => 'There is no suitable contact information for this user.', 'IM_NO_JABBER' => 'Sorry, direct messaging of Jabber users is not supported on this board. You will need a Jabber client installed on your system to contact the recipient above.', @@ -96,7 +90,7 @@ $lang = array_merge($lang, array( 1 => '%d user', 2 => '%d users', ), - 'LOGIN_EXPLAIN_LEADERS' => 'The board requires you to be registered and logged in to view the team listing.', + 'LOGIN_EXPLAIN_TEAM' => 'The board requires you to be registered and logged in to view the team listing.', 'LOGIN_EXPLAIN_MEMBERLIST' => 'The board requires you to be registered and logged in to access the memberlist.', 'LOGIN_EXPLAIN_SEARCHUSER' => 'The board requires you to be registered and logged in to search users.', 'LOGIN_EXPLAIN_VIEWPROFILE' => 'The board requires you to be registered and logged in to view profiles.', @@ -118,12 +112,10 @@ $lang = array_merge($lang, array( 'SELECT_MARKED' => 'Select marked', 'SELECT_SORT_METHOD' => 'Select sort method', - 'SEND_AIM_MESSAGE' => 'Send AIM message', 'SEND_ICQ_MESSAGE' => 'Send ICQ message', 'SEND_IM' => 'Instant messaging', 'SEND_JABBER_MESSAGE' => 'Send Jabber message', 'SEND_MESSAGE' => 'Message', - 'SEND_MSNM_MESSAGE' => 'Send WLM message', 'SEND_YIM_MESSAGE' => 'Send YIM message', 'SORT_EMAIL' => 'Email', 'SORT_LAST_ACTIVE' => 'Last active', @@ -140,9 +132,7 @@ $lang = array_merge($lang, array( ), 'USER_ONLINE' => 'Online', 'USER_PRESENCE' => 'Board presence', + 'USERS_PER_PAGE' => 'Users per page', 'VIEWING_PROFILE' => 'Viewing profile - %s', - 'VISITED' => 'Last visited', - - 'WWW' => 'Website', )); diff --git a/phpBB/language/en/migrator.php b/phpBB/language/en/migrator.php index 34dcbf4c52..1d8886d12b 100644 --- a/phpBB/language/en/migrator.php +++ b/phpBB/language/en/migrator.php @@ -39,11 +39,12 @@ $lang = array_merge($lang, array( 'GROUP_NOT_EXIST' => 'The group "%s" unexpectedly does not exist.', - 'MIGRATION_DATA_DONE' => 'Installed Data: %s', + 'MIGRATION_DATA_DONE' => 'Installed Data: %1$s; Time: %2$.2f seconds', + 'MIGRATION_DATA_IN_PROGRESS' => 'Installing Data: %1$s; Time: %2$.2f seconds', 'MIGRATION_EFFECTIVELY_INSTALLED' => 'Migration already effectively installed (skipped): %s', 'MIGRATION_EXCEPTION_ERROR' => 'Something went wrong during the request and an exception was thrown. The changes made before the error occurred were reversed to the best of our abilities, but you should check the board for errors.', 'MIGRATION_NOT_FULFILLABLE' => 'The migration "%1$s" is not fulfillable, missing migration "%2$s".', - 'MIGRATION_SCHEMA_DONE' => 'Installed Schema: %s', + 'MIGRATION_SCHEMA_DONE' => 'Installed Schema: %1$s; Time: %2$.2f seconds', 'MODULE_ERROR' => 'An error occurred while creating a module: %s', 'MODULE_INFO_FILE_NOT_EXIST' => 'A required module info file is missing: %2$s', diff --git a/phpBB/language/en/mods/index.htm b/phpBB/language/en/mods/index.htm deleted file mode 100644 index e69de29bb2..0000000000 --- a/phpBB/language/en/mods/index.htm +++ /dev/null diff --git a/phpBB/language/en/plupload.php b/phpBB/language/en/plupload.php new file mode 100644 index 0000000000..f174920f6b --- /dev/null +++ b/phpBB/language/en/plupload.php @@ -0,0 +1,77 @@ +<?php +/** +* +* plupload [English] +* +* @package language +* @copyright (c) 2010-2013 Moxiecode Systems AB +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* DO NOT CHANGE +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +if (empty($lang) || !is_array($lang)) +{ + $lang = array(); +} + +// DEVELOPERS PLEASE NOTE +// +// All language files should use UTF-8 as their encoding and the files must not contain a BOM. +// +// Placeholders can now contain order information, e.g. instead of +// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows +// translators to re-order the output of data while ensuring it remains correct +// +// You do not need this where single placeholders are used, e.g. 'Message %d' is fine +// equally where a string contains only two placeholders which are used to wrap text +// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine + +$lang = array_merge($lang, array( + 'PLUPLOAD_ADD_FILES' => 'Add files', + 'PLUPLOAD_ADD_FILES_TO_QUEUE' => 'Add files to the upload queue and click the start button.', + 'PLUPLOAD_ALREADY_QUEUED' => '%s already present in the queue.', + 'PLUPLOAD_CLOSE' => 'Close', + 'PLUPLOAD_DRAG' => 'Drag files here.', + 'PLUPLOAD_DUPLICATE_ERROR' => 'Duplicate file error.', + 'PLUPLOAD_DRAG_TEXTAREA' => 'You may also attach files by dragging and dropping them in the message box.', + 'PLUPLOAD_ERR_INPUT' => 'Failed to open input stream.', + 'PLUPLOAD_ERR_MOVE_UPLOADED' => 'Failed to move uploaded file.', + 'PLUPLOAD_ERR_OUTPUT' => 'Failed to open output stream.', + 'PLUPLOAD_ERR_FILE_TOO_LARGE' => 'File too large:', + 'PLUPLOAD_ERR_FILE_COUNT' => 'File count error.', + 'PLUPLOAD_ERR_FILE_INVALID_EXT' => 'Invalid file extension:', + 'PLUPLOAD_ERR_RUNTIME_MEMORY' => 'Runtime ran out of available memory.', + 'PLUPLOAD_ERR_UPLOAD_URL' => 'Upload URL might be wrong or does not exist.', + 'PLUPLOAD_EXTENSION_ERROR' => 'File extension error.', + 'PLUPLOAD_FILE' => 'File: %s', + 'PLUPLOAD_FILE_DETAILS' => 'File: %s, size: %d, max file size: %d', + 'PLUPLOAD_FILENAME' => 'Filename', + 'PLUPLOAD_FILES_QUEUED' => '%d files queued', + 'PLUPLOAD_GENERIC_ERROR' => 'Generic error.', + 'PLUPLOAD_HTTP_ERROR' => 'HTTP error.', + 'PLUPLOAD_IMAGE_FORMAT' => 'Image format either wrong or not supported.', + 'PLUPLOAD_INIT_ERROR' => 'Init error.', + 'PLUPLOAD_IO_ERROR' => 'IO error.', + 'PLUPLOAD_NOT_APPLICABLE' => 'N/A', + 'PLUPLOAD_SECURITY_ERROR' => 'Security error.', + 'PLUPLOAD_SELECT_FILES' => 'Select files', + 'PLUPLOAD_SIZE' => 'Size', + 'PLUPLOAD_SIZE_ERROR' => 'File size error.', + 'PLUPLOAD_STATUS' => 'Status', + 'PLUPLOAD_START_UPLOAD' => 'Start upload', + 'PLUPLOAD_START_CURRENT_UPLOAD' => 'Start uploading queue', + 'PLUPLOAD_STOP_UPLOAD' => 'Stop upload', + 'PLUPLOAD_STOP_CURRENT_UPLOAD' => 'Stop current upload', + // Note: This string is formatted independently by plupload and so does not + // use the same formatting rules as normal phpBB translation strings + 'PLUPLOAD_UPLOADED' => 'Uploaded %d/%d files', +)); diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php index 0e8d59a92e..e3b6101310 100644 --- a/phpBB/language/en/posting.php +++ b/phpBB/language/en/posting.php @@ -53,7 +53,7 @@ $lang = array_merge($lang, array( 'BBCODE_IS_OFF' => '%sBBCode%s is <em>OFF</em>', 'BBCODE_IS_ON' => '%sBBCode%s is <em>ON</em>', 'BBCODE_I_HELP' => 'Italic text: [i]text[/i]', - 'BBCODE_L_HELP' => 'List: [list][*]text[/list]', + 'BBCODE_L_HELP' => 'List: [list][*]text[/list]', 'BBCODE_LISTITEM_HELP' => 'List item: [*]text', 'BBCODE_O_HELP' => 'Ordered list: e.g. [list=1][*]First point[/list] or [list=a][*]Point a[/list]', 'BBCODE_P_HELP' => 'Insert image: [img]http://image_url[/img]', @@ -85,7 +85,7 @@ $lang = array_merge($lang, array( 'DELETE_POSTS_PERMANENTLY_CONFIRM' => 'Are you sure you want to <strong>permanently</strong> delete these posts?', 'DELETE_REASON' => 'Soft delete reason', 'DELETE_REASON_EXPLAIN' => 'The specified reason for deletion will be visible to moderators.', - 'DELETE_POST_WARN' => 'Deleted this post', + 'DELETE_POST_WARN' => 'Delete this post', 'DELETE_TOPIC_CONFIRM' => 'Are you sure you want to delete this topic?', 'DELETE_TOPIC_PERMANENTLY' => 'Permanently delete this topic so it can not be recovered', 'DELETE_TOPIC_PERMANENTLY_CONFIRM' => 'Are you sure you want to <strong>permanently</strong> delete this topic?', @@ -194,9 +194,9 @@ $lang = array_merge($lang, array( 'POST_APPROVAL_NOTIFY' => 'You will be notified when your post has been approved.', 'POST_CONFIRMATION' => 'Confirmation of post', 'POST_CONFIRM_EXPLAIN' => 'To prevent automated posts the board requires you to enter a confirmation code. The code is displayed in the image you should see below. If you are visually impaired or cannot otherwise read this code please contact the %sBoard Administrator%s.', - 'POST_DELETED' => 'This message has been deleted successfully.', - 'POST_EDITED' => 'This message has been edited successfully.', - 'POST_EDITED_MOD' => 'This message has been edited successfully, but it will need to be approved by a moderator before it is publicly viewable.', + 'POST_DELETED' => 'This post has been deleted successfully.', + 'POST_EDITED' => 'This post has been edited successfully.', + 'POST_EDITED_MOD' => 'This post has been edited successfully, but it will need to be approved by a moderator before it is publicly viewable.', 'POST_GLOBAL' => 'Global', 'POST_ICON' => 'Post icon', 'POST_NORMAL' => 'Normal', diff --git a/phpBB/language/en/search.php b/phpBB/language/en/search.php index 71cbec4b41..13aa66514c 100644 --- a/phpBB/language/en/search.php +++ b/phpBB/language/en/search.php @@ -60,13 +60,19 @@ $lang = array_merge($lang, array( 'LOGIN_EXPLAIN_UNREADSEARCH'=> 'The board requires you to be registered and logged in to view your unread posts.', 'LOGIN_EXPLAIN_NEWPOSTS' => 'The board requires you to be registered and logged in to view new posts since your last visit.', - 'MAX_NUM_SEARCH_KEYWORDS_REFINE' => 'You specified too many words to search for. Please do not enter more than %1$d words.', + 'MAX_NUM_SEARCH_KEYWORDS_REFINE' => array( + 1 => 'You specified too many words to search for. Please do not enter more than %1$d word.', + 2 => 'You specified too many words to search for. Please do not enter more than %1$d words.', + ), 'NO_KEYWORDS' => 'You must specify at least one word to search for. Each word must consist of at least %s and must not contain more than %s excluding wildcards.', 'NO_RECENT_SEARCHES' => 'No searches have been carried out recently.', 'NO_SEARCH' => 'Sorry but you are not permitted to use the search system.', 'NO_SEARCH_RESULTS' => 'No suitable matches were found.', - 'NO_SEARCH_TIME' => 'Sorry but you cannot use search at this time. Please try again in a few minutes.', + 'NO_SEARCH_TIME' => array( + 1 => 'Sorry but you cannot use search at this time. Please try again in %d second.', + 2 => 'Sorry but you cannot use search at this time. Please try again in %d seconds.', + ), 'NO_SEARCH_UNREADS' => 'Sorry but searching for unread posts has been disabled on this board.', 'WORD_IN_NO_POST' => 'No posts were found because the word <strong>%s</strong> is not contained in any post.', 'WORDS_IN_NO_POST' => 'No posts were found because the words <strong>%s</strong> are not contained in any post.', diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index e2d5dc5ad1..79d2b9fa3a 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -205,10 +205,13 @@ $lang = array_merge($lang, array( ), 'FIELD_TOO_SMALL' => 'The value of “%2$s” is too small, a minimum value of %1$d is required.', 'FIELD_TOO_LARGE' => 'The value of “%2$s” is too large, a maximum value of %1$d is allowed.', + 'FIELD_INVALID_CHARS_INVALID' => 'The field “%s” has invalid characters.', 'FIELD_INVALID_CHARS_NUMBERS_ONLY' => 'The field “%s” has invalid characters, only numbers are allowed.', 'FIELD_INVALID_CHARS_ALPHA_ONLY' => 'The field “%s” has invalid characters, only alphanumeric characters are allowed.', - 'FIELD_INVALID_CHARS_SPACERS_ONLY' => 'The field “%s” has invalid characters, only alphanumeric, space or -+_[] characters are allowed.', + 'FIELD_INVALID_CHARS_ALPHA_SPACERS' => 'The field “%s” has invalid characters, only alphanumeric, space or -+_[] characters are allowed.', + 'FIELD_INVALID_CHARS_ALPHA_UNDERSCORE' => 'The field “%s” has invalid characters, only alphanumeric or _ characters are allowed.', 'FIELD_INVALID_DATE' => 'The field “%s” has an invalid date.', + 'FIELD_INVALID_URL' => 'The field “%s” has an invalid url.', 'FIELD_INVALID_VALUE' => 'The field “%s” has an invalid value.', 'FOE_MESSAGE' => 'Message from foe', @@ -216,8 +219,8 @@ $lang = array_merge($lang, array( 'FOES_UPDATED' => 'Your foes list has been updated successfully.', 'FOLDER_ADDED' => 'Folder successfully added.', 'FOLDER_MESSAGE_STATUS' => array( - 1 => '%2$d from %1$d message stored', - 2 => '%2$d from %1$d messages stored', + 1 => '%2$d out of %1$s stored', + 2 => '%2$d out of %1$s stored', ), 'FOLDER_NAME_EMPTY' => 'You must enter a name for this folder.', 'FOLDER_NAME_EXIST' => 'Folder <strong>%s</strong> already exists.', @@ -225,8 +228,8 @@ $lang = array_merge($lang, array( 'FOLDER_RENAMED' => 'Folder successfully renamed.', 'FOLDER_REMOVED' => 'Folder successfully removed.', 'FOLDER_STATUS_MSG' => array( - 1 => 'Folder is %3$d%% full (%2$d from %1$d message stored)', - 2 => 'Folder is %3$d%% full (%2$d from %1$d messages stored)', + 1 => 'Folder is %3$d%% full (%2$d out of %1$s stored)', + 2 => 'Folder is %3$d%% full (%2$d out of %1$s stored)', ), 'FORWARD_PM' => 'Forward PM', 'FORCE_PASSWORD_EXPLAIN' => 'Before you may continue browsing the board you are required to change your password.', @@ -297,7 +300,8 @@ $lang = array_merge($lang, array( 'MOVE_DOWN' => 'Move down', 'MOVE_MARKED_TO_FOLDER' => 'Move marked to %s', 'MOVE_PM_ERROR' => array( - 2 => 'An error occurred while moving the messages to the new folder, only %2d from %1d messages were moved.', + 1 => 'An error occurred while moving the messages to the new folder, only %2$d out of %1$s was moved.', + 2 => 'An error occurred while moving the messages to the new folder, only %2$d out of %1$s were moved.', ), 'MOVE_TO_FOLDER' => 'Move to folder', 'MOVE_UP' => 'Move up', @@ -312,6 +316,7 @@ $lang = array_merge($lang, array( 'NOTIFICATIONS_MARK_ALL_READ_SUCCESS' => 'All notifications have been marked read.', 'NOTIFICATION_GROUP_MISCELLANEOUS' => 'Miscellaneous Notifications', 'NOTIFICATION_GROUP_MODERATION' => 'Moderation Notifications', + 'NOTIFICATION_GROUP_ADMINISTRATION' => 'Administration Notifications', 'NOTIFICATION_GROUP_POSTING' => 'Posting Notifications', 'NOTIFICATION_METHOD_EMAIL' => 'Email', 'NOTIFICATION_METHOD_JABBER' => 'Jabber', @@ -325,6 +330,7 @@ $lang = array_merge($lang, array( 'NOTIFICATION_TYPE_QUOTE' => 'Someone quotes you in a post', 'NOTIFICATION_TYPE_REPORT' => 'Someone reports a post', 'NOTIFICATION_TYPE_TOPIC' => 'Someone creates a topic in a forum to which you are subscribed', + 'NOTIFICATION_TYPE_ADMIN_ACTIVATE_USER' => 'Newly registered user requiring activation', 'NOTIFY_METHOD' => 'Notification method', 'NOTIFY_METHOD_BOTH' => 'Both', @@ -406,8 +412,8 @@ $lang = array_merge($lang, array( 'PM_SENTBOX' => 'Sent messages', 'PM_SUBJECT' => 'Message subject', 'PM_TO' => 'Send to', + 'PM_TOOLS' => 'Message tools', 'PM_USERS_REMOVED_NO_PM' => 'Some users couldn’t be added as they have disabled private message receipt.', - 'POPUP_ON_PM' => 'Pop up window on new private message', 'POST_EDIT_PM' => 'Edit message', 'POST_FORWARD_PM' => 'Forward message', 'POST_NEW_PM' => 'Compose message', @@ -471,14 +477,17 @@ $lang = array_merge($lang, array( 'TIMEZONE' => 'Timezone', 'TIMEZONE_DATE_SUGGESTION' => 'Suggestion: %s', 'TIMEZONE_INVALID' => 'The timezone you selected is invalid.', - 'TO' => 'To', + 'TO' => 'Recipient', + 'TO_MASS' => 'Recipients', + 'TO_ADD' => 'Add recipient', + 'TO_ADD_MASS' => 'Add recipients', + 'TO_ADD_GROUPS' => 'Add groups', 'TOO_MANY_RECIPIENTS' => 'You tried to send a private message to too many recipients.', 'TOO_MANY_REGISTERS' => 'You have exceeded the maximum number of registration attempts for this session. Please try again later.', 'UCP' => 'User Control Panel', 'UCP_ACTIVATE' => 'Activate account', 'UCP_ADMIN_ACTIVATE' => 'Please note that you will need to enter a valid email address before your account is activated. The administrator will review your account and if approved you will receive an email at the address you specified.', - 'UCP_AIM' => 'AOL Instant Messenger', 'UCP_ATTACHMENTS' => 'Attachments', 'UCP_AUTH_LINK' => 'External accounts', 'UCP_AUTH_LINK_ASK' => 'You currently have no account associated with this external service. Click the button below to link your board account to an account with this external service.', @@ -491,7 +500,6 @@ $lang = array_merge($lang, array( 'UCP_COPPA_BEFORE' => 'Before %s', 'UCP_COPPA_ON_AFTER' => 'On or after %s', 'UCP_EMAIL_ACTIVATE' => 'Please note that you will need to enter a valid email address before your account is activated. You will receive an email at the address you provide that contains an account activation link.', - 'UCP_ICQ' => 'ICQ number', 'UCP_JABBER' => 'Jabber address', 'UCP_LOGIN_LINK' => 'Set up an external account association', @@ -502,7 +510,6 @@ $lang = array_merge($lang, array( 'UCP_MAIN_FRONT' => 'Front page', 'UCP_MAIN_SUBSCRIBED' => 'Manage subscriptions', - 'UCP_MSNM' => 'Windows Live Messenger', 'UCP_NO_ATTACHMENTS' => 'You have posted no files.', 'UCP_NOTIFICATION_LIST' => 'Manage notifications', @@ -519,8 +526,6 @@ $lang = array_merge($lang, array( 'UCP_PM_COMPOSE' => 'Compose message', 'UCP_PM_DRAFTS' => 'Manage PM drafts', 'UCP_PM_OPTIONS' => 'Rules, folders & settings', - 'UCP_PM_POPUP' => 'Private messages', - 'UCP_PM_POPUP_TITLE' => 'Private message popup', 'UCP_PM_UNREAD' => 'Unread messages', 'UCP_PM_VIEW' => 'View messages', @@ -529,7 +534,7 @@ $lang = array_merge($lang, array( 'UCP_PROFILE_PROFILE_INFO' => 'Edit profile', 'UCP_PROFILE_REG_DETAILS' => 'Edit account settings', 'UCP_PROFILE_SIGNATURE' => 'Edit signature', - 'UCP_PROFILE_AUTOLOGIN_KEYS'=> 'Edit "Remember Me" login keys', + 'UCP_PROFILE_AUTOLOGIN_KEYS'=> 'Manage “Remember Me” login keys', 'UCP_USERGROUPS' => 'Usergroups', 'UCP_USERGROUPS_MEMBER' => 'Edit memberships', @@ -540,7 +545,6 @@ $lang = array_merge($lang, array( 'UCP_REMIND' => 'Send password', 'UCP_RESEND' => 'Send activation email', 'UCP_WELCOME' => 'Welcome to the User Control Panel. From here you can monitor, view and update your profile, preferences, subscribed forums and topics. You can also send messages to other users (if permitted). Please ensure you read any announcements before continuing.', - 'UCP_YIM' => 'Yahoo Messenger', 'UCP_ZEBRA' => 'Friends & Foes', 'UCP_ZEBRA_FOES' => 'Manage foes', 'UCP_ZEBRA_FRIENDS' => 'Manage friends', @@ -599,14 +603,14 @@ $lang = array_merge($lang, array( 'PLACE_INTO_FOLDER' => 'Place into folder', 'MARK_AS_READ' => 'Mark as read', 'MARK_AS_IMPORTANT' => 'Mark message', - 'DELETE_MESSAGE' => 'Delete message' + 'DELETE_MESSAGE' => 'Delete message', ), 'PM_CHECK' => array( 'SUBJECT' => 'Subject', 'SENDER' => 'Sender', 'MESSAGE' => 'Message', 'STATUS' => 'Message status', - 'TO' => 'Sent To' + 'TO' => 'Sent To', ), 'PM_RULE' => array( 'IS_LIKE' => 'is like', @@ -622,10 +626,9 @@ $lang = array_merge($lang, array( 'ANSWERED' => 'answered', 'FORWARDED' => 'forwarded', 'TO_GROUP' => 'to my default usergroup', - 'TO_ME' => 'to me' + 'TO_ME' => 'to me', ), - 'GROUPS_EXPLAIN' => 'Usergroups enable board admins to better administer users. By default you will be placed in a specific group, this is your default group. This group defines how you may appear to other users, for example your username colouration, avatar, rank, etc. Depending on whether the administrator allows it you may be allowed to change your default group. You may also be placed in or allowed to join other groups. Some groups may give you additional permissions to view content or increase your capabilities in other areas.', 'GROUP_LEADER' => 'Leaderships', 'GROUP_MEMBER' => 'Memberships', diff --git a/phpBB/language/en/viewtopic.php b/phpBB/language/en/viewtopic.php index 6f318c39f1..afbad5a0d6 100644 --- a/phpBB/language/en/viewtopic.php +++ b/phpBB/language/en/viewtopic.php @@ -58,7 +58,7 @@ $lang = array_merge($lang, array( 1 => 'Last edited by %2$s on %3$s, edited %1$d time in total.', 2 => 'Last edited by %2$s on %3$s, edited %1$d times in total.', ), - 'EMAIL_TOPIC' => 'Email friend', + 'EMAIL_TOPIC' => 'Email topic', 'ERROR_NO_ATTACHMENT' => 'The selected attachment does not exist anymore.', 'FILE_NOT_FOUND_404' => 'The file <strong>%s</strong> does not exist.', @@ -104,6 +104,7 @@ $lang = array_merge($lang, array( 'SUBMIT_VOTE' => 'Submit vote', + 'TOPIC_TOOLS' => 'Topic tools', 'TOTAL_VOTES' => 'Total votes', 'UNLOCK_TOPIC' => 'Unlock topic', @@ -117,7 +118,6 @@ $lang = array_merge($lang, array( 2 => '%d posts', ), 'VIEW_UNREAD_POST' => 'First unread post', - 'VISIT_WEBSITE' => 'WWW', 'VOTE_SUBMITTED' => 'Your vote has been cast.', 'VOTE_CONVERTED' => 'Changing votes is not supported for converted polls.', diff --git a/phpBB/mcp.php b/phpBB/mcp.php index e2915cad78..3555eb3b48 100644 --- a/phpBB/mcp.php +++ b/phpBB/mcp.php @@ -183,7 +183,27 @@ if ($quickmod) break; default: - trigger_error($user->lang('QUICKMOD_ACTION_NOT_ALLOWED', $action), E_USER_ERROR); + // If needed, the flag can be set to true within event listener + // to indicate that the action was handled properly + // and to pass by the trigger_error() call below + $is_valid_action = false; + + /** + * This event allows you to add custom quickmod options + * + * @event core.modify_quickmod_options + * @var object module Instance of module system class + * @var string action Quickmod option + * @var bool is_valid_action Flag indicating if the action was handled properly + * @since 3.1.0-a4 + */ + $vars = array('module', 'action', 'is_valid_action'); + extract($phpbb_dispatcher->trigger_event('core.modify_quickmod_options', compact($vars))); + + if (!$is_valid_action) + { + trigger_error($user->lang('QUICKMOD_ACTION_NOT_ALLOWED', $action), E_USER_ERROR); + } break; } } @@ -233,6 +253,32 @@ if (!$user_id && $username == '') $module->set_display('warn', 'warn_user', false); } +/** +* This event allows you to set display option for custom MCP modules +* +* @event core.modify_mcp_modules_display_option +* @var p_master module Module system class +* @var string mode MCP mode +* @var int user_id User id +* @var int forum_id Forum id +* @var int topic_id Topic id +* @var int post_id Post id +* @var string username User name +* @var int id Parent module id +* @since 3.1.0-b2 +*/ +$vars = array( + 'module', + 'mode', + 'user_id', + 'forum_id', + 'topic_id', + 'post_id', + 'username', + 'id', +); +extract($phpbb_dispatcher->trigger_event('core.modify_mcp_modules_display_option', compact($vars))); + // Load and execute the relevant module $module->load_active(); @@ -248,7 +294,7 @@ $template->assign_vars(array( )); // Generate the page, do not display/query online list -$module->display($module->get_page_title(), false); +$module->display($module->get_page_title()); /** * Functions used to generate additional URL paramters @@ -641,7 +687,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, case 'unapproved_posts': case 'deleted_posts': - $visibility_const = ($mode == 'unapproved_posts') ? ITEM_UNAPPROVED : ITEM_DELETED; + $visibility_const = ($mode == 'unapproved_posts') ? array(ITEM_UNAPPROVED, ITEM_REAPPROVE) : ITEM_DELETED; $type = 'posts'; $default_key = 't'; $default_dir = 'd'; @@ -650,7 +696,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, $sql = 'SELECT COUNT(p.post_id) AS total FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t $where_sql " . $db->sql_in_set('p.forum_id', ($forum_id) ? array($forum_id) : array_intersect(get_forum_list('f_read'), get_forum_list('m_approve'))) . ' - AND p.post_visibility = ' . $visibility_const . ' + AND ' . $db->sql_in_set('p.post_visibility', $visibility_const) .' AND t.topic_id = p.topic_id AND t.topic_visibility <> p.post_visibility'; @@ -662,7 +708,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, case 'unapproved_topics': case 'deleted_topics': - $visibility_const = ($mode == 'unapproved_topics') ? ITEM_UNAPPROVED : ITEM_DELETED; + $visibility_const = ($mode == 'unapproved_topics') ? array(ITEM_UNAPPROVED, ITEM_REAPPROVE) : ITEM_DELETED; $type = 'topics'; $default_key = 't'; $default_dir = 'd'; @@ -670,7 +716,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql, $sql = 'SELECT COUNT(topic_id) AS total FROM ' . TOPICS_TABLE . " $where_sql " . $db->sql_in_set('forum_id', ($forum_id) ? array($forum_id) : array_intersect(get_forum_list('f_read'), get_forum_list('m_approve'))) . ' - AND topic_visibility = ' . $visibility_const; + AND ' . $db->sql_in_set('topic_visibility', $visibility_const); if ($min_time) { diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index ead7179732..63c8dc0c08 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -21,6 +21,9 @@ $user->session_begin(); $auth->acl($user->data); $user->setup(array('memberlist', 'groups')); +// Setting a variable to let the style designer know where he is... +$template->assign_var('S_IN_MEMBERLIST', true); + // Grab data $mode = request_var('mode', ''); $action = request_var('action', ''); @@ -29,8 +32,15 @@ $username = request_var('un', '', true); $group_id = request_var('g', 0); $topic_id = request_var('t', 0); +// Redirect when old mode is used +if ($mode == 'leaders') +{ + send_status_line(301, 'Moved Permanently'); + redirect(append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=team')); +} + // Check our mode... -if (!in_array($mode, array('', 'group', 'viewprofile', 'email', 'contact', 'searchuser', 'leaders'))) +if (!in_array($mode, array('', 'group', 'viewprofile', 'email', 'contact', 'searchuser', 'team'))) { trigger_error('NO_MODE'); } @@ -64,12 +74,12 @@ $sort_dir = request_var('sd', 'a'); // What do you want to do today? ... oops, I think that line is taken ... switch ($mode) { - case 'leaders': + case 'team': // Display a listing of board admins, moderators include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $page_title = $user->lang['THE_TEAM']; - $template_html = 'memberlist_leaders.html'; + $template_html = 'memberlist_team.html'; $sql = 'SELECT * FROM ' . TEAMPAGE_TABLE . ' @@ -305,20 +315,6 @@ switch ($mode) $presence_img = ''; switch ($action) { - case 'aim': - $lang = 'AIM'; - $sql_field = 'user_aim'; - $s_select = 'S_SEND_AIM'; - $s_action = ''; - break; - - case 'msnm': - $lang = 'MSNM'; - $sql_field = 'user_msnm'; - $s_select = 'S_SEND_MSNM'; - $s_action = ''; - break; - case 'jabber': $lang = 'JABBER'; $sql_field = 'user_jabber'; @@ -402,9 +398,6 @@ switch ($mode) 'IM_CONTACT' => $row[$sql_field], 'A_IM_CONTACT' => addslashes($row[$sql_field]), - 'U_AIM_CONTACT' => ($action == 'aim') ? 'aim:addbuddy?screenname=' . urlencode($row[$sql_field]) : '', - 'U_AIM_MESSAGE' => ($action == 'aim') ? 'aim:goim?screenname=' . urlencode($row[$sql_field]) . '&message=' . urlencode($config['sitename']) : '', - 'USERNAME' => $row['username'], 'CONTACT_NAME' => $row[$sql_field], 'SITENAME' => $config['sitename'], @@ -595,7 +588,7 @@ switch ($mode) * Modify user data before we display the profile * * @event core.memberlist_view_profile - * @var array member Title of the index page + * @var array member Array with user's data * @var bool user_notes_enabled Is the mcp user notes module * enabled? * @var bool warn_user_enabled Is the mcp warnings module @@ -606,9 +599,21 @@ switch ($mode) * enabled? * @var bool foes_enabled Is the ucp foes module * enabled? - * @since 3.1-A1 + * @var bool friend Is the user friend? + * @var bool foe Is the user foe? + * @since 3.1.0-a1 + * @changed 3.1.0-b2 Added friend and foe status */ - $vars = array('member', 'user_notes_enabled', 'warn_user_enabled', 'zebra_enabled', 'friends_enabled', 'foes_enabled'); + $vars = array( + 'member', + 'user_notes_enabled', + 'warn_user_enabled', + 'zebra_enabled', + 'friends_enabled', + 'foes_enabled', + 'friend', + 'foe', + ); extract($phpbb_dispatcher->trigger_event('core.memberlist_view_profile', compact($vars))); $template->assign_vars(show_profile($member, $user_notes_enabled, $warn_user_enabled)); @@ -617,10 +622,9 @@ switch ($mode) $profile_fields = array(); if ($config['load_cpf_viewprofile']) { - include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - $cp = new custom_profile(); - $profile_fields = $cp->generate_profile_fields_template('grab', $user_id); - $profile_fields = (isset($profile_fields[$user_id])) ? $cp->generate_profile_fields_template('show', false, $profile_fields[$user_id]) : array(); + $cp = $phpbb_container->get('profilefields.manager'); + $profile_fields = $cp->grab_profile_fields_data($user_id); + $profile_fields = (isset($profile_fields[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields[$user_id]) : array(); } // If the user has m_approve permission or a_user permission, then list then display unapproved posts @@ -629,7 +633,7 @@ switch ($mode) $sql = 'SELECT COUNT(post_id) as posts_in_queue FROM ' . POSTS_TABLE . ' WHERE poster_id = ' . $user_id . ' - AND post_visibility = ' . ITEM_UNAPPROVED; + AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)); $result = $db->sql_query($sql); $member['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue'); $db->sql_freeresult($result); @@ -645,19 +649,12 @@ switch ($mode) 'POSTS_DAY' => $user->lang('POST_DAY', $posts_per_day), 'POSTS_PCT' => $user->lang('POST_PCT', $percentage), - 'OCCUPATION' => (!empty($member['user_occ'])) ? censor_text($member['user_occ']) : '', - 'INTERESTS' => (!empty($member['user_interests'])) ? censor_text($member['user_interests']) : '', 'SIGNATURE' => $member['user_sig'], 'POSTS_IN_QUEUE'=> $member['posts_in_queue'], 'AVATAR_IMG' => $poster_avatar, 'PM_IMG' => $user->img('icon_contact_pm', $user->lang['SEND_PRIVATE_MESSAGE']), 'EMAIL_IMG' => $user->img('icon_contact_email', $user->lang['EMAIL']), - 'WWW_IMG' => $user->img('icon_contact_www', $user->lang['WWW']), - 'ICQ_IMG' => $user->img('icon_contact_icq', $user->lang['ICQ']), - 'AIM_IMG' => $user->img('icon_contact_aim', $user->lang['AIM']), - 'MSN_IMG' => $user->img('icon_contact_msnm', $user->lang['MSNM']), - 'YIM_IMG' => $user->img('icon_contact_yahoo', $user->lang['YIM']), 'JABBER_IMG' => $user->img('icon_contact_jabber', $user->lang['JABBER']), 'SEARCH_IMG' => $user->img('icon_user_search', $user->lang['SEARCH']), @@ -998,10 +995,11 @@ switch ($mode) // The basic memberlist $page_title = $user->lang['MEMBERLIST']; $template_html = 'memberlist_body.html'; + $pagination = $phpbb_container->get('pagination'); // Sorting - $sort_key_text = array('a' => $user->lang['SORT_USERNAME'], 'b' => $user->lang['SORT_LOCATION'], 'c' => $user->lang['SORT_JOINED'], 'd' => $user->lang['SORT_POST_COUNT'], 'f' => $user->lang['WEBSITE'], 'g' => $user->lang['ICQ'], 'h' => $user->lang['AIM'], 'i' => $user->lang['MSNM'], 'j' => $user->lang['YIM'], 'k' => $user->lang['JABBER']); - $sort_key_sql = array('a' => 'u.username_clean', 'b' => 'u.user_from', 'c' => 'u.user_regdate', 'd' => 'u.user_posts', 'f' => 'u.user_website', 'g' => 'u.user_icq', 'h' => 'u.user_aim', 'i' => 'u.user_msnm', 'j' => 'u.user_yim', 'k' => 'u.user_jabber'); + $sort_key_text = array('a' => $user->lang['SORT_USERNAME'], 'c' => $user->lang['SORT_JOINED'], 'd' => $user->lang['SORT_POST_COUNT'], 'k' => $user->lang['JABBER']); + $sort_key_sql = array('a' => 'u.username_clean', 'c' => 'u.user_regdate', 'd' => 'u.user_posts', 'k' => 'u.user_jabber'); if ($auth->acl_get('a_user')) { @@ -1044,7 +1042,7 @@ switch ($mode) $select_single = request_var('select_single', false); // Search URL parameters, if any of these are in the URL we do a search - $search_params = array('username', 'email', 'icq', 'aim', 'yahoo', 'msn', 'jabber', 'search_group_id', 'joined_select', 'active_select', 'count_select', 'joined', 'active', 'count', 'ip'); + $search_params = array('username', 'email', 'jabber', 'search_group_id', 'joined_select', 'active_select', 'count_select', 'joined', 'active', 'count', 'ip'); // We validate form and field here, only id/class allowed $form = (!preg_match('/^[a-z0-9_-]+$/i', $form)) ? '' : $form; @@ -1053,10 +1051,6 @@ switch ($mode) { $username = request_var('username', '', true); $email = strtolower(request_var('email', '')); - $icq = request_var('icq', ''); - $aim = request_var('aim', ''); - $yahoo = request_var('yahoo', ''); - $msn = request_var('msn', ''); $jabber = request_var('jabber', ''); $search_group_id = request_var('search_group_id', 0); @@ -1097,10 +1091,6 @@ switch ($mode) $sql_where .= ($username) ? ' AND u.username_clean ' . $db->sql_like_expression(str_replace('*', $db->any_char, utf8_clean_string($username))) : ''; $sql_where .= ($auth->acl_get('a_user') && $email) ? ' AND u.user_email ' . $db->sql_like_expression(str_replace('*', $db->any_char, $email)) . ' ' : ''; - $sql_where .= ($icq) ? ' AND u.user_icq ' . $db->sql_like_expression(str_replace('*', $db->any_char, $icq)) . ' ' : ''; - $sql_where .= ($aim) ? ' AND u.user_aim ' . $db->sql_like_expression(str_replace('*', $db->any_char, $aim)) . ' ' : ''; - $sql_where .= ($yahoo) ? ' AND u.user_yim ' . $db->sql_like_expression(str_replace('*', $db->any_char, $yahoo)) . ' ' : ''; - $sql_where .= ($msn) ? ' AND u.user_msnm ' . $db->sql_like_expression(str_replace('*', $db->any_char, $msn)) . ' ' : ''; $sql_where .= ($jabber) ? ' AND u.user_jabber ' . $db->sql_like_expression(str_replace('*', $db->any_char, $jabber)) . ' ' : ''; $sql_where .= (is_numeric($count) && isset($find_key_match[$count_select])) ? ' AND u.user_posts ' . $find_key_match[$count_select] . ' ' . (int) $count . ' ' : ''; @@ -1329,10 +1319,6 @@ switch ($mode) 'select_single' => array('select_single', $select_single), 'username' => array('username', '', true), 'email' => array('email', ''), - 'icq' => array('icq', ''), - 'aim' => array('aim', ''), - 'yahoo' => array('yahoo', ''), - 'msn' => array('msn', ''), 'jabber' => array('jabber', ''), 'search_group_id' => array('search_group_id', 0), 'joined_select' => array('joined_select', 'lt'), @@ -1461,10 +1447,6 @@ switch ($mode) $template->assign_vars(array( 'USERNAME' => $username, 'EMAIL' => $email, - 'ICQ' => $icq, - 'AIM' => $aim, - 'YAHOO' => $yahoo, - 'MSNM' => $msn, 'JABBER' => $jabber, 'JOINED' => implode('-', $joined), 'ACTIVE' => implode('-', $active), @@ -1487,6 +1469,8 @@ switch ($mode) ); } + $start = $pagination->validate_start($start, $config['topics_per_page'], $config['num_users']); + // Get us some users :D $sql = "SELECT u.user_id FROM " . USERS_TABLE . " u @@ -1502,6 +1486,19 @@ switch ($mode) $user_list[] = (int) $row['user_id']; } $db->sql_freeresult($result); + + // Load custom profile fields + if ($config['load_cpf_memberlist']) + { + $cp = $phpbb_container->get('profilefields.manager'); + + $cp_row = $cp->generate_profile_fields_template_headlines('field_show_on_ml'); + foreach ($cp_row as $profile_field) + { + $template->assign_block_vars('custom_fields', $profile_field); + } + } + $leaders_set = false; // So, did we get any users? if (sizeof($user_list)) @@ -1552,11 +1549,20 @@ switch ($mode) // Load custom profile fields if ($config['load_cpf_memberlist']) { - include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - $cp = new custom_profile(); - // Grab all profile fields from users in id cache for later use - similar to the poster cache - $profile_fields_cache = $cp->generate_profile_fields_template('grab', $user_list); + $profile_fields_cache = $cp->grab_profile_fields_data($user_list); + + // Filter the fields we don't want to show + foreach ($profile_fields_cache as $user_id => $user_profile_fields) + { + foreach ($user_profile_fields as $field_ident => $profile_field) + { + if (!$profile_field['data']['field_show_on_ml']) + { + unset($profile_fields_cache[$user_id][$field_ident]); + } + } + } } // If we sort by last active date we need to adjust the id cache due to user_lastvisit not being the last active date... @@ -1576,7 +1582,7 @@ switch ($mode) $cp_row = array(); if ($config['load_cpf_memberlist']) { - $cp_row = (isset($profile_fields_cache[$user_id])) ? $cp->generate_profile_fields_template('show', false, $profile_fields_cache[$user_id]) : array(); + $cp_row = (isset($profile_fields_cache[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields_cache[$user_id], false) : array(); } $memberrow = array_merge(show_profile($row), array( @@ -1585,8 +1591,8 @@ switch ($mode) 'S_CUSTOM_PROFILE' => (isset($cp_row['row']) && sizeof($cp_row['row'])) ? true : false, 'S_GROUP_LEADER' => $is_leader, - 'U_VIEW_PROFILE' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u=' . $user_id)) - ); + 'U_VIEW_PROFILE' => get_username_string('profile', $user_id, $row['username']), + )); if (isset($cp_row['row']) && sizeof($cp_row['row'])) { @@ -1607,37 +1613,24 @@ switch ($mode) } } - phpbb_generate_template_pagination($template, $pagination_url, 'pagination', 'start', $total_users, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($pagination_url, 'pagination', 'start', $total_users, $config['topics_per_page'], $start); // Generate page $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $pagination_url, $total_users, $config['topics_per_page'], $start), 'TOTAL_USERS' => $user->lang('LIST_USERS', (int) $total_users), 'PROFILE_IMG' => $user->img('icon_user_profile', $user->lang['PROFILE']), 'PM_IMG' => $user->img('icon_contact_pm', $user->lang['SEND_PRIVATE_MESSAGE']), 'EMAIL_IMG' => $user->img('icon_contact_email', $user->lang['EMAIL']), - 'WWW_IMG' => $user->img('icon_contact_www', $user->lang['WWW']), - 'ICQ_IMG' => $user->img('icon_contact_icq', $user->lang['ICQ']), - 'AIM_IMG' => $user->img('icon_contact_aim', $user->lang['AIM']), - 'MSN_IMG' => $user->img('icon_contact_msnm', $user->lang['MSNM']), - 'YIM_IMG' => $user->img('icon_contact_yahoo', $user->lang['YIM']), 'JABBER_IMG' => $user->img('icon_contact_jabber', $user->lang['JABBER']), 'SEARCH_IMG' => $user->img('icon_user_search', $user->lang['SEARCH']), 'U_FIND_MEMBER' => ($config['load_search'] || $auth->acl_get('a_')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser' . (($start) ? "&start=$start" : '') . (!empty($params) ? '&' . implode('&', $params) : '')) : '', 'U_HIDE_FIND_MEMBER' => ($mode == 'searchuser' || ($mode == '' && $submit)) ? $u_hide_find_member : '', 'U_SORT_USERNAME' => $sort_url . '&sk=a&sd=' . (($sort_key == 'a' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_FROM' => $sort_url . '&sk=b&sd=' . (($sort_key == 'b' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_JOINED' => $sort_url . '&sk=c&sd=' . (($sort_key == 'c' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_POSTS' => $sort_url . '&sk=d&sd=' . (($sort_key == 'd' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_EMAIL' => $sort_url . '&sk=e&sd=' . (($sort_key == 'e' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_WEBSITE' => $sort_url . '&sk=f&sd=' . (($sort_key == 'f' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_LOCATION' => $sort_url . '&sk=b&sd=' . (($sort_key == 'b' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_ICQ' => $sort_url . '&sk=g&sd=' . (($sort_key == 'g' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_AIM' => $sort_url . '&sk=h&sd=' . (($sort_key == 'h' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_MSN' => $sort_url . '&sk=i&sd=' . (($sort_key == 'i' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_YIM' => $sort_url . '&sk=j&sd=' . (($sort_key == 'j' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_ACTIVE' => ($auth->acl_get('u_viewonline')) ? $sort_url . '&sk=l&sd=' . (($sort_key == 'l' && $sort_dir == 'a') ? 'd' : 'a') : '', 'U_SORT_RANK' => $sort_url . '&sk=m&sd=' . (($sort_key == 'm' && $sort_dir == 'a') ? 'd' : 'a'), 'U_LIST_CHAR' => $sort_url . '&sk=a&sd=' . (($sort_key == 'l' && $sort_dir == 'a') ? 'd' : 'a'), @@ -1652,7 +1645,7 @@ switch ($mode) } // Output the page -page_header($page_title, false); +page_header($page_title); $template->set_filenames(array( 'body' => $template_html) @@ -1695,11 +1688,11 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f if ($data['user_allow_viewonline'] || $auth->acl_get('u_viewonline')) { - $last_visit = (!empty($data['session_time'])) ? $data['session_time'] : $data['user_lastvisit']; + $last_active = (!empty($data['session_time'])) ? $data['session_time'] : $data['user_lastvisit']; } else { - $last_visit = ''; + $last_active = ''; } $age = ''; @@ -1732,7 +1725,7 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f 'AGE' => $age, 'RANK_TITLE' => $rank_title, 'JOINED' => $user->format_date($data['user_regdate']), - 'VISITED' => (empty($last_visit)) ? ' - ' : $user->format_date($last_visit), + 'LAST_ACTIVE' => (empty($last_active)) ? ' - ' : $user->format_date($last_active), 'POSTS' => ($data['user_posts']) ? $data['user_posts'] : 0, 'WARNINGS' => isset($data['user_warnings']) ? $data['user_warnings'] : 0, @@ -1748,7 +1741,6 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f 'S_ONLINE' => ($config['load_onlinetrack'] && $online) ? true : false, 'RANK_IMG' => $rank_img, 'RANK_IMG_SRC' => $rank_img_src, - 'ICQ_STATUS_IMG' => (!empty($data['user_icq'])) ? '<img src="http://web.icq.com/whitepages/online?icq=' . $data['user_icq'] . '&img=5" width="18" height="18" />' : '', 'S_JABBER_ENABLED' => ($config['jab_enable']) ? true : false, 'S_WARNINGS' => ($auth->acl_getf_global('m_') || $auth->acl_get('m_warn')) ? true : false, @@ -1758,19 +1750,8 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f 'U_WARN' => ($warn_user_enabled && $auth->acl_get('m_warn')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&mode=warn_user&u=' . $user_id, true, $user->session_id) : '', 'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($data['user_allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose&u=' . $user_id) : '', 'U_EMAIL' => $email, - 'U_WWW' => (!empty($data['user_website'])) ? $data['user_website'] : '', - 'U_SHORT_WWW' => (!empty($data['user_website'])) ? ((strlen($data['user_website']) > 55) ? substr($data['user_website'], 0, 39) . ' ... ' . substr($data['user_website'], -10) : $data['user_website']) : '', - 'U_ICQ' => ($data['user_icq']) ? 'http://www.icq.com/people/' . urlencode($data['user_icq']) . '/' : '', - 'U_AIM' => ($data['user_aim'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=aim&u=' . $user_id) : '', - 'U_YIM' => ($data['user_yim']) ? 'http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($data['user_yim']) . '&.src=pg' : '', - 'U_MSN' => ($data['user_msnm'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=msnm&u=' . $user_id) : '', 'U_JABBER' => ($data['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&action=jabber&u=' . $user_id) : '', - 'LOCATION' => ($data['user_from']) ? $data['user_from'] : '', - 'USER_ICQ' => $data['user_icq'], - 'USER_AIM' => $data['user_aim'], - 'USER_YIM' => $data['user_yim'], - 'USER_MSN' => $data['user_msnm'], 'USER_JABBER' => $data['user_jabber'], 'USER_JABBER_IMG' => ($data['user_jabber']) ? $user->img('icon_contact_jabber', $data['user_jabber']) : '', @@ -1783,7 +1764,7 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f * @event core.memberlist_prepare_profile_data * @var array data Array with user's data * @var array template_data Template array with user's data - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('data', 'template_data'); extract($phpbb_dispatcher->trigger_event('core.memberlist_prepare_profile_data', compact($vars))); diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php index b5cc675838..81676e75fc 100644 --- a/phpBB/phpbb/auth/auth.php +++ b/phpBB/phpbb/auth/auth.php @@ -10,14 +10,6 @@ namespace phpbb\auth; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Permission/Auth class * @package phpBB3 */ diff --git a/phpBB/phpbb/auth/provider/apache.php b/phpBB/phpbb/auth/provider/apache.php index 5cbb63c4fc..6374f29d67 100644 --- a/phpBB/phpbb/auth/provider/apache.php +++ b/phpBB/phpbb/auth/provider/apache.php @@ -10,14 +10,6 @@ namespace phpbb\auth\provider; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Apache authentication provider for phpBB3 * * @package auth @@ -25,19 +17,28 @@ if (!defined('IN_PHPBB')) class apache extends \phpbb\auth\provider\base { /** + * phpBB passwords manager + * + * @var \phpbb\passwords\manager + */ + protected $passwords_manager; + + /** * Apache Authentication Constructor * - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\config\config $config + * @param \phpbb\passwords\manager $passwords_manager * @param \phpbb\request\request $request * @param \phpbb\user $user * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; + $this->passwords_manager = $passwords_manager; $this->request = $request; $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; @@ -228,7 +229,7 @@ class apache extends \phpbb\auth\provider\base // generate user account data return array( 'username' => $username, - 'user_password' => phpbb_hash($password), + 'user_password' => $this->passwords_manager->hash($password), 'user_email' => '', 'group_id' => (int) $row['group_id'], 'user_type' => USER_NORMAL, diff --git a/phpBB/phpbb/auth/provider/base.php b/phpBB/phpbb/auth/provider/base.php index 2222d8c1b6..78a3289356 100644 --- a/phpBB/phpbb/auth/provider/base.php +++ b/phpBB/phpbb/auth/provider/base.php @@ -10,14 +10,6 @@ namespace phpbb\auth\provider; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Base authentication provider class that all other providers should implement * * @package auth diff --git a/phpBB/phpbb/auth/provider/db.php b/phpBB/phpbb/auth/provider/db.php index 4654e49fb5..5adbf84d9f 100644 --- a/phpBB/phpbb/auth/provider/db.php +++ b/phpBB/phpbb/auth/provider/db.php @@ -10,14 +10,6 @@ namespace phpbb\auth\provider; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Database authentication provider for phpBB3 * * This is for authentication via the integrated user table @@ -26,21 +18,29 @@ if (!defined('IN_PHPBB')) */ class db extends \phpbb\auth\provider\base { + /** + * phpBB passwords manager + * + * @var \phpbb\passwords\manager + */ + protected $passwords_manager; /** * Database Authentication Constructor * - * @param \phpbb\db\driver\driver $db - * @param \phpbb\config\config $config - * @param \phpbb\request\request $request - * @param \phpbb\user $user - * @param string $phpbb_root_path - * @param string $php_ext + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\config\config $config + * @param \phpbb\passwords\manager $passwords_manager + * @param \phpbb\request\request $request + * @param \phpbb\user $user + * @param string $phpbb_root_path + * @param string $php_ext */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; + $this->passwords_manager = $passwords_manager; $this->request = $request; $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; @@ -199,10 +199,10 @@ class db extends \phpbb\auth\provider\base // cp1252 is phpBB2's default encoding, characters outside ASCII range might work when converted into that encoding // plain md5 support left in for conversions from other systems. - if ((strlen($row['user_password']) == 34 && (phpbb_check_hash(md5($password_old_format), $row['user_password']) || phpbb_check_hash(md5(utf8_to_cp1252($password_old_format)), $row['user_password']))) + if ((strlen($row['user_password']) == 34 && ($this->passwords_manager->check(md5($password_old_format), $row['user_password']) || $this->passwords_manager->check(md5(utf8_to_cp1252($password_old_format)), $row['user_password']))) || (strlen($row['user_password']) == 32 && (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password']))) { - $hash = phpbb_hash($password_new_format); + $hash = $this->passwords_manager->hash($password_new_format); // Update the password in the users table to the new format and remove user_pass_convert flag $sql = 'UPDATE ' . USERS_TABLE . ' @@ -234,12 +234,12 @@ class db extends \phpbb\auth\provider\base } // Check password ... - if (!$row['user_pass_convert'] && phpbb_check_hash($password, $row['user_password'])) + if (!$row['user_pass_convert'] && $this->passwords_manager->check($password, $row['user_password'])) { // Check for old password hash... - if (strlen($row['user_password']) == 32) + if ($this->passwords_manager->convert_flag || strlen($row['user_password']) == 32) { - $hash = phpbb_hash($password); + $hash = $this->passwords_manager->hash($password); // Update the password in the users table to the new format $sql = 'UPDATE ' . USERS_TABLE . " diff --git a/phpBB/phpbb/auth/provider/ldap.php b/phpBB/phpbb/auth/provider/ldap.php index 9d29789567..3d3f1990eb 100644 --- a/phpBB/phpbb/auth/provider/ldap.php +++ b/phpBB/phpbb/auth/provider/ldap.php @@ -10,14 +10,6 @@ namespace phpbb\auth\provider; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Database authentication provider for phpBB3 * * This is for authentication via the integrated user table @@ -27,16 +19,25 @@ if (!defined('IN_PHPBB')) class ldap extends \phpbb\auth\provider\base { /** + * phpBB passwords manager + * + * @var \phpbb\passwords\manager + */ + protected $passwords_manager; + + /** * LDAP Authentication Constructor * - * @param \phpbb\db\driver\driver $db - * @param \phpbb\config\config $config - * @param \phpbb\user $user + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\config\config $config + * @param \phpbb\passwords\manager $passwords_manager + * @param \phpbb\user $user */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\user $user) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\user $user) { $this->db = $db; $this->config = $config; + $this->passwords_manager = $passwords_manager; $this->user = $user; } @@ -97,7 +98,6 @@ class ldap extends \phpbb\auth\provider\base @ldap_close($ldap); - if (!is_array($result) || sizeof($result) < 2) { return sprintf($this->user->lang['LDAP_NO_IDENTITY'], $this->user->data['username']); @@ -244,7 +244,7 @@ class ldap extends \phpbb\auth\provider\base // generate user account data $ldap_user_row = array( 'username' => $username, - 'user_password' => phpbb_hash($password), + 'user_password' => $this->passwords_manager->hash($password), 'user_email' => (!empty($this->config['ldap_email'])) ? utf8_htmlspecialchars($ldap_result[0][htmlspecialchars_decode($this->config['ldap_email'])][0]) : '', 'group_id' => (int) $row['group_id'], 'user_type' => USER_NORMAL, diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index de81ac0d04..10d5cda5e3 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -9,14 +9,6 @@ namespace phpbb\auth\provider\oauth; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use OAuth\Common\Consumer\Credentials; use OAuth\Common\Http\Uri\Uri; @@ -30,7 +22,7 @@ class oauth extends \phpbb\auth\provider\base /** * Database driver * - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -42,6 +34,13 @@ class oauth extends \phpbb\auth\provider\base protected $config; /** + * phpBB passwords manager + * + * @var \phpbb\passwords\manager + */ + protected $passwords_manager; + + /** * phpBB request object * * @var \phpbb\request\request_interface @@ -107,8 +106,9 @@ class oauth extends \phpbb\auth\provider\base /** * OAuth Authentication Constructor * - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\config\config $config + * @param \phpbb\passwords\manager $passwords_manager * @param \phpbb\request\request_interface $request * @param \phpbb\user $user * @param string $auth_provider_oauth_token_storage_table @@ -118,10 +118,11 @@ class oauth extends \phpbb\auth\provider\base * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; + $this->passwords_manager = $passwords_manager; $this->request = $request; $this->user = $user; $this->auth_provider_oauth_token_storage_table = $auth_provider_oauth_token_storage_table; @@ -158,7 +159,7 @@ class oauth extends \phpbb\auth\provider\base // Temporary workaround for only having one authentication provider available if (!$this->request->is_set('oauth_service')) { - $provider = new \phpbb\auth\provider\db($this->db, $this->config, $this->request, $this->user, $this->phpbb_root_path, $this->php_ext); + $provider = new \phpbb\auth\provider\db($this->db, $this->config, $this->passwords_manager, $this->request, $this->user, $this->phpbb_root_path, $this->php_ext); return $provider->login($username, $password); } @@ -179,7 +180,7 @@ class oauth extends \phpbb\auth\provider\base $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); $query = 'mode=login&login=external&oauth_service=' . $service_name_original; - $service = $this->get_service($service_name_original, $storage, $service_credentials, $this->service_providers[$service_name]->get_auth_scope(), $query); + $service = $this->get_service($service_name_original, $storage, $service_credentials, $query, $this->service_providers[$service_name]->get_auth_scope()); if ($this->request->is_set('code', \phpbb\request\request_interface::GET)) { @@ -273,13 +274,13 @@ class oauth extends \phpbb\auth\provider\base * @param string $service_name The name of the service * @param \phpbb\auth\provider\oauth\token_storage $storage * @param array $service_credentials {@see \phpbb\auth\provider\oauth\oauth::get_service_credentials} - * @param array $scope The scope of the request against - * the api. * @param string $query The query string of the * current_uri used in redirection + * @param array $scope The scope of the request against + * the api. * @return \OAuth\Common\Service\ServiceInterface */ - protected function get_service($service_name, \phpbb\auth\provider\oauth\token_storage $storage, array $service_credentials, array $scopes = array(), $query) + protected function get_service($service_name, \phpbb\auth\provider\oauth\token_storage $storage, array $service_credentials, $query, array $scopes = array()) { $current_uri = $this->get_current_uri($service_name, $query); @@ -458,7 +459,7 @@ class oauth extends \phpbb\auth\provider\base // Prepare for an authentication request $service_credentials = $this->service_providers[$service_name]->get_service_credentials(); $scopes = $this->service_providers[$service_name]->get_auth_scope(); - $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $scopes, $query); + $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $query, $scopes); $this->service_providers[$service_name]->set_external_service_provider($service); // The user has already authenticated successfully, request to authenticate again @@ -491,7 +492,7 @@ class oauth extends \phpbb\auth\provider\base $query = 'i=ucp_auth_link&mode=auth_link&link=1&oauth_service=' . strtolower($link_data['oauth_service']); $service_credentials = $this->service_providers[$service_name]->get_service_credentials(); $scopes = $this->service_providers[$service_name]->get_auth_scope(); - $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $scopes, $query); + $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $query, $scopes); if ($this->request->is_set('code', \phpbb\request\request_interface::GET)) { diff --git a/phpBB/phpbb/auth/provider/oauth/service/base.php b/phpBB/phpbb/auth/provider/oauth/service/base.php index 61deb48695..7a144d2f51 100644 --- a/phpBB/phpbb/auth/provider/oauth/service/base.php +++ b/phpBB/phpbb/auth/provider/oauth/service/base.php @@ -10,14 +10,6 @@ namespace phpbb\auth\provider\oauth\service; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Base OAuth abstract class that all OAuth services should implement * * @package auth diff --git a/phpBB/phpbb/auth/provider/oauth/service/bitly.php b/phpBB/phpbb/auth/provider/oauth/service/bitly.php index 47cf7ee380..b4050033a6 100644 --- a/phpBB/phpbb/auth/provider/oauth/service/bitly.php +++ b/phpBB/phpbb/auth/provider/oauth/service/bitly.php @@ -10,14 +10,6 @@ namespace phpbb\auth\provider\oauth\service; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Bitly OAuth service * * @package auth diff --git a/phpBB/phpbb/auth/provider/oauth/service/exception.php b/phpBB/phpbb/auth/provider/oauth/service/exception.php index 23d3387951..3bc93be01e 100644 --- a/phpBB/phpbb/auth/provider/oauth/service/exception.php +++ b/phpBB/phpbb/auth/provider/oauth/service/exception.php @@ -7,19 +7,13 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\auth\provider\oauth\service; /** * OAuth service exception class * * @package auth */ -class phpbb_auth_provider_oauth_service_exception extends RuntimeException +class exception extends \RuntimeException { } diff --git a/phpBB/phpbb/auth/provider/oauth/service/facebook.php b/phpBB/phpbb/auth/provider/oauth/service/facebook.php index 4a4eeba6d5..2698be8b18 100644 --- a/phpBB/phpbb/auth/provider/oauth/service/facebook.php +++ b/phpBB/phpbb/auth/provider/oauth/service/facebook.php @@ -10,14 +10,6 @@ namespace phpbb\auth\provider\oauth\service; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Facebook OAuth service * * @package auth diff --git a/phpBB/phpbb/auth/provider/oauth/service/google.php b/phpBB/phpbb/auth/provider/oauth/service/google.php index 2449bbf523..08cb025c2d 100644 --- a/phpBB/phpbb/auth/provider/oauth/service/google.php +++ b/phpBB/phpbb/auth/provider/oauth/service/google.php @@ -10,14 +10,6 @@ namespace phpbb\auth\provider\oauth\service; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Google OAuth service * * @package auth diff --git a/phpBB/phpbb/auth/provider/oauth/service/service_interface.php b/phpBB/phpbb/auth/provider/oauth/service/service_interface.php index ab69fe6ef3..eee3a51cac 100644 --- a/phpBB/phpbb/auth/provider/oauth/service/service_interface.php +++ b/phpBB/phpbb/auth/provider/oauth/service/service_interface.php @@ -10,14 +10,6 @@ namespace phpbb\auth\provider\oauth\service; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * OAuth service interface * * @package auth diff --git a/phpBB/phpbb/auth/provider/oauth/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php index 2ce0e32da3..d32a03be0a 100644 --- a/phpBB/phpbb/auth/provider/oauth/token_storage.php +++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php @@ -9,14 +9,6 @@ namespace phpbb\auth\provider\oauth; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use OAuth\OAuth1\Token\StdOAuth1Token; use OAuth\Common\Token\TokenInterface; @@ -34,7 +26,7 @@ class token_storage implements TokenStorageInterface /** * Cache driver. * - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -60,11 +52,11 @@ class token_storage implements TokenStorageInterface /** * Creates token storage for phpBB. * - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\user $user * @param string $auth_provider_oauth_table */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\user $user, $auth_provider_oauth_table) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $auth_provider_oauth_table) { $this->db = $db; $this->user = $user; @@ -78,7 +70,7 @@ class token_storage implements TokenStorageInterface { $service = $this->get_service_name_for_db($service); - if ($this->cachedToken instanceOf TokenInterface) + if ($this->cachedToken instanceof TokenInterface) { return $this->cachedToken; } @@ -238,7 +230,7 @@ class token_storage implements TokenStorageInterface { $service = $this->get_service_name_for_db($service); - if ($this->cachedToken instanceOf TokenInterface) { + if ($this->cachedToken instanceof TokenInterface) { return $this->cachedToken; } diff --git a/phpBB/phpbb/auth/provider/provider_interface.php b/phpBB/phpbb/auth/provider/provider_interface.php index 1bb209c821..946731f52d 100644 --- a/phpBB/phpbb/auth/provider/provider_interface.php +++ b/phpBB/phpbb/auth/provider/provider_interface.php @@ -10,14 +10,6 @@ namespace phpbb\auth\provider; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * The interface authentication provider classes have to implement. * * @package auth diff --git a/phpBB/phpbb/avatar/driver/driver.php b/phpBB/phpbb/avatar/driver/driver.php index 0c54951cbd..dd55f09119 100644 --- a/phpBB/phpbb/avatar/driver/driver.php +++ b/phpBB/phpbb/avatar/driver/driver.php @@ -10,14 +10,6 @@ namespace phpbb\avatar\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Base class for avatar drivers * @package phpBB3 */ @@ -48,6 +40,12 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface protected $php_ext; /** + * Path Helper + * @var \phpbb\path_helper + */ + protected $path_helper; + + /** * Cache driver * @var \phpbb\cache\driver\driver_interface */ @@ -75,13 +73,15 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface * @param \phpbb\request\request $request Request object * @param string $phpbb_root_path Path to the phpBB root * @param string $php_ext PHP file extension + * @param \phpbb_path_helper $path_helper phpBB path helper * @param \phpbb\cache\driver\driver_interface $cache Cache driver */ - public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\cache\driver\driver_interface $cache = null) { $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; + $this->path_helper = $path_helper; $this->cache = $cache; } @@ -112,17 +112,6 @@ abstract class driver implements \phpbb\avatar\driver\driver_interface /** * @inheritdoc */ - public function get_template_name() - { - $driver = preg_replace('#^phpbb\\\\avatar\\\\driver\\\\#', '', get_class($this)); - $template = "ucp_avatar_options_$driver.html"; - - return $template; - } - - /** - * @inheritdoc - */ public function get_name() { return $this->name; diff --git a/phpBB/phpbb/avatar/driver/driver_interface.php b/phpBB/phpbb/avatar/driver/driver_interface.php index d9540c19db..7f049469a2 100644 --- a/phpBB/phpbb/avatar/driver/driver_interface.php +++ b/phpBB/phpbb/avatar/driver/driver_interface.php @@ -10,14 +10,6 @@ namespace phpbb\avatar\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Interface for avatar drivers * @package phpBB3 */ diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php index 3ad783932e..9f14b7f468 100644 --- a/phpBB/phpbb/avatar/driver/gravatar.php +++ b/phpBB/phpbb/avatar/driver/gravatar.php @@ -10,14 +10,6 @@ namespace phpbb\avatar\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Handles avatars hosted at gravatar.com * @package phpBB3 */ @@ -155,6 +147,14 @@ class gravatar extends \phpbb\avatar\driver\driver } /** + * @inheritdoc + */ + public function get_template_name() + { + return 'ucp_avatar_options_gravatar.html'; + } + + /** * Build gravatar URL for output on page * * @return string Gravatar URL diff --git a/phpBB/phpbb/avatar/driver/local.php b/phpBB/phpbb/avatar/driver/local.php index d779099c46..611a44cb3d 100644 --- a/phpBB/phpbb/avatar/driver/local.php +++ b/phpBB/phpbb/avatar/driver/local.php @@ -10,14 +10,6 @@ namespace phpbb\avatar\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Handles avatars selected from the board gallery * @package phpBB3 */ @@ -29,7 +21,7 @@ class local extends \phpbb\avatar\driver\driver public function get_data($row) { return array( - 'src' => $this->phpbb_root_path . $this->config['avatar_gallery_path'] . '/' . $row['avatar'], + 'src' => $this->path_helper->get_web_root_path() . $this->config['avatar_gallery_path'] . '/' . $row['avatar'], 'width' => $row['avatar_width'], 'height' => $row['avatar_height'], ); @@ -143,6 +135,14 @@ class local extends \phpbb\avatar\driver\driver } /** + * @inheritdoc + */ + public function get_template_name() + { + return 'ucp_avatar_options_local.html'; + } + + /** * Get a list of avatars that are locally available * Results get cached for 24 hours (86400 seconds) * diff --git a/phpBB/phpbb/avatar/driver/remote.php b/phpBB/phpbb/avatar/driver/remote.php index 1aa638dfe5..36623942df 100644 --- a/phpBB/phpbb/avatar/driver/remote.php +++ b/phpBB/phpbb/avatar/driver/remote.php @@ -10,14 +10,6 @@ namespace phpbb\avatar\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Handles avatars hosted remotely * @package phpBB3 */ @@ -125,6 +117,37 @@ class remote extends \phpbb\avatar\driver\driver $types = \fileupload::image_types(); $extension = strtolower(\filespec::get_extension($url)); + // Check if this is actually an image + if ($file_stream = @fopen($url, 'r')) + { + // Timeout after 1 second + stream_set_timeout($file_stream, 1); + $meta = stream_get_meta_data($file_stream); + foreach ($meta['wrapper_data'] as $header) + { + $header = preg_split('/ /', $header, 2); + if (strtr(strtolower(trim($header[0], ':')), '_', '-') === 'content-type') + { + if (strpos($header[1], 'image/') !== 0) + { + $error[] = 'AVATAR_URL_INVALID'; + fclose($file_stream); + return false; + } + else + { + fclose($file_stream); + break; + } + } + } + } + else + { + $error[] = 'AVATAR_URL_INVALID'; + return false; + } + if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]]))) { if (!isset($types[$image_data[2]])) @@ -163,4 +186,12 @@ class remote extends \phpbb\avatar\driver\driver 'avatar_height' => $height, ); } + + /** + * @inheritdoc + */ + public function get_template_name() + { + return 'ucp_avatar_options_remote.html'; + } } diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index 377c9a0b04..f77ef1332b 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -10,14 +10,6 @@ namespace phpbb\avatar\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Handles avatars uploaded to the board * @package phpBB3 */ @@ -29,7 +21,7 @@ class upload extends \phpbb\avatar\driver\driver public function get_data($row, $ignore_config = false) { return array( - 'src' => $this->phpbb_root_path . 'download/file.' . $this->php_ext . '?avatar=' . $row['avatar'], + 'src' => $this->path_helper->get_web_root_path() . 'download/file.' . $this->php_ext . '?avatar=' . $row['avatar'], 'width' => $row['avatar_width'], 'height' => $row['avatar_height'], ); @@ -155,7 +147,7 @@ class upload extends \phpbb\avatar\driver\driver return array( 'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), - 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true), + 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true), ); } @@ -176,6 +168,14 @@ class upload extends \phpbb\avatar\driver\driver } /** + * @inheritdoc + */ + public function get_template_name() + { + return 'ucp_avatar_options_upload.html'; + } + + /** * Check if user is able to upload an avatar * * @return bool True if user can upload, false if not diff --git a/phpBB/phpbb/avatar/manager.php b/phpBB/phpbb/avatar/manager.php index c28380a401..6ce924d2eb 100644 --- a/phpBB/phpbb/avatar/manager.php +++ b/phpBB/phpbb/avatar/manager.php @@ -10,14 +10,6 @@ namespace phpbb\avatar; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * @package avatar */ class manager @@ -42,12 +34,6 @@ class manager protected $avatar_drivers; /** - * Service container object - * @var object - */ - protected $container; - - /** * Default avatar data row * @var array */ @@ -63,13 +49,27 @@ class manager * * @param \phpbb\config\config $config phpBB configuration * @param array $avatar_drivers Avatar drivers passed via the service container - * @param object $container Container object */ - public function __construct(\phpbb\config\config $config, $avatar_drivers, $container) + public function __construct(\phpbb\config\config $config, $avatar_drivers) { $this->config = $config; - $this->avatar_drivers = $avatar_drivers; - $this->container = $container; + $this->register_avatar_drivers($avatar_drivers); + } + + /** + * Register avatar drivers + * + * @param array $avatar_drivers Service collection of avatar drivers + */ + protected function register_avatar_drivers($avatar_drivers) + { + if (!empty($avatar_drivers)) + { + foreach ($avatar_drivers as $driver) + { + $this->avatar_drivers[$driver->get_name()] = $driver; + } + } } /** @@ -112,7 +112,7 @@ class manager * There is no need to handle invalid avatar types as the following code * will cause a ServiceNotFoundException if the type does not exist */ - $driver = $this->container->get($avatar_type); + $driver = $this->avatar_drivers[$avatar_type]; return $driver; } @@ -178,14 +178,16 @@ class manager } /** - * Strip out user_ and group_ prefixes from keys + * Strip out user_, group_, or other prefixes from array keys * - * @param array $row User data or group data + * @param array $row User data or group data + * @param string $prefix Prefix of data keys (e.g. user), should not include the trailing underscore * - * @return array User data or group data with keys that have been - * stripped from the preceding "user_" or "group_" + * @return array User or group data with keys that have been + * stripped from the preceding "user_" or "group_" + * Also the group id is prefixed with g, when the prefix group is removed. */ - static public function clean_row($row) + static public function clean_row($row, $prefix = '') { // Upon creation of a user/group $row might be empty if (empty($row)) @@ -193,23 +195,19 @@ class manager return self::$default_row; } - $keys = array_keys($row); - $values = array_values($row); - - $keys = array_map(array('\phpbb\avatar\manager', 'strip_prefix'), $keys); + $output = array(); + foreach ($row as $key => $value) + { + $key = preg_replace("#^(?:{$prefix}_)#", '', $key); + $output[$key] = $value; + } - return array_combine($keys, $values); - } + if ($prefix === 'group' && isset($output['id'])) + { + $output['id'] = 'g' . $output['id']; + } - /** - * Strip prepending user_ or group_ prefix from key - * - * @param string Array key - * @return string Key that has been stripped from its prefix - */ - static protected function strip_prefix($key) - { - return preg_replace('#^(?:user_|group_)#', '', $key); + return $output; } /** diff --git a/phpBB/phpbb/cache/driver/apc.php b/phpBB/phpbb/cache/driver/apc.php index ce72ec6134..77b7b11181 100644 --- a/phpBB/phpbb/cache/driver/apc.php +++ b/phpBB/phpbb/cache/driver/apc.php @@ -10,14 +10,6 @@ namespace phpbb\cache\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * ACM for APC * @package acm */ @@ -26,9 +18,7 @@ class apc extends \phpbb\cache\driver\memory var $extension = 'apc'; /** - * Purge cache data - * - * @return null + * {@inheritDoc} */ function purge() { diff --git a/phpBB/phpbb/cache/driver/base.php b/phpBB/phpbb/cache/driver/base.php index 90185a00d2..feaca25a5b 100644 --- a/phpBB/phpbb/cache/driver/base.php +++ b/phpBB/phpbb/cache/driver/base.php @@ -10,14 +10,6 @@ namespace phpbb\cache\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * @package acm */ abstract class base implements \phpbb\cache\driver\driver_interface diff --git a/phpBB/phpbb/cache/driver/driver_interface.php b/phpBB/phpbb/cache/driver/driver_interface.php index 34c60b5935..8929647411 100644 --- a/phpBB/phpbb/cache/driver/driver_interface.php +++ b/phpBB/phpbb/cache/driver/driver_interface.php @@ -10,14 +10,6 @@ namespace phpbb\cache\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * An interface that all cache drivers must implement * * @package acm @@ -26,46 +18,73 @@ interface driver_interface { /** * Load global cache + * + * @return mixed False if an error was encountered, otherwise the data type of the cached data */ public function load(); /** * Unload cache object + * + * @return null */ public function unload(); /** * Save modified objects + * + * @return null */ public function save(); /** * Tidy cache + * + * @return null */ public function tidy(); /** * Get saved cache object + * + * @param string $var_name Cache key + * @return mixed False if an error was encountered, otherwise the saved cached object */ public function get($var_name); /** * Put data into cache + * + * @param string $var_name Cache key + * @param mixed $var Cached data to store + * @param int $ttl Time-to-live of cached data + * @return null */ public function put($var_name, $var, $ttl = 0); /** * Purge cache data + * + * @return null */ public function purge(); /** * Destroy cache data + * + * @param string $var_name Cache key + * @param string $table Table name + * @return null */ public function destroy($var_name, $table = ''); /** * Check if a given cache entry exists + * + * @param string $var_name Cache key + * + * @return bool True if cache file exists and has not expired. + * False otherwise. */ public function _exists($var_name); @@ -87,7 +106,7 @@ interface driver_interface * result to persistent storage. In other words, there is no need * to call save() afterwards. * - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param string $query SQL query, should be used for generating storage key * @param mixed $query_result The result from \dbal::sql_query, to be passed to * \dbal::sql_fetchrow to get all rows and store them @@ -98,7 +117,7 @@ interface driver_interface * representing the query should be returned. Otherwise * the original $query_result should be returned. */ - public function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl); + public function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl); /** * Check if result for a given SQL query exists in cache. diff --git a/phpBB/phpbb/cache/driver/eaccelerator.php b/phpBB/phpbb/cache/driver/eaccelerator.php index 72c0d77d02..d1ad69ef6d 100644 --- a/phpBB/phpbb/cache/driver/eaccelerator.php +++ b/phpBB/phpbb/cache/driver/eaccelerator.php @@ -10,14 +10,6 @@ namespace phpbb\cache\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * ACM for eAccelerator * @package acm * @todo Missing locks from destroy() talk with David @@ -30,9 +22,7 @@ class eaccelerator extends \phpbb\cache\driver\memory var $serialize_header = '#phpbb-serialized#'; /** - * Purge cache data - * - * @return null + * {@inheritDoc} */ function purge() { @@ -47,10 +37,8 @@ class eaccelerator extends \phpbb\cache\driver\memory } /** - * Perform cache garbage collection - * - * @return null - */ + * {@inheritDoc} + */ function tidy() { eaccelerator_gc(); diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index a64232400b..286ba328c3 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -10,14 +10,6 @@ namespace phpbb\cache\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * ACM File Based Caching * @package acm */ @@ -41,7 +33,7 @@ class file extends \phpbb\cache\driver\base } /** - * Load global cache + * {@inheritDoc} */ function load() { @@ -49,7 +41,7 @@ class file extends \phpbb\cache\driver\base } /** - * Unload cache object + * {@inheritDoc} */ function unload() { @@ -66,7 +58,7 @@ class file extends \phpbb\cache\driver\base } /** - * Save modified objects + * {@inheritDoc} */ function save() { @@ -101,7 +93,7 @@ class file extends \phpbb\cache\driver\base } /** - * Tidy cache + * {@inheritDoc} */ function tidy() { @@ -163,7 +155,7 @@ class file extends \phpbb\cache\driver\base } /** - * Get saved cache object + * {@inheritDoc} */ function get($var_name) { @@ -185,7 +177,7 @@ class file extends \phpbb\cache\driver\base } /** - * Put data into cache + * {@inheritDoc} */ function put($var_name, $var, $ttl = 31536000) { @@ -202,7 +194,7 @@ class file extends \phpbb\cache\driver\base } /** - * Purge cache data + * {@inheritDoc} */ function purge() { @@ -288,7 +280,7 @@ class file extends \phpbb\cache\driver\base } /** - * Destroy cache data + * {@inheritDoc} */ function destroy($var_name, $table = '') { @@ -367,7 +359,7 @@ class file extends \phpbb\cache\driver\base } /** - * Check if a given cache entry exist + * {@inheritDoc} */ function _exists($var_name) { @@ -393,7 +385,7 @@ class file extends \phpbb\cache\driver\base } /** - * Load cached sql query + * {@inheritDoc} */ function sql_load($query) { @@ -415,7 +407,7 @@ class file extends \phpbb\cache\driver\base /** * {@inheritDoc} */ - function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl) + function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) { // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); @@ -439,7 +431,7 @@ class file extends \phpbb\cache\driver\base } /** - * Ceck if a given sql query exist in cache + * {@inheritDoc} */ function sql_exists($query_id) { @@ -447,7 +439,7 @@ class file extends \phpbb\cache\driver\base } /** - * Fetch row from cache (database) + * {@inheritDoc} */ function sql_fetchrow($query_id) { @@ -460,7 +452,7 @@ class file extends \phpbb\cache\driver\base } /** - * Fetch a field from the current row of a cached database result (database) + * {@inheritDoc} */ function sql_fetchfield($query_id, $field) { @@ -473,7 +465,7 @@ class file extends \phpbb\cache\driver\base } /** - * Seek a specific row in an a cached database result (database) + * {@inheritDoc} */ function sql_rowseek($rownum, $query_id) { @@ -487,7 +479,7 @@ class file extends \phpbb\cache\driver\base } /** - * Free memory used for a cached database result (database) + * {@inheritDoc} */ function sql_freeresult($query_id) { @@ -766,6 +758,10 @@ class file extends \phpbb\cache\driver\base /** * Removes/unlinks file + * + * @param string $filename Filename to remove + * @param bool $check Check file permissions + * @return bool True if the file was successfully removed, otherwise false */ function remove_file($filename, $check = false) { diff --git a/phpBB/phpbb/cache/driver/memcache.php b/phpBB/phpbb/cache/driver/memcache.php index 84fe68ae49..eb3fced973 100644 --- a/phpBB/phpbb/cache/driver/memcache.php +++ b/phpBB/phpbb/cache/driver/memcache.php @@ -9,14 +9,6 @@ namespace phpbb\cache\driver; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - if (!defined('PHPBB_ACM_MEMCACHE_PORT')) { define('PHPBB_ACM_MEMCACHE_PORT', 11211); @@ -64,9 +56,7 @@ class memcache extends \phpbb\cache\driver\memory } /** - * Unload the cache resources - * - * @return null + * {@inheritDoc} */ function unload() { @@ -76,9 +66,7 @@ class memcache extends \phpbb\cache\driver\memory } /** - * Purge cache data - * - * @return null + * {@inheritDoc} */ function purge() { diff --git a/phpBB/phpbb/cache/driver/memory.php b/phpBB/phpbb/cache/driver/memory.php index 5a9861913f..d5404455d1 100644 --- a/phpBB/phpbb/cache/driver/memory.php +++ b/phpBB/phpbb/cache/driver/memory.php @@ -10,14 +10,6 @@ namespace phpbb\cache\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * ACM Abstract Memory Class * @package acm */ @@ -58,7 +50,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Load global cache + * {@inheritDoc} */ function load() { @@ -74,7 +66,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Unload cache object + * {@inheritDoc} */ function unload() { @@ -89,7 +81,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Save modified objects + * {@inheritDoc} */ function save() { @@ -104,7 +96,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Tidy cache + * {@inheritDoc} */ function tidy() { @@ -114,7 +106,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Get saved cache object + * {@inheritDoc} */ function get($var_name) { @@ -134,7 +126,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Put data into cache + * {@inheritDoc} */ function put($var_name, $var, $ttl = 2592000) { @@ -150,7 +142,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Purge cache data + * {@inheritDoc} */ function purge() { @@ -191,7 +183,7 @@ abstract class memory extends \phpbb\cache\driver\base /** - * Destroy cache data + * {@inheritDoc} */ function destroy($var_name, $table = '') { @@ -245,7 +237,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Check if a given cache entry exist + * {@inheritDoc} */ function _exists($var_name) { @@ -265,7 +257,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Load cached sql query + * {@inheritDoc} */ function sql_load($query) { @@ -287,7 +279,7 @@ abstract class memory extends \phpbb\cache\driver\base /** * {@inheritDoc} */ - function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl) + function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) { // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); @@ -343,7 +335,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Ceck if a given sql query exist in cache + * {@inheritDoc} */ function sql_exists($query_id) { @@ -351,7 +343,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Fetch row from cache (database) + * {@inheritDoc} */ function sql_fetchrow($query_id) { @@ -364,7 +356,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Fetch a field from the current row of a cached database result (database) + * {@inheritDoc} */ function sql_fetchfield($query_id, $field) { @@ -377,7 +369,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Seek a specific row in an a cached database result (database) + * {@inheritDoc} */ function sql_rowseek($rownum, $query_id) { @@ -391,7 +383,7 @@ abstract class memory extends \phpbb\cache\driver\base } /** - * Free memory used for a cached database result (database) + * {@inheritDoc} */ function sql_freeresult($query_id) { @@ -408,6 +400,10 @@ abstract class memory extends \phpbb\cache\driver\base /** * Removes/unlinks file + * + * @param string $filename Filename to remove + * @param bool $check Check file permissions + * @return bool True if the file was successfully removed, otherwise false */ function remove_file($filename, $check = false) { diff --git a/phpBB/phpbb/cache/driver/null.php b/phpBB/phpbb/cache/driver/null.php index c03319ad61..99cfe454e0 100644 --- a/phpBB/phpbb/cache/driver/null.php +++ b/phpBB/phpbb/cache/driver/null.php @@ -10,14 +10,6 @@ namespace phpbb\cache\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * ACM Null Caching * @package acm */ @@ -31,7 +23,7 @@ class null extends \phpbb\cache\driver\base } /** - * Load global cache + * {@inheritDoc} */ function load() { @@ -39,21 +31,21 @@ class null extends \phpbb\cache\driver\base } /** - * Unload cache object + * {@inheritDoc} */ function unload() { } /** - * Save modified objects + * {@inheritDoc} */ function save() { } /** - * Tidy cache + * {@inheritDoc} */ function tidy() { @@ -62,7 +54,7 @@ class null extends \phpbb\cache\driver\base } /** - * Get saved cache object + * {@inheritDoc} */ function get($var_name) { @@ -70,28 +62,28 @@ class null extends \phpbb\cache\driver\base } /** - * Put data into cache + * {@inheritDoc} */ function put($var_name, $var, $ttl = 0) { } /** - * Purge cache data + * {@inheritDoc} */ function purge() { } /** - * Destroy cache data + * {@inheritDoc} */ function destroy($var_name, $table = '') { } /** - * Check if a given cache entry exist + * {@inheritDoc} */ function _exists($var_name) { @@ -99,7 +91,7 @@ class null extends \phpbb\cache\driver\base } /** - * Load cached sql query + * {@inheritDoc} */ function sql_load($query) { @@ -109,13 +101,13 @@ class null extends \phpbb\cache\driver\base /** * {@inheritDoc} */ - function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl) + function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) { return $query_result; } /** - * Ceck if a given sql query exist in cache + * {@inheritDoc} */ function sql_exists($query_id) { @@ -123,7 +115,7 @@ class null extends \phpbb\cache\driver\base } /** - * Fetch row from cache (database) + * {@inheritDoc} */ function sql_fetchrow($query_id) { @@ -131,7 +123,7 @@ class null extends \phpbb\cache\driver\base } /** - * Fetch a field from the current row of a cached database result (database) + * {@inheritDoc} */ function sql_fetchfield($query_id, $field) { @@ -139,7 +131,7 @@ class null extends \phpbb\cache\driver\base } /** - * Seek a specific row in an a cached database result (database) + * {@inheritDoc} */ function sql_rowseek($rownum, $query_id) { @@ -147,7 +139,7 @@ class null extends \phpbb\cache\driver\base } /** - * Free memory used for a cached database result (database) + * {@inheritDoc} */ function sql_freeresult($query_id) { diff --git a/phpBB/phpbb/cache/driver/redis.php b/phpBB/phpbb/cache/driver/redis.php index 317d07428a..2f2a32a12d 100644 --- a/phpBB/phpbb/cache/driver/redis.php +++ b/phpBB/phpbb/cache/driver/redis.php @@ -9,14 +9,6 @@ namespace phpbb\cache\driver; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - if (!defined('PHPBB_ACM_REDIS_PORT')) { define('PHPBB_ACM_REDIS_PORT', 6379); @@ -100,9 +92,7 @@ class redis extends \phpbb\cache\driver\memory } /** - * Unload the cache resources - * - * @return null + * {@inheritDoc} */ function unload() { @@ -112,9 +102,7 @@ class redis extends \phpbb\cache\driver\memory } /** - * Purge cache data - * - * @return null + * {@inheritDoc} */ function purge() { @@ -165,4 +153,3 @@ class redis extends \phpbb\cache\driver\memory return false; } } - diff --git a/phpBB/phpbb/cache/driver/wincache.php b/phpBB/phpbb/cache/driver/wincache.php index a0b24e4a1f..d0f636d9cb 100644 --- a/phpBB/phpbb/cache/driver/wincache.php +++ b/phpBB/phpbb/cache/driver/wincache.php @@ -10,14 +10,6 @@ namespace phpbb\cache\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * ACM for WinCache * @package acm */ @@ -26,9 +18,7 @@ class wincache extends \phpbb\cache\driver\memory var $extension = 'wincache'; /** - * Purge cache data - * - * @return null + * {@inheritDoc} */ function purge() { diff --git a/phpBB/phpbb/cache/driver/xcache.php b/phpBB/phpbb/cache/driver/xcache.php index fdcbf7e4b5..6c9323ec83 100644 --- a/phpBB/phpbb/cache/driver/xcache.php +++ b/phpBB/phpbb/cache/driver/xcache.php @@ -10,14 +10,6 @@ namespace phpbb\cache\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * ACM for XCache * @package acm * @@ -41,9 +33,7 @@ class xcache extends \phpbb\cache\driver\memory } /** - * Purge cache data - * - * @return null + * {@inheritDoc} */ function purge() { diff --git a/phpBB/phpbb/cache/service.php b/phpBB/phpbb/cache/service.php index da8f4eb8d8..f9b6324b05 100644 --- a/phpBB/phpbb/cache/service.php +++ b/phpBB/phpbb/cache/service.php @@ -10,14 +10,6 @@ namespace phpbb\cache; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Class for grabbing/handling cached entries * @package acm */ @@ -40,7 +32,7 @@ class service /** * Database connection. * - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -63,11 +55,11 @@ class service * * @param \phpbb\cache\driver\driver_interface $driver The cache driver * @param \phpbb\config\config $config The config - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param string $phpbb_root_path Root path * @param string $php_ext PHP extension */ - public function __construct(\phpbb\cache\driver\driver_interface $driver, \phpbb\config\config $config, \phpbb\db\driver\driver $db, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\cache\driver\driver_interface $driver, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, $phpbb_root_path, $php_ext) { $this->set_driver($driver); $this->config = $config; diff --git a/phpBB/phpbb/class_loader.php b/phpBB/phpbb/class_loader.php index 769f28b4f1..ee9767148b 100644 --- a/phpBB/phpbb/class_loader.php +++ b/phpBB/phpbb/class_loader.php @@ -10,14 +10,6 @@ namespace phpbb; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * The class loader resolves class names to file system paths and loads them if * necessary. * @@ -55,7 +47,7 @@ class class_loader * @param \phpbb\cache\driver\driver_interface $cache An implementation of the phpBB cache interface. */ public function __construct($namespace, $path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null) - { + { if ($namespace[0] !== '\\') { $namespace = '\\' . $namespace; @@ -150,7 +142,13 @@ class class_loader */ public function load_class($class) { - $class = '\\' . $class; + // In general $class is not supposed to contain a leading backslash, + // but sometimes it does. See tickets PHP-50731 and HHVM-1840. + if ($class[0] !== '\\') + { + $class = '\\' . $class; + } + if (substr($class, 0, strlen($this->namespace)) === $this->namespace) { $path = $this->resolve_path($class); diff --git a/phpBB/phpbb/config/config.php b/phpBB/phpbb/config/config.php index dc865df707..d37922acf1 100644 --- a/phpBB/phpbb/config/config.php +++ b/phpBB/phpbb/config/config.php @@ -10,14 +10,6 @@ namespace phpbb\config; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Configuration container class * @package phpBB3 */ diff --git a/phpBB/phpbb/config/db.php b/phpBB/phpbb/config/db.php index 0a490af14f..ea84a9f873 100644 --- a/phpBB/phpbb/config/db.php +++ b/phpBB/phpbb/config/db.php @@ -10,14 +10,6 @@ namespace phpbb\config; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Configuration container class * @package phpBB3 */ @@ -31,7 +23,7 @@ class db extends \phpbb\config\config /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -44,11 +36,11 @@ class db extends \phpbb\config\config /** * Creates a configuration container with a default set of values * - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\cache\driver\driver_interface $cache Cache instance * @param string $table Configuration table name */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, $table) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $table) { $this->db = $db; $this->cache = $cache; diff --git a/phpBB/phpbb/config/db_text.php b/phpBB/phpbb/config/db_text.php index 3ee3351e19..250a2ec7de 100644 --- a/phpBB/phpbb/config/db_text.php +++ b/phpBB/phpbb/config/db_text.php @@ -10,14 +10,6 @@ namespace phpbb\config; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Manages configuration options with an arbitrary length value stored in a TEXT * column. In constrast to class \phpbb\config\db, values are never cached and * prefetched, but every get operation sends a query to the database. @@ -28,7 +20,7 @@ class db_text { /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -39,10 +31,10 @@ class db_text protected $table; /** - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param string $table Table name */ - public function __construct(\phpbb\db\driver\driver $db, $table) + public function __construct(\phpbb\db\driver\driver_interface $db, $table) { $this->db = $db; $this->table = $this->db->sql_escape($table); diff --git a/phpBB/phpbb/console/application.php b/phpBB/phpbb/console/application.php new file mode 100644 index 0000000000..fdcd9d42f6 --- /dev/null +++ b/phpBB/phpbb/console/application.php @@ -0,0 +1,23 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\console; + +use Symfony\Component\DependencyInjection\TaggedContainerInterface; + +class application extends \Symfony\Component\Console\Application +{ + function register_container_commands(TaggedContainerInterface $container, $tag = 'console.command') + { + foreach($container->findTaggedServiceIds($tag) as $id => $void) + { + $this->add($container->get($id)); + } + } +} diff --git a/phpBB/phpbb/console/command/command.php b/phpBB/phpbb/console/command/command.php new file mode 100644 index 0000000000..6abbdd203c --- /dev/null +++ b/phpBB/phpbb/console/command/command.php @@ -0,0 +1,14 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\console\command; + +abstract class command extends \Symfony\Component\Console\Command\Command +{ +} diff --git a/phpBB/phpbb/console/command/config/command.php b/phpBB/phpbb/console/command/config/command.php new file mode 100644 index 0000000000..b105bc826d --- /dev/null +++ b/phpBB/phpbb/console/command/config/command.php @@ -0,0 +1,22 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\config; + +abstract class command extends \phpbb\console\command\command +{ + /** @var \phpbb\config\config */ + protected $config; + + function __construct(\phpbb\config\config $config) + { + $this->config = $config; + + parent::__construct(); + } +} diff --git a/phpBB/phpbb/console/command/config/delete.php b/phpBB/phpbb/console/command/config/delete.php new file mode 100644 index 0000000000..9a2d00561d --- /dev/null +++ b/phpBB/phpbb/console/command/config/delete.php @@ -0,0 +1,46 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\config; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class delete extends command +{ + protected function configure() + { + $this + ->setName('config:delete') + ->setDescription('Deletes a configuration option') + ->addArgument( + 'key', + InputArgument::REQUIRED, + "The configuration option's name" + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $key = $input->getArgument('key'); + + if (isset($this->config[$key])) + { + $this->config->delete($key); + + $output->writeln("<info>Successfully deleted config $key</info>"); + } + else + { + $output->writeln("<error>Config $key does not exist</error>"); + } + } +} diff --git a/phpBB/phpbb/console/command/config/get.php b/phpBB/phpbb/console/command/config/get.php new file mode 100644 index 0000000000..275c82b53f --- /dev/null +++ b/phpBB/phpbb/console/command/config/get.php @@ -0,0 +1,54 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\config; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class get extends command +{ + protected function configure() + { + $this + ->setName('config:get') + ->setDescription("Gets a configuration option's value") + ->addArgument( + 'key', + InputArgument::REQUIRED, + "The configuration option's name" + ) + ->addOption( + 'no-newline', + null, + InputOption::VALUE_NONE, + 'Set this option if the value should be printed without a new line at the end.' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $key = $input->getArgument('key'); + + if (isset($this->config[$key]) && $input->getOption('no-newline')) + { + $output->write($this->config[$key]); + } + elseif (isset($this->config[$key])) + { + $output->writeln($this->config[$key]); + } + else + { + $output->writeln("<error>Could not get config $key</error>"); + } + } +} diff --git a/phpBB/phpbb/console/command/config/increment.php b/phpBB/phpbb/console/command/config/increment.php new file mode 100644 index 0000000000..bc6b63c6ff --- /dev/null +++ b/phpBB/phpbb/console/command/config/increment.php @@ -0,0 +1,52 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\config; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class increment extends command +{ + protected function configure() + { + $this + ->setName('config:increment') + ->setDescription("Increments a configuration option's value") + ->addArgument( + 'key', + InputArgument::REQUIRED, + "The configuration option's name" + ) + ->addArgument( + 'increment', + InputArgument::REQUIRED, + 'Amount to increment by' + ) + ->addOption( + 'dynamic', + 'd', + InputOption::VALUE_NONE, + 'Set this option if the configuration option changes too frequently to be efficiently cached.' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $key = $input->getArgument('key'); + $increment = $input->getArgument('increment'); + $use_cache = !$input->getOption('dynamic'); + + $this->config->increment($key, $increment, $use_cache); + + $output->writeln("<info>Successfully incremented config $key</info>"); + } +} diff --git a/phpBB/phpbb/console/command/config/set.php b/phpBB/phpbb/console/command/config/set.php new file mode 100644 index 0000000000..9d471a96ad --- /dev/null +++ b/phpBB/phpbb/console/command/config/set.php @@ -0,0 +1,52 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\config; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class set extends command +{ + protected function configure() + { + $this + ->setName('config:set') + ->setDescription("Sets a configuration option's value") + ->addArgument( + 'key', + InputArgument::REQUIRED, + "The configuration option's name" + ) + ->addArgument( + 'value', + InputArgument::REQUIRED, + 'New configuration value, use 0 and 1 to specify boolean values' + ) + ->addOption( + 'dynamic', + 'd', + InputOption::VALUE_NONE, + 'Set this option if the configuration option changes too frequently to be efficiently cached.' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $key = $input->getArgument('key'); + $value = $input->getArgument('value'); + $use_cache = !$input->getOption('dynamic'); + + $this->config->set($key, $value, $use_cache); + + $output->writeln("<info>Successfully set config $key</info>"); + } +} diff --git a/phpBB/phpbb/console/command/config/set_atomic.php b/phpBB/phpbb/console/command/config/set_atomic.php new file mode 100644 index 0000000000..03e7a60210 --- /dev/null +++ b/phpBB/phpbb/console/command/config/set_atomic.php @@ -0,0 +1,65 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\config; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class set_atomic extends command +{ + protected function configure() + { + $this + ->setName('config:set-atomic') + ->setDescription("Sets a configuration option's value only if the old matches the current value.") + ->addArgument( + 'key', + InputArgument::REQUIRED, + "The configuration option's name" + ) + ->addArgument( + 'old', + InputArgument::REQUIRED, + 'Current configuration value, use 0 and 1 to specify boolean values' + ) + ->addArgument( + 'new', + InputArgument::REQUIRED, + 'New configuration value, use 0 and 1 to specify boolean values' + ) + ->addOption( + 'dynamic', + 'd', + InputOption::VALUE_NONE, + 'Set this option if the configuration option changes too frequently to be efficiently cached.' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $key = $input->getArgument('key'); + $old_value = $input->getArgument('old'); + $new_value = $input->getArgument('new'); + $use_cache = !$input->getOption('dynamic'); + + if ($this->config->set_atomic($key, $old_value, $new_value, $use_cache)) + { + $output->writeln("<info>Successfully set config $key</info>"); + return 0; + } + else + { + $output->writeln("<error>Could not set config $key</error>"); + return 1; + } + } +} diff --git a/phpBB/phpbb/console/command/extension/command.php b/phpBB/phpbb/console/command/extension/command.php new file mode 100644 index 0000000000..edde7ce2e2 --- /dev/null +++ b/phpBB/phpbb/console/command/extension/command.php @@ -0,0 +1,22 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\extension; + +abstract class command extends \phpbb\console\command\command +{ + /** @var \phpbb\extension\manager */ + protected $manager; + + function __construct(\phpbb\extension\manager $manager) + { + $this->manager = $manager; + + parent::__construct(); + } +} diff --git a/phpBB/phpbb/console/command/extension/disable.php b/phpBB/phpbb/console/command/extension/disable.php new file mode 100644 index 0000000000..e4de70ca34 --- /dev/null +++ b/phpBB/phpbb/console/command/extension/disable.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\extension; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class disable extends command +{ + protected function configure() + { + $this + ->setName('extension:disable') + ->setDescription('Disables the specified extension.') + ->addArgument( + 'extension-name', + InputArgument::REQUIRED, + 'Name of the extension' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $name = $input->getArgument('extension-name'); + $this->manager->disable($name); + $this->manager->load_extensions(); + + if ($this->manager->enabled($name)) + { + $output->writeln("<error>Could not disable extension $name</error>"); + return 1; + } + else + { + $output->writeln("<info>Successfully disabled extension $name</info>"); + return 0; + } + } +} diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php new file mode 100644 index 0000000000..ee7dae76aa --- /dev/null +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\extension; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class enable extends command +{ + protected function configure() + { + $this + ->setName('extension:enable') + ->setDescription('Enables the specified extension.') + ->addArgument( + 'extension-name', + InputArgument::REQUIRED, + 'Name of the extension' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $name = $input->getArgument('extension-name'); + $this->manager->enable($name); + $this->manager->load_extensions(); + + if ($this->manager->enabled($name)) + { + $output->writeln("<info>Successfully enabled extension $name</info>"); + return 0; + } + else + { + $output->writeln("<error>Could not enable extension $name</error>"); + return 1; + } + } +} diff --git a/phpBB/phpbb/console/command/extension/purge.php b/phpBB/phpbb/console/command/extension/purge.php new file mode 100644 index 0000000000..c2e1d2928c --- /dev/null +++ b/phpBB/phpbb/console/command/extension/purge.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\extension; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class purge extends command +{ + protected function configure() + { + $this + ->setName('extension:purge') + ->setDescription('Purges the specified extension.') + ->addArgument( + 'extension-name', + InputArgument::REQUIRED, + 'Name of the extension' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $name = $input->getArgument('extension-name'); + $this->manager->purge($name); + $this->manager->load_extensions(); + + if ($this->manager->enabled($name)) + { + $output->writeln("<error>Could not purge extension $name</error>"); + return 1; + } + else + { + $output->writeln("<info>Successfully purge extension $name</info>"); + return 0; + } + } +} diff --git a/phpBB/phpbb/console/command/extension/show.php b/phpBB/phpbb/console/command/extension/show.php new file mode 100644 index 0000000000..0f48ac2379 --- /dev/null +++ b/phpBB/phpbb/console/command/extension/show.php @@ -0,0 +1,58 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\extension; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class show extends command +{ + protected function configure() + { + $this + ->setName('extension:show') + ->setDescription('Lists all extensions in the database and on the filesystem.') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->manager->load_extensions(); + $all = array_keys($this->manager->all_available()); + + if (empty($all)) + { + $output->writeln('<comment>No extensions were found.</comment>'); + return 3; + } + + $enabled = array_keys($this->manager->all_enabled()); + $this->print_extension_list($output, 'Enabled', $enabled); + + $output->writeln(''); + + $disabled = array_keys($this->manager->all_disabled()); + $this->print_extension_list($output, 'Disabled', $disabled); + + $output->writeln(''); + + $purged = array_diff($all, $enabled, $disabled); + $this->print_extension_list($output, 'Available', $purged); + } + + protected function print_extension_list(OutputInterface $output, $type, array $extensions) + { + $output->writeln("<info>$type:</info>"); + + foreach ($extensions as $extension) + { + $output->writeln(" - $extension"); + } + } +} diff --git a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php new file mode 100644 index 0000000000..8c520673d9 --- /dev/null +++ b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php @@ -0,0 +1,71 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\fixup; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class recalculate_email_hash extends \phpbb\console\command\command +{ + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + function __construct(\phpbb\db\driver\driver_interface $db) + { + $this->db = $db; + + parent::__construct(); + } + + protected function configure() + { + $this + ->setName('fixup:recalculate-email-hash') + ->setDescription('Recalculates the user_email_hash column of the users table.') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $sql = 'SELECT user_id, user_email, user_email_hash + FROM ' . USERS_TABLE . ' + WHERE user_type <> ' . USER_IGNORE . " + AND user_email <> ''"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $user_email_hash = phpbb_email_hash($row['user_email']); + if ($user_email_hash !== $row['user_email_hash']) + { + $sql_ary = array( + 'user_email_hash' => $user_email_hash, + ); + + $sql = 'UPDATE ' . USERS_TABLE . ' + SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE user_id = ' . (int) $row['user_id']; + $this->db->sql_query($sql); + + if ($output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG) + { + $output->writeln(sprintf( + 'user_id %d, email %s => %s', + $row['user_id'], + $row['user_email'], + $user_email_hash + )); + } + } + } + $this->db->sql_freeresult($result); + + $output->writeln('<info>Successfully recalculated all email hashes.</info>'); + } +} diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php index bf720957bc..881a8f2c54 100644 --- a/phpBB/phpbb/content_visibility.php +++ b/phpBB/phpbb/content_visibility.php @@ -10,14 +10,6 @@ namespace phpbb; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * phpbb_visibility * Handle fetching and setting the visibility for topics and posts * @package phpbb @@ -26,7 +18,7 @@ class content_visibility { /** * Database object - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -58,13 +50,13 @@ class content_visibility * Constructor * * @param \phpbb\auth\auth $auth Auth object - * @param \phpbb\db\driver\driver $db Database object + * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\user $user User object * @param string $phpbb_root_path Root path * @param string $php_ext PHP Extension * @return null */ - public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver $db, \phpbb\user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table) + public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table) { $this->auth = $auth; $this->db = $db; @@ -223,23 +215,23 @@ class content_visibility /** * Change visibility status of one post or all posts of a topic * - * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED} + * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} * @param $post_id mixed Post ID or array of post IDs to act on, * if it is empty, all posts of topic_id will be modified * @param $topic_id int Topic where $post_id is found * @param $forum_id int Forum where $topic_id is found * @param $user_id int User performing the action * @param $time int Timestamp when the action is performed - * @param $reason string Reason why the visibilty was changed. + * @param $reason string Reason why the visibility was changed. * @param $is_starter bool Is this the first post of the topic changed? * @param $is_latest bool Is this the last post of the topic changed? * @param $limit_visibility mixed Limit updating per topic_id to a certain visibility * @param $limit_delete_time mixed Limit updating per topic_id to a certain deletion time - * @return array Changed post data, empty array if an error occured. + * @return array Changed post data, empty array if an error occurred. */ public function set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest, $limit_visibility = false, $limit_delete_time = false) { - if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED))) + if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE))) { return array(); } @@ -334,7 +326,7 @@ class content_visibility // Update users postcounts foreach ($postcounts as $num_posts => $poster_ids) { - if ($visibility == ITEM_DELETED) + if (in_array($visibility, array(ITEM_REAPPROVE, ITEM_DELETED))) { $sql = 'UPDATE ' . $this->users_table . ' SET user_posts = 0 @@ -395,54 +387,36 @@ class content_visibility // Update the topic's reply count and the forum's post count if ($update_topic_postcount) { - $cur_posts = $cur_unapproved_posts = $cur_softdeleted_posts = 0; + $field_alias = array( + ITEM_APPROVED => 'posts_approved', + ITEM_UNAPPROVED => 'posts_unapproved', + ITEM_DELETED => 'posts_softdeleted', + ITEM_REAPPROVE => 'posts_unapproved', + ); + $cur_posts = array_fill_keys($field_alias, 0); + foreach ($postcount_visibility as $post_visibility => $visibility_posts) { - // We need to substract the posts from the counters ... - if ($post_visibility == ITEM_APPROVED) - { - $cur_posts += $visibility_posts; - } - else if ($post_visibility == ITEM_UNAPPROVED) - { - $cur_unapproved_posts += $visibility_posts; - } - else if ($post_visibility == ITEM_DELETED) - { - $cur_softdeleted_posts += $visibility_posts; - } + $cur_posts[$field_alias[(int) $post_visibility]] += $visibility_posts; } $sql_ary = array(); - if ($visibility == ITEM_DELETED) + $recipient_field = $field_alias[$visibility]; + + foreach ($cur_posts as $field => $count) { - if ($cur_posts) - { - $sql_ary['posts_approved'] = ' - ' . $cur_posts; - } - if ($cur_unapproved_posts) + // Decrease the count for the old statuses. + if ($count && $field != $recipient_field) { - $sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts; - } - if ($cur_posts + $cur_unapproved_posts) - { - $sql_ary['posts_softdeleted'] = ' + ' . ($cur_posts + $cur_unapproved_posts); + $sql_ary[$field] = " - $count"; } } - else + // Add up the count from all statuses excluding the recipient status. + $count_increase = array_sum(array_diff($cur_posts, array($recipient_field))); + + if ($count_increase) { - if ($cur_unapproved_posts) - { - $sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts; - } - if ($cur_softdeleted_posts) - { - $sql_ary['posts_softdeleted'] = ' - ' . $cur_softdeleted_posts; - } - if ($cur_softdeleted_posts + $cur_unapproved_posts) - { - $sql_ary['posts_approved'] = ' + ' . ($cur_softdeleted_posts + $cur_unapproved_posts); - } + $sql_ary[$recipient_field] = " + $count_increase"; } if (sizeof($sql_ary)) @@ -483,7 +457,7 @@ class content_visibility * as soft deleted. * If you want to update all posts, use the force option. * - * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED} + * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} * @param $topic_id mixed Topic ID to act on * @param $forum_id int Forum where $topic_id is found * @param $user_id int User performing the action @@ -494,7 +468,7 @@ class content_visibility */ public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false) { - if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED))) + if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE))) { return array(); } @@ -536,16 +510,16 @@ class content_visibility if (!$force_update_all && $original_topic_data['topic_delete_time'] && $original_topic_data['topic_visibility'] == ITEM_DELETED && $visibility == ITEM_APPROVED) { // If we're restoring a topic we only restore posts, that were soft deleted through the topic soft deletion. - self::set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility'], $original_topic_data['topic_delete_time']); + $this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility'], $original_topic_data['topic_delete_time']); } else if (!$force_update_all && $original_topic_data['topic_visibility'] == ITEM_APPROVED && $visibility == ITEM_DELETED) { - // If we're soft deleting a topic we only approved posts are soft deleted. - self::set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility']); + // If we're soft deleting a topic we only mark approved posts as soft deleted. + $this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility']); } else { - self::set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true); + $this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true); } return $data; @@ -556,7 +530,7 @@ class content_visibility * * @param $data array Contains information from the topics table about given topic * @param $sql_data array Populated with the SQL changes, may be empty at call time - * @return void + * @return null */ public function add_post_to_statistic($data, &$sql_data) { @@ -577,7 +551,7 @@ class content_visibility * * @param $data array Contains information from the topics table about given topic * @param $sql_data array Populated with the SQL changes, may be empty at call time - * @return void + * @return null */ public function remove_post_from_statistic($data, &$sql_data) { @@ -599,7 +573,7 @@ class content_visibility * @param $forum_id int Forum where the topic is found * @param $topic_row array Contains information from the topic, may be empty at call time * @param $sql_data array Populated with the SQL changes, may be empty at call time - * @return void + * @return null */ public function remove_topic_from_statistic($topic_id, $forum_id, &$topic_row, &$sql_data) { diff --git a/phpBB/phpbb/controller/exception.php b/phpBB/phpbb/controller/exception.php index e8694b8bcf..06ece8d1d5 100644 --- a/phpBB/phpbb/controller/exception.php +++ b/phpBB/phpbb/controller/exception.php @@ -10,14 +10,6 @@ namespace phpbb\controller; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Controller exception class * @package phpBB3 */ diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index 07483a91eb..54c30c93fc 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -9,15 +9,9 @@ namespace phpbb\controller; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Generator\UrlGenerator; +use Symfony\Component\Routing\RequestContext; /** * Controller helper class, contains methods that do things for controllers @@ -59,18 +53,20 @@ class helper * Constructor * * @param \phpbb\template\template $template Template object - * @param \phpbb\user $user User object - * @param \phpbb\config\config $config Config object + * @param \phpbb\user $user User object + * @param \phpbb\config\config $config Config object + * @param \phpbb\controller\provider $provider Path provider * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP extension */ - public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, $phpbb_root_path, $php_ext) { $this->template = $template; $this->user = $user; $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; + $this->route_collection = $provider->get_routes(); } /** @@ -81,9 +77,9 @@ class helper * @param int $status_code The status code to be sent to the page header * @return Response object containing rendered page */ - public function render($template_file, $page_title = '', $status_code = 200) + public function render($template_file, $page_title = '', $status_code = 200, $display_online_list = false) { - page_header($page_title); + page_header($page_title, $display_online_list); $this->template->set_filenames(array( 'body' => $template_file, @@ -95,21 +91,33 @@ class helper } /** - * Generate a URL + * Generate a URL to a route * - * @param string $route The route to travel - * @param mixed $params String or array of additional url parameters + * @param string $route Name of the route to travel + * @param array $params String or array of additional url parameters * @param bool $is_amp Is url using & (true) or & (false) * @param string $session_id Possibility to use a custom session id instead of the global one * @return string The URL already passed through append_sid() */ - public function url($route, $params = false, $is_amp = true, $session_id = false) + public function route($route, array $params = array(), $is_amp = true, $session_id = false) { - $route_params = ''; - if (($route_delim = strpos($route, '?')) !== false) + $anchor = ''; + if (isset($params['#'])) + { + $anchor = '#' . $params['#']; + unset($params['#']); + } + $url_generator = new UrlGenerator($this->route_collection, new RequestContext()); + $route_url = $url_generator->generate($route, $params); + + if (strpos($route_url, '/') === 0) + { + $route_url = substr($route_url, 1); + } + + if ($is_amp) { - $route_params = substr($route, $route_delim); - $route = substr($route, 0, $route_delim); + $route_url = str_replace(array('&', '&'), array('&', '&'), $route_url); } // If enable_mod_rewrite is false, we need to include app.php @@ -119,7 +127,7 @@ class helper $route_prefix .= 'app.' . $this->php_ext . '/'; } - return append_sid($route_prefix . "$route" . $route_params, $params, $is_amp, $session_id); + return append_sid($route_prefix . $route_url . $anchor, false, $is_amp, $session_id); } /** diff --git a/phpBB/phpbb/controller/provider.php b/phpBB/phpbb/controller/provider.php index 3aad08e3aa..9df8130210 100644 --- a/phpBB/phpbb/controller/provider.php +++ b/phpBB/phpbb/controller/provider.php @@ -9,14 +9,6 @@ namespace phpbb\controller; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Loader\YamlFileLoader; use Symfony\Component\Config\FileLocator; @@ -31,54 +23,61 @@ class provider * YAML file(s) containing route information * @var array */ - protected $routing_paths; + protected $routing_files; + + /** + * Collection of the routes in phpBB and all found extensions + * @var RouteCollection + */ + protected $routes; /** * Construct method * - * @param array() $routing_paths Array of strings containing paths + * @param array() $routing_files Array of strings containing paths * to YAML files holding route information */ - public function __construct($routing_paths = array()) + public function __construct(\phpbb\extension\finder $finder = null, $routing_files = array()) { - $this->routing_paths = $routing_paths; + $this->routing_files = $routing_files; + + if ($finder) + { + // We hardcode the path to the core config directory + // because the finder cannot find it + $this->routing_files = array_merge($this->routing_files, array('config/routing.yml'), array_keys($finder + ->directory('config') + ->suffix('routing.yml') + ->find() + )); + } } /** - * Locate paths containing routing files - * This sets an internal property but does not return the paths. + * Find a list of controllers and return it * - * @return The current instance of this object for method chaining + * @param string $base_path Base path to prepend to file paths + * @return null */ - public function import_paths_from_finder(\phpbb\extension\finder $finder) + public function find($base_path = '') { - // We hardcode the path to the core config directory - // because the finder cannot find it - $this->routing_paths = array_merge(array('config'), array_map('dirname', array_keys($finder - ->directory('config') - ->prefix('routing') - ->suffix('yml') - ->find() - ))); + $this->routes = new RouteCollection; + foreach ($this->routing_files as $file_path) + { + $loader = new YamlFileLoader(new FileLocator($base_path)); + $this->routes->addCollection($loader->load($file_path)); + } return $this; } /** - * Get a list of controllers and return it + * Get the list of routes * - * @param string $base_path Base path to prepend to file paths - * @return array Array of controllers and their route information + * @return RouteCollection Get the route collection */ - public function find($base_path = '') + public function get_routes() { - $routes = new RouteCollection; - foreach ($this->routing_paths as $path) - { - $loader = new YamlFileLoader(new FileLocator($base_path . $path)); - $routes->addCollection($loader->load('routing.yml')); - } - - return $routes; + return $this->routes; } } diff --git a/phpBB/phpbb/controller/resolver.php b/phpBB/phpbb/controller/resolver.php index 1cc8981105..233179e343 100644 --- a/phpBB/phpbb/controller/resolver.php +++ b/phpBB/phpbb/controller/resolver.php @@ -9,14 +9,6 @@ namespace phpbb\controller; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; diff --git a/phpBB/phpbb/cron/manager.php b/phpBB/phpbb/cron/manager.php index f58ba64a3d..b6af07aff7 100644 --- a/phpBB/phpbb/cron/manager.php +++ b/phpBB/phpbb/cron/manager.php @@ -10,14 +10,6 @@ namespace phpbb\cron; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Cron manager class. * * Finds installed cron tasks, stores task objects, provides task selection. diff --git a/phpBB/phpbb/cron/task/base.php b/phpBB/phpbb/cron/task/base.php index f30c9daf1b..63f0407bcd 100644 --- a/phpBB/phpbb/cron/task/base.php +++ b/phpBB/phpbb/cron/task/base.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Cron task base class. Provides sensible defaults for cron tasks * and partially implements cron task interface, making writing cron tasks easier. * diff --git a/phpBB/phpbb/cron/task/core/prune_all_forums.php b/phpBB/phpbb/cron/task/core/prune_all_forums.php index 8e3ef25ce6..36a551394a 100644 --- a/phpBB/phpbb/cron/task/core/prune_all_forums.php +++ b/phpBB/phpbb/cron/task/core/prune_all_forums.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task\core; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Prune all forums cron task. * * It is intended to be invoked from system cron. @@ -39,9 +31,9 @@ class prune_all_forums extends \phpbb\cron\task\base * @param string $phpbb_root_path The root path * @param string $php_ext The PHP extension * @param \phpbb\config\config $config The config - * @param \phpbb\db\driver\driver $db The db connection + * @param \phpbb\db\driver\driver_interface $db The db connection */ - public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver $db) + public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; diff --git a/phpBB/phpbb/cron/task/core/prune_forum.php b/phpBB/phpbb/cron/task/core/prune_forum.php index f14ab7b702..542d75e5b9 100644 --- a/phpBB/phpbb/cron/task/core/prune_forum.php +++ b/phpBB/phpbb/cron/task/core/prune_forum.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task\core; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Prune one forum cron task. * * It is intended to be used when cron is invoked via web. @@ -49,9 +41,9 @@ class prune_forum extends \phpbb\cron\task\base implements \phpbb\cron\task\para * @param string $phpbb_root_path The root path * @param string $php_ext The PHP extension * @param \phpbb\config\config $config The config - * @param \phpbb\db\driver\driver $db The db connection + * @param \phpbb\db\driver\driver_interface $db The db connection */ - public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver $db) + public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; diff --git a/phpBB/phpbb/cron/task/core/prune_notifications.php b/phpBB/phpbb/cron/task/core/prune_notifications.php index 296c0ae64f..9f67c54e1c 100644 --- a/phpBB/phpbb/cron/task/core/prune_notifications.php +++ b/phpBB/phpbb/cron/task/core/prune_notifications.php @@ -7,20 +7,14 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\cron\task\core; /** * Prune notifications cron task. * * @package phpBB3 */ -class phpbb_cron_task_core_prune_notifications extends phpbb_cron_task_base +class prune_notifications extends \phpbb\cron\task\base { protected $config; protected $notification_manager; @@ -28,10 +22,10 @@ class phpbb_cron_task_core_prune_notifications extends phpbb_cron_task_base /** * Constructor. * - * @param phpbb_config $config The config - * @param phpbb_notification_manager $notification_manager Notification manager + * @param \phpbb\config\config $config The config + * @param \phpbb\notification\manager $notification_manager Notification manager */ - public function __construct(phpbb_config $config, phpbb_notification_manager $notification_manager) + public function __construct(\phpbb\config\config $config, \phpbb\notification\manager $notification_manager) { $this->config = $config; $this->notification_manager = $notification_manager; diff --git a/phpBB/phpbb/cron/task/core/prune_shadow_topics.php b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php new file mode 100644 index 0000000000..b30e665a87 --- /dev/null +++ b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php @@ -0,0 +1,191 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\cron\task\core; + +/** +* Prune one forum of its shadow topics cron task. +* +* It is intended to be used when cron is invoked via web. +* This task can decide whether it should be run using data obtained by viewforum +* code, without making additional database queries. +* +* @package phpBB3 +*/ +class prune_shadow_topics extends \phpbb\cron\task\base implements \phpbb\cron\task\parametrized +{ + protected $phpbb_root_path; + protected $php_ext; + protected $config; + protected $db; + protected $log; + + /** + * If $forum_data is given, it is assumed to contain necessary information + * about a single forum that is to be pruned. + * + * If $forum_data is not given, forum id will be retrieved via request_var + * and a database query will be performed to load the necessary information + * about the forum. + */ + protected $forum_data; + + /** + * Constructor. + * + * @param string $phpbb_root_path The root path + * @param string $php_ext The PHP extension + * @param \phpbb\config\config $config The config + * @param \phpbb\db\driver\driver $db The db connection + * @param \phpbb\log\log $log The phpBB log system + */ + public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\log\log $log) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->config = $config; + $this->db = $db; + $this->log = $log; + } + + /** + * Manually set forum data. + * + * @param array $forum_data Information about a forum to be pruned. + */ + public function set_forum_data($forum_data) + { + $this->forum_data = $forum_data; + } + + /** + * Runs this cron task. + * + * @return null + */ + public function run() + { + if (!function_exists('auto_prune')) + { + include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext); + } + + if ($this->forum_data['prune_shadow_days']) + { + $this->auto_prune_shadow_topics($this->forum_data['forum_id'], 'shadow', $this->forum_data['forum_flags'], $this->forum_data['prune_shadow_days'], $this->forum_data['prune_shadow_freq']); + } + } + + /** + * Returns whether this cron task can run, given current board configuration. + * + * This cron task will not run when system cron is utilised, as in + * such cases prune_all_forums task would run instead. + * + * Additionally, this task must be given the forum data, either via + * the constructor or parse_parameters method. + * + * @return bool + */ + public function is_runnable() + { + return !$this->config['use_system_cron'] && $this->forum_data; + } + + /** + * Returns whether this cron task should run now, because enough time + * has passed since it was last run. + * + * Forum pruning interval is specified in the forum data. + * + * @return bool + */ + public function should_run() + { + return $this->forum_data['enable_shadow_prune'] && $this->forum_data['prune_shadow_next'] < time(); + } + + /** + * Returns parameters of this cron task as an array. + * The array has one key, f, whose value is id of the forum to be pruned. + * + * @return array + */ + public function get_parameters() + { + return array('f' => $this->forum_data['forum_id']); + } + + /** + * Parses parameters found in $request, which is an instance of + * \phpbb\request\request_interface. + * + * It is expected to have a key f whose value is id of the forum to be pruned. + * + * @param \phpbb\request\request_interface $request Request object. + * + * @return null + */ + public function parse_parameters(\phpbb\request\request_interface $request) + { + $this->forum_data = null; + if ($request->is_set('f')) + { + $forum_id = $request->variable('f', 0); + + $sql = 'SELECT forum_id, prune_shadow_next, enable_shadow_prune, prune_shadow_days, forum_flags, prune_shadow_freq + FROM ' . FORUMS_TABLE . " + WHERE forum_id = $forum_id"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + $this->forum_data = $row; + } + } + } + + /** + * Automatically prune shadow topics + * Based on fuunction auto_prune() + * @param int $forum_id Forum ID of forum that should be pruned + * @param string $prune_mode Prune mode + * @param int $prune_flags Prune flags + * @param int $prune_freq Prune frequency + * @return null + */ + protected function auto_prune_shadow_topics($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_freq) + { + $sql = 'SELECT forum_name + FROM ' . FORUMS_TABLE . " + WHERE forum_id = $forum_id"; + $result = $this->db->sql_query($sql, 3600); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + $prune_date = time() - ($prune_days * 86400); + $next_prune = time() + ($prune_freq * 86400); + + prune($forum_id, $prune_mode, $prune_date, $prune_flags, true); + + $sql = 'UPDATE ' . FORUMS_TABLE . " + SET prune_shadow_next = $next_prune + WHERE forum_id = $forum_id"; + $this->db->sql_query($sql); + + $this->log->add('admin', 'LOG_PRUNE_SHADOW', $row['forum_name']); + } + + return; + } +} diff --git a/phpBB/phpbb/cron/task/core/queue.php b/phpBB/phpbb/cron/task/core/queue.php index cb13df86df..cd799b8024 100644 --- a/phpBB/phpbb/cron/task/core/queue.php +++ b/phpBB/phpbb/cron/task/core/queue.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task\core; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Queue cron task. Sends email and jabber messages queued by other scripts. * * @package phpBB3 diff --git a/phpBB/phpbb/cron/task/core/tidy_cache.php b/phpBB/phpbb/cron/task/core/tidy_cache.php index 021d5fd8a3..a94a85db53 100644 --- a/phpBB/phpbb/cron/task/core/tidy_cache.php +++ b/phpBB/phpbb/cron/task/core/tidy_cache.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task\core; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Tidy cache cron task. * * @package phpBB3 diff --git a/phpBB/phpbb/cron/task/core/tidy_database.php b/phpBB/phpbb/cron/task/core/tidy_database.php index d03cba1d86..f712a5047c 100644 --- a/phpBB/phpbb/cron/task/core/tidy_database.php +++ b/phpBB/phpbb/cron/task/core/tidy_database.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task\core; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Tidy database cron task. * * @package phpBB3 diff --git a/phpBB/phpbb/cron/task/core/tidy_plupload.php b/phpBB/phpbb/cron/task/core/tidy_plupload.php new file mode 100644 index 0000000000..5a98e0bd7b --- /dev/null +++ b/phpBB/phpbb/cron/task/core/tidy_plupload.php @@ -0,0 +1,116 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\cron\task\core; + +/** +* Cron task for cleaning plupload's temporary upload directory. +* +* @package phpBB3 +*/ +class tidy_plupload extends \phpbb\cron\task\base +{ + /** + * How old a file must be (in seconds) before it is deleted. + * @var int + */ + protected $max_file_age = 86400; + + /** + * How often we run the cron (in seconds). + * @var int + */ + protected $cron_frequency = 86400; + + /** + * phpBB root path + * @var string + */ + protected $phpbb_root_path; + + /** + * Config object + * @var \phpbb\config\config + */ + protected $config; + + /** + * Directory where plupload stores temporary files. + * @var string + */ + protected $plupload_upload_path; + + /** + * Constructor. + * + * @param string $phpbb_root_path The root path + * @param \phpbb\config\config $config The config + */ + public function __construct($phpbb_root_path, \phpbb\config\config $config) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->config = $config; + + $this->plupload_upload_path = $this->phpbb_root_path . $this->config['upload_path'] . '/plupload'; + } + + /** + * {@inheritDoc} + */ + public function run() + { + // Remove old temporary file (perhaps failed uploads?) + $last_valid_timestamp = time() - $this->max_file_age; + try + { + $iterator = new \DirectoryIterator($this->plupload_upload_path); + foreach ($iterator as $file) + { + if (strpos($file->getBasename(), $this->config['plupload_salt']) !== 0) + { + // Skip over any non-plupload files. + continue; + } + + if ($file->getMTime() < $last_valid_timestamp) + { + @unlink($file->getPathname()); + } + } + } + catch (\UnexpectedValueException $e) + { + add_log( + 'critical', + 'LOG_PLUPLOAD_TIDY_FAILED', + $this->plupload_upload_path, + $e->getMessage(), + $e->getTraceAsString() + ); + } + + $this->config->set('plupload_last_gc', time(), true); + } + + /** + * {@inheritDoc} + */ + public function is_runnable() + { + return !empty($this->config['plupload_salt']) && is_dir($this->plupload_upload_path); + } + + /** + * {@inheritDoc} + */ + public function should_run() + { + return $this->config['plupload_last_gc'] < time() - $this->cron_frequency; + } +} diff --git a/phpBB/phpbb/cron/task/core/tidy_search.php b/phpBB/phpbb/cron/task/core/tidy_search.php index ebd0d86cbc..eac6aa0a36 100644 --- a/phpBB/phpbb/cron/task/core/tidy_search.php +++ b/phpBB/phpbb/cron/task/core/tidy_search.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task\core; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Tidy search cron task. * * Will only run when the currently selected search backend supports tidying. @@ -40,10 +32,10 @@ class tidy_search extends \phpbb\cron\task\base * @param string $php_ext The PHP extension * @param \phpbb\auth\auth $auth The auth * @param \phpbb\config\config $config The config - * @param \phpbb\db\driver\driver $db The db connection + * @param \phpbb\db\driver\driver_interface $db The db connection * @param \phpbb\user $user The user */ - public function __construct($phpbb_root_path, $php_ext, \phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\user $user) + public function __construct($phpbb_root_path, $php_ext, \phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\user $user) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; diff --git a/phpBB/phpbb/cron/task/core/tidy_sessions.php b/phpBB/phpbb/cron/task/core/tidy_sessions.php index 5df019ae46..68094af1f7 100644 --- a/phpBB/phpbb/cron/task/core/tidy_sessions.php +++ b/phpBB/phpbb/cron/task/core/tidy_sessions.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task\core; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Tidy sessions cron task. * * @package phpBB3 diff --git a/phpBB/phpbb/cron/task/core/tidy_warnings.php b/phpBB/phpbb/cron/task/core/tidy_warnings.php index 1cc0abbe88..a0ff23fc57 100644 --- a/phpBB/phpbb/cron/task/core/tidy_warnings.php +++ b/phpBB/phpbb/cron/task/core/tidy_warnings.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task\core; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Tidy warnings cron task. * * Will only run when warnings are configured to expire. diff --git a/phpBB/phpbb/cron/task/parametrized.php b/phpBB/phpbb/cron/task/parametrized.php index 1d2f449c58..1aeead0399 100644 --- a/phpBB/phpbb/cron/task/parametrized.php +++ b/phpBB/phpbb/cron/task/parametrized.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Parametrized cron task interface. * * Parametrized cron tasks are somewhat of a cross between regular cron tasks and diff --git a/phpBB/phpbb/cron/task/task.php b/phpBB/phpbb/cron/task/task.php index 84218c4fc9..3ce3de9598 100644 --- a/phpBB/phpbb/cron/task/task.php +++ b/phpBB/phpbb/cron/task/task.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Cron task interface * @package phpBB3 */ diff --git a/phpBB/phpbb/cron/task/wrapper.php b/phpBB/phpbb/cron/task/wrapper.php index aa015966c6..fc3f897206 100644 --- a/phpBB/phpbb/cron/task/wrapper.php +++ b/phpBB/phpbb/cron/task/wrapper.php @@ -10,14 +10,6 @@ namespace phpbb\cron\task; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Cron task wrapper class. * Enhances cron tasks with convenience methods that work identically for all tasks. * diff --git a/phpBB/phpbb/datetime.php b/phpBB/phpbb/datetime.php index 84b13202af..dfa21976e0 100644 --- a/phpBB/phpbb/datetime.php +++ b/phpBB/phpbb/datetime.php @@ -74,8 +74,8 @@ class datetime extends \DateTime * finally check that relative dates are supported by the language pack */ if ($delta <= 3600 && $delta > -60 && - ($delta >= -5 || (($now_ts / 60) % 60) == (($timestamp / 60) % 60)) - && isset($this->user->lang['datetime']['AGO'])) + ($delta >= -5 || (($now_ts / 60) % 60) == (($timestamp / 60) % 60)) + && isset($this->user->lang['datetime']['AGO'])) { return $this->user->lang(array('datetime', 'AGO'), max(0, (int) floor($delta / 60))); } diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 53d39e9127..85d160c80e 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -10,18 +10,10 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Database Abstraction Layer * @package dbal */ -class driver +abstract class driver implements driver_interface { var $db_connect_id; var $query_result; @@ -92,7 +84,7 @@ class driver } /** - * return on error or display error message + * {@inheritDoc} */ function sql_return_on_error($fail = false) { @@ -103,7 +95,7 @@ class driver } /** - * Return number of sql queries and cached sql queries used + * {@inheritDoc} */ function sql_num_queries($cached = false) { @@ -111,7 +103,7 @@ class driver } /** - * Add to query count + * {@inheritDoc} */ function sql_add_num_queries($cached = false) { @@ -121,7 +113,7 @@ class driver } /** - * DBAL garbage collection, close sql connection + * {@inheritDoc} */ function sql_close() { @@ -154,8 +146,7 @@ class driver } /** - * Build LIMIT query - * Doing some validation here. + * {@inheritDoc} */ function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) { @@ -172,7 +163,7 @@ class driver } /** - * Fetch all rows + * {@inheritDoc} */ function sql_fetchrowset($query_id = false) { @@ -196,8 +187,7 @@ class driver } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -239,8 +229,7 @@ class driver } /** - * Fetch field - * if rownum is false, the current row is used, else it is pointing to the row (zero-based) + * {@inheritDoc} */ function sql_fetchfield($field, $rownum = false, $query_id = false) { @@ -271,11 +260,7 @@ class driver } /** - * Correctly adjust LIKE expression for special characters - * Some DBMS are handling them in a different way - * - * @param string $expression The expression to use. Every wildcard is escaped, except $this->any_char and $this->one_char - * @return string LIKE expression including the keyword! + * {@inheritDoc} */ function sql_like_expression($expression) { @@ -286,14 +271,7 @@ class driver } /** - * Build a case expression - * - * Note: The two statements action_true and action_false must have the same data type (int, vchar, ...) in the database! - * - * @param string $condition The condition which must be true, to use action_true rather then action_else - * @param string $action_true SQL expression that is used, if the condition is true - * @param string $action_else SQL expression that is used, if the condition is false, optional - * @return string CASE expression including the condition and statements + * {@inheritDoc} */ public function sql_case($condition, $action_true, $action_false = false) { @@ -305,11 +283,7 @@ class driver } /** - * Build a concatenated expression - * - * @param string $expr1 Base SQL expression where we append the second one - * @param string $expr2 SQL expression that is appended to the first expression - * @return string Concatenated string + * {@inheritDoc} */ public function sql_concatenate($expr1, $expr2) { @@ -317,9 +291,7 @@ class driver } /** - * Returns whether results of a query need to be buffered to run a transaction while iterating over them. - * - * @return bool Whether buffering is required. + * {@inheritDoc} */ function sql_buffer_nested_transactions() { @@ -327,15 +299,14 @@ class driver } /** - * SQL Transaction - * @access private + * {@inheritDoc} */ function sql_transaction($status = 'begin') { switch ($status) { case 'begin': - // If we are within a transaction we will not open another one, but enclose the current one to not loose data (prevening auto commit) + // If we are within a transaction we will not open another one, but enclose the current one to not loose data (preventing auto commit) if ($this->transaction) { $this->transactions++; @@ -353,14 +324,16 @@ class driver break; case 'commit': - // If there was a previously opened transaction we do not commit yet... but count back the number of inner transactions + // If there was a previously opened transaction we do not commit yet... + // but count back the number of inner transactions if ($this->transaction && $this->transactions) { $this->transactions--; return true; } - // Check if there is a transaction (no transaction can happen if there was an error, with a combined rollback and error returning enabled) + // Check if there is a transaction (no transaction can happen if + // there was an error, with a combined rollback and error returning enabled) // This implies we have transaction always set for autocommit db's if (!$this->transaction) { @@ -393,11 +366,7 @@ class driver } /** - * Build sql statement from array for insert/update/select statements - * - * Idea for this from Ikonboard - * Possible query values: INSERT, INSERT_SELECT, UPDATE, SELECT - * + * {@inheritDoc} */ function sql_build_array($query, $assoc_ary = false) { @@ -431,7 +400,7 @@ class driver { trigger_error('The MULTI_INSERT query value is no longer supported. Please use sql_multi_insert() instead.', E_USER_ERROR); } - else if ($query == 'UPDATE' || $query == 'SELECT') + else if ($query == 'UPDATE' || $query == 'SELECT' || $query == 'DELETE') { $values = array(); foreach ($assoc_ary as $key => $var) @@ -445,14 +414,7 @@ class driver } /** - * Build IN or NOT IN sql comparison string, uses <> or = on single element - * arrays to improve comparison speed - * - * @access public - * @param string $field name of the sql column that shall be compared - * @param array $array array of values that are allowed (IN) or not allowed (NOT IN) - * @param bool $negate true for NOT IN (), false for IN () (default) - * @param bool $allow_empty_set If true, allow $array to be empty, this function will return 1=1 or 1=0 then. Default to false. + * {@inheritDoc} */ function sql_in_set($field, $array, $negate = false, $allow_empty_set = false) { @@ -497,12 +459,7 @@ class driver } /** - * Run binary AND operator on DB column. - * Results in sql statement: "{$column_name} & (1 << {$bit}) {$compare}" - * - * @param string $column_name The column name to use - * @param int $bit The value to use for the AND operator, will be converted to (1 << $bit). Is used by options, using the number schema... 0, 1, 2...29 - * @param string $compare Any custom SQL code after the check (for example "= 0") + * {@inheritDoc} */ function sql_bit_and($column_name, $bit, $compare = '') { @@ -515,12 +472,7 @@ class driver } /** - * Run binary OR operator on DB column. - * Results in sql statement: "{$column_name} | (1 << {$bit}) {$compare}" - * - * @param string $column_name The column name to use - * @param int $bit The value to use for the OR operator, will be converted to (1 << $bit). Is used by options, using the number schema... 0, 1, 2...29 - * @param string $compare Any custom SQL code after the check (for example "= 0") + * {@inheritDoc} */ function sql_bit_or($column_name, $bit, $compare = '') { @@ -533,10 +485,7 @@ class driver } /** - * Returns SQL string to cast a string expression to an int. - * - * @param string $expression An expression evaluating to string - * @return string Expression returning an int + * {@inheritDoc} */ function cast_expr_to_bigint($expression) { @@ -544,10 +493,7 @@ class driver } /** - * Returns SQL string to cast an integer expression to a string. - * - * @param string $expression An expression evaluating to int - * @return string Expression returning a string + * {@inheritDoc} */ function cast_expr_to_string($expression) { @@ -555,11 +501,7 @@ class driver } /** - * Run LOWER() on DB column of type text (i.e. neither varchar nor char). - * - * @param string $column_name The column name to use - * - * @return string A SQL statement like "LOWER($column_name)" + * {@inheritDoc} */ function sql_lower_text($column_name) { @@ -567,13 +509,7 @@ class driver } /** - * Run more than one insert statement. - * - * @param string $table table name to run the statements on - * @param array $sql_ary multi-dimensional array holding the statement data. - * - * @return bool false if no statements were executed. - * @access public + * {@inheritDoc} */ function sql_multi_insert($table, $sql_ary) { @@ -645,9 +581,7 @@ class driver } /** - * Build sql statement from array for select and select distinct statements - * - * Possible query values: SELECT, SELECT_DISTINCT + * {@inheritDoc} */ function sql_build_query($query, $array) { @@ -750,7 +684,7 @@ class driver } /** - * display sql error page + * {@inheritDoc} */ function sql_error($sql = '') { @@ -820,11 +754,11 @@ class driver } /** - * Explain queries + * {@inheritDoc} */ function sql_report($mode, $query = '') { - global $cache, $starttime, $phpbb_root_path, $phpbb_admin_path, $user; + global $cache, $starttime, $phpbb_root_path, $phpbb_path_helper, $user; global $request; if (is_object($request) && !$request->variable('explain', false)) @@ -854,7 +788,7 @@ class driver <head> <meta charset="utf-8"> <title>SQL Report</title> - <link href="' . htmlspecialchars($phpbb_admin_path) . 'style/admin.css" rel="stylesheet" type="text/css" media="screen" /> + <link href="' . htmlspecialchars($phpbb_path_helper->update_web_root_path($phpbb_root_path) . $phpbb_path_helper->get_adm_relative_path()) . 'style/admin.css" rel="stylesheet" type="text/css" media="screen" /> </head> <body id="errorpage"> <div id="wrap"> @@ -1010,14 +944,7 @@ class driver } /** - * Gets the estimated number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Number of rows in $table_name. - * Prefixed with ~ if estimated (otherwise exact). - * - * @access public + * {@inheritDoc} */ function get_estimated_row_count($table_name) { @@ -1025,13 +952,7 @@ class driver } /** - * Gets the exact number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Exact number of rows in $table_name. - * - * @access public + * {@inheritDoc} */ function get_row_count($table_name) { diff --git a/phpBB/phpbb/db/driver/driver_interface.php b/phpBB/phpbb/db/driver/driver_interface.php new file mode 100644 index 0000000000..a9051616c9 --- /dev/null +++ b/phpBB/phpbb/db/driver/driver_interface.php @@ -0,0 +1,355 @@ +<?php +/** +* +* @package dbal +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\driver; + +interface driver_interface +{ + /** + * Gets the exact number of rows in a specified table. + * + * @param string $table_name Table name + * @return string Exact number of rows in $table_name. + */ + public function get_row_count($table_name); + + /** + * Gets the estimated number of rows in a specified table. + * + * @param string $table_name Table name + * @return string Number of rows in $table_name. + * Prefixed with ~ if estimated (otherwise exact). + */ + public function get_estimated_row_count($table_name); + + /** + * Run LOWER() on DB column of type text (i.e. neither varchar nor char). + * + * @param string $column_name The column name to use + * @return string A SQL statement like "LOWER($column_name)" + */ + public function sql_lower_text($column_name); + + /** + * Display sql error page + * + * @param string $sql The SQL query causing the error + * @return mixed Returns the full error message, if $this->return_on_error + * is set, null otherwise + */ + public function sql_error($sql = ''); + + /** + * Returns whether results of a query need to be buffered to run a + * transaction while iterating over them. + * + * @return bool Whether buffering is required. + */ + public function sql_buffer_nested_transactions(); + + /** + * Run binary OR operator on DB column. + * + * @param string $column_name The column name to use + * @param int $bit The value to use for the OR operator, + * will be converted to (1 << $bit). Is used by options, + * using the number schema... 0, 1, 2...29 + * @param string $compare Any custom SQL code after the check (e.g. "= 0") + * @return string A SQL statement like "$column | (1 << $bit) {$compare}" + */ + public function sql_bit_or($column_name, $bit, $compare = ''); + + /** + * Version information about used database + * + * @param bool $raw Only return the fetched sql_server_version + * @param bool $use_cache Is it safe to retrieve the value from the cache + * @return string sql server version + */ + public function sql_server_info($raw = false, $use_cache = true); + + /** + * Return on error or display error message + * + * @param bool $fail Should we return on errors, or stop + * @return null + */ + public function sql_return_on_error($fail = false); + + /** + * Build sql statement from an array + * + * @param string $query Should be on of the following strings: + * INSERT, INSERT_SELECT, UPDATE, SELECT, DELETE + * @param array $assoc_ary Array with "column => value" pairs + * @return string A SQL statement like "c1 = 'a' AND c2 = 'b'" + */ + public function sql_build_array($query, $assoc_ary = array()); + + /** + * Fetch all rows + * + * @param mixed $query_id Already executed query to get the rows from, + * if false, the last query will be used. + * @return mixed Nested array if the query had rows, false otherwise + */ + public function sql_fetchrowset($query_id = false); + + /** + * SQL Transaction + * + * @param string $status Should be one of the following strings: + * begin, commit, rollback + * @return mixed Buffered, seekable result handle, false on error + */ + public function sql_transaction($status = 'begin'); + + /** + * Build a concatenated expression + * + * @param string $expr1 Base SQL expression where we append the second one + * @param string $expr2 SQL expression that is appended to the first expression + * @return string Concatenated string + */ + public function sql_concatenate($expr1, $expr2); + + /** + * Build a case expression + * + * Note: The two statements action_true and action_false must have the same + * data type (int, vchar, ...) in the database! + * + * @param string $condition The condition which must be true, + * to use action_true rather then action_else + * @param string $action_true SQL expression that is used, if the condition is true + * @param mixed $action_false SQL expression that is used, if the condition is false + * @return string CASE expression including the condition and statements + */ + public function sql_case($condition, $action_true, $action_false = false); + + /** + * Build sql statement from array for select and select distinct statements + * + * Possible query values: SELECT, SELECT_DISTINCT + * + * @param string $query Should be one of: SELECT, SELECT_DISTINCT + * @param array $array Array with the query data: + * SELECT A comma imploded list of columns to select + * FROM Array with "table => alias" pairs, + * (alias can also be an array) + * Optional: LEFT_JOIN Array of join entries: + * FROM Table that should be joined + * ON Condition for the join + * Optional: WHERE Where SQL statement + * Optional: GROUP_BY Group by SQL statement + * Optional: ORDER_BY Order by SQL statement + * @return string A SQL statement ready for execution + */ + public function sql_build_query($query, $array); + + /** + * Fetch field + * if rownum is false, the current row is used, else it is pointing to the row (zero-based) + * + * @param string $field Name of the column + * @param mixed $rownum Row number, if false the current row will be used + * and the row curser will point to the next row + * Note: $rownum is 0 based + * @param mixed $query_id Already executed query to get the rows from, + * if false, the last query will be used. + * @return mixed String value of the field in the selected row, + * false, if the row does not exist + */ + public function sql_fetchfield($field, $rownum = false, $query_id = false); + + /** + * Fetch current row + * + * @param mixed $query_id Already executed query to get the rows from, + * if false, the last query will be used. + * @return mixed Array with the current row, + * false, if the row does not exist + */ + public function sql_fetchrow($query_id = false); + + /** + * Returns SQL string to cast a string expression to an int. + * + * @param string $expression An expression evaluating to string + * @return string Expression returning an int + */ + public function cast_expr_to_bigint($expression); + + /** + * Get last inserted id after insert statement + * + * @return string Autoincrement value of the last inserted row + */ + public function sql_nextid(); + + /** + * Add to query count + * + * @param bool $cached Is this query cached? + * @return null + */ + public function sql_add_num_queries($cached = false); + + /** + * Build LIMIT query + * + * @param string $query The SQL query to execute + * @param int $total The number of rows to select + * @param int $offset + * @param int $cache_ttl Either 0 to avoid caching or + * the time in seconds which the result shall be kept in cache + * @return mixed Buffered, seekable result handle, false on error + */ + public function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0); + + /** + * Base query method + * + * @param string $query The SQL query to execute + * @param int $cache_ttl Either 0 to avoid caching or + * the time in seconds which the result shall be kept in cache + * @return mixed Buffered, seekable result handle, false on error + */ + public function sql_query($query = '', $cache_ttl = 0); + + /** + * Returns SQL string to cast an integer expression to a string. + * + * @param string $expression An expression evaluating to int + * @return string Expression returning a string + */ + public function cast_expr_to_string($expression); + + /** + * Connect to server + * + * @param string $sqlserver Address of the database server + * @param string $sqluser User name of the SQL user + * @param string $sqlpassword Password of the SQL user + * @param string $database Name of the database + * @param mixed $port Port of the database server + * @param bool $persistency + * @param bool $new_link Should a new connection be established + * @return mixed Connection ID on success, string error message otherwise + */ + public function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false); + + /** + * Run binary AND operator on DB column. + * Results in sql statement: "{$column_name} & (1 << {$bit}) {$compare}" + * + * @param string $column_name The column name to use + * @param int $bit The value to use for the AND operator, + * will be converted to (1 << $bit). Is used by + * options, using the number schema: 0, 1, 2...29 + * @param string $compare Any custom SQL code after the check (for example "= 0") + * @return string A SQL statement like: "{$column} & (1 << {$bit}) {$compare}" + */ + public function sql_bit_and($column_name, $bit, $compare = ''); + + /** + * Free sql result + * + * @param mixed $query_id Already executed query result, + * if false, the last query will be used. + * @return null + */ + public function sql_freeresult($query_id = false); + + /** + * Return number of sql queries and cached sql queries used + * + * @param bool $cached Should we return the number of cached or normal queries? + * @return int Number of queries that have been executed + */ + public function sql_num_queries($cached = false); + + /** + * Run more than one insert statement. + * + * @param string $table Table name to run the statements on + * @param array $sql_ary Multi-dimensional array holding the statement data + * @return bool false if no statements were executed. + */ + public function sql_multi_insert($table, $sql_ary); + + /** + * Return number of affected rows + * + * @return mixed Number of the affected rows by the last query + * false if no query has been run before + */ + public function sql_affectedrows(); + + /** + * DBAL garbage collection, close SQL connection + * + * @return mixed False if no connection was opened before, + * Server response otherwise + */ + public function sql_close(); + + /** + * Seek to given row number + * + * @param mixed $rownum Row number the curser should point to + * Note: $rownum is 0 based + * @param mixed $query_id ID of the query to set the row cursor on + * if false, the last query will be used. + * $query_id will then be set correctly + * @return bool False if something went wrong + */ + public function sql_rowseek($rownum, &$query_id); + + /** + * Escape string used in sql query + * + * @param string $msg String to be escaped + * @return string Escaped version of $msg + */ + public function sql_escape($msg); + + /** + * Correctly adjust LIKE expression for special characters + * Some DBMS are handling them in a different way + * + * @param string $expression The expression to use. Every wildcard is + * escaped, except $this->any_char and $this->one_char + * @return string A SQL statement like: "LIKE 'bertie_%'" + */ + public function sql_like_expression($expression); + + /** + * Explain queries + * + * @param string $mode Available modes: display, start, stop, + * add_select_row, fromcache, record_fromcache + * @param string $query The Query that should be explained + * @return mixed Either a full HTML page, boolean or null + */ + public function sql_report($mode, $query = ''); + + /** + * Build IN or NOT IN sql comparison string, uses <> or = on single element + * arrays to improve comparison speed + * + * @param string $field Name of the sql column that shall be compared + * @param array $array Array of values that are (not) allowed + * @param bool $negate true for NOT IN (), false for IN () + * @param bool $allow_empty_set If true, allow $array to be empty, + * this function will return 1=1 or 1=0 then. + * @return string A SQL statement like: "IN (1, 2, 3, 4)" or "= 1" + */ + public function sql_in_set($field, $array, $negate = false, $allow_empty_set = false); +} diff --git a/phpBB/phpbb/db/driver/firebird.php b/phpBB/phpbb/db/driver/firebird.php index 2df5eaf369..a4967c7ffe 100644 --- a/phpBB/phpbb/db/driver/firebird.php +++ b/phpBB/phpbb/db/driver/firebird.php @@ -10,14 +10,6 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Firebird/Interbase Database Abstraction Layer * Minimum Requirement is Firebird 2.1 * @package dbal @@ -30,7 +22,7 @@ class firebird extends \phpbb\db\driver\driver var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -87,10 +79,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache forced to false for Interbase - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -135,13 +124,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -305,7 +288,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -321,7 +304,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -359,7 +342,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -387,7 +370,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -398,7 +381,7 @@ class firebird extends \phpbb\db\driver\driver $query_id = $this->query_result; } - if ($cache && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } @@ -413,7 +396,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { @@ -449,7 +432,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * @inheritdoc + * {@inheritDoc} */ function cast_expr_to_bigint($expression) { @@ -458,7 +441,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * @inheritdoc + * {@inheritDoc} */ function cast_expr_to_string($expression) { diff --git a/phpBB/phpbb/db/driver/mssql.php b/phpBB/phpbb/db/driver/mssql.php index 4d2cd287da..588cd7a7e8 100644 --- a/phpBB/phpbb/db/driver/mssql.php +++ b/phpBB/phpbb/db/driver/mssql.php @@ -10,14 +10,6 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * MSSQL Database Abstraction Layer * Minimum Requirement is MSSQL 2000+ * @package dbal @@ -27,7 +19,7 @@ class mssql extends \phpbb\db\driver\driver var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -63,10 +55,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -132,13 +121,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -223,7 +206,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -231,7 +214,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -259,7 +242,7 @@ class mssql extends \phpbb\db\driver\driver { foreach ($row as $key => $value) { - $row[$key] = ($value === ' ' || $value === NULL) ? '' : $value; + $row[$key] = ($value === ' ' || $value === null) ? '' : $value; } } @@ -267,8 +250,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -288,7 +270,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -307,7 +289,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -318,14 +300,14 @@ class mssql extends \phpbb\db\driver\driver $query_id = $this->query_result; } - if ($cache && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } - if (isset($this->open_queries[$query_id])) + if (isset($this->open_queries[(int) $query_id])) { - unset($this->open_queries[$query_id]); + unset($this->open_queries[(int) $query_id]); return @mssql_free_result($query_id); } @@ -333,7 +315,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { diff --git a/phpBB/phpbb/db/driver/mssql_base.php b/phpBB/phpbb/db/driver/mssql_base.php index 57c4e0f1fd..1e3fb8235a 100644 --- a/phpBB/phpbb/db/driver/mssql_base.php +++ b/phpBB/phpbb/db/driver/mssql_base.php @@ -10,14 +10,6 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * MSSQL Database Base Abstraction Layer * @package dbal */ @@ -32,7 +24,7 @@ abstract class mssql_base extends \phpbb\db\driver\driver } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { diff --git a/phpBB/phpbb/db/driver/mssql_odbc.php b/phpBB/phpbb/db/driver/mssql_odbc.php index 9db34a69fb..34b913dc8a 100644 --- a/phpBB/phpbb/db/driver/mssql_odbc.php +++ b/phpBB/phpbb/db/driver/mssql_odbc.php @@ -10,14 +10,6 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Unified ODBC functions * Unified ODBC functions support any database having ODBC driver, for example Adabas D, IBM DB2, iODBC, Solid, Sybase SQL Anywhere... * Here we only support MSSQL Server 2000+ because of the provided schema @@ -34,7 +26,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -91,10 +83,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -152,13 +141,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -244,7 +227,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -252,8 +235,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Fetch current row - * @note number of bytes returned depends on odbc.defaultlrl php.ini setting. If it is limited to 4K for example only 4K of data is returned max. + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -273,7 +255,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -294,7 +276,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -305,7 +287,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base $query_id = $this->query_result; } - if ($cache && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } diff --git a/phpBB/phpbb/db/driver/mssqlnative.php b/phpBB/phpbb/db/driver/mssqlnative.php index e6002fe1a3..b449de2ae4 100644 --- a/phpBB/phpbb/db/driver/mssqlnative.php +++ b/phpBB/phpbb/db/driver/mssqlnative.php @@ -14,194 +14,17 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** - * Prior to version 1.1 the SQL Server Native PHP driver didn't support sqlsrv_num_rows, or cursor based seeking so we recall all rows into an array - * and maintain our own cursor index into that array. - */ -class result_mssqlnative -{ - public function result_mssqlnative($queryresult = false) - { - $this->m_cursor = 0; - $this->m_rows = array(); - $this->m_num_fields = sqlsrv_num_fields($queryresult); - $this->m_field_meta = sqlsrv_field_metadata($queryresult); - - while ($row = sqlsrv_fetch_array($queryresult, SQLSRV_FETCH_ASSOC)) - { - if ($row !== null) - { - foreach($row as $k => $v) - { - if (is_object($v) && method_exists($v, 'format')) - { - $row[$k] = $v->format("Y-m-d\TH:i:s\Z"); - } - } - $this->m_rows[] = $row;//read results into memory, cursors are not supported - } - } - - $this->m_row_count = sizeof($this->m_rows); - } - - private function array_to_obj($array, &$obj) - { - foreach ($array as $key => $value) - { - if (is_array($value)) - { - $obj->$key = new \stdClass(); - array_to_obj($value, $obj->$key); - } - else - { - $obj->$key = $value; - } - } - return $obj; - } - - public function fetch($mode = SQLSRV_FETCH_BOTH, $object_class = 'stdClass') - { - if ($this->m_cursor >= $this->m_row_count || $this->m_row_count == 0) - { - return false; - } - - $ret = false; - $arr_num = array(); - - if ($mode == SQLSRV_FETCH_NUMERIC || $mode == SQLSRV_FETCH_BOTH) - { - foreach($this->m_rows[$this->m_cursor] as $key => $value) - { - $arr_num[] = $value; - } - } - - switch ($mode) - { - case SQLSRV_FETCH_ASSOC: - $ret = $this->m_rows[$this->m_cursor]; - break; - case SQLSRV_FETCH_NUMERIC: - $ret = $arr_num; - break; - case 'OBJECT': - $ret = $this->array_to_obj($this->m_rows[$this->m_cursor], $o = new $object_class); - break; - case SQLSRV_FETCH_BOTH: - default: - $ret = $this->m_rows[$this->m_cursor] + $arr_num; - break; - } - $this->m_cursor++; - return $ret; - } - - public function get($pos, $fld) - { - return $this->m_rows[$pos][$fld]; - } - - public function num_rows() - { - return $this->m_row_count; - } - - public function seek($iRow) - { - $this->m_cursor = min($iRow, $this->m_row_count); - } - - public function num_fields() - { - return $this->m_num_fields; - } - - public function field_name($nr) - { - $arr_keys = array_keys($this->m_rows[0]); - return $arr_keys[$nr]; - } - - public function field_type($nr) - { - $i = 0; - $int_type = -1; - $str_type = ''; - - foreach ($this->m_field_meta as $meta) - { - if ($nr == $i) - { - $int_type = $meta['Type']; - break; - } - $i++; - } - - //http://msdn.microsoft.com/en-us/library/cc296183.aspx contains type table - switch ($int_type) - { - case SQLSRV_SQLTYPE_BIGINT: $str_type = 'bigint'; break; - case SQLSRV_SQLTYPE_BINARY: $str_type = 'binary'; break; - case SQLSRV_SQLTYPE_BIT: $str_type = 'bit'; break; - case SQLSRV_SQLTYPE_CHAR: $str_type = 'char'; break; - case SQLSRV_SQLTYPE_DATETIME: $str_type = 'datetime'; break; - case SQLSRV_SQLTYPE_DECIMAL/*($precision, $scale)*/: $str_type = 'decimal'; break; - case SQLSRV_SQLTYPE_FLOAT: $str_type = 'float'; break; - case SQLSRV_SQLTYPE_IMAGE: $str_type = 'image'; break; - case SQLSRV_SQLTYPE_INT: $str_type = 'int'; break; - case SQLSRV_SQLTYPE_MONEY: $str_type = 'money'; break; - case SQLSRV_SQLTYPE_NCHAR/*($charCount)*/: $str_type = 'nchar'; break; - case SQLSRV_SQLTYPE_NUMERIC/*($precision, $scale)*/: $str_type = 'numeric'; break; - case SQLSRV_SQLTYPE_NVARCHAR/*($charCount)*/: $str_type = 'nvarchar'; break; - case SQLSRV_SQLTYPE_NTEXT: $str_type = 'ntext'; break; - case SQLSRV_SQLTYPE_REAL: $str_type = 'real'; break; - case SQLSRV_SQLTYPE_SMALLDATETIME: $str_type = 'smalldatetime'; break; - case SQLSRV_SQLTYPE_SMALLINT: $str_type = 'smallint'; break; - case SQLSRV_SQLTYPE_SMALLMONEY: $str_type = 'smallmoney'; break; - case SQLSRV_SQLTYPE_TEXT: $str_type = 'text'; break; - case SQLSRV_SQLTYPE_TIMESTAMP: $str_type = 'timestamp'; break; - case SQLSRV_SQLTYPE_TINYINT: $str_type = 'tinyint'; break; - case SQLSRV_SQLTYPE_UNIQUEIDENTIFIER: $str_type = 'uniqueidentifier'; break; - case SQLSRV_SQLTYPE_UDT: $str_type = 'UDT'; break; - case SQLSRV_SQLTYPE_VARBINARY/*($byteCount)*/: $str_type = 'varbinary'; break; - case SQLSRV_SQLTYPE_VARCHAR/*($charCount)*/: $str_type = 'varchar'; break; - case SQLSRV_SQLTYPE_XML: $str_type = 'xml'; break; - default: $str_type = $int_type; - } - return $str_type; - } - - public function free() - { - unset($this->m_rows); - return; - } -} - -/** * @package dbal */ class mssqlnative extends \phpbb\db\driver\mssql_base { - var $m_insert_id = NULL; + var $m_insert_id = null; var $last_query_text = ''; var $query_options = array(); var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -230,10 +53,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -290,13 +110,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -392,7 +206,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -400,7 +214,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -427,7 +241,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base { foreach ($row as $key => $value) { - $row[$key] = ($value === ' ' || $value === NULL) ? '' : $value; + $row[$key] = ($value === ' ' || $value === null) ? '' : $value; } // remove helper values from LIMIT queries @@ -440,7 +254,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -460,7 +274,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -471,7 +285,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base $query_id = $this->query_result; } - if ($cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } @@ -481,6 +295,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base unset($this->open_queries[(int) $query_id]); return @sqlsrv_free_stmt($query_id); } + return false; } diff --git a/phpBB/phpbb/db/driver/mysql.php b/phpBB/phpbb/db/driver/mysql.php index c76126763d..1a4fd364df 100644 --- a/phpBB/phpbb/db/driver/mysql.php +++ b/phpBB/phpbb/db/driver/mysql.php @@ -10,14 +10,6 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * MySQL4 Database Abstraction Layer * Compatible with: * MySQL 3.23+ @@ -32,8 +24,7 @@ class mysql extends \phpbb\db\driver\mysql_base var $connect_error = ''; /** - * Connect to server - * @access public + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -111,10 +102,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -162,13 +150,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -221,7 +203,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -229,7 +211,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -249,8 +231,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -270,7 +251,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -278,7 +259,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -289,7 +270,7 @@ class mysql extends \phpbb\db\driver\mysql_base $query_id = $this->query_result; } - if ($cache && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } @@ -304,7 +285,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { diff --git a/phpBB/phpbb/db/driver/mysql_base.php b/phpBB/phpbb/db/driver/mysql_base.php index 8f2f66674b..d0f6a9e8fa 100644 --- a/phpBB/phpbb/db/driver/mysql_base.php +++ b/phpBB/phpbb/db/driver/mysql_base.php @@ -10,14 +10,6 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Abstract MySQL Database Base Abstraction Layer * @package dbal */ @@ -51,14 +43,7 @@ abstract class mysql_base extends \phpbb\db\driver\driver } /** - * Gets the estimated number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Number of rows in $table_name. - * Prefixed with ~ if estimated (otherwise exact). - * - * @access public + * {@inheritDoc} */ function get_estimated_row_count($table_name) { @@ -80,13 +65,7 @@ abstract class mysql_base extends \phpbb\db\driver\driver } /** - * Gets the exact number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Exact number of rows in $table_name. - * - * @access public + * {@inheritDoc} */ function get_row_count($table_name) { diff --git a/phpBB/phpbb/db/driver/mysqli.php b/phpBB/phpbb/db/driver/mysqli.php index 4d0e43b464..6814599b24 100644 --- a/phpBB/phpbb/db/driver/mysqli.php +++ b/phpBB/phpbb/db/driver/mysqli.php @@ -10,14 +10,6 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * MySQLi Database Abstraction Layer * mysqli-extension has to be compiled with: * MySQL 4.1+ or MySQL 5.0+ @@ -29,9 +21,9 @@ class mysqli extends \phpbb\db\driver\mysql_base var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ - function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false , $new_link = false) + function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { if (!function_exists('mysqli_connect')) { @@ -47,11 +39,11 @@ class mysqli extends \phpbb\db\driver\mysql_base $this->server = ($this->persistency) ? 'p:' . (($sqlserver) ? $sqlserver : 'localhost') : $sqlserver; $this->dbname = $database; - $port = (!$port) ? NULL : $port; + $port = (!$port) ? null : $port; // If port is set and it is not numeric, most likely mysqli socket is set. // Try to map it to the $socket parameter. - $socket = NULL; + $socket = null; if ($port) { if (is_numeric($port)) @@ -61,7 +53,7 @@ class mysqli extends \phpbb\db\driver\mysql_base else { $socket = $port; - $port = NULL; + $port = null; } } @@ -104,10 +96,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -159,13 +148,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -213,7 +196,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -221,7 +204,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -247,8 +230,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -268,7 +250,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -276,7 +258,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -296,7 +278,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { diff --git a/phpBB/phpbb/db/driver/oracle.php b/phpBB/phpbb/db/driver/oracle.php index 5dfab21455..8a304b5042 100644 --- a/phpBB/phpbb/db/driver/oracle.php +++ b/phpBB/phpbb/db/driver/oracle.php @@ -10,14 +10,6 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Oracle Database Abstraction Layer * @package dbal */ @@ -27,7 +19,7 @@ class oracle extends \phpbb\db\driver\driver var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -80,10 +72,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache forced to false for Oracle - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -248,13 +237,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -481,7 +464,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -489,7 +472,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -540,8 +523,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -578,7 +560,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -610,7 +592,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -621,7 +603,7 @@ class oracle extends \phpbb\db\driver\driver $query_id = $this->query_result; } - if ($cache && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } @@ -636,7 +618,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { diff --git a/phpBB/phpbb/db/driver/postgres.php b/phpBB/phpbb/db/driver/postgres.php index 7a98b90c73..9e091f0a5d 100644 --- a/phpBB/phpbb/db/driver/postgres.php +++ b/phpBB/phpbb/db/driver/postgres.php @@ -10,14 +10,6 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * PostgreSQL Database Abstraction Layer * Minimum Requirement is Version 7.3+ * @package dbal @@ -28,7 +20,7 @@ class postgres extends \phpbb\db\driver\driver var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -123,10 +115,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -174,13 +163,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -261,7 +244,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -269,7 +252,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -289,8 +272,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -310,7 +292,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -328,7 +310,7 @@ class postgres extends \phpbb\db\driver\driver return false; } - $temp_result = @pg_fetch_assoc($temp_q_id, NULL); + $temp_result = @pg_fetch_assoc($temp_q_id, null); @pg_free_result($query_id); return ($temp_result) ? $temp_result['last_value'] : false; @@ -339,7 +321,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -350,7 +332,7 @@ class postgres extends \phpbb\db\driver\driver $query_id = $this->query_result; } - if ($cache && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } @@ -365,8 +347,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Escape string used in sql query - * Note: Do not use for bytea values if we may use them at a later stage + * {@inheritDoc} */ function sql_escape($msg) { @@ -383,7 +364,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * @inheritdoc + * {@inheritDoc} */ function cast_expr_to_bigint($expression) { @@ -391,7 +372,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * @inheritdoc + * {@inheritDoc} */ function cast_expr_to_string($expression) { @@ -456,7 +437,7 @@ class postgres extends \phpbb\db\driver\driver if ($result = @pg_query($this->db_connect_id, "EXPLAIN $explain_query")) { - while ($row = @pg_fetch_assoc($result, NULL)) + while ($row = @pg_fetch_assoc($result, null)) { $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); } @@ -476,7 +457,7 @@ class postgres extends \phpbb\db\driver\driver $endtime = $endtime[0] + $endtime[1]; $result = @pg_query($this->db_connect_id, $query); - while ($void = @pg_fetch_assoc($result, NULL)) + while ($void = @pg_fetch_assoc($result, null)) { // Take the time spent on parsing rows into account } diff --git a/phpBB/phpbb/db/driver/sqlite.php b/phpBB/phpbb/db/driver/sqlite.php index a548fd2618..86a585f4eb 100644 --- a/phpBB/phpbb/db/driver/sqlite.php +++ b/phpBB/phpbb/db/driver/sqlite.php @@ -10,14 +10,6 @@ namespace phpbb\db\driver; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Sqlite Database Abstraction Layer * Minimum Requirement: 2.8.2+ * @package dbal @@ -27,7 +19,7 @@ class sqlite extends \phpbb\db\driver\driver var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -66,10 +58,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache if true, it is safe to retrieve the stored value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -116,13 +105,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -193,7 +176,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -201,7 +184,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -221,8 +204,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -242,7 +224,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -250,7 +232,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -261,7 +243,7 @@ class sqlite extends \phpbb\db\driver\driver $query_id = $this->query_result; } - if ($cache && $cache->sql_exists($query_id)) + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) { return $cache->sql_freeresult($query_id); } @@ -270,7 +252,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { @@ -278,7 +260,8 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Correctly adjust LIKE expression for special characters + * {@inheritDoc} + * * For SQLite an underscore is a not-known character... this may change with SQLite3 */ function sql_like_expression($expression) diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_0.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_0.php new file mode 100644 index 0000000000..41ade22a29 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_0.php @@ -0,0 +1,1177 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v30x; + +class release_3_0_0 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.0.0', '>='); + } + + public function update_schema() + { + return array( + 'add_tables' => array( + $this->table_prefix . 'attachments' => array( + 'COLUMNS' => array( + 'attach_id' => array('UINT', NULL, 'auto_increment'), + 'post_msg_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + 'in_message' => array('BOOL', 0), + 'poster_id' => array('UINT', 0), + 'is_orphan' => array('BOOL', 1), + 'physical_filename' => array('VCHAR', ''), + 'real_filename' => array('VCHAR', ''), + 'download_count' => array('UINT', 0), + 'attach_comment' => array('TEXT_UNI', ''), + 'extension' => array('VCHAR:100', ''), + 'mimetype' => array('VCHAR:100', ''), + 'filesize' => array('UINT:20', 0), + 'filetime' => array('TIMESTAMP', 0), + 'thumbnail' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => 'attach_id', + 'KEYS' => array( + 'filetime' => array('INDEX', 'filetime'), + 'post_msg_id' => array('INDEX', 'post_msg_id'), + 'topic_id' => array('INDEX', 'topic_id'), + 'poster_id' => array('INDEX', 'poster_id'), + 'is_orphan' => array('INDEX', 'is_orphan'), + ), + ), + + $this->table_prefix . 'acl_groups' => array( + 'COLUMNS' => array( + 'group_id' => array('UINT', 0), + 'forum_id' => array('UINT', 0), + 'auth_option_id' => array('UINT', 0), + 'auth_role_id' => array('UINT', 0), + 'auth_setting' => array('TINT:2', 0), + ), + 'KEYS' => array( + 'group_id' => array('INDEX', 'group_id'), + 'auth_opt_id' => array('INDEX', 'auth_option_id'), + 'auth_role_id' => array('INDEX', 'auth_role_id'), + ), + ), + + $this->table_prefix . 'acl_options' => array( + 'COLUMNS' => array( + 'auth_option_id' => array('UINT', NULL, 'auto_increment'), + 'auth_option' => array('VCHAR:50', ''), + 'is_global' => array('BOOL', 0), + 'is_local' => array('BOOL', 0), + 'founder_only' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => 'auth_option_id', + 'KEYS' => array( + 'auth_option' => array('INDEX', 'auth_option'), + ), + ), + + $this->table_prefix . 'acl_roles' => array( + 'COLUMNS' => array( + 'role_id' => array('UINT', NULL, 'auto_increment'), + 'role_name' => array('VCHAR_UNI', ''), + 'role_description' => array('TEXT_UNI', ''), + 'role_type' => array('VCHAR:10', ''), + 'role_order' => array('USINT', 0), + ), + 'PRIMARY_KEY' => 'role_id', + 'KEYS' => array( + 'role_type' => array('INDEX', 'role_type'), + 'role_order' => array('INDEX', 'role_order'), + ), + ), + + $this->table_prefix . 'acl_roles_data' => array( + 'COLUMNS' => array( + 'role_id' => array('UINT', 0), + 'auth_option_id' => array('UINT', 0), + 'auth_setting' => array('TINT:2', 0), + ), + 'PRIMARY_KEY' => array('role_id', 'auth_option_id'), + 'KEYS' => array( + 'ath_op_id' => array('INDEX', 'auth_option_id'), + ), + ), + + $this->table_prefix . 'acl_users' => array( + 'COLUMNS' => array( + 'user_id' => array('UINT', 0), + 'forum_id' => array('UINT', 0), + 'auth_option_id' => array('UINT', 0), + 'auth_role_id' => array('UINT', 0), + 'auth_setting' => array('TINT:2', 0), + ), + 'KEYS' => array( + 'user_id' => array('INDEX', 'user_id'), + 'auth_option_id' => array('INDEX', 'auth_option_id'), + 'auth_role_id' => array('INDEX', 'auth_role_id'), + ), + ), + + $this->table_prefix . 'banlist' => array( + 'COLUMNS' => array( + 'ban_id' => array('UINT', NULL, 'auto_increment'), + 'ban_userid' => array('UINT', 0), + 'ban_ip' => array('VCHAR:40', ''), + 'ban_email' => array('VCHAR_UNI:100', ''), + 'ban_start' => array('TIMESTAMP', 0), + 'ban_end' => array('TIMESTAMP', 0), + 'ban_exclude' => array('BOOL', 0), + 'ban_reason' => array('VCHAR_UNI', ''), + 'ban_give_reason' => array('VCHAR_UNI', ''), + ), + 'PRIMARY_KEY' => 'ban_id', + 'KEYS' => array( + 'ban_end' => array('INDEX', 'ban_end'), + 'ban_user' => array('INDEX', array('ban_userid', 'ban_exclude')), + 'ban_email' => array('INDEX', array('ban_email', 'ban_exclude')), + 'ban_ip' => array('INDEX', array('ban_ip', 'ban_exclude')), + ), + ), + + $this->table_prefix . 'bbcodes' => array( + 'COLUMNS' => array( + 'bbcode_id' => array('TINT:3', 0), + 'bbcode_tag' => array('VCHAR:16', ''), + 'bbcode_helpline' => array('VCHAR_UNI', ''), + 'display_on_posting' => array('BOOL', 0), + 'bbcode_match' => array('TEXT_UNI', ''), + 'bbcode_tpl' => array('MTEXT_UNI', ''), + 'first_pass_match' => array('MTEXT_UNI', ''), + 'first_pass_replace' => array('MTEXT_UNI', ''), + 'second_pass_match' => array('MTEXT_UNI', ''), + 'second_pass_replace' => array('MTEXT_UNI', ''), + ), + 'PRIMARY_KEY' => 'bbcode_id', + 'KEYS' => array( + 'display_on_post' => array('INDEX', 'display_on_posting'), + ), + ), + + $this->table_prefix . 'bookmarks' => array( + 'COLUMNS' => array( + 'topic_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + ), + 'PRIMARY_KEY' => array('topic_id', 'user_id'), + ), + + $this->table_prefix . 'bots' => array( + 'COLUMNS' => array( + 'bot_id' => array('UINT', NULL, 'auto_increment'), + 'bot_active' => array('BOOL', 1), + 'bot_name' => array('STEXT_UNI', ''), + 'user_id' => array('UINT', 0), + 'bot_agent' => array('VCHAR', ''), + 'bot_ip' => array('VCHAR', ''), + ), + 'PRIMARY_KEY' => 'bot_id', + 'KEYS' => array( + 'bot_active' => array('INDEX', 'bot_active'), + ), + ), + + $this->table_prefix . 'config' => array( + 'COLUMNS' => array( + 'config_name' => array('VCHAR', ''), + 'config_value' => array('VCHAR_UNI', ''), + 'is_dynamic' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => 'config_name', + 'KEYS' => array( + 'is_dynamic' => array('INDEX', 'is_dynamic'), + ), + ), + + $this->table_prefix . 'confirm' => array( + 'COLUMNS' => array( + 'confirm_id' => array('CHAR:32', ''), + 'session_id' => array('CHAR:32', ''), + 'confirm_type' => array('TINT:3', 0), + 'code' => array('VCHAR:8', ''), + 'seed' => array('UINT:10', 0), + ), + 'PRIMARY_KEY' => array('session_id', 'confirm_id'), + 'KEYS' => array( + 'confirm_type' => array('INDEX', 'confirm_type'), + ), + ), + + $this->table_prefix . 'disallow' => array( + 'COLUMNS' => array( + 'disallow_id' => array('UINT', NULL, 'auto_increment'), + 'disallow_username' => array('VCHAR_UNI:255', ''), + ), + 'PRIMARY_KEY' => 'disallow_id', + ), + + $this->table_prefix . 'drafts' => array( + 'COLUMNS' => array( + 'draft_id' => array('UINT', NULL, 'auto_increment'), + 'user_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + 'forum_id' => array('UINT', 0), + 'save_time' => array('TIMESTAMP', 0), + 'draft_subject' => array('XSTEXT_UNI', ''), + 'draft_message' => array('MTEXT_UNI', ''), + ), + 'PRIMARY_KEY' => 'draft_id', + 'KEYS' => array( + 'save_time' => array('INDEX', 'save_time'), + ), + ), + + $this->table_prefix . 'extensions' => array( + 'COLUMNS' => array( + 'extension_id' => array('UINT', NULL, 'auto_increment'), + 'group_id' => array('UINT', 0), + 'extension' => array('VCHAR:100', ''), + ), + 'PRIMARY_KEY' => 'extension_id', + ), + + $this->table_prefix . 'extension_groups' => array( + 'COLUMNS' => array( + 'group_id' => array('UINT', NULL, 'auto_increment'), + 'group_name' => array('VCHAR_UNI', ''), + 'cat_id' => array('TINT:2', 0), + 'allow_group' => array('BOOL', 0), + 'download_mode' => array('BOOL', 1), + 'upload_icon' => array('VCHAR', ''), + 'max_filesize' => array('UINT:20', 0), + 'allowed_forums' => array('TEXT', ''), + 'allow_in_pm' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => 'group_id', + ), + + $this->table_prefix . 'forums' => array( + 'COLUMNS' => array( + 'forum_id' => array('UINT', NULL, 'auto_increment'), + 'parent_id' => array('UINT', 0), + 'left_id' => array('UINT', 0), + 'right_id' => array('UINT', 0), + 'forum_parents' => array('MTEXT', ''), + 'forum_name' => array('STEXT_UNI', ''), + 'forum_desc' => array('TEXT_UNI', ''), + 'forum_desc_bitfield' => array('VCHAR:255', ''), + 'forum_desc_options' => array('UINT:11', 7), + 'forum_desc_uid' => array('VCHAR:8', ''), + 'forum_link' => array('VCHAR_UNI', ''), + 'forum_password' => array('VCHAR_UNI:40', ''), + 'forum_style' => array('USINT', 0), + 'forum_image' => array('VCHAR', ''), + 'forum_rules' => array('TEXT_UNI', ''), + 'forum_rules_link' => array('VCHAR_UNI', ''), + 'forum_rules_bitfield' => array('VCHAR:255', ''), + 'forum_rules_options' => array('UINT:11', 7), + 'forum_rules_uid' => array('VCHAR:8', ''), + 'forum_topics_per_page' => array('TINT:4', 0), + 'forum_type' => array('TINT:4', 0), + 'forum_status' => array('TINT:4', 0), + 'forum_posts' => array('UINT', 0), + 'forum_topics' => array('UINT', 0), + 'forum_topics_real' => array('UINT', 0), + 'forum_last_post_id' => array('UINT', 0), + 'forum_last_poster_id' => array('UINT', 0), + 'forum_last_post_subject' => array('XSTEXT_UNI', ''), + 'forum_last_post_time' => array('TIMESTAMP', 0), + 'forum_last_poster_name'=> array('VCHAR_UNI', ''), + 'forum_last_poster_colour'=> array('VCHAR:6', ''), + 'forum_flags' => array('TINT:4', 32), + 'display_on_index' => array('BOOL', 1), + 'enable_indexing' => array('BOOL', 1), + 'enable_icons' => array('BOOL', 1), + 'enable_prune' => array('BOOL', 0), + 'prune_next' => array('TIMESTAMP', 0), + 'prune_days' => array('UINT', 0), + 'prune_viewed' => array('UINT', 0), + 'prune_freq' => array('UINT', 0), + ), + 'PRIMARY_KEY' => 'forum_id', + 'KEYS' => array( + 'left_right_id' => array('INDEX', array('left_id', 'right_id')), + 'forum_lastpost_id' => array('INDEX', 'forum_last_post_id'), + ), + ), + + $this->table_prefix . 'forums_access' => array( + 'COLUMNS' => array( + 'forum_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'session_id' => array('CHAR:32', ''), + ), + 'PRIMARY_KEY' => array('forum_id', 'user_id', 'session_id'), + ), + + $this->table_prefix . 'forums_track' => array( + 'COLUMNS' => array( + 'user_id' => array('UINT', 0), + 'forum_id' => array('UINT', 0), + 'mark_time' => array('TIMESTAMP', 0), + ), + 'PRIMARY_KEY' => array('user_id', 'forum_id'), + ), + + $this->table_prefix . 'forums_watch' => array( + 'COLUMNS' => array( + 'forum_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'notify_status' => array('BOOL', 0), + ), + 'KEYS' => array( + 'forum_id' => array('INDEX', 'forum_id'), + 'user_id' => array('INDEX', 'user_id'), + 'notify_stat' => array('INDEX', 'notify_status'), + ), + ), + + $this->table_prefix . 'groups' => array( + 'COLUMNS' => array( + 'group_id' => array('UINT', NULL, 'auto_increment'), + 'group_type' => array('TINT:4', 1), + 'group_founder_manage' => array('BOOL', 0), + 'group_name' => array('VCHAR_CI', ''), + 'group_desc' => array('TEXT_UNI', ''), + 'group_desc_bitfield' => array('VCHAR:255', ''), + 'group_desc_options' => array('UINT:11', 7), + 'group_desc_uid' => array('VCHAR:8', ''), + 'group_display' => array('BOOL', 0), + 'group_avatar' => array('VCHAR', ''), + 'group_avatar_type' => array('TINT:2', 0), + 'group_avatar_width' => array('USINT', 0), + 'group_avatar_height' => array('USINT', 0), + 'group_rank' => array('UINT', 0), + 'group_colour' => array('VCHAR:6', ''), + 'group_sig_chars' => array('UINT', 0), + 'group_receive_pm' => array('BOOL', 0), + 'group_message_limit' => array('UINT', 0), + 'group_legend' => array('BOOL', 1), + ), + 'PRIMARY_KEY' => 'group_id', + 'KEYS' => array( + 'group_legend' => array('INDEX', 'group_legend'), + ), + ), + + $this->table_prefix . 'icons' => array( + 'COLUMNS' => array( + 'icons_id' => array('UINT', NULL, 'auto_increment'), + 'icons_url' => array('VCHAR', ''), + 'icons_width' => array('TINT:4', 0), + 'icons_height' => array('TINT:4', 0), + 'icons_order' => array('UINT', 0), + 'display_on_posting' => array('BOOL', 1), + ), + 'PRIMARY_KEY' => 'icons_id', + 'KEYS' => array( + 'display_on_posting' => array('INDEX', 'display_on_posting'), + ), + ), + + $this->table_prefix . 'lang' => array( + 'COLUMNS' => array( + 'lang_id' => array('TINT:4', NULL, 'auto_increment'), + 'lang_iso' => array('VCHAR:30', ''), + 'lang_dir' => array('VCHAR:30', ''), + 'lang_english_name' => array('VCHAR_UNI:100', ''), + 'lang_local_name' => array('VCHAR_UNI:255', ''), + 'lang_author' => array('VCHAR_UNI:255', ''), + ), + 'PRIMARY_KEY' => 'lang_id', + 'KEYS' => array( + 'lang_iso' => array('INDEX', 'lang_iso'), + ), + ), + + $this->table_prefix . 'log' => array( + 'COLUMNS' => array( + 'log_id' => array('UINT', NULL, 'auto_increment'), + 'log_type' => array('TINT:4', 0), + 'user_id' => array('UINT', 0), + 'forum_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + 'reportee_id' => array('UINT', 0), + 'log_ip' => array('VCHAR:40', ''), + 'log_time' => array('TIMESTAMP', 0), + 'log_operation' => array('TEXT_UNI', ''), + 'log_data' => array('MTEXT_UNI', ''), + ), + 'PRIMARY_KEY' => 'log_id', + 'KEYS' => array( + 'log_type' => array('INDEX', 'log_type'), + 'forum_id' => array('INDEX', 'forum_id'), + 'topic_id' => array('INDEX', 'topic_id'), + 'reportee_id' => array('INDEX', 'reportee_id'), + 'user_id' => array('INDEX', 'user_id'), + ), + ), + + $this->table_prefix . 'moderator_cache' => array( + 'COLUMNS' => array( + 'forum_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'username' => array('VCHAR_UNI:255', ''), + 'group_id' => array('UINT', 0), + 'group_name' => array('VCHAR_UNI', ''), + 'display_on_index' => array('BOOL', 1), + ), + 'KEYS' => array( + 'disp_idx' => array('INDEX', 'display_on_index'), + 'forum_id' => array('INDEX', 'forum_id'), + ), + ), + + $this->table_prefix . 'modules' => array( + 'COLUMNS' => array( + 'module_id' => array('UINT', NULL, 'auto_increment'), + 'module_enabled' => array('BOOL', 1), + 'module_display' => array('BOOL', 1), + 'module_basename' => array('VCHAR', ''), + 'module_class' => array('VCHAR:10', ''), + 'parent_id' => array('UINT', 0), + 'left_id' => array('UINT', 0), + 'right_id' => array('UINT', 0), + 'module_langname' => array('VCHAR', ''), + 'module_mode' => array('VCHAR', ''), + 'module_auth' => array('VCHAR', ''), + ), + 'PRIMARY_KEY' => 'module_id', + 'KEYS' => array( + 'left_right_id' => array('INDEX', array('left_id', 'right_id')), + 'module_enabled' => array('INDEX', 'module_enabled'), + 'class_left_id' => array('INDEX', array('module_class', 'left_id')), + ), + ), + + $this->table_prefix . 'poll_options' => array( + 'COLUMNS' => array( + 'poll_option_id' => array('TINT:4', 0), + 'topic_id' => array('UINT', 0), + 'poll_option_text' => array('TEXT_UNI', ''), + 'poll_option_total' => array('UINT', 0), + ), + 'KEYS' => array( + 'poll_opt_id' => array('INDEX', 'poll_option_id'), + 'topic_id' => array('INDEX', 'topic_id'), + ), + ), + + $this->table_prefix . 'poll_votes' => array( + 'COLUMNS' => array( + 'topic_id' => array('UINT', 0), + 'poll_option_id' => array('TINT:4', 0), + 'vote_user_id' => array('UINT', 0), + 'vote_user_ip' => array('VCHAR:40', ''), + ), + 'KEYS' => array( + 'topic_id' => array('INDEX', 'topic_id'), + 'vote_user_id' => array('INDEX', 'vote_user_id'), + 'vote_user_ip' => array('INDEX', 'vote_user_ip'), + ), + ), + + $this->table_prefix . 'posts' => array( + 'COLUMNS' => array( + 'post_id' => array('UINT', NULL, 'auto_increment'), + 'topic_id' => array('UINT', 0), + 'forum_id' => array('UINT', 0), + 'poster_id' => array('UINT', 0), + 'icon_id' => array('UINT', 0), + 'poster_ip' => array('VCHAR:40', ''), + 'post_time' => array('TIMESTAMP', 0), + 'post_approved' => array('BOOL', 1), + 'post_reported' => array('BOOL', 0), + 'enable_bbcode' => array('BOOL', 1), + 'enable_smilies' => array('BOOL', 1), + 'enable_magic_url' => array('BOOL', 1), + 'enable_sig' => array('BOOL', 1), + 'post_username' => array('VCHAR_UNI:255', ''), + 'post_subject' => array('XSTEXT_UNI', '', 'true_sort'), + 'post_text' => array('MTEXT_UNI', ''), + 'post_checksum' => array('VCHAR:32', ''), + 'post_attachment' => array('BOOL', 0), + 'bbcode_bitfield' => array('VCHAR:255', ''), + 'bbcode_uid' => array('VCHAR:8', ''), + 'post_postcount' => array('BOOL', 1), + 'post_edit_time' => array('TIMESTAMP', 0), + 'post_edit_reason' => array('STEXT_UNI', ''), + 'post_edit_user' => array('UINT', 0), + 'post_edit_count' => array('USINT', 0), + 'post_edit_locked' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => 'post_id', + 'KEYS' => array( + 'forum_id' => array('INDEX', 'forum_id'), + 'topic_id' => array('INDEX', 'topic_id'), + 'poster_ip' => array('INDEX', 'poster_ip'), + 'poster_id' => array('INDEX', 'poster_id'), + 'post_approved' => array('INDEX', 'post_approved'), + 'tid_post_time' => array('INDEX', array('topic_id', 'post_time')), + ), + ), + + $this->table_prefix . 'privmsgs' => array( + 'COLUMNS' => array( + 'msg_id' => array('UINT', NULL, 'auto_increment'), + 'root_level' => array('UINT', 0), + 'author_id' => array('UINT', 0), + 'icon_id' => array('UINT', 0), + 'author_ip' => array('VCHAR:40', ''), + 'message_time' => array('TIMESTAMP', 0), + 'enable_bbcode' => array('BOOL', 1), + 'enable_smilies' => array('BOOL', 1), + 'enable_magic_url' => array('BOOL', 1), + 'enable_sig' => array('BOOL', 1), + 'message_subject' => array('XSTEXT_UNI', ''), + 'message_text' => array('MTEXT_UNI', ''), + 'message_edit_reason' => array('STEXT_UNI', ''), + 'message_edit_user' => array('UINT', 0), + 'message_attachment' => array('BOOL', 0), + 'bbcode_bitfield' => array('VCHAR:255', ''), + 'bbcode_uid' => array('VCHAR:8', ''), + 'message_edit_time' => array('TIMESTAMP', 0), + 'message_edit_count' => array('USINT', 0), + 'to_address' => array('TEXT_UNI', ''), + 'bcc_address' => array('TEXT_UNI', ''), + ), + 'PRIMARY_KEY' => 'msg_id', + 'KEYS' => array( + 'author_ip' => array('INDEX', 'author_ip'), + 'message_time' => array('INDEX', 'message_time'), + 'author_id' => array('INDEX', 'author_id'), + 'root_level' => array('INDEX', 'root_level'), + ), + ), + + $this->table_prefix . 'privmsgs_folder' => array( + 'COLUMNS' => array( + 'folder_id' => array('UINT', NULL, 'auto_increment'), + 'user_id' => array('UINT', 0), + 'folder_name' => array('VCHAR_UNI', ''), + 'pm_count' => array('UINT', 0), + ), + 'PRIMARY_KEY' => 'folder_id', + 'KEYS' => array( + 'user_id' => array('INDEX', 'user_id'), + ), + ), + + $this->table_prefix . 'privmsgs_rules' => array( + 'COLUMNS' => array( + 'rule_id' => array('UINT', NULL, 'auto_increment'), + 'user_id' => array('UINT', 0), + 'rule_check' => array('UINT', 0), + 'rule_connection' => array('UINT', 0), + 'rule_string' => array('VCHAR_UNI', ''), + 'rule_user_id' => array('UINT', 0), + 'rule_group_id' => array('UINT', 0), + 'rule_action' => array('UINT', 0), + 'rule_folder_id' => array('INT:11', 0), + ), + 'PRIMARY_KEY' => 'rule_id', + 'KEYS' => array( + 'user_id' => array('INDEX', 'user_id'), + ), + ), + + $this->table_prefix . 'privmsgs_to' => array( + 'COLUMNS' => array( + 'msg_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'author_id' => array('UINT', 0), + 'pm_deleted' => array('BOOL', 0), + 'pm_new' => array('BOOL', 1), + 'pm_unread' => array('BOOL', 1), + 'pm_replied' => array('BOOL', 0), + 'pm_marked' => array('BOOL', 0), + 'pm_forwarded' => array('BOOL', 0), + 'folder_id' => array('INT:11', 0), + ), + 'KEYS' => array( + 'msg_id' => array('INDEX', 'msg_id'), + 'author_id' => array('INDEX', 'author_id'), + 'usr_flder_id' => array('INDEX', array('user_id', 'folder_id')), + ), + ), + + $this->table_prefix . 'profile_fields' => array( + 'COLUMNS' => array( + 'field_id' => array('UINT', NULL, 'auto_increment'), + 'field_name' => array('VCHAR_UNI', ''), + 'field_type' => array('TINT:4', 0), + 'field_ident' => array('VCHAR:20', ''), + 'field_length' => array('VCHAR:20', ''), + 'field_minlen' => array('VCHAR', ''), + 'field_maxlen' => array('VCHAR', ''), + 'field_novalue' => array('VCHAR_UNI', ''), + 'field_default_value' => array('VCHAR_UNI', ''), + 'field_validation' => array('VCHAR_UNI:20', ''), + 'field_required' => array('BOOL', 0), + 'field_show_on_reg' => array('BOOL', 0), + 'field_hide' => array('BOOL', 0), + 'field_no_view' => array('BOOL', 0), + 'field_active' => array('BOOL', 0), + 'field_order' => array('UINT', 0), + ), + 'PRIMARY_KEY' => 'field_id', + 'KEYS' => array( + 'fld_type' => array('INDEX', 'field_type'), + 'fld_ordr' => array('INDEX', 'field_order'), + ), + ), + + $this->table_prefix . 'profile_fields_data' => array( + 'COLUMNS' => array( + 'user_id' => array('UINT', 0), + ), + 'PRIMARY_KEY' => 'user_id', + ), + + $this->table_prefix . 'profile_fields_lang' => array( + 'COLUMNS' => array( + 'field_id' => array('UINT', 0), + 'lang_id' => array('UINT', 0), + 'option_id' => array('UINT', 0), + 'field_type' => array('TINT:4', 0), + 'lang_value' => array('VCHAR_UNI', ''), + ), + 'PRIMARY_KEY' => array('field_id', 'lang_id', 'option_id'), + ), + + $this->table_prefix . 'profile_lang' => array( + 'COLUMNS' => array( + 'field_id' => array('UINT', 0), + 'lang_id' => array('UINT', 0), + 'lang_name' => array('VCHAR_UNI', ''), + 'lang_explain' => array('TEXT_UNI', ''), + 'lang_default_value' => array('VCHAR_UNI', ''), + ), + 'PRIMARY_KEY' => array('field_id', 'lang_id'), + ), + + $this->table_prefix . 'ranks' => array( + 'COLUMNS' => array( + 'rank_id' => array('UINT', NULL, 'auto_increment'), + 'rank_title' => array('VCHAR_UNI', ''), + 'rank_min' => array('UINT', 0), + 'rank_special' => array('BOOL', 0), + 'rank_image' => array('VCHAR', ''), + ), + 'PRIMARY_KEY' => 'rank_id', + ), + + $this->table_prefix . 'reports' => array( + 'COLUMNS' => array( + 'report_id' => array('UINT', NULL, 'auto_increment'), + 'reason_id' => array('USINT', 0), + 'post_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'user_notify' => array('BOOL', 0), + 'report_closed' => array('BOOL', 0), + 'report_time' => array('TIMESTAMP', 0), + 'report_text' => array('MTEXT_UNI', ''), + ), + 'PRIMARY_KEY' => 'report_id', + ), + + $this->table_prefix . 'reports_reasons' => array( + 'COLUMNS' => array( + 'reason_id' => array('USINT', NULL, 'auto_increment'), + 'reason_title' => array('VCHAR_UNI', ''), + 'reason_description' => array('MTEXT_UNI', ''), + 'reason_order' => array('USINT', 0), + ), + 'PRIMARY_KEY' => 'reason_id', + ), + + $this->table_prefix . 'search_results' => array( + 'COLUMNS' => array( + 'search_key' => array('VCHAR:32', ''), + 'search_time' => array('TIMESTAMP', 0), + 'search_keywords' => array('MTEXT_UNI', ''), + 'search_authors' => array('MTEXT', ''), + ), + 'PRIMARY_KEY' => 'search_key', + ), + + $this->table_prefix . 'search_wordlist' => array( + 'COLUMNS' => array( + 'word_id' => array('UINT', NULL, 'auto_increment'), + 'word_text' => array('VCHAR_UNI', ''), + 'word_common' => array('BOOL', 0), + 'word_count' => array('UINT', 0), + ), + 'PRIMARY_KEY' => 'word_id', + 'KEYS' => array( + 'wrd_txt' => array('UNIQUE', 'word_text'), + 'wrd_cnt' => array('INDEX', 'word_count'), + ), + ), + + $this->table_prefix . 'search_wordmatch' => array( + 'COLUMNS' => array( + 'post_id' => array('UINT', 0), + 'word_id' => array('UINT', 0), + 'title_match' => array('BOOL', 0), + ), + 'KEYS' => array( + 'unq_mtch' => array('UNIQUE', array('word_id', 'post_id', 'title_match')), + 'word_id' => array('INDEX', 'word_id'), + 'post_id' => array('INDEX', 'post_id'), + ), + ), + + $this->table_prefix . 'sessions' => array( + 'COLUMNS' => array( + 'session_id' => array('CHAR:32', ''), + 'session_user_id' => array('UINT', 0), + 'session_last_visit' => array('TIMESTAMP', 0), + 'session_start' => array('TIMESTAMP', 0), + 'session_time' => array('TIMESTAMP', 0), + 'session_ip' => array('VCHAR:40', ''), + 'session_browser' => array('VCHAR:150', ''), + 'session_forwarded_for' => array('VCHAR:255', ''), + 'session_page' => array('VCHAR_UNI', ''), + 'session_viewonline' => array('BOOL', 1), + 'session_autologin' => array('BOOL', 0), + 'session_admin' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => 'session_id', + 'KEYS' => array( + 'session_time' => array('INDEX', 'session_time'), + 'session_user_id' => array('INDEX', 'session_user_id'), + ), + ), + + $this->table_prefix . 'sessions_keys' => array( + 'COLUMNS' => array( + 'key_id' => array('CHAR:32', ''), + 'user_id' => array('UINT', 0), + 'last_ip' => array('VCHAR:40', ''), + 'last_login' => array('TIMESTAMP', 0), + ), + 'PRIMARY_KEY' => array('key_id', 'user_id'), + 'KEYS' => array( + 'last_login' => array('INDEX', 'last_login'), + ), + ), + + $this->table_prefix . 'sitelist' => array( + 'COLUMNS' => array( + 'site_id' => array('UINT', NULL, 'auto_increment'), + 'site_ip' => array('VCHAR:40', ''), + 'site_hostname' => array('VCHAR', ''), + 'ip_exclude' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => 'site_id', + ), + + $this->table_prefix . 'smilies' => array( + 'COLUMNS' => array( + 'smiley_id' => array('UINT', NULL, 'auto_increment'), +// We may want to set 'code' to VCHAR:50 or check if unicode support is possible... at the moment only ASCII characters are allowed. + 'code' => array('VCHAR_UNI:50', ''), + 'emotion' => array('VCHAR_UNI:50', ''), + 'smiley_url' => array('VCHAR:50', ''), + 'smiley_width' => array('USINT', 0), + 'smiley_height' => array('USINT', 0), + 'smiley_order' => array('UINT', 0), + 'display_on_posting'=> array('BOOL', 1), + ), + 'PRIMARY_KEY' => 'smiley_id', + 'KEYS' => array( + 'display_on_post' => array('INDEX', 'display_on_posting'), + ), + ), + + $this->table_prefix . 'styles' => array( + 'COLUMNS' => array( + 'style_id' => array('USINT', NULL, 'auto_increment'), + 'style_name' => array('VCHAR_UNI:255', ''), + 'style_copyright' => array('VCHAR_UNI', ''), + 'style_active' => array('BOOL', 1), + 'template_id' => array('USINT', 0), + 'theme_id' => array('USINT', 0), + 'imageset_id' => array('USINT', 0), + ), + 'PRIMARY_KEY' => 'style_id', + 'KEYS' => array( + 'style_name' => array('UNIQUE', 'style_name'), + 'template_id' => array('INDEX', 'template_id'), + 'theme_id' => array('INDEX', 'theme_id'), + 'imageset_id' => array('INDEX', 'imageset_id'), + ), + ), + + $this->table_prefix . 'styles_template' => array( + 'COLUMNS' => array( + 'template_id' => array('USINT', NULL, 'auto_increment'), + 'template_name' => array('VCHAR_UNI:255', ''), + 'template_copyright' => array('VCHAR_UNI', ''), + 'template_path' => array('VCHAR:100', ''), + 'bbcode_bitfield' => array('VCHAR:255', 'kNg='), + 'template_storedb' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => 'template_id', + 'KEYS' => array( + 'tmplte_nm' => array('UNIQUE', 'template_name'), + ), + ), + + $this->table_prefix . 'styles_template_data' => array( + 'COLUMNS' => array( + 'template_id' => array('USINT', 0), + 'template_filename' => array('VCHAR:100', ''), + 'template_included' => array('TEXT', ''), + 'template_mtime' => array('TIMESTAMP', 0), + 'template_data' => array('MTEXT_UNI', ''), + ), + 'KEYS' => array( + 'tid' => array('INDEX', 'template_id'), + 'tfn' => array('INDEX', 'template_filename'), + ), + ), + + $this->table_prefix . 'styles_theme' => array( + 'COLUMNS' => array( + 'theme_id' => array('USINT', NULL, 'auto_increment'), + 'theme_name' => array('VCHAR_UNI:255', ''), + 'theme_copyright' => array('VCHAR_UNI', ''), + 'theme_path' => array('VCHAR:100', ''), + 'theme_storedb' => array('BOOL', 0), + 'theme_mtime' => array('TIMESTAMP', 0), + 'theme_data' => array('MTEXT_UNI', ''), + ), + 'PRIMARY_KEY' => 'theme_id', + 'KEYS' => array( + 'theme_name' => array('UNIQUE', 'theme_name'), + ), + ), + + $this->table_prefix . 'styles_imageset' => array( + 'COLUMNS' => array( + 'imageset_id' => array('USINT', NULL, 'auto_increment'), + 'imageset_name' => array('VCHAR_UNI:255', ''), + 'imageset_copyright' => array('VCHAR_UNI', ''), + 'imageset_path' => array('VCHAR:100', ''), + ), + 'PRIMARY_KEY' => 'imageset_id', + 'KEYS' => array( + 'imgset_nm' => array('UNIQUE', 'imageset_name'), + ), + ), + + $this->table_prefix . 'styles_imageset_data' => array( + 'COLUMNS' => array( + 'image_id' => array('USINT', NULL, 'auto_increment'), + 'image_name' => array('VCHAR:200', ''), + 'image_filename' => array('VCHAR:200', ''), + 'image_lang' => array('VCHAR:30', ''), + 'image_height' => array('USINT', 0), + 'image_width' => array('USINT', 0), + 'imageset_id' => array('USINT', 0), + ), + 'PRIMARY_KEY' => 'image_id', + 'KEYS' => array( + 'i_d' => array('INDEX', 'imageset_id'), + ), + ), + + $this->table_prefix . 'topics' => array( + 'COLUMNS' => array( + 'topic_id' => array('UINT', NULL, 'auto_increment'), + 'forum_id' => array('UINT', 0), + 'icon_id' => array('UINT', 0), + 'topic_attachment' => array('BOOL', 0), + 'topic_approved' => array('BOOL', 1), + 'topic_reported' => array('BOOL', 0), + 'topic_title' => array('XSTEXT_UNI', '', 'true_sort'), + 'topic_poster' => array('UINT', 0), + 'topic_time' => array('TIMESTAMP', 0), + 'topic_time_limit' => array('TIMESTAMP', 0), + 'topic_views' => array('UINT', 0), + 'topic_replies' => array('UINT', 0), + 'topic_replies_real' => array('UINT', 0), + 'topic_status' => array('TINT:3', 0), + 'topic_type' => array('TINT:3', 0), + 'topic_first_post_id' => array('UINT', 0), + 'topic_first_poster_name' => array('VCHAR_UNI', ''), + 'topic_first_poster_colour' => array('VCHAR:6', ''), + 'topic_last_post_id' => array('UINT', 0), + 'topic_last_poster_id' => array('UINT', 0), + 'topic_last_poster_name' => array('VCHAR_UNI', ''), + 'topic_last_poster_colour' => array('VCHAR:6', ''), + 'topic_last_post_subject' => array('XSTEXT_UNI', ''), + 'topic_last_post_time' => array('TIMESTAMP', 0), + 'topic_last_view_time' => array('TIMESTAMP', 0), + 'topic_moved_id' => array('UINT', 0), + 'topic_bumped' => array('BOOL', 0), + 'topic_bumper' => array('UINT', 0), + 'poll_title' => array('STEXT_UNI', ''), + 'poll_start' => array('TIMESTAMP', 0), + 'poll_length' => array('TIMESTAMP', 0), + 'poll_max_options' => array('TINT:4', 1), + 'poll_last_vote' => array('TIMESTAMP', 0), + 'poll_vote_change' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => 'topic_id', + 'KEYS' => array( + 'forum_id' => array('INDEX', 'forum_id'), + 'forum_id_type' => array('INDEX', array('forum_id', 'topic_type')), + 'last_post_time' => array('INDEX', 'topic_last_post_time'), + 'topic_approved' => array('INDEX', 'topic_approved'), + 'forum_appr_last' => array('INDEX', array('forum_id', 'topic_approved', 'topic_last_post_id')), + 'fid_time_moved' => array('INDEX', array('forum_id', 'topic_last_post_time', 'topic_moved_id')), + ), + ), + + $this->table_prefix . 'topics_track' => array( + 'COLUMNS' => array( + 'user_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + 'forum_id' => array('UINT', 0), + 'mark_time' => array('TIMESTAMP', 0), + ), + 'PRIMARY_KEY' => array('user_id', 'topic_id'), + 'KEYS' => array( + 'forum_id' => array('INDEX', 'forum_id'), + ), + ), + + $this->table_prefix . 'topics_posted' => array( + 'COLUMNS' => array( + 'user_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + 'topic_posted' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => array('user_id', 'topic_id'), + ), + + $this->table_prefix . 'topics_watch' => array( + 'COLUMNS' => array( + 'topic_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'notify_status' => array('BOOL', 0), + ), + 'KEYS' => array( + 'topic_id' => array('INDEX', 'topic_id'), + 'user_id' => array('INDEX', 'user_id'), + 'notify_stat' => array('INDEX', 'notify_status'), + ), + ), + + $this->table_prefix . 'user_group' => array( + 'COLUMNS' => array( + 'group_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'group_leader' => array('BOOL', 0), + 'user_pending' => array('BOOL', 1), + ), + 'KEYS' => array( + 'group_id' => array('INDEX', 'group_id'), + 'user_id' => array('INDEX', 'user_id'), + 'group_leader' => array('INDEX', 'group_leader'), + ), + ), + + $this->table_prefix . 'users' => array( + 'COLUMNS' => array( + 'user_id' => array('UINT', NULL, 'auto_increment'), + 'user_type' => array('TINT:2', 0), + 'group_id' => array('UINT', 3), + 'user_permissions' => array('MTEXT', ''), + 'user_perm_from' => array('UINT', 0), + 'user_ip' => array('VCHAR:40', ''), + 'user_regdate' => array('TIMESTAMP', 0), + 'username' => array('VCHAR_CI', ''), + 'username_clean' => array('VCHAR_CI', ''), + 'user_password' => array('VCHAR_UNI:40', ''), + 'user_passchg' => array('TIMESTAMP', 0), + 'user_pass_convert' => array('BOOL', 0), + 'user_email' => array('VCHAR_UNI:100', ''), + 'user_email_hash' => array('BINT', 0), + 'user_birthday' => array('VCHAR:10', ''), + 'user_lastvisit' => array('TIMESTAMP', 0), + 'user_lastmark' => array('TIMESTAMP', 0), + 'user_lastpost_time' => array('TIMESTAMP', 0), + 'user_lastpage' => array('VCHAR_UNI:200', ''), + 'user_last_confirm_key' => array('VCHAR:10', ''), + 'user_last_search' => array('TIMESTAMP', 0), + 'user_warnings' => array('TINT:4', 0), + 'user_last_warning' => array('TIMESTAMP', 0), + 'user_login_attempts' => array('TINT:4', 0), + 'user_inactive_reason' => array('TINT:2', 0), + 'user_inactive_time' => array('TIMESTAMP', 0), + 'user_posts' => array('UINT', 0), + 'user_lang' => array('VCHAR:30', ''), + 'user_timezone' => array('DECIMAL', 0), + 'user_dst' => array('BOOL', 0), + 'user_dateformat' => array('VCHAR_UNI:30', 'd M Y H:i'), + 'user_style' => array('USINT', 0), + 'user_rank' => array('UINT', 0), + 'user_colour' => array('VCHAR:6', ''), + 'user_new_privmsg' => array('INT:4', 0), + 'user_unread_privmsg' => array('INT:4', 0), + 'user_last_privmsg' => array('TIMESTAMP', 0), + 'user_message_rules' => array('BOOL', 0), + 'user_full_folder' => array('INT:11', -3), + 'user_emailtime' => array('TIMESTAMP', 0), + 'user_topic_show_days' => array('USINT', 0), + 'user_topic_sortby_type' => array('VCHAR:1', 't'), + 'user_topic_sortby_dir' => array('VCHAR:1', 'd'), + 'user_post_show_days' => array('USINT', 0), + 'user_post_sortby_type' => array('VCHAR:1', 't'), + 'user_post_sortby_dir' => array('VCHAR:1', 'a'), + 'user_notify' => array('BOOL', 0), + 'user_notify_pm' => array('BOOL', 1), + 'user_notify_type' => array('TINT:4', 0), + 'user_allow_pm' => array('BOOL', 1), + 'user_allow_viewonline' => array('BOOL', 1), + 'user_allow_viewemail' => array('BOOL', 1), + 'user_allow_massemail' => array('BOOL', 1), + 'user_options' => array('UINT:11', 895), + 'user_avatar' => array('VCHAR', ''), + 'user_avatar_type' => array('TINT:2', 0), + 'user_avatar_width' => array('USINT', 0), + 'user_avatar_height' => array('USINT', 0), + 'user_sig' => array('MTEXT_UNI', ''), + 'user_sig_bbcode_uid' => array('VCHAR:8', ''), + 'user_sig_bbcode_bitfield' => array('VCHAR:255', ''), + 'user_from' => array('VCHAR_UNI:100', ''), + 'user_icq' => array('VCHAR:15', ''), + 'user_aim' => array('VCHAR_UNI', ''), + 'user_yim' => array('VCHAR_UNI', ''), + 'user_msnm' => array('VCHAR_UNI', ''), + 'user_jabber' => array('VCHAR_UNI', ''), + 'user_website' => array('VCHAR_UNI:200', ''), + 'user_occ' => array('TEXT_UNI', ''), + 'user_interests' => array('TEXT_UNI', ''), + 'user_actkey' => array('VCHAR:32', ''), + 'user_newpasswd' => array('VCHAR_UNI:40', ''), + 'user_form_salt' => array('VCHAR_UNI:32', ''), + + ), + 'PRIMARY_KEY' => 'user_id', + 'KEYS' => array( + 'user_birthday' => array('INDEX', 'user_birthday'), + 'user_email_hash' => array('INDEX', 'user_email_hash'), + 'user_type' => array('INDEX', 'user_type'), + 'username_clean' => array('UNIQUE', 'username_clean'), + ), + ), + + $this->table_prefix . 'warnings' => array( + 'COLUMNS' => array( + 'warning_id' => array('UINT', NULL, 'auto_increment'), + 'user_id' => array('UINT', 0), + 'post_id' => array('UINT', 0), + 'log_id' => array('UINT', 0), + 'warning_time' => array('TIMESTAMP', 0), + ), + 'PRIMARY_KEY' => 'warning_id', + ), + + $this->table_prefix . 'words' => array( + 'COLUMNS' => array( + 'word_id' => array('UINT', NULL, 'auto_increment'), + 'word' => array('VCHAR_UNI', ''), + 'replacement' => array('VCHAR_UNI', ''), + ), + 'PRIMARY_KEY' => 'word_id', + ), + + $this->table_prefix . 'zebra' => array( + 'COLUMNS' => array( + 'user_id' => array('UINT', 0), + 'zebra_id' => array('UINT', 0), + 'friend' => array('BOOL', 0), + 'foe' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => array('user_id', 'zebra_id'), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_tables' => array( + $this->table_prefix . 'attachments', + $this->table_prefix . 'acl_groups', + $this->table_prefix . 'acl_options', + $this->table_prefix . 'acl_roles', + $this->table_prefix . 'acl_roles_data', + $this->table_prefix . 'acl_users', + $this->table_prefix . 'banlist', + $this->table_prefix . 'bbcodes', + $this->table_prefix . 'bookmarks', + $this->table_prefix . 'bots', + $this->table_prefix . 'config', + $this->table_prefix . 'confirm', + $this->table_prefix . 'disallow', + $this->table_prefix . 'drafts', + $this->table_prefix . 'extensions', + $this->table_prefix . 'extension_groups', + $this->table_prefix . 'forums', + $this->table_prefix . 'forums_access', + $this->table_prefix . 'forums_track', + $this->table_prefix . 'forums_watch', + $this->table_prefix . 'groups', + $this->table_prefix . 'icons', + $this->table_prefix . 'lang', + $this->table_prefix . 'log', + $this->table_prefix . 'moderator_cache', + $this->table_prefix . 'modules', + $this->table_prefix . 'poll_options', + $this->table_prefix . 'poll_votes', + $this->table_prefix . 'posts', + $this->table_prefix . 'privmsgs', + $this->table_prefix . 'privmsgs_folder', + $this->table_prefix . 'privmsgs_rules', + $this->table_prefix . 'privmsgs_to', + $this->table_prefix . 'profile_fields', + $this->table_prefix . 'profile_fields_data', + $this->table_prefix . 'profile_fields_lang', + $this->table_prefix . 'profile_lang', + $this->table_prefix . 'ranks', + $this->table_prefix . 'reports', + $this->table_prefix . 'reports_reasons', + $this->table_prefix . 'search_results', + $this->table_prefix . 'search_wordlist', + $this->table_prefix . 'search_wordmatch', + $this->table_prefix . 'sessions', + $this->table_prefix . 'sessions_keys', + $this->table_prefix . 'sitelist', + $this->table_prefix . 'smilies', + $this->table_prefix . 'styles', + $this->table_prefix . 'styles_template', + $this->table_prefix . 'styles_template_data', + $this->table_prefix . 'styles_theme', + $this->table_prefix . 'styles_imageset', + $this->table_prefix . 'styles_imageset_data', + $this->table_prefix . 'topics', + $this->table_prefix . 'topics_track', + $this->table_prefix . 'topics_posted', + $this->table_prefix . 'topics_watch', + $this->table_prefix . 'user_group', + $this->table_prefix . 'users', + $this->table_prefix . 'warnings', + $this->table_prefix . 'words', + $this->table_prefix . 'zebra', + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php index aed0f2784b..2b65bb0185 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php index 305309c3bd..d6f3029f7e 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php index fb50d67fb5..0ee2a46a00 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php index 63ba1e8fc2..e676571a15 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php index 7055063032..d2656397a2 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php index 1246597efb..6b7c9735fa 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php index 7e284235e1..91ffae2f05 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php index 017038855d..55290dcbcf 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php new file mode 100644 index 0000000000..c4bf3a30ef --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php @@ -0,0 +1,33 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v30x; + +class release_3_0_12 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.0.12', '>=') && phpbb_version_compare($this->config['version'], '3.1.0-dev', '<'); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v30x\release_3_0_12_rc3'); + } + + public function update_data() + { + return array( + array('if', array( + phpbb_version_compare($this->config['version'], '3.0.12', '<'), + array('config.update', array('version', '3.0.12')), + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php index 35a3015959..ab8463cc73 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php new file mode 100644 index 0000000000..f41f20954a --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php @@ -0,0 +1,33 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v30x; + +class release_3_0_12_rc2 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.0.12-RC2', '>=') && phpbb_version_compare($this->config['version'], '3.1.0-dev', '<'); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v30x\release_3_0_12_rc1'); + } + + public function update_data() + { + return array( + array('if', array( + phpbb_version_compare($this->config['version'], '3.0.12-RC2', '<'), + array('config.update', array('version', '3.0.12-RC2')), + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php new file mode 100644 index 0000000000..9171ceb26f --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php @@ -0,0 +1,33 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v30x; + +class release_3_0_12_rc3 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.0.12-RC3', '>=') && phpbb_version_compare($this->config['version'], '3.1.0-dev', '<'); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v30x\release_3_0_12_rc2'); + } + + public function update_data() + { + return array( + array('if', array( + phpbb_version_compare($this->config['version'], '3.0.12-RC3', '<'), + array('config.update', array('version', '3.0.12-RC3')), + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php index 862276528d..724a61ecce 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -16,6 +16,11 @@ class release_3_0_1_rc1 extends \phpbb\db\migration\migration return phpbb_version_compare($this->config['version'], '3.0.1-RC1', '>='); } + static public function depends_on() + { + return array('\phpbb\db\migration\data\v30x\release_3_0_0'); + } + public function update_schema() { return array( diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php index 7e2a08590e..53792d4ce1 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php index 7a856383e2..691ad44406 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php index 61562575eb..26fa4f015b 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php index b2adbeaa43..5374e8786a 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php index 57bd59bba3..367bf2c806 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php index 5d6140393b..94bba00079 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php index a8af4dd76c..98aafc6d43 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php index 7bbe7ffed9..92555adf78 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php index ffe2c6a44d..c6b77bc379 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php index 04b14b5189..b56721bd80 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php index 85ea2e9d20..fb0957fc45 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php index 87d5e490f8..12b0122237 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php index 7a0ef28601..351079e96c 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php index 73a1fe9e6a..1ccfa1cb37 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php index b6e5be2c2f..6451f4fe02 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php index 2b0da30bc6..70cb1293e6 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php index 3547ee77e1..db2175a99a 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php index de4d772808..3bdedf8c57 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php index 800803a753..65ad905aa7 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php index 6c8b1df6fc..c1e49f1dde 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php index 1a14e5c961..e3c232f9e4 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php index 9af2fce971..34e85f010a 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php index 3fb790bc0d..79ef839005 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php index cd79d24ade..1eb7837faf 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php index 7e59b8f9e8..bbeb76509f 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php index e71d9defa6..bc75891f4d 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php b/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php new file mode 100644 index 0000000000..aa44222cd8 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php @@ -0,0 +1,77 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class acp_prune_users_module extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + $sql = 'SELECT module_id + FROM ' . MODULES_TABLE . " + WHERE module_class = 'acp' + AND module_langname = 'ACP_CAT_USERS'"; + $result = $this->db->sql_query($sql); + $acp_cat_users_id = (int) $this->db->sql_fetchfield('module_id'); + $this->db->sql_freeresult($result); + + $sql = 'SELECT parent_id + FROM ' . MODULES_TABLE . " + WHERE module_class = 'acp' + AND module_basename = 'acp_prune' + AND module_mode = 'users'"; + $result = $this->db->sql_query($sql); + $acp_prune_users_parent = (int) $this->db->sql_fetchfield('parent_id'); + $this->db->sql_freeresult($result); + + // Skip migration if "Users" category has been deleted + // or the module has already been moved to that category + return !$acp_cat_users_id || $acp_cat_users_id === $acp_prune_users_parent; + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\beta1'); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'move_prune_users_module'))), + ); + } + + public function move_prune_users_module() + { + $sql = 'SELECT module_id + FROM ' . MODULES_TABLE . " + WHERE module_class = 'acp' + AND module_basename = 'acp_prune' + AND module_mode = 'users'"; + $result = $this->db->sql_query($sql); + $acp_prune_users_id = (int) $this->db->sql_fetchfield('module_id'); + $this->db->sql_freeresult($result); + + $sql = 'SELECT module_id + FROM ' . MODULES_TABLE . " + WHERE module_class = 'acp' + AND module_langname = 'ACP_CAT_USERS'"; + $result = $this->db->sql_query($sql); + $acp_cat_users_id = (int) $this->db->sql_fetchfield('module_id'); + $this->db->sql_freeresult($result); + + if (!class_exists('\acp_modules')) + { + include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext); + } + $module_manager = new \acp_modules(); + $module_manager->module_class = 'acp'; + $module_manager->move_module($acp_prune_users_id, $acp_cat_users_id); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/acp_style_components_module.php b/phpBB/phpbb/db/migration/data/v310/acp_style_components_module.php new file mode 100644 index 0000000000..9f168f4fd6 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/acp_style_components_module.php @@ -0,0 +1,42 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class acp_style_components_module extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + $sql = 'SELECT module_id + FROM ' . MODULES_TABLE . " + WHERE module_class = 'acp' + AND module_langname = 'ACP_STYLE_COMPONENTS'"; + $result = $this->db->sql_query($sql); + $module_id = $this->db->sql_fetchfield('module_id'); + $this->db->sql_freeresult($result); + + return $module_id == false; + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\dev'); + } + + public function update_data() + { + return array( + array('module.remove', array( + 'acp', + false, + 'ACP_STYLE_COMPONENTS', + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/allow_cdn.php b/phpBB/phpbb/db/migration/data/v310/allow_cdn.php new file mode 100644 index 0000000000..2cb9e58767 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/allow_cdn.php @@ -0,0 +1,33 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class allow_cdn extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return isset($this->config['allow_cdn']); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\jquery_update', + ); + } + + public function update_data() + { + return array( + array('config.add', array('allow_cdn', (int) $this->config['load_jquery_cdn'])), + array('config.remove', array('load_jquery_cdn')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/alpha1.php b/phpBB/phpbb/db/migration/data/v310/alpha1.php new file mode 100644 index 0000000000..704f5a7a29 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/alpha1.php @@ -0,0 +1,44 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class alpha1 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v30x\local_url_bbcode', + '\phpbb\db\migration\data\v30x\release_3_0_12', + '\phpbb\db\migration\data\v310\acp_style_components_module', + '\phpbb\db\migration\data\v310\allow_cdn', + '\phpbb\db\migration\data\v310\auth_provider_oauth', + '\phpbb\db\migration\data\v310\avatars', + '\phpbb\db\migration\data\v310\boardindex', + '\phpbb\db\migration\data\v310\config_db_text', + '\phpbb\db\migration\data\v310\forgot_password', + '\phpbb\db\migration\data\v310\mod_rewrite', + '\phpbb\db\migration\data\v310\mysql_fulltext_drop', + '\phpbb\db\migration\data\v310\namespaces', + '\phpbb\db\migration\data\v310\notifications_cron', + '\phpbb\db\migration\data\v310\notification_options_reconvert', + '\phpbb\db\migration\data\v310\plupload', + '\phpbb\db\migration\data\v310\signature_module_auth', + '\phpbb\db\migration\data\v310\softdelete_mcp_modules', + '\phpbb\db\migration\data\v310\teampage', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.0-a1')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/alpha2.php b/phpBB/phpbb/db/migration/data/v310/alpha2.php new file mode 100644 index 0000000000..3c0853f924 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/alpha2.php @@ -0,0 +1,28 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class alpha2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\alpha1', + '\phpbb\db\migration\data\v310\notifications_cron_p2', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.0-a2')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/alpha3.php b/phpBB/phpbb/db/migration/data/v310/alpha3.php new file mode 100644 index 0000000000..4bd2231bb9 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/alpha3.php @@ -0,0 +1,30 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class alpha3 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\alpha2', + '\phpbb\db\migration\data\v310\avatar_types', + '\phpbb\db\migration\data\v310\passwords', + '\phpbb\db\migration\data\v310\profilefield_types', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.0-a3')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php index 971a7e8504..daca99c255 100644 --- a/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php +++ b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php new file mode 100644 index 0000000000..692647dcde --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class auth_provider_oauth2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\auth_provider_oauth', + ); + } + + public function update_data() + { + return array( + array('custom', array( + array($this, 'update_auth_link_module_auth'), + )), + ); + } + + public function update_auth_link_module_auth() + { + $sql = 'UPDATE ' . MODULES_TABLE . " + SET module_auth = 'authmethod_oauth' + WHERE module_class = 'ucp' + AND module_basename = 'ucp_auth_link' + AND module_mode = 'auth_link' + AND module_auth = ''"; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/avatar_types.php b/phpBB/phpbb/db/migration/data/v310/avatar_types.php new file mode 100644 index 0000000000..17bb1f26ca --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/avatar_types.php @@ -0,0 +1,60 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class avatar_types extends \phpbb\db\migration\migration +{ + /** + * @var avatar type map + */ + protected $avatar_type_map = array( + AVATAR_UPLOAD => 'avatar.driver.upload', + AVATAR_REMOTE => 'avatar.driver.remote', + AVATAR_GALLERY => 'avatar.driver.local', + ); + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\dev', + '\phpbb\db\migration\data\v310\avatars', + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'update_user_avatar_type'))), + array('custom', array(array($this, 'update_group_avatar_type'))), + ); + } + + public function update_user_avatar_type() + { + foreach ($this->avatar_type_map as $old => $new) + { + $sql = 'UPDATE ' . $this->table_prefix . "users + SET user_avatar_type = '$new' + WHERE user_avatar_type = '$old'"; + $this->db->sql_query($sql); + } + } + + public function update_group_avatar_type() + { + foreach ($this->avatar_type_map as $old => $new) + { + $sql = 'UPDATE ' . $this->table_prefix . "groups + SET group_avatar_type = '$new' + WHERE group_avatar_type = '$old'"; + $this->db->sql_query($sql); + } + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/avatars.php b/phpBB/phpbb/db/migration/data/v310/avatars.php index 80ce606f29..b6cd914dd9 100644 --- a/phpBB/phpbb/db/migration/data/v310/avatars.php +++ b/phpBB/phpbb/db/migration/data/v310/avatars.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/beta1.php b/phpBB/phpbb/db/migration/data/v310/beta1.php new file mode 100644 index 0000000000..36d0c62b6f --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/beta1.php @@ -0,0 +1,33 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class beta1 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\alpha3', + '\phpbb\db\migration\data\v310\passwords_p2', + '\phpbb\db\migration\data\v310\postgres_fulltext_drop', + '\phpbb\db\migration\data\v310\profilefield_change_load_settings', + '\phpbb\db\migration\data\v310\profilefield_location', + '\phpbb\db\migration\data\v310\soft_delete_mod_convert2', + '\phpbb\db\migration\data\v310\ucp_popuppm_module', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.0-b1')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/beta2.php b/phpBB/phpbb/db/migration/data/v310/beta2.php new file mode 100644 index 0000000000..4cf29dfb3d --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/beta2.php @@ -0,0 +1,29 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class beta2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\beta1', + '\phpbb\db\migration\data\v310\acp_prune_users_module', + '\phpbb\db\migration\data\v310\profilefield_location_cleanup', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.0-b2')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/board_contact_name.php b/phpBB/phpbb/db/migration/data/v310/board_contact_name.php new file mode 100644 index 0000000000..37b4d50545 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/board_contact_name.php @@ -0,0 +1,30 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class board_contact_name extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return isset($this->config['board_contact_name']); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\beta2'); + } + + public function update_data() + { + return array( + array('config.add', array('board_contact_name', '')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/boardindex.php b/phpBB/phpbb/db/migration/data/v310/boardindex.php index 27492f2d0d..17040a60b8 100644 --- a/phpBB/phpbb/db/migration/data/v310/boardindex.php +++ b/phpBB/phpbb/db/migration/data/v310/boardindex.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/config_db_text.php b/phpBB/phpbb/db/migration/data/v310/config_db_text.php index 1a7ee7a9a6..49f30d289f 100644 --- a/phpBB/phpbb/db/migration/data/v310/config_db_text.php +++ b/phpBB/phpbb/db/migration/data/v310/config_db_text.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/dev.php b/phpBB/phpbb/db/migration/data/v310/dev.php index c1db883616..da78db7b89 100644 --- a/phpBB/phpbb/db/migration/data/v310/dev.php +++ b/phpBB/phpbb/db/migration/data/v310/dev.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -23,6 +23,7 @@ class dev extends \phpbb\db\migration\migration '\phpbb\db\migration\data\v310\style_update_p2', '\phpbb\db\migration\data\v310\timezone_p2', '\phpbb\db\migration\data\v310\reported_posts_display', + '\phpbb\db\migration\data\v310\migrations_table', ); } diff --git a/phpBB/phpbb/db/migration/data/v310/extensions.php b/phpBB/phpbb/db/migration/data/v310/extensions.php index d8b38dbc9e..a0d57087d4 100644 --- a/phpBB/phpbb/db/migration/data/v310/extensions.php +++ b/phpBB/phpbb/db/migration/data/v310/extensions.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/forgot_password.php b/phpBB/phpbb/db/migration/data/v310/forgot_password.php index 814093caa9..523f4e2c0a 100644 --- a/phpBB/phpbb/db/migration/data/v310/forgot_password.php +++ b/phpBB/phpbb/db/migration/data/v310/forgot_password.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/jquery_update.php b/phpBB/phpbb/db/migration/data/v310/jquery_update.php index bd2de2b4d4..187d6b876a 100644 --- a/phpBB/phpbb/db/migration/data/v310/jquery_update.php +++ b/phpBB/phpbb/db/migration/data/v310/jquery_update.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/jquery_update2.php b/phpBB/phpbb/db/migration/data/v310/jquery_update2.php new file mode 100644 index 0000000000..46a115d8ad --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/jquery_update2.php @@ -0,0 +1,33 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class jquery_update2 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return $this->config['load_jquery_url'] !== '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'; + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\jquery_update', + ); + } + + public function update_data() + { + return array( + array('config.update', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js')), + ); + } + +} diff --git a/phpBB/phpbb/db/migration/data/v310/migrations_table.php b/phpBB/phpbb/db/migration/data/v310/migrations_table.php new file mode 100644 index 0000000000..e70fd35819 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/migrations_table.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class migrations_table extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return $this->db_tools->sql_table_exists($this->table_prefix . 'migrations'); + } + + public function update_schema() + { + return array( + 'add_tables' => array( + $this->table_prefix . 'migrations' => array( + 'COLUMNS' => array( + 'migration_name' => array('VCHAR', ''), + 'migration_depends_on' => array('TEXT', ''), + 'migration_schema_done' => array('BOOL', 0), + 'migration_data_done' => array('BOOL', 0), + 'migration_data_state' => array('TEXT', ''), + 'migration_start_time' => array('TIMESTAMP', 0), + 'migration_end_time' => array('TIMESTAMP', 0), + ), + 'PRIMARY_KEY' => 'migration_name', + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_tables' => array( + $this->table_prefix . 'migrations', + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php b/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php index ffb790b135..e7d71f63e3 100644 --- a/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php +++ b/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php b/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php new file mode 100644 index 0000000000..97d174d4bc --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/mysql_fulltext_drop.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class mysql_fulltext_drop extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + // This migration is irrelevant for all non-MySQL DBMSes. + return strpos($this->db->sql_layer, 'mysql') === false; + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\dev', + ); + } + + public function update_schema() + { + /* + * Drop FULLTEXT indexes related to MySQL fulltext search. + * Doing so is equivalent to dropping the search index from the ACP. + * Possibly time-consuming recreation of the search index (i.e. + * FULLTEXT indexes) is left as a task to the admin to not + * unnecessarily stall the upgrade process. The new search index will + * then require about 40% less table space (also see PHPBB3-11621). + */ + return array( + 'drop_keys' => array( + $this->table_prefix . 'posts' => array( + 'post_subject', + 'post_text', + 'post_content', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/namespaces.php b/phpBB/phpbb/db/migration/data/v310/namespaces.php index 9b182f88b8..aa0b2bbfac 100644 --- a/phpBB/phpbb/db/migration/data/v310/namespaces.php +++ b/phpBB/phpbb/db/migration/data/v310/namespaces.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -23,7 +23,7 @@ class namespaces extends \phpbb\db\migration\migration return array( array('if', array( (preg_match('#^phpbb_search_#', $this->config['search_type'])), - array('config.update', array('search_type', str_replace('phpbb_search_', 'phpbb\\search\\', $this->config['search_type']))), + array('config.update', array('search_type', str_replace('phpbb_search_', '\\phpbb\\search\\', $this->config['search_type']))), )), ); } diff --git a/phpBB/phpbb/db/migration/data/v310/notifications.php b/phpBB/phpbb/db/migration/data/v310/notifications.php index 10f1392094..cf26436ccb 100644 --- a/phpBB/phpbb/db/migration/data/v310/notifications.php +++ b/phpBB/phpbb/db/migration/data/v310/notifications.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -34,7 +34,7 @@ class notifications extends \phpbb\db\migration\migration ), $this->table_prefix . 'notifications' => array( 'COLUMNS' => array( - 'notification_id' => array('UINT', NULL, 'auto_increment'), + 'notification_id' => array('UINT', null, 'auto_increment'), 'item_type' => array('VCHAR:255', ''), 'item_id' => array('UINT', 0), 'item_parent_id' => array('UINT', 0), diff --git a/phpBB/phpbb/db/migration/data/v310/notifications_cron_p2.php b/phpBB/phpbb/db/migration/data/v310/notifications_cron_p2.php new file mode 100644 index 0000000000..050e679cc0 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/notifications_cron_p2.php @@ -0,0 +1,27 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class notifications_cron_p2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\notifications_cron'); + } + + public function update_data() + { + return array( + // Make read_notification_last_gc dynamic. + array('config.remove', array('read_notification_last_gc')), + array('config.add', array('read_notification_last_gc', 0, 1)), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php b/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php index 8ed626d8a6..a9d11d384c 100644 --- a/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php +++ b/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -26,7 +26,7 @@ class notifications_schema_fix extends \phpbb\db\migration\migration 'add_tables' => array( $this->table_prefix . 'notification_types' => array( 'COLUMNS' => array( - 'notification_type_id' => array('USINT', NULL, 'auto_increment'), + 'notification_type_id' => array('USINT', null, 'auto_increment'), 'notification_type_name' => array('VCHAR:255', ''), 'notification_type_enabled' => array('BOOL', 1), ), @@ -37,7 +37,7 @@ class notifications_schema_fix extends \phpbb\db\migration\migration ), $this->table_prefix . 'notifications' => array( 'COLUMNS' => array( - 'notification_id' => array('UINT:10', NULL, 'auto_increment'), + 'notification_id' => array('UINT:10', null, 'auto_increment'), 'notification_type_id' => array('USINT', 0), 'item_id' => array('UINT', 0), 'item_parent_id' => array('UINT', 0), @@ -73,7 +73,7 @@ class notifications_schema_fix extends \phpbb\db\migration\migration ), $this->table_prefix . 'notifications' => array( 'COLUMNS' => array( - 'notification_id' => array('UINT', NULL, 'auto_increment'), + 'notification_id' => array('UINT', null, 'auto_increment'), 'item_type' => array('VCHAR:255', ''), 'item_id' => array('UINT', 0), 'item_parent_id' => array('UINT', 0), diff --git a/phpBB/phpbb/db/migration/data/v310/passwords.php b/phpBB/phpbb/db/migration/data/v310/passwords.php new file mode 100644 index 0000000000..2bba9b7a70 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/passwords.php @@ -0,0 +1,46 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class passwords extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v30x\release_3_0_11'); + } + + public function update_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'users' => array( + 'user_password' => array('VCHAR:255', ''), + ), + $this->table_prefix . 'forums' => array( + 'forum_password' => array('VCHAR:255', ''), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'users' => array( + 'user_password' => array('VCHAR:40', ''), + ), + $this->table_prefix . 'forums' => array( + 'forum_password' => array('VCHAR:40', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/passwords_p2.php b/phpBB/phpbb/db/migration/data/v310/passwords_p2.php new file mode 100644 index 0000000000..2768c8975d --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/passwords_p2.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class passwords_p2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\passwords'); + } + + public function update_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'users' => array( + 'user_newpasswd' => array('VCHAR:255', ''), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'users' => array( + 'user_newpasswd' => array('VCHAR:40', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/plupload.php b/phpBB/phpbb/db/migration/data/v310/plupload.php new file mode 100644 index 0000000000..7cdba507a2 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/plupload.php @@ -0,0 +1,32 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class plupload extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return isset($this->config['plupload_last_gc']) && + isset($this->config['plupload_salt']); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\dev'); + } + + public function update_data() + { + return array( + array('config.add', array('plupload_last_gc', 0)), + array('config.add', array('plupload_salt', unique_id())), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php b/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php new file mode 100644 index 0000000000..7d4aea3c95 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/postgres_fulltext_drop.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class postgres_fulltext_drop extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + // This migration is irrelevant for all non-PostgreSQL DBMSes. + return strpos($this->db->sql_layer, 'postgres') === false; + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\dev', + ); + } + + public function update_schema() + { + /* + * Drop FULLTEXT indexes related to PostgreSQL fulltext search. + * Doing so is equivalent to dropping the search index from the ACP. + * Possibly time-consuming recreation of the search index (i.e. + * FULLTEXT indexes) is left as a task to the admin to not + * unnecessarily stall the upgrade process. The new search index will + * then require about 40% less table space (also see PHPBB3-11040). + */ + return array( + 'drop_keys' => array( + $this->table_prefix . 'posts' => array( + 'post_subject', + 'post_text', + 'post_content', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_aol.php b/phpBB/phpbb/db/migration/data/v310/profilefield_aol.php new file mode 100644 index 0000000000..87574cb858 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_aol.php @@ -0,0 +1,51 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_aol extends \phpbb\db\migration\profilefield_base_migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_yahoo_cleanup', + ); + } + + protected $profilefield_name = 'phpbb_aol'; + + protected $profilefield_database_type = array('VCHAR', ''); + + protected $profilefield_data = array( + 'field_name' => 'phpbb_aol', + 'field_type' => 'profilefields.type.string', + 'field_ident' => 'phpbb_aol', + 'field_length' => '40', + 'field_minlen' => '5', + 'field_maxlen' => '255', + 'field_novalue' => '', + 'field_default_value' => '', + 'field_validation' => '.*', + 'field_required' => 0, + 'field_show_novalue' => 0, + 'field_show_on_reg' => 0, + 'field_show_on_pm' => 1, + 'field_show_on_vt' => 1, + 'field_show_on_ml' => 0, + 'field_show_profile' => 1, + 'field_hide' => 0, + 'field_no_view' => 0, + 'field_active' => 1, + 'field_is_contact' => 1, + 'field_contact_desc' => '', + 'field_contact_url' => '', + ); + + protected $user_column_name = 'user_aim'; +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_aol_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_aol_cleanup.php new file mode 100644 index 0000000000..a7088c6a7a --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_aol_cleanup.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_aol_cleanup extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_aim'); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_aol', + ); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'users' => array( + 'user_aim', + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'users' => array( + 'user_aim' => array('VCHAR_UNI', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_change_load_settings.php b/phpBB/phpbb/db/migration/data/v310/profilefield_change_load_settings.php new file mode 100644 index 0000000000..7d09d8149a --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_change_load_settings.php @@ -0,0 +1,30 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_change_load_settings extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_aol_cleanup', + ); + } + + public function update_data() + { + return array( + array('config.update', array('load_cpf_memberlist', '1')), + array('config.update', array('load_cpf_pm', '1')), + array('config.update', array('load_cpf_viewprofile', '1')), + array('config.update', array('load_cpf_viewtopic', '1')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php new file mode 100644 index 0000000000..625e74fba1 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php @@ -0,0 +1,51 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_cleanup extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_occ') && + !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_interests'); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_interests', + '\phpbb\db\migration\data\v310\profilefield_occupation', + ); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'users' => array( + 'user_occ', + 'user_interests', + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'users' => array( + 'user_occ' => array('MTEXT', ''), + 'user_interests' => array('MTEXT', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_contact_field.php b/phpBB/phpbb/db/migration/data/v310/profilefield_contact_field.php new file mode 100644 index 0000000000..c7617813eb --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_contact_field.php @@ -0,0 +1,51 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_contact_field extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return $this->db_tools->sql_column_exists($this->table_prefix . 'profile_fields', 'field_is_contact'); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_on_memberlist', + ); + } + + public function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'profile_fields' => array( + 'field_is_contact' => array('BOOL', 0), + 'field_contact_desc' => array('VCHAR', ''), + 'field_contact_url' => array('VCHAR', ''), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'profile_fields' => array( + 'field_is_contact', + 'field_contact_desc', + 'field_contact_url', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_icq.php b/phpBB/phpbb/db/migration/data/v310/profilefield_icq.php new file mode 100644 index 0000000000..2c8c8c511f --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_icq.php @@ -0,0 +1,50 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_icq extends \phpbb\db\migration\profilefield_base_migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_contact_field', + ); + } + + protected $profilefield_name = 'phpbb_icq'; + + protected $profilefield_database_type = array('VCHAR', ''); + + protected $profilefield_data = array( + 'field_name' => 'phpbb_icq', + 'field_type' => 'profilefields.type.string', + 'field_ident' => 'phpbb_icq', + 'field_length' => '20', + 'field_minlen' => '3', + 'field_maxlen' => '15', + 'field_novalue' => '', + 'field_default_value' => '', + 'field_validation' => '[0-9]+', + 'field_required' => 0, + 'field_show_novalue' => 0, + 'field_show_on_reg' => 0, + 'field_show_on_pm' => 1, + 'field_show_on_vt' => 1, + 'field_show_profile' => 1, + 'field_hide' => 0, + 'field_no_view' => 0, + 'field_active' => 1, + 'field_is_contact' => 1, + 'field_contact_desc' => 'SEND_ICQ_MESSAGE', + 'field_contact_url' => 'https://www.icq.com/people/%s/', + ); + + protected $user_column_name = 'user_icq'; +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_icq_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_icq_cleanup.php new file mode 100644 index 0000000000..0129a7248f --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_icq_cleanup.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_icq_cleanup extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_icq'); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_icq', + ); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'users' => array( + 'user_icq', + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'users' => array( + 'user_icq' => array('VCHAR:20', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php b/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php new file mode 100644 index 0000000000..53fae2ea1a --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php @@ -0,0 +1,48 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_interests extends \phpbb\db\migration\profilefield_base_migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_types', + '\phpbb\db\migration\data\v310\profilefield_show_novalue', + ); + } + + protected $profilefield_name = 'phpbb_interests'; + + protected $profilefield_database_type = array('MTEXT', ''); + + protected $profilefield_data = array( + 'field_name' => 'phpbb_interests', + 'field_type' => 'profilefields.type.text', + 'field_ident' => 'phpbb_interests', + 'field_length' => '3|30', + 'field_minlen' => '2', + 'field_maxlen' => '500', + 'field_novalue' => '', + 'field_default_value' => '', + 'field_validation' => '.*', + 'field_required' => 0, + 'field_show_novalue' => 0, + 'field_show_on_reg' => 0, + 'field_show_on_pm' => 0, + 'field_show_on_vt' => 0, + 'field_show_profile' => 1, + 'field_hide' => 0, + 'field_no_view' => 0, + 'field_active' => 1, + ); + + protected $user_column_name = 'user_interests'; +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_location.php b/phpBB/phpbb/db/migration/data/v310/profilefield_location.php new file mode 100644 index 0000000000..f4db79ca5e --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_location.php @@ -0,0 +1,48 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_location extends \phpbb\db\migration\profilefield_base_migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_types', + '\phpbb\db\migration\data\v310\profilefield_on_memberlist', + ); + } + + protected $profilefield_name = 'phpbb_location'; + + protected $profilefield_database_type = array('VCHAR', ''); + + protected $profilefield_data = array( + 'field_name' => 'phpbb_location', + 'field_type' => 'profilefields.type.string', + 'field_ident' => 'phpbb_location', + 'field_length' => '20', + 'field_minlen' => '2', + 'field_maxlen' => '100', + 'field_novalue' => '', + 'field_default_value' => '', + 'field_validation' => '.*', + 'field_required' => 0, + 'field_show_novalue' => 0, + 'field_show_on_reg' => 0, + 'field_show_on_pm' => 1, + 'field_show_on_vt' => 1, + 'field_show_profile' => 1, + 'field_hide' => 0, + 'field_no_view' => 0, + 'field_active' => 1, + ); + + protected $user_column_name = 'user_from'; +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_location_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_location_cleanup.php new file mode 100644 index 0000000000..54ff2a31eb --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_location_cleanup.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_location_cleanup extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_from'); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_location', + ); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'users' => array( + 'user_from', + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'users' => array( + 'user_from' => array('VCHAR_UNI:100', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php b/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php new file mode 100644 index 0000000000..9a710fbcbc --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_occupation extends \phpbb\db\migration\profilefield_base_migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_interests', + ); + } + + protected $profilefield_name = 'phpbb_occupation'; + + protected $profilefield_database_type = array('MTEXT', ''); + + protected $profilefield_data = array( + 'field_name' => 'phpbb_occupation', + 'field_type' => 'profilefields.type.text', + 'field_ident' => 'phpbb_occupation', + 'field_length' => '3|30', + 'field_minlen' => '2', + 'field_maxlen' => '500', + 'field_novalue' => '', + 'field_default_value' => '', + 'field_validation' => '.*', + 'field_required' => 0, + 'field_show_novalue' => 0, + 'field_show_on_reg' => 0, + 'field_show_on_pm' => 0, + 'field_show_on_vt' => 0, + 'field_show_profile' => 1, + 'field_hide' => 0, + 'field_no_view' => 0, + 'field_active' => 1, + ); + + protected $user_column_name = 'user_occ'; +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php b/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php new file mode 100644 index 0000000000..4733b7713d --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_on_memberlist extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return $this->db_tools->sql_column_exists($this->table_prefix . 'profile_fields', 'field_show_on_ml'); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_cleanup', + ); + } + + public function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'profile_fields' => array( + 'field_show_on_ml' => array('BOOL', 0), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'profile_fields' => array( + 'field_show_on_ml', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_show_novalue.php b/phpBB/phpbb/db/migration/data/v310/profilefield_show_novalue.php new file mode 100644 index 0000000000..d37103e2ce --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_show_novalue.php @@ -0,0 +1,45 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_show_novalue extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return $this->db_tools->sql_column_exists($this->table_prefix . 'profile_fields', 'field_show_novalue'); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\profilefield_types'); + } + + public function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'profile_fields' => array( + 'field_show_novalue' => array('BOOL', 0), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'profile_fields' => array( + 'field_show_novalue', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_types.php b/phpBB/phpbb/db/migration/data/v310/profilefield_types.php new file mode 100644 index 0000000000..9b54d87c9a --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_types.php @@ -0,0 +1,106 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_types extends \phpbb\db\migration\migration +{ + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\alpha2', + ); + } + + public function update_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'profile_fields' => array( + 'field_type' => array('VCHAR:100', ''), + ), + $this->table_prefix . 'profile_fields_lang' => array( + 'field_type' => array('VCHAR:100', ''), + ), + ), + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'update_profile_fields_type'))), + array('custom', array(array($this, 'update_profile_fields_lang_type'))), + ); + } + + public function update_profile_fields_type() + { + // Update profile field types + $sql = 'SELECT field_type + FROM ' . $this->table_prefix . 'profile_fields + GROUP BY field_type'; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $sql = 'UPDATE ' . $this->table_prefix . "profile_fields + SET field_type = '" . $this->db->sql_escape($this->convert_phpbb30_field_type($row['field_type'])) . "' + WHERE field_type = '" . $this->db->sql_escape($row['field_type']) . "'"; + $this->sql_query($sql); + } + $this->db->sql_freeresult($result); + } + + public function update_profile_fields_lang_type() + { + // Update profile field language types + $sql = 'SELECT field_type + FROM ' . $this->table_prefix . 'profile_fields_lang + GROUP BY field_type'; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $sql = 'UPDATE ' . $this->table_prefix . "profile_fields_lang + SET field_type = '" . $this->db->sql_escape($this->convert_phpbb30_field_type($row['field_type'])) . "' + WHERE field_type = '" . $this->db->sql_escape($row['field_type']) . "'"; + $this->sql_query($sql); + } + $this->db->sql_freeresult($result); + } + + /** + * Determine the new field type for a given phpBB 3.0 field type + * + * @param $field_type string Field type in 3.0 + * @return string Field new type which is used since 3.1 + */ + public function convert_phpbb30_field_type($field_type) + { + switch ($field_type) + { + case FIELD_INT: + return 'profilefields.type.int'; + case FIELD_STRING: + return 'profilefields.type.string'; + case FIELD_TEXT: + return 'profilefields.type.text'; + case FIELD_BOOL: + return 'profilefields.type.bool'; + case FIELD_DROPDOWN: + return 'profilefields.type.dropdown'; + case FIELD_DATE: + return 'profilefields.type.date'; + default: + return $field_type; + } + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_website.php b/phpBB/phpbb/db/migration/data/v310/profilefield_website.php new file mode 100644 index 0000000000..818b66d2e4 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_website.php @@ -0,0 +1,52 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_website extends \phpbb\db\migration\profilefield_base_migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_on_memberlist', + '\phpbb\db\migration\data\v310\profilefield_icq_cleanup', + ); + } + + protected $profilefield_name = 'phpbb_website'; + + protected $profilefield_database_type = array('VCHAR', ''); + + protected $profilefield_data = array( + 'field_name' => 'phpbb_website', + 'field_type' => 'profilefields.type.url', + 'field_ident' => 'phpbb_website', + 'field_length' => '40', + 'field_minlen' => '12', + 'field_maxlen' => '255', + 'field_novalue' => '', + 'field_default_value' => '', + 'field_validation' => '', + 'field_required' => 0, + 'field_show_novalue' => 0, + 'field_show_on_reg' => 0, + 'field_show_on_pm' => 1, + 'field_show_on_vt' => 1, + 'field_show_on_ml' => 1, + 'field_show_profile' => 1, + 'field_hide' => 0, + 'field_no_view' => 0, + 'field_active' => 1, + 'field_is_contact' => 1, + 'field_contact_desc' => 'VISIT_WEBSITE', + 'field_contact_url' => '%s', + ); + + protected $user_column_name = 'user_website'; +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_website_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_website_cleanup.php new file mode 100644 index 0000000000..35cc92199e --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_website_cleanup.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_website_cleanup extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_website'); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_website', + ); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'users' => array( + 'user_website', + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'users' => array( + 'user_website' => array('VCHAR_UNI:200', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_wlm.php b/phpBB/phpbb/db/migration/data/v310/profilefield_wlm.php new file mode 100644 index 0000000000..8a42f1fea1 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_wlm.php @@ -0,0 +1,51 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_wlm extends \phpbb\db\migration\profilefield_base_migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_website_cleanup', + ); + } + + protected $profilefield_name = 'phpbb_wlm'; + + protected $profilefield_database_type = array('VCHAR', ''); + + protected $profilefield_data = array( + 'field_name' => 'phpbb_wlm', + 'field_type' => 'profilefields.type.string', + 'field_ident' => 'phpbb_wlm', + 'field_length' => '40', + 'field_minlen' => '5', + 'field_maxlen' => '255', + 'field_novalue' => '', + 'field_default_value' => '', + 'field_validation' => '.*', + 'field_required' => 0, + 'field_show_novalue' => 0, + 'field_show_on_reg' => 0, + 'field_show_on_pm' => 1, + 'field_show_on_vt' => 1, + 'field_show_on_ml' => 0, + 'field_show_profile' => 1, + 'field_hide' => 0, + 'field_no_view' => 0, + 'field_active' => 1, + 'field_is_contact' => 1, + 'field_contact_desc' => '', + 'field_contact_url' => '', + ); + + protected $user_column_name = 'user_msnm'; +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_wlm_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_wlm_cleanup.php new file mode 100644 index 0000000000..98b92eb188 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_wlm_cleanup.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_wlm_cleanup extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_msnm'); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_wlm', + ); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'users' => array( + 'user_msnm', + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'users' => array( + 'user_msnm' => array('VCHAR_UNI', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo.php b/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo.php new file mode 100644 index 0000000000..808aec8099 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo.php @@ -0,0 +1,51 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_yahoo extends \phpbb\db\migration\profilefield_base_migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_wlm_cleanup', + ); + } + + protected $profilefield_name = 'phpbb_yahoo'; + + protected $profilefield_database_type = array('VCHAR', ''); + + protected $profilefield_data = array( + 'field_name' => 'phpbb_yahoo', + 'field_type' => 'profilefields.type.string', + 'field_ident' => 'phpbb_yahoo', + 'field_length' => '40', + 'field_minlen' => '5', + 'field_maxlen' => '255', + 'field_novalue' => '', + 'field_default_value' => '', + 'field_validation' => '.*', + 'field_required' => 0, + 'field_show_novalue' => 0, + 'field_show_on_reg' => 0, + 'field_show_on_pm' => 1, + 'field_show_on_vt' => 1, + 'field_show_on_ml' => 0, + 'field_show_profile' => 1, + 'field_hide' => 0, + 'field_no_view' => 0, + 'field_active' => 1, + 'field_is_contact' => 1, + 'field_contact_desc' => 'SEND_YIM_MESSAGE', + 'field_contact_url' => 'http://edit.yahoo.com/config/send_webmesg?.target=%s&.src=pg', + ); + + protected $user_column_name = 'user_yim'; +} diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo_cleanup.php new file mode 100644 index 0000000000..c11d06576f --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_yahoo_cleanup.php @@ -0,0 +1,47 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_yahoo_cleanup extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_yim'); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\profilefield_yahoo', + ); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'users' => array( + 'user_yim', + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'users' => array( + 'user_yim' => array('VCHAR_UNI', ''), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php b/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php new file mode 100644 index 0000000000..83f5f903e8 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php @@ -0,0 +1,46 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class prune_shadow_topics extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\dev'); + } + + public function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'forums' => array( + 'enable_shadow_prune' => array('BOOL', 0), + 'prune_shadow_days' => array('UINT', 7), + 'prune_shadow_freq' => array('UINT', 1), + 'prune_shadow_next' => array('INT:11', 0), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'forums' => array( + 'enable_shadow_prune', + 'prune_shadow_days', + 'prune_shadow_freq', + 'prune_shadow_next', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php b/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php index 56b7a0916c..c6618cf467 100644 --- a/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php +++ b/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/signature_module_auth.php b/phpBB/phpbb/db/migration/data/v310/signature_module_auth.php index a85e0be01c..6da1cb8009 100644 --- a/phpBB/phpbb/db/migration/data/v310/signature_module_auth.php +++ b/phpBB/phpbb/db/migration/data/v310/signature_module_auth.php @@ -27,7 +27,7 @@ class signature_module_auth extends \phpbb\db\migration\migration static public function depends_on() { - return array('\phpbb\db\migration\data\v31x\dev'); + return array('\phpbb\db\migration\data\v310\dev'); } public function update_data() diff --git a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php new file mode 100644 index 0000000000..c9255d88ee --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php @@ -0,0 +1,128 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +/** + * Migration to convert the Soft Delete MOD for 3.0 + * + * https://www.phpbb.com/customise/db/mod/soft_delete/ + */ +class soft_delete_mod_convert extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\alpha3', + ); + } + + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'posts', 'post_deleted'); + } + + public function update_data() + { + return array( + array('permission.remove', array('m_harddelete', true)), + array('permission.remove', array('m_harddelete', false)), + + array('custom', array(array($this, 'convert_posts'))), + array('custom', array(array($this, 'convert_topics'))), + ); + } + + public function convert_posts($start) + { + $content_visibility = $this->get_content_visibility(); + + $limit = 250; + $i = 0; + + $sql = 'SELECT p.*, t.topic_first_post_id, t.topic_last_post_id + FROM ' . $this->table_prefix . 'posts p, ' . $this->table_prefix . 'topics t + WHERE p.post_deleted > 0 + AND t.topic_id = p.topic_id'; + $result = $this->db->sql_query_limit($sql, $limit, $start); + + while ($row = $this->db->sql_fetchrow($result)) + { + $content_visibility->set_post_visibility( + ITEM_DELETED, + $row['post_id'], + $row['topic_id'], + $row['forum_id'], + $row['post_deleted'], + $row['post_deleted_time'], + '', + ($row['post_id'] == $row['topic_first_post_id']) ? true : false, + ($row['post_id'] == $row['topic_last_post_id']) ? true : false + ); + + $i++; + } + + $this->db->sql_freeresult($result); + + if ($i == $limit) + { + return $start + $i; + } + } + + public function convert_topics($start) + { + $content_visibility = $this->get_content_visibility(); + + $limit = 100; + $i = 0; + + $sql = 'SELECT * + FROM ' . $this->table_prefix . 'topics + WHERE topic_deleted > 0'; + $result = $this->db->sql_query_limit($sql, $limit, $start); + + while ($row = $this->db->sql_fetchrow($result)) + { + $content_visibility->set_topic_visibility( + ITEM_DELETED, + $row['topic_id'], + $row['forum_id'], + $row['topic_deleted'], + $row['topic_deleted_time'], + '' + ); + + $i++; + } + + $this->db->sql_freeresult($result); + + if ($i == $limit) + { + return $start + $i; + } + } + + protected function get_content_visibility() + { + return new \phpbb\content_visibility( + new \phpbb\auth\auth(), + $this->db, + new \phpbb\user(), + $this->phpbb_root_path, + $this->php_ext, + $this->table_prefix . 'forums', + $this->table_prefix . 'posts', + $this->table_prefix . 'topics', + $this->table_prefix . 'users' + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php new file mode 100644 index 0000000000..ab4be269e6 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert2.php @@ -0,0 +1,62 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +/** + * Migration to convert the Soft Delete MOD for 3.0 + * + * https://www.phpbb.com/customise/db/mod/soft_delete/ + */ +class soft_delete_mod_convert2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\soft_delete_mod_convert', + ); + } + + public function effectively_installed() + { + return !$this->db_tools->sql_column_exists($this->table_prefix . 'posts', 'post_deleted'); + } + + public function update_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'forums' => array('forum_deleted_topic_count', 'forum_deleted_reply_count'), + $this->table_prefix . 'posts' => array('post_deleted', 'post_deleted_time'), + $this->table_prefix . 'topics' => array('topic_deleted', 'topic_deleted_time', 'topic_deleted_reply_count'), + ), + ); + } + + public function revert_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'forums' => array( + 'forum_deleted_topic_count' => array('UINT', 0), + 'forum_deleted_reply_count' => array('UINT', 0), + ), + $this->table_prefix . 'posts' => array( + 'post_deleted' => array('UINT', 0), + 'post_deleted_time' => array('TIMESTAMP', 0), + ), + $this->table_prefix . 'topics' => array( + 'topic_deleted' => array('UINT', 0), + 'topic_deleted_time' => array('TIMESTAMP', 0), + 'topic_deleted_reply_count' => array('UINT', 0), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php b/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php index d1a31815b2..18c225d19f 100644 --- a/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php +++ b/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php b/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php index f080c78c50..10243dc77f 100644 --- a/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php +++ b/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -149,6 +149,15 @@ class softdelete_p1 extends \phpbb\db\migration\migration $limit = 10; $converted_forums = 0; + if (!$start) + { + // Preserve the forum_posts value for link forums as it represents redirects. + $sql = 'UPDATE ' . $this->table_prefix . 'forums + SET forum_posts_approved = forum_posts + WHERE forum_type = ' . FORUM_LINK; + $this->db->sql_query($sql); + } + $sql = 'SELECT forum_id, topic_visibility, COUNT(topic_id) AS sum_topics, SUM(topic_posts_approved) AS sum_posts_approved, SUM(topic_posts_unapproved) AS sum_posts_unapproved FROM ' . $this->table_prefix . 'topics GROUP BY forum_id, topic_visibility diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php b/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php index 0c32e474f4..6b84a1b980 100644 --- a/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php +++ b/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -34,7 +34,10 @@ class softdelete_p2 extends \phpbb\db\migration\migration ), 'drop_keys' => array( $this->table_prefix . 'posts' => array('post_approved'), - $this->table_prefix . 'topics' => array('forum_appr_last'), + $this->table_prefix . 'topics' => array( + 'forum_appr_last', + 'topic_approved', + ), ), ); } @@ -63,6 +66,7 @@ class softdelete_p2 extends \phpbb\db\migration\migration ), $this->table_prefix . 'topics' => array( 'forum_appr_last' => array('forum_id', 'topic_approved', 'topic_last_post_id'), + 'topic_approved' => array('topic_approved'), ), ), ); diff --git a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php index 26f1046287..fcba1d73ed 100644 --- a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php +++ b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/style_update_p2.php b/phpBB/phpbb/db/migration/data/v310/style_update_p2.php index 202a8409fb..316741e11d 100644 --- a/phpBB/phpbb/db/migration/data/v310/style_update_p2.php +++ b/phpBB/phpbb/db/migration/data/v310/style_update_p2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -24,6 +24,14 @@ class style_update_p2 extends \phpbb\db\migration\migration public function update_schema() { return array( + 'drop_keys' => array( + $this->table_prefix . 'styles' => array( + 'imageset_id', + 'template_id', + 'theme_id', + ), + ), + 'drop_columns' => array( $this->table_prefix . 'styles' => array( 'imageset_id', @@ -53,10 +61,18 @@ class style_update_p2 extends \phpbb\db\migration\migration ), ), + 'add_index' => array( + $this->table_prefix . 'styles' => array( + 'imageset_id' => array('imageset_id'), + 'template_id' => array('template_id'), + 'theme_id' => array('theme_id'), + ), + ), + 'add_tables' => array( $this->table_prefix . 'styles_imageset' => array( 'COLUMNS' => array( - 'imageset_id' => array('UINT', NULL, 'auto_increment'), + 'imageset_id' => array('UINT', null, 'auto_increment'), 'imageset_name' => array('VCHAR_UNI:255', ''), 'imageset_copyright' => array('VCHAR_UNI', ''), 'imageset_path' => array('VCHAR:100', ''), @@ -68,7 +84,7 @@ class style_update_p2 extends \phpbb\db\migration\migration ), $this->table_prefix . 'styles_imageset_data' => array( 'COLUMNS' => array( - 'image_id' => array('UINT', NULL, 'auto_increment'), + 'image_id' => array('UINT', null, 'auto_increment'), 'image_name' => array('VCHAR:200', ''), 'image_filename' => array('VCHAR:200', ''), 'image_lang' => array('VCHAR:30', ''), @@ -83,7 +99,7 @@ class style_update_p2 extends \phpbb\db\migration\migration ), $this->table_prefix . 'styles_template' => array( 'COLUMNS' => array( - 'template_id' => array('UINT', NULL, 'auto_increment'), + 'template_id' => array('UINT', null, 'auto_increment'), 'template_name' => array('VCHAR_UNI:255', ''), 'template_copyright' => array('VCHAR_UNI', ''), 'template_path' => array('VCHAR:100', ''), @@ -112,7 +128,7 @@ class style_update_p2 extends \phpbb\db\migration\migration ), $this->table_prefix . 'styles_theme' => array( 'COLUMNS' => array( - 'theme_id' => array('UINT', NULL, 'auto_increment'), + 'theme_id' => array('UINT', null, 'auto_increment'), 'theme_name' => array('VCHAR_UNI:255', ''), 'theme_copyright' => array('VCHAR_UNI', ''), 'theme_path' => array('VCHAR:100', ''), diff --git a/phpBB/phpbb/db/migration/data/v310/teampage.php b/phpBB/phpbb/db/migration/data/v310/teampage.php index 80cc4be1c0..f03c09e04f 100644 --- a/phpBB/phpbb/db/migration/data/v310/teampage.php +++ b/phpBB/phpbb/db/migration/data/v310/teampage.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -27,7 +27,7 @@ class teampage extends \phpbb\db\migration\migration 'add_tables' => array( $this->table_prefix . 'teampage' => array( 'COLUMNS' => array( - 'teampage_id' => array('UINT', NULL, 'auto_increment'), + 'teampage_id' => array('UINT', null, 'auto_increment'), 'group_id' => array('UINT', 0), 'teampage_name' => array('VCHAR_UNI:255', ''), 'teampage_position' => array('UINT', 0), diff --git a/phpBB/phpbb/db/migration/data/v310/timezone.php b/phpBB/phpbb/db/migration/data/v310/timezone.php index 61f8dc488e..2efedd4514 100644 --- a/phpBB/phpbb/db/migration/data/v310/timezone.php +++ b/phpBB/phpbb/db/migration/data/v310/timezone.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/timezone_p2.php b/phpBB/phpbb/db/migration/data/v310/timezone_p2.php index 1066ab8571..891d8622a0 100644 --- a/phpBB/phpbb/db/migration/data/v310/timezone_p2.php +++ b/phpBB/phpbb/db/migration/data/v310/timezone_p2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/ucp_popuppm_module.php b/phpBB/phpbb/db/migration/data/v310/ucp_popuppm_module.php new file mode 100644 index 0000000000..f8ada6c6f5 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/ucp_popuppm_module.php @@ -0,0 +1,42 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class ucp_popuppm_module extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + $sql = 'SELECT module_id + FROM ' . MODULES_TABLE . " + WHERE module_class = 'ucp' + AND module_langname = 'UCP_PM_POPUP_TITLE'"; + $result = $this->db->sql_query($sql); + $module_id = $this->db->sql_fetchfield('module_id'); + $this->db->sql_freeresult($result); + + return $module_id == false; + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\dev'); + } + + public function update_data() + { + return array( + array('module.remove', array( + 'ucp', + 'UCP_PM', + 'UCP_PM_POPUP_TITLE', + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/exception.php b/phpBB/phpbb/db/migration/exception.php index 58e29b5218..c6c1a45947 100644 --- a/phpBB/phpbb/db/migration/exception.php +++ b/phpBB/phpbb/db/migration/exception.php @@ -3,21 +3,13 @@ * * @package db * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ namespace phpbb\db\migration; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * The migrator is responsible for applying new migrations in the correct order. * * @package db diff --git a/phpBB/phpbb/db/migration/helper.php b/phpBB/phpbb/db/migration/helper.php new file mode 100644 index 0000000000..238b2dbe53 --- /dev/null +++ b/phpBB/phpbb/db/migration/helper.php @@ -0,0 +1,82 @@ +<?php +/** +* +* @package db +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration; + +/** +* The migrator is responsible for applying new migrations in the correct order. +* +* @package db +*/ +class helper +{ + /** + * Get the schema steps from an array of schema changes + * + * This splits up $schema_changes into individual changes so that the + * changes can be chunked + * + * @param array $schema_changes from migration + * @return array + */ + public function get_schema_steps($schema_changes) + { + $steps = array(); + + // Nested level of data (only supports 1/2 currently) + $nested_level = array( + 'drop_tables' => 1, + 'add_tables' => 1, + 'change_columns' => 2, + 'add_columns' => 2, + 'drop_keys' => 2, + 'drop_columns' => 2, + 'add_primary_keys' => 2, // perform_schema_changes only uses one level, but second is in the function + 'add_unique_index' => 2, + 'add_index' => 2, + ); + + foreach ($nested_level as $change_type => $data_depth) + { + if (!empty($schema_changes[$change_type])) + { + foreach ($schema_changes[$change_type] as $key => $value) + { + if ($data_depth === 1) + { + $steps[] = array( + 'dbtools.perform_schema_changes', array(array( + $change_type => array( + (!is_int($key)) ? $key : 0 => $value, + ), + )), + ); + } + else if ($data_depth === 2) + { + foreach ($value as $key2 => $value2) + { + $steps[] = array( + 'dbtools.perform_schema_changes', array(array( + $change_type => array( + $key => array( + $key2 => $value2, + ), + ), + )), + ); + } + } + } + } + } + + return $steps; + } +} diff --git a/phpBB/phpbb/db/migration/migration.php b/phpBB/phpbb/db/migration/migration.php index aff3837279..85c5fc5d08 100644 --- a/phpBB/phpbb/db/migration/migration.php +++ b/phpBB/phpbb/db/migration/migration.php @@ -3,21 +3,13 @@ * * @package db * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ namespace phpbb\db\migration; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Abstract base class for database migrations * * Each migration consists of a set of schema and data changes to be implemented @@ -31,7 +23,7 @@ abstract class migration /** @var \phpbb\config\config */ protected $config; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\db\tools */ @@ -56,13 +48,13 @@ abstract class migration * Constructor * * @param \phpbb\config\config $config - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\db\tools $db_tools * @param string $phpbb_root_path * @param string $php_ext * @param string $table_prefix */ - public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix) + public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix) { $this->config = $config; $this->db = $db; diff --git a/phpBB/phpbb/db/migration/profilefield_base_migration.php b/phpBB/phpbb/db/migration/profilefield_base_migration.php new file mode 100644 index 0000000000..3797d670f7 --- /dev/null +++ b/phpBB/phpbb/db/migration/profilefield_base_migration.php @@ -0,0 +1,155 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration; + +abstract class profilefield_base_migration extends \phpbb\db\migration\migration +{ + protected $profilefield_name; + + protected $profilefield_database_type; + + protected $profilefield_data; + + protected $user_column_name; + + public function effectively_installed() + { + return $this->db_tools->sql_column_exists($this->table_prefix . 'profile_fields_data', 'pf_' . $this->profilefield_name); + } + + public function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'profile_fields_data' => array( + 'pf_' . $this->profilefield_name => $this->profilefield_database_type, + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'profile_fields_data' => array( + 'pf_' . $this->profilefield_name, + ), + ), + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'create_custom_field'))), + array('custom', array(array($this, 'convert_user_field_to_custom_field'))), + ); + } + + public function create_custom_field() + { + $sql = 'SELECT MAX(field_order) as max_field_order + FROM ' . PROFILE_FIELDS_TABLE; + $result = $this->db->sql_query($sql); + $max_field_order = (int) $this->db->sql_fetchfield('max_field_order'); + $this->db->sql_freeresult($result); + + $sql_ary = array_merge($this->profilefield_data, array( + 'field_order' => $max_field_order + 1, + )); + + $sql = 'INSERT INTO ' . PROFILE_FIELDS_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); + $this->db->sql_query($sql); + $field_id = (int) $this->db->sql_nextid(); + + $insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, PROFILE_LANG_TABLE); + + $sql = 'SELECT lang_id + FROM ' . LANG_TABLE; + $result = $this->db->sql_query($sql); + while ($lang_id = (int) $this->db->sql_fetchfield('lang_id')) + { + $insert_buffer->insert(array( + 'field_id' => $field_id, + 'lang_id' => $lang_id, + 'lang_name' => strtoupper(substr($this->profilefield_name, 6)),// Remove phpbb_ from field name + 'lang_explain' => '', + 'lang_default_value' => '', + )); + } + $this->db->sql_freeresult($result); + + $insert_buffer->flush(); + } + + /** + * @param int $start Start of staggering step + * @return mixed int start of the next step, null if the end was reached + */ + public function convert_user_field_to_custom_field($start) + { + $insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, $this->table_prefix . 'profile_fields_data'); + $limit = 250; + $converted_users = 0; + + $sql = 'SELECT user_id, ' . $this->user_column_name . ' + FROM ' . $this->table_prefix . 'users + WHERE ' . $this->user_column_name . " <> '' + ORDER BY user_id"; + $result = $this->db->sql_query_limit($sql, $limit, $start); + + while ($row = $this->db->sql_fetchrow($result)) + { + $converted_users++; + + $cp_data = array( + 'pf_' . $this->profilefield_name => $row[$this->user_column_name], + ); + + $sql = 'UPDATE ' . $this->table_prefix . 'profile_fields_data + SET ' . $this->db->sql_build_array('UPDATE', $cp_data) . ' + WHERE user_id = ' . (int) $row['user_id']; + $this->db->sql_query($sql); + + if (!$this->db->sql_affectedrows()) + { + $cp_data['user_id'] = (int) $row['user_id']; + $cp_data = array_merge($this->get_insert_sql_array(), $cp_data); + $insert_buffer->insert($cp_data); + } + } + $this->db->sql_freeresult($result); + + $insert_buffer->flush(); + + if ($converted_users < $limit) + { + // No more users left, we are done... + return; + } + + return $start + $limit; + } + + protected function get_insert_sql_array() + { + static $profile_row; + + if ($profile_row === null) + { + global $phpbb_container; + $manager = $phpbb_container->get('profilefields.manager'); + $profile_row = $manager->build_insert_sql_array(array()); + } + + return $profile_row; + } +} diff --git a/phpBB/phpbb/db/migration/schema_generator.php b/phpBB/phpbb/db/migration/schema_generator.php new file mode 100644 index 0000000000..5d40b0b26f --- /dev/null +++ b/phpBB/phpbb/db/migration/schema_generator.php @@ -0,0 +1,215 @@ +<?php +/** +* +* @package db +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration; + +/** +* The schema generator generates the schema based on the existing migrations +* +* @package db +*/ +class schema_generator +{ + /** @var \phpbb\config\config */ + protected $config; + + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\db\tools */ + protected $db_tools; + + /** @var array */ + protected $class_names; + + /** @var string */ + protected $table_prefix; + + /** @var string */ + protected $phpbb_root_path; + + /** @var string */ + protected $php_ext; + + /** @var array */ + protected $tables; + + /** @var array */ + protected $dependencies = array(); + + /** + * Constructor + */ + public function __construct(array $class_names, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix) + { + $this->config = $config; + $this->db = $db; + $this->db_tools = $db_tools; + $this->class_names = $class_names; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->table_prefix = $table_prefix; + } + + /** + * Loads all migrations and their application state from the database. + * + * @return array + */ + public function get_schema() + { + if (!empty($this->tables)) + { + return $this->tables; + } + + $migrations = $this->class_names; + + $tree = array(); + $check_dependencies = true; + while (!empty($migrations)) + { + foreach ($migrations as $migration_class) + { + $open_dependencies = array_diff($migration_class::depends_on(), $tree); + + if (empty($open_dependencies)) + { + $migration = new $migration_class($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix); + $tree[] = $migration_class; + $migration_key = array_search($migration_class, $migrations); + + foreach ($migration->update_schema() as $change_type => $data) + { + if ($change_type === 'add_tables') + { + foreach ($data as $table => $table_data) + { + $this->tables[$table] = $table_data; + } + } + else if ($change_type === 'drop_tables') + { + foreach ($data as $table) + { + unset($this->tables[$table]); + } + } + else if ($change_type === 'add_columns') + { + foreach ($data as $table => $add_columns) + { + foreach ($add_columns as $column => $column_data) + { + $this->tables[$table]['COLUMNS'][$column] = $column_data; + } + } + } + else if ($change_type === 'change_columns') + { + foreach ($data as $table => $change_columns) + { + foreach ($change_columns as $column => $column_data) + { + $this->tables[$table]['COLUMNS'][$column] = $column_data; + } + } + } + else if ($change_type === 'drop_columns') + { + foreach ($data as $table => $drop_columns) + { + if (is_array($drop_columns)) + { + foreach ($drop_columns as $column) + { + unset($this->tables[$table]['COLUMNS'][$column]); + } + } + else + { + unset($this->tables[$table]['COLUMNS'][$drop_columns]); + } + } + } + else if ($change_type === 'add_unique_index') + { + foreach ($data as $table => $add_index) + { + foreach ($add_index as $key => $index_data) + { + $this->tables[$table]['KEYS'][$key] = array('UNIQUE', $index_data); + } + } + } + else if ($change_type === 'add_index') + { + foreach ($data as $table => $add_index) + { + foreach ($add_index as $key => $index_data) + { + $this->tables[$table]['KEYS'][$key] = array('INDEX', $index_data); + } + } + } + else if ($change_type === 'drop_keys') + { + foreach ($data as $table => $drop_keys) + { + foreach ($drop_keys as $key) + { + unset($this->tables[$table]['KEYS'][$key]); + } + } + } + else + { + var_dump($change_type); + } + } + unset($migrations[$migration_key]); + } + else if ($check_dependencies) + { + $this->dependencies = array_merge($this->dependencies, $open_dependencies); + } + } + + // Only run this check after the first run + if ($check_dependencies) + { + $this->check_dependencies(); + $check_dependencies = false; + } + } + + ksort($this->tables); + return $this->tables; + } + + /** + * Check if one of the migrations files' dependencies can't be resolved + * by the supplied list of migrations + * + * @throws UnexpectedValueException If a dependency can't be resolved + */ + protected function check_dependencies() + { + // Strip duplicate values from array + $this->dependencies = array_unique($this->dependencies); + + foreach ($this->dependencies as $dependency) + { + if (!in_array($dependency, $this->class_names)) + { + throw new \UnexpectedValueException("Unable to resolve the dependency '$dependency'"); + } + } + } +} diff --git a/phpBB/phpbb/db/migration/tool/config.php b/phpBB/phpbb/db/migration/tool/config.php index f2149dc59a..96d358f647 100644 --- a/phpBB/phpbb/db/migration/tool/config.php +++ b/phpBB/phpbb/db/migration/tool/config.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -130,6 +130,10 @@ class config implements \phpbb\db\migration\tool\tool_interface case 'remove': $call = 'add'; + if (sizeof($arguments) == 1) + { + $arguments[] = ''; + } break; case 'update_if_equals': diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 9869dd4230..96cc6b54a5 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -19,7 +19,7 @@ class module implements \phpbb\db\migration\tool\tool_interface /** @var \phpbb\cache\service */ protected $cache; - /** @var dbal */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\user */ @@ -37,14 +37,14 @@ class module implements \phpbb\db\migration\tool\tool_interface /** * Constructor * - * @param \phpbb\db\driver\driver $db - * @param mixed $cache + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\cache\service $cache * @param \phpbb\user $user * @param string $phpbb_root_path * @param string $php_ext * @param string $modules_table */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\cache\service $cache, \phpbb\user $user, $phpbb_root_path, $php_ext, $modules_table) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\user $user, $phpbb_root_path, $php_ext, $modules_table) { $this->db = $db; $this->cache = $cache; @@ -163,11 +163,10 @@ class module implements \phpbb\db\migration\tool\tool_interface * ) * Optionally you may not send 'modes' and it will insert all of the * modules in that info file. - * @param string|bool $include_path If you would like to use a custom include * path, specify that here * @return null */ - public function add($class, $parent = 0, $data = array(), $include_path = false) + public function add($class, $parent = 0, $data = array()) { // Allows '' to be sent as 0 $parent = $parent ?: 0; @@ -182,9 +181,6 @@ class module implements \phpbb\db\migration\tool\tool_interface { // The "automatic" way $basename = (isset($data['module_basename'])) ? $data['module_basename'] : ''; - $basename = str_replace(array('/', '\\'), '', $basename); - $class = str_replace(array('/', '\\'), '', $class); - $module = $this->get_module_info($class, $basename); $result = ''; @@ -331,11 +327,10 @@ class module implements \phpbb\db\migration\tool\tool_interface * @param int|string|bool $parent The parent module_id|module_langname(0 for no parent). * Use false to ignore the parent check and check class wide. * @param int|string $module The module id|module_langname - * @param string|bool $include_path If you would like to use a custom include path, * specify that here * @return null */ - public function remove($class, $parent = 0, $module = '', $include_path = false) + public function remove($class, $parent = 0, $module = '') { // Imitation of module_add's "automatic" and "manual" method so the uninstaller works from the same set of instructions for umil_auto if (is_array($module)) @@ -343,7 +338,7 @@ class module implements \phpbb\db\migration\tool\tool_interface if (isset($module['module_langname'])) { // Manual Method - return $this->remove($class, $parent, $module['module_langname'], $include_path); + return $this->remove($class, $parent, $module['module_langname']); } // Failed. @@ -353,9 +348,7 @@ class module implements \phpbb\db\migration\tool\tool_interface } // Automatic method - $basename = str_replace(array('/', '\\'), '', $module['module_basename']); - $class = str_replace(array('/', '\\'), '', $class); - + $basename = $module['module_basename']; $module_info = $this->get_module_info($class, $basename); foreach ($module_info['modes'] as $mode => $info) @@ -412,22 +405,10 @@ class module implements \phpbb\db\migration\tool\tool_interface $module_ids[] = (int) $module_id; } $this->db->sql_freeresult($result); - - $module_name = $module; } else { - $module = (int) $module; - $sql = 'SELECT module_langname - FROM ' . $this->modules_table . " - WHERE module_id = $module - AND module_class = '" . $this->db->sql_escape($class) . "' - $parent_sql"; - $result = $this->db->sql_query($sql); - $module_name = $this->db->sql_fetchfield('module_id'); - $this->db->sql_freeresult($result); - - $module_ids[] = $module; + $module_ids[] = (int) $module; } if (!class_exists('acp_modules')) diff --git a/phpBB/phpbb/db/migration/tool/permission.php b/phpBB/phpbb/db/migration/tool/permission.php index fd2de9c8fb..6cb3f213f1 100644 --- a/phpBB/phpbb/db/migration/tool/permission.php +++ b/phpBB/phpbb/db/migration/tool/permission.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -22,7 +22,7 @@ class permission implements \phpbb\db\migration\tool\tool_interface /** @var \phpbb\cache\service */ protected $cache; - /** @var dbal */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var string */ @@ -34,13 +34,13 @@ class permission implements \phpbb\db\migration\tool\tool_interface /** * Constructor * - * @param \phpbb\db\driver\driver $db - * @param mixed $cache + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\cache\service $cache * @param \phpbb\auth\auth $auth * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\cache\service $cache, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext) { $this->db = $db; $this->cache = $cache; diff --git a/phpBB/phpbb/db/migration/tool/tool_interface.php b/phpBB/phpbb/db/migration/tool/tool_interface.php index e7b89d8858..5eb1a2f521 100644 --- a/phpBB/phpbb/db/migration/tool/tool_interface.php +++ b/phpBB/phpbb/db/migration/tool/tool_interface.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 7efb23a230..5ad8563e5c 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -3,21 +3,13 @@ * * @package db * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ namespace phpbb\db; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * The migrator is responsible for applying new migrations in the correct order. * * @package db @@ -27,12 +19,15 @@ class migrator /** @var \phpbb\config\config */ protected $config; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\db\tools */ protected $db_tools; + /** @var \phpbb\db\migration\helper */ + protected $helper; + /** @var string */ protected $table_prefix; @@ -73,11 +68,12 @@ class migrator /** * Constructor of the database migrator */ - public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\db\tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools) + public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper) { $this->config = $config; $this->db = $db; $this->db_tools = $db_tools; + $this->helper = $helper; $this->migrations_table = $migrations_table; @@ -91,6 +87,8 @@ class migrator $this->tools[$tool->get_name()] = $tool; } + $this->tools['dbtools'] = $this->db_tools; + $this->load_migration_state(); } @@ -192,6 +190,11 @@ class migrator foreach ($state['migration_depends_on'] as $depend) { + if ($this->unfulfillable($depend) !== false) + { + throw new \phpbb\db\migration\exception('MIGRATION_NOT_FULFILLABLE', $name, $depend); + } + if (!isset($this->migration_state[$depend]) || !$this->migration_state[$depend]['migration_schema_done'] || !$this->migration_state[$depend]['migration_data_done']) @@ -204,6 +207,7 @@ class migrator 'name' => $name, 'class' => $migration, 'state' => $state, + 'task' => '', ); if (!isset($this->migration_state[$name])) @@ -231,13 +235,18 @@ class migrator if (!$state['migration_schema_done']) { - $this->apply_schema_changes($migration->update_schema()); - $state['migration_schema_done'] = true; + $this->last_run_migration['task'] = 'process_schema_step'; + $steps = $this->helper->get_schema_steps($migration->update_schema()); + $result = $this->process_data_step($steps, $state['migration_data_state']); + + $state['migration_data_state'] = ($result === true) ? '' : $result; + $state['migration_schema_done'] = ($result === true); } else if (!$state['migration_data_done']) { try { + $this->last_run_migration['task'] = 'process_data_step'; $result = $this->process_data_step($migration->update_data(), $state['migration_data_state']); $state['migration_data_state'] = ($result === true) ? '' : $result; @@ -308,6 +317,7 @@ class migrator $this->last_run_migration = array( 'name' => $name, 'class' => $migration, + 'task' => '', ); if ($state['migration_data_done']) @@ -328,33 +338,28 @@ class migrator $this->set_migration_state($name, $state); } - else + else if ($state['migration_schema_done']) { - $this->apply_schema_changes($migration->revert_schema()); + $steps = $this->helper->get_schema_steps($migration->revert_schema()); + $result = $this->process_data_step($steps, $state['migration_data_state']); - $sql = 'DELETE FROM ' . $this->migrations_table . " - WHERE migration_name = '" . $this->db->sql_escape($name) . "'"; - $this->db->sql_query($sql); + $state['migration_data_state'] = ($result === true) ? '' : $result; + $state['migration_schema_done'] = ($result === true) ? false : true; - unset($this->migration_state[$name]); + if (!$state['migration_schema_done']) + { + $sql = 'DELETE FROM ' . $this->migrations_table . " + WHERE migration_name = '" . $this->db->sql_escape($name) . "'"; + $this->db->sql_query($sql); + + unset($this->migration_state[$name]); + } } return true; } /** - * Apply schema changes from a migration - * - * Just calls db_tools->perform_schema_changes - * - * @param array $schema_changes from migration - */ - protected function apply_schema_changes($schema_changes) - { - $this->db_tools->perform_schema_changes($schema_changes); - } - - /** * Process the data step of the migration * * @param array $steps The steps to run @@ -374,7 +379,7 @@ class migrator foreach ($steps as $step_identifier => $step) { - $last_result = false; + $last_result = 0; if ($state) { // Continue until we reach the step that matches the last step called @@ -435,7 +440,7 @@ class migrator * @param bool $reverse False to install, True to attempt uninstallation by reversing the call * @return null */ - protected function run_step($step, $last_result = false, $reverse = false) + protected function run_step($step, $last_result = 0, $reverse = false) { $callable_and_parameters = $this->get_callable_from_step($step, $last_result, $reverse); @@ -458,7 +463,7 @@ class migrator * @param bool $reverse False to install, True to attempt uninstallation by reversing the call * @return array Array with parameters for call_user_func_array(), 0 is the callable, 1 is parameters */ - protected function get_callable_from_step(array $step, $last_result = false, $reverse = false) + protected function get_callable_from_step(array $step, $last_result = 0, $reverse = false) { $type = $step[0]; $parameters = $step[1]; @@ -497,16 +502,24 @@ class migrator return $this->get_callable_from_step($step); break; + case 'custom': if (!is_callable($parameters[0])) { throw new \phpbb\db\migration\exception('MIGRATION_INVALID_DATA_CUSTOM_NOT_CALLABLE', $step); } - return array( - $parameters[0], - array($last_result), - ); + if ($reverse) + { + return false; + } + else + { + return array( + $parameters[0], + array($last_result), + ); + } break; default: @@ -626,6 +639,7 @@ class migrator { continue; } + return false; } diff --git a/phpBB/phpbb/db/sql_insert_buffer.php b/phpBB/phpbb/db/sql_insert_buffer.php index 7bbd213bdc..0236a55b82 100644 --- a/phpBB/phpbb/db/sql_insert_buffer.php +++ b/phpBB/phpbb/db/sql_insert_buffer.php @@ -10,14 +10,6 @@ namespace phpbb\db; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Collects rows for insert into a database until the buffer size is reached. * Then flushes the buffer to the database and starts over again. * @@ -57,7 +49,7 @@ if (!defined('IN_PHPBB')) */ class sql_insert_buffer { - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var string */ @@ -70,11 +62,11 @@ class sql_insert_buffer protected $buffer = array(); /** - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param string $table_name * @param int $max_buffered_rows */ - public function __construct(\phpbb\db\driver\driver $db, $table_name, $max_buffered_rows = 500) + public function __construct(\phpbb\db\driver\driver_interface $db, $table_name, $max_buffered_rows = 500) { $this->db = $db; $this->table_name = $table_name; diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 1f156fbb04..2b0132075b 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -10,14 +10,6 @@ namespace phpbb\db; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Database Tools for handling cross-db actions such as altering columns, etc. * Currently not supported is returning SQL for creating tables. * @@ -33,7 +25,7 @@ class tools /** * @var object DB object */ - var $db = NULL; + var $db = null; /** * The Column types for every database we support @@ -42,6 +34,12 @@ class tools var $dbms_type_map = array(); /** + * Is the used MS SQL Server a SQL Server 2000? + * @var bool + */ + protected $is_sql_server_2000; + + /** * Get the column types for every database we support * * @return array @@ -312,10 +310,10 @@ class tools /** * Constructor. Set DB Object and set {@link $return_statements return_statements}. * - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param bool $return_statements True if only statements should be returned and no SQL being executed */ - public function __construct(\phpbb\db\driver\driver $db, $return_statements = false) + public function __construct(\phpbb\db\driver\driver_interface $db, $return_statements = false) { $this->db = $db; $this->return_statements = $return_statements; @@ -475,9 +473,6 @@ class tools // Determine if we have created a PRIMARY KEY in the earliest $primary_key_gen = false; - // Determine if the table must be created with TEXTIMAGE - $create_textimage = false; - // Determine if the table requires a sequence $create_sequence = false; @@ -494,13 +489,22 @@ class tools break; } + if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative') + { + if (!isset($table_data['PRIMARY_KEY'])) + { + $table_data['COLUMNS']['mssqlindex'] = array('UINT', null, 'auto_increment'); + $table_data['PRIMARY_KEY'] = 'mssqlindex'; + } + } + // Iterate through the columns to create a table foreach ($table_data['COLUMNS'] as $column_name => $column_data) { // here lies an array, filled with information compiled on the column's data $prepared_column = $this->sql_prepare_column_data($table_name, $column_name, $column_data); - if (isset($prepared_column['auto_increment']) && strlen($column_name) > 26) // "${column_name}_gen" + if (isset($prepared_column['auto_increment']) && $prepared_column['auto_increment'] && strlen($column_name) > 26) // "${column_name}_gen" { trigger_error("Index name '${column_name}_gen' on table '$table_name' is too long. The maximum auto increment column length is 26 characters.", E_USER_ERROR); } @@ -524,12 +528,6 @@ class tools $primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set']; } - // create textimage DDL based off of the existance of certain column types - if (!$create_textimage) - { - $create_textimage = isset($prepared_column['textimage']) && $prepared_column['textimage']; - } - // create sequence DDL based off of the existance of auto incrementing columns if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment']) { @@ -544,13 +542,9 @@ class tools switch ($this->sql_layer) { case 'firebird': - $table_sql .= "\n);"; - $statements[] = $table_sql; - break; - case 'mssql': case 'mssqlnative': - $table_sql .= "\n) ON [PRIMARY]" . (($create_textimage) ? ' TEXTIMAGE_ON [PRIMARY]' : ''); + $table_sql .= "\n);"; $statements[] = $table_sql; break; } @@ -904,7 +898,7 @@ class tools } } - // Add unqiue indexes? + // Add unique indexes? if (!empty($schema_changes['add_unique_index'])) { foreach ($schema_changes['add_unique_index'] as $table => $index_array) @@ -1315,7 +1309,7 @@ class tools } /** - * Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes. + * Check if a specified index exists in table. Does not return PRIMARY KEY indexes. * * @param string $table_name Table to check the index at * @param string $index_name The index name to check @@ -1482,52 +1476,7 @@ class tools } // Get type - if (strpos($column_data[0], ':') !== false) - { - list($orig_column_type, $column_length) = explode(':', $column_data[0]); - if (!is_array($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'])) - { - $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'], $column_length); - } - else - { - if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'])) - { - switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][0]) - { - case 'div': - $column_length /= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][1]; - $column_length = ceil($column_length); - $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); - break; - } - } - - if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'])) - { - switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][0]) - { - case 'mult': - $column_length *= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][1]; - if ($column_length > $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][2]) - { - $column_type = $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][3]; - } - else - { - $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); - } - break; - } - } - } - $orig_column_type .= ':'; - } - else - { - $orig_column_type = $column_data[0]; - $column_type = $this->dbms_type_map[$this->sql_layer][$column_data[0]]; - } + list($column_type, $orig_column_type) = $this->get_column_type($column_data[0]); // Adjust default value if db-dependent specified if (is_array($column_data[1])) @@ -1703,6 +1652,65 @@ class tools } /** + * Get the column's database type from the type map + * + * @param string $column_map_type + * @return array column type for this database + * and map type without length + */ + function get_column_type($column_map_type) + { + if (strpos($column_map_type, ':') !== false) + { + list($orig_column_type, $column_length) = explode(':', $column_map_type); + if (!is_array($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'])) + { + $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'], $column_length); + } + else + { + if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'])) + { + switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][0]) + { + case 'div': + $column_length /= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][1]; + $column_length = ceil($column_length); + $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); + break; + } + } + + if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'])) + { + switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][0]) + { + case 'mult': + $column_length *= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][1]; + if ($column_length > $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][2]) + { + $column_type = $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][3]; + } + else + { + $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length); + } + break; + } + } + } + $orig_column_type .= ':'; + } + else + { + $orig_column_type = $column_map_type; + $column_type = $this->dbms_type_map[$this->sql_layer][$column_map_type]; + } + + return array($column_type, $orig_column_type); + } + + /** * Add new column */ function sql_column_add($table_name, $column_name, $column_data, $inline = false) @@ -1844,23 +1852,46 @@ class tools case 'mssql': case 'mssqlnative': - // remove default cosntraints first - // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx - $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) - SET @drop_default_name = - (SELECT so.name FROM sysobjects so - JOIN sysconstraints sc ON so.id = sc.constid - WHERE object_name(so.parent_obj) = '{$table_name}' - AND so.xtype = 'D' - AND sc.colid = (SELECT colid FROM syscolumns - WHERE id = object_id('{$table_name}') - AND name = '{$column_name}')) - IF @drop_default_name <> '' - BEGIN - SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' - EXEC(@cmd) - END"; + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $indexes = $this->mssql_get_existing_indexes($table_name, $column_name); + + // Drop any indexes + $recreate_indexes = array(); + if (!empty($indexes)) + { + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_index_drop($table_name, $index_name); + $statements = array_merge($statements, $result); + if (sizeof($index_data) > 1) + { + // Remove this column from the index and recreate it + $recreate_indexes[$index_name] = array_diff($index_data, array($column_name)); + } + } + } + + // Drop default value constraint + $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Remove the column $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']'; + + if (!empty($recreate_indexes)) + { + // Recreate indexes after we removed the column + foreach ($recreate_indexes as $index_name => $index_data) + { + $result = $this->sql_create_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + $this->return_statements = $old_return_statements; break; case 'mysql_40': @@ -2063,7 +2094,7 @@ class tools $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD "; $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED ("; $sql .= '[' . implode("],\n\t\t[", $column) . ']'; - $sql .= ') ON [PRIMARY]'; + $sql .= ')'; $statements[] = $sql; break; @@ -2161,7 +2192,7 @@ class tools case 'mssql': case 'mssqlnative': - $statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]'; + $statements[] = 'CREATE UNIQUE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; break; } @@ -2214,7 +2245,7 @@ class tools case 'mssql': case 'mssqlnative': - $statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]'; + $statements[] = 'CREATE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; break; } @@ -2342,28 +2373,46 @@ class tools case 'mssql': case 'mssqlnative': + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $indexes = $this->mssql_get_existing_indexes($table_name, $column_name); + + // Drop any indexes + if (!empty($indexes)) + { + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_index_drop($table_name, $index_name); + $statements = array_merge($statements, $result); + } + } + + // Drop default value constraint + $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Change the column $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; if (!empty($column_data['default'])) { - // Using TRANSACT-SQL for this statement because we do not want to have colliding data if statements are executed at a later stage - $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) - SET @drop_default_name = - (SELECT so.name FROM sysobjects so - JOIN sysconstraints sc ON so.id = sc.constid - WHERE object_name(so.parent_obj) = '{$table_name}' - AND so.xtype = 'D' - AND sc.colid = (SELECT colid FROM syscolumns - WHERE id = object_id('{$table_name}') - AND name = '{$column_name}')) - IF @drop_default_name <> '' - BEGIN - SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' - EXEC(@cmd) - END - SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]' - EXEC(@cmd)"; + // Add new default value constraint + $statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $this->db->sql_escape($column_data['default']) . ' FOR [' . $column_name . ']'; } + + if (!empty($indexes)) + { + // Recreate indexes after we changed the column + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_create_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + $this->return_statements = $old_return_statements; break; case 'mysql_40': @@ -2497,4 +2546,159 @@ class tools return $this->_sql_run_sql($statements); } + + /** + * Get queries to drop the default constraints of a column + * + * We need to drop the default constraints of a column, + * before being able to change their type or deleting them. + * + * @param string $table_name + * @param string $column_name + * @return array Array with SQL statements + */ + protected function mssql_get_drop_default_constraints_queries($table_name, $column_name) + { + $statements = array(); + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT so.name AS def_name + FROM sysobjects so + JOIN sysconstraints sc ON so.id = sc.constid + WHERE object_name(so.parent_obj) = '{$table_name}' + AND so.xtype = 'D' + AND sc.colid = (SELECT colid FROM syscolumns + WHERE id = object_id('{$table_name}') + AND name = '{$column_name}')"; + } + else + { + $sql = "SELECT dobj.name AS def_name + FROM sys.columns col + LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D') + WHERE col.object_id = object_id('{$table_name}') + AND col.name = '{$column_name}' + AND dobj.name IS NOT NULL"; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']'; + } + $this->db->sql_freeresult($result); + + return $statements; + } + + /** + * Get a list with existing indexes for the column + * + * @param string $table_name + * @param string $column_name + * @return array Array with Index name => columns + */ + protected function mssql_get_existing_indexes($table_name, $column_name) + { + $existing_indexes = array(); + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND cols.name = '{$column_name}'"; + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND cols.name = '{$column_name}'"; + } + + $result = $this->db->sql_query($sql); + $existing_indexes = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $existing_indexes[$row['phpbb_index_name']] = array(); + } + $this->db->sql_freeresult($result); + + if (empty($existing_indexes)) + { + return array(); + } + + if ($this->mssql_is_sql_server_2000()) + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; + } + $this->db->sql_freeresult($result); + + return $existing_indexes; + } + + /** + * Is the used MS SQL Server a SQL Server 2000? + * + * @return bool + */ + protected function mssql_is_sql_server_2000() + { + if ($this->is_sql_server_2000 === null) + { + $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version"; + $result = $this->db->sql_query($sql); + $properties = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + $this->is_sql_server_2000 = $properties['mssql_version'][0] == '8'; + } + + return $this->is_sql_server_2000; + } } diff --git a/phpBB/phpbb/di/extension/config.php b/phpBB/phpbb/di/extension/config.php index 85b374a3ca..2603e7b358 100644 --- a/phpBB/phpbb/di/extension/config.php +++ b/phpBB/phpbb/di/extension/config.php @@ -9,14 +9,6 @@ namespace phpbb\di\extension; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; @@ -78,7 +70,7 @@ class config extends Extension { if (preg_match('#^[a-z]+$#', $acm_type)) { - return '\\phpbb\cache\driver\\'.$acm_type; + return 'phpbb\\cache\\driver\\' . $acm_type; } return $acm_type; diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 1f6b700973..455dfa7ecd 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -9,14 +9,6 @@ namespace phpbb\di\extension; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; diff --git a/phpBB/phpbb/di/extension/ext.php b/phpBB/phpbb/di/extension/ext.php index cf623a7c87..4f2f24cb1a 100644 --- a/phpBB/phpbb/di/extension/ext.php +++ b/phpBB/phpbb/di/extension/ext.php @@ -9,14 +9,6 @@ namespace phpbb\di\extension; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; diff --git a/phpBB/phpbb/di/pass/collection_pass.php b/phpBB/phpbb/di/pass/collection_pass.php index ffc5a41f6d..507271de3e 100644 --- a/phpBB/phpbb/di/pass/collection_pass.php +++ b/phpBB/phpbb/di/pass/collection_pass.php @@ -9,14 +9,6 @@ namespace phpbb\di\pass; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; diff --git a/phpBB/phpbb/di/pass/kernel_pass.php b/phpBB/phpbb/di/pass/kernel_pass.php index 6a9124ad78..9c2b193361 100644 --- a/phpBB/phpbb/di/pass/kernel_pass.php +++ b/phpBB/phpbb/di/pass/kernel_pass.php @@ -9,14 +9,6 @@ namespace phpbb\di\pass; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; diff --git a/phpBB/phpbb/di/service_collection.php b/phpBB/phpbb/di/service_collection.php index fccdd77071..65df9ab1d1 100644 --- a/phpBB/phpbb/di/service_collection.php +++ b/phpBB/phpbb/di/service_collection.php @@ -9,14 +9,6 @@ namespace phpbb\di; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\DependencyInjection\ContainerInterface; /** diff --git a/phpBB/phpbb/error_collector.php b/phpBB/phpbb/error_collector.php index 9b3216e32f..297972c6b8 100644 --- a/phpBB/phpbb/error_collector.php +++ b/phpBB/phpbb/error_collector.php @@ -9,14 +9,6 @@ namespace phpbb; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class error_collector { var $errors; diff --git a/phpBB/phpbb/event/data.php b/phpBB/phpbb/event/data.php index 3481023b74..fbb16574ed 100644 --- a/phpBB/phpbb/event/data.php +++ b/phpBB/phpbb/event/data.php @@ -9,62 +9,54 @@ namespace phpbb\event; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\EventDispatcher\Event; class data extends Event implements \ArrayAccess { - private $data; - - public function __construct(array $data = array()) - { - $this->set_data($data); - } - - public function set_data(array $data = array()) - { - $this->data = $data; - } - - public function get_data() - { - return $this->data; - } - - /** - * Returns data filtered to only include specified keys. - * - * This effectively discards any keys added to data by hooks. - */ - public function get_data_filtered($keys) - { - return array_intersect_key($this->data, array_flip($keys)); - } - - public function offsetExists($offset) - { - return isset($this->data[$offset]); - } - - public function offsetGet($offset) - { - return isset($this->data[$offset]) ? $this->data[$offset] : null; - } - - public function offsetSet($offset, $value) - { - $this->data[$offset] = $value; - } - - public function offsetUnset($offset) - { - unset($this->data[$offset]); - } + private $data; + + public function __construct(array $data = array()) + { + $this->set_data($data); + } + + public function set_data(array $data = array()) + { + $this->data = $data; + } + + public function get_data() + { + return $this->data; + } + + /** + * Returns data filtered to only include specified keys. + * + * This effectively discards any keys added to data by hooks. + */ + public function get_data_filtered($keys) + { + return array_intersect_key($this->data, array_flip($keys)); + } + + public function offsetExists($offset) + { + return isset($this->data[$offset]); + } + + public function offsetGet($offset) + { + return isset($this->data[$offset]) ? $this->data[$offset] : null; + } + + public function offsetSet($offset, $value) + { + $this->data[$offset] = $value; + } + + public function offsetUnset($offset) + { + unset($this->data[$offset]); + } } diff --git a/phpBB/phpbb/event/dispatcher.php b/phpBB/phpbb/event/dispatcher.php index cc3733692e..74b35eb78d 100644 --- a/phpBB/phpbb/event/dispatcher.php +++ b/phpBB/phpbb/event/dispatcher.php @@ -9,14 +9,6 @@ namespace phpbb\event; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; /** diff --git a/phpBB/phpbb/event/extension_subscriber_loader.php b/phpBB/phpbb/event/extension_subscriber_loader.php index ab50a589fe..6408f93e2a 100644 --- a/phpBB/phpbb/event/extension_subscriber_loader.php +++ b/phpBB/phpbb/event/extension_subscriber_loader.php @@ -9,39 +9,27 @@ namespace phpbb\event; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\EventDispatcher\EventDispatcherInterface; class extension_subscriber_loader { private $dispatcher; - private $extension_manager; + private $listener_collection; - public function __construct(EventDispatcherInterface $dispatcher, \phpbb\extension\manager $extension_manager) + public function __construct(EventDispatcherInterface $dispatcher, \phpbb\di\service_collection $listener_collection) { $this->dispatcher = $dispatcher; - $this->extension_manager = $extension_manager; + $this->listener_collection = $listener_collection; } public function load() { - $finder = $this->extension_manager->get_finder(); - $subscriber_classes = $finder - ->extension_directory('/event') - ->core_path('event/') - ->get_classes(); - - foreach ($subscriber_classes as $class) + if (!empty($this->listener_collection)) { - $subscriber = new $class(); - $this->dispatcher->addSubscriber($subscriber); + foreach ($this->listener_collection as $listener) + { + $this->dispatcher->addSubscriber($listener); + } } } } diff --git a/phpBB/phpbb/event/kernel_exception_subscriber.php b/phpBB/phpbb/event/kernel_exception_subscriber.php index 09103680e8..8a4de1fbad 100644 --- a/phpBB/phpbb/event/kernel_exception_subscriber.php +++ b/phpBB/phpbb/event/kernel_exception_subscriber.php @@ -9,14 +9,6 @@ namespace phpbb\event; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; @@ -72,7 +64,6 @@ class kernel_exception_subscriber implements EventSubscriberInterface page_footer(true, false, false); - $status_code = $exception instanceof HttpException ? $exception->getStatusCode() : 500; $response = new Response($this->template->assign_display('body'), $status_code); $event->setResponse($response); diff --git a/phpBB/phpbb/event/kernel_request_subscriber.php b/phpBB/phpbb/event/kernel_request_subscriber.php index a629dd8440..7d5418498b 100644 --- a/phpBB/phpbb/event/kernel_request_subscriber.php +++ b/phpBB/phpbb/event/kernel_request_subscriber.php @@ -9,14 +9,6 @@ namespace phpbb\event; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseEvent; diff --git a/phpBB/phpbb/event/kernel_terminate_subscriber.php b/phpBB/phpbb/event/kernel_terminate_subscriber.php index de441da102..32dba322d1 100644 --- a/phpBB/phpbb/event/kernel_terminate_subscriber.php +++ b/phpBB/phpbb/event/kernel_terminate_subscriber.php @@ -9,14 +9,6 @@ namespace phpbb\event; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\PostResponseEvent; diff --git a/phpBB/phpbb/event/md_exporter.php b/phpBB/phpbb/event/md_exporter.php new file mode 100644 index 0000000000..af86882885 --- /dev/null +++ b/phpBB/phpbb/event/md_exporter.php @@ -0,0 +1,439 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\event; + +/** +* Class md_exporter +* Crawls through a markdown file and grabs all events +* +* @package phpbb\event +*/ +class md_exporter +{ + /** @var string Path where we look for files*/ + protected $path; + + /** @var string phpBB Root Path */ + protected $root_path; + + /** @var string */ + protected $filter; + + /** @var string */ + protected $current_event; + + /** @var array */ + protected $events; + + /** + * @param string $phpbb_root_path + * @param mixed $extension String 'vendor/ext' to filter, null for phpBB core + */ + public function __construct($phpbb_root_path, $extension = null) + { + $this->root_path = $phpbb_root_path; + $this->path = $this->root_path; + if ($extension) + { + $this->path .= 'ext/' . $extension . '/'; + } + + $this->events = array(); + $this->events_by_file = array(); + $this->filter = $this->current_event = ''; + } + + /** + * Get the list of all events + * + * @return array Array with events: name => details + */ + public function get_events() + { + return $this->events; + } + + /** + * @param string $md_file Relative from phpBB root + * @return int Number of events found + * @throws \LogicException + */ + public function crawl_phpbb_directory_adm($md_file) + { + $this->crawl_eventsmd($md_file, 'adm'); + + $file_list = $this->get_recursive_file_list($this->path . 'adm/style/'); + foreach ($file_list as $file) + { + $file_name = 'adm/style/' . $file; + $this->validate_events_from_file($file_name, $this->crawl_file_for_events($file_name)); + } + + return sizeof($this->events); + } + + /** + * @param string $md_file Relative from phpBB root + * @return int Number of events found + * @throws \LogicException + */ + public function crawl_phpbb_directory_styles($md_file) + { + $this->crawl_eventsmd($md_file, 'styles'); + + $styles = array('prosilver', 'subsilver2'); + foreach ($styles as $style) + { + $file_list = $this->get_recursive_file_list( + $this->path . 'styles/' . $style . '/template/' + ); + + foreach ($file_list as $file) + { + $file_name = 'styles/' . $style . '/template/' . $file; + $this->validate_events_from_file($file_name, $this->crawl_file_for_events($file_name)); + } + } + + return sizeof($this->events); + } + + /** + * @param string $md_file Relative from phpBB root + * @param string $filter Should be 'styles' or 'adm' + * @return int Number of events found + * @throws \LogicException + */ + public function crawl_eventsmd($md_file, $filter) + { + if (!file_exists($this->path . $md_file)) + { + throw new \LogicException("The event docs file '{$md_file}' could not be found"); + } + + $file_content = file_get_contents($this->path . $md_file); + $this->filter = $filter; + + $events = explode("\n\n", $file_content); + foreach ($events as $event) + { + // Last row of the file + if (strpos($event, "\n===\n") === false) + { + continue; + } + + list($event_name, $details) = explode("\n===\n", $event, 2); + $this->validate_event_name($event_name); + $this->current_event = $event_name; + + if (isset($this->events[$this->current_event])) + { + throw new \LogicException("The event '{$this->current_event}' is defined multiple times"); + } + + if (($this->filter == 'adm' && strpos($this->current_event, 'acp_') !== 0) + || ($this->filter == 'styles' && strpos($this->current_event, 'acp_') === 0)) + { + continue; + } + + list($file_details, $details) = explode("\n* Since: ", $details, 2); + list($since, $description) = explode("\n* Purpose: ", $details, 2); + + $files = $this->validate_file_list($file_details); + $since = $this->validate_since($since); + + $this->events[$event_name] = array( + 'event' => $this->current_event, + 'files' => $files, + 'since' => $since, + 'description' => $description, + ); + } + + return sizeof($this->events); + } + + /** + * Format the php events as a wiki table + * @return string Number of events found + */ + public function export_events_for_wiki() + { + if ($this->filter === 'adm') + { + $wiki_page = '= ACP Template Events =' . "\n"; + $wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n"; + $wiki_page .= '! Identifier !! Placement !! Added in Release !! Explanation' . "\n"; + } + else + { + $wiki_page = '= Template Events =' . "\n"; + $wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n"; + $wiki_page .= '! Identifier !! Prosilver Placement (If applicable) !! Subsilver Placement (If applicable) !! Added in Release !! Explanation' . "\n"; + } + + foreach ($this->events as $event_name => $event) + { + $wiki_page .= "|- id=\"{$event_name}\"\n"; + $wiki_page .= "| [[#{$event_name}|{$event_name}]] || "; + + if ($this->filter === 'adm') + { + $wiki_page .= implode(', ', $event['files']['adm']); + } + else + { + $wiki_page .= implode(', ', $event['files']['prosilver']) . ' || ' . implode(', ', $event['files']['subsilver2']); + } + + $wiki_page .= " || {$event['since']} || " . str_replace("\n", ' ', $event['description']) . "\n"; + } + $wiki_page .= '|}' . "\n"; + + return $wiki_page; + } + + /** + * Validates a template event name + * + * @param $event_name + * @return null + * @throws \LogicException + */ + public function validate_event_name($event_name) + { + if (!preg_match('#^([a-z][a-z0-9]*(?:_[a-z][a-z0-9]*)+)$#', $event_name)) + { + throw new \LogicException("Invalid event name '{$event_name}'"); + } + } + + /** + * Validate "Since" Information + * + * @param string $since + * @return string + * @throws \LogicException + */ + public function validate_since($since) + { + if (!preg_match('#^\d+\.\d+\.\d+(?:-(?:a|b|rc|pl)\d+)?$#', $since)) + { + throw new \LogicException("Invalid since information found for event '{$this->current_event}'"); + } + + return $since; + } + + /** + * Validate the files list + * + * @param string $file_details + * @return array + * @throws \LogicException + */ + public function validate_file_list($file_details) + { + $files_list = array( + 'prosilver' => array(), + 'subsilver2' => array(), + 'adm' => array(), + ); + + // Multi file list + if (strpos($file_details, "* Locations:\n + ") === 0) + { + $file_details = substr($file_details, strlen("* Locations:\n + ")); + $files = explode("\n + ", $file_details); + foreach ($files as $file) + { + if (!file_exists($this->path . $file) || substr($file, -5) !== '.html') + { + throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 1); + } + + if (($this->filter !== 'adm') && strpos($file, 'styles/prosilver/template/') === 0) + { + $files_list['prosilver'][] = substr($file, strlen('styles/prosilver/template/')); + } + else if (($this->filter !== 'adm') && strpos($file, 'styles/subsilver2/template/') === 0) + { + $files_list['subsilver2'][] = substr($file, strlen('styles/subsilver2/template/')); + } + else if (($this->filter === 'adm') && strpos($file, 'adm/style/') === 0) + { + $files_list['adm'][] = substr($file, strlen('adm/style/')); + } + else + { + throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 2); + } + + $this->events_by_file[$file][] = $this->current_event; + } + } + else if ($this->filter == 'adm') + { + $file = substr($file_details, strlen('* Location: ')); + if (!file_exists($this->path . $file) || substr($file, -5) !== '.html') + { + throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 1); + } + + $files_list['adm'][] = substr($file, strlen('adm/style/')); + + $this->events_by_file[$file][] = $this->current_event; + } + else + { + throw new \LogicException("Invalid file list found for event '{$this->current_event}'", 2); + } + + return $files_list; + } + + /** + * Get all template events in a template file + * + * @param string $file + * @return array + * @throws \LogicException + */ + public function crawl_file_for_events($file) + { + if (!file_exists($this->path . $file)) + { + throw new \LogicException("File '{$file}' does not exist", 1); + } + + $event_list = array(); + $file_content = file_get_contents($this->path . $file); + + $events = explode('<!-- EVENT ', $file_content); + // Remove the code before the first event + array_shift($events); + foreach ($events as $event) + { + $event = explode(' -->', $event, 2); + $event_list[] = array_shift($event); + } + + return $event_list; + } + + /** + * Validates whether all events from $file are in the md file and vice-versa + * + * @param string $file + * @param array $events + * @return true + * @throws \LogicException + */ + public function validate_events_from_file($file, array $events) + { + if (empty($this->events_by_file[$file]) && empty($events)) + { + return true; + } + else if (empty($this->events_by_file[$file])) + { + $event_list = implode("', '", $events); + throw new \LogicException("File '{$file}' should not contain events, but contains: " + . "'{$event_list}'", 1); + } + else if (empty($events)) + { + $event_list = implode("', '", $this->events_by_file[$file]); + throw new \LogicException("File '{$file}' contains no events, but should contain: " + . "'{$event_list}'", 1); + } + + $missing_events_from_file = array(); + foreach ($this->events_by_file[$file] as $event) + { + if (!in_array($event, $events)) + { + $missing_events_from_file[] = $event; + } + } + + if (!empty($missing_events_from_file)) + { + $event_list = implode("', '", $missing_events_from_file); + throw new \LogicException("File '{$file}' does not contain events: '{$event_list}'", 2); + } + + $missing_events_from_md = array(); + foreach ($events as $event) + { + if (!in_array($event, $this->events_by_file[$file])) + { + $missing_events_from_md[] = $event; + } + } + + if (!empty($missing_events_from_md)) + { + $event_list = implode("', '", $missing_events_from_md); + throw new \LogicException("File '{$file}' contains additional events: '{$event_list}'", 3); + } + + return true; + } + + /** + * Returns a list of files in $dir + * + * Works recursive with any depth + * + * @param string $dir Directory to go through + * @return array List of files (including directories) + */ + public function get_recursive_file_list($dir) + { + try + { + $iterator = new \RecursiveIteratorIterator( + new \phpbb\recursive_dot_prefix_filter_iterator( + new \RecursiveDirectoryIterator( + $dir, + \FilesystemIterator::SKIP_DOTS + ) + ), + \RecursiveIteratorIterator::SELF_FIRST + ); + } + catch (\Exception $e) + { + return array(); + } + + $files = array(); + foreach ($iterator as $file_info) + { + /** @var \RecursiveDirectoryIterator $file_info */ + if ($file_info->isDir()) + { + continue; + } + + $relative_path = $iterator->getInnerIterator()->getSubPathname(); + + if (substr($relative_path, -5) == '.html') + { + $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $relative_path); + } + } + + return $files; + } +} diff --git a/phpBB/phpbb/event/php_exporter.php b/phpBB/phpbb/event/php_exporter.php new file mode 100644 index 0000000000..d86ee3c045 --- /dev/null +++ b/phpBB/phpbb/event/php_exporter.php @@ -0,0 +1,608 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\event; + +/** +* Class php_exporter +* Crawls through a list of files and grabs all php-events +* +* @package phpbb\event +*/ +class php_exporter +{ + /** @var string Path where we look for files*/ + protected $path; + + /** @var string phpBB Root Path */ + protected $root_path; + + /** @var string */ + protected $current_file; + + /** @var string */ + protected $current_event; + + /** @var int */ + protected $current_event_line; + + /** @var array */ + protected $events; + + /** @var array */ + protected $file_lines; + + /** + * @param string $phpbb_root_path + * @param mixed $extension String 'vendor/ext' to filter, null for phpBB core + */ + public function __construct($phpbb_root_path, $extension = null) + { + $this->root_path = $phpbb_root_path; + $this->path = $phpbb_root_path; + $this->events = $this->file_lines = array(); + $this->current_file = $this->current_event = ''; + $this->current_event_line = 0; + + $this->path = $this->root_path; + if ($extension) + { + $this->path .= 'ext/' . $extension . '/'; + } + } + + /** + * Get the list of all events + * + * @return array Array with events: name => details + */ + public function get_events() + { + return $this->events; + } + + /** + * Set current event data + * + * @param string $name Name of the current event (used for error messages) + * @param int $line Line where the current event is placed in + * @return null + */ + public function set_current_event($name, $line) + { + $this->current_event = $name; + $this->current_event_line = $line; + } + + /** + * Set the content of this file + * + * @param array $content Array with the lines of the file + * @return null + */ + public function set_content($content) + { + $this->file_lines = $content; + } + + /** + * Crawl the phpBB/ directory for php events + * @return int The number of events found + */ + public function crawl_phpbb_directory_php() + { + $files = $this->get_recursive_file_list(); + $this->events = array(); + foreach ($files as $file) + { + $this->crawl_php_file($file); + } + ksort($this->events); + + return sizeof($this->events); + } + + /** + * Returns a list of files in $dir + * + * @return array List of files (including the path) + */ + public function get_recursive_file_list() + { + try + { + $iterator = new \RecursiveIteratorIterator( + new \phpbb\event\recursive_event_filter_iterator( + new \RecursiveDirectoryIterator( + $this->path, + \FilesystemIterator::SKIP_DOTS + ), + $this->path + ), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + } + catch (\Exception $e) + { + return array(); + } + + $files = array(); + foreach ($iterator as $file_info) + { + /** @var \RecursiveDirectoryIterator $file_info */ + $relative_path = $iterator->getInnerIterator()->getSubPathname(); + $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $relative_path); + } + + return $files; + } + + /** + * Format the php events as a wiki table + * @return string + */ + public function export_events_for_wiki() + { + $wiki_page = '= PHP Events (Hook Locations) =' . "\n"; + $wiki_page .= '{| class="sortable zebra" cellspacing="0" cellpadding="5"' . "\n"; + $wiki_page .= '! Identifier !! Placement !! Arguments !! Added in Release !! Explanation' . "\n"; + foreach ($this->events as $event) + { + $wiki_page .= '|- id="' . $event['event'] . '"' . "\n"; + $wiki_page .= '| [[#' . $event['event'] . '|' . $event['event'] . ']] || ' . $event['file'] . ' || ' . implode(', ', $event['arguments']) . ' || ' . $event['since'] . ' || ' . $event['description'] . "\n"; + } + $wiki_page .= '|}' . "\n"; + + return $wiki_page; + } + + /** + * @param string $file + * @return int Number of events found in this file + * @throws \LogicException + */ + public function crawl_php_file($file) + { + $this->current_file = $file; + $this->file_lines = array(); + $content = file_get_contents($this->path . $this->current_file); + $num_events_found = 0; + + if (strpos($content, "dispatcher->trigger_event('") || strpos($content, "dispatcher->dispatch('")) + { + $this->set_content(explode("\n", $content)); + for ($i = 0, $num_lines = sizeof($this->file_lines); $i < $num_lines; $i++) + { + $event_line = false; + $found_trigger_event = strpos($this->file_lines[$i], "dispatcher->trigger_event('"); + $arguments = array(); + if ($found_trigger_event !== false) + { + $event_line = $i; + $this->set_current_event($this->get_event_name($event_line, false), $event_line); + + // Find variables of the event + $arguments = $this->get_vars_from_array(); + $doc_vars = $this->get_vars_from_docblock(); + $this->validate_vars_docblock_array($arguments, $doc_vars); + } + else + { + $found_dispatch = strpos($this->file_lines[$i], "dispatcher->dispatch('"); + if ($found_dispatch !== false) + { + $event_line = $i; + $this->set_current_event($this->get_event_name($event_line, true), $event_line); + } + } + + if ($event_line) + { + // Validate @event + $event_line_num = $this->find_event(); + $this->validate_event($this->current_event, $this->file_lines[$event_line_num]); + + // Validate @since + $since_line_num = $this->find_since(); + $since = $this->validate_since($this->file_lines[$since_line_num]); + + // Find event description line + $description_line_num = $this->find_description(); + $description = substr(trim($this->file_lines[$description_line_num]), strlen('* ')); + + if (isset($this->events[$this->current_event])) + { + throw new \LogicException("The event '{$this->current_event}' from file " + . "'{$this->current_file}:{$event_line_num}' already exists in file " + . "'{$this->events[$this->current_event]['file']}'", 10); + } + + sort($arguments); + $this->events[$this->current_event] = array( + 'event' => $this->current_event, + 'file' => $this->current_file, + 'arguments' => $arguments, + 'since' => $since, + 'description' => $description, + ); + $num_events_found++; + } + } + } + + return $num_events_found; + } + + /** + * Find the name of the event inside the dispatch() line + * + * @param int $event_line + * @param bool $is_dispatch Do we look for dispatch() or trigger_event() ? + * @return string Name of the event + * @throws \LogicException + */ + public function get_event_name($event_line, $is_dispatch) + { + $event_text_line = $this->file_lines[$event_line]; + $event_text_line = ltrim($event_text_line, "\t"); + + if ($is_dispatch) + { + $regex = '#\$([a-z](?:[a-z0-9_]|->)*)'; + $regex .= '->dispatch\('; + $regex .= '\'' . $this->preg_match_event_name() . '\''; + $regex .= '\);#'; + } + else + { + $regex = '#extract\(\$([a-z](?:[a-z0-9_]|->)*)'; + $regex .= '->trigger_event\('; + $regex .= '\'' . $this->preg_match_event_name() . '\''; + $regex .= ', compact\(\$vars\)\)\);#'; + } + + $match = array(); + preg_match($regex, $event_text_line, $match); + if (!isset($match[2])) + { + throw new \LogicException("Can not find event name in line '{$event_text_line}' " + . "in file '{$this->current_file}:{$event_line}'", 1); + } + + return $match[2]; + } + + /** + * Returns a regex match for the event name + * + * @return string + */ + protected function preg_match_event_name() + { + return '([a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+)'; + } + + /** + * Find the $vars array + * + * @return array List of variables + * @throws \LogicException + */ + public function get_vars_from_array() + { + $line = ltrim($this->file_lines[$this->current_event_line - 1], "\t"); + if ($line === ');') + { + $vars_array = $this->get_vars_from_multi_line_array(); + } + else + { + $vars_array = $this->get_vars_from_single_line_array($line); + } + + foreach ($vars_array as $var) + { + if (!preg_match('#^([a-zA-Z_][a-zA-Z0-9_]*)$#', $var)) + { + throw new \LogicException("Found invalid var '{$var}' in array for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3); + } + } + + sort($vars_array); + return $vars_array; + } + + /** + * Find the variables in single line array + * + * @param string $line + * @param bool $throw_multiline Throw an exception when there are too + * many arguments in one line. + * @return array List of variables + * @throws \LogicException + */ + public function get_vars_from_single_line_array($line, $throw_multiline = true) + { + $match = array(); + preg_match('#^\$vars = array\(\'([a-zA-Z0-9_\' ,]+)\'\);$#', $line, $match); + + if (isset($match[1])) + { + $vars_array = explode("', '", $match[1]); + if ($throw_multiline && sizeof($vars_array) > 6) + { + throw new \LogicException('Should use multiple lines for $vars definition ' + . "for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + return $vars_array; + } + else + { + throw new \LogicException("Can not find '\$vars = array();'-line for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1); + } + } + + /** + * Find the variables in single line array + * + * @return array List of variables + * @throws \LogicException + */ + public function get_vars_from_multi_line_array() + { + $current_vars_line = 2; + $var_lines = array(); + while (ltrim($this->file_lines[$this->current_event_line - $current_vars_line], "\t") !== '$vars = array(') + { + $var_lines[] = substr(trim($this->file_lines[$this->current_event_line - $current_vars_line]), 0, -1); + + $current_vars_line++; + if ($current_vars_line > $this->current_event_line) + { + // Reached the start of the file + throw new \LogicException("Can not find end of \$vars array for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + } + + return $this->get_vars_from_single_line_array('$vars = array(' . implode(", ", $var_lines) . ');', false); + } + + /** + * Find the $vars array + * + * @return array List of variables + * @throws \LogicException + */ + public function get_vars_from_docblock() + { + $doc_vars = array(); + $current_doc_line = 1; + $found_comment_end = false; + while (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t") !== '/**') + { + if (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t") === '*/') + { + $found_comment_end = true; + } + + if ($found_comment_end) + { + $var_line = trim($this->file_lines[$this->current_event_line - $current_doc_line]); + $var_line = preg_replace('!\s+!', ' ', $var_line); + if (strpos($var_line, '* @var ') === 0) + { + $doc_line = explode(' ', $var_line, 5); + if (sizeof($doc_line) !== 5) + { + throw new \LogicException("Found invalid line '{$this->file_lines[$this->current_event_line - $current_doc_line]}' " + . "for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1); + } + $doc_vars[] = $doc_line[3]; + } + } + + $current_doc_line++; + if ($current_doc_line > $this->current_event_line) + { + // Reached the start of the file + throw new \LogicException("Can not find end of docblock for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + } + + if (empty($doc_vars)) + { + // Reached the start of the file + throw new \LogicException("Can not find @var lines for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3); + } + + foreach ($doc_vars as $var) + { + if (!preg_match('#^([a-zA-Z_][a-zA-Z0-9_]*)$#', $var)) + { + throw new \LogicException("Found invalid @var '{$var}' in docblock for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 4); + } + } + + sort($doc_vars); + return $doc_vars; + } + + /** + * Find the "@since" Information line + * + * @return int Absolute line number + * @throws \LogicException + */ + public function find_since() + { + return $this->find_tag('since', array('event', 'var')); + } + + /** + * Find the "@event" Information line + * + * @return int Absolute line number + */ + public function find_event() + { + return $this->find_tag('event', array()); + } + + /** + * Find a "@*" Information line + * + * @param string $find_tag Name of the tag we are trying to find + * @param array $disallowed_tags List of tags that must not appear between + * the tag and the actual event + * @return int Absolute line number + * @throws \LogicException + */ + public function find_tag($find_tag, $disallowed_tags) + { + $find_tag_line = 0; + $found_comment_end = false; + while (strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t"), '* @' . $find_tag . ' ') !== 0) + { + if ($found_comment_end && ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '/**') + { + // Reached the start of this doc block + throw new \LogicException("Can not find '@{$find_tag}' information for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1); + } + + foreach ($disallowed_tags as $disallowed_tag) + { + if ($found_comment_end && strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t"), '* @' . $disallowed_tag) === 0) + { + // Found @var after the @since + throw new \LogicException("Found '@{$disallowed_tag}' information after '@{$find_tag}' for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3); + } + } + + if (ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '*/') + { + $found_comment_end = true; + } + + $find_tag_line++; + if ($find_tag_line >= $this->current_event_line) + { + // Reached the start of the file + throw new \LogicException("Can not find '@{$find_tag}' information for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + } + + return $this->current_event_line - $find_tag_line; + } + + /** + * Find a "@*" Information line + * + * @return int Absolute line number + * @throws \LogicException + */ + public function find_description() + { + $find_desc_line = 0; + while (ltrim($this->file_lines[$this->current_event_line - $find_desc_line], "\t") !== '/**') + { + $find_desc_line++; + if ($find_desc_line > $this->current_event_line) + { + // Reached the start of the file + throw new \LogicException("Can not find a description for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1); + } + } + + $find_desc_line = $this->current_event_line - $find_desc_line + 1; + + $desc = trim($this->file_lines[$find_desc_line]); + if (strpos($desc, '* @') === 0 || $desc[0] !== '*' || substr($desc, 1) == '') + { + // First line of the doc block is a @-line, empty or only contains "*" + throw new \LogicException("Can not find a description for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + + return $find_desc_line; + } + + /** + * Validate "@since" Information + * + * @param string $line + * @return string + * @throws \LogicException + */ + public function validate_since($line) + { + $match = array(); + preg_match('#^\* @since (\d+\.\d+\.\d+(?:-(?:a|b|rc|pl)\d+)?)$#', ltrim($line, "\t"), $match); + if (!isset($match[1])) + { + throw new \LogicException("Invalid '@since' information for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'"); + } + + return $match[1]; + } + + /** + * Validate "@event" Information + * + * @param string $event_name + * @param string $line + * @return string + * @throws \LogicException + */ + public function validate_event($event_name, $line) + { + $event = substr(ltrim($line, "\t"), strlen('* @event ')); + + if ($event !== trim($event)) + { + throw new \LogicException("Invalid '@event' information for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1); + } + + if ($event !== $event_name) + { + throw new \LogicException("Event name does not match '@event' tag for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + + return $event; + } + + /** + * Validates that two arrays contain the same strings + * + * @param array $vars_array Variables found in the array line + * @param array $vars_docblock Variables found in the doc block + * @return null + * @throws \LogicException + */ + public function validate_vars_docblock_array($vars_array, $vars_docblock) + { + $vars_array = array_unique($vars_array); + $vars_docblock = array_unique($vars_docblock); + $sizeof_vars_array = sizeof($vars_array); + + if ($sizeof_vars_array !== sizeof($vars_docblock) || $sizeof_vars_array !== sizeof(array_intersect($vars_array, $vars_docblock))) + { + throw new \LogicException("\$vars array does not match the list of '@var' tags for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'"); + } + } +} diff --git a/phpBB/phpbb/event/recursive_event_filter_iterator.php b/phpBB/phpbb/event/recursive_event_filter_iterator.php new file mode 100644 index 0000000000..ef2f2ec0ed --- /dev/null +++ b/phpBB/phpbb/event/recursive_event_filter_iterator.php @@ -0,0 +1,70 @@ +<?php +/** +* +* @package event +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\event; + +/** +* Class recursive_event_filter_iterator +* +* This filter ignores directories and files starting with a dot. +* It also skips some directories that do not contain events anyway, +* such as e.g. files/, store/ and vendor/ +* +* @package phpbb\event +*/ +class recursive_event_filter_iterator extends \RecursiveFilterIterator +{ + protected $root_path; + + /** + * Construct + * + * @param \RecursiveIterator $iterator + * @param string $root_path + */ + public function __construct(\RecursiveIterator $iterator, $root_path) + { + $this->root_path = str_replace(DIRECTORY_SEPARATOR, '/', $root_path); + parent::__construct($iterator); + } + + /** + * Return the inner iterator's children contained in a recursive_event_filter_iterator + * + * @return recursive_event_filter_iterator + */ + public function getChildren() { + return new self($this->getInnerIterator()->getChildren(), $this->root_path); + } + + /** + * {@inheritDoc} + */ + public function accept() + { + $relative_path = str_replace(DIRECTORY_SEPARATOR, '/', $this->current()); + $filename = $this->current()->getFilename(); + + return (substr($relative_path, -4) === '.php' || $this->current()->isDir()) + && $filename[0] !== '.' + && strpos($relative_path, $this->root_path . 'cache/') !== 0 + && strpos($relative_path, $this->root_path . 'develop/') !== 0 + && strpos($relative_path, $this->root_path . 'docs/') !== 0 + && strpos($relative_path, $this->root_path . 'ext/') !== 0 + && strpos($relative_path, $this->root_path . 'files/') !== 0 + && strpos($relative_path, $this->root_path . 'includes/utf/') !== 0 + && strpos($relative_path, $this->root_path . 'language/') !== 0 + && strpos($relative_path, $this->root_path . 'phpbb/db/migration/data/') !== 0 + && strpos($relative_path, $this->root_path . 'phpbb/event/') !== 0 + && strpos($relative_path, $this->root_path . 'store/') !== 0 + && strpos($relative_path, $this->root_path . 'tests/') !== 0 + && strpos($relative_path, $this->root_path . 'vendor/') !== 0 + ; + } +} diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index a529cc7961..1f871750e0 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -9,14 +9,6 @@ namespace phpbb\extension; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\DependencyInjection\ContainerInterface; /** diff --git a/phpBB/phpbb/extension/exception.php b/phpBB/phpbb/extension/exception.php index e2ba647878..82327c9d5e 100644 --- a/phpBB/phpbb/extension/exception.php +++ b/phpBB/phpbb/extension/exception.php @@ -10,14 +10,6 @@ namespace phpbb\extension; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Exception class for metadata */ class exception extends \UnexpectedValueException @@ -26,4 +18,4 @@ class exception extends \UnexpectedValueException { return $this->getMessage(); } -}
\ No newline at end of file +} diff --git a/phpBB/phpbb/extension/extension_interface.php b/phpBB/phpbb/extension/extension_interface.php index 1e5f546dc5..bddff51b5a 100644 --- a/phpBB/phpbb/extension/extension_interface.php +++ b/phpBB/phpbb/extension/extension_interface.php @@ -10,14 +10,6 @@ namespace phpbb\extension; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * The interface extension meta classes have to implement to run custom code * on enable/disable/purge. * diff --git a/phpBB/phpbb/extension/finder.php b/phpBB/phpbb/extension/finder.php index e787919588..6cc6e1808a 100644 --- a/phpBB/phpbb/extension/finder.php +++ b/phpBB/phpbb/extension/finder.php @@ -10,14 +10,6 @@ namespace phpbb\extension; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * The extension finder provides a simple way to locate files in active extensions * * @package extension @@ -483,14 +475,19 @@ class finder } $directory_pattern = '#' . $directory_pattern . '#'; - $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST); + $iterator = new \RecursiveIteratorIterator( + new \phpbb\recursive_dot_prefix_filter_iterator( + new \RecursiveDirectoryIterator( + $path, + \FilesystemIterator::SKIP_DOTS + ) + ), + \RecursiveIteratorIterator::SELF_FIRST + ); + foreach ($iterator as $file_info) { $filename = $file_info->getFilename(); - if ($filename == '.' || $filename == '..') - { - continue; - } if ($file_info->isDir() == $is_dir) { diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index ce6d7e05c8..b22fbf07a6 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -9,14 +9,6 @@ namespace phpbb\extension; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -42,7 +34,7 @@ class manager * Creates a manager and loads information from database * * @param ContainerInterface $container A container - * @param \phpbb\db\driver\driver $db A database connection + * @param \phpbb\db\driver\driver_interface $db A database connection * @param \phpbb\config\config $config \phpbb\config\config * @param \phpbb\filesystem $filesystem * @param string $extension_table The name of the table holding extensions @@ -51,7 +43,7 @@ class manager * @param \phpbb\cache\driver\driver_interface $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(ContainerInterface $container, \phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') { $this->container = $container; $this->phpbb_root_path = $phpbb_root_path; @@ -220,6 +212,11 @@ class manager $this->cache->purge(); } + if ($active) + { + $this->config->increment('assets_version', 1); + } + return !$active; } @@ -234,7 +231,9 @@ class manager */ public function enable($name) { + // @codingStandardsIgnoreStart while ($this->enable_step($name)); + // @codingStandardsIgnoreEnd } /** @@ -311,7 +310,9 @@ class manager */ public function disable($name) { + // @codingStandardsIgnoreStart while ($this->disable_step($name)); + // @codingStandardsIgnoreEnd } /** @@ -388,7 +389,9 @@ class manager */ public function purge($name) { + // @codingStandardsIgnoreStart while ($this->purge_step($name)); + // @codingStandardsIgnoreEnd } /** @@ -413,9 +416,24 @@ class manager if ($file_info->isFile() && $file_info->getFilename() == 'ext.' . $this->php_ext) { $ext_name = $iterator->getInnerIterator()->getSubPath(); + $composer_file = $iterator->getPath() . '/composer.json'; + // Ignore the extension if there is no composer.json. + if (!is_readable($composer_file) || !($ext_info = file_get_contents($composer_file))) + { + continue; + } + + $ext_info = json_decode($ext_info, true); $ext_name = str_replace(DIRECTORY_SEPARATOR, '/', $ext_name); + // Ignore the extension if directory depth is not correct or if the directory structure + // does not match the name value specified in composer.json. + if (substr_count($ext_name, '/') !== 1 || !isset($ext_info['name']) || $ext_name != $ext_info['name']) + { + continue; + } + $available[$ext_name] = $this->phpbb_root_path . 'ext/' . $ext_name . '/'; } } diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index a77f3a2c6e..c90445ee09 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -10,14 +10,6 @@ namespace phpbb\extension; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * The extension metadata manager validates and gets meta-data for extensions * * @package extension @@ -147,7 +139,7 @@ class metadata_manager if (!file_exists($this->metadata_file)) { - throw new \phpbb\extension\exception('The required file does not exist: ' . $this->metadata_file); + throw new \phpbb\extension\exception('The required file does not exist: ' . $this->metadata_file); } } @@ -166,12 +158,12 @@ class metadata_manager { if (!($file_contents = file_get_contents($this->metadata_file))) { - throw new \phpbb\extension\exception('file_get_contents failed on ' . $this->metadata_file); + throw new \phpbb\extension\exception('file_get_contents failed on ' . $this->metadata_file); } - if (($metadata = json_decode($file_contents, true)) === NULL) + if (($metadata = json_decode($file_contents, true)) === null) { - throw new \phpbb\extension\exception('json_decode failed on ' . $this->metadata_file); + throw new \phpbb\extension\exception('json_decode failed on ' . $this->metadata_file); } $this->metadata = $metadata; @@ -199,50 +191,50 @@ class metadata_manager * @return Bool True if valid, throws an exception if invalid */ public function validate($name = 'display') - { - // Basic fields - $fields = array( - 'name' => '#^[a-zA-Z0-9_\x7f-\xff]{2,}/[a-zA-Z0-9_\x7f-\xff]{2,}$#', - 'type' => '#^phpbb3-extension$#', - 'licence' => '#.+#', - 'version' => '#.+#', - ); - - switch ($name) - { - case 'all': - $this->validate('display'); + { + // Basic fields + $fields = array( + 'name' => '#^[a-zA-Z0-9_\x7f-\xff]{2,}/[a-zA-Z0-9_\x7f-\xff]{2,}$#', + 'type' => '#^phpbb-extension$#', + 'license' => '#.+#', + 'version' => '#.+#', + ); + + switch ($name) + { + case 'all': + $this->validate('display'); $this->validate_enable(); - break; + break; - case 'display': - foreach ($fields as $field => $data) + case 'display': + foreach ($fields as $field => $data) { $this->validate($field); } $this->validate_authors(); - break; - - default: - if (isset($fields[$name])) - { - if (!isset($this->metadata[$name])) - { - throw new \phpbb\extension\exception("Required meta field '$name' has not been set."); + break; + + default: + if (isset($fields[$name])) + { + if (!isset($this->metadata[$name])) + { + throw new \phpbb\extension\exception("Required meta field '$name' has not been set."); } if (!preg_match($fields[$name], $this->metadata[$name])) { - throw new \phpbb\extension\exception("Meta field '$name' is invalid."); + throw new \phpbb\extension\exception("Meta field '$name' is invalid."); } } break; } return true; - } + } /** * Validates the contents of the authors field @@ -253,14 +245,14 @@ class metadata_manager { if (empty($this->metadata['authors'])) { - throw new \phpbb\extension\exception("Required meta field 'authors' has not been set."); + throw new \phpbb\extension\exception("Required meta field 'authors' has not been set."); } foreach ($this->metadata['authors'] as $author) { if (!isset($author['name'])) { - throw new \phpbb\extension\exception("Required meta field 'author name' has not been set."); + throw new \phpbb\extension\exception("Required meta field 'author name' has not been set."); } } @@ -274,8 +266,8 @@ class metadata_manager */ public function validate_enable() { - // Check for phpBB, PHP versions - if (!$this->validate_require_phpbb() || !$this->validate_require_php()) + // Check for valid directory & phpBB, PHP versions + if (!$this->validate_dir() || !$this->validate_require_phpbb() || !$this->validate_require_php()) { return false; } @@ -283,6 +275,16 @@ class metadata_manager return true; } + /** + * Validates the most basic directory structure to ensure it follows <vendor>/<ext> convention. + * + * @return boolean True when passes validation + */ + public function validate_dir() + { + return (substr_count($this->ext_name, '/') === 1 && $this->ext_name == $this->get_metadata('name')); + } + /** * Validates the contents of the phpbb requirement field @@ -291,12 +293,12 @@ class metadata_manager */ public function validate_require_phpbb() { - if (!isset($this->metadata['require']['phpbb'])) + if (!isset($this->metadata['require']['phpbb/phpbb'])) { - return true; + return false; } - return $this->_validate_version($this->metadata['require']['phpbb'], $this->config['version']); + return true; } /** @@ -308,10 +310,10 @@ class metadata_manager { if (!isset($this->metadata['require']['php'])) { - return true; + return false; } - return $this->_validate_version($this->metadata['require']['php'], phpversion()); + return true; } /** @@ -349,12 +351,12 @@ class metadata_manager 'META_HOMEPAGE' => (isset($this->metadata['homepage'])) ? $this->metadata['homepage'] : '', 'META_VERSION' => (isset($this->metadata['version'])) ? htmlspecialchars($this->metadata['version']) : '', 'META_TIME' => (isset($this->metadata['time'])) ? htmlspecialchars($this->metadata['time']) : '', - 'META_LICENCE' => htmlspecialchars($this->metadata['licence']), + 'META_LICENSE' => htmlspecialchars($this->metadata['license']), 'META_REQUIRE_PHP' => (isset($this->metadata['require']['php'])) ? htmlspecialchars($this->metadata['require']['php']) : '', 'META_REQUIRE_PHP_FAIL' => !$this->validate_require_php(), - 'META_REQUIRE_PHPBB' => (isset($this->metadata['require']['phpbb'])) ? htmlspecialchars($this->metadata['require']['phpbb']) : '', + 'META_REQUIRE_PHPBB' => (isset($this->metadata['require']['phpbb/phpbb'])) ? htmlspecialchars($this->metadata['require']['phpbb/phpbb']) : '', 'META_REQUIRE_PHPBB_FAIL' => !$this->validate_require_phpbb(), 'META_DISPLAY_NAME' => (isset($this->metadata['extra']['display-name'])) ? htmlspecialchars($this->metadata['extra']['display-name']) : '', diff --git a/phpBB/phpbb/extension/provider.php b/phpBB/phpbb/extension/provider.php index c2a264d311..bfdc2b66b9 100644 --- a/phpBB/phpbb/extension/provider.php +++ b/phpBB/phpbb/extension/provider.php @@ -10,14 +10,6 @@ namespace phpbb\extension; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Provides a set of items found in extensions. * * This abstract class is essentially a wrapper around item-specific diff --git a/phpBB/phpbb/feed/base.php b/phpBB/phpbb/feed/base.php index de7dd41df4..0e3a80ebb8 100644 --- a/phpBB/phpbb/feed/base.php +++ b/phpBB/phpbb/feed/base.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Base class with some generic functions and settings. * * @package phpBB3 @@ -33,7 +25,7 @@ abstract class base /** @var \phpbb\config\config */ protected $config; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\cache\driver\driver_interface */ @@ -78,7 +70,7 @@ abstract class base * * @param \phpbb\feed\helper $helper Feed helper * @param \phpbb\config\config $config Config object - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\cache\driver\driver_interface $cache Cache object * @param \phpbb\user $user User object * @param \phpbb\auth\auth $auth Auth object @@ -86,7 +78,7 @@ abstract class base * @param string $phpEx php file extension * @return null */ - function __construct(\phpbb\feed\helper $helper, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, \phpbb\user $user, \phpbb\auth\auth $auth, \phpbb\content_visibility $content_visibility, $phpEx) + function __construct(\phpbb\feed\helper $helper, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, \phpbb\user $user, \phpbb\auth\auth $auth, \phpbb\content_visibility $content_visibility, $phpEx) { $this->config = $config; $this->helper = $helper; @@ -150,7 +142,7 @@ abstract class base */ function get($key) { - return (isset($this->keys[$key])) ? $this->keys[$key] : NULL; + return (isset($this->keys[$key])) ? $this->keys[$key] : null; } function get_readable_forums() diff --git a/phpBB/phpbb/feed/factory.php b/phpBB/phpbb/feed/factory.php index e011b0e3a9..742b279ef4 100644 --- a/phpBB/phpbb/feed/factory.php +++ b/phpBB/phpbb/feed/factory.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Factory class to return correct object * @package phpBB3 */ @@ -32,7 +24,7 @@ class factory /** @var \phpbb\config\config */ protected $config; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @@ -40,10 +32,10 @@ class factory * * @param objec $container Container object * @param \phpbb\config\config $config Config object - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @return null */ - public function __construct($container, \phpbb\config\config $config, \phpbb\db\driver\driver $db) + public function __construct($container, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db) { $this->container = $container; $this->config = $config; diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php index 5f64d85625..85ecb60f7e 100644 --- a/phpBB/phpbb/feed/forum.php +++ b/phpBB/phpbb/feed/forum.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Forum feed * * This will give you the last {$this->num_items} posts made @@ -36,7 +28,7 @@ class forum extends \phpbb\feed\post_base * @param int $forum_id Forum ID * @return \phpbb\feed\forum */ - public function set_forum_id($topic_id) + public function set_forum_id($forum_id) { $this->forum_id = (int) $forum_id; @@ -117,7 +109,7 @@ class forum extends \phpbb\feed\post_base } $this->sql = array( - 'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' . + 'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' . 'u.username, u.user_id', 'FROM' => array( POSTS_TABLE => 'p', diff --git a/phpBB/phpbb/feed/forums.php b/phpBB/phpbb/feed/forums.php index 6be1c68da8..ddbb0bf7b3 100644 --- a/phpBB/phpbb/feed/forums.php +++ b/phpBB/phpbb/feed/forums.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * 'All Forums' feed * * This will give you a list of all postable forums where feeds are enabled diff --git a/phpBB/phpbb/feed/helper.php b/phpBB/phpbb/feed/helper.php index cf8328bd5e..12acf997ac 100644 --- a/phpBB/phpbb/feed/helper.php +++ b/phpBB/phpbb/feed/helper.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Class with some helpful functions used in feeds * @package phpBB3 */ @@ -32,6 +24,9 @@ class helper /** @var string */ protected $phpbb_root_path; + /** @var string */ + protected $phpEx; + /** * Constructor * @@ -40,11 +35,12 @@ class helper * @param string $phpbb_root_path Root path * @return null */ - public function __construct(\phpbb\config\config $config, \phpbb\user $user, $phpbb_root_path) + public function __construct(\phpbb\config\config $config, \phpbb\user $user, $phpbb_root_path, $phpEx) { $this->config = $config; $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; + $this->phpEx = $phpEx; } /** @@ -89,8 +85,16 @@ class helper /** * Generate text content + * + * @param string $content is feed text content + * @param string $uid is bbcode_uid + * @param string $bitfield is bbcode bitfield + * @param int $options bbcode flag options + * @param int $forum_id is the forum id + * @param array $post_attachments is an array containing the attachments and their respective info + * @return string the html content to be printed for the feed */ - public function generate_content($content, $uid, $bitfield, $options) + public function generate_content($content, $uid, $bitfield, $options, $forum_id, $post_attachments) { if (empty($content)) { @@ -137,8 +141,21 @@ class helper // Remove some specials html tag, because somewhere there are a mod to allow html tags ;) $content = preg_replace( '#<(script|iframe)([^[]+)\1>#siU', ' <strong>$1</strong> ', $content); + // Parse inline images to display with the feed + if (!empty($post_attachments)) + { + $update_count = array(); + parse_attachments($forum_id, $content, $post_attachments, $update_count); + $post_attachments = implode('<br />', $post_attachments); + + // Convert attachments' relative path to absolute path + $post_attachments = str_replace($this->phpbb_root_path . 'download/file.' . $this->phpEx, $this->get_board_url() . '/download/file.' . $this->phpEx, $post_attachments); + + $content .= $post_attachments; + } + // Remove Comments from inline attachments [ia] - $content = preg_replace('#<div class="(inline-attachment|attachtitle)">(.*?)<!-- ia(.*?) -->(.*?)<!-- ia(.*?) -->(.*?)</div>#si','$4',$content); + $content = preg_replace('#<dd>(.*?)</dd>#','',$content); // Replace some entities with their unicode counterpart $entities = array( diff --git a/phpBB/phpbb/feed/news.php b/phpBB/phpbb/feed/news.php index 20017a3248..1b7c452a92 100644 --- a/phpBB/phpbb/feed/news.php +++ b/phpBB/phpbb/feed/news.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * News feed * * This will give you {$this->num_items} first posts @@ -93,7 +85,7 @@ class news extends \phpbb\feed\topic_base $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time, - p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url', + p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment', 'FROM' => array( TOPICS_TABLE => 't', POSTS_TABLE => 'p', diff --git a/phpBB/phpbb/feed/overall.php b/phpBB/phpbb/feed/overall.php index 8ee1f092ab..d99200475e 100644 --- a/phpBB/phpbb/feed/overall.php +++ b/phpBB/phpbb/feed/overall.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Board wide feed (aka overall feed) * * This will give you the newest {$this->num_items} posts @@ -61,7 +53,7 @@ class overall extends \phpbb\feed\post_base // Get the actual data $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, ' . - 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' . + 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' . 'u.username, u.user_id', 'FROM' => array( USERS_TABLE => 'u', diff --git a/phpBB/phpbb/feed/post_base.php b/phpBB/phpbb/feed/post_base.php index 5588ecadb0..c797d6a8ca 100644 --- a/phpBB/phpbb/feed/post_base.php +++ b/phpBB/phpbb/feed/post_base.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Abstract class for post based feeds * * @package phpBB3 @@ -25,6 +17,7 @@ if (!defined('IN_PHPBB')) abstract class post_base extends \phpbb\feed\base { var $num_items = 'feed_limit_post'; + var $attachments = array(); function set_keys() { @@ -56,4 +49,41 @@ abstract class post_base extends \phpbb\feed\base . (($this->is_moderator_approve_forum($row['forum_id']) && $row['post_visibility'] !== ITEM_APPROVED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : ''); } } + + function fetch_attachments() + { + $sql_array = array( + 'SELECT' => 'a.*', + 'FROM' => array( + ATTACHMENTS_TABLE => 'a' + ), + 'WHERE' => 'a.in_message = 0 ', + 'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC', + ); + + if (isset($this->topic_id)) + { + $sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id; + } + else if (isset($this->forum_id)) + { + $sql_array['LEFT_JOIN'] = array( + array( + 'FROM' => array(TOPICS_TABLE => 't'), + 'ON' => 'a.topic_id = t.topic_id', + ) + ); + $sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id; + } + + $sql = $this->db->sql_build_query('SELECT', $sql_array); + $result = $this->db->sql_query($sql); + + // Set attachments in feed items + while ($row = $this->db->sql_fetchrow($result)) + { + $this->attachments[$row['post_msg_id']][] = $row; + } + $this->db->sql_freeresult($result); + } } diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php index 1eeb4fbe94..a7acfb502f 100644 --- a/phpBB/phpbb/feed/topic.php +++ b/phpBB/phpbb/feed/topic.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Topic feed for a specific topic * * This will give you the last {$this->num_items} posts made within this topic. @@ -96,7 +88,7 @@ class topic extends \phpbb\feed\post_base function get_sql() { $this->sql = array( - 'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' . + 'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' . 'u.username, u.user_id', 'FROM' => array( POSTS_TABLE => 'p', diff --git a/phpBB/phpbb/feed/topic_base.php b/phpBB/phpbb/feed/topic_base.php index f05be9223e..7e28e67b82 100644 --- a/phpBB/phpbb/feed/topic_base.php +++ b/phpBB/phpbb/feed/topic_base.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Abstract class for topic based feeds * * @package phpBB3 diff --git a/phpBB/phpbb/feed/topics.php b/phpBB/phpbb/feed/topics.php index d70195c87b..e8b9f6de6c 100644 --- a/phpBB/phpbb/feed/topics.php +++ b/phpBB/phpbb/feed/topics.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * New Topics feed * * This will give you the last {$this->num_items} created topics @@ -65,7 +57,7 @@ class topics extends \phpbb\feed\topic_base $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time, - p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url', + p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment', 'FROM' => array( TOPICS_TABLE => 't', POSTS_TABLE => 'p', diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php index c6f46d67e6..809a536c2a 100644 --- a/phpBB/phpbb/feed/topics_active.php +++ b/phpBB/phpbb/feed/topics_active.php @@ -10,14 +10,6 @@ namespace phpbb\feed; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Active Topics feed * * This will give you the last {$this->num_items} topics @@ -82,7 +74,7 @@ class topics_active extends \phpbb\feed\topic_base 'SELECT' => 'f.forum_id, f.forum_name, t.topic_id, t.topic_title, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_post_time, - p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url', + p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment', 'FROM' => array( TOPICS_TABLE => 't', POSTS_TABLE => 'p', diff --git a/phpBB/phpbb/filesystem.php b/phpBB/phpbb/filesystem.php index dbfaebe0fa..7878be0a5e 100644 --- a/phpBB/phpbb/filesystem.php +++ b/phpBB/phpbb/filesystem.php @@ -10,14 +10,6 @@ namespace phpbb; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * A class with various functions that are related to paths, files and the filesystem * @package phpBB3 */ diff --git a/phpBB/phpbb/groupposition/exception.php b/phpBB/phpbb/groupposition/exception.php index 3a8d92dbc7..9b55669524 100644 --- a/phpBB/phpbb/groupposition/exception.php +++ b/phpBB/phpbb/groupposition/exception.php @@ -3,21 +3,13 @@ * * @package groupposition * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ namespace phpbb\groupposition; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * @package groupposition */ class exception extends \Exception diff --git a/phpBB/phpbb/groupposition/groupposition_interface.php b/phpBB/phpbb/groupposition/groupposition_interface.php index a568785185..9785172a00 100644 --- a/phpBB/phpbb/groupposition/groupposition_interface.php +++ b/phpBB/phpbb/groupposition/groupposition_interface.php @@ -10,14 +10,6 @@ namespace phpbb\groupposition; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Interface to manage group positions in various places of phpbb * * The interface provides simple methods to add, delete and move a group diff --git a/phpBB/phpbb/groupposition/legend.php b/phpBB/phpbb/groupposition/legend.php index 9a1ef3d1d0..42af005622 100644 --- a/phpBB/phpbb/groupposition/legend.php +++ b/phpBB/phpbb/groupposition/legend.php @@ -10,14 +10,6 @@ namespace phpbb\groupposition; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Legend group position class * * group_legend is an ascending list 1, 2, ..., n for groups which are displayed. 1 is the first group, n the last. @@ -34,7 +26,7 @@ class legend implements \phpbb\groupposition\groupposition_interface /** * Database object - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -47,10 +39,10 @@ class legend implements \phpbb\groupposition\groupposition_interface /** * Constructor * - * @param \phpbb\db\driver\driver $db Database object + * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\user $user User object */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\user $user) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user) { $this->db = $db; $this->user = $user; diff --git a/phpBB/phpbb/groupposition/teampage.php b/phpBB/phpbb/groupposition/teampage.php index 4e8228eb58..4f1b102720 100644 --- a/phpBB/phpbb/groupposition/teampage.php +++ b/phpBB/phpbb/groupposition/teampage.php @@ -10,14 +10,6 @@ namespace phpbb\groupposition; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Teampage group position class * * Teampage position is an ascending list 1, 2, ..., n for items which are displayed. 1 is the first item, n the last. @@ -38,7 +30,7 @@ class teampage implements \phpbb\groupposition\groupposition_interface /** * Database object - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -57,11 +49,11 @@ class teampage implements \phpbb\groupposition\groupposition_interface /** * Constructor * - * @param \phpbb\db\driver\driver $db Database object + * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\user $user User object * @param \phpbb\cache\driver\driver_interface $cache Cache object */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\user $user, \phpbb\cache\driver\driver_interface $cache) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\cache\driver\driver_interface $cache) { $this->db = $db; $this->user = $user; diff --git a/phpBB/phpbb/hook/finder.php b/phpBB/phpbb/hook/finder.php index d5eb1f8186..c8f71861d9 100644 --- a/phpBB/phpbb/hook/finder.php +++ b/phpBB/phpbb/hook/finder.php @@ -10,14 +10,6 @@ namespace phpbb\hook; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * The hook finder locates installed hooks. * * @package phpBB3 diff --git a/phpBB/phpbb/json_response.php b/phpBB/phpbb/json_response.php index fe532fc9d4..e17525519a 100644 --- a/phpBB/phpbb/json_response.php +++ b/phpBB/phpbb/json_response.php @@ -3,21 +3,13 @@ * * @package phpBB3 * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ namespace phpbb; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * JSON class * @package phpBB3 */ diff --git a/phpBB/phpbb/lock/db.php b/phpBB/phpbb/lock/db.php index 3e15727c12..2b437ef899 100644 --- a/phpBB/phpbb/lock/db.php +++ b/phpBB/phpbb/lock/db.php @@ -10,14 +10,6 @@ namespace phpbb\lock; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Database locking class * @package phpBB3 */ @@ -50,7 +42,7 @@ class db /** * A database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ private $db; @@ -61,9 +53,9 @@ class db * * @param string $config_name A config variable to be used for locking * @param array $config The phpBB configuration - * @param \phpbb\db\driver\driver $db A database connection + * @param \phpbb\db\driver\driver_interface $db A database connection */ - public function __construct($config_name, \phpbb\config\config $config, \phpbb\db\driver\driver $db) + public function __construct($config_name, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db) { $this->config_name = $config_name; $this->config = $config; diff --git a/phpBB/phpbb/lock/flock.php b/phpBB/phpbb/lock/flock.php index 2a36a853ee..94a5895440 100644 --- a/phpBB/phpbb/lock/flock.php +++ b/phpBB/phpbb/lock/flock.php @@ -10,14 +10,6 @@ namespace phpbb\lock; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * File locking class * @package phpBB3 */ diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php index 7f4e52ed39..e4c5ce47d9 100644 --- a/phpBB/phpbb/log/log.php +++ b/phpBB/phpbb/log/log.php @@ -10,14 +10,6 @@ namespace phpbb\log; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * This class is used to add entries into the log table. * * @package \phpbb\log\log @@ -101,10 +93,10 @@ class log implements \phpbb\log\log_interface /** * Constructor * - * @param \phpbb\db\driver\driver $db Database object + * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\user $user User object * @param \phpbb\auth\auth $auth Auth object - * @param phpbb_dispatcher $phpbb_dispatcher Event dispatcher + * @param \phpbb\event\dispatcher $phpbb_dispatcher Event dispatcher * @param string $phpbb_root_path Root path * @param string $relative_admin_path Relative admin root path * @param string $php_ext PHP Extension @@ -313,10 +305,18 @@ class log implements \phpbb\log\log_interface * @var array sql_ary Array with log data we insert into the * database. If sql_ary[log_type] is not set, * we won't add the entry to the database. - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('mode', 'user_id', 'log_ip', 'log_operation', 'log_time', 'additional_data', 'sql_ary'); - extract($this->dispatcher->trigger_event('core.add_log', $vars)); + $vars = array( + 'mode', + 'user_id', + 'log_ip', + 'log_operation', + 'log_time', + 'additional_data', + 'sql_ary', + ); + extract($this->dispatcher->trigger_event('core.add_log', compact($vars))); // We didn't find a log_type, so we don't save it in the database. if (!isset($sql_ary['log_type'])) @@ -411,10 +411,24 @@ class log implements \phpbb\log\log_interface * is false, no entries will be returned. * @var string sql_additional Additional conditions for the entries, * e.g.: 'AND l.forum_id = 1' - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('mode', 'count_logs', 'limit', 'offset', 'forum_id', 'topic_id', 'user_id', 'log_time', 'sort_by', 'keywords', 'profile_url', 'log_type', 'sql_additional'); - extract($this->dispatcher->trigger_event('core.get_logs_modify_type', $vars)); + $vars = array( + 'mode', + 'count_logs', + 'limit', + 'offset', + 'forum_id', + 'topic_id', + 'user_id', + 'log_time', + 'sort_by', + 'keywords', + 'profile_url', + 'log_type', + 'sql_additional', + ); + extract($this->dispatcher->trigger_event('core.get_logs_modify_type', compact($vars))); if ($log_type === false) { @@ -432,7 +446,7 @@ class log implements \phpbb\log\log_interface if ($count_logs) { $sql = 'SELECT COUNT(l.log_id) AS total_entries - FROM ' . LOG_TABLE . ' l, ' . USERS_TABLE . ' u + FROM ' . $this->log_table . ' l, ' . USERS_TABLE . ' u WHERE l.log_type = ' . (int) $log_type . ' AND l.user_id = u.user_id AND l.log_time >= ' . (int) $log_time . " @@ -457,7 +471,7 @@ class log implements \phpbb\log\log_interface } $sql = 'SELECT l.*, u.username, u.username_clean, u.user_colour - FROM ' . LOG_TABLE . ' l, ' . USERS_TABLE . ' u + FROM ' . $this->log_table . ' l, ' . USERS_TABLE . ' u WHERE l.log_type = ' . (int) $log_type . ' AND u.user_id = l.user_id ' . (($log_time) ? 'AND l.log_time >= ' . (int) $log_time : '') . " @@ -498,7 +512,7 @@ class log implements \phpbb\log\log_interface 'topic_id' => (int) $row['topic_id'], 'viewforum' => ($row['forum_id'] && $this->auth->acl_get('f_read', $row['forum_id'])) ? append_sid("{$this->phpbb_root_path}viewforum.{$this->php_ext}", 'f=' . $row['forum_id']) : false, - 'action' => (isset($this->user->lang[$row['log_operation']])) ? $this->user->lang[$row['log_operation']] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}', + 'action' => (isset($this->user->lang[$row['log_operation']])) ? $row['log_operation'] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}', ); /** @@ -507,10 +521,10 @@ class log implements \phpbb\log\log_interface * @event core.get_logs_modify_entry_data * @var array row Entry data from the database * @var array log_entry_data Entry's data which is returned - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('row', 'log_entry_data'); - extract($this->dispatcher->trigger_event('core.get_logs_modify_entry_data', $vars)); + extract($this->dispatcher->trigger_event('core.get_logs_modify_entry_data', compact($vars))); $log[$i] = $log_entry_data; @@ -525,12 +539,26 @@ class log implements \phpbb\log\log_interface // arguments, if there are we fill out the arguments // array. It doesn't matter if we add more arguments than // placeholders. - if ((substr_count($log[$i]['action'], '%') - sizeof($log_data_ary)) > 0) + $num_args = 0; + if (!is_array($this->user->lang[$row['log_operation']])) + { + $num_args = substr_count($this->user->lang[$row['log_operation']], '%'); + } + else { - $log_data_ary = array_merge($log_data_ary, array_fill(0, substr_count($log[$i]['action'], '%') - sizeof($log_data_ary), '')); + foreach ($this->user->lang[$row['log_operation']] as $case => $plural_string) + { + $num_args = max($num_args, substr_count($plural_string, '%')); + } } - $log[$i]['action'] = vsprintf($log[$i]['action'], $log_data_ary); + if (($num_args - sizeof($log_data_ary)) > 0) + { + $log_data_ary = array_merge($log_data_ary, array_fill(0, $num_args - sizeof($log_data_ary), '')); + } + + $lang_arguments = array_merge(array($log[$i]['action']), $log_data_ary); + $log[$i]['action'] = call_user_func_array(array($this->user, 'lang'), $lang_arguments); // If within the admin panel we do not censor text out if ($this->get_is_admin()) @@ -552,6 +580,10 @@ class log implements \phpbb\log\log_interface $log[$i]['action'] = make_clickable($log[$i]['action']); */ } + else + { + $log[$i]['action'] = $this->user->lang($log[$i]['action']); + } $i++; } @@ -566,10 +598,10 @@ class log implements \phpbb\log\log_interface * get the permission data * @var array reportee_id_list Array of additional user IDs we * get the username strings for - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('log', 'topic_id_list', 'reportee_id_list'); - extract($this->dispatcher->trigger_event('core.get_logs_get_additional_data', $vars)); + extract($this->dispatcher->trigger_event('core.get_logs_get_additional_data', compact($vars))); if (sizeof($topic_id_list)) { @@ -633,9 +665,23 @@ class log implements \phpbb\log\log_interface $operations = array(); foreach ($this->user->lang as $key => $value) { - if (substr($key, 0, 4) == 'LOG_' && preg_match($keywords_pattern, $value)) + if (substr($key, 0, 4) == 'LOG_') { - $operations[] = $key; + if (is_array($value)) + { + foreach ($value as $plural_value) + { + if (preg_match($keywords_pattern, $plural_value)) + { + $operations[] = $key; + break; + } + } + } + else if (preg_match($keywords_pattern, $value)) + { + $operations[] = $key; + } } } diff --git a/phpBB/phpbb/log/log_interface.php b/phpBB/phpbb/log/log_interface.php index 427d30015d..420ba79691 100644 --- a/phpBB/phpbb/log/log_interface.php +++ b/phpBB/phpbb/log/log_interface.php @@ -10,14 +10,6 @@ namespace phpbb\log; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * The interface for the log-system. * * @package \phpbb\log\log diff --git a/phpBB/phpbb/log/null.php b/phpBB/phpbb/log/null.php index 2ef69926ee..77d0fbe2d7 100644 --- a/phpBB/phpbb/log/null.php +++ b/phpBB/phpbb/log/null.php @@ -10,14 +10,6 @@ namespace phpbb\log; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Null logger * * @package phpbb_log diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php new file mode 100644 index 0000000000..2d74582a21 --- /dev/null +++ b/phpBB/phpbb/mimetype/content_guesser.php @@ -0,0 +1,33 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\mimetype; + +/** +* @package mimetype +*/ + +class content_guesser extends guesser_base +{ + /** + * @inheritdoc + */ + public function is_supported() + { + return function_exists('mime_content_type'); + } + + /** + * @inheritdoc + */ + public function guess($file, $file_name = '') + { + return mime_content_type($file); + } +} diff --git a/phpBB/phpbb/mimetype/extension_guesser.php b/phpBB/phpbb/mimetype/extension_guesser.php new file mode 100644 index 0000000000..f6f4ae0138 --- /dev/null +++ b/phpBB/phpbb/mimetype/extension_guesser.php @@ -0,0 +1,509 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\mimetype; + +/** +* @package mimetype +*/ + +class extension_guesser extends guesser_base +{ + /** + * @var file extension map + */ + protected $extension_map = array( + '3dm' => 'x-world/x-3dmf', + '3dmf' => 'x-world/x-3dmf', + 'a' => 'application/octet-stream', + 'aab' => 'application/x-authorware-bin', + 'aam' => 'application/x-authorware-map', + 'aas' => 'application/x-authorware-seg', + 'abc' => 'text/vnd.abc', + 'acgi' => 'text/html', + 'afl' => 'video/animaflex', + 'ai' => 'application/postscript', + 'aif' => 'audio/aiff', + 'aifc' => 'audio/aiff', + 'aiff' => 'audio/aiff', + 'aim' => 'application/x-aim', + 'aip' => 'text/x-audiosoft-intra', + 'ani' => 'application/x-navi-animation', + 'aos' => 'application/x-nokia-9000-communicator-add-on-software', + 'aps' => 'application/mime', + 'arc' => 'application/octet-stream', + 'arj' => 'application/arj', + 'art' => 'image/x-jg', + 'asf' => 'video/x-ms-asf', + 'asm' => 'text/x-asm', + 'asp' => 'text/asp', + 'asx' => 'video/x-ms-asf', + 'au' => 'audio/x-au', + 'avi' => 'video/avi', + 'avs' => 'video/avs-video', + 'bcpio' => 'application/x-bcpio', + 'bin' => 'application/x-binary', + 'bm' => 'image/bmp', + 'bmp' => 'image/bmp', + 'boo' => 'application/book', + 'book' => 'application/book', + 'boz' => 'application/x-bzip2', + 'bsh' => 'application/x-bsh', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'c' => 'text/x-c', + 'c++' => 'text/x-c', + 'cat' => 'application/vnd.ms-pki.seccat', + 'cc' => 'text/plain', + 'ccad' => 'application/clariscad', + 'cco' => 'application/x-cocoa', + 'cdf' => 'application/cdf', + 'cer' => 'application/x-x509-ca-cert', + 'cha' => 'application/x-chat', + 'chat' => 'application/x-chat', + 'class' => 'application/java', + 'com' => 'application/octet-stream', + 'conf' => 'text/plain', + 'cpio' => 'application/x-cpio', + 'cpp' => 'text/x-c', + 'cpt' => 'application/x-cpt', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'csh' => 'application/x-csh', + 'css' => 'text/css', + 'cxx' => 'text/plain', + 'dcr' => 'application/x-director', + 'deepv' => 'application/x-deepv', + 'def' => 'text/plain', + 'der' => 'application/x-x509-ca-cert', + 'dif' => 'video/x-dv', + 'dir' => 'application/x-director', + 'dl' => 'video/dl', + 'doc' => 'application/msword', + 'dot' => 'application/msword', + 'dp' => 'application/commonground', + 'drw' => 'application/drafting', + 'dump' => 'application/octet-stream', + 'dv' => 'video/x-dv', + 'dvi' => 'application/x-dvi', + 'dwf' => 'model/vnd.dwf', + 'dwg' => 'image/x-dwg', + 'dxf' => 'image/x-dwg', + 'dxr' => 'application/x-director', + 'el' => 'text/x-script.elisp', + 'elc' => 'application/x-elc', + 'env' => 'application/x-envoy', + 'eps' => 'application/postscript', + 'es' => 'application/x-esrehber', + 'etx' => 'text/x-setext', + 'evy' => 'application/x-envoy', + 'exe' => 'application/octet-stream', + 'f' => 'text/x-fortran', + 'f77' => 'text/x-fortran', + 'f90' => 'text/x-fortran', + 'fdf' => 'application/vnd.fdf', + 'fif' => 'image/fif', + 'fli' => 'video/x-fli', + 'flo' => 'image/florian', + 'flx' => 'text/vnd.fmi.flexstor', + 'fmf' => 'video/x-atomic3d-feature', + 'for' => 'text/x-fortran', + 'fpx' => 'image/vnd.fpx', + 'frl' => 'application/freeloader', + 'funk' => 'audio/make', + 'g' => 'text/plain', + 'g3' => 'image/g3fax', + 'gif' => 'image/gif', + 'gl' => 'video/x-gl', + 'gsd' => 'audio/x-gsm', + 'gsm' => 'audio/x-gsm', + 'gsp' => 'application/x-gsp', + 'gss' => 'application/x-gss', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'h' => 'text/x-h', + 'hdf' => 'application/x-hdf', + 'help' => 'application/x-helpfile', + 'hgl' => 'application/vnd.hp-hpgl', + 'hh' => 'text/x-h', + 'hlb' => 'text/x-script', + 'hlp' => 'application/hlp', + 'hpg' => 'application/vnd.hp-hpgl', + 'hpgl' => 'application/vnd.hp-hpgl', + 'hqx' => 'application/x-binhex40', + 'hta' => 'application/hta', + 'htc' => 'text/x-component', + 'htm' => 'text/html', + 'html' => 'text/html', + 'htmls' => 'text/html', + 'htt' => 'text/webviewhtml', + 'htx' => 'text/html', + 'ice' => 'x-conference/x-cooltalk', + 'ico' => 'image/x-icon', + 'idc' => 'text/plain', + 'ief' => 'image/ief', + 'iefs' => 'image/ief', + 'iges' => 'application/iges', + 'igs' => 'application/iges', + 'ima' => 'application/x-ima', + 'imap' => 'application/x-httpd-imap', + 'inf' => 'application/inf', + 'ins' => 'application/x-internett-signup', + 'ip' => 'application/x-ip2', + 'isu' => 'video/x-isvideo', + 'it' => 'audio/it', + 'iv' => 'application/x-inventor', + 'ivr' => 'i-world/i-vrml', + 'ivy' => 'application/x-livescreen', + 'jam' => 'audio/x-jam', + 'jav' => 'text/plain', + 'jav' => 'text/x-java-source', + 'java' => 'text/x-java-source', + 'jcm' => 'application/x-java-commerce', + 'jfif' => 'image/jpeg', + 'jfif-tbnl' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jps' => 'image/x-jps', + 'js' => 'application/x-javascript', + 'jut' => 'image/jutvision', + 'kar' => 'audio/midi', + 'ksh' => 'text/x-script.ksh', + 'la' => 'audio/x-nspaudio', + 'lam' => 'audio/x-liveaudio', + 'latex' => 'application/x-latex', + 'lha' => 'application/x-lha', + 'lhx' => 'application/octet-stream', + 'list' => 'text/plain', + 'lma' => 'audio/x-nspaudio', + 'log' => 'text/plain', + 'lsp' => 'text/x-script.lisp', + 'lst' => 'text/plain', + 'lsx' => 'text/x-la-asf', + 'ltx' => 'application/x-latex', + 'lzh' => 'application/x-lzh', + 'lzx' => 'application/x-lzx', + 'm' => 'text/x-m', + 'm1v' => 'video/mpeg', + 'm2a' => 'audio/mpeg', + 'm2v' => 'video/mpeg', + 'm3u' => 'audio/x-mpequrl', + 'man' => 'application/x-troff-man', + 'map' => 'application/x-navimap', + 'mar' => 'text/plain', + 'mbd' => 'application/mbedlet', + 'mc$' => 'application/x-magic-cap-package-1.0', + 'mcd' => 'application/x-mathcad', + 'mcf' => 'text/mcf', + 'mcp' => 'application/netmc', + 'me' => 'application/x-troff-me', + 'mht' => 'message/rfc822', + 'mhtml' => 'message/rfc822', + 'mid' => 'audio/x-midi', + 'midi' => 'audio/x-midi', + 'mif' => 'application/x-mif', + 'mime' => 'www/mime', + 'mjf' => 'audio/x-vnd.audioexplosion.mjuicemediafile', + 'mjpg' => 'video/x-motion-jpeg', + 'mm' => 'application/x-meme', + 'mme' => 'application/base64', + 'mod' => 'audio/x-mod', + 'moov' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/x-mpeg', + 'mp3' => 'audio/x-mpeg-3', + 'mpa' => 'audio/mpeg', + 'mpc' => 'application/x-project', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpga' => 'audio/mpeg', + 'mpp' => 'application/vnd.ms-project', + 'mpt' => 'application/x-project', + 'mpv' => 'application/x-project', + 'mpx' => 'application/x-project', + 'mrc' => 'application/marc', + 'ms' => 'application/x-troff-ms', + 'mv' => 'video/x-sgi-movie', + 'my' => 'audio/make', + 'mzz' => 'application/x-vnd.audioexplosion.mzz', + 'nap' => 'image/naplps', + 'naplps' => 'image/naplps', + 'nc' => 'application/x-netcdf', + 'ncm' => 'application/vnd.nokia.configuration-message', + 'nif' => 'image/x-niff', + 'niff' => 'image/x-niff', + 'nix' => 'application/x-mix-transfer', + 'nsc' => 'application/x-conference', + 'nvd' => 'application/x-navidoc', + 'o' => 'application/octet-stream', + 'oda' => 'application/oda', + 'omc' => 'application/x-omc', + 'omcd' => 'application/x-omcdatamaker', + 'omcr' => 'application/x-omcregerator', + 'p' => 'text/x-pascal', + 'p10' => 'application/x-pkcs10', + 'p12' => 'application/x-pkcs12', + 'p7a' => 'application/x-pkcs7-signature', + 'p7c' => 'application/x-pkcs7-mime', + 'p7m' => 'application/x-pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'part' => 'application/pro_eng', + 'pas' => 'text/pascal', + 'pbm' => 'image/x-portable-bitmap', + 'pcl' => 'application/x-pcl', + 'pct' => 'image/x-pict', + 'pcx' => 'image/x-pcx', + 'pdb' => 'chemical/x-pdb', + 'pdf' => 'application/pdf', + 'pfunk' => 'audio/make.my.funk', + 'pgm' => 'image/x-portable-greymap', + 'pic' => 'image/pict', + 'pict' => 'image/pict', + 'pkg' => 'application/x-newton-compatible-pkg', + 'pko' => 'application/vnd.ms-pki.pko', + 'pl' => 'text/x-script.perl', + 'plx' => 'application/x-pixclscript', + 'pm' => 'text/x-script.perl-module', + 'pm4' => 'application/x-pagemaker', + 'pm5' => 'application/x-pagemaker', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'pot' => 'application/mspowerpoint', + 'pov' => 'model/x-pov', + 'ppa' => 'application/vnd.ms-powerpoint', + 'ppm' => 'image/x-portable-pixmap', + 'pps' => 'application/mspowerpoint', + 'ppt' => 'application/mspowerpoint', + 'ppz' => 'application/mspowerpoint', + 'pre' => 'application/x-freelance', + 'prt' => 'application/pro_eng', + 'ps' => 'application/postscript', + 'psd' => 'application/octet-stream', + 'pvu' => 'paleovu/x-pv', + 'pwz' => 'application/vnd.ms-powerpoint', + 'py' => 'text/x-script.phyton', + 'pyc' => 'applicaiton/x-bytecode.python', + 'qcp' => 'audio/vnd.qcelp', + 'qd3' => 'x-world/x-3dmf', + 'qd3d' => 'x-world/x-3dmf', + 'qif' => 'image/x-quicktime', + 'qt' => 'video/quicktime', + 'qtc' => 'video/x-qtc', + 'qti' => 'image/x-quicktime', + 'qtif' => 'image/x-quicktime', + 'ra' => 'audio/x-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'ras' => 'image/x-cmu-raster', + 'rast' => 'image/cmu-raster', + 'rexx' => 'text/x-script.rexx', + 'rf' => 'image/vnd.rn-realflash', + 'rgb' => 'image/x-rgb', + 'rm' => 'audio/x-pn-realaudio', + 'rmi' => 'audio/mid', + 'rmm' => 'audio/x-pn-realaudio', + 'rmp' => 'audio/x-pn-realaudio', + 'rng' => 'application/vnd.nokia.ringing-tone', + 'rnx' => 'application/vnd.rn-realplayer', + 'roff' => 'application/x-troff', + 'rp' => 'image/vnd.rn-realpix', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'rt' => 'text/richtext', + 'rtf' => 'text/richtext', + 'rtx' => 'text/richtext', + 'rv' => 'video/vnd.rn-realvideo', + 's' => 'text/x-asm', + 's3m' => 'audio/s3m', + 'saveme' => 'application/octet-stream', + 'sbk' => 'application/x-tbook', + 'scm' => 'video/x-scm', + 'sdml' => 'text/plain', + 'sdp' => 'application/x-sdp', + 'sdr' => 'application/sounder', + 'sea' => 'application/x-sea', + 'set' => 'application/set', + 'sgm' => 'text/x-sgml', + 'sgml' => 'text/x-sgml', + 'sh' => 'text/x-script.sh', + 'shar' => 'application/x-shar', + 'shtml' => 'text/x-server-parsed-html', + 'sid' => 'audio/x-psid', + 'sit' => 'application/x-stuffit', + 'skd' => 'application/x-koan', + 'skm' => 'application/x-koan', + 'skp' => 'application/x-koan', + 'skt' => 'application/x-koan', + 'sl' => 'application/x-seelogo', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'snd' => 'audio/x-adpcm', + 'sol' => 'application/solids', + 'spc' => 'text/x-speech', + 'spl' => 'application/futuresplash', + 'spr' => 'application/x-sprite', + 'sprite' => 'application/x-sprite', + 'src' => 'application/x-wais-source', + 'ssi' => 'text/x-server-parsed-html', + 'ssm' => 'application/streamingmedia', + 'sst' => 'application/vnd.ms-pki.certstore', + 'step' => 'application/step', + 'stl' => 'application/vnd.ms-pki.stl', + 'stp' => 'application/step', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'svf' => 'image/x-dwg', + 'svr' => 'application/x-world', + 'swf' => 'application/x-shockwave-flash', + 't' => 'application/x-troff', + 'talk' => 'text/x-speech', + 'tar' => 'application/x-tar', + 'tbk' => 'application/x-tbook', + 'tcl' => 'text/x-script.tcl', + 'tcsh' => 'text/x-script.tcsh', + 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'text' => 'text/plain', + 'tgz' => 'application/x-compressed', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tr' => 'application/x-troff', + 'tsi' => 'audio/tsp-audio', + 'tsp' => 'audio/tsplayer', + 'tsv' => 'text/tab-separated-values', + 'turbot' => 'image/florian', + 'txt' => 'text/plain', + 'uil' => 'text/x-uil', + 'uni' => 'text/uri-list', + 'unis' => 'text/uri-list', + 'unv' => 'application/i-deas', + 'uri' => 'text/uri-list', + 'uris' => 'text/uri-list', + 'ustar' => 'multipart/x-ustar', + 'uu' => 'text/x-uuencode', + 'uue' => 'text/x-uuencode', + 'vcd' => 'application/x-cdlink', + 'vcs' => 'text/x-vcalendar', + 'vda' => 'application/vda', + 'vdo' => 'video/vdo', + 'vew' => 'application/groupwise', + 'viv' => 'video/vivo', + 'vivo' => 'video/vivo', + 'vmd' => 'application/vocaltec-media-desc', + 'vmf' => 'application/vocaltec-media-file', + 'voc' => 'audio/voc', + 'vos' => 'video/vosaic', + 'vox' => 'audio/voxware', + 'vqe' => 'audio/x-twinvq-plugin', + 'vqf' => 'audio/x-twinvq', + 'vql' => 'audio/x-twinvq-plugin', + 'vrml' => 'application/x-vrml', + 'vrt' => 'x-world/x-vrt', + 'vsd' => 'application/x-visio', + 'vst' => 'application/x-visio', + 'vsw' => 'application/x-visio', + 'w60' => 'application/wordperfect6.0', + 'w61' => 'application/wordperfect6.1', + 'w6w' => 'application/msword', + 'wav' => 'audio/wav', + 'wb1' => 'application/x-qpro', + 'wbmp' => 'image/vnd.wap.wbmp', + 'web' => 'application/vnd.xara', + 'wiz' => 'application/msword', + 'wk1' => 'application/x-123', + 'wmf' => 'windows/metafile', + 'wml' => 'text/vnd.wap.wml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmls' => 'text/vnd.wap.wmlscript', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'word' => 'application/msword', + 'wp' => 'application/wordperfect', + 'wp5' => 'application/wordperfect', + 'wp6' => 'application/wordperfect', + 'wpd' => 'application/wordperfect', + 'wq1' => 'application/x-lotus', + 'wri' => 'application/mswrite', + 'wrl' => 'model/vrml', + 'wrz' => 'model/vrml', + 'wsc' => 'text/scriplet', + 'wsrc' => 'application/x-wais-source', + 'wtk' => 'application/x-wintalk', + 'xbm' => 'image/xbm', + 'xdr' => 'video/x-amt-demorun', + 'xgz' => 'xgl/drawing', + 'xif' => 'image/vnd.xiff', + 'xl' => 'application/excel', + 'xla' => 'application/excel', + 'xlb' => 'application/excel', + 'xlc' => 'application/excel', + 'xld' => 'application/excel', + 'xlk' => 'application/excel', + 'xll' => 'application/excel', + 'xlm' => 'application/excel', + 'xls' => 'application/excel', + 'xlt' => 'application/excel', + 'xlv' => 'application/excel', + 'xlw' => 'application/excel', + 'xm' => 'audio/xm', + 'xml' => 'text/xml', + 'xmz' => 'xgl/movie', + 'xpix' => 'application/x-vnd.ls-xpix', + 'xpm' => 'image/xpm', + 'x-png' => 'image/png', + 'xsr' => 'video/x-amt-showrun', + 'xwd' => 'image/x-xwindowdump', + 'xyz' => 'chemical/x-pdb', + 'z' => 'application/x-compressed', + 'zip' => 'application/x-zip-compressed', + 'zoo' => 'application/octet-stream', + 'zsh' => 'text/x-script.zsh', + ); + + /** + * @inheritdoc + */ + public function is_supported() + { + return true; + } + + /** + * @inheritdoc + */ + public function guess($file, $file_name = '') + { + $file_name = (empty($file_name)) ? $file : $file_name; + return $this->map_extension_to_type($file_name); + } + + /** + * Map extension of supplied file_name to mime type + * + * @param string $file_name Path to file or filename + * + * @return string|null Mimetype if known or null if not + */ + protected function map_extension_to_type($file_name) + { + $extension = pathinfo($file_name, PATHINFO_EXTENSION); + + if (isset($this->extension_map[$extension])) + { + return $this->extension_map[$extension]; + } + else + { + return null; + } + } +} diff --git a/phpBB/phpbb/mimetype/guesser.php b/phpBB/phpbb/mimetype/guesser.php new file mode 100644 index 0000000000..3499b3b0f7 --- /dev/null +++ b/phpBB/phpbb/mimetype/guesser.php @@ -0,0 +1,130 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\mimetype; + +/** +* @package mimetype +*/ + +class guesser +{ + /** + * @const Default priority for mimetype guessers + */ + const PRIORITY_DEFAULT = 0; + + /** + * @var mimetype guessers + */ + protected $guessers; + + /** + * Construct a mimetype guesser object + * + * @param array $mimetype_guessers Mimetype guesser service collection + */ + public function __construct($mimetype_guessers) + { + $this->register_guessers($mimetype_guessers); + } + + /** + * Register MimeTypeGuessers and sort them by priority + * + * @param array $mimetype_guessers Mimetype guesser service collection + * + * @throws \LogicException If incorrect or not mimetype guessers have + * been supplied to class + */ + protected function register_guessers($mimetype_guessers) + { + foreach ($mimetype_guessers as $guesser) + { + $is_supported = (method_exists($guesser, 'is_supported')) ? 'is_supported' : ''; + $is_supported = (method_exists($guesser, 'isSupported')) ? 'isSupported' : $is_supported; + + if (empty($is_supported)) + { + throw new \LogicException('Incorrect mimetype guesser supplied.'); + } + + if ($guesser->$is_supported()) + { + $this->guessers[] = $guesser; + } + } + + if (empty($this->guessers)) + { + throw new \LogicException('No mimetype guesser supplied.'); + } + + // Sort guessers by priority + usort($this->guessers, array($this, 'sort_priority')); + } + + /** + * Sort the priority of supplied guessers + * This is a compare function for usort. A guesser with higher priority + * should be used first and vice versa. usort() orders the array values + * from low to high depending on what the comparison function returns + * to it. Return value should be smaller than 0 if value a is smaller + * than value b. This has been reversed in the comparision function in + * order to sort the guessers from high to low. + * Method has been set to public in order to allow proper testing. + * + * @param object $guesser_a Mimetype guesser a + * @param object $guesser_b Mimetype guesser b + * + * @return int If both guessers have the same priority 0, bigger + * than 0 if first guesser has lower priority, and lower + * than 0 if first guesser has higher priority + */ + public function sort_priority($guesser_a, $guesser_b) + { + $priority_a = (int) (method_exists($guesser_a, 'get_priority')) ? $guesser_a->get_priority() : self::PRIORITY_DEFAULT; + $priority_b = (int) (method_exists($guesser_b, 'get_priority')) ? $guesser_b->get_priority() : self::PRIORITY_DEFAULT; + + return $priority_b - $priority_a; + } + + /** + * Guess mimetype of supplied file + * + * @param string $file Path to file + * + * @return string Guess for mimetype of file + */ + public function guess($file, $file_name = '') + { + if (!is_file($file)) + { + return false; + } + + if (!is_readable($file)) + { + return false; + } + + foreach ($this->guessers as $guesser) + { + $mimetype = $guesser->guess($file, $file_name); + + // Try to guess something that is not the fallback application/octet-stream + if ($mimetype !== null && $mimetype !== 'application/octet-stream') + { + return $mimetype; + } + } + // Return any mimetype if we got a result or the fallback value + return (!empty($mimetype)) ? $mimetype : 'application/octet-stream'; + } +} diff --git a/phpBB/phpbb/mimetype/guesser_base.php b/phpBB/phpbb/mimetype/guesser_base.php new file mode 100644 index 0000000000..082b098028 --- /dev/null +++ b/phpBB/phpbb/mimetype/guesser_base.php @@ -0,0 +1,38 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\mimetype; + +/** +* @package mimetype +*/ + +abstract class guesser_base implements guesser_interface +{ + /** + * @var int Guesser Priority + */ + protected $priority; + + /** + * @inheritdoc + */ + public function get_priority() + { + return $this->priority; + } + + /** + * @inheritdoc + */ + public function set_priority($priority) + { + $this->priority = $priority; + } +} diff --git a/phpBB/phpbb/mimetype/guesser_interface.php b/phpBB/phpbb/mimetype/guesser_interface.php new file mode 100644 index 0000000000..103689765e --- /dev/null +++ b/phpBB/phpbb/mimetype/guesser_interface.php @@ -0,0 +1,49 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\mimetype; + +/** +* @package mimetype +*/ + +interface guesser_interface +{ + /** + * Returns whether this guesser is supported on the current OS + * + * @return bool True if guesser is supported, false if not + */ + public function is_supported(); + + /** + * Guess mimetype of supplied file + * + * @param string $file Path to file + * + * @return string Guess for mimetype of file + */ + public function guess($file, $file_name = ''); + + /** + * Get the guesser priority + * + * @return int Guesser priority + */ + public function get_priority(); + + /** + * Set the guesser priority + * + * @param int Guesser priority + * + * @return void + */ + public function set_priority($priority); +} diff --git a/phpBB/phpbb/notification/exception.php b/phpBB/phpbb/notification/exception.php index 275fb3b542..1b4cc89fc9 100644 --- a/phpBB/phpbb/notification/exception.php +++ b/phpBB/phpbb/notification/exception.php @@ -3,21 +3,13 @@ * * @package notifications * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ namespace phpbb\notification; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Notifications exception * * @package notifications diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index c42c84fb1f..09d9677ccd 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -10,14 +10,6 @@ namespace phpbb\notification; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Notifications service class * @package notifications */ @@ -35,7 +27,10 @@ class manager /** @var \phpbb\user_loader */ protected $user_loader; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\config\config */ + protected $config; + + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\cache\service */ @@ -66,7 +61,8 @@ class manager * @param array $notification_methods * @param ContainerBuilder $phpbb_container * @param \phpbb\user_loader $user_loader - * @param \phpbb\db\driver\driver $db + * @param \phpbb\config\config $config + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\user $user * @param string $phpbb_root_path * @param string $php_ext @@ -75,13 +71,14 @@ class manager * @param string $user_notifications_table * @return \phpbb\notification\manager */ - public function __construct($notification_types, $notification_methods, $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\db\driver\driver $db, \phpbb\cache\service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) + public function __construct($notification_types, $notification_methods, $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) { $this->notification_types = $notification_types; $this->notification_methods = $notification_methods; $this->phpbb_container = $phpbb_container; $this->user_loader = $user_loader; + $this->config = $config; $this->db = $db; $this->cache = $cache; $this->user = $user; @@ -154,7 +151,7 @@ class manager AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); - $unread_count = (int) $this->db->sql_fetchfield('unread_count', $result); + $unread_count = (int) $this->db->sql_fetchfield('unread_count'); $this->db->sql_freeresult($result); } @@ -167,7 +164,7 @@ class manager AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); - $total_count = (int) $this->db->sql_fetchfield('total_count', $result); + $total_count = (int) $this->db->sql_fetchfield('total_count'); $this->db->sql_freeresult($result); } @@ -262,8 +259,7 @@ class manager SET notification_read = 1 WHERE notification_time <= " . (int) $time . (($notification_type_name !== false) ? ' AND ' . - (is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name)) - : '') . + (is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name)) : '') . (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '') . (($item_id !== false) ? ' AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) : ''); $this->db->sql_query($sql); @@ -285,8 +281,7 @@ class manager SET notification_read = 1 WHERE notification_time <= " . (int) $time . (($notification_type_name !== false) ? ' AND ' . - (is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name)) - : '') . + (is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name)) : '') . (($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id) : 'item_parent_id = ' . (int) $item_parent_id) : '') . (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : ''); $this->db->sql_query($sql); @@ -807,6 +802,8 @@ class manager WHERE notification_time < ' . (int) $timestamp . (($only_read) ? ' AND notification_read = 1' : ''); $this->db->sql_query($sql); + + $this->config->set('read_notification_last_gc', time(), false); } /** diff --git a/phpBB/phpbb/notification/method/base.php b/phpBB/phpbb/notification/method/base.php index 327f964424..2e6507d30f 100644 --- a/phpBB/phpbb/notification/method/base.php +++ b/phpBB/phpbb/notification/method/base.php @@ -10,14 +10,6 @@ namespace phpbb\notification\method; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Base notifications method class * @package notifications */ @@ -29,7 +21,7 @@ abstract class base implements \phpbb\notification\method\method_interface /** @var \phpbb\user_loader */ protected $user_loader; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\cache\driver\driver_interface */ @@ -67,7 +59,7 @@ abstract class base implements \phpbb\notification\method\method_interface * Notification Method Base Constructor * * @param \phpbb\user_loader $user_loader - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\cache\driver\driver_interface $cache * @param \phpbb\user $user * @param \phpbb\auth\auth $auth @@ -76,7 +68,7 @@ abstract class base implements \phpbb\notification\method\method_interface * @param string $php_ext * @return \phpbb\notification\method\base */ - public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext) { $this->user_loader = $user_loader; $this->db = $db; diff --git a/phpBB/phpbb/notification/method/email.php b/phpBB/phpbb/notification/method/email.php index b761eb5a28..e039fae8de 100644 --- a/phpBB/phpbb/notification/method/email.php +++ b/phpBB/phpbb/notification/method/email.php @@ -10,14 +10,6 @@ namespace phpbb\notification\method; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Email notification method class * This class handles sending emails for notifications * diff --git a/phpBB/phpbb/notification/method/jabber.php b/phpBB/phpbb/notification/method/jabber.php index 6ec21bb735..bdfaf5a6fc 100644 --- a/phpBB/phpbb/notification/method/jabber.php +++ b/phpBB/phpbb/notification/method/jabber.php @@ -10,14 +10,6 @@ namespace phpbb\notification\method; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Jabber notification method class * This class handles sending Jabber messages for notifications * diff --git a/phpBB/phpbb/notification/method/messenger_base.php b/phpBB/phpbb/notification/method/messenger_base.php index b1b30f29b7..7cb38eb59d 100644 --- a/phpBB/phpbb/notification/method/messenger_base.php +++ b/phpBB/phpbb/notification/method/messenger_base.php @@ -10,14 +10,6 @@ namespace phpbb\notification\method; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Abstract notification method handling email and jabber notifications * using the phpBB messenger. * diff --git a/phpBB/phpbb/notification/method/method_interface.php b/phpBB/phpbb/notification/method/method_interface.php index 0131a8bde0..4830d06b86 100644 --- a/phpBB/phpbb/notification/method/method_interface.php +++ b/phpBB/phpbb/notification/method/method_interface.php @@ -10,14 +10,6 @@ namespace phpbb\notification\method; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Base notifications method interface * @package notifications */ diff --git a/phpBB/phpbb/notification/type/admin_activate_user.php b/phpBB/phpbb/notification/type/admin_activate_user.php new file mode 100644 index 0000000000..62ea759a98 --- /dev/null +++ b/phpBB/phpbb/notification/type/admin_activate_user.php @@ -0,0 +1,166 @@ +<?php +/** +* +* @package notifications +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\notification\type; + +/** +* Admin activation notifications class +* This class handles notifications for users requiring admin activation +* +* @package notifications +*/ +class admin_activate_user extends \phpbb\notification\type\base +{ + /** + * {@inheritdoc} + */ + public function get_type() + { + return 'admin_activate_user'; + } + + /** + * {@inheritdoc} + */ + protected $language_key = 'NOTIFICATION_ADMIN_ACTIVATE_USER'; + + /** + * {@inheritdoc} + */ + public static $notification_option = array( + 'lang' => 'NOTIFICATION_TYPE_ADMIN_ACTIVATE_USER', + 'group' => 'NOTIFICATION_GROUP_ADMINISTRATION', + ); + + /** + * {@inheritdoc} + */ + public function is_available() + { + return ($this->auth->acl_get('a_user') && $this->config['require_activation'] == USER_ACTIVATION_ADMIN); + } + + /** + * {@inheritdoc} + */ + public static function get_item_id($user) + { + return (int) $user['user_id']; + } + + /** + * {@inheritdoc} + */ + public static function get_item_parent_id($post) + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function find_users_for_notification($user, $options = array()) + { + $options = array_merge(array( + 'ignore_users' => array(), + ), $options); + + // Grab admins that have permission to administer users. + $admin_ary = $this->auth->acl_get_list(false, 'a_user', false); + $users = (!empty($admin_ary[0]['a_user'])) ? $admin_ary[0]['a_user'] : array(); + + // Grab founders + $sql = 'SELECT user_id + FROM ' . USERS_TABLE . ' + WHERE user_type = ' . USER_FOUNDER; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $users[] = (int) $row['user_id']; + } + $this->db->sql_freeresult($result); + + if (empty($users)) + { + return array(); + } + $users = array_unique($users); + + return $this->check_user_notification_options($users, $options); + } + + /** + * {@inheritdoc} + */ + public function get_avatar() + { + return $this->user_loader->get_avatar($this->item_id); + } + + /** + * {@inheritdoc} + */ + public function get_title() + { + $username = $this->user_loader->get_username($this->item_id, 'no_profile'); + + return $this->user->lang($this->language_key, $username); + } + + /** + * {@inheritdoc} + */ + public function get_email_template() + { + return 'admin_activate'; + } + + /** + * {@inheritdoc} + */ + public function get_email_template_variables() + { + $board_url = generate_board_url(); + $username = $this->user_loader->get_username($this->item_id, 'no_profile'); + + return array( + 'USERNAME' => htmlspecialchars_decode($username), + 'U_USER_DETAILS' => "{$board_url}/memberlist.{$this->php_ext}?mode=viewprofile&u={$this->item_id}", + 'U_ACTIVATE' => "{$board_url}/ucp.{$this->php_ext}?mode=activate&u={$this->item_id}&k={$this->get_data('user_actkey')}", + ); + } + + /** + * {@inheritdoc} + */ + public function get_url() + { + return $this->user_loader->get_username($this->item_id, 'profile'); + } + + /** + * {@inheritdoc} + */ + public function users_to_query() + { + return array($this->item_id); + } + + /** + * {@inheritdoc} + */ + public function create_insert_array($user, $pre_create_data) + { + $this->set_data('user_actkey', $user['user_actkey']); + $this->notification_time = $user['user_regdate']; + + return parent::create_insert_array($user, $pre_create_data); + } +} diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php index cf4ec57989..5912ad62b4 100644 --- a/phpBB/phpbb/notification/type/approve_post.php +++ b/phpBB/phpbb/notification/type/approve_post.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Post approved notifications class * This class handles notifications for posts when they are approved (to their authors) * @@ -43,6 +35,13 @@ class approve_post extends \phpbb\notification\type\post protected $language_key = 'NOTIFICATION_POST_APPROVED'; /** + * Inherit notification read status from post. + * + * @var bool + */ + protected $inherit_read_status = false; + + /** * Notification option data (for outputting to the user) * * @var bool|array False if the service should use it's default data @@ -139,4 +138,12 @@ class approve_post extends \phpbb\notification\type\post { return 'post_approved'; } + + /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return $this->get_url(); + } } diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php index ca5bb67754..11a240e03d 100644 --- a/phpBB/phpbb/notification/type/approve_topic.php +++ b/phpBB/phpbb/notification/type/approve_topic.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Topic approved notifications class * This class handles notifications for topics when they are approved (for authors) * @@ -34,7 +26,7 @@ class approve_topic extends \phpbb\notification\type\topic { return 'approve_topic'; } - + /** * Language key used to output the text * @@ -43,6 +35,13 @@ class approve_topic extends \phpbb\notification\type\topic protected $language_key = 'NOTIFICATION_TOPIC_APPROVED'; /** + * Inherit notification read status from topic. + * + * @var bool + */ + protected $inherit_read_status = false; + + /** * Notification option data (for outputting to the user) * * @var bool|array False if the service should use it's default data diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index 3c44468bb8..7d08521d40 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Base notifications class * @package notifications */ @@ -29,7 +21,7 @@ abstract class base implements \phpbb\notification\type\type_interface /** @var \phpbb\user_loader */ protected $user_loader; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\cache\driver\driver_interface */ @@ -97,7 +89,7 @@ abstract class base implements \phpbb\notification\type\type_interface * Notification Type Base Constructor * * @param \phpbb\user_loader $user_loader - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\cache\driver\driver_interface $cache * @param \phpbb\user $user * @param \phpbb\auth\auth $auth @@ -109,7 +101,7 @@ abstract class base implements \phpbb\notification\type\type_interface * @param string $user_notifications_table * @return \phpbb\notification\type\base */ - public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) + public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) { $this->user_loader = $user_loader; $this->db = $db; @@ -284,21 +276,31 @@ abstract class base implements \phpbb\notification\type\type_interface } /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return $this->get_url(); + } + + /** * Prepare to output the notification to the template * * @return array Template variables */ public function prepare_for_display() { + $mark_hash = generate_link_hash('mark_notification_read'); + if ($this->get_url()) { - $u_mark_read = append_sid($this->phpbb_root_path . 'index.' . $this->php_ext, 'mark_notification=' . $this->notification_id); + $u_mark_read = append_sid($this->phpbb_root_path . 'index.' . $this->php_ext, 'mark_notification=' . $this->notification_id . '&hash=' . $mark_hash); } else { $redirect = (($this->user->page['page_dir']) ? $this->user->page['page_dir'] . '/' : '') . $this->user->page['page_name'] . (($this->user->page['query_string']) ? '?' . $this->user->page['query_string'] : ''); - $u_mark_read = append_sid($this->phpbb_root_path . 'index.' . $this->php_ext, 'mark_notification=' . $this->notification_id . '&redirect=' . urlencode($redirect)); + $u_mark_read = append_sid($this->phpbb_root_path . 'index.' . $this->php_ext, 'mark_notification=' . $this->notification_id . '&hash=' . $mark_hash . '&redirect=' . urlencode($redirect)); } return array( diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php index 50ea7380af..c981695f74 100644 --- a/phpBB/phpbb/notification/type/bookmark.php +++ b/phpBB/phpbb/notification/type/bookmark.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Bookmark updating notifications class * This class handles notifications for replies to a bookmarked topic * @@ -83,7 +75,7 @@ class bookmark extends \phpbb\notification\type\post $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - $users[] = $row['user_id']; + $users[] = (int) $row['user_id']; } $this->db->sql_freeresult($result); @@ -118,10 +110,14 @@ class bookmark extends \phpbb\notification\type\post unset($notify_users[$row['user_id']]); $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); - $sql = 'UPDATE ' . $this->notifications_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . ' - WHERE notification_id = ' . $row['notification_id']; - $this->db->sql_query($sql); + $update_responders = $notification->add_responders($post); + if (!empty($update_responders)) + { + $sql = 'UPDATE ' . $this->notifications_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . ' + WHERE notification_id = ' . $row['notification_id']; + $this->db->sql_query($sql); + } } $this->db->sql_freeresult($result); diff --git a/phpBB/phpbb/notification/type/disapprove_post.php b/phpBB/phpbb/notification/type/disapprove_post.php index 0c9162ec5c..70de2a3e10 100644 --- a/phpBB/phpbb/notification/type/disapprove_post.php +++ b/phpBB/phpbb/notification/type/disapprove_post.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Post disapproved notifications class * This class handles notifications for posts when they are disapproved (for authors) * @@ -43,6 +35,13 @@ class disapprove_post extends \phpbb\notification\type\approve_post protected $language_key = 'NOTIFICATION_POST_DISAPPROVED'; /** + * Inherit notification read status from post. + * + * @var bool + */ + protected $inherit_read_status = false; + + /** * Notification option data (for outputting to the user) * * @var bool|array False if the service should use it's default data diff --git a/phpBB/phpbb/notification/type/disapprove_topic.php b/phpBB/phpbb/notification/type/disapprove_topic.php index dde6f83ec4..d39201d928 100644 --- a/phpBB/phpbb/notification/type/disapprove_topic.php +++ b/phpBB/phpbb/notification/type/disapprove_topic.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Topic disapproved notifications class * This class handles notifications for topics when they are disapproved (for authors) * @@ -43,6 +35,13 @@ class disapprove_topic extends \phpbb\notification\type\approve_topic protected $language_key = 'NOTIFICATION_TOPIC_DISAPPROVED'; /** + * Inherit notification read status from topic. + * + * @var bool + */ + protected $inherit_read_status = false; + + /** * Notification option data (for outputting to the user) * * @var bool|array False if the service should use it's default data diff --git a/phpBB/phpbb/notification/type/group_request.php b/phpBB/phpbb/notification/type/group_request.php index 1768a8fffa..e0527fe220 100644 --- a/phpBB/phpbb/notification/type/group_request.php +++ b/phpBB/phpbb/notification/type/group_request.php @@ -9,14 +9,6 @@ namespace phpbb\notification\type; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class group_request extends \phpbb\notification\type\base { /** diff --git a/phpBB/phpbb/notification/type/group_request_approved.php b/phpBB/phpbb/notification/type/group_request_approved.php index be4a902acd..448f049412 100644 --- a/phpBB/phpbb/notification/type/group_request_approved.php +++ b/phpBB/phpbb/notification/type/group_request_approved.php @@ -9,14 +9,6 @@ namespace phpbb\notification\type; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class group_request_approved extends \phpbb\notification\type\base { /** diff --git a/phpBB/phpbb/notification/type/pm.php b/phpBB/phpbb/notification/type/pm.php index bed0807b0f..584a30efa6 100644 --- a/phpBB/phpbb/notification/type/pm.php +++ b/phpBB/phpbb/notification/type/pm.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Private message notifications class * This class handles notifications for private messages * diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index fe50e7f172..93fbcbde22 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Post notifications class * This class handles notifications for replies to a topic * @@ -43,6 +35,13 @@ class post extends \phpbb\notification\type\base protected $language_key = 'NOTIFICATION_POST'; /** + * Inherit notification read status from post. + * + * @var bool + */ + protected $inherit_read_status = true; + + /** * Notification option data (for outputting to the user) * * @var bool|array False if the service should use it's default data @@ -104,7 +103,7 @@ class post extends \phpbb\notification\type\base $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - $users[] = $row['user_id']; + $users[] = (int) $row['user_id']; } $this->db->sql_freeresult($result); @@ -116,7 +115,7 @@ class post extends \phpbb\notification\type\base $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - $users[] = $row['user_id']; + $users[] = (int) $row['user_id']; } $this->db->sql_freeresult($result); @@ -153,10 +152,14 @@ class post extends \phpbb\notification\type\base unset($notify_users[$row['user_id']]); $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); - $sql = 'UPDATE ' . $this->notifications_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . ' - WHERE notification_id = ' . $row['notification_id']; - $this->db->sql_query($sql); + $update_responders = $notification->add_responders($post); + if (!empty($update_responders)) + { + $sql = 'UPDATE ' . $this->notifications_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . ' + WHERE notification_id = ' . $row['notification_id']; + $this->db->sql_query($sql); + } } $this->db->sql_freeresult($result); @@ -191,6 +194,10 @@ class post extends \phpbb\notification\type\base 'username' => $this->get_data('post_username'), )), $responders); + $responders_cnt = sizeof($responders); + $responders = $this->trim_user_ary($responders); + $trimmed_responders_cnt = $responders_cnt - sizeof($responders); + foreach ($responders as $responder) { if ($responder['username']) @@ -203,10 +210,20 @@ class post extends \phpbb\notification\type\base } } + if ($trimmed_responders_cnt > 20) + { + $usernames[] = $this->user->lang('NOTIFICATION_MANY_OTHERS'); + } + else if ($trimmed_responders_cnt) + { + $usernames[] = $this->user->lang('NOTIFICATION_X_OTHERS', $trimmed_responders_cnt); + } + return $this->user->lang( $this->language_key, - implode(', ', $usernames), - censor_text($this->get_data('topic_title')) + phpbb_generate_string_list($usernames, $this->user), + censor_text($this->get_data('topic_title')), + $responders_cnt ); } @@ -242,7 +259,7 @@ class post extends \phpbb\notification\type\base 'TOPIC_TITLE' => htmlspecialchars_decode(censor_text($this->get_data('topic_title'))), 'U_VIEW_POST' => generate_board_url() . "/viewtopic.{$this->php_ext}?p={$this->item_id}#p{$this->item_id}", - 'U_NEWEST_POST' => generate_board_url() . "/viewtopic.{$this->php_ext}?f={$this->get_data('forum_id')}&t={$this->item_parent_id}&view=unread#unread", + 'U_NEWEST_POST' => generate_board_url() . "/viewtopic.{$this->php_ext}?f={$this->get_data('forum_id')}&t={$this->item_parent_id}&e=1&view=unread#unread", 'U_TOPIC' => generate_board_url() . "/viewtopic.{$this->php_ext}?f={$this->get_data('forum_id')}&t={$this->item_parent_id}", 'U_VIEW_TOPIC' => generate_board_url() . "/viewtopic.{$this->php_ext}?f={$this->get_data('forum_id')}&t={$this->item_parent_id}", 'U_FORUM' => generate_board_url() . "/viewforum.{$this->php_ext}?f={$this->get_data('forum_id')}", @@ -261,6 +278,14 @@ class post extends \phpbb\notification\type\base } /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "t={$this->item_parent_id}&view=unread#unread"); + } + + /** * Users needed to query before this notification can be displayed * * @return array Array of user_ids @@ -280,6 +305,22 @@ class post extends \phpbb\notification\type\base } } + return $this->trim_user_ary($users); + } + + /** + * Trim the user array passed down to 3 users if the array contains + * more than 4 users. + * + * @param array $users Array of users + * @return array Trimmed array of user_ids + */ + public function trim_user_ary($users) + { + if (sizeof($users) > 4) + { + array_splice($users, 3); + } return $users; } @@ -296,7 +337,7 @@ class post extends \phpbb\notification\type\base */ public function pre_create_insert_array($post, $notify_users) { - if (!sizeof($notify_users)) + if (!sizeof($notify_users) || !$this->inherit_read_status) { return array(); } @@ -341,7 +382,7 @@ class post extends \phpbb\notification\type\base // Topics can be "read" before they are public (while awaiting approval). // Make sure that if the user has read the topic, it's marked as read in the notification - if (isset($pre_create_data[$this->user_id]) && $pre_create_data[$this->user_id] >= $this->notification_time) + if ($this->inherit_read_status && isset($pre_create_data[$this->user_id]) && $pre_create_data[$this->user_id] >= $this->notification_time) { $this->notification_read = true; } @@ -359,19 +400,27 @@ class post extends \phpbb\notification\type\base // Do not add them as a responder if they were the original poster that created the notification if ($this->get_data('poster_id') == $post['poster_id']) { - return array('notification_data' => serialize($this->get_data(false))); + return array(); } $responders = $this->get_data('responders'); $responders = ($responders === null) ? array() : $responders; + // Do not add more than 25 responders, + // we trim the username list to "a, b, c and x others" anyway + // so there is no use to add all of them anyway. + if (sizeof($responders) > 25) + { + return array(); + } + foreach ($responders as $responder) { // Do not add them as a responder multiple times if ($responder['poster_id'] == $post['poster_id']) { - return array('notification_data' => serialize($this->get_data(false))); + return array(); } } @@ -382,6 +431,15 @@ class post extends \phpbb\notification\type\base $this->set_data('responders', $responders); - return array('notification_data' => serialize($this->get_data(false))); + $serialized_data = serialize($this->get_data(false)); + + // If the data is longer then 4000 characters, it would cause a SQL error. + // We don't add the username to the list if this is the case. + if (utf8_strlen($serialized_data) >= 4000) + { + return array(); + } + + return array('notification_data' => $serialized_data); } } diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php index f05ed1ce9a..56dfcce588 100644 --- a/phpBB/phpbb/notification/type/post_in_queue.php +++ b/phpBB/phpbb/notification/type/post_in_queue.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Post in queue notifications class * This class handles notifications for posts that are put in the moderation queue (for moderators) * @@ -127,6 +119,14 @@ class post_in_queue extends \phpbb\notification\type\post } /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return parent::get_url(); + } + + /** * Function for preparing the data for insertion in an SQL query * (The service handles insertion) * diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 56cfbc9364..f4b4d763eb 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -10,16 +10,8 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Post quoting notifications class -* This class handles notifications for quoting users in a post +* This class handles notifying users when they have been quoted in a post * * @package notifications */ @@ -102,7 +94,7 @@ class quote extends \phpbb\notification\type\post $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - $users[] = $row['user_id']; + $users[] = (int) $row['user_id']; } $this->db->sql_freeresult($result); @@ -121,29 +113,6 @@ class quote extends \phpbb\notification\type\post $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options); - // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications - $update_notifications = array(); - $sql = 'SELECT n.* - FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt - WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' - AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . ' - AND n.notification_read = 0 - AND nt.notification_type_id = n.notification_type_id - AND nt.notification_type_enabled = 1'; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // Do not create a new notification - unset($notify_users[$row['user_id']]); - - $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); - $sql = 'UPDATE ' . $this->notifications_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . ' - WHERE notification_id = ' . $row['notification_id']; - $this->db->sql_query($sql); - } - $this->db->sql_freeresult($result); - return $notify_users; } @@ -199,6 +168,14 @@ class quote extends \phpbb\notification\type\post } /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return $this->get_url(); + } + + /** * Get email template * * @return string|bool diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php index fd3f754f8a..55f6bf946d 100644 --- a/phpBB/phpbb/notification/type/report_pm.php +++ b/phpBB/phpbb/notification/type/report_pm.php @@ -10,15 +10,7 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Private message reproted notifications class +* Private message reported notifications class * This class handles notifications for private messages when they are reported * * @package notifications diff --git a/phpBB/phpbb/notification/type/report_pm_closed.php b/phpBB/phpbb/notification/type/report_pm_closed.php index 2e4a1ceb30..56485f5d37 100644 --- a/phpBB/phpbb/notification/type/report_pm_closed.php +++ b/phpBB/phpbb/notification/type/report_pm_closed.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * PM report closed notifications class * This class handles notifications for when reports are closed on PMs (for the one who reported the PM) * @@ -122,7 +114,7 @@ class report_pm_closed extends \phpbb\notification\type\pm */ public function get_avatar() { - return $this->get_user_avatar($this->get_data('closer_id')); + return $this->user_loader->get_avatar($this->get_data('closer_id')); } /** diff --git a/phpBB/phpbb/notification/type/report_post.php b/phpBB/phpbb/notification/type/report_post.php index c2dad6f1bb..9bf035b91e 100644 --- a/phpBB/phpbb/notification/type/report_post.php +++ b/phpBB/phpbb/notification/type/report_post.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Reported post notifications class * This class handles notifications for reported posts * @@ -43,6 +35,13 @@ class report_post extends \phpbb\notification\type\post_in_queue protected $language_key = 'NOTIFICATION_REPORT_POST'; /** + * Inherit notification read status from post. + * + * @var bool + */ + protected $inherit_read_status = false; + + /** * Permission to check for (in find_users_for_notification) * * @var string Permission name diff --git a/phpBB/phpbb/notification/type/report_post_closed.php b/phpBB/phpbb/notification/type/report_post_closed.php index 270ccf0a1a..fff45612b3 100644 --- a/phpBB/phpbb/notification/type/report_post_closed.php +++ b/phpBB/phpbb/notification/type/report_post_closed.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Post report closed notifications class * This class handles notifications for when reports are closed on posts (for the one who reported the post) * @@ -49,6 +41,13 @@ class report_post_closed extends \phpbb\notification\type\post */ protected $language_key = 'NOTIFICATION_REPORT_CLOSED'; + /** + * Inherit notification read status from post. + * + * @var bool + */ + protected $inherit_read_status = false; + public function is_available() { return false; diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php index 8db02f610b..635d05bccd 100644 --- a/phpBB/phpbb/notification/type/topic.php +++ b/phpBB/phpbb/notification/type/topic.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Topic notifications class * This class handles notifications for new topics * @@ -43,6 +35,13 @@ class topic extends \phpbb\notification\type\base protected $language_key = 'NOTIFICATION_TOPIC'; /** + * Inherit notification read status from topic. + * + * @var bool + */ + protected $inherit_read_status = true; + + /** * Notification option data (for outputting to the user) * * @var bool|array False if the service should use it's default data @@ -104,7 +103,7 @@ class topic extends \phpbb\notification\type\base $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - $users[] = $row['user_id']; + $users[] = (int) $row['user_id']; } $this->db->sql_freeresult($result); @@ -228,7 +227,7 @@ class topic extends \phpbb\notification\type\base */ public function pre_create_insert_array($post, $notify_users) { - if (!sizeof($notify_users)) + if (!sizeof($notify_users) || !$this->inherit_read_status) { return array(); } @@ -269,7 +268,7 @@ class topic extends \phpbb\notification\type\base // Topics can be "read" before they are public (while awaiting approval). // Make sure that if the user has read the topic, it's marked as read in the notification - if (isset($pre_create_data[$this->user_id]) && $pre_create_data[$this->user_id] >= $this->notification_time) + if ($this->inherit_read_status && isset($pre_create_data[$this->user_id]) && $pre_create_data[$this->user_id] >= $this->notification_time) { $this->notification_read = true; } diff --git a/phpBB/phpbb/notification/type/topic_in_queue.php b/phpBB/phpbb/notification/type/topic_in_queue.php index 056651bc53..c8c1b5b7e2 100644 --- a/phpBB/phpbb/notification/type/topic_in_queue.php +++ b/phpBB/phpbb/notification/type/topic_in_queue.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Topic in queue notifications class * This class handles notifications for topics when they are put in the moderation queue (for moderators) * diff --git a/phpBB/phpbb/notification/type/type_interface.php b/phpBB/phpbb/notification/type/type_interface.php index cfc6cd461e..2f465aae2b 100644 --- a/phpBB/phpbb/notification/type/type_interface.php +++ b/phpBB/phpbb/notification/type/type_interface.php @@ -10,14 +10,6 @@ namespace phpbb\notification\type; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Base notifications interface * @package notifications */ @@ -107,6 +99,13 @@ interface type_interface public function get_url(); /** + * Get the url to redirect after the item has been marked as read + * + * @return string URL + */ + public function get_redirect_url(); + + /** * URL to unsubscribe to this notification * * @param string|bool $method Method name to unsubscribe from (email|jabber|etc), False to unsubscribe from all notifications for this item diff --git a/phpBB/phpbb/pagination.php b/phpBB/phpbb/pagination.php new file mode 100644 index 0000000000..6a7631c89d --- /dev/null +++ b/phpBB/phpbb/pagination.php @@ -0,0 +1,315 @@ +<?php +/** +* +* @package phpbb +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb; + +class pagination +{ + /** @var \phpbb\template\template */ + protected $template; + + /** @var \phpbb\user */ + protected $user; + + /** + * Constructor + * + * @param \phpbb\template\template $template + * @param \phpbb\user $user + * @param \phpbb\controller\helper $helper + */ + public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\controller\helper $helper) + { + $this->template = $template; + $this->user = $user; + $this->helper = $helper; + } + + /** + * Generate a pagination link based on the url and the page information + * + * @param string $base_url is url prepended to all links generated within the function + * If you use page numbers inside your controller route, base_url should contains a placeholder (%d) + * for the page. Also be sure to specify the pagination path information into the start_name argument + * @param string $on_page is the page for which we want to generate the link + * @param string $start_name is the name of the parameter containing the first item of the given page (example: start=20) + * If you use page numbers inside your controller route, start name should be the string + * that should be removed for the first page (example: /page/%d) + * @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce + * @return URL for the requested page + */ + protected function generate_page_link($base_url, $on_page, $start_name, $per_page) + { + if (!is_string($base_url)) + { + if (is_array($base_url['routes'])) + { + $route = ($on_page > 1) ? $base_url['routes'][1] : $base_url['routes'][0]; + } + else + { + $route = $base_url['routes']; + } + $params = (isset($base_url['params'])) ? $base_url['params'] : array(); + $is_amp = (isset($base_url['is_amp'])) ? $base_url['is_amp'] : true; + $session_id = (isset($base_url['session_id'])) ? $base_url['session_id'] : false; + + if ($on_page > 1 || !is_array($base_url['routes'])) + { + $params[$start_name] = (int) $on_page; + } + + return $this->helper->route($route, $params, $is_amp, $session_id); + } + else + { + $url_delim = (strpos($base_url, '?') === false) ? '?' : ((strpos($base_url, '?') === strlen($base_url) - 1) ? '' : '&'); + return ($on_page > 1) ? $base_url . $url_delim . $start_name . '=' . (($on_page - 1) * $per_page) : $base_url; + } + } + + /** + * Generate template rendered pagination + * Allows full control of rendering of pagination with the template + * + * @param string $base_url is url prepended to all links generated within the function + * If you use page numbers inside your controller route, base_url should contains a placeholder (%d) + * for the page. Also be sure to specify the pagination path information into the start_name argument + * @param string $block_var_name is the name assigned to the pagination data block within the template (example: <!-- BEGIN pagination -->) + * @param string $start_name is the name of the parameter containing the first item of the given page (example: start=20) + * If you use page numbers inside your controller route, start name should be the string + * that should be removed for the first page (example: /page/%d) + * @param int $num_items the total number of items, posts, etc., used to determine the number of pages to produce + * @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce + * @param int $start the item which should be considered currently active, used to determine the page we're on + * @param bool $reverse_count determines whether we weight display of the list towards the start (false) or end (true) of the list + * @param bool $ignore_on_page decides whether we enable an active (unlinked) item, used primarily for embedded lists + * @return null + */ + public function generate_template_pagination($base_url, $block_var_name, $start_name, $num_items, $per_page, $start = 1, $reverse_count = false, $ignore_on_page = false) + { + $total_pages = ceil($num_items / $per_page); + $on_page = $this->get_on_page($per_page, $start); + $u_previous_page = $u_next_page = ''; + + if ($total_pages > 1) + { + if ($reverse_count) + { + $start_page = ($total_pages > 5) ? $total_pages - 4 : 1; + $end_page = $total_pages; + } + else + { + // What we're doing here is calculating what the "start" and "end" pages should be. We + // do this by assuming pagination is "centered" around the currently active page with + // the three previous and three next page links displayed. Anything more than that and + // we display the ellipsis, likewise anything less. + // + // $start_page is the page at which we start creating the list. When we have five or less + // pages we start at page 1 since there will be no ellipsis displayed. Anymore than that + // and we calculate the start based on the active page. This is the min/max calculation. + // First (max) would we end up starting on a page less than 1? Next (min) would we end + // up starting so close to the end that we'd not display our minimum number of pages. + // + // $end_page is the last page in the list to display. Like $start_page we use a min/max to + // determine this number. Again at most five pages? Then just display them all. More than + // five and we first (min) determine whether we'd end up listing more pages than exist. + // We then (max) ensure we're displaying the minimum number of pages. + $start_page = ($total_pages > 5) ? min(max(1, $on_page - 3), $total_pages - 4) : 1; + $end_page = ($total_pages > 5) ? max(min($total_pages, $on_page + 3), 5) : $total_pages; + } + + if ($on_page != 1) + { + $u_previous_page = $this->generate_page_link($base_url, $on_page - 1, $start_name, $per_page); + + $this->template->assign_block_vars($block_var_name, array( + 'PAGE_NUMBER' => '', + 'PAGE_URL' => $u_previous_page, + 'S_IS_CURRENT' => false, + 'S_IS_PREV' => true, + 'S_IS_NEXT' => false, + 'S_IS_ELLIPSIS' => false, + )); + } + + // This do...while exists purely to negate the need for start and end assign_block_vars, i.e. + // to display the first and last page in the list plus any ellipsis. We use this loop to jump + // around a little within the list depending on where we're starting (and ending). + $at_page = 1; + do + { + // We decide whether to display the ellipsis during the loop. The ellipsis is always + // displayed as either the second or penultimate item in the list. So are we at either + // of those points and of course do we even need to display it, i.e. is the list starting + // on at least page 3 and ending three pages before the final item. + $this->template->assign_block_vars($block_var_name, array( + 'PAGE_NUMBER' => $at_page, + 'PAGE_URL' => $this->generate_page_link($base_url, $at_page, $start_name, $per_page), + 'S_IS_CURRENT' => (!$ignore_on_page && $at_page == $on_page), + 'S_IS_NEXT' => false, + 'S_IS_PREV' => false, + 'S_IS_ELLIPSIS' => ($at_page == 2 && $start_page > 2) || ($at_page == $total_pages - 1 && $end_page < $total_pages - 1), + )); + + // We may need to jump around in the list depending on whether we have or need to display + // the ellipsis. Are we on page 2 and are we more than one page away from the start + // of the list? Yes? Then we jump to the start of the list. Likewise are we at the end of + // the list and are there more than two pages left in total? Yes? Then jump to the penultimate + // page (so we can display the ellipsis next pass). Else, increment the counter and keep + // going + if ($at_page == 2 && $at_page < $start_page - 1) + { + $at_page = $start_page; + } + else if ($at_page == $end_page && $end_page < $total_pages - 1) + { + $at_page = $total_pages - 1; + } + else + { + $at_page++; + } + } + while ($at_page <= $total_pages); + + if ($on_page != $total_pages) + { + $u_next_page = $this->generate_page_link($base_url, $on_page + 1, $start_name, $per_page); + + $this->template->assign_block_vars($block_var_name, array( + 'PAGE_NUMBER' => '', + 'PAGE_URL' => $u_next_page, + 'S_IS_CURRENT' => false, + 'S_IS_PREV' => false, + 'S_IS_NEXT' => true, + 'S_IS_ELLIPSIS' => false, + )); + } + } + + // If the block_var_name is a nested block, we will use the last (most + // inner) block as a prefix for the template variables. If the last block + // name is pagination, the prefix is empty. If the rest of the + // block_var_name is not empty, we will modify the last row of that block + // and add our pagination items. + $tpl_block_name = $tpl_prefix = ''; + if (strrpos($block_var_name, '.') !== false) + { + $tpl_block_name = substr($block_var_name, 0, strrpos($block_var_name, '.')); + $tpl_prefix = strtoupper(substr($block_var_name, strrpos($block_var_name, '.') + 1)); + } + else + { + $tpl_prefix = strtoupper($block_var_name); + } + $tpl_prefix = ($tpl_prefix == 'PAGINATION') ? '' : $tpl_prefix . '_'; + + $template_array = array( + $tpl_prefix . 'BASE_URL' => is_string($base_url) ? $base_url : '',//@todo: Fix this for routes + $tpl_prefix . 'START_NAME' => $start_name, + $tpl_prefix . 'PER_PAGE' => $per_page, + 'U_' . $tpl_prefix . 'PREVIOUS_PAGE' => ($on_page != 1) ? $u_previous_page : '', + 'U_' . $tpl_prefix . 'NEXT_PAGE' => ($on_page != $total_pages) ? $u_next_page : '', + $tpl_prefix . 'TOTAL_PAGES' => $total_pages, + $tpl_prefix . 'CURRENT_PAGE' => $on_page, + $tpl_prefix . 'PAGE_NUMBER' => $this->on_page($num_items, $per_page, $start), + ); + + if ($tpl_block_name) + { + $this->template->alter_block_array($tpl_block_name, $template_array, true, 'change'); + } + else + { + $this->template->assign_vars($template_array); + } + } + + /** + * Get current page number + * + * @param int $per_page the number of items, posts, etc. per page + * @param int $start the item which should be considered currently active, used to determine the page we're on + * @return int Current page number + */ + public function get_on_page($per_page, $start) + { + return floor($start / $per_page) + 1; + } + + /** + * Return current page + * + * @param int $num_items the total number of items, posts, topics, etc. + * @param int $per_page the number of items, posts, etc. per page + * @param int $start the item which should be considered currently active, used to determine the page we're on + * @return string Descriptive pagination string (e.g. "page 1 of 10") + */ + public function on_page($num_items, $per_page, $start) + { + $on_page = $this->get_on_page($per_page, $start); + return $this->user->lang('PAGE_OF', $on_page, max(ceil($num_items / $per_page), 1)); + } + + /** + * Get current page number + * + * @param int $start the item which should be considered currently active, used to determine the page we're on + * @param int $per_page the number of items, posts, etc. per page + * @param int $num_items the total number of items, posts, topics, etc. + * @return int Current page number + */ + public function validate_start($start, $per_page, $num_items) + { + if ($start < 0 || $start >= $num_items) + { + return ($start < 0 || $num_items <= 0) ? 0 : floor(($num_items - 1) / $per_page) * $per_page; + } + + return $start; + } + + /** + * Get new start when searching from the end + * + * If the user is trying to reach late pages, start searching from the end. + * + * @param int $start the item which should be considered currently active, used to determine the page we're on + * @param int $limit the number of items, posts, etc. to display + * @param int $num_items the total number of items, posts, topics, etc. + * @return int Current page number + */ + public function reverse_start($start, $limit, $num_items) + { + return max(0, $num_items - $limit - $start); + } + + /** + * Get new item limit when searching from the end + * + * If the user is trying to reach late pages, start searching from the end. + * In this case the items to display might be lower then the actual per_page setting. + * + * @param int $start the item which should be considered currently active, used to determine the page we're on + * @param int $per_page the number of items, posts, etc. per page + * @param int $num_items the total number of items, posts, topics, etc. + * @return int Current page number + */ + public function reverse_limit($start, $per_page, $num_items) + { + if ($start + $per_page > $num_items) + { + return min($per_page, max(1, $num_items - $start)); + } + + return $per_page; + } +} diff --git a/phpBB/phpbb/passwords/driver/base.php b/phpBB/phpbb/passwords/driver/base.php new file mode 100644 index 0000000000..8256fd721c --- /dev/null +++ b/phpBB/phpbb/passwords/driver/base.php @@ -0,0 +1,45 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\passwords\driver; + +/** +* @package passwords +*/ +abstract class base implements driver_interface +{ + /** @var phpbb\config\config */ + protected $config; + + /** @var phpbb\passwords\driver\helper */ + protected $helper; + + /** @var driver name */ + protected $name; + + /** + * Constructor of passwords driver object + * + * @param \phpbb\config\config $config phpBB config + * @param \phpbb\passwords\driver\helper $helper Password driver helper + */ + public function __construct(\phpbb\config\config $config, helper $helper) + { + $this->config = $config; + $this->helper = $helper; + } + + /** + * @inheritdoc + */ + public function is_supported() + { + return true; + } +} diff --git a/phpBB/phpbb/passwords/driver/bcrypt.php b/phpBB/phpbb/passwords/driver/bcrypt.php new file mode 100644 index 0000000000..1d1b1e267d --- /dev/null +++ b/phpBB/phpbb/passwords/driver/bcrypt.php @@ -0,0 +1,104 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\passwords\driver; + +/** +* @package passwords +*/ +class bcrypt extends base +{ + const PREFIX = '$2a$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function hash($password, $salt = '') + { + // The 2x and 2y prefixes of bcrypt might not be supported + // Revert to 2a if this is the case + $prefix = (!$this->is_supported()) ? '$2a$' : $this->get_prefix(); + + // Do not support 8-bit characters with $2a$ bcrypt + // Also see http://www.php.net/security/crypt_blowfish.php + if ($prefix === self::PREFIX) + { + if (ord($password[strlen($password)-1]) & 128) + { + return false; + } + } + + if ($salt == '') + { + $salt = $prefix . '10$' . $this->get_random_salt(); + } + + $hash = crypt($password, $salt); + if (strlen($hash) < 60) + { + return false; + } + return $hash; + } + + /** + * @inheritdoc + */ + public function check($password, $hash) + { + $salt = substr($hash, 0, 29); + if (strlen($salt) != 29) + { + return false; + } + + if ($hash == $this->hash($password, $salt)) + { + return true; + } + return false; + } + + /** + * Get a random salt value with a length of 22 characters + * + * @return string Salt for password hashing + */ + protected function get_random_salt() + { + return $this->helper->hash_encode64($this->helper->get_random_salt(22), 22); + } + + /** + * @inheritdoc + */ + public function get_settings_only($hash, $full = false) + { + if ($full) + { + $pos = stripos($hash, '$', 1) + 1; + $length = 22 + (strripos($hash, '$') + 1 - $pos); + } + else + { + $pos = strripos($hash, '$') + 1; + $length = 22; + } + return substr($hash, $pos, $length); + } +} diff --git a/phpBB/phpbb/passwords/driver/bcrypt_2y.php b/phpBB/phpbb/passwords/driver/bcrypt_2y.php new file mode 100644 index 0000000000..11c3617e49 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/bcrypt_2y.php @@ -0,0 +1,34 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\passwords\driver; + +/** +* @package passwords +*/ +class bcrypt_2y extends bcrypt +{ + const PREFIX = '$2y$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function is_supported() + { + return (version_compare(PHP_VERSION, '5.3.7', '<')) ? false : true; + } +} diff --git a/phpBB/phpbb/passwords/driver/driver_interface.php b/phpBB/phpbb/passwords/driver/driver_interface.php new file mode 100644 index 0000000000..ebaf0626af --- /dev/null +++ b/phpBB/phpbb/passwords/driver/driver_interface.php @@ -0,0 +1,60 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\passwords\driver; + +/** +* @package passwords +*/ +interface driver_interface +{ + /** + * Check if hash type is supported + * + * @return bool True if supported, false if not + */ + public function is_supported(); + + /** + * Returns the hash prefix + * + * @return string Hash prefix + */ + public function get_prefix(); + + /** + * Hash the password + * + * @param string $password The password that should be hashed + * + * @return bool|string Password hash or false if something went wrong + * during hashing + */ + public function hash($password); + + /** + * Check the password against the supplied hash + * + * @param string $password The password to check + * @param string $hash The password hash to check against + * + * @return bool True if password is correct, else false + */ + public function check($password, $hash); + + /** + * Get only the settings of the specified hash + * + * @param string $hash Password hash + * @param bool $full Return full settings or only settings + * related to the salt + * @return string String containing the hash settings + */ + public function get_settings_only($hash, $full = false); +} diff --git a/phpBB/phpbb/passwords/driver/helper.php b/phpBB/phpbb/passwords/driver/helper.php new file mode 100644 index 0000000000..4b8dc9a123 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/helper.php @@ -0,0 +1,144 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\passwords\driver; + +/** +* @package passwords +*/ +class helper +{ + /** + * @var phpbb\config\config + */ + protected $config; + + /** + * base64 alphabet + * @var string + */ + public $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + + /** + * Construct a driver helper object + * + * @param phpbb\config\config $config phpBB configuration + */ + public function __construct(\phpbb\config\config $config) + { + $this->config = $config; + } + + /** + * Base64 encode hash + * + * @param string $input Input string + * @param int $count Input string length + * + * @return string base64 encoded string + */ + public function hash_encode64($input, $count) + { + $output = ''; + $i = 0; + + do + { + $value = ord($input[$i++]); + $output .= $this->itoa64[$value & 0x3f]; + + if ($i < $count) + { + $value |= ord($input[$i]) << 8; + } + + $output .= $this->itoa64[($value >> 6) & 0x3f]; + + if ($i++ >= $count) + { + break; + } + + if ($i < $count) + { + $value |= ord($input[$i]) << 16; + } + + $output .= $this->itoa64[($value >> 12) & 0x3f]; + + if ($i++ >= $count) + { + break; + } + + $output .= $this->itoa64[($value >> 18) & 0x3f]; + } + while ($i < $count); + + return $output; + } + + /** + * Return unique id + * + * @param string $extra Additional entropy + * + * @return string Unique id + */ + public function unique_id($extra = 'c') + { + static $dss_seeded = false; + + $val = $this->config['rand_seed'] . microtime(); + $val = md5($val); + $this->config['rand_seed'] = md5($this->config['rand_seed'] . $val . $extra); + + if ($dss_seeded !== true && ($this->config['rand_seed_last_update'] < time() - rand(1,10))) + { + $this->config->set('rand_seed_last_update', time(), true); + $this->config->set('rand_seed', $this->config['rand_seed'], true); + $dss_seeded = true; + } + + return substr($val, 4, 16); + } + + /** + * Get random salt with specified length + * + * @param int $length Salt length + * @param string $rand_seed Seed for random data (optional). For tests. + * + * @return string Random salt with specified length + */ + public function get_random_salt($length, $rand_seed = '/dev/urandom') + { + $random = ''; + + if (($fh = @fopen($rand_seed, 'rb'))) + { + $random = fread($fh, $length); + fclose($fh); + } + + if (strlen($random) < $length) + { + $random = ''; + $random_state = $this->unique_id(); + + for ($i = 0; $i < $length; $i += 16) + { + $random_state = md5($this->unique_id() . $random_state); + $random .= pack('H*', md5($random_state)); + } + $random = substr($random, 0, $length); + } + return $random; + } +} diff --git a/phpBB/phpbb/passwords/driver/phpass.php b/phpBB/phpbb/passwords/driver/phpass.php new file mode 100644 index 0000000000..80c4d7a7f0 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/phpass.php @@ -0,0 +1,26 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\passwords\driver; + +/** +* @package passwords +*/ +class phpass extends salted_md5 +{ + const PREFIX = '$P$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } +} diff --git a/phpBB/phpbb/passwords/driver/salted_md5.php b/phpBB/phpbb/passwords/driver/salted_md5.php new file mode 100644 index 0000000000..5c72726422 --- /dev/null +++ b/phpBB/phpbb/passwords/driver/salted_md5.php @@ -0,0 +1,160 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\passwords\driver; + +/** +* +* @version Version 0.1 / slightly modified for phpBB 3.1.x (using $H$ as hash type identifier) +* +* Portable PHP password hashing framework. +* +* Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in +* the public domain. +* +* There's absolutely no warranty. +* +* The homepage URL for this framework is: +* +* http://www.openwall.com/phpass/ +* +* Please be sure to update the Version line if you edit this file in any way. +* It is suggested that you leave the main version number intact, but indicate +* your project name (after the slash) and add your own revision information. +* +* Please do not change the "private" password hashing method implemented in +* here, thereby making your hashes incompatible. However, if you must, please +* change the hash type identifier (the "$P$") to something different. +* +* Obviously, since this code is in the public domain, the above are not +* requirements (there can be none), but merely suggestions. +* +*/ + +/** +* @package passwords +*/ +class salted_md5 extends base +{ + const PREFIX = '$H$'; + + /** + * @inheritdoc + */ + public function get_prefix() + { + return self::PREFIX; + } + + /** + * @inheritdoc + */ + public function hash($password, $setting = '') + { + if ($setting) + { + if (($settings = $this->get_hash_settings($setting)) === false) + { + // Return md5 of password if settings do not + // comply with our standards. This will only + // happen if pre-determined settings are + // directly passed to the driver. The manager + // will not do this. Same as the old hashing + // implementatio in phpBB 3.0 + return md5($password); + } + } + else + { + $settings = $this->get_hash_settings($this->generate_salt()); + } + + $hash = md5($settings['salt'] . $password, true); + do + { + $hash = md5($hash . $password, true); + } + while (--$settings['count']); + + $output = $settings['full']; + $output .= $this->helper->hash_encode64($hash, 16); + + return $output; + } + + /** + * @inheritdoc + */ + public function check($password, $hash) + { + if (strlen($hash) !== 34) + { + return md5($password) === $hash; + } + + return $hash === $this->hash($password, $hash); + } + + /** + * Generate salt for hashing method + * + * @return string Salt for hashing method + */ + protected function generate_salt() + { + $count = 6; + + $random = $this->helper->get_random_salt($count); + + $salt = $this->get_prefix(); + $salt .= $this->helper->itoa64[min($count + 5, 30)]; + $salt .= $this->helper->hash_encode64($random, $count); + + return $salt; + } + + /** + * Get hash settings + * + * @param string $hash The hash that contains the settings + * + * @return bool|array Array containing the count_log2, salt, and full + * hash settings string or false if supplied hash is empty + * or contains incorrect settings + */ + public function get_hash_settings($hash) + { + if (empty($hash)) + { + return false; + } + + $count_log2 = strpos($this->helper->itoa64, $hash[3]); + $salt = substr($hash, 4, 8); + + if ($count_log2 < 7 || $count_log2 > 30 || strlen($salt) != 8) + { + return false; + } + + return array( + 'count' => 1 << $count_log2, + 'salt' => $salt, + 'full' => substr($hash, 0, 12), + ); + } + + /** + * @inheritdoc + */ + public function get_settings_only($hash, $full = false) + { + return substr($hash, 3, 9); + } +} diff --git a/phpBB/phpbb/passwords/helper.php b/phpBB/phpbb/passwords/helper.php new file mode 100644 index 0000000000..95bad5805f --- /dev/null +++ b/phpBB/phpbb/passwords/helper.php @@ -0,0 +1,103 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\passwords; + +/** +* @package passwords +*/ +class helper +{ + /** + * Get hash settings from combined hash + * + * @param string $hash Password hash of combined hash + * + * @return array An array containing the hash settings for the hash + * types in successive order as described by the combined + * password hash or an empty array if hash does not + * properly fit the combined hash format + */ + public function get_combined_hash_settings($hash) + { + $output = array(); + + preg_match('#^\$([a-zA-Z0-9\\\]*?)\$#', $hash, $match); + $hash_settings = substr($hash, strpos($hash, $match[1]) + strlen($match[1]) + 1); + $matches = explode('\\', $match[1]); + foreach ($matches as $cur_type) + { + $dollar_position = strpos($hash_settings, '$'); + $output[] = substr($hash_settings, 0, ($dollar_position != false) ? $dollar_position : strlen($hash_settings)); + $hash_settings = substr($hash_settings, $dollar_position + 1); + } + + return $output; + } + + /** + * Combine hash prefixes, settings, and actual hash + * + * @param array $data Array containing the keys 'prefix' and 'settings'. + * It will hold the prefixes and settings + * @param string $type Data type of the supplied value + * @param string $value Value that should be put into the data array + * + * @return string|null Return complete combined hash if type is neither + * 'prefix' nor 'settings', nothing if it is + */ + public function combine_hash_output(&$data, $type, $value) + { + if ($type == 'prefix') + { + $data[$type] .= ($data[$type] !== '$') ? '\\' : ''; + $data[$type] .= str_replace('$', '', $value); + } + elseif ($type == 'settings') + { + $data[$type] .= ($data[$type] !== '$') ? '$' : ''; + $data[$type] .= $value; + } + else + { + // Return full hash + return $data['prefix'] . $data['settings'] . '$' . $value; + } + } + + /** + * Rebuild hash for hashing functions + * + * @param string $prefix Hash prefix + * @param string $settings Hash settings + * + * @return string Rebuilt hash for hashing functions + */ + public function rebuild_hash($prefix, $settings) + { + $rebuilt_hash = $prefix; + if (strpos($settings, '\\') !== false) + { + $settings = str_replace('\\', '$', $settings); + } + $rebuilt_hash .= $settings; + return $rebuilt_hash; + } + + /** + * Obtain only the actual hash after the prefixes + * + * @param string $hash The full password hash + * @return string Actual hash (incl. settings) + */ + public function obtain_hash_only($hash) + { + return substr($hash, strripos($hash, '$') + 1); + } +} diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php new file mode 100644 index 0000000000..0ac6b05ec4 --- /dev/null +++ b/phpBB/phpbb/passwords/manager.php @@ -0,0 +1,341 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\passwords; + +/** +* @package passwords +*/ +class manager +{ + /** + * Default hashing method + */ + protected $type = false; + + /** + * Hashing algorithm type map + * Will be used to map hash prefix to type + */ + protected $type_map = false; + + /** + * Service collection of hashing algorithms + * Needs to be public for passwords helper + */ + public $algorithms = false; + + /** + * Password convert flag. Signals that password should be converted + */ + public $convert_flag = false; + + /** + * Passwords helper + * @var phpbb\passwords\helper + */ + protected $helper; + + /** + * phpBB configuration + * @var phpbb\config\config + */ + protected $config; + + /** + * Construct a passwords object + * + * @param phpbb\config\config $config phpBB configuration + * @param array $hashing_algorithms Hashing driver + * service collection + * @param phpbb\passwords\helper $helper Passwords helper object + * @param string $defaults List of default driver types + */ + public function __construct(\phpbb\config\config $config, $hashing_algorithms, helper $helper, $defaults) + { + $this->config = $config; + $this->helper = $helper; + + $this->fill_type_map($hashing_algorithms); + $this->register_default_type($defaults); + } + + /** + * Register default type + * Will register the first supported type from the list of default types + * + * @param array $defaults List of default types in order from first to + * use to last to use + */ + protected function register_default_type($defaults) + { + foreach ($defaults as $type) + { + if ($this->algorithms[$type]->is_supported()) + { + $this->type = $this->algorithms[$type]->get_prefix(); + break; + } + } + } + + /** + * Fill algorithm type map + * + * @param phpbb\di\service_collection $hashing_algorithms + */ + protected function fill_type_map($hashing_algorithms) + { + foreach ($hashing_algorithms as $algorithm) + { + if (!isset($this->type_map[$algorithm->get_prefix()])) + { + $this->type_map[$algorithm->get_prefix()] = $algorithm; + } + } + $this->algorithms = $hashing_algorithms; + } + + /** + * Get the algorithm specified by a specific prefix + * + * @param string $prefix Password hash prefix + * + * @return object|bool The hash type object or false if prefix is not + * supported + */ + protected function get_algorithm($prefix) + { + if (isset($this->type_map[$prefix])) + { + return $this->type_map[$prefix]; + } + else + { + return false; + } + } + + /** + * Detect the hash type of the supplied hash + * + * @param string $hash Password hash that should be checked + * + * @return object|bool The hash type object or false if the specified + * type is not supported + */ + public function detect_algorithm($hash) + { + /* + * preg_match() will also show hashing algos like $2a\H$, which + * is a combination of bcrypt and phpass. Legacy algorithms + * like md5 will not be matched by this and need to be treated + * differently. + */ + if (!preg_match('#^\$([a-zA-Z0-9\\\]*?)\$#', $hash, $match)) + { + return $this->get_algorithm('$H$'); + } + + // Be on the lookout for multiple hashing algorithms + // 2 is correct: H\2a > 2, H\P > 2 + if (strlen($match[1]) > 2) + { + $hash_types = explode('\\', $match[1]); + $return_ary = array(); + foreach ($hash_types as $type) + { + // we do not support the same hashing + // algorithm more than once + if (isset($return_ary[$type])) + { + return false; + } + + $return_ary[$type] = $this->get_algorithm('$' . $type . '$'); + + if (empty($return_ary[$type])) + { + return false; + } + } + return $return_ary; + } + + // get_algorithm() will automatically return false if prefix + // is not supported + return $this->get_algorithm($match[0]); + } + + /** + * Hash supplied password + * + * @param string $password Password that should be hashed + * @param string $type Hash type. Will default to standard hash type if + * none is supplied + * @return string|bool Password hash of supplied password or false if + * if something went wrong during hashing + */ + public function hash($password, $type = '') + { + if (strlen($password) > 4096) + { + // If the password is too huge, we will simply reject it + // and not let the server try to hash it. + return false; + } + + // Try to retrieve algorithm by service name if type doesn't + // start with dollar sign + if (!is_array($type) && strpos($type, '$') !== 0 && isset($this->algorithms[$type])) + { + $type = $this->algorithms[$type]->get_prefix(); + } + + $type = ($type === '') ? $this->type : $type; + + if (is_array($type)) + { + return $this->combined_hash_password($password, $type); + } + + if (isset($this->type_map[$type])) + { + $hashing_algorithm = $this->type_map[$type]; + } + else + { + return false; + } + + return $hashing_algorithm->hash($password); + } + + /** + * Check supplied password against hash and set convert_flag if password + * needs to be converted to different format (preferrably newer one) + * + * @param string $password Password that should be checked + * @param string $hash Stored hash + * @return string|bool True if password is correct, false if not + */ + public function check($password, $hash) + { + if (strlen($password) > 4096) + { + // If the password is too huge, we will simply reject it + // and not let the server try to hash it. + return false; + } + + // First find out what kind of hash we're dealing with + $stored_hash_type = $this->detect_algorithm($hash); + if ($stored_hash_type == false) + { + return false; + } + + // Multiple hash passes needed + if (is_array($stored_hash_type)) + { + $correct = $this->check_combined_hash($password, $stored_hash_type, $hash); + $this->convert_flag = ($correct === true) ? true : false; + return $correct; + } + + if ($stored_hash_type->get_prefix() !== $this->type) + { + $this->convert_flag = true; + } + else + { + $this->convert_flag = false; + } + + return $stored_hash_type->check($password, $hash); + } + + /** + * Create combined hash from already hashed password + * + * @param string $password_hash Complete current password hash + * @param string $type Type of the hashing algorithm the password hash + * should be combined with + * @return string|bool Combined password hash if combined hashing was + * successful, else false + */ + public function combined_hash_password($password_hash, $type) + { + $data = array( + 'prefix' => '$', + 'settings' => '$', + ); + $hash_settings = $this->helper->get_combined_hash_settings($password_hash); + $hash = $hash_settings[0]; + + // Put settings of current hash into data array + $stored_hash_type = $this->detect_algorithm($password_hash); + $this->helper->combine_hash_output($data, 'prefix', $stored_hash_type->get_prefix()); + $this->helper->combine_hash_output($data, 'settings', $stored_hash_type->get_settings_only($password_hash)); + + // Hash current hash with the defined types + foreach ($type as $cur_type) + { + if (isset($this->algorithms[$cur_type])) + { + $new_hash_type = $this->algorithms[$cur_type]; + } + else + { + $new_hash_type = $this->get_algorithm($cur_type); + } + + if (!$new_hash_type) + { + return false; + } + + $new_hash = $new_hash_type->hash(str_replace($stored_hash_type->get_settings_only($password_hash), '', $hash)); + $this->helper->combine_hash_output($data, 'prefix', $new_hash_type->get_prefix()); + $this->helper->combine_hash_output($data, 'settings', substr(str_replace('$', '\\', $new_hash_type->get_settings_only($new_hash, true)), 0)); + $hash = str_replace($new_hash_type->get_settings_only($new_hash), '', $this->helper->obtain_hash_only($new_hash)); + } + return $this->helper->combine_hash_output($data, 'hash', $hash); + } + + /** + * Check combined password hash against the supplied password + * + * @param string $password Password entered by user + * @param array $stored_hash_type An array containing the hash types + * as described by stored password hash + * @param string $hash Stored password hash + * + * @return bool True if password is correct, false if not + */ + public function check_combined_hash($password, $stored_hash_type, $hash) + { + $i = 0; + $data = array( + 'prefix' => '$', + 'settings' => '$', + ); + $hash_settings = $this->helper->get_combined_hash_settings($hash); + foreach ($stored_hash_type as $key => $hash_type) + { + $rebuilt_hash = $this->helper->rebuild_hash($hash_type->get_prefix(), $hash_settings[$i]); + $this->helper->combine_hash_output($data, 'prefix', $key); + $this->helper->combine_hash_output($data, 'settings', $hash_settings[$i]); + $cur_hash = $hash_type->hash($password, $rebuilt_hash); + $password = str_replace($rebuilt_hash, '', $cur_hash); + $i++; + } + return ($hash === $this->helper->combine_hash_output($data, 'hash', $password)); + } +} diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php index b2ed11a927..fefef39c51 100644 --- a/phpBB/phpbb/path_helper.php +++ b/phpBB/phpbb/path_helper.php @@ -10,14 +10,6 @@ namespace phpbb; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * A class with various functions that are related to paths, files and the filesystem * @package phpBB3 */ @@ -89,26 +81,45 @@ class path_helper } /** - * Update a path to the correct relative root path + * Update a web path to the correct relative root path * * This replaces $phpbb_root_path . some_url with - * get_web_root_path() . some_url OR if $phpbb_root_path - * is not at the beginning of $path, just prepends the - * web root path + * get_web_root_path() . some_url * * @param string $path The path to be updated * @return string */ public function update_web_root_path($path) { - $web_root_path = $this->get_web_root_path($this->symfony_request); - if (strpos($path, $this->phpbb_root_path) === 0) { $path = substr($path, strlen($this->phpbb_root_path)); + + return $this->get_web_root_path() . $path; } - return $web_root_path . $path; + return $path; + } + + /** + * Strips away the web root path and prepends the normal root path + * + * This replaces get_web_root_path() . some_url with + * $phpbb_root_path . some_url + * + * @param string $path The path to be updated + * @return string + */ + public function remove_web_root_path($path) + { + if (strpos($path, $this->get_web_root_path()) === 0) + { + $path = substr($path, strlen($this->get_web_root_path())); + + return $this->phpbb_root_path . $path; + } + + return $path; } /** @@ -138,6 +149,16 @@ class path_helper $script_name = $this->symfony_request->getScriptName(); /* + * If the path info is empty but we're using app.php, then we + * might be using an empty route like app.php/ which is + * supported by symfony's routing + */ + if ($path_info === '/' && preg_match('/app\.' . $this->php_ext . '\/$/', $request_uri)) + { + return $this->web_root_path = $this->phpbb_root_path . '../'; + } + + /* * If the path info is empty (single /), then we're not using * a route like app.php/foo/bar */ @@ -172,4 +193,27 @@ class path_helper */ return $this->web_root_path = $this->phpbb_root_path . str_repeat('../', $corrections - 1); } + + /** + * Eliminates useless . and .. components from specified URL + * + * @param string $url URL to clean + * + * @return string Cleaned URL + */ + public function clean_url($url) + { + $delimiter_position = strpos($url, '://'); + // URL should contain :// but it shouldn't start with it. + // Do not clean URLs that do not fit these constraints. + if (empty($delimiter_position)) + { + return $url; + } + $scheme = substr($url, 0, $delimiter_position) . '://'; + // Add length of URL delimiter to position + $path = substr($url, $delimiter_position + 3); + + return $scheme . $this->filesystem->clean_path($path); + } } diff --git a/phpBB/phpbb/permissions.php b/phpBB/phpbb/permissions.php index d0405471bc..3cf39b5126 100644 --- a/phpBB/phpbb/permissions.php +++ b/phpBB/phpbb/permissions.php @@ -9,14 +9,6 @@ namespace phpbb; -/** -* DO NOT CHANGE -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class permissions { /** @@ -65,7 +57,7 @@ class permissions * 'lang' => 'ACL_U_VIEWPROFILE', * 'cat' => 'profile', * ), - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('types', 'categories', 'permissions'); extract($phpbb_dispatcher->trigger_event('core.permissions', compact($vars))); @@ -259,6 +251,7 @@ class permissions 'f_reply' => array('lang' => 'ACL_F_REPLY', 'cat' => 'post'), 'f_edit' => array('lang' => 'ACL_F_EDIT', 'cat' => 'post'), 'f_delete' => array('lang' => 'ACL_F_DELETE', 'cat' => 'post'), + 'f_softdelete' => array('lang' => 'ACL_F_SOFTDELETE', 'cat' => 'post'), 'f_ignoreflood' => array('lang' => 'ACL_F_IGNOREFLOOD', 'cat' => 'post'), 'f_postcount' => array('lang' => 'ACL_F_POSTCOUNT', 'cat' => 'post'), 'f_noapprove' => array('lang' => 'ACL_F_NOAPPROVE', 'cat' => 'post'), diff --git a/phpBB/phpbb/php/ini.php b/phpBB/phpbb/php/ini.php index 8767091aba..f0f53807fe 100644 --- a/phpBB/phpbb/php/ini.php +++ b/phpBB/phpbb/php/ini.php @@ -10,14 +10,6 @@ namespace phpbb\php; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Wrapper class for ini_get function. * * Provides easier handling of the different interpretations of ini values. diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php new file mode 100644 index 0000000000..b988ce7ce0 --- /dev/null +++ b/phpBB/phpbb/plupload/plupload.php @@ -0,0 +1,375 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\plupload; + +/** +* This class handles all server-side plupload functions +* +* @package \phpbb\plupload\plupload +*/ +class plupload +{ + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var \phpbb\config\config + */ + protected $config; + + /** + * @var \phpbb\request\request_interface + */ + protected $request; + + /** + * @var \phpbb\user + */ + protected $user; + + /** + * @var \phpbb\php\ini + */ + protected $php_ini; + + /** + * @var \phpbb\mimetype\guesser + */ + protected $mimetype_guesser; + + /** + * Final destination for uploaded files, i.e. the "files" directory. + * @var string + */ + protected $upload_directory; + + /** + * Temporary upload directory for plupload uploads. + * @var string + */ + protected $temporary_directory; + + /** + * Constructor. + * + * @param string $phpbb_root_path + * @param \phpbb\config\config $config + * @param \phpbb\request\request_interface $request + * @param \phpbb\user $user + * @param \phpbb\php\ini $php_ini + * @param \phpbb\mimetype\guesser $mimetype_guesser + * + * @return null + */ + public function __construct($phpbb_root_path, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\user $user, \phpbb\php\ini $php_ini, \phpbb\mimetype\guesser $mimetype_guesser) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->config = $config; + $this->request = $request; + $this->user = $user; + $this->php_ini = $php_ini; + $this->mimetype_guesser = $mimetype_guesser; + + $this->upload_directory = $this->phpbb_root_path . $this->config['upload_path']; + $this->temporary_directory = $this->upload_directory . '/plupload'; + } + + /** + * Plupload allows for chunking so we must check for that and assemble + * the whole file first before performing any checks on it. + * + * @param string $form_name The name of the file element in the upload form + * + * @return array|null null if there are no chunks to piece together + * otherwise array containing the path to the + * pieced-together file and its size + */ + public function handle_upload($form_name) + { + $chunks_expected = $this->request->variable('chunks', 0); + + // If chunking is disabled or we are not using plupload, just return + // and handle the file as usual + if ($chunks_expected < 2) + { + return; + } + + $file_name = $this->request->variable('name', ''); + $chunk = $this->request->variable('chunk', 0); + + $this->user->add_lang('plupload'); + $this->prepare_temporary_directory(); + + $file_path = $this->temporary_filepath($file_name); + $this->integrate_uploaded_file($form_name, $chunk, $file_path); + + // If we are done with all the chunks, strip the .part suffix and then + // handle the resulting file as normal, otherwise die and await the + // next chunk. + if ($chunk == $chunks_expected - 1) + { + rename("{$file_path}.part", $file_path); + + // Need to modify some of the $_FILES values to reflect the new file + return array( + 'tmp_name' => $file_path, + 'name' => $this->request->variable('real_filename', ''), + 'size' => filesize($file_path), + 'type' => $this->mimetype_guesser->guess($file_path, $file_name), + ); + } + else + { + $json_response = new \phpbb\json_response(); + $json_response->send(array( + 'jsonrpc' => '2.0', + 'id' => 'id', + 'result' => null, + )); + } + } + + /** + * Fill in the plupload configuration options in the template + * + * @param \phpbb\cache\service $cache + * @param \phpbb\template\template $template + * @param string $s_action The URL to submit the POST data to + * @param int $forum_id The ID of the forum + * @param int $max_files Maximum number of files allowed. 0 for unlimited. + * + * @return null + */ + public function configure(\phpbb\cache\service $cache, \phpbb\template\template $template, $s_action, $forum_id, $max_files) + { + $filters = $this->generate_filter_string($cache, $forum_id); + $chunk_size = $this->get_chunk_size(); + $resize = $this->generate_resize_string(); + + $template->assign_vars(array( + 'S_RESIZE' => $resize, + 'S_PLUPLOAD' => true, + 'FILTERS' => $filters, + 'CHUNK_SIZE' => $chunk_size, + 'S_PLUPLOAD_URL' => htmlspecialchars_decode($s_action), + 'MAX_ATTACHMENTS' => $max_files, + 'ATTACH_ORDER' => ($this->config['display_order']) ? 'asc' : 'desc', + 'L_TOO_MANY_ATTACHMENTS' => $this->user->lang('TOO_MANY_ATTACHMENTS', $max_files), + )); + + $this->user->add_lang('plupload'); + } + + /** + * Checks whether the page request was sent by plupload or not + * + * @return bool + */ + public function is_active() + { + return $this->request->header('X-PHPBB-USING-PLUPLOAD', false); + } + + /** + * Returns whether the current HTTP request is a multipart request. + * + * @return bool + */ + public function is_multipart() + { + $content_type = $this->request->server('CONTENT_TYPE'); + + return strpos($content_type, 'multipart') === 0; + } + + /** + * Sends an error message back to the client via JSON response + * + * @param int $code The error code + * @param string $msg The translation string of the message to be sent + * + * @return null + */ + public function emit_error($code, $msg) + { + $json_response = new \phpbb\json_response(); + $json_response->send(array( + 'jsonrpc' => '2.0', + 'id' => 'id', + 'error' => array( + 'code' => $code, + 'message' => $this->user->lang($msg), + ), + )); + } + + /** + * Looks at the list of allowed extensions and generates a string + * appropriate for use in configuring plupload with + * + * @param \phpbb\cache\service $cache + * @param string $forum_id The ID of the forum + * + * @return string + */ + public function generate_filter_string(\phpbb\cache\service $cache, $forum_id) + { + $attach_extensions = $cache->obtain_attach_extensions($forum_id); + unset($attach_extensions['_allowed_']); + $groups = array(); + + // Re-arrange the extension array to $groups[$group_name][] + foreach ($attach_extensions as $extension => $extension_info) + { + if (!isset($groups[$extension_info['group_name']])) + { + $groups[$extension_info['group_name']] = array(); + } + + $groups[$extension_info['group_name']][] = $extension; + } + + $filters = array(); + foreach ($groups as $group => $extensions) + { + $filters[] = sprintf( + "{title: '%s', extensions: '%s'}", + addslashes(ucfirst(strtolower($group))), + addslashes(implode(',', $extensions)) + ); + } + + return implode(',', $filters); + } + + /** + * Generates a string that is used to tell plupload to automatically resize + * files before uploading them. + * + * @return string + */ + public function generate_resize_string() + { + $resize = ''; + if ($this->config['img_max_height'] > 0 && $this->config['img_max_width'] > 0) + { + $resize = sprintf( + 'resize: {width: %d, height: %d, quality: 100},', + (int) $this->config['img_max_height'], + (int) $this->config['img_max_width'] + ); + } + + return $resize; + } + + /** + * Checks various php.ini values and the maximum file size to determine + * the maximum size chunks a file can be split up into for upload + * + * @return int + */ + public function get_chunk_size() + { + $max = min( + $this->php_ini->get_bytes('upload_max_filesize'), + $this->php_ini->get_bytes('post_max_size'), + max(1, $this->php_ini->get_bytes('memory_limit')), + $this->config['max_filesize'] + ); + + // Use half of the maximum possible to leave plenty of room for other + // POST data. + return floor($max / 2); + } + + protected function temporary_filepath($file_name) + { + // Must preserve the extension for plupload to work. + return sprintf( + '%s/%s_%s%s', + $this->temporary_directory, + $this->config['plupload_salt'], + md5($file_name), + \filespec::get_extension($file_name) + ); + } + + /** + * Checks whether the chunk we are about to deal with was actually uploaded + * by PHP and actually exists, if not, it generates an error + * + * @param string $form_name The name of the file in the form data + * + * @return null + */ + protected function integrate_uploaded_file($form_name, $chunk, $file_path) + { + $is_multipart = $this->is_multipart(); + $upload = $this->request->file($form_name); + if ($is_multipart && (!isset($upload['tmp_name']) || !is_uploaded_file($upload['tmp_name']))) + { + $this->emit_error(103, 'PLUPLOAD_ERR_MOVE_UPLOADED'); + } + + $tmp_file = $this->temporary_filepath($upload['tmp_name']); + + if (!move_uploaded_file($upload['tmp_name'], $tmp_file)) + { + $this->emit_error(103, 'PLUPLOAD_ERR_MOVE_UPLOADED'); + } + + $out = fopen("{$file_path}.part", $chunk == 0 ? 'wb' : 'ab'); + if (!$out) + { + $this->emit_error(102, 'PLUPLOAD_ERR_OUTPUT'); + } + + $in = fopen(($is_multipart) ? $tmp_file : 'php://input', 'rb'); + if (!$in) + { + $this->emit_error(101, 'PLUPLOAD_ERR_INPUT'); + } + + while ($buf = fread($in, 4096)) + { + fwrite($out, $buf); + } + + fclose($in); + fclose($out); + + if ($is_multipart) + { + unlink($tmp_file); + } + } + + /** + * Creates the temporary directory if it does not already exist. + * + * @return null + */ + protected function prepare_temporary_directory() + { + if (!file_exists($this->temporary_directory)) + { + mkdir($this->temporary_directory); + + copy( + $this->upload_directory . '/index.htm', + $this->temporary_directory . '/index.htm' + ); + } + } +} diff --git a/phpBB/phpbb/profilefields/lang_helper.php b/phpBB/phpbb/profilefields/lang_helper.php new file mode 100644 index 0000000000..7ad4722230 --- /dev/null +++ b/phpBB/phpbb/profilefields/lang_helper.php @@ -0,0 +1,130 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields; + +/** +* Custom Profile Fields +* @package phpBB3 +*/ +class lang_helper +{ + /** + * Array with the language option, grouped by field and language + * @var array + */ + protected $options_lang = array(); + + /** + * Database object + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * Table where the language strings are stored + * @var string + */ + protected $language_table; + + /** + * Construct + * + * @param \phpbb\db\driver\driver_interface $db Database object + * @param string $language_table Table where the language strings are stored + */ + public function __construct($db, $language_table) + { + $this->db = $db; + $this->language_table = $language_table; + } + + /** + * Get language entries for options and store them here for later use + */ + public function get_option_lang($field_id, $lang_id, $field_type, $preview_options) + { + if ($preview_options !== false) + { + $lang_options = (!is_array($preview_options)) ? explode("\n", $preview_options) : $preview_options; + + foreach ($lang_options as $num => $var) + { + if (!isset($this->options_lang[$field_id])) + { + $this->options_lang[$field_id] = array(); + } + if (!isset($this->options_lang[$field_id][$lang_id])) + { + $this->options_lang[$field_id][$lang_id] = array(); + } + $this->options_lang[$field_id][$lang_id][($num + 1)] = $var; + } + } + else + { + $sql = 'SELECT option_id, lang_value + FROM ' . $this->language_table . ' + WHERE field_id = ' . (int) $field_id . ' + AND lang_id = ' . (int) $lang_id . " + AND field_type = '" . $this->db->sql_escape($field_type) . "' + ORDER BY option_id"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $this->options_lang[$field_id][$lang_id][($row['option_id'] + 1)] = $row['lang_value']; + } + $this->db->sql_freeresult($result); + } + } + + /** + * Are language options set for this field? + * + * @param int $field_id Database ID of the field + * @param int $lang_id ID of the language + * @param int $field_value Selected value of the field + * @return boolean + */ + public function is_set($field_id, $lang_id = null, $field_value = null) + { + $is_set = isset($this->options_lang[$field_id]); + + if ($is_set && (!is_null($lang_id) || !is_null($field_value))) + { + $is_set = isset($this->options_lang[$field_id][$lang_id]); + } + + if ($is_set && !is_null($field_value)) + { + $is_set = isset($this->options_lang[$field_id][$lang_id][$field_value]); + } + + return $is_set; + } + + /** + * Get the selected language string + * + * @param int $field_id Database ID of the field + * @param int $lang_id ID of the language + * @param int $field_value Selected value of the field + * @return string + */ + public function get($field_id, $lang_id, $field_value = null) + { + if (is_null($field_value)) + { + return $this->options_lang[$field_id][$lang_id]; + } + + return $this->options_lang[$field_id][$lang_id][$field_value]; + } +} diff --git a/phpBB/phpbb/profilefields/manager.php b/phpBB/phpbb/profilefields/manager.php new file mode 100644 index 0000000000..37449c67c4 --- /dev/null +++ b/phpBB/phpbb/profilefields/manager.php @@ -0,0 +1,437 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields; + +/** +* Custom Profile Fields +* @package phpBB3 +*/ +class manager +{ + /** + * Auth object + * @var \phpbb\auth\auth + */ + protected $auth; + + /** + * Database object + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * Request object + * @var \phpbb\request\request + */ + protected $request; + + /** + * Template object + * @var \phpbb\template\template + */ + protected $template; + + /** + * Service Collection object + * @var \phpbb\di\service_collection + */ + protected $type_collection; + + /** + * User object + * @var \phpbb\user + */ + protected $user; + + protected $fields_table; + + protected $fields_language_table; + + protected $fields_data_table; + + protected $profile_cache = array(); + + /** + * Construct + * + * @param \phpbb\auth\auth $auth Auth object + * @param \phpbb\db\driver\driver_interface $db Database object + * @param \phpbb\request\request $request Request object + * @param \phpbb\template\template $template Template object + * @param \phpbb\di\service_collection $type_collection + * @param \phpbb\user $user User object + * @param string $fields_table + * @param string $fields_language_table + * @param string $fields_data_table + */ + public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\di\service_collection $type_collection, \phpbb\user $user, $fields_table, $fields_language_table, $fields_data_table) + { + $this->auth = $auth; + $this->db = $db; + $this->request = $request; + $this->template = $template; + $this->type_collection = $type_collection; + $this->user = $user; + + $this->fields_table = $fields_table; + $this->fields_language_table = $fields_language_table; + $this->fields_data_table = $fields_data_table; + } + + /** + * Assign editable fields to template, mode can be profile (for profile change) or register (for registration) + * Called by ucp_profile and ucp_register + */ + public function generate_profile_fields($mode, $lang_id) + { + $sql_where = ''; + switch ($mode) + { + case 'register': + // If the field is required we show it on the registration page + $sql_where .= ' AND f.field_show_on_reg = 1'; + break; + + case 'profile': + // Show hidden fields to moderators/admins + if (!$this->auth->acl_gets('a_', 'm_') && !$this->auth->acl_getf_global('m_')) + { + $sql_where .= ' AND f.field_show_profile = 1'; + } + break; + + default: + trigger_error('Wrong profile mode specified', E_USER_ERROR); + break; + } + + $sql = 'SELECT l.*, f.* + FROM ' . $this->fields_language_table . ' l, ' . $this->fields_table . " f + WHERE f.field_active = 1 + $sql_where + AND l.lang_id = " . (int) $lang_id . ' + AND l.field_id = f.field_id + ORDER BY f.field_order'; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + // Return templated field + $profile_field = $this->type_collection[$row['field_type']]; + $tpl_snippet = $profile_field->process_field_row('change', $row); + + $this->template->assign_block_vars('profile_fields', array( + 'LANG_NAME' => $this->user->lang($row['lang_name']), + 'LANG_EXPLAIN' => $this->user->lang($row['lang_explain']), + 'FIELD' => $tpl_snippet, + 'FIELD_ID' => $profile_field->get_field_ident($row), + 'S_REQUIRED' => ($row['field_required']) ? true : false, + )); + } + $this->db->sql_freeresult($result); + } + + /** + * Build profile cache, used for display + */ + protected function build_cache() + { + $this->profile_cache = array(); + + // Display hidden/no_view fields for admin/moderator + $sql = 'SELECT l.*, f.* + FROM ' . $this->fields_language_table . ' l, ' . $this->fields_table . ' f + WHERE l.lang_id = ' . $this->user->get_iso_lang_id() . ' + AND f.field_active = 1 ' . + ((!$this->auth->acl_gets('a_', 'm_') && !$this->auth->acl_getf_global('m_')) ? ' AND f.field_hide = 0 ' : '') . ' + AND f.field_no_view = 0 + AND l.field_id = f.field_id + ORDER BY f.field_order'; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $this->profile_cache[$row['field_ident']] = $row; + } + $this->db->sql_freeresult($result); + } + + /** + * Submit profile field for validation + */ + public function submit_cp_field($mode, $lang_id, &$cp_data, &$cp_error) + { + $sql_where = ''; + switch ($mode) + { + case 'register': + // If the field is required we show it on the registration page + $sql_where .= ' AND f.field_show_on_reg = 1'; + break; + + case 'profile': + // Show hidden fields to moderators/admins + if (!$this->auth->acl_gets('a_', 'm_') && !$this->auth->acl_getf_global('m_')) + { + $sql_where .= ' AND f.field_show_profile = 1'; + } + break; + + default: + trigger_error('Wrong profile mode specified', E_USER_ERROR); + break; + } + + $sql = 'SELECT l.*, f.* + FROM ' . $this->fields_language_table . ' l, ' . $this->fields_table . ' f + WHERE l.lang_id = ' . (int) $lang_id . " + AND f.field_active = 1 + $sql_where + AND l.field_id = f.field_id + ORDER BY f.field_order"; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $profile_field = $this->type_collection[$row['field_type']]; + $cp_data['pf_' . $row['field_ident']] = $profile_field->get_profile_field($row); + $check_value = $cp_data['pf_' . $row['field_ident']]; + + if (($cp_result = $profile_field->validate_profile_field($check_value, $row)) !== false) + { + // If the result is not false, it's an error message + $cp_error[] = $cp_result; + } + } + $this->db->sql_freeresult($result); + } + + /** + * Update profile field data directly + */ + public function update_profile_field_data($user_id, $cp_data) + { + if (!sizeof($cp_data)) + { + return; + } + + $sql = 'UPDATE ' . $this->fields_data_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $cp_data) . ' + WHERE user_id = ' . (int) $user_id; + $this->db->sql_query($sql); + + if (!$this->db->sql_affectedrows()) + { + $cp_data = $this->build_insert_sql_array($cp_data); + $cp_data['user_id'] = (int) $user_id; + + $this->db->sql_return_on_error(true); + + $sql = 'INSERT INTO ' . $this->fields_data_table . ' ' . $this->db->sql_build_array('INSERT', $cp_data); + $this->db->sql_query($sql); + + $this->db->sql_return_on_error(false); + } + } + + /** + * Generate the template arrays in order to display the column names + * + * @param string $restrict_option Restrict the published fields to a certain profile field option + * @return array Returns an array with the template variables type, name and explain for the fields to display + */ + public function generate_profile_fields_template_headlines($restrict_option = '') + { + if (!sizeof($this->profile_cache)) + { + $this->build_cache(); + } + + $tpl_fields = array(); + + // Go through the fields in correct order + foreach ($this->profile_cache as $field_ident => $field_data) + { + if ($restrict_option && !$field_data[$restrict_option]) + { + continue; + } + + $profile_field = $this->type_collection[$field_data['field_type']]; + + $tpl_fields[] = array( + 'PROFILE_FIELD_TYPE' => $field_data['field_type'], + 'PROFILE_FIELD_NAME' => $profile_field->get_field_name($field_data['lang_name']), + 'PROFILE_FIELD_EXPLAIN' => $this->user->lang($field_data['lang_explain']), + ); + } + + return $tpl_fields; + } + + /** + * Grab the user specific profile fields data + * + * @param int|array $user_ids Single user id or an array of ids + * @return array Users profile fields data + */ + public function grab_profile_fields_data($user_ids = 0) + { + if (!is_array($user_ids)) + { + $user_ids = array($user_ids); + } + + if (!sizeof($this->profile_cache)) + { + $this->build_cache(); + } + + if (!sizeof($user_ids)) + { + return array(); + } + + $sql = 'SELECT * + FROM ' . $this->fields_data_table . ' + WHERE ' . $this->db->sql_in_set('user_id', array_map('intval', $user_ids)); + $result = $this->db->sql_query($sql); + + $field_data = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $field_data[$row['user_id']] = $row; + } + $this->db->sql_freeresult($result); + + $user_fields = array(); + + // Go through the fields in correct order + foreach (array_keys($this->profile_cache) as $used_ident) + { + foreach ($field_data as $user_id => $row) + { + $user_fields[$user_id][$used_ident]['value'] = $row['pf_' . $used_ident]; + $user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident]; + } + + foreach ($user_ids as $user_id) + { + if (!isset($user_fields[$user_id][$used_ident]) && $this->profile_cache[$used_ident]['field_show_novalue']) + { + $user_fields[$user_id][$used_ident]['value'] = ''; + $user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident]; + } + } + } + + return $user_fields; + } + + /** + * Assign the user's profile fields data to the template + * + * @param array $profile_row Array with users profile field data + * @param bool $use_contact_fields Should we display contact fields as such? + * This requires special treatments (links should not be parsed in the values, and more) + * @return array + */ + public function generate_profile_fields_template_data($profile_row, $use_contact_fields = true) + { + // $profile_row == $user_fields[$row['user_id']]; + $tpl_fields = array(); + $tpl_fields['row'] = $tpl_fields['blockrow'] = array(); + + foreach ($profile_row as $ident => $ident_ary) + { + $profile_field = $this->type_collection[$ident_ary['data']['field_type']]; + $value = $profile_field->get_profile_value($ident_ary['value'], $ident_ary['data']); + + if ($value === null) + { + continue; + } + + $field_desc = $contact_url = ''; + if ($use_contact_fields) + { + $value = $profile_field->get_profile_contact_value($ident_ary['value'], $ident_ary['data']); + $field_desc = $this->user->lang($ident_ary['data']['field_contact_desc']); + if (strpos($field_desc, '%s') !== false) + { + $field_desc = sprintf($field_desc, $value); + } + $contact_url = ''; + if (strpos($ident_ary['data']['field_contact_url'], '%s') !== false) + { + $contact_url = sprintf($ident_ary['data']['field_contact_url'], $value); + } + } + + $tpl_fields['row'] += array( + 'PROFILE_' . strtoupper($ident) . '_IDENT' => $ident, + 'PROFILE_' . strtoupper($ident) . '_VALUE' => $value, + 'PROFILE_' . strtoupper($ident) . '_CONTACT'=> $contact_url, + 'PROFILE_' . strtoupper($ident) . '_DESC' => $field_desc, + 'PROFILE_' . strtoupper($ident) . '_TYPE' => $ident_ary['data']['field_type'], + 'PROFILE_' . strtoupper($ident) . '_NAME' => $this->user->lang($ident_ary['data']['lang_name']), + 'PROFILE_' . strtoupper($ident) . '_EXPLAIN'=> $this->user->lang($ident_ary['data']['lang_explain']), + + 'S_PROFILE_' . strtoupper($ident) . '_CONTACT' => $ident_ary['data']['field_is_contact'], + 'S_PROFILE_' . strtoupper($ident) => true, + ); + + $tpl_fields['blockrow'][] = array( + 'PROFILE_FIELD_IDENT' => $ident, + 'PROFILE_FIELD_VALUE' => $value, + 'PROFILE_FIELD_CONTACT' => $contact_url, + 'PROFILE_FIELD_DESC' => $field_desc, + 'PROFILE_FIELD_TYPE' => $ident_ary['data']['field_type'], + 'PROFILE_FIELD_NAME' => $this->user->lang($ident_ary['data']['lang_name']), + 'PROFILE_FIELD_EXPLAIN' => $this->user->lang($ident_ary['data']['lang_explain']), + + 'S_PROFILE_CONTACT' => $ident_ary['data']['field_is_contact'], + 'S_PROFILE_' . strtoupper($ident) => true, + ); + } + + return $tpl_fields; + } + + /** + * Build Array for user insertion into custom profile fields table + */ + public function build_insert_sql_array($cp_data) + { + $sql_not_in = array(); + foreach ($cp_data as $key => $null) + { + $sql_not_in[] = (strncmp($key, 'pf_', 3) === 0) ? substr($key, 3) : $key; + } + + $sql = 'SELECT f.field_type, f.field_ident, f.field_default_value, l.lang_default_value + FROM ' . $this->fields_language_table . ' l, ' . $this->fields_table . ' f + WHERE l.lang_id = ' . $this->user->get_iso_lang_id() . ' + ' . ((sizeof($sql_not_in)) ? ' AND ' . $this->db->sql_in_set('f.field_ident', $sql_not_in, true) : '') . ' + AND l.field_id = f.field_id'; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $profile_field = $this->type_collection[$row['field_type']]; + $cp_data['pf_' . $row['field_ident']] = $profile_field->get_default_field_value($row); + } + $this->db->sql_freeresult($result); + + return $cp_data; + } +} diff --git a/phpBB/phpbb/profilefields/type/type_base.php b/phpBB/phpbb/profilefields/type/type_base.php new file mode 100644 index 0000000000..a96196674d --- /dev/null +++ b/phpBB/phpbb/profilefields/type/type_base.php @@ -0,0 +1,191 @@ +<?php +/** +* +* @package phpBB +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields\type; + +abstract class type_base implements type_interface +{ + /** + * Request object + * @var \phpbb\request\request + */ + protected $request; + + /** + * Template object + * @var \phpbb\template\template + */ + protected $template; + + /** + * User object + * @var \phpbb\user + */ + protected $user; + + /** + * Construct + * + * @param \phpbb\request\request $request Request object + * @param \phpbb\template\template $template Template object + * @param \phpbb\user $user User object + * @param string $language_table Table where the language strings are stored + */ + public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) + { + $this->request = $request; + $this->template = $template; + $this->user = $user; + } + + /** + * {@inheritDoc} + */ + public function get_name() + { + return $this->user->lang('FIELD_' . strtoupper($this->get_name_short())); + } + + /** + * {@inheritDoc} + */ + public function get_service_name() + { + return 'profilefields.type.' . $this->get_name_short(); + } + + /** + * {@inheritDoc} + */ + public function get_template_filename() + { + return 'profilefields/' . $this->get_name_short() . '.html'; + } + + /** + * {@inheritDoc} + */ + public function get_field_ident($field_data) + { + return 'pf_' . $field_data['field_ident']; + } + + /** + * {@inheritDoc} + */ + public function get_field_name($field_name) + { + return isset($this->user->lang[$field_name]) ? $this->user->lang[$field_name] : $field_name; + } + + /** + * {@inheritDoc} + */ + public function get_profile_contact_value($field_value, $field_data) + { + return $this->get_profile_value($field_value, $field_data); + } + + /** + * {@inheritDoc} + */ + public function get_language_options_input($field_data) + { + $field_data['l_lang_name'] = $this->request->variable('l_lang_name', array(0 => ''), true); + $field_data['l_lang_explain'] = $this->request->variable('l_lang_explain', array(0 => ''), true); + $field_data['l_lang_default_value'] = $this->request->variable('l_lang_default_value', array(0 => ''), true); + $field_data['l_lang_options'] = $this->request->variable('l_lang_options', array(0 => ''), true); + + return $field_data; + } + + /** + * {@inheritDoc} + */ + public function prepare_options_form(&$exclude_options, &$visibility_options) + { + return $this->request->variable('lang_options', '', true); + } + + /** + * {@inheritDoc} + */ + public function validate_options_on_submit($error, $field_data) + { + return $error; + } + + /** + * {@inheritDoc} + */ + public function get_excluded_options($key, $action, $current_value, &$field_data, $step) + { + if ($step == 3 && ($field_data[$key] || $action != 'edit') && $key == 'l_lang_options' && is_array($field_data[$key])) + { + foreach ($field_data[$key] as $lang_id => $options) + { + $field_data[$key][$lang_id] = explode("\n", $options); + } + + return $current_value; + } + + return $current_value; + } + + /** + * {@inheritDoc} + */ + public function prepare_hidden_fields($step, $key, $action, &$field_data) + { + if (!$this->request->is_set($key)) + { + // Do not set this variable, we will use the default value + return null; + } + else if ($key == 'field_ident' && isset($field_data[$key])) + { + return $field_data[$key]; + } + else + { + return $this->request->variable($key, '', true); + } + } + + /** + * {@inheritDoc} + */ + public function display_options(&$template_vars, &$field_data) + { + return; + } + + /** + * Return templated value/field. Possible values for $mode are: + * change == user is able to set/enter profile values; preview == just show the value + */ + public function process_field_row($mode, $profile_row) + { + $preview_options = ($mode == 'preview') ? $profile_row['lang_options'] : false; + + // set template filename + $this->template->set_filenames(array( + 'cp_body' => $this->get_template_filename(), + )); + + // empty previously filled blockvars + $this->template->destroy_block_vars($this->get_name_short()); + + // Assign template variables + $this->generate_field($profile_row, $preview_options); + + return $this->template->assign_display('cp_body'); + } +} diff --git a/phpBB/phpbb/profilefields/type/type_bool.php b/phpBB/phpbb/profilefields/type/type_bool.php new file mode 100644 index 0000000000..fa9c0a8714 --- /dev/null +++ b/phpBB/phpbb/profilefields/type/type_bool.php @@ -0,0 +1,387 @@ +<?php +/** +* +* @package phpBB +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields\type; + +class type_bool extends type_base +{ + /** + * Profile fields language helper + * @var \phpbb\profilefields\lang_helper + */ + protected $lang_helper; + + /** + * Request object + * @var \phpbb\request\request + */ + protected $request; + + /** + * Template object + * @var \phpbb\template\template + */ + protected $template; + + /** + * User object + * @var \phpbb\user + */ + protected $user; + + /** + * Construct + * + * @param \phpbb\profilefields\lang_helper $lang_helper Profile fields language helper + * @param \phpbb\request\request $request Request object + * @param \phpbb\template\template $template Template object + * @param \phpbb\user $user User object + * @param string $language_table Table where the language strings are stored + */ + public function __construct(\phpbb\profilefields\lang_helper $lang_helper, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) + { + $this->lang_helper = $lang_helper; + $this->request = $request; + $this->template = $template; + $this->user = $user; + } + + /** + * {@inheritDoc} + */ + public function get_name_short() + { + return 'bool'; + } + + /** + * {@inheritDoc} + */ + public function get_options($default_lang_id, $field_data) + { + $profile_row = array( + 'var_name' => 'field_default_value', + 'field_id' => 1, + 'lang_name' => $field_data['lang_name'], + 'lang_explain' => $field_data['lang_explain'], + 'lang_id' => $default_lang_id, + 'field_default_value' => $field_data['field_default_value'], + 'field_ident' => 'field_default_value', + 'field_type' => $this->get_service_name(), + 'field_length' => $field_data['field_length'], + 'lang_options' => $field_data['lang_options'], + ); + + $options = array( + 0 => array('TITLE' => $this->user->lang['FIELD_TYPE'], 'EXPLAIN' => $this->user->lang['BOOL_TYPE_EXPLAIN'], 'FIELD' => '<label><input type="radio" class="radio" name="field_length" value="1"' . (($field_data['field_length'] == 1) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $this->user->lang['RADIO_BUTTONS'] . '</label><label><input type="radio" class="radio" name="field_length" value="2"' . (($field_data['field_length'] == 2) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $this->user->lang['CHECKBOX'] . '</label>'), + 1 => array('TITLE' => $this->user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row)), + ); + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_default_option_values() + { + return array( + 'field_length' => 1, + 'field_minlen' => 0, + 'field_maxlen' => 0, + 'field_validation' => '', + 'field_novalue' => 0, + 'field_default_value' => 0, + ); + } + + /** + * {@inheritDoc} + */ + public function get_default_field_value($field_data) + { + return $field_data['field_default_value']; + } + + /** + * {@inheritDoc} + */ + public function get_profile_field($profile_row) + { + $var_name = 'pf_' . $profile_row['field_ident']; + + // Checkbox + if ($profile_row['field_length'] == 2) + { + return ($this->request->is_set($var_name)) ? 1 : 0; + } + else + { + return $this->request->variable($var_name, (int) $profile_row['field_default_value']); + } + } + + /** + * {@inheritDoc} + */ + public function validate_profile_field(&$field_value, $field_data) + { + $field_value = (bool) $field_value; + + if (!$field_value && $field_data['field_required']) + { + return $this->user->lang('FIELD_REQUIRED', $this->get_field_name($field_data['lang_name'])); + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function get_profile_value($field_value, $field_data) + { + $field_id = $field_data['field_id']; + $lang_id = $field_data['lang_id']; + + if (!$this->lang_helper->is_set($field_id, $lang_id)) + { + $this->lang_helper->get_option_lang($field_id, $lang_id, FIELD_BOOL, false); + } + + if (!$field_value && $field_data['field_show_novalue']) + { + $field_value = $field_data['field_default_value']; + } + + if ($field_data['field_length'] == 1) + { + return ($this->lang_helper->is_set($field_id, $lang_id, (int) $field_value)) ? $this->lang_helper->get($field_id, $lang_id, (int) $field_value) : null; + } + else if (!$field_value) + { + return null; + } + else + { + return $this->lang_helper->is_set($field_id, $lang_id, $field_value + 1); + } + } + + /** + * {@inheritDoc} + */ + public function generate_field($profile_row, $preview_options = false) + { + $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; + $field_ident = $profile_row['field_ident']; + $default_value = $profile_row['field_default_value']; + + // checkbox - set the value to "true" if it has been set to 1 + if ($profile_row['field_length'] == 2) + { + $value = ($this->request->is_set($field_ident) && $this->request->variable($field_ident, $default_value) == 1) ? true : ((!isset($this->user->profile_fields[$field_ident]) || $preview_options !== false) ? $default_value : $this->user->profile_fields[$field_ident]); + } + else + { + $value = ($this->request->is_set($field_ident)) ? $this->request->variable($field_ident, $default_value) : ((!isset($this->user->profile_fields[$field_ident]) || $preview_options !== false) ? $default_value : $this->user->profile_fields[$field_ident]); + } + + $profile_row['field_value'] = (int) $value; + $this->template->assign_block_vars('bool', array_change_key_case($profile_row, CASE_UPPER)); + + if ($profile_row['field_length'] == 1) + { + if (!$this->lang_helper->is_set($profile_row['field_id'], $profile_row['lang_id'], 1)) + { + $this->lang_helper->get_option_lang($profile_row['field_id'], $profile_row['lang_id'], $this->get_service_name(), $preview_options); + } + + $options = $this->lang_helper->get($profile_row['field_id'], $profile_row['lang_id']); + foreach ($options as $option_id => $option_value) + { + $this->template->assign_block_vars('bool.options', array( + 'OPTION_ID' => $option_id, + 'CHECKED' => ($value == $option_id) ? ' checked="checked"' : '', + 'VALUE' => $option_value, + )); + } + } + } + + /** + * {@inheritDoc} + */ + public function get_field_ident($field_data) + { + return ($field_data['field_length'] == '1') ? '' : 'pf_' . $field_data['field_ident']; + } + + /** + * {@inheritDoc} + */ + public function get_database_column_type() + { + return 'TINT:2'; + } + + /** + * {@inheritDoc} + */ + public function get_language_options($field_data) + { + $options = array( + 'lang_name' => 'string', + 'lang_options' => 'two_options', + ); + + if ($field_data['lang_explain']) + { + $options['lang_explain'] = 'text'; + } + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_language_options_input($field_data) + { + $field_data['l_lang_name'] = $this->request->variable('l_lang_name', array(0 => ''), true); + $field_data['l_lang_explain'] = $this->request->variable('l_lang_explain', array(0 => ''), true); + $field_data['l_lang_default_value'] = $this->request->variable('l_lang_default_value', array(0 => ''), true); + + /** + * @todo check if this line is correct... + $field_data['l_lang_default_value'] = $this->request->variable('l_lang_default_value', array(0 => array('')), true); + */ + $field_data['l_lang_options'] = $this->request->variable('l_lang_options', array(0 => array('')), true); + + return $field_data; + } + + /** + * {@inheritDoc} + */ + public function prepare_options_form(&$exclude_options, &$visibility_options) + { + $exclude_options[1][] = 'lang_options'; + + return $this->request->variable('lang_options', array(''), true); + } + + /** + * {@inheritDoc} + */ + public function validate_options_on_submit($error, $field_data) + { + if (empty($field_data['lang_options'][0]) || empty($field_data['lang_options'][1])) + { + $error[] = $this->user->lang['NO_FIELD_ENTRIES']; + } + + return $error; + } + + /** + * {@inheritDoc} + */ + public function get_excluded_options($key, $action, $current_value, &$field_data, $step) + { + if ($step == 2 && $key == 'field_default_value') + { + // 'field_length' == 1 defines radio buttons. Possible values are 1 or 2 only. + // 'field_length' == 2 defines checkbox. Possible values are 0 or 1 only. + // If we switch the type on step 2, we have to adjust field value. + // 1 is a common value for the checkbox and radio buttons. + + // Adjust unchecked checkbox value. + // If we return or save settings from 2nd/3rd page + // and the checkbox is unchecked, set the value to 0. + if ($this->request->is_set('step') && !$this->request->is_set($key)) + { + return 0; + } + + // If we switch to the checkbox type but former radio buttons value was 2, + // which is not the case for the checkbox, set it to 0 (unchecked). + if ($field_data['field_length'] == 2 && $current_value == 2) + { + return 0; + } + // If we switch to the radio buttons but the former checkbox value was 0, + // which is not the case for the radio buttons, set it to 0. + else if ($field_data['field_length'] == 1 && $current_value == 0) + { + return 2; + } + } + + if ($step == 3 && ($field_data[$key] || $action != 'edit') && $key == 'l_lang_options') + { + $field_data[$key] = $this->request->variable($key, array(0 => array('')), true); + + return $current_value; + } + + return parent::get_excluded_options($key, $action, $current_value, $field_data, $step); + } + + /** + * {@inheritDoc} + */ + public function prepare_hidden_fields($step, $key, $action, &$field_data) + { + if ($key == 'l_lang_options' && $this->request->is_set('l_lang_options')) + { + return $this->request->variable($key, array(array('')), true); + } + else if ($key == 'field_default_value') + { + return $this->request->variable($key, $field_data[$key]); + } + else + { + if (!$this->request->is_set($key)) + { + return false; + } + else if ($key == 'field_ident' && isset($field_data[$key])) + { + return $field_data[$key]; + } + else + { + return ($key == 'lang_options') ? $this->request->variable($key, array(''), true) : $this->request->variable($key, '', true); + } + } + } + + /** + * {@inheritDoc} + */ + public function display_options(&$template_vars, &$field_data) + { + // Initialize these array elements if we are creating a new field + if (!sizeof($field_data['lang_options'])) + { + // No options have been defined for a boolean field. + $field_data['lang_options'][0] = ''; + $field_data['lang_options'][1] = ''; + } + + $template_vars = array_merge($template_vars, array( + 'S_BOOL' => true, + 'L_LANG_OPTIONS_EXPLAIN' => $this->user->lang['BOOL_ENTRIES_EXPLAIN'], + 'FIRST_LANG_OPTION' => $field_data['lang_options'][0], + 'SECOND_LANG_OPTION' => $field_data['lang_options'][1], + )); + } +} diff --git a/phpBB/phpbb/profilefields/type/type_date.php b/phpBB/phpbb/profilefields/type/type_date.php new file mode 100644 index 0000000000..af3d65c9b6 --- /dev/null +++ b/phpBB/phpbb/profilefields/type/type_date.php @@ -0,0 +1,358 @@ +<?php +/** +* +* @package phpBB +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields\type; + +class type_date extends type_base +{ + /** + * Request object + * @var \phpbb\request\request + */ + protected $request; + + /** + * Template object + * @var \phpbb\template\template + */ + protected $template; + + /** + * User object + * @var \phpbb\user + */ + protected $user; + + /** + * Construct + * + * @param \phpbb\request\request $request Request object + * @param \phpbb\template\template $template Template object + * @param \phpbb\user $user User object + * @param string $language_table Table where the language strings are stored + */ + public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) + { + $this->request = $request; + $this->template = $template; + $this->user = $user; + } + + /** + * {@inheritDoc} + */ + public function get_name_short() + { + return 'date'; + } + + /** + * {@inheritDoc} + */ + public function get_options($default_lang_id, $field_data) + { + $profile_row = array( + 'var_name' => 'field_default_value', + 'lang_name' => $field_data['lang_name'], + 'lang_explain' => $field_data['lang_explain'], + 'lang_id' => $default_lang_id, + 'field_default_value' => $field_data['field_default_value'], + 'field_ident' => 'field_default_value', + 'field_type' => $this->get_service_name(), + 'field_length' => $field_data['field_length'], + 'lang_options' => $field_data['lang_options'], + ); + + $always_now = request_var('always_now', -1); + if ($always_now == -1) + { + $s_checked = ($field_data['field_default_value'] == 'now') ? true : false; + } + else + { + $s_checked = ($always_now) ? true : false; + } + + $options = array( + 0 => array('TITLE' => $this->user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row)), + 1 => array('TITLE' => $this->user->lang['ALWAYS_TODAY'], 'FIELD' => '<label><input type="radio" class="radio" name="always_now" value="1"' . (($s_checked) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $this->user->lang['YES'] . '</label><label><input type="radio" class="radio" name="always_now" value="0"' . ((!$s_checked) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $this->user->lang['NO'] . '</label>'), + ); + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_default_option_values() + { + return array( + 'field_length' => 10, + 'field_minlen' => 10, + 'field_maxlen' => 10, + 'field_validation' => '', + 'field_novalue' => ' 0- 0- 0', + 'field_default_value' => ' 0- 0- 0', + ); + } + + /** + * {@inheritDoc} + */ + public function get_default_field_value($field_data) + { + if ($field_data['field_default_value'] == 'now') + { + $now = getdate(); + $field_data['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); + } + + return $field_data['field_default_value']; + } + + /** + * {@inheritDoc} + */ + public function get_profile_field($profile_row) + { + $var_name = 'pf_' . $profile_row['field_ident']; + + if (!$this->request->is_set($var_name . '_day')) + { + if ($profile_row['field_default_value'] == 'now') + { + $now = getdate(); + $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); + } + list($day, $month, $year) = explode('-', $profile_row['field_default_value']); + } + else + { + $day = $this->request->variable($var_name . '_day', 0); + $month = $this->request->variable($var_name . '_month', 0); + $year = $this->request->variable($var_name . '_year', 0); + } + + return sprintf('%2d-%2d-%4d', $day, $month, $year); + } + + /** + * {@inheritDoc} + */ + public function validate_profile_field(&$field_value, $field_data) + { + $field_validate = explode('-', $field_value); + + $day = (isset($field_validate[0])) ? (int) $field_validate[0] : 0; + $month = (isset($field_validate[1])) ? (int) $field_validate[1] : 0; + $year = (isset($field_validate[2])) ? (int) $field_validate[2] : 0; + + if ((!$day || !$month || !$year) && !$field_data['field_required']) + { + return false; + } + + if ((!$day || !$month || !$year) && $field_data['field_required']) + { + return $this->user->lang('FIELD_REQUIRED', $this->get_field_name($field_data['lang_name'])); + } + + if ($day < 0 || $day > 31 || $month < 0 || $month > 12 || ($year < 1901 && $year > 0) || $year > gmdate('Y', time()) + 50) + { + return $this->user->lang('FIELD_INVALID_DATE', $this->get_field_name($field_data['lang_name'])); + } + + if (checkdate($month, $day, $year) === false) + { + return $this->user->lang('FIELD_INVALID_DATE', $this->get_field_name($field_data['lang_name'])); + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function get_profile_value($field_value, $field_data) + { + $date = explode('-', $field_value); + $day = (isset($date[0])) ? (int) $date[0] : 0; + $month = (isset($date[1])) ? (int) $date[1] : 0; + $year = (isset($date[2])) ? (int) $date[2] : 0; + + if (!$day && !$month && !$year && !$field_data['field_show_novalue']) + { + return null; + } + else if ($day && $month && $year) + { + // Date should display as the same date for every user regardless of timezone + return $this->user->create_datetime() + ->setDate($year, $month, $day) + ->setTime(0, 0, 0) + ->format($this->user->lang['DATE_FORMAT'], true); + } + + return $field_value; + } + + /** + * {@inheritDoc} + */ + public function generate_field($profile_row, $preview_options = false) + { + $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; + $field_ident = $profile_row['field_ident']; + + $now = getdate(); + + if (!$this->request->is_set($profile_row['field_ident'] . '_day')) + { + if ($profile_row['field_default_value'] == 'now') + { + $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); + } + list($day, $month, $year) = explode('-', ((!isset($this->user->profile_fields[$field_ident]) || $preview_options !== false) ? $profile_row['field_default_value'] : $this->user->profile_fields[$field_ident])); + } + else + { + if ($preview_options !== false && $profile_row['field_default_value'] == 'now') + { + $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); + list($day, $month, $year) = explode('-', ((!isset($this->user->profile_fields[$field_ident]) || $preview_options !== false) ? $profile_row['field_default_value'] : $this->user->profile_fields[$field_ident])); + } + else + { + $day = $this->request->variable($profile_row['field_ident'] . '_day', 0); + $month = $this->request->variable($profile_row['field_ident'] . '_month', 0); + $year = $this->request->variable($profile_row['field_ident'] . '_year', 0); + } + } + + $profile_row['s_day_options'] = '<option value="0"' . ((!$day) ? ' selected="selected"' : '') . '>--</option>'; + for ($i = 1; $i < 32; $i++) + { + $profile_row['s_day_options'] .= '<option value="' . $i . '"' . (($i == $day) ? ' selected="selected"' : '') . ">$i</option>"; + } + + $profile_row['s_month_options'] = '<option value="0"' . ((!$month) ? ' selected="selected"' : '') . '>--</option>'; + for ($i = 1; $i < 13; $i++) + { + $profile_row['s_month_options'] .= '<option value="' . $i . '"' . (($i == $month) ? ' selected="selected"' : '') . ">$i</option>"; + } + + $profile_row['s_year_options'] = '<option value="0"' . ((!$year) ? ' selected="selected"' : '') . '>--</option>'; + for ($i = $now['year'] - 100; $i <= $now['year'] + 100; $i++) + { + $profile_row['s_year_options'] .= '<option value="' . $i . '"' . (($i == $year) ? ' selected="selected"' : '') . ">$i</option>"; + } + + $profile_row['field_value'] = 0; + $this->template->assign_block_vars('date', array_change_key_case($profile_row, CASE_UPPER)); + } + + /** + * {@inheritDoc} + */ + public function get_field_ident($field_data) + { + return ''; + } + + /** + * {@inheritDoc} + */ + public function get_database_column_type() + { + return 'VCHAR:10'; + } + + /** + * {@inheritDoc} + */ + public function get_language_options($field_data) + { + $options = array( + 'lang_name' => 'string', + ); + + if ($field_data['lang_explain']) + { + $options['lang_explain'] = 'text'; + } + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_excluded_options($key, $action, $current_value, &$field_data, $step) + { + if ($step == 2 && $key == 'field_default_value') + { + $always_now = $this->request->variable('always_now', -1); + + if ($always_now == 1 || ($always_now === -1 && $current_value == 'now')) + { + $now = getdate(); + + $field_data['field_default_value_day'] = $now['mday']; + $field_data['field_default_value_month'] = $now['mon']; + $field_data['field_default_value_year'] = $now['year']; + $current_value = 'now'; + $this->request->overwrite('field_default_value', $current_value, \phpbb\request\request_interface::POST); + } + else + { + if ($this->request->is_set('field_default_value_day')) + { + $field_data['field_default_value_day'] = $this->request->variable('field_default_value_day', 0); + $field_data['field_default_value_month'] = $this->request->variable('field_default_value_month', 0); + $field_data['field_default_value_year'] = $this->request->variable('field_default_value_year', 0); + $current_value = sprintf('%2d-%2d-%4d', $field_data['field_default_value_day'], $field_data['field_default_value_month'], $field_data['field_default_value_year']); + $this->request->overwrite('field_default_value', $current_value, \phpbb\request\request_interface::POST); + } + else + { + list($field_data['field_default_value_day'], $field_data['field_default_value_month'], $field_data['field_default_value_year']) = explode('-', $current_value); + } + } + + return $current_value; + } + + return parent::get_excluded_options($key, $action, $current_value, $field_data, $step); + } + + /** + * {@inheritDoc} + */ + public function prepare_hidden_fields($step, $key, $action, &$field_data) + { + if ($key == 'field_default_value') + { + $always_now = $this->request->variable('always_now', 0); + + if ($always_now) + { + return 'now'; + } + else if ($this->request->is_set('field_default_value_day')) + { + $field_data['field_default_value_day'] = $this->request->variable('field_default_value_day', 0); + $field_data['field_default_value_month'] = $this->request->variable('field_default_value_month', 0); + $field_data['field_default_value_year'] = $this->request->variable('field_default_value_year', 0); + return sprintf('%2d-%2d-%4d', $field_data['field_default_value_day'], $field_data['field_default_value_month'], $field_data['field_default_value_year']); + } + } + + return parent::prepare_hidden_fields($step, $key, $action, $field_data); + } +} diff --git a/phpBB/phpbb/profilefields/type/type_dropdown.php b/phpBB/phpbb/profilefields/type/type_dropdown.php new file mode 100644 index 0000000000..bcf0ba05f9 --- /dev/null +++ b/phpBB/phpbb/profilefields/type/type_dropdown.php @@ -0,0 +1,297 @@ +<?php +/** +* +* @package phpBB +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields\type; + +class type_dropdown extends type_base +{ + /** + * Profile fields language helper + * @var \phpbb\profilefields\lang_helper + */ + protected $lang_helper; + + /** + * Request object + * @var \phpbb\request\request + */ + protected $request; + + /** + * Template object + * @var \phpbb\template\template + */ + protected $template; + + /** + * User object + * @var \phpbb\user + */ + protected $user; + + /** + * Construct + * + * @param \phpbb\profilefields\lang_helper $lang_helper Profile fields language helper + * @param \phpbb\request\request $request Request object + * @param \phpbb\template\template $template Template object + * @param \phpbb\user $user User object + * @param string $language_table Table where the language strings are stored + */ + public function __construct(\phpbb\profilefields\lang_helper $lang_helper, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) + { + $this->lang_helper = $lang_helper; + $this->request = $request; + $this->template = $template; + $this->user = $user; + } + + /** + * {@inheritDoc} + */ + public function get_name_short() + { + return 'dropdown'; + } + + /** + * {@inheritDoc} + */ + public function get_options($default_lang_id, $field_data) + { + $profile_row[0] = array( + 'var_name' => 'field_default_value', + 'field_id' => 1, + 'lang_name' => $field_data['lang_name'], + 'lang_explain' => $field_data['lang_explain'], + 'lang_id' => $default_lang_id, + 'field_default_value' => $field_data['field_default_value'], + 'field_ident' => 'field_default_value', + 'field_type' => $this->get_service_name(), + 'lang_options' => $field_data['lang_options'], + ); + + $profile_row[1] = $profile_row[0]; + $profile_row[1]['var_name'] = 'field_novalue'; + $profile_row[1]['field_ident'] = 'field_novalue'; + $profile_row[1]['field_default_value'] = $field_data['field_novalue']; + + $options = array( + 0 => array('TITLE' => $this->user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row[0])), + 1 => array('TITLE' => $this->user->lang['NO_VALUE_OPTION'], 'EXPLAIN' => $this->user->lang['NO_VALUE_OPTION_EXPLAIN'], 'FIELD' => $this->process_field_row('preview', $profile_row[1])), + ); + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_default_option_values() + { + return array( + 'field_length' => 0, + 'field_minlen' => 0, + 'field_maxlen' => 5, + 'field_validation' => '', + 'field_novalue' => 0, + 'field_default_value' => 0, + ); + } + + /** + * {@inheritDoc} + */ + public function get_default_field_value($field_data) + { + return $field_data['field_default_value']; + } + + /** + * {@inheritDoc} + */ + public function get_profile_field($profile_row) + { + $var_name = 'pf_' . $profile_row['field_ident']; + return $this->request->variable($var_name, (int) $profile_row['field_default_value']); + } + + /** + * {@inheritDoc} + */ + public function validate_profile_field(&$field_value, $field_data) + { + $field_value = (int) $field_value; + + // retrieve option lang data if necessary + if (!$this->lang_helper->is_set($field_data['field_id'], $field_data['lang_id'], 1)) + { + $this->lang_helper->get_option_lang($field_data['field_id'], $field_data['lang_id'], $this->get_service_name(), false); + } + + if (!$this->lang_helper->is_set($field_data['field_id'], $field_data['lang_id'], $field_value)) + { + return $this->user->lang('FIELD_INVALID_VALUE', $this->get_field_name($field_data['lang_name'])); + } + + if ($field_value == $field_data['field_novalue'] && $field_data['field_required']) + { + return $this->user->lang('FIELD_REQUIRED', $this->get_field_name($field_data['lang_name'])); + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function get_profile_value($field_value, $field_data) + { + $field_id = $field_data['field_id']; + $lang_id = $field_data['lang_id']; + if (!$this->lang_helper->is_set($field_id, $lang_id)) + { + $this->lang_helper->get_option_lang($field_id, $lang_id, $this->get_service_name(), false); + } + + if ($field_value == $field_data['field_novalue'] && !$field_data['field_show_novalue']) + { + return null; + } + + $field_value = (int) $field_value; + + // User not having a value assigned + if (!$this->lang_helper->is_set($field_id, $lang_id, $field_value)) + { + if ($field_data['field_show_novalue']) + { + $field_value = $field_data['field_novalue']; + } + else + { + return null; + } + } + + return $this->lang_helper->get($field_id, $lang_id, $field_value); + } + + /** + * {@inheritDoc} + */ + public function generate_field($profile_row, $preview_options = false) + { + $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; + $field_ident = $profile_row['field_ident']; + $default_value = $profile_row['field_default_value']; + + $value = ($this->request->is_set($field_ident)) ? $this->request->variable($field_ident, $default_value) : ((!isset($this->user->profile_fields[$field_ident]) || $preview_options !== false) ? $default_value : $this->user->profile_fields[$field_ident]); + + if (!$this->lang_helper->is_set($profile_row['field_id'], $profile_row['lang_id'], 1)) + { + $this->lang_helper->get_option_lang($profile_row['field_id'], $profile_row['lang_id'], $this->get_service_name(), $preview_options); + } + + $profile_row['field_value'] = (int) $value; + $this->template->assign_block_vars('dropdown', array_change_key_case($profile_row, CASE_UPPER)); + + $options = $this->lang_helper->get($profile_row['field_id'], $profile_row['lang_id']); + foreach ($options as $option_id => $option_value) + { + $this->template->assign_block_vars('dropdown.options', array( + 'OPTION_ID' => $option_id, + 'SELECTED' => ($value == $option_id) ? ' selected="selected"' : '', + 'VALUE' => $option_value, + )); + } + } + + /** + * {@inheritDoc} + */ + public function get_database_column_type() + { + return 'UINT'; + } + + /** + * {@inheritDoc} + */ + public function get_language_options($field_data) + { + $options = array( + 'lang_name' => 'string', + 'lang_options' => 'optionfield', + ); + + if ($field_data['lang_explain']) + { + $options['lang_explain'] = 'text'; + } + + return $options; + } + + /** + * {@inheritDoc} + */ + public function prepare_options_form(&$exclude_options, &$visibility_options) + { + $exclude_options[1][] = 'lang_options'; + + return $this->request->variable('lang_options', '', true); + } + + /** + * {@inheritDoc} + */ + public function validate_options_on_submit($error, $field_data) + { + if (!sizeof($field_data['lang_options'])) + { + $error[] = $this->user->lang['NO_FIELD_ENTRIES']; + } + + return $error; + } + + /** + * {@inheritDoc} + */ + public function get_excluded_options($key, $action, $current_value, &$field_data, $step) + { + if ($step == 2 && $key == 'field_maxlen') + { + // Get the number of options if this key is 'field_maxlen' + return sizeof(explode("\n", $this->request->variable('lang_options', '', true))); + } + + return parent::get_excluded_options($key, $action, $current_value, $field_data, $step); + } + + /** + * {@inheritDoc} + */ + public function display_options(&$template_vars, &$field_data) + { + // Initialize these array elements if we are creating a new field + if (!sizeof($field_data['lang_options'])) + { + // No options have been defined for the dropdown menu + $field_data['lang_options'] = array(); + } + + $template_vars = array_merge($template_vars, array( + 'S_DROPDOWN' => true, + 'L_LANG_OPTIONS_EXPLAIN' => $this->user->lang['DROPDOWN_ENTRIES_EXPLAIN'], + 'LANG_OPTIONS' => implode("\n", $field_data['lang_options']), + )); + } +} diff --git a/phpBB/phpbb/profilefields/type/type_int.php b/phpBB/phpbb/profilefields/type/type_int.php new file mode 100644 index 0000000000..c98c863e13 --- /dev/null +++ b/phpBB/phpbb/profilefields/type/type_int.php @@ -0,0 +1,234 @@ +<?php +/** +* +* @package phpBB +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields\type; + +class type_int extends type_base +{ + /** + * Request object + * @var \phpbb\request\request + */ + protected $request; + + /** + * Template object + * @var \phpbb\template\template + */ + protected $template; + + /** + * User object + * @var \phpbb\user + */ + protected $user; + + /** + * Construct + * + * @param \phpbb\request\request $request Request object + * @param \phpbb\template\template $template Template object + * @param \phpbb\user $user User object + * @param string $language_table Table where the language strings are stored + */ + public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) + { + $this->request = $request; + $this->template = $template; + $this->user = $user; + } + + /** + * {@inheritDoc} + */ + public function get_name_short() + { + return 'int'; + } + + /** + * {@inheritDoc} + */ + public function get_options($default_lang_id, $field_data) + { + $options = array( + 0 => array('TITLE' => $this->user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_length" size="5" value="' . $field_data['field_length'] . '" />'), + 1 => array('TITLE' => $this->user->lang['MIN_FIELD_NUMBER'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_minlen" size="5" value="' . $field_data['field_minlen'] . '" />'), + 2 => array('TITLE' => $this->user->lang['MAX_FIELD_NUMBER'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_maxlen" size="5" value="' . $field_data['field_maxlen'] . '" />'), + 3 => array('TITLE' => $this->user->lang['DEFAULT_VALUE'], 'FIELD' => '<input type="number" name="field_default_value" value="' . $field_data['field_default_value'] . '" />'), + ); + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_default_option_values() + { + return array( + 'field_length' => 5, + 'field_minlen' => 0, + 'field_maxlen' => 100, + 'field_validation' => '', + 'field_novalue' => 0, + 'field_default_value' => 0, + ); + } + + /** + * {@inheritDoc} + */ + public function get_default_field_value($field_data) + { + if ($field_data['field_default_value'] === '') + { + // We cannot insert an empty string into an integer column. + return null; + } + + return $field_data['field_default_value']; + } + + /** + * {@inheritDoc} + */ + public function get_profile_field($profile_row) + { + $var_name = 'pf_' . $profile_row['field_ident']; + if ($this->request->is_set($var_name) && $this->request->variable($var_name, '') === '') + { + return null; + } + else + { + return $this->request->variable($var_name, (int) $profile_row['field_default_value']); + } + } + + /** + * {@inheritDoc} + */ + public function validate_profile_field(&$field_value, $field_data) + { + if (trim($field_value) === '' && !$field_data['field_required']) + { + return false; + } + + $field_value = (int) $field_value; + + if ($field_value < $field_data['field_minlen']) + { + return $this->user->lang('FIELD_TOO_SMALL', (int) $field_data['field_minlen'], $this->get_field_name($field_data['lang_name'])); + } + else if ($field_value > $field_data['field_maxlen']) + { + return $this->user->lang('FIELD_TOO_LARGE', (int) $field_data['field_maxlen'], $this->get_field_name($field_data['lang_name'])); + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function get_profile_value($field_value, $field_data) + { + if (($field_value === '' || $field_value === null) && !$field_data['field_show_novalue']) + { + return null; + } + return (int) $field_value; + } + + /** + * {@inheritDoc} + */ + public function generate_field($profile_row, $preview_options = false) + { + $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; + $field_ident = $profile_row['field_ident']; + $default_value = $profile_row['field_default_value']; + + if ($this->request->is_set($field_ident)) + { + $value = ($this->request->variable($field_ident, '') === '') ? null : $this->request->variable($field_ident, $default_value); + } + else + { + if ($preview_options === false && array_key_exists($field_ident, $this->user->profile_fields) && is_null($this->user->profile_fields[$field_ident])) + { + $value = null; + } + else if (!isset($this->user->profile_fields[$field_ident]) || $preview_options !== false) + { + $value = $default_value; + } + else + { + $value = $this->user->profile_fields[$field_ident]; + } + } + + $profile_row['field_value'] = (is_null($value) || $value === '') ? '' : (int) $value; + + $this->template->assign_block_vars('int', array_change_key_case($profile_row, CASE_UPPER)); + } + + /** + * {@inheritDoc} + */ + public function get_field_ident($field_data) + { + return 'pf_' . $field_data['field_ident']; + } + + /** + * {@inheritDoc} + */ + public function get_database_column_type() + { + return 'BINT'; + } + + /** + * {@inheritDoc} + */ + public function get_language_options($field_data) + { + $options = array( + 'lang_name' => 'string', + ); + + if ($field_data['lang_explain']) + { + $options['lang_explain'] = 'text'; + } + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_excluded_options($key, $action, $current_value, &$field_data, $step) + { + if ($step == 2 && $key == 'field_default_value') + { + // Permit an empty string + if ($action == 'create' && $this->request->variable('field_default_value', '') === '') + { + return ''; + } + } + + return parent::get_excluded_options($key, $action, $current_value, $field_data, $step); + } +} diff --git a/phpBB/phpbb/profilefields/type/type_interface.php b/phpBB/phpbb/profilefields/type/type_interface.php new file mode 100644 index 0000000000..a1c3d879c8 --- /dev/null +++ b/phpBB/phpbb/profilefields/type/type_interface.php @@ -0,0 +1,205 @@ +<?php +/** +* +* @package phpBB +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields\type; + +interface type_interface +{ + /** + * Get the translated name of the type + * + * @return string Translated name of the field type + */ + public function get_name(); + + /** + * Get the short name of the type, used for error messages and template loops + * + * @return string lowercase version of the fields type + */ + public function get_name_short(); + + /** + * Get the name of service representing the type + * + * @return string lowercase version of the fields type + */ + public function get_service_name(); + + /** + * Get the name of template file for this type + * + * @return string Returns the name of the template file + */ + public function get_template_filename(); + + /** + * Get dropdown options for second step in ACP + * + * @param string $default_lang_id ID of the default language + * @param array $field_data Array with data for this field + * @return array with the acp options + */ + public function get_options($default_lang_id, $field_data); + + /** + * Get default values for the options of this type + * + * @return array with values like default field size and more + */ + public function get_default_option_values(); + + /** + * Get default value for this type + * + * @param array $field_data Array with data for this field + * @return mixed default value for new users when no value is given + */ + public function get_default_field_value($field_data); + + /** + * Get profile field value on submit + * + * @param array $profile_row Array with data for this field + * @return mixed Submitted value of the profile field + */ + public function get_profile_field($profile_row); + + /** + * Validate entered profile field data + * + * @param mixed $field_value Field value to validate + * @param array $field_data Array with requirements of the field + * @return mixed String with the error message + */ + public function validate_profile_field(&$field_value, $field_data); + + /** + * Get Profile Value for display + * + * @param mixed $field_value Field value as stored in the database + * @param array $field_data Array with requirements of the field + * @return mixed Field value to display + */ + public function get_profile_value($field_value, $field_data); + + /** + * Get Profile Value for display + * + * When displaying a contact field, we don't want to have links already parsed and more + * + * @param mixed $field_value Field value as stored in the database + * @param array $field_data Array with requirements of the field + * @return mixed Field value to display + */ + public function get_profile_contact_value($field_value, $field_data); + + /** + * Generate the input field for display + * + * @param array $profile_row Array with data for this field + * @param mixed $preview_options When previewing we use different data + * @return null + */ + public function generate_field($profile_row, $preview_options = false); + + /** + * Get the ident of the field + * + * Some types are multivalue, we can't give them a field_id + * as we would not know which to pick. + * + * @param array $field_data Array with data for this field + * @return string ident of the field + */ + public function get_field_ident($field_data); + + /** + * Get the column type for the database + * + * @return string Returns the database column type + */ + public function get_database_column_type(); + + /** + * Get the options we need to display for the language input fields in the ACP + * + * @param array $field_data Array with data for this field + * @return array Returns the language options we need to generate + */ + public function get_language_options($field_data); + + /** + * Get the input for the supplied language options + * + * @param array $field_data Array with data for this field + * @return array Returns the language options we need to generate + */ + public function get_language_options_input($field_data); + + /** + * Allows exclusion of options in single steps of the creation process + * + * @param array $exclude_options Array with options that should be excluded in the steps + * @param array $visibility_options Array with options responsible for the fields visibility + * @return mixed Returns the provided language options + */ + public function prepare_options_form(&$exclude_options, &$visibility_options); + + /** + * Allows exclusion of options in single steps of the creation process + * + * @param array $error Array with error messages + * @param array $field_data Array with data for this field + * @return array Array with error messages + */ + public function validate_options_on_submit($error, $field_data); + + /** + * Allows manipulating the intended variables if needed + * + * @param string $key Name of the option + * @param string $action Currently performed action (create|edit) + * @param mixed $current_value Currently value of the option + * @param array $field_data Array with data for this field + * @param int $step Step on which the option is excluded + * @return mixed Final value of the option + */ + public function get_excluded_options($key, $action, $current_value, &$field_data, $step); + + /** + * Allows manipulating the intended variables if needed + * + * @param string $key Name of the option + * @param int $step Step on which the option is hidden + * @param string $action Currently performed action (create|edit) + * @param array $field_data Array with data for this field + * @return mixed Final value of the option + */ + public function prepare_hidden_fields($step, $key, $action, &$field_data); + + /** + * Allows assigning of additional template variables + * + * @param array $template_vars Template variables we are going to assign + * @param array $field_data Array with data for this field + * @return null + */ + public function display_options(&$template_vars, &$field_data); + + /** + * Return templated value/field. Possible values for $mode are: + * change == user is able to set/enter profile values; preview == just show the value + * + * @param string $mode Mode for displaying the field (preview|change) + * @param array $profile_row Array with data for this field + * @return null + */ + public function process_field_row($mode, $profile_row); +} diff --git a/phpBB/phpbb/profilefields/type/type_string.php b/phpBB/phpbb/profilefields/type/type_string.php new file mode 100644 index 0000000000..9dada592eb --- /dev/null +++ b/phpBB/phpbb/profilefields/type/type_string.php @@ -0,0 +1,156 @@ +<?php +/** +* +* @package phpBB +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields\type; + +class type_string extends type_string_common +{ + /** + * Request object + * @var \phpbb\request\request + */ + protected $request; + + /** + * Template object + * @var \phpbb\template\template + */ + protected $template; + + /** + * User object + * @var \phpbb\user + */ + protected $user; + + /** + * Construct + * + * @param \phpbb\request\request $request Request object + * @param \phpbb\template\template $template Template object + * @param \phpbb\user $user User object + * @param string $language_table Table where the language strings are stored + */ + public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) + { + $this->request = $request; + $this->template = $template; + $this->user = $user; + } + + /** + * {@inheritDoc} + */ + public function get_name_short() + { + return 'string'; + } + + /** + * {@inheritDoc} + */ + public function get_options($default_lang_id, $field_data) + { + $options = array( + 0 => array('TITLE' => $this->user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" name="field_length" size="5" value="' . $field_data['field_length'] . '" />'), + 1 => array('TITLE' => $this->user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" name="field_minlen" size="5" value="' . $field_data['field_minlen'] . '" />'), + 2 => array('TITLE' => $this->user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" name="field_maxlen" size="5" value="' . $field_data['field_maxlen'] . '" />'), + 3 => array('TITLE' => $this->user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options($field_data) . '</select>'), + ); + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_default_option_values() + { + return array( + 'field_length' => 10, + 'field_minlen' => 0, + 'field_maxlen' => 20, + 'field_validation' => '.*', + 'field_novalue' => '', + 'field_default_value' => '', + ); + } + + /** + * {@inheritDoc} + */ + public function get_profile_field($profile_row) + { + $var_name = 'pf_' . $profile_row['field_ident']; + return $this->request->variable($var_name, (string) $profile_row['field_default_value'], true); + } + + /** + * {@inheritDoc} + */ + public function validate_profile_field(&$field_value, $field_data) + { + return $this->validate_string_profile_field('string', $field_value, $field_data); + } + + /** + * {@inheritDoc} + */ + public function generate_field($profile_row, $preview_options = false) + { + $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; + $field_ident = $profile_row['field_ident']; + $default_value = $profile_row['lang_default_value']; + $profile_row['field_value'] = ($this->request->is_set($field_ident)) ? $this->request->variable($field_ident, $default_value, true) : ((!isset($this->user->profile_fields[$field_ident]) || $preview_options !== false) ? $default_value : $this->user->profile_fields[$field_ident]); + + $this->template->assign_block_vars($this->get_name_short(), array_change_key_case($profile_row, CASE_UPPER)); + } + + /** + * {@inheritDoc} + */ + public function get_database_column_type() + { + return 'VCHAR'; + } + + /** + * {@inheritDoc} + */ + public function get_language_options($field_data) + { + $options = array( + 'lang_name' => 'string', + ); + + if ($field_data['lang_explain']) + { + $options['lang_explain'] = 'text'; + } + + if (strlen($field_data['lang_default_value'])) + { + $options['lang_default_value'] = 'string'; + } + + return $options; + } + + /** + * {@inheritDoc} + */ + public function display_options(&$template_vars, &$field_data) + { + $template_vars = array_merge($template_vars, array( + 'S_STRING' => true, + 'L_DEFAULT_VALUE_EXPLAIN' => $this->user->lang['STRING_DEFAULT_VALUE_EXPLAIN'], + 'LANG_DEFAULT_VALUE' => $field_data['lang_default_value'], + )); + } +} diff --git a/phpBB/phpbb/profilefields/type/type_string_common.php b/phpBB/phpbb/profilefields/type/type_string_common.php new file mode 100644 index 0000000000..78e219a61f --- /dev/null +++ b/phpBB/phpbb/profilefields/type/type_string_common.php @@ -0,0 +1,128 @@ +<?php +/** +* +* @package phpBB +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields\type; + +abstract class type_string_common extends type_base +{ + protected $validation_options = array( + 'CHARS_ANY' => '.*', + 'NUMBERS_ONLY' => '[0-9]+', + 'ALPHA_ONLY' => '[\w]+', + 'ALPHA_UNDERSCORE' => '[\w_]+', + 'ALPHA_SPACERS' => '[\w_\+\. \-\[\]]+', + ); + + /** + * Return possible validation options + */ + public function validate_options($field_data) + { + $validate_options = ''; + foreach ($this->validation_options as $lang => $value) + { + $selected = ($field_data['field_validation'] == $value) ? ' selected="selected"' : ''; + $validate_options .= '<option value="' . $value . '"' . $selected . '>' . $this->user->lang[$lang] . '</option>'; + } + + return $validate_options; + } + + /** + * {@inheritDoc} + */ + public function get_default_field_value($field_data) + { + return $field_data['lang_default_value']; + } + + /** + * Validate entered profile field data + * + * @param string $field_type Field type (string or text) + * @param mixed $field_value Field value to validate + * @param array $field_data Array with requirements of the field + * @return mixed String with key of the error language string, false otherwise + */ + public function validate_string_profile_field($field_type, &$field_value, $field_data) + { + if (trim($field_value) === '' && !$field_data['field_required']) + { + return false; + } + else if (trim($field_value) === '' && $field_data['field_required']) + { + return $this->user->lang('FIELD_REQUIRED', $this->get_field_name($field_data['lang_name'])); + } + + if ($field_data['field_minlen'] && utf8_strlen($field_value) < $field_data['field_minlen']) + { + return $this->user->lang('FIELD_TOO_SHORT', (int) $field_data['field_minlen'], $this->get_field_name($field_data['lang_name'])); + } + else if ($field_data['field_maxlen'] && utf8_strlen(html_entity_decode($field_value)) > $field_data['field_maxlen']) + { + return $this->user->lang('FIELD_TOO_LONG', (int) $field_data['field_maxlen'], $this->get_field_name($field_data['lang_name'])); + } + + if (!empty($field_data['field_validation']) && $field_data['field_validation'] != '.*') + { + $field_validate = ($field_type != 'text') ? $field_value : bbcode_nl2br($field_value); + if (!preg_match('#^' . str_replace('\\\\', '\\', $field_data['field_validation']) . '$#i', $field_validate)) + { + $validation = array_search($field_data['field_validation'], $this->validation_options); + if ($validation) + { + return $this->user->lang('FIELD_INVALID_CHARS_' . $validation, $this->get_field_name($field_data['lang_name'])); + } + return $this->user->lang('FIELD_INVALID_CHARS_INVALID', $this->get_field_name($field_data['lang_name'])); + } + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function get_profile_value($field_value, $field_data) + { + if (!$field_value && !$field_data['field_show_novalue']) + { + return null; + } + + $field_value = make_clickable($field_value); + $field_value = censor_text($field_value); + $field_value = bbcode_nl2br($field_value); + return $field_value; + } + + /** + * {@inheritDoc} + */ + public function get_profile_contact_value($field_value, $field_data) + { + if (!$field_value && !$field_data['field_show_novalue']) + { + return null; + } + + return $field_value; + } + + /** + * {@inheritDoc} + */ + public function prepare_options_form(&$exclude_options, &$visibility_options) + { + $exclude_options[1][] = 'lang_default_value'; + + return $this->request->variable('lang_options', '', true); + } +} diff --git a/phpBB/phpbb/profilefields/type/type_text.php b/phpBB/phpbb/profilefields/type/type_text.php new file mode 100644 index 0000000000..660bb20ef8 --- /dev/null +++ b/phpBB/phpbb/profilefields/type/type_text.php @@ -0,0 +1,201 @@ +<?php +/** +* +* @package phpBB +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields\type; + +class type_text extends type_string_common +{ + /** + * Request object + * @var \phpbb\request\request + */ + protected $request; + + /** + * Template object + * @var \phpbb\template\template + */ + protected $template; + + /** + * User object + * @var \phpbb\user + */ + protected $user; + + /** + * Construct + * + * @param \phpbb\request\request $request Request object + * @param \phpbb\template\template $template Template object + * @param \phpbb\user $user User object + * @param string $language_table Table where the language strings are stored + */ + public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) + { + $this->request = $request; + $this->template = $template; + $this->user = $user; + } + + /** + * {@inheritDoc} + */ + public function get_name_short() + { + return 'text'; + } + + /** + * {@inheritDoc} + */ + public function get_options($default_lang_id, $field_data) + { + $options = array( + 0 => array('TITLE' => $this->user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" max="99999" name="rows" size="5" value="' . $field_data['rows'] . '" /> ' . $this->user->lang['ROWS'] . '</dd><dd><input type="number" min="0" max="99999" name="columns" size="5" value="' . $field_data['columns'] . '" /> ' . $this->user->lang['COLUMNS'] . ' <input type="hidden" name="field_length" value="' . $field_data['field_length'] . '" />'), + 1 => array('TITLE' => $this->user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" max="9999999999" name="field_minlen" size="10" value="' . $field_data['field_minlen'] . '" />'), + 2 => array('TITLE' => $this->user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" max="9999999999" name="field_maxlen" size="10" value="' . $field_data['field_maxlen'] . '" />'), + 3 => array('TITLE' => $this->user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options($field_data) . '</select>'), + ); + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_default_option_values() + { + return array( + 'field_length' => '5|80', + 'field_minlen' => 0, + 'field_maxlen' => 1000, + 'field_validation' => '.*', + 'field_novalue' => '', + 'field_default_value' => '', + ); + } + + /** + * {@inheritDoc} + */ + public function get_profile_field($profile_row) + { + $var_name = 'pf_' . $profile_row['field_ident']; + return $this->request->variable($var_name, (string) $profile_row['field_default_value'], true); + } + + /** + * {@inheritDoc} + */ + public function validate_profile_field(&$field_value, $field_data) + { + return $this->validate_string_profile_field('text', $field_value, $field_data); + } + + /** + * {@inheritDoc} + */ + public function generate_field($profile_row, $preview_options = false) + { + $field_length = explode('|', $profile_row['field_length']); + $profile_row['field_rows'] = $field_length[0]; + $profile_row['field_cols'] = $field_length[1]; + $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; + $field_ident = $profile_row['field_ident']; + $default_value = $profile_row['lang_default_value']; + + $profile_row['field_value'] = ($this->request->is_set($field_ident)) ? $this->request->variable($field_ident, $default_value, true) : ((!isset($this->user->profile_fields[$field_ident]) || $preview_options !== false) ? $default_value : $this->user->profile_fields[$field_ident]); + + $this->template->assign_block_vars('text', array_change_key_case($profile_row, CASE_UPPER)); + } + + /** + * {@inheritDoc} + */ + public function get_database_column_type() + { + return 'MTEXT'; + } + + /** + * {@inheritDoc} + */ + public function get_language_options($field_data) + { + $options = array( + 'lang_name' => 'string', + ); + + if ($field_data['lang_explain']) + { + $options['lang_explain'] = 'text'; + } + + if (strlen($field_data['lang_default_value'])) + { + $options['lang_default_value'] = 'text'; + } + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_excluded_options($key, $action, $current_value, &$field_data, $step) + { + if ($step == 2 && $key == 'field_length') + { + if ($this->request->is_set('rows')) + { + $field_data['rows'] = $this->request->variable('rows', 0); + $field_data['columns'] = $this->request->variable('columns', 0); + $current_value = $field_data['rows'] . '|' . $field_data['columns']; + } + else + { + $row_col = explode('|', $current_value); + $field_data['rows'] = $row_col[0]; + $field_data['columns'] = $row_col[1]; + } + + return $current_value; + } + + return parent::get_excluded_options($key, $action, $current_value, $field_data, $step); + } + + /** + * {@inheritDoc} + */ + public function prepare_hidden_fields($step, $key, $action, &$field_data) + { + if ($key == 'field_length' && $this->request->is_set('rows')) + { + $field_data['rows'] = $this->request->variable('rows', 0); + $field_data['columns'] = $this->request->variable('columns', 0); + return $field_data['rows'] . '|' . $field_data['columns']; + } + + return parent::prepare_hidden_fields($step, $key, $action, $field_data); + } + + /** + * {@inheritDoc} + */ + public function display_options(&$template_vars, &$field_data) + { + $template_vars = array_merge($template_vars, array( + 'S_TEXT' => true, + 'L_DEFAULT_VALUE_EXPLAIN' => $this->user->lang['TEXT_DEFAULT_VALUE_EXPLAIN'], + 'LANG_DEFAULT_VALUE' => $field_data['lang_default_value'], + )); + } +} diff --git a/phpBB/phpbb/profilefields/type/type_url.php b/phpBB/phpbb/profilefields/type/type_url.php new file mode 100644 index 0000000000..b1523b9355 --- /dev/null +++ b/phpBB/phpbb/profilefields/type/type_url.php @@ -0,0 +1,70 @@ +<?php +/** +* +* @package phpBB +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\profilefields\type; + +class type_url extends type_string +{ + /** + * {@inheritDoc} + */ + public function get_name_short() + { + return 'url'; + } + + /** + * {@inheritDoc} + */ + public function get_options($default_lang_id, $field_data) + { + $options = array( + 0 => array('TITLE' => $this->user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" name="field_length" size="5" value="' . $field_data['field_length'] . '" />'), + 1 => array('TITLE' => $this->user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" name="field_minlen" size="5" value="' . $field_data['field_minlen'] . '" />'), + 2 => array('TITLE' => $this->user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" name="field_maxlen" size="5" value="' . $field_data['field_maxlen'] . '" />'), + ); + + return $options; + } + + /** + * {@inheritDoc} + */ + public function get_default_option_values() + { + return array( + 'field_length' => 40, + 'field_minlen' => 0, + 'field_maxlen' => 200, + 'field_validation' => '', + 'field_novalue' => '', + 'field_default_value' => '', + ); + } + + /** + * {@inheritDoc} + */ + public function validate_profile_field(&$field_value, $field_data) + { + $field_value = trim($field_value); + + if ($field_value === '' && !$field_data['field_required']) + { + return false; + } + + if (!preg_match('#^' . get_preg_expression('url') . '$#i', $field_value)) + { + return $this->user->lang('FIELD_INVALID_URL', $this->get_field_name($field_data['lang_name'])); + } + + return false; + } +} diff --git a/phpBB/phpbb/recursive_dot_prefix_filter_iterator.php b/phpBB/phpbb/recursive_dot_prefix_filter_iterator.php new file mode 100644 index 0000000000..6ef63ec906 --- /dev/null +++ b/phpBB/phpbb/recursive_dot_prefix_filter_iterator.php @@ -0,0 +1,28 @@ +<?php +/** +* +* @package extension +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb; + +/** +* Class recursive_dot_prefix_filter_iterator +* +* This filter ignores directories starting with a dot. +* When searching for php classes and template files of extensions +* we don't need to look inside these directories. +* +* @package phpbb +*/ +class recursive_dot_prefix_filter_iterator extends \RecursiveFilterIterator +{ + public function accept() + { + $filename = $this->current()->getFilename(); + return !$this->current()->isDir() || $filename[0] !== '.'; + } +} diff --git a/phpBB/phpbb/request/deactivated_super_global.php b/phpBB/phpbb/request/deactivated_super_global.php index 8f39960477..b6940cf51f 100644 --- a/phpBB/phpbb/request/deactivated_super_global.php +++ b/phpBB/phpbb/request/deactivated_super_global.php @@ -10,14 +10,6 @@ namespace phpbb\request; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Replacement for a superglobal (like $_GET or $_POST) which calls * trigger_error on all operations but isset, overloads the [] operator with SPL. * @@ -120,4 +112,3 @@ class deactivated_super_global implements \ArrayAccess, \Countable, \IteratorAgg $this->error(); } } - diff --git a/phpBB/phpbb/request/request.php b/phpBB/phpbb/request/request.php index 1c388b3c73..3171a6edb7 100644 --- a/phpBB/phpbb/request/request.php +++ b/phpBB/phpbb/request/request.php @@ -10,14 +10,6 @@ namespace phpbb\request; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * All application input is accessed through this class. * * It provides a method to disable access to input data through super globals. @@ -225,7 +217,7 @@ class request implements \phpbb\request\request_interface * @return mixed The value of $_REQUEST[$var_name] run through {@link set_var set_var} to ensure that the type is the * the same as that of $default. If the variable is not set $default is returned. */ - public function untrimmed_variable($var_name, $default, $multibyte, $super_global = \phpbb\request\request_interface::REQUEST) + public function untrimmed_variable($var_name, $default, $multibyte = false, $super_global = \phpbb\request\request_interface::REQUEST) { return $this->_variable($var_name, $default, $multibyte, $super_global, false); } diff --git a/phpBB/phpbb/request/request_interface.php b/phpBB/phpbb/request/request_interface.php index cd949147f7..1f9978b276 100644 --- a/phpBB/phpbb/request/request_interface.php +++ b/phpBB/phpbb/request/request_interface.php @@ -10,14 +10,6 @@ namespace phpbb\request; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * An interface through which all application input can be accessed. * * @package \phpbb\request\request diff --git a/phpBB/phpbb/request/type_cast_helper.php b/phpBB/phpbb/request/type_cast_helper.php index 262aff73c1..e9b55663af 100644 --- a/phpBB/phpbb/request/type_cast_helper.php +++ b/phpBB/phpbb/request/type_cast_helper.php @@ -10,14 +10,6 @@ namespace phpbb\request; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * A helper class that provides convenience methods for type casting. * * @package \phpbb\request\request diff --git a/phpBB/phpbb/request/type_cast_helper_interface.php b/phpBB/phpbb/request/type_cast_helper_interface.php index e8195c352e..f12795eef9 100644 --- a/phpBB/phpbb/request/type_cast_helper_interface.php +++ b/phpBB/phpbb/request/type_cast_helper_interface.php @@ -10,14 +10,6 @@ namespace phpbb\request; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * An interface for type cast operations. * * @package \phpbb\request\request diff --git a/phpBB/phpbb/search/base.php b/phpBB/phpbb/search/base.php index f2f982c31b..9ecf3751d0 100644 --- a/phpBB/phpbb/search/base.php +++ b/phpBB/phpbb/search/base.php @@ -12,14 +12,6 @@ namespace phpbb\search; /** * @ignore */ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* @ignore -*/ define('SEARCH_RESULT_NOT_IN_CACHE', 0); define('SEARCH_RESULT_IN_CACHE', 1); define('SEARCH_RESULT_INCOMPLETE', 2); diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index 50d2d2577f..e5b0c89cb6 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -10,14 +10,6 @@ namespace phpbb\search; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * fulltext_mysql * Fulltext search for MySQL * @package search @@ -44,7 +36,7 @@ class fulltext_mysql extends \phpbb\search\base /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -224,7 +216,7 @@ class fulltext_mysql extends \phpbb\search\base // We limit the number of allowed keywords to minimize load on the database if ($this->config['max_num_search_keywords'] && sizeof($this->split_words) > $this->config['max_num_search_keywords']) { - trigger_error($this->user->lang('MAX_NUM_SEARCH_KEYWORDS_REFINE', $this->config['max_num_search_keywords'], sizeof($this->split_words))); + trigger_error($this->user->lang('MAX_NUM_SEARCH_KEYWORDS_REFINE', (int) $this->config['max_num_search_keywords'], sizeof($this->split_words))); } // to allow phrase search, we need to concatenate quoted words @@ -781,7 +773,7 @@ class fulltext_mysql extends \phpbb\search\base $alter[] = 'ADD FULLTEXT (post_subject)'; } - if (!isset($this->stats['post_text'])) + if (!isset($this->stats['post_content'])) { if ($this->db->sql_layer == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) { @@ -791,12 +783,8 @@ class fulltext_mysql extends \phpbb\search\base { $alter[] = 'MODIFY post_text mediumtext NOT NULL'; } - $alter[] = 'ADD FULLTEXT (post_text)'; - } - if (!isset($this->stats['post_content'])) - { - $alter[] = 'ADD FULLTEXT post_content (post_subject, post_text)'; + $alter[] = 'ADD FULLTEXT post_content (post_text, post_subject)'; } if (sizeof($alter)) @@ -834,11 +822,6 @@ class fulltext_mysql extends \phpbb\search\base $alter[] = 'DROP INDEX post_subject'; } - if (isset($this->stats['post_text'])) - { - $alter[] = 'DROP INDEX post_text'; - } - if (isset($this->stats['post_content'])) { $alter[] = 'DROP INDEX post_content'; @@ -864,7 +847,7 @@ class fulltext_mysql extends \phpbb\search\base $this->get_stats(); } - return (isset($this->stats['post_text']) && isset($this->stats['post_subject']) && isset($this->stats['post_content'])) ? true : false; + return isset($this->stats['post_subject']) && isset($this->stats['post_content']); } /** @@ -904,11 +887,7 @@ class fulltext_mysql extends \phpbb\search\base if ($index_type == 'FULLTEXT') { - if ($row['Key_name'] == 'post_text') - { - $this->stats['post_text'] = $row; - } - else if ($row['Key_name'] == 'post_subject') + if ($row['Key_name'] == 'post_subject') { $this->stats['post_subject'] = $row; } diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 33326f2882..7d51d164c7 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -10,14 +10,6 @@ namespace phpbb\search; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * fulltext_native * phpBB's own db driven fulltext search, version 2 * @package search @@ -88,7 +80,7 @@ class fulltext_native extends \phpbb\search\base /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -285,7 +277,7 @@ class fulltext_native extends \phpbb\search\base // We limit the number of allowed keywords to minimize load on the database if ($this->config['max_num_search_keywords'] && $num_keywords > $this->config['max_num_search_keywords']) { - trigger_error($this->user->lang('MAX_NUM_SEARCH_KEYWORDS_REFINE', $this->config['max_num_search_keywords'], $num_keywords)); + trigger_error($this->user->lang('MAX_NUM_SEARCH_KEYWORDS_REFINE', (int) $this->config['max_num_search_keywords'], $num_keywords)); } // $keywords input format: each word separated by a space, words in a bracket are not separated @@ -333,7 +325,12 @@ class fulltext_native extends \phpbb\search\base } $this->db->sql_freeresult($result); } - unset($exact_words); + + // Handle +, - without preceeding whitespace character + $match = array('#(\S)\+#', '#(\S)-#'); + $replace = array('$1 +', '$1 +'); + + $keywords = preg_replace($match, $replace, $keywords); // now analyse the search query, first split it using the spaces $query = explode(' ', $keywords); @@ -459,39 +456,21 @@ class fulltext_native extends \phpbb\search\base $this->{$mode . '_ids'}[] = $words[$word]; } } - // throw an error if we shall not ignore unexistant words - else if (!$ignore_no_id) + else { if (!isset($common_ids[$word])) { $len = utf8_strlen($word); - if ($len >= $this->word_length['min'] && $len <= $this->word_length['max']) - { - trigger_error(sprintf($this->user->lang['WORD_IN_NO_POST'], $word)); - } - else + if ($len < $this->word_length['min'] || $len > $this->word_length['max']) { $this->common_words[] = $word; } } } - else - { - $len = utf8_strlen($word); - if ($len < $this->word_length['min'] || $len > $this->word_length['max']) - { - $this->common_words[] = $word; - } - } - } - - // we can't search for negatives only - if (!sizeof($this->must_contain_ids)) - { - return false; } - if (!empty($this->search_query)) + // Return true if all words are not common words + if (sizeof($exact_words) - sizeof($this->common_words) > 0) { return true; } @@ -526,6 +505,12 @@ class fulltext_native extends \phpbb\search\base return false; } + // we can't search for negatives only + if (empty($this->must_contain_ids)) + { + return false; + } + $must_contain_ids = $this->must_contain_ids; $must_not_contain_ids = $this->must_not_contain_ids; $must_exclude_one_ids = $this->must_exclude_one_ids; @@ -850,7 +835,6 @@ class fulltext_native extends \phpbb\search\base } $this->db->sql_freeresult($result); - // if we use mysql and the total result count is not cached yet, retrieve it from the db if (!$total_results && $is_mysql) { @@ -1189,8 +1173,8 @@ class fulltext_native extends \phpbb\search\base * we know that it will also be lower than CJK ranges */ if ((strncmp($word, UTF8_HANGUL_FIRST, 3) < 0 || strncmp($word, UTF8_HANGUL_LAST, 3) > 0) - && (strncmp($word, UTF8_CJK_FIRST, 3) < 0 || strncmp($word, UTF8_CJK_LAST, 3) > 0) - && (strncmp($word, UTF8_CJK_B_FIRST, 4) < 0 || strncmp($word, UTF8_CJK_B_LAST, 4) > 0)) + && (strncmp($word, UTF8_CJK_FIRST, 3) < 0 || strncmp($word, UTF8_CJK_LAST, 3) > 0) + && (strncmp($word, UTF8_CJK_B_FIRST, 4) < 0 || strncmp($word, UTF8_CJK_B_LAST, 4) > 0)) { $word = strtok(' '); continue; @@ -1684,8 +1668,8 @@ class fulltext_native extends \phpbb\search\base $pos += $utf_len; if (($utf_char >= UTF8_HANGUL_FIRST && $utf_char <= UTF8_HANGUL_LAST) - || ($utf_char >= UTF8_CJK_FIRST && $utf_char <= UTF8_CJK_LAST) - || ($utf_char >= UTF8_CJK_B_FIRST && $utf_char <= UTF8_CJK_B_LAST)) + || ($utf_char >= UTF8_CJK_FIRST && $utf_char <= UTF8_CJK_LAST) + || ($utf_char >= UTF8_CJK_B_FIRST && $utf_char <= UTF8_CJK_B_LAST)) { /** * All characters within these ranges are valid diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php index 756034103e..864a53e642 100644 --- a/phpBB/phpbb/search/fulltext_postgres.php +++ b/phpBB/phpbb/search/fulltext_postgres.php @@ -10,14 +10,6 @@ namespace phpbb\search; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * fulltext_postgres * Fulltext search for PostgreSQL * @package search @@ -69,7 +61,7 @@ class fulltext_postgres extends \phpbb\search\base /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -465,15 +457,13 @@ class fulltext_postgres extends \phpbb\search\base $sql_where_options .= $sql_match_where; $tmp_sql_match = array(); - foreach (explode(',', $sql_match) as $sql_match_column) - { - $tmp_sql_match[] = "to_tsvector ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', " . $sql_match_column . ") @@ to_tsquery ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', '" . $this->db->sql_escape($this->tsearch_query) . "')"; - } + $sql_match = str_replace(',', " || ' ' ||", $sql_match); + $tmp_sql_match = "to_tsvector ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', " . $sql_match . ") @@ to_tsquery ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', '" . $this->db->sql_escape($this->tsearch_query) . "')"; $this->db->sql_transaction('begin'); $sql_from = "FROM $sql_from$sql_sort_table" . POSTS_TABLE . " p"; - $sql_where = "WHERE (" . implode(' OR ', $tmp_sql_match) . ") + $sql_where = "WHERE (" . $tmp_sql_match . ") $sql_where_options"; $sql = "SELECT $sql_select $sql_from @@ -801,9 +791,9 @@ class fulltext_postgres extends \phpbb\search\base $this->db->sql_query("CREATE INDEX " . POSTS_TABLE . "_" . $this->config['fulltext_postgres_ts_name'] . "_post_subject ON " . POSTS_TABLE . " USING gin (to_tsvector ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', post_subject))"); } - if (!isset($this->stats['post_text'])) + if (!isset($this->stats['post_content'])) { - $this->db->sql_query("CREATE INDEX " . POSTS_TABLE . "_" . $this->config['fulltext_postgres_ts_name'] . "_post_text ON " . POSTS_TABLE . " USING gin (to_tsvector ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', post_text))"); + $this->db->sql_query("CREATE INDEX " . POSTS_TABLE . "_" . $this->config['fulltext_postgres_ts_name'] . "_post_content ON " . POSTS_TABLE . " USING gin (to_tsvector ('" . $this->db->sql_escape($this->config['fulltext_postgres_ts_name']) . "', post_text || ' ' || post_subject))"); } $this->db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE); @@ -834,9 +824,9 @@ class fulltext_postgres extends \phpbb\search\base $this->db->sql_query('DROP INDEX ' . $this->stats['post_subject']['relname']); } - if (isset($this->stats['post_text'])) + if (isset($this->stats['post_content'])) { - $this->db->sql_query('DROP INDEX ' . $this->stats['post_text']['relname']); + $this->db->sql_query('DROP INDEX ' . $this->stats['post_content']['relname']); } $this->db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE); @@ -854,7 +844,7 @@ class fulltext_postgres extends \phpbb\search\base $this->get_stats(); } - return (isset($this->stats['post_text']) && isset($this->stats['post_subject'])) ? true : false; + return (isset($this->stats['post_subject']) && isset($this->stats['post_content'])) ? true : false; } /** @@ -896,13 +886,13 @@ class fulltext_postgres extends \phpbb\search\base // deal with older PostgreSQL versions which didn't use Index_type if (strpos($row['indexdef'], 'to_tsvector') !== false) { - if ($row['relname'] == POSTS_TABLE . '_' . $this->config['fulltext_postgres_ts_name'] . '_post_text' || $row['relname'] == POSTS_TABLE . '_post_text') + if ($row['relname'] == POSTS_TABLE . '_' . $this->config['fulltext_postgres_ts_name'] . '_post_subject' || $row['relname'] == POSTS_TABLE . '_post_subject') { - $this->stats['post_text'] = $row; + $this->stats['post_subject'] = $row; } - else if ($row['relname'] == POSTS_TABLE . '_' . $this->config['fulltext_postgres_ts_name'] . '_post_subject' || $row['relname'] == POSTS_TABLE . '_post_subject') + else if ($row['relname'] == POSTS_TABLE . '_' . $this->config['fulltext_postgres_ts_name'] . '_post_content' || $row['relname'] == POSTS_TABLE . '_post_content') { - $this->stats['post_subject'] = $row; + $this->stats['post_content'] = $row; } } } diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index cb76d58f49..1501dcdc31 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -9,16 +9,6 @@ namespace phpbb\search; -/** -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* @ignore -*/ define('SPHINX_MAX_MATCHES', 20000); define('SPHINX_CONNECT_RETRIES', 3); define('SPHINX_CONNECT_WAIT_TIME', 300); @@ -87,7 +77,7 @@ class fulltext_sphinx /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -292,9 +282,9 @@ class fulltext_sphinx array('sql_attr_uint', 'post_visibility'), array('sql_attr_bool', 'topic_first_post'), array('sql_attr_bool', 'deleted'), - array('sql_attr_timestamp' , 'post_time'), - array('sql_attr_timestamp' , 'topic_last_post_time'), - array('sql_attr_str2ordinal', 'post_subject'), + array('sql_attr_timestamp', 'post_time'), + array('sql_attr_timestamp', 'topic_last_post_time'), + array('sql_attr_string', 'post_subject'), ), 'source source_phpbb_' . $this->id . '_delta : source_phpbb_' . $this->id . '_main' => array( array('sql_query_pre', ''), diff --git a/phpBB/phpbb/search/sphinx/config.php b/phpBB/phpbb/search/sphinx/config.php index 262d6008cc..cb8e4524df 100644 --- a/phpBB/phpbb/search/sphinx/config.php +++ b/phpBB/phpbb/search/sphinx/config.php @@ -10,14 +10,6 @@ namespace phpbb\search\sphinx; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * \phpbb\search\sphinx\config * An object representing the sphinx configuration * Can read it from file and write it back out after modification diff --git a/phpBB/phpbb/search/sphinx/config_comment.php b/phpBB/phpbb/search/sphinx/config_comment.php index 77a943377d..20b1c19af1 100644 --- a/phpBB/phpbb/search/sphinx/config_comment.php +++ b/phpBB/phpbb/search/sphinx/config_comment.php @@ -10,14 +10,6 @@ namespace phpbb\search\sphinx; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * \phpbb\search\sphinx\config_comment * Represents a comment inside the sphinx configuration */ diff --git a/phpBB/phpbb/search/sphinx/config_section.php b/phpBB/phpbb/search/sphinx/config_section.php index 730abf011e..8f9253ec56 100644 --- a/phpBB/phpbb/search/sphinx/config_section.php +++ b/phpBB/phpbb/search/sphinx/config_section.php @@ -10,14 +10,6 @@ namespace phpbb\search\sphinx; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * \phpbb\search\sphinx\config_section * Represents a single section inside the sphinx configuration */ diff --git a/phpBB/phpbb/search/sphinx/config_variable.php b/phpBB/phpbb/search/sphinx/config_variable.php index c8f40bfb5f..c0f6d28dcc 100644 --- a/phpBB/phpbb/search/sphinx/config_variable.php +++ b/phpBB/phpbb/search/sphinx/config_variable.php @@ -10,14 +10,6 @@ namespace phpbb\search\sphinx; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * \phpbb\search\sphinx\config_variable * Represents a single variable inside the sphinx configuration */ diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 2baf61043d..f530d30f1f 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -10,14 +10,6 @@ namespace phpbb; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Session class * @package phpBB3 */ @@ -42,13 +34,13 @@ class session */ static function extract_current_page($root_path) { - global $request; + global $request, $symfony_request, $phpbb_filesystem; $page_array = array(); // First of all, get the request uri... - $script_name = htmlspecialchars_decode($request->server('PHP_SELF')); - $args = explode('&', htmlspecialchars_decode($request->server('QUERY_STRING'))); + $script_name = $symfony_request->getScriptName(); + $args = explode('&', $symfony_request->getQueryString()); // If we are unable to get the script name we use REQUEST_URI as a failover and note it within the page array for easier support... if (!$script_name) @@ -89,6 +81,12 @@ class session $page_name = (substr($script_name, -1, 1) == '/') ? '' : basename($script_name); $page_name = urlencode(htmlspecialchars($page_name)); + $symfony_request_path = $phpbb_filesystem->clean_path($symfony_request->getPathInfo()); + if ($symfony_request_path !== '/') + { + $page_name .= $symfony_request_path; + } + // current directory within the phpBB root (for example: adm) $root_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($root_path))); $page_dirs = explode('/', str_replace('\\', '/', phpbb_realpath('./'))); @@ -105,10 +103,14 @@ class session } // Current page from phpBB root (for example: adm/index.php?i=10&b=2) - $page = (($page_dir) ? $page_dir . '/' : '') . $page_name . (($query_string) ? "?$query_string" : ''); + $page = (($page_dir) ? $page_dir . '/' : '') . $page_name; + if ($query_string) + { + $page .= '?' . $query_string; + } // The script path from the webroot to the current directory (for example: /phpBB3/adm/) : always prefixed with / and ends in / - $script_path = trim(str_replace('\\', '/', dirname($script_name))); + $script_path = $symfony_request->getBasePath(); // The script path from the webroot to the phpBB root (for example: /phpBB3/) $script_dirs = explode('/', $script_path); @@ -1225,7 +1227,6 @@ class session $this->session_create(ANONYMOUS); } - // Determine which message to output $till_date = ($ban_row['ban_end']) ? $this->format_date($ban_row['ban_end']) : ''; $message = ($ban_row['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM'; diff --git a/phpBB/phpbb/symfony_request.php b/phpBB/phpbb/symfony_request.php index 92784c213b..ebe862a565 100644 --- a/phpBB/phpbb/symfony_request.php +++ b/phpBB/phpbb/symfony_request.php @@ -11,14 +11,6 @@ namespace phpbb; use Symfony\Component\HttpFoundation\Request; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class symfony_request extends Request { /** diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php index 27564bf347..24e0d6698d 100644 --- a/phpBB/phpbb/template/asset.php +++ b/phpBB/phpbb/template/asset.php @@ -9,14 +9,6 @@ namespace phpbb\template; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class asset { protected $components = array(); diff --git a/phpBB/phpbb/template/base.php b/phpBB/phpbb/template/base.php index 86868707f0..5bce79fd85 100644 --- a/phpBB/phpbb/template/base.php +++ b/phpBB/phpbb/template/base.php @@ -9,14 +9,6 @@ namespace phpbb\template; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - abstract class base implements template { /** @@ -121,6 +113,16 @@ abstract class base implements template /** * {@inheritdoc} */ + public function assign_block_vars_array($blockname, array $block_vars_array) + { + $this->context->assign_block_vars_array($blockname, $block_vars_array); + + return $this; + } + + /** + * {@inheritdoc} + */ public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') { return $this->context->alter_block_array($blockname, $vararray, $key, $mode); diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 24234c1e4a..a222fbb69e 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -10,14 +10,6 @@ namespace phpbb\template; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Stores variables assigned to template. * * @package phpBB3 @@ -163,11 +155,12 @@ class context // We're adding a new iteration to this block with the given // variable assignments. $str[$blocks[$blockcount]][] = $vararray; + $s_num_rows = sizeof($str[$blocks[$blockcount]]); // Set S_NUM_ROWS foreach ($str[$blocks[$blockcount]] as &$mod_block) { - $mod_block['S_NUM_ROWS'] = sizeof($str[$blocks[$blockcount]]); + $mod_block['S_NUM_ROWS'] = $s_num_rows; } } else @@ -194,11 +187,12 @@ class context // Add a new iteration to this block with the variable assignments we were given. $this->tpldata[$blockname][] = $vararray; + $s_num_rows = sizeof($this->tpldata[$blockname]); // Set S_NUM_ROWS foreach ($this->tpldata[$blockname] as &$mod_block) { - $mod_block['S_NUM_ROWS'] = sizeof($this->tpldata[$blockname]); + $mod_block['S_NUM_ROWS'] = $s_num_rows; } } @@ -206,6 +200,22 @@ class context } /** + * Assign key variable pairs from an array to a whole specified block loop + * + * @param string $blockname Name of block to assign $block_vars_array to + * @param array $block_vars_array An array of hashes of variable name => value pairs + */ + public function assign_block_vars_array($blockname, array $block_vars_array) + { + foreach ($block_vars_array as $vararray) + { + $this->assign_block_vars($blockname, $vararray); + } + + return true; + } + + /** * Change already assigned key variable pair (one-dimensional - single loop entry) * * An example of how to use this function: @@ -285,7 +295,7 @@ class context // Search array to get correct position list($search_key, $search_value) = @each($key); - $key = NULL; + $key = null; foreach ($block as $i => $val_ary) { if ($val_ary[$search_key] === $search_value) @@ -296,7 +306,7 @@ class context } // key/value pair not found - if ($key === NULL) + if ($key === null) { return false; } diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php index cf38bba522..87ae7a9766 100644 --- a/phpBB/phpbb/template/template.php +++ b/phpBB/phpbb/template/template.php @@ -9,14 +9,6 @@ namespace phpbb\template; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - interface template { @@ -140,6 +132,14 @@ interface template public function assign_block_vars($blockname, array $vararray); /** + * Assign key variable pairs from an array to a whole specified block loop + * @param string $blockname Name of block to assign $block_vars_array to + * @param array $block_vars_array An array of hashes of variable name => value pairs + * @return \phpbb\template\template $this + */ + public function assign_block_vars_array($blockname, array $block_vars_array); + + /** * Change already assigned key variable pair (one-dimensional - single loop entry) * * An example of how to use this function: diff --git a/phpBB/phpbb/template/twig/definition.php b/phpBB/phpbb/template/twig/definition.php index 2490a43f81..945c46675e 100644 --- a/phpBB/phpbb/template/twig/definition.php +++ b/phpBB/phpbb/template/twig/definition.php @@ -10,14 +10,6 @@ namespace phpbb\template\twig; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * This class holds all DEFINE variables from the current page load */ class definition diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index a6c0e476f0..aa55f1e011 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -9,25 +9,17 @@ namespace phpbb\template\twig; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class environment extends \Twig_Environment { - /** @var array */ - protected $phpbb_extensions; - /** @var \phpbb\config\config */ protected $phpbb_config; /** @var \phpbb\path_helper */ protected $phpbb_path_helper; + /** @var \phpbb\extension\manager */ + protected $extension_manager; + /** @var string */ protected $phpbb_root_path; @@ -41,18 +33,19 @@ class environment extends \Twig_Environment * Constructor * * @param \phpbb\config\config $phpbb_config - * @param array $phpbb_extensions Array of enabled extensions (name => path) * @param \phpbb\path_helper + * @param \phpbb\extension\manager * @param string $phpbb_root_path * @param Twig_LoaderInterface $loader * @param array $options Array of options to pass to Twig */ - public function __construct($phpbb_config, $phpbb_extensions, \phpbb\path_helper $path_helper, \Twig_LoaderInterface $loader = null, $options = array()) + public function __construct($phpbb_config, \phpbb\path_helper $path_helper, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array()) { $this->phpbb_config = $phpbb_config; - $this->phpbb_extensions = $phpbb_extensions; $this->phpbb_path_helper = $path_helper; + $this->extension_manager = $extension_manager; + $this->phpbb_root_path = $this->phpbb_path_helper->get_phpbb_root_path(); $this->web_root_path = $this->phpbb_path_helper->get_web_root_path(); @@ -68,7 +61,7 @@ class environment extends \Twig_Environment */ public function get_phpbb_extensions() { - return $this->phpbb_extensions; + return ($this->extension_manager) ? $this->extension_manager->all_enabled() : array(); } /** diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index 1ddb97369e..6847dbd9f8 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class extension extends \Twig_Extension { /** @var \phpbb\template\context */ @@ -48,11 +40,11 @@ class extension extends \Twig_Extension return 'phpbb'; } - /** - * Returns the token parser instance to add to the existing list. - * - * @return array An array of Twig_TokenParser instances - */ + /** + * Returns the token parser instance to add to the existing list. + * + * @return array An array of Twig_TokenParser instances + */ public function getTokenParsers() { return array( @@ -66,36 +58,36 @@ class extension extends \Twig_Extension ); } - /** - * Returns a list of filters to add to the existing list. - * - * @return array An array of filters - */ - public function getFilters() - { + /** + * Returns a list of filters to add to the existing list. + * + * @return array An array of filters + */ + public function getFilters() + { return array( new \Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), new \Twig_SimpleFilter('addslashes', 'addslashes'), ); - } - - /** - * Returns a list of global functions to add to the existing list. - * - * @return array An array of global functions - */ - public function getFunctions() - { + } + + /** + * Returns a list of global functions to add to the existing list. + * + * @return array An array of global functions + */ + public function getFunctions() + { return array( new \Twig_SimpleFunction('lang', array($this, 'lang')), ); } - /** - * Returns a list of operators to add to the existing list. - * - * @return array An array of operators - */ + /** + * Returns a list of operators to add to the existing list. + * + * @return array An array of operators + */ public function getOperators() { return array( @@ -126,19 +118,19 @@ class extension extends \Twig_Extension 'mod' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), ), ); - } + } /** - * Grabs a subset of a loop - * - * @param Twig_Environment $env A Twig_Environment instance - * @param mixed $item A variable - * @param integer $start Start of the subset - * @param integer $end End of the subset - * @param Boolean $preserveKeys Whether to preserve key or not (when the input is an array) - * - * @return mixed The sliced variable - */ + * Grabs a subset of a loop + * + * @param Twig_Environment $env A Twig_Environment instance + * @param mixed $item A variable + * @param integer $start Start of the subset + * @param integer $end End of the subset + * @param Boolean $preserveKeys Whether to preserve key or not (when the input is an array) + * + * @return mixed The sliced variable + */ function loop_subset(\Twig_Environment $env, $item, $start, $end = null, $preserveKeys = false) { // We do almost the same thing as Twig's slice (array_slice), except when $end is positive diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php index d832fbf84e..f4efc58540 100644 --- a/phpBB/phpbb/template/twig/lexer.php +++ b/phpBB/phpbb/template/twig/lexer.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class lexer extends \Twig_Lexer { public function tokenize($code, $filename = null) @@ -76,6 +68,12 @@ class lexer extends \Twig_Lexer ); // Fix tokens that may have inline variables (e.g. <!-- DEFINE $TEST = '{FOO}') + $code = $this->strip_surrounding_quotes(array( + 'INCLUDE', + 'INCLUDEPHP', + 'INCLUDEJS', + 'INCLUDECSS', + ), $code); $code = $this->fix_inline_variable_tokens(array( 'DEFINE \$[a-zA-Z0-9_]+ =', 'INCLUDE', @@ -83,6 +81,12 @@ class lexer extends \Twig_Lexer 'INCLUDEJS', 'INCLUDECSS', ), $code); + $code = $this->add_surrounding_quotes(array( + 'INCLUDE', + 'INCLUDEPHP', + 'INCLUDEJS', + 'INCLUDECSS', + ), $code); // Fix our BEGIN statements $code = $this->fix_begin_tokens($code); @@ -116,9 +120,29 @@ class lexer extends \Twig_Lexer } /** + * Strip surrounding quotes + * + * First step to fix tokens that may have inline variables + * E.g. <!-- INCLUDE '{TEST}.html' to <!-- INCLUDE {TEST}.html + * + * @param array $tokens array of tokens to search for (imploded to a regular expression) + * @param string $code + * @return string + */ + protected function strip_surrounding_quotes($tokens, $code) + { + // Remove matching quotes at the beginning/end if a statement; + // E.g. 'asdf'"' -> asdf'" + // E.g. "asdf'"" -> asdf'" + // E.g. 'asdf'" -> 'asdf'" + return preg_replace('#<!-- (' . implode('|', $tokens) . ') (([\'"])?(.*?)\1) -->#', '<!-- $1 $2 -->', $code); + } + + /** * Fix tokens that may have inline variables * - * E.g. <!-- INCLUDE {TEST}.html + * Second step to fix tokens that may have inline variables + * E.g. <!-- INCLUDE '{TEST}.html' to <!-- INCLUDE ' ~ {TEST} ~ '.html * * @param array $tokens array of tokens to search for (imploded to a regular expression) * @param string $code @@ -128,23 +152,31 @@ class lexer extends \Twig_Lexer { $callback = function($matches) { - // Remove matching quotes at the beginning/end if a statement; - // E.g. 'asdf'"' -> asdf'" - // E.g. "asdf'"" -> asdf'" - // E.g. 'asdf'" -> 'asdf'" - $matches[2] = preg_replace('#^([\'"])?(.*?)\1$#', '$2', $matches[2]); - // Replace template variables with start/end to parse variables (' ~ TEST ~ '.html) $matches[2] = preg_replace('#{([a-zA-Z0-9_\.$]+)}#', "'~ \$1 ~'", $matches[2]); - // Surround the matches in single quotes ('' ~ TEST ~ '.html') - return "<!-- {$matches[1]} '{$matches[2]}' -->"; + return "<!-- {$matches[1]} {$matches[2]} -->"; }; return preg_replace_callback('#<!-- (' . implode('|', $tokens) . ') (.+?) -->#', $callback, $code); } /** + * Add surrounding quotes + * + * Last step to fix tokens that may have inline variables + * E.g. <!-- INCLUDE '{TEST}.html' to <!-- INCLUDE '' ~ {TEST} ~ '.html' + * + * @param array $tokens array of tokens to search for (imploded to a regular expression) + * @param string $code + * @return string + */ + protected function add_surrounding_quotes($tokens, $code) + { + return preg_replace('#<!-- (' . implode('|', $tokens) . ') (.+?) -->#', '<!-- $1 \'$2\' -->', $code); + } + + /** * Fix begin tokens (convert our BEGIN to Twig for) * * Not meant to be used outside of this context, public because the anonymous function calls this diff --git a/phpBB/phpbb/template/twig/loader.php b/phpBB/phpbb/template/twig/loader.php index 910061dc0f..e01e9de467 100644 --- a/phpBB/phpbb/template/twig/loader.php +++ b/phpBB/phpbb/template/twig/loader.php @@ -10,14 +10,6 @@ namespace phpbb\template\twig; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Twig Template loader * @package phpBB3 */ diff --git a/phpBB/phpbb/template/twig/node/definenode.php b/phpBB/phpbb/template/twig/node/definenode.php index ec084d0f7d..6a9969f8c6 100644 --- a/phpBB/phpbb/template/twig/node/definenode.php +++ b/phpBB/phpbb/template/twig/node/definenode.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\node; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class definenode extends \Twig_Node { diff --git a/phpBB/phpbb/template/twig/node/event.php b/phpBB/phpbb/template/twig/node/event.php index 202db775ee..7a1181a866 100644 --- a/phpBB/phpbb/template/twig/node/event.php +++ b/phpBB/phpbb/template/twig/node/event.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\node; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class event extends \Twig_Node { @@ -57,10 +49,10 @@ class event extends \Twig_Node // templates on page load rather than at compile. This is // slower, but makes developing extensions easier (no need to // purge the cache when a new event template file is added) - $compiler - ->write("if (\$this->env->getLoader()->exists('@{$ext_namespace}/{$location}.html')) {\n") - ->indent() - ; + $compiler + ->write("if (\$this->env->getLoader()->exists('@{$ext_namespace}/{$location}.html')) {\n") + ->indent() + ; } if (defined('DEBUG') || $this->environment->getLoader()->exists('@' . $ext_namespace . '/' . $location . '.html')) @@ -79,7 +71,7 @@ class event extends \Twig_Node { $compiler ->outdent() - ->write("}\n\n") + ->write("}\n\n") ; } } diff --git a/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php b/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php index 48d8b814b8..f3bbfa6691 100644 --- a/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php +++ b/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\node\expression\binary; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class equalequal extends \Twig_Node_Expression_Binary { diff --git a/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php b/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php index 87585dfb4c..c9c2687e08 100644 --- a/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php +++ b/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\node\expression\binary; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class notequalequal extends \Twig_Node_Expression_Binary { diff --git a/phpBB/phpbb/template/twig/node/includenode.php b/phpBB/phpbb/template/twig/node/includenode.php index 77fe7f3acb..d9b45d6407 100644 --- a/phpBB/phpbb/template/twig/node/includenode.php +++ b/phpBB/phpbb/template/twig/node/includenode.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\node; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class includenode extends \Twig_Node_Include { diff --git a/phpBB/phpbb/template/twig/node/includephp.php b/phpBB/phpbb/template/twig/node/includephp.php index 4024cf0cc8..3f4621c0a9 100644 --- a/phpBB/phpbb/template/twig/node/includephp.php +++ b/phpBB/phpbb/template/twig/node/includephp.php @@ -9,21 +9,13 @@ namespace phpbb\template\twig\node; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class includephp extends \Twig_Node { /** @var Twig_Environment */ protected $environment; - public function __construct(\Twig_Node_Expression $expr, \phpbb\template\twig\environment $environment, $ignoreMissing = false, $lineno, $tag = null) + public function __construct(\Twig_Node_Expression $expr, \phpbb\template\twig\environment $environment, $lineno, $ignoreMissing = false, $tag = null) { $this->environment = $environment; diff --git a/phpBB/phpbb/template/twig/node/php.php b/phpBB/phpbb/template/twig/node/php.php index b37759303d..2b18551266 100644 --- a/phpBB/phpbb/template/twig/node/php.php +++ b/phpBB/phpbb/template/twig/node/php.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\node; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class php extends \Twig_Node { diff --git a/phpBB/phpbb/template/twig/tokenparser/defineparser.php b/phpBB/phpbb/template/twig/tokenparser/defineparser.php index 688afec191..8484f2e81a 100644 --- a/phpBB/phpbb/template/twig/tokenparser/defineparser.php +++ b/phpBB/phpbb/template/twig/tokenparser/defineparser.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\tokenparser; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class defineparser extends \Twig_TokenParser { @@ -38,6 +30,13 @@ class defineparser extends \Twig_TokenParser $stream->next(); $value = $this->parser->getExpressionParser()->parseExpression(); + if ($value instanceof \Twig_Node_Expression_Name) + { + // This would happen if someone improperly formed their DEFINE syntax + // e.g. <!-- DEFINE $VAR = foo --> + throw new \Twig_Error_Syntax('Invalid DEFINE', $token->getLine(), $this->parser->getFilename()); + } + $stream->expect(\Twig_Token::BLOCK_END_TYPE); } else { $capture = true; diff --git a/phpBB/phpbb/template/twig/tokenparser/event.php b/phpBB/phpbb/template/twig/tokenparser/event.php index 7cf4000909..8864e879f8 100644 --- a/phpBB/phpbb/template/twig/tokenparser/event.php +++ b/phpBB/phpbb/template/twig/tokenparser/event.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\tokenparser; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class event extends \Twig_TokenParser { diff --git a/phpBB/phpbb/template/twig/tokenparser/includejs.php b/phpBB/phpbb/template/twig/tokenparser/includejs.php index 30a99f3279..0e46915b86 100644 --- a/phpBB/phpbb/template/twig/tokenparser/includejs.php +++ b/phpBB/phpbb/template/twig/tokenparser/includejs.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\tokenparser; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class includejs extends \Twig_TokenParser { diff --git a/phpBB/phpbb/template/twig/tokenparser/includeparser.php b/phpBB/phpbb/template/twig/tokenparser/includeparser.php index 715c0ec84d..d351f1b4cd 100644 --- a/phpBB/phpbb/template/twig/tokenparser/includeparser.php +++ b/phpBB/phpbb/template/twig/tokenparser/includeparser.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\tokenparser; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class includeparser extends \Twig_TokenParser_Include { diff --git a/phpBB/phpbb/template/twig/tokenparser/includephp.php b/phpBB/phpbb/template/twig/tokenparser/includephp.php index d906837590..1b3d1742e3 100644 --- a/phpBB/phpbb/template/twig/tokenparser/includephp.php +++ b/phpBB/phpbb/template/twig/tokenparser/includephp.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\tokenparser; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class includephp extends \Twig_TokenParser { @@ -43,7 +35,7 @@ class includephp extends \Twig_TokenParser $stream->expect(\Twig_Token::BLOCK_END_TYPE); - return new \phpbb\template\twig\node\includephp($expr, $this->parser->getEnvironment(), $ignoreMissing, $token->getLine(), $this->getTag()); + return new \phpbb\template\twig\node\includephp($expr, $this->parser->getEnvironment(), $token->getLine(), $ignoreMissing, $this->getTag()); } /** diff --git a/phpBB/phpbb/template/twig/tokenparser/php.php b/phpBB/phpbb/template/twig/tokenparser/php.php index e4f70fb9b1..b427969e2d 100644 --- a/phpBB/phpbb/template/twig/tokenparser/php.php +++ b/phpBB/phpbb/template/twig/tokenparser/php.php @@ -9,14 +9,6 @@ namespace phpbb\template\twig\tokenparser; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class php extends \Twig_TokenParser { @@ -53,5 +45,5 @@ class php extends \Twig_TokenParser public function getTag() { return 'PHP'; - } + } } diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php index 9df9310427..83630f5992 100644 --- a/phpBB/phpbb/template/twig/twig.php +++ b/phpBB/phpbb/template/twig/twig.php @@ -10,14 +10,6 @@ namespace phpbb\template\twig; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Twig Template class. * @package phpBB3 */ @@ -102,8 +94,8 @@ class twig extends \phpbb\template\base $this->twig = new \phpbb\template\twig\environment( $this->config, - ($this->extension_manager) ? $this->extension_manager->all_enabled() : array(), $this->path_helper, + $this->extension_manager, $loader, array( 'cache' => (defined('IN_INSTALL')) ? false : $this->cachepath, diff --git a/phpBB/phpbb/tree/nestedset.php b/phpBB/phpbb/tree/nestedset.php index 171dae4d14..9aaee9e468 100644 --- a/phpBB/phpbb/tree/nestedset.php +++ b/phpBB/phpbb/tree/nestedset.php @@ -9,17 +9,9 @@ namespace phpbb\tree; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - abstract class nestedset implements \phpbb\tree\tree_interface { - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\lock\db */ @@ -60,7 +52,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface /** * Construct * - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\lock\db $lock Lock class used to lock the table when moving forums around * @param string $table_name Table name * @param string $message_prefix Prefix for the messages thrown by exceptions @@ -68,7 +60,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface * @param array $item_basic_data Array with basic item data that is stored in item_parents * @param array $columns Array with column names to overwrite */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\lock\db $lock, $table_name, $message_prefix = '', $sql_where = '', $item_basic_data = array(), $columns = array()) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\lock\db $lock, $table_name, $message_prefix = '', $sql_where = '', $item_basic_data = array(), $columns = array()) { $this->db = $db; $this->lock = $lock; @@ -672,6 +664,32 @@ abstract class nestedset implements \phpbb\tree\tree_interface } /** + * Get all items from the tree + * + * @param bool $order_asc Order the items ascending by their left_id + * @return array Array of items (containing all columns from the item table) + * ID => Item data + */ + public function get_all_tree_data($order_asc = true) + { + $rows = array(); + + $sql = 'SELECT * + FROM ' . $this->table_name . ' ' . + $this->get_sql_where('WHERE') . ' + ORDER BY ' . $this->column_left_id . ' ' . ($order_asc ? 'ASC' : 'DESC'); + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $rows[(int) $row[$this->column_item_id]] = $row; + } + $this->db->sql_freeresult($result); + + return $rows; + } + + /** * Remove a subset from the nested set * * @param array $subset_items Subset of items to remove diff --git a/phpBB/phpbb/tree/nestedset_forum.php b/phpBB/phpbb/tree/nestedset_forum.php index 2fee5b097e..5973b0b6d9 100644 --- a/phpBB/phpbb/tree/nestedset_forum.php +++ b/phpBB/phpbb/tree/nestedset_forum.php @@ -9,24 +9,16 @@ namespace phpbb\tree; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - class nestedset_forum extends \phpbb\tree\nestedset { /** * Construct * - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\lock\db $lock Lock class used to lock the table when moving forums around * @param string $table_name Table name */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\lock\db $lock, $table_name) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\lock\db $lock, $table_name) { parent::__construct( $db, diff --git a/phpBB/phpbb/tree/tree_interface.php b/phpBB/phpbb/tree/tree_interface.php index 162c1e5e29..90ec27e024 100644 --- a/phpBB/phpbb/tree/tree_interface.php +++ b/phpBB/phpbb/tree/tree_interface.php @@ -9,14 +9,6 @@ namespace phpbb\tree; -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - interface tree_interface { /** diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index f97cc94d40..18b7a3d096 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -10,14 +10,6 @@ namespace phpbb; /** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Base user class * * This is the overarching class which contains (through session extend) @@ -44,7 +36,7 @@ class user extends \phpbb\session var $img_array = array(); // Able to add new options (up to id 31) - var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'popuppm' => 10, 'sig_bbcode' => 15, 'sig_smilies' => 16, 'sig_links' => 17); + var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'sig_bbcode' => 15, 'sig_smilies' => 16, 'sig_links' => 17); /** * Constructor to set the lang path @@ -151,9 +143,17 @@ class user extends \phpbb\session * that are absolutely needed globally using this * event. Use local events otherwise. * @var mixed style_id Style we are going to display - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('user_data', 'user_lang_name', 'user_date_format', 'user_timezone', 'lang_set', 'lang_set_ext', 'style_id'); + $vars = array( + 'user_data', + 'user_lang_name', + 'user_date_format', + 'user_timezone', + 'lang_set', + 'lang_set_ext', + 'style_id', + ); extract($phpbb_dispatcher->trigger_event('core.user_setup', compact($vars))); $this->data = $user_data; @@ -191,7 +191,7 @@ class user extends \phpbb\session unset($lang_set_ext); $style_request = request_var('style', 0); - if ($style_request && $auth->acl_get('a_styles') && !defined('ADMIN_START')) + if ($style_request && (!$config['override_user_style'] || $auth->acl_get('a_styles')) && !defined('ADMIN_START')) { global $SID, $_EXTRA_URL; @@ -212,6 +212,19 @@ class user extends \phpbb\session $this->style = $db->sql_fetchrow($result); $db->sql_freeresult($result); + // Fallback to user's standard style + if (!$this->style && $style_id != $this->data['user_style']) + { + $style_id = $this->data['user_style']; + + $sql = 'SELECT * + FROM ' . STYLES_TABLE . " s + WHERE s.style_id = $style_id"; + $result = $db->sql_query($sql, 3600); + $this->style = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + } + // User has wrong style if (!$this->style && $style_id == $this->data['user_style']) { @@ -343,7 +356,6 @@ class user extends \phpbb\session } } - // Does the user need to change their password? If so, redirect to the // ucp profile reg_details page ... of course do not redirect if we're already in the ucp if (!defined('IN_ADMIN') && !defined('ADMIN_START') && $config['chg_passforce'] && !empty($this->data['is_registered']) && $auth->acl_get('u_chgpasswd') && $this->data['user_passchg'] < time() - ($config['chg_passforce'] * 86400)) @@ -627,18 +639,20 @@ class user extends \phpbb\session else if ($this->lang_name == basename($config['default_lang'])) { // Fall back to the English Language + $reset_lang_name = $this->lang_name; $this->lang_name = 'en'; $this->set_lang($lang, $help, $lang_file, $use_db, $use_help, $ext_name); + $this->lang_name = $reset_lang_name; } else if ($this->lang_name == $this->data['user_lang']) { // Fall back to the board default language + $reset_lang_name = $this->lang_name; $this->lang_name = basename($config['default_lang']); $this->set_lang($lang, $help, $lang_file, $use_db, $use_help, $ext_name); + $this->lang_name = $reset_lang_name; } - // Reset the lang name - $this->lang_name = (file_exists($lang_path . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']); return; } diff --git a/phpBB/phpbb/user_loader.php b/phpBB/phpbb/user_loader.php index 78620ab1b9..9179572277 100644 --- a/phpBB/phpbb/user_loader.php +++ b/phpBB/phpbb/user_loader.php @@ -10,13 +10,6 @@ namespace phpbb; /** -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * User loader class * * This handles loading users from the database and @@ -26,7 +19,7 @@ if (!defined('IN_PHPBB')) */ class user_loader { - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db = null; /** @var string */ @@ -48,12 +41,12 @@ class user_loader /** * User loader constructor * - * @param \phpbb\db\driver\driver $db A database connection + * @param \phpbb\db\driver\driver_interface $db A database connection * @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $php_ext php file extension * @param string $users_table The name of the database table (phpbb_users) */ - public function __construct(\phpbb\db\driver\driver $db, $phpbb_root_path, $php_ext, $users_table) + public function __construct(\phpbb\db\driver\driver_interface $db, $phpbb_root_path, $php_ext, $users_table) { $this->db = $db; diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php new file mode 100644 index 0000000000..e2fdf6ce63 --- /dev/null +++ b/phpBB/phpbb/version_helper.php @@ -0,0 +1,271 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb; + +/** + * Class to handle version checking and comparison + */ +class version_helper +{ + /** + * @var string Host + */ + protected $host = 'version.phpbb.com'; + + /** + * @var string Path to file + */ + protected $path = '/phpbb'; + + /** + * @var string File name + */ + protected $file = 'versions.json'; + + /** + * @var string Current version installed + */ + protected $current_version; + + /** + * @var null|string Null to not force stability, 'unstable' or 'stable' to + * force the corresponding stability + */ + protected $force_stability; + + /** @var \phpbb\cache\service */ + protected $cache; + + /** @var \phpbb\config\config */ + protected $config; + + /** @var \phpbb\user */ + protected $user; + + /** + * Constructor + * + * @param \phpbb\cache\service $cache + * @param \phpbb\config\config $config + * @param \phpbb\user $user + */ + public function __construct(\phpbb\cache\service $cache, \phpbb\config\config $config, \phpbb\user $user) + { + $this->cache = $cache; + $this->config = $config; + $this->user = $user; + + if (defined('PHPBB_QA')) + { + $this->force_stability = 'unstable'; + } + + $this->current_version = $this->config['version']; + } + + /** + * Set location to the file + * + * @param string $host Host (e.g. version.phpbb.com) + * @param string $path Path to file (e.g. /phpbb) + * @param string $file File name (Default: versions.json) + * @return version_helper + */ + public function set_file_location($host, $path, $file = 'versions.json') + { + $this->host = $host; + $this->path = $path; + $this->file = $file; + + return $this; + } + + /** + * Set current version + * + * @param string $version The current version + * @return version_helper + */ + public function set_current_version($version) + { + $this->current_version = $version; + + return $this; + } + + /** + * Over-ride the stability to force check to include unstable versions + * + * @param null|string Null to not force stability, 'unstable' or 'stable' to + * force the corresponding stability + * @return version_helper + */ + public function force_stability($stability) + { + $this->force_stability = $stability; + + return $this; + } + + /** + * Wrapper for version_compare() that allows using uppercase A and B + * for alpha and beta releases. + * + * See http://www.php.net/manual/en/function.version-compare.php + * + * @param string $version1 First version number + * @param string $version2 Second version number + * @param string $operator Comparison operator (optional) + * + * @return mixed Boolean (true, false) if comparison operator is specified. + * Integer (-1, 0, 1) otherwise. + */ + public function compare($version1, $version2, $operator = null) + { + return phpbb_version_compare($version1, $version2, $operator); + } + + /** + * Check whether or not a version is "stable" + * + * Stable means only numbers OR a pl release + * + * @param string $version + * @return bool Bool true or false + */ + public function is_stable($version) + { + $matches = false; + preg_match('/^[\d\.]+/', $version, $matches); + + if (empty($matches[0])) + { + return false; + } + + return $this->compare($version, $matches[0], '>='); + } + + /** + * Gets the latest version for the current branch the user is on + * + * @param bool $force_update Ignores cached data. Defaults to false. + * @return string + * @throws \RuntimeException + */ + public function get_latest_on_current_branch($force_update = false) + { + $versions = $this->get_versions_matching_stability($force_update); + + $self = $this; + $current_version = $this->current_version; + + // Filter out any versions less than to the current version + $versions = array_filter($versions, function($data) use ($self, $current_version) { + return $self->compare($data['current'], $current_version, '>='); + }); + + // Get the lowest version from the previous list. + return array_reduce($versions, function($value, $data) use ($self) { + if ($value === null || $self->compare($data['current'], $value, '<')) + { + return $data['current']; + } + + return $value; + }); + } + + /** + * Obtains the latest version information + * + * @param bool $force_update Ignores cached data. Defaults to false. + * @return string + * @throws \RuntimeException + */ + public function get_suggested_updates($force_update = false) + { + $versions = $this->get_versions_matching_stability($force_update); + + $self = $this; + $current_version = $this->current_version; + + // Filter out any versions less than or equal to the current version + return array_filter($versions, function($data) use ($self, $current_version) { + return $self->compare($data['current'], $current_version, '>'); + }); + } + + /** + * Obtains the latest version information matching the stability of the current install + * + * @param bool $force_update Ignores cached data. Defaults to false. + * @return string Version info + * @throws \RuntimeException + */ + public function get_versions_matching_stability($force_update = false) + { + $info = $this->get_versions($force_update); + + if ($this->force_stability !== null) + { + return ($this->force_stability === 'unstable') ? $info['unstable'] : $info['stable']; + } + + return ($this->is_stable($this->current_version)) ? $info['stable'] : $info['unstable']; + } + + /** + * Obtains the latest version information + * + * @param bool $force_update Ignores cached data. Defaults to false. + * @return string Version info, includes stable and unstable data + * @throws \RuntimeException + */ + public function get_versions($force_update = false) + { + $cache_file = 'versioncheck_' . $this->host . $this->path . $this->file; + + $info = $this->cache->get($cache_file); + + if ($info === false || $force_update) + { + $errstr = $errno = ''; + $info = get_remote_file($this->host, $this->path, $this->file, $errstr, $errno); + + if (!empty($errstr)) + { + throw new \RuntimeException($errstr); + } + + $info = json_decode($info, true); + + if (empty($info['stable']) || empty($info['unstable'])) + { + $this->user->add_lang('acp/common'); + + throw new \RuntimeException($this->user->lang('VERSIONCHECK_FAIL')); + } + + // Replace & with & on announcement links + foreach ($info as $stability => $branches) + { + foreach ($branches as $branch => $branch_data) + { + $info[$stability][$branch]['announcement'] = str_replace('&', '&', $branch_data['announcement']); + } + } + + $this->cache->put($cache_file, $info, 86400); // 24 hours + } + + return $info; + } +} diff --git a/phpBB/posting.php b/phpBB/posting.php index 1609382551..cfd6524e62 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -42,7 +42,7 @@ $refresh = (isset($_POST['add_file']) || isset($_POST['delete_file']) || isset($ $mode = request_var('mode', ''); // If the user is not allowed to delete the post, we try to soft delete it, so we overwrite the mode here. -if ($mode == 'delete' && (($confirm && !$request->is_set_post('delete_permanent')) || !$auth->acl_get('m_delete', $forum_id))) +if ($mode == 'delete' && (($confirm && !$request->is_set_post('delete_permanent')) || !$auth->acl_gets('f_delete', 'm_delete', $forum_id))) { $mode = 'soft_delete'; } @@ -52,7 +52,7 @@ $current_time = time(); /** * This event allows you to alter the above parameters, such as submit and mode -* +* * Note: $refresh must be true to retain previously submitted form data. * * Note: The template class will not work properly until $user->setup() is @@ -74,15 +74,30 @@ $current_time = time(); * viewtopic or viewforum depending on if the user * is posting a new topic or editing a post) * @var bool refresh Whether or not to retain previously submitted data -* @var string mode What action to take if the form has been sumitted +* @var string mode What action to take if the form has been submitted * post|reply|quote|edit|delete|bump|smilies|popup * @var array error Any error strings; a non-empty array aborts * form submission. * NOTE: Should be actual language strings, NOT * language keys. -* @since 3.1-A1 +* @since 3.1.0-a1 */ -$vars = array('post_id', 'topic_id', 'forum_id', 'draft_id', 'lastclick', 'submit', 'preview', 'save', 'load', 'delete', 'cancel', 'refresh', 'mode', 'error'); +$vars = array( + 'post_id', + 'topic_id', + 'forum_id', + 'draft_id', + 'lastclick', + 'submit', + 'preview', + 'save', + 'load', + 'delete', + 'cancel', + 'refresh', + 'mode', + 'error', +); extract($phpbb_dispatcher->trigger_event('core.modify_posting_parameters', compact($vars))); // Was cancel pressed? If so then redirect to the appropriate page @@ -255,8 +270,18 @@ if (!$auth->acl_get('f_read', $forum_id)) { trigger_error('USER_CANNOT_READ'); } + $message = $user->lang['LOGIN_EXPLAIN_POST']; - login_box('', $user->lang['LOGIN_EXPLAIN_POST']); + if ($request->is_ajax()) + { + $json = new phpbb\json_response(); + $json->send(array( + 'title' => $user->lang['INFORMATION'], + 'message' => $message, + )); + } + + login_box('', $message); } // Permission to do the action asked? @@ -326,8 +351,18 @@ if (!$is_authed) { trigger_error('USER_CANNOT_' . strtoupper($check_auth)); } + $message = $user->lang['LOGIN_EXPLAIN_' . strtoupper($mode)]; + + if ($request->is_ajax()) + { + $json = new phpbb\json_response(); + $json->send(array( + 'title' => $user->lang['INFORMATION'], + 'message' => $message, + )); + } - login_box('', $user->lang['LOGIN_EXPLAIN_' . strtoupper($mode)]); + login_box('', $message); } // Is the user able to post within this forum? @@ -381,13 +416,17 @@ if ($mode == 'delete' || $mode == 'soft_delete') if ($mode == 'bump') { if ($bump_time = bump_topic_allowed($forum_id, $post_data['topic_bumped'], $post_data['topic_last_post_time'], $post_data['topic_poster'], $post_data['topic_last_poster_id']) - && check_link_hash(request_var('hash', ''), "topic_{$post_data['topic_id']}")) + && check_link_hash(request_var('hash', ''), "topic_{$post_data['topic_id']}")) { $meta_url = phpbb_bump_topic($forum_id, $topic_id, $post_data, $current_time); meta_refresh(3, $meta_url); + $message = $user->lang['TOPIC_BUMPED']; - $message = $user->lang['TOPIC_BUMPED'] . '<br /><br />' . $user->lang('VIEW_MESSAGE', '<a href="' . $meta_url . '">', '</a>'); - $message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>'); + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('VIEW_MESSAGE', '<a href="' . $meta_url . '">', '</a>'); + $message .= '<br /><br />' . $user->lang('RETURN_FORUM', '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>'); + } trigger_error($message); } @@ -452,6 +491,8 @@ if ($mode == 'edit') $orig_poll_options_size = sizeof($post_data['poll_options']); $message_parser = new parse_message(); +$plupload = $phpbb_container->get('plupload'); +$message_parser->set_plupload($plupload); if (isset($post_data['post_text'])) { @@ -478,7 +519,7 @@ $message_parser->get_submitted_attachment_data($post_data['poster_id']); if ($post_data['post_attachment'] && !$submit && !$refresh && !$preview && $mode == 'edit') { // Do not change to SELECT * - $sql = 'SELECT attach_id, is_orphan, attach_comment, real_filename + $sql = 'SELECT attach_id, is_orphan, attach_comment, real_filename, filesize FROM ' . ATTACHMENTS_TABLE . " WHERE post_msg_id = $post_id AND in_message = 0 @@ -815,8 +856,13 @@ if ($submit || $preview || $refresh) // We make sure nobody else made exactly the same change // we're about to submit by also checking $message_md5 != $post_data['post_checksum'] - if (($edit_post_message_checksum !== '' && $edit_post_message_checksum != $post_data['post_checksum'] && $message_md5 != $post_data['post_checksum']) - || ($edit_post_subject_checksum !== '' && $edit_post_subject_checksum != $post_data['post_subject_md5'] && md5($post_data['post_subject']) != $post_data['post_subject_md5'])) + if ($edit_post_message_checksum !== '' && + $edit_post_message_checksum != $post_data['post_checksum'] && + $message_md5 != $post_data['post_checksum'] + || + $edit_post_subject_checksum !== '' && + $edit_post_subject_checksum != $post_data['post_subject_md5'] && + md5($post_data['post_subject']) != $post_data['post_subject_md5']) { if (topic_review($topic_id, $forum_id, 'post_review_edit', $post_id)) { @@ -1182,17 +1228,11 @@ if ($submit || $preview || $refresh) meta_refresh(10, $redirect_url); $message = ($mode == 'edit') ? $user->lang['POST_EDITED_MOD'] : $user->lang['POST_STORED_MOD']; $message .= (($user->data['user_id'] == ANONYMOUS) ? '' : ' '. $user->lang['POST_APPROVAL_NOTIFY']); - } - else - { - meta_refresh(3, $redirect_url); - - $message = ($mode == 'edit') ? 'POST_EDITED' : 'POST_STORED'; - $message = $user->lang[$message] . '<br /><br />' . sprintf($user->lang['VIEW_MESSAGE'], '<a href="' . $redirect_url . '">', '</a>'); + $message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $data['forum_id']) . '">', '</a>'); + trigger_error($message); } - $message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $data['forum_id']) . '">', '</a>'); - trigger_error($message); + redirect($redirect_url); } } } @@ -1514,16 +1554,39 @@ $template->assign_vars(array( 'S_BBCODE_QUOTE' => $quote_status, 'S_POST_ACTION' => $s_action, - 'S_HIDDEN_FIELDS' => $s_hidden_fields) -); + 'S_HIDDEN_FIELDS' => $s_hidden_fields, + 'S_ATTACH_DATA' => json_encode($message_parser->attachment_data), + 'S_IN_POSTING' => true, +)); /** * This event allows you to modify template variables for the posting screen * * @event core.posting_modify_template_vars -* @since 3.1-A1 +* @var array post_data Array with post data +* @var array moderators Array with forum moderators +* @var string mode What action to take if the form is submitted +* post|reply|quote|edit|delete|bump|smilies|popup +* @var string page_title Title of the mode page +* @var bool s_topic_icons Whether or not to show the topic icons +* @var string form_enctype If attachments are allowed for this form the value of +* this is "multipart/form-data" else it is the empty string +* @var string s_action The URL to submit the POST data to +* @var string s_hidden_fields The concatenated input tags of the form's hidden fields +* @since 3.1.0-a1 +* @change 3.1.0-b3 Added vars post_data, moderators, mode, page_title, s_topic_icons, form_enctype, s_action, s_hidden_fields */ -$phpbb_dispatcher->trigger_event('core.posting_modify_template_vars'); +$vars = array( + 'post_data', + 'moderators', + 'mode', + 'page_title', + 's_topic_icons', + 'form_enctype', + 's_action', + 's_hidden_fields', +); +extract($phpbb_dispatcher->trigger_event('core.posting_modify_template_vars', compact($vars))); // Build custom bbcodes array display_custom_bbcodes(); @@ -1551,11 +1614,17 @@ if (($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_ // Show attachment box for adding attachments if true $allowed = ($auth->acl_get('f_attach', $forum_id) && $auth->acl_get('u_attach') && $config['allow_attachments'] && $form_enctype); +if ($allowed) +{ + $max_files = ($auth->acl_get('a_') || $auth->acl_get('m_', $forum_id)) ? 0 : (int) $config['max_attachments']; + $plupload->configure($cache, $template, $s_action, $forum_id, $max_files); +} + // Attachment entry posting_gen_attachment_entry($attachment_data, $filename_data, $allowed); // Output page ... -page_header($page_title, false); +page_header($page_title); $template->set_filenames(array( 'body' => 'posting_body.html') @@ -1583,7 +1652,7 @@ function upload_popup($forum_style = 0) ($forum_style) ? $user->setup('posting', $forum_style) : $user->setup('posting'); - page_header($user->lang['PROGRESS_BAR'], false); + page_header($user->lang['PROGRESS_BAR']); $template->set_filenames(array( 'popup' => 'posting_progress_bar.html') @@ -1604,7 +1673,7 @@ function upload_popup($forum_style = 0) */ function handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $is_soft = false, $soft_delete_reason = '') { - global $user, $db, $auth, $config; + global $user, $db, $auth, $config, $request; global $phpbb_root_path, $phpEx; $perm_check = ($is_soft) ? 'softdelete' : 'delete'; @@ -1650,11 +1719,19 @@ function handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $is_sof add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_POST' : 'LOG_DELETE_POST'), $post_data['post_subject'], $post_username); $meta_info = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id&p=$next_post_id") . "#p$next_post_id"; - $message = $user->lang['POST_DELETED'] . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $meta_info . '">', '</a>'); + $message = $user->lang['POST_DELETED']; + + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('RETURN_TOPIC', '<a href="' . $meta_info . '">', '</a>'); + } } meta_refresh(3, $meta_info); - $message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>'); + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('RETURN_FORUM', '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>'); + } trigger_error($message); } else diff --git a/phpBB/report.php b/phpBB/report.php index 5081f90ad1..f37a2f9d5c 100644 --- a/phpBB/report.php +++ b/phpBB/report.php @@ -136,7 +136,7 @@ else $message .= '<br /><br />' . sprintf($user->lang['RETURN_PM'], '<a href="' . $redirect_url . '">', '</a>'); trigger_error($message); } - + $reported_post_text = $report_data['message_text']; $reported_post_bitfield = $report_data['bbcode_bitfield']; $reported_post_uid = $report_data['bbcode_uid']; @@ -301,8 +301,9 @@ $template->assign_vars(array( 'S_HIDDEN_FIELDS' => (sizeof($s_hidden_fields)) ? $s_hidden_fields : null, 'S_NOTIFY' => $user_notify, - 'S_CAN_NOTIFY' => ($user->data['is_registered']) ? true : false) -); + 'S_CAN_NOTIFY' => ($user->data['is_registered']) ? true : false, + 'S_IN_REPORT' => true, +)); generate_forum_nav($forum_data); diff --git a/phpBB/search.php b/phpBB/search.php index ae573b18e8..dfb53c6896 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -108,7 +108,7 @@ if ($interval && !in_array($search_id, array('unreadposts', 'unanswered', 'activ if ($user->data['user_last_search'] > time() - $interval) { $template->assign_var('S_NO_SEARCH', true); - trigger_error('NO_SEARCH_TIME'); + trigger_error($user->lang('NO_SEARCH_TIME', (int) ($user->data['user_last_search'] + $interval - time()))); } } @@ -120,6 +120,7 @@ $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = ''; gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param); $phpbb_content_visibility = $phpbb_container->get('content.visibility'); +$pagination = $phpbb_container->get('pagination'); if ($keywords || $author || $author_id || $search_id || $submit) { @@ -501,14 +502,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) } // Make sure $start is set to the last page if it exceeds the amount - if ($start < 0) - { - $start = 0; - } - else if ($start >= $total_match_count) - { - $start = floor(($total_match_count - 1) / $per_page) * $per_page; - } + $start = $pagination->validate_start($start, $per_page, $total_match_count); $id_ary = array_slice($id_ary, $start, $per_page); } @@ -533,12 +527,6 @@ if ($keywords || $author || $author_id || $search_id || $submit) $total_match_count = $search->author_search($show_results, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_posts_fid_sql, $topic_id, $author_id_ary, $sql_author_match, $id_ary, $start, $per_page); } - // For some searches we need to print out the "no results" page directly to allow re-sorting/refining the search options. - if (!sizeof($id_ary) && !$search_id) - { - trigger_error('NO_SEARCH_RESULTS'); - } - $sql_where = ''; if (sizeof($id_ary)) @@ -573,9 +561,9 @@ if ($keywords || $author || $author_id || $search_id || $submit) } // define some vars for urls - $hilit = implode('|', explode(' ', preg_replace('#\s+#u', ' ', str_replace(array('+', '-', '|', '(', ')', '"'), ' ', $keywords)))); - // Do not allow *only* wildcard being used for hilight - $hilit = (strspn($hilit, '*') === strlen($hilit)) ? '' : $hilit; + // A single wildcard will make the search results look ugly + $hilit = phpbb_clean_search_string(str_replace(array('+', '-', '|', '(', ')', '"'), ' ', $keywords)); + $hilit = str_replace(' ', '|', $hilit); $u_hilit = urlencode(htmlspecialchars_decode(str_replace('|', ' ', $hilit))); $u_show_results = '&sr=' . $show_results; @@ -600,7 +588,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) $phrase_search_disabled = $search->supports_phrase_search() ? false : true; } - phpbb_generate_template_pagination($template, $u_search, 'pagination', 'start', $total_match_count, $per_page, $start); + $pagination->generate_template_pagination($u_search, 'pagination', 'start', $total_match_count, $per_page, $start); $template->assign_vars(array( 'SEARCH_TITLE' => $l_search_title, @@ -608,7 +596,6 @@ if ($keywords || $author || $author_id || $search_id || $submit) 'SEARCH_WORDS' => $keywords, 'SEARCHED_QUERY' => $search->get_search_query(), 'IGNORED_WORDS' => (sizeof($common_words)) ? implode(' ', $common_words) : '', - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $u_search, $total_match_count, $per_page, $start), 'PHRASE_SEARCH_DISABLED' => $phrase_search_disabled, @@ -694,7 +681,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) * @var string sql_select The SQL SELECT string used by search to get topic data * @var string sql_from The SQL FROM string used by search to get topic data * @var string sql_where The SQL WHERE string used by search to get topic data - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('sql_select', 'sql_from', 'sql_where'); extract($phpbb_dispatcher->trigger_event('core.search_get_topic_data', compact($vars))); @@ -863,7 +850,8 @@ if ($keywords || $author || $author_id || $search_id || $submit) $hilit_array = array_filter(explode('|', $hilit), 'strlen'); foreach ($hilit_array as $key => $value) { - $hilit_array[$key] = str_replace('\*', '\w*?', preg_quote($value, '#')); + $hilit_array[$key] = phpbb_clean_search_string($value); + $hilit_array[$key] = str_replace('\*', '\w*?', preg_quote($hilit_array[$key], '#')); $hilit_array[$key] = preg_replace('#(^|\s)\\\\w\*\?(\s|$)#', '$1\w+?$2', $hilit_array[$key]); } $hilit = implode('|', $hilit_array); @@ -891,7 +879,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) $unread_topic = (isset($topic_tracking_info[$forum_id][$row['topic_id']]) && $row['topic_last_post_time'] > $topic_tracking_info[$forum_id][$row['topic_id']]) ? true : false; - $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $forum_id)) ? true : false; + $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $forum_id)) ? true : false; $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $forum_id)) ? true : false; $topic_deleted = $row['topic_visibility'] == ITEM_DELETED; $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . "&t=$result_topic_id", true, $user->session_id) : ''; @@ -1016,7 +1004,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) * @event core.search_modify_tpl_ary * @var array row Array with topic data * @var array tpl_ary Template block array with topic data - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('row', 'tpl_ary'); extract($phpbb_dispatcher->trigger_event('core.search_modify_tpl_ary', compact($vars))); @@ -1025,7 +1013,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) if ($show_results == 'topics') { - phpbb_generate_template_pagination($template, $view_topic_url, 'searchresults.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); + $pagination->generate_template_pagination($view_topic_url, 'searchresults.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); } } @@ -1033,6 +1021,7 @@ if ($keywords || $author || $author_id || $search_id || $submit) { $template->assign_vars(array( 'SEARCH_TOPIC' => $topic_title, + 'L_RETURN_TO_TOPIC' => $user->lang('RETURN_TO', $topic_title), 'U_SEARCH_TOPIC' => $view_topic_url )); } diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg index 633079e4a6..1beb32685c 100644 --- a/phpBB/styles/prosilver/style.cfg +++ b/phpBB/styles/prosilver/style.cfg @@ -17,9 +17,9 @@ # General Information about this style name = prosilver -copyright = © phpBB Group, 2007 -style_version = 3.1.0-dev -phpbb_version = 3.1.0-dev +copyright = © phpBB Group, 2007 +style_version = 3.1.0-b2 +phpbb_version = 3.1.0-b2 # Defining a different template bitfield # template_bitfield = lNg= diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 394aca749b..bc68e5ae0c 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -8,7 +8,7 @@ * @param int Delay in ms until darkenwrapper's click event is triggered */ phpbb.closeDarkenWrapper = function(delay) { - setTimeout(function() { + phpbbAlertTimer = setTimeout(function() { $('#darkenwrapper').trigger('click'); }, delay); }; @@ -106,6 +106,47 @@ phpbb.addAjaxCallback('mark_topics_read', function(res, update_topic_links) { phpbb.closeDarkenWrapper(3000); }); +// This callback will mark all notifications read +phpbb.addAjaxCallback('notification.mark_all_read', function(res) { + if (typeof res.success !== 'undefined') { + phpbb.markNotifications($('#notification_list li.bg2'), 0); + phpbb.closeDarkenWrapper(3000); + } +}); + +// This callback will mark a notification read +phpbb.addAjaxCallback('notification.mark_read', function(res) { + if (typeof res.success !== 'undefined') { + var unreadCount = Number($('#notification_list_button strong').html()) - 1; + phpbb.markNotifications($(this).parent('li.bg2'), unreadCount); + } +}); + +/** + * Mark notification popup rows as read. + * + * @param {jQuery} el jQuery object(s) to mark read. + * @param {int} unreadCount The new unread notifications count. + */ +phpbb.markNotifications = function(el, unreadCount) { + // Remove the unread status. + el.removeClass('bg2'); + el.find('a.mark_read').remove(); + + // Update the notification link to the real URL. + el.each(function() { + var link = $(this).find('a'); + link.attr('href', link.attr('data-real-url')); + }); + + // Update the unread count. + $('#notification_list_button strong').html(unreadCount); + // Remove the Mark all read link if there are no unread notifications. + if (!unreadCount) { + $('#mark_all_notifications').remove(); + } +}; + // This callback finds the post from the delete link, and removes it. phpbb.addAjaxCallback('post_delete', function() { var el = $(this), @@ -157,7 +198,119 @@ phpbb.addAjaxCallback('zebra', function(res) { } }); +/** + * This callback updates the poll results after voting. + */ +phpbb.addAjaxCallback('vote_poll', function(res) { + if (typeof res.success !== 'undefined') { + var poll = $('.topic_poll'); + var panel = poll.find('.panel'); + var results_visible = poll.find('dl:first-child .resultbar').is(':visible'); + var most_votes = 0; + + // Set min-height to prevent the page from jumping when the content changes + var update_panel_height = function (height) { + var height = (typeof height === 'undefined') ? panel.find('.inner').outerHeight() : height; + panel.css('min-height', height); + }; + update_panel_height(); + + // Remove the View results link + if (!results_visible) { + poll.find('.poll_view_results').hide(500); + } + + if (!res.can_vote) { + poll.find('.polls, .poll_max_votes, .poll_vote, .poll_option_select').fadeOut(500, function () { + poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(); + }); + } else { + // If the user can still vote, simply slide down the results + poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500); + } + + // Get the votes count of the highest poll option + poll.find('[data-poll-option-id]').each(function() { + var option = $(this); + var option_id = option.attr('data-poll-option-id'); + most_votes = (res.vote_counts[option_id] >= most_votes) ? res.vote_counts[option_id] : most_votes; + }); + + // Update the total votes count + poll.find('.poll_total_vote_cnt').html(res.total_votes); + + // Update each option + poll.find('[data-poll-option-id]').each(function() { + var option = $(this); + var option_id = option.attr('data-poll-option-id'); + var voted = (typeof res.user_votes[option_id] !== 'undefined') ? true : false; + var most_voted = (res.vote_counts[option_id] == most_votes) ? true : false; + var percent = (!res.total_votes) ? 0 : Math.round((res.vote_counts[option_id] / res.total_votes) * 100); + var percent_rel = (most_votes == 0) ? 0 : Math.round((res.vote_counts[option_id] / most_votes) * 100); + + option.toggleClass('voted', voted); + option.toggleClass('most-votes', most_voted); + + // Update the bars + var bar = option.find('.resultbar div'); + var bar_time_lapse = (res.can_vote) ? 500 : 1500; + var new_bar_class = (percent == 100) ? 'pollbar5' : 'pollbar' + (Math.floor(percent / 20) + 1); + + setTimeout(function () { + bar.animate({width: percent_rel + '%'}, 500).removeClass('pollbar1 pollbar2 pollbar3 pollbar4 pollbar5').addClass(new_bar_class); + bar.html(res.vote_counts[option_id]); + + var percent_txt = (!percent) ? res.NO_VOTES : percent + '%'; + option.find('.poll_option_percent').html(percent_txt); + }, bar_time_lapse); + }); + + if (!res.can_vote) { + poll.find('.polls').delay(400).fadeIn(500); + } + + // Display "Your vote has been cast." message. Disappears after 5 seconds. + var confirmation_delay = (res.can_vote) ? 300 : 900; + poll.find('.vote-submitted').delay(confirmation_delay).slideDown(200, function() { + if (results_visible) { + update_panel_height(); + } + + $(this).delay(5000).fadeOut(500, function() { + resize_panel(300); + }); + }); + + // Remove the gap resulting from removing options + setTimeout(function() { + resize_panel(500); + }, 1500); + + var resize_panel = function (time) { + var panel_height = panel.height(); + var inner_height = panel.find('.inner').outerHeight(); + + if (panel_height != inner_height) { + panel.css({'min-height': '', 'height': panel_height}).animate({height: inner_height}, time, function () { + panel.css({'min-height': inner_height, 'height': ''}); + }); + } + }; + } +}); + +/** + * Show poll results when clicking View results link. + */ +$('.poll_view_results a').click(function(e) { + // Do not follow the link + e.preventDefault(); + + var poll = $(this).parents('.topic_poll'); + poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500); + poll.find('.poll_view_results').hide(500); +}); $('[data-ajax]').each(function() { var $this = $(this), @@ -231,7 +384,7 @@ $('#quick-mod-select').change(function () { }); $('#delete_permanent').click(function () { - if ($(this).attr('checked')) { + if ($(this).prop('checked')) { $('#delete_reason').hide(); } else { $('#delete_reason').show(); @@ -247,7 +400,7 @@ $('#delete_permanent').click(function () { */ $('#member_search').click(function () { $('#memberlist_search').slideToggle('fast'); - phpbb.ajax_callbacks.alt_text.call(this); + phpbb.ajaxCallbacks.alt_text.call(this); // Focus on the username textbox if it's available and displayed if ($('#memberlist_search').is(':visible')) { $('#username').focus(); diff --git a/phpBB/styles/prosilver/template/attachment.html b/phpBB/styles/prosilver/template/attachment.html index 4c0a326f1e..c227e710b1 100644 --- a/phpBB/styles/prosilver/template/attachment.html +++ b/phpBB/styles/prosilver/template/attachment.html @@ -6,7 +6,7 @@ <!-- IF _file.S_THUMBNAIL --> <dl class="thumbnail"> - <dt><a href="{_file.U_DOWNLOAD_LINK}"><img src="{_file.THUMB_IMAGE}" alt="{_file.DOWNLOAD_NAME}" title="{_file.DOWNLOAD_NAME} ({_file.FILESIZE} {_file.SIZE_LANG}) {_file.L_DOWNLOAD_COUNT}" /></a></dt> + <dt><a href="{_file.U_DOWNLOAD_LINK}"><img src="{_file.THUMB_IMAGE}" class="postimage" alt="{_file.DOWNLOAD_NAME}" title="{_file.DOWNLOAD_NAME} ({_file.FILESIZE} {_file.SIZE_LANG}) {_file.L_DOWNLOAD_COUNT}" /></a></dt> <!-- IF _file.COMMENT --><dd> {_file.COMMENT}</dd><!-- ENDIF --> </dl> <!-- ENDIF --> @@ -14,7 +14,7 @@ <!-- IF _file.S_IMAGE --> <dl class="file"> - <dt class="attach-image"><img src="{_file.U_INLINE_LINK}" alt="{_file.DOWNLOAD_NAME}" onclick="viewableArea(this);" /></dt> + <dt class="attach-image"><img src="{_file.U_INLINE_LINK}" class="postimage" alt="{_file.DOWNLOAD_NAME}" onclick="viewableArea(this);" /></dt> <!-- IF _file.COMMENT --><dd><em>{_file.COMMENT}</em></dd><!-- ENDIF --> <dd>{_file.DOWNLOAD_NAME} ({_file.FILESIZE} {_file.SIZE_LANG}) {_file.L_DOWNLOAD_COUNT}</dd> </dl> diff --git a/phpBB/styles/prosilver/template/bbcode.html b/phpBB/styles/prosilver/template/bbcode.html index 909c09df5a..3e38d13a32 100644 --- a/phpBB/styles/prosilver/template/bbcode.html +++ b/phpBB/styles/prosilver/template/bbcode.html @@ -31,7 +31,7 @@ <!-- BEGIN size --><span style="font-size: {SIZE}%; line-height: 116%;">{TEXT}</span><!-- END size --> -<!-- BEGIN img --><img src="{URL}" alt="{L_IMAGE}" /><!-- END img --> +<!-- BEGIN img --><img src="{URL}" class="postimage" alt="{L_IMAGE}" /><!-- END img --> <!-- BEGIN url --><a href="{URL}" class="postlink">{DESCRIPTION}</a><!-- END url --> diff --git a/phpBB/styles/prosilver/template/captcha_default.html b/phpBB/styles/prosilver/template/captcha_default.html index c9c5295d13..550962db67 100644 --- a/phpBB/styles/prosilver/template/captcha_default.html +++ b/phpBB/styles/prosilver/template/captcha_default.html @@ -2,7 +2,7 @@ <div class="panel"> <div class="inner"> - <h3>{L_CONFIRMATION}</h3> + <h3 class="captcha-title">{L_CONFIRMATION}</h3> <p>{L_CONFIRM_EXPLAIN}</p> <fieldset class="fields2"> diff --git a/phpBB/styles/prosilver/template/captcha_qa.html b/phpBB/styles/prosilver/template/captcha_qa.html index c179f6dc20..1671987f63 100644 --- a/phpBB/styles/prosilver/template/captcha_qa.html +++ b/phpBB/styles/prosilver/template/captcha_qa.html @@ -2,7 +2,7 @@ <div class="panel"> <div class="inner"> - <h3>{L_CONFIRMATION}</h3> + <h3 class="captcha-title">{L_CONFIRMATION}</h3> <fieldset class="fields2"> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/captcha_recaptcha.html b/phpBB/styles/prosilver/template/captcha_recaptcha.html index aad1008241..bde0c9df13 100644 --- a/phpBB/styles/prosilver/template/captcha_recaptcha.html +++ b/phpBB/styles/prosilver/template/captcha_recaptcha.html @@ -2,7 +2,7 @@ <div class="panel"> <div class="inner"> - <h3>{L_CONFIRMATION}</h3> + <h3 class="captcha-title">{L_CONFIRMATION}</h3> <p>{L_CONFIRM_EXPLAIN}</p> <fieldset class="fields2"> diff --git a/phpBB/styles/prosilver/template/confirm_body.html b/phpBB/styles/prosilver/template/confirm_body.html index bf575c20fa..aaea5cfd05 100644 --- a/phpBB/styles/prosilver/template/confirm_body.html +++ b/phpBB/styles/prosilver/template/confirm_body.html @@ -1,12 +1,13 @@ <!-- IF S_AJAX_REQUEST --> + <form action="{S_CONFIRM_ACTION}" method="post"> + <h3>{MESSAGE_TITLE}</h3> + <p>{MESSAGE_TEXT}</p> - <h3>{MESSAGE_TITLE}</h3> - <p>{MESSAGE_TEXT}</p> - - <fieldset class="submit-buttons"> - <input type="button" name="confirm" value="{L_YES}" class="button2" /> - <input type="button" name="cancel" value="{L_NO}" class="button2" /> - </fieldset> + <fieldset class="submit-buttons"> + <input type="button" name="confirm" value="{L_YES}" class="button2" /> + <input type="button" name="cancel" value="{L_NO}" class="button2" /> + </fieldset> + </form> <!-- ELSE --> @@ -16,7 +17,7 @@ <div class="panel"> <div class="inner"> - <h2>{MESSAGE_TITLE}</h2> + <h2 class="message-title">{MESSAGE_TITLE}</h2> <p>{MESSAGE_TEXT}</p> <fieldset class="submit-buttons"> diff --git a/phpBB/styles/prosilver/template/confirm_delete_body.html b/phpBB/styles/prosilver/template/confirm_delete_body.html index 759b6b46b2..2d4dde5cd5 100644 --- a/phpBB/styles/prosilver/template/confirm_delete_body.html +++ b/phpBB/styles/prosilver/template/confirm_delete_body.html @@ -1,27 +1,29 @@ <!-- IF S_AJAX_REQUEST --> - <p>{MESSAGE_TEXT}</p> + <form action="{S_CONFIRM_ACTION}" method="post"> + <p>{MESSAGE_TEXT}</p> - <!-- IF not S_SOFTDELETED and (S_DELETE_REASON or (S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE)) --> - <!-- IF S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE --> - <label> - <strong>{L_DELETE_PERMANENTLY}{L_COLON}</strong> - <input id="delete_permanent" name="delete_permanent" type="checkbox" value="1" {S_CHECKED_PERMANENT} /> - <!-- IF S_TOPIC_MODE -->{L_DELETE_TOPIC_PERMANENTLY}<!-- ELSE -->{L_DELETE_POST_PERMANENTLY}<!-- ENDIF --> - </label> - <!-- ENDIF --> + <!-- IF not S_SOFTDELETED and (S_DELETE_REASON or (S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE)) --> + <!-- IF S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE --> + <label> + <strong>{L_DELETE_PERMANENTLY}{L_COLON}</strong> + <input id="delete_permanent" name="delete_permanent" type="checkbox" value="1" {S_CHECKED_PERMANENT} /> + <!-- IF S_TOPIC_MODE -->{L_DELETE_TOPIC_PERMANENTLY}<!-- ELSE -->{L_DELETE_POST_PERMANENTLY}<!-- ENDIF --> + </label> + <!-- ENDIF --> - <!-- IF S_DELETE_REASON --> - <label for="delete_reason"> - <strong>{L_DELETE_REASON}{L_COLON}</strong><br /><span>{L_DELETE_REASON_EXPLAIN}</span><br /> - <input type="text" name="delete_reason" value="" class="inputbox autowidth" maxlength="120" size="45" /> - </label> + <!-- IF S_DELETE_REASON --> + <label for="delete_reason"> + <strong>{L_DELETE_REASON}{L_COLON}</strong><br /><span>{L_DELETE_REASON_EXPLAIN}</span><br /> + <input type="text" name="delete_reason" value="" class="inputbox autowidth" maxlength="120" size="45" /> + </label> + <!-- ENDIF --> <!-- ENDIF --> - <!-- ENDIF --> - <fieldset class="submit-buttons"> - <input type="button" name="confirm" value="{L_YES}" class="button1" /> - <input type="button" name="cancel" value="{L_NO}" class="button2" /> - </fieldset> + <fieldset class="submit-buttons"> + <input type="button" name="confirm" value="{L_YES}" class="button1" /> + <input type="button" name="cancel" value="{L_NO}" class="button2" /> + </fieldset> + </form> <!-- ELSE --> @@ -31,7 +33,7 @@ <div class="panel"> <div class="inner"> - <h2>{MESSAGE_TITLE}</h2> + <h2 class="message-title">{MESSAGE_TITLE}</h2> <p>{MESSAGE_TEXT}</p> diff --git a/phpBB/styles/prosilver/template/custom_profile_fields.html b/phpBB/styles/prosilver/template/custom_profile_fields.html deleted file mode 100644 index 7de97f64cb..0000000000 --- a/phpBB/styles/prosilver/template/custom_profile_fields.html +++ /dev/null @@ -1,31 +0,0 @@ -<!-- BEGIN dropdown --> -<select name="{dropdown.FIELD_IDENT}" id="{dropdown.FIELD_IDENT}"> - <!-- BEGIN options --><option value="{dropdown.options.OPTION_ID}"{dropdown.options.SELECTED}>{dropdown.options.VALUE}</option><!-- END options --> -</select> -<!-- END dropdown --> - -<!-- BEGIN text --> -<textarea name="{text.FIELD_IDENT}" id="{text.FIELD_IDENT}" rows="{text.FIELD_ROWS}" cols="{text.FIELD_COLS}" class="inputbox autowidth">{text.FIELD_VALUE}</textarea> -<!-- END text --> - -<!-- BEGIN string --> -<input type="text" class="inputbox autowidth" name="{string.FIELD_IDENT}" id="{string.FIELD_IDENT}" size="{string.FIELD_LENGTH}" maxlength="{string.FIELD_MAXLEN}" value="{string.FIELD_VALUE}" /> -<!-- END string --> - -<!-- BEGIN bool --> -<!-- IF bool.FIELD_LENGTH eq 1 --> - <!-- BEGIN options --><label for="{bool.FIELD_IDENT}_{bool.options.OPTION_ID}"><input type="radio" class="radio" name="{bool.FIELD_IDENT}" id="{bool.FIELD_IDENT}_{bool.options.OPTION_ID}" value="{bool.options.OPTION_ID}"{bool.options.CHECKED} /> {bool.options.VALUE}</label> <!-- END options --> -<!-- ELSE --> - <input type="checkbox" class="radio" name="{bool.FIELD_IDENT}" id="{bool.FIELD_IDENT}"<!-- IF bool.FIELD_VALUE --> checked="checked"<!-- ENDIF --> /> -<!-- ENDIF --> -<!-- END bool --> - -<!-- BEGIN int --> -<input type="number" min="{int.FIELD_MINLEN}" max="{int.FIELD_MAXLEN}" class="inputbox autowidth" name="{int.FIELD_IDENT}" id="{int.FIELD_IDENT}" size="{int.FIELD_LENGTH}" value="{int.FIELD_VALUE}" /> -<!-- END int --> - -<!-- BEGIN date --> -<label for="{date.FIELD_IDENT}_day">{L_DAY}{L_COLON} <select name="{date.FIELD_IDENT}_day" id="{date.FIELD_IDENT}_day">{date.S_DAY_OPTIONS}</select></label> -<label for="{date.FIELD_IDENT}_month">{L_MONTH}{L_COLON} <select name="{date.FIELD_IDENT}_month" id="{date.FIELD_IDENT}_month">{date.S_MONTH_OPTIONS}</select></label> -<label for="{date.FIELD_IDENT}_year">{L_YEAR}{L_COLON} <select name="{date.FIELD_IDENT}_year" id="{date.FIELD_IDENT}_year">{date.S_YEAR_OPTIONS}</select></label> -<!-- END date --> diff --git a/phpBB/styles/prosilver/template/drafts.html b/phpBB/styles/prosilver/template/drafts.html index b6e6a7f5b7..ea2849a485 100644 --- a/phpBB/styles/prosilver/template/drafts.html +++ b/phpBB/styles/prosilver/template/drafts.html @@ -4,7 +4,7 @@ <div class="panel"> <div class="inner"> - <h3>{L_LOAD_DRAFT}</h3> + <h3 class="draft-title">{L_LOAD_DRAFT}</h3> <p>{L_LOAD_DRAFT_EXPLAIN}</p> </div> @@ -13,26 +13,31 @@ <div class="<!-- IF not S_PRIVMSGS -->forumbg<!-- ELSE -->panel<!-- ENDIF -->"> <div class="inner"> - <ul class="topiclist"> + <ul class="topiclist two-long-columns"> <li class="header"> <dl> <dt>{L_LOAD_DRAFT}</dt> - <dd class="posted">{L_SAVE_DATE}</dd> + <dd class="info">{L_SAVE_DATE}</dd> </dl> </li> </ul> - <ul class="topiclist<!-- IF not S_PRIVMSGS --> topics<!-- ELSE --> cplist<!-- ENDIF -->"> + <ul class="topiclist two-long-columns<!-- IF not S_PRIVMSGS --> topics<!-- ELSE --> cplist<!-- ENDIF -->"> <!-- BEGIN draftrow --> <li class="row<!-- IF draftrow.S_ROW_COUNT is even --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <dl> <dt> - <a href="{draftrow.U_INSERT}" title="{L_LOAD_DRAFT}" class="topictitle">{draftrow.DRAFT_SUBJECT}</a><br /> - <!-- IF not S_PRIVMSGS --><!-- IF draftrow.S_LINK_TOPIC -->{L_TOPIC}{L_COLON} <a href="{draftrow.U_VIEW}">{draftrow.TITLE}</a> - <!-- ELSEIF draftrow.S_LINK_FORUM -->{L_FORUM}{L_COLON} <a href="{draftrow.U_VIEW}">{draftrow.TITLE}</a> - <!-- ELSE -->{L_NO_TOPIC_FORUM}<!-- ENDIF --><!-- ENDIF --> + <div class="list-inner"> + <a href="{draftrow.U_INSERT}" title="{L_LOAD_DRAFT}" class="topictitle">{draftrow.DRAFT_SUBJECT}</a><br /> + <!-- IF not S_PRIVMSGS --><!-- IF draftrow.S_LINK_TOPIC -->{L_TOPIC}{L_COLON} <a href="{draftrow.U_VIEW}">{draftrow.TITLE}</a> + <!-- ELSEIF draftrow.S_LINK_FORUM -->{L_FORUM}{L_COLON} <a href="{draftrow.U_VIEW}">{draftrow.TITLE}</a> + <!-- ELSE -->{L_NO_TOPIC_FORUM}<!-- ENDIF --><!-- ENDIF --> + <div class="responsive-show" style="display: none;"> + {L_SAVE_DATE}{L_COLON} <strong>{draftrow.DATE}</strong> + </div> + </div> </dt> - <dd class="posted">{draftrow.DATE}</dd> + <dd class="info"><span>{draftrow.DATE}</span></dd> </dl> </li> <!-- END draftrow --> diff --git a/phpBB/styles/prosilver/template/editor.js b/phpBB/styles/prosilver/template/editor.js deleted file mode 100644 index 4c70ee345f..0000000000 --- a/phpBB/styles/prosilver/template/editor.js +++ /dev/null @@ -1,422 +0,0 @@ -/** -* bbCode control by subBlue design [ www.subBlue.com ] -* Includes unixsafe colour palette selector by SHS` -*/ - -// Startup variables -var imageTag = false; -var theSelection = false; -var bbcodeEnabled = true; - -// Check for Browser & Platform for PC & IE specific bits -// More details from: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html -var clientPC = navigator.userAgent.toLowerCase(); // Get client info -var clientVer = parseInt(navigator.appVersion, 10); // Get browser version - -var is_ie = ((clientPC.indexOf('msie') !== -1) && (clientPC.indexOf('opera') === -1)); -var is_win = ((clientPC.indexOf('win') !== -1) || (clientPC.indexOf('16bit') !== -1)); -var baseHeight; - -/** -* Shows the help messages in the helpline window -*/ -function helpline(help) { - document.forms[form_name].helpbox.value = help_line[help]; -} - -/** -* Fix a bug involving the TextRange object. From -* http://www.frostjedi.com/terra/scripts/demo/caretBug.html -*/ -function initInsertions() { - var doc; - - if (document.forms[form_name]) { - doc = document; - } else { - doc = opener.document; - } - - var textarea = doc.forms[form_name].elements[text_name]; - - if (is_ie && typeof(baseHeight) !== 'number') { - textarea.focus(); - baseHeight = doc.selection.createRange().duplicate().boundingHeight; - - if (!document.forms[form_name]) { - document.body.focus(); - } - } -} - -/** -* bbstyle -*/ -function bbstyle(bbnumber) { - if (bbnumber !== -1) { - bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]); - } else { - insert_text('[*]'); - document.forms[form_name].elements[text_name].focus(); - } -} - -/** -* Apply bbcodes -*/ -function bbfontstyle(bbopen, bbclose) { - theSelection = false; - - var textarea = document.forms[form_name].elements[text_name]; - - textarea.focus(); - - if ((clientVer >= 4) && is_ie && is_win) { - // Get text selection - theSelection = document.selection.createRange().text; - - if (theSelection) { - // Add tags around selection - document.selection.createRange().text = bbopen + theSelection + bbclose; - document.forms[form_name].elements[text_name].focus(); - theSelection = ''; - return; - } - } else if (document.forms[form_name].elements[text_name].selectionEnd - && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) { - mozWrap(document.forms[form_name].elements[text_name], bbopen, bbclose); - document.forms[form_name].elements[text_name].focus(); - theSelection = ''; - return; - } - - //The new position for the cursor after adding the bbcode - var caret_pos = getCaretPosition(textarea).start; - var new_pos = caret_pos + bbopen.length; - - // Open tag - insert_text(bbopen + bbclose); - - // Center the cursor when we don't have a selection - // Gecko and proper browsers - if (!isNaN(textarea.selectionStart)) { - textarea.selectionStart = new_pos; - textarea.selectionEnd = new_pos; - } - // IE - else if (document.selection) { - var range = textarea.createTextRange(); - range.move("character", new_pos); - range.select(); - storeCaret(textarea); - } - - textarea.focus(); - return; -} - -/** -* Insert text at position -*/ -function insert_text(text, spaces, popup) { - var textarea; - - if (!popup) { - textarea = document.forms[form_name].elements[text_name]; - } else { - textarea = opener.document.forms[form_name].elements[text_name]; - } - - if (spaces) { - text = ' ' + text + ' '; - } - - // Since IE9, IE also has textarea.selectionStart, but it still needs to be treated the old way. - // Therefore we simply add a !is_ie here until IE fixes the text-selection completely. - if (!isNaN(textarea.selectionStart) && !is_ie) { - var sel_start = textarea.selectionStart; - var sel_end = textarea.selectionEnd; - - mozWrap(textarea, text, ''); - textarea.selectionStart = sel_start + text.length; - textarea.selectionEnd = sel_end + text.length; - } else if (textarea.createTextRange && textarea.caretPos) { - if (baseHeight !== textarea.caretPos.boundingHeight) { - textarea.focus(); - storeCaret(textarea); - } - - var caret_pos = textarea.caretPos; - caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; - } else { - textarea.value = textarea.value + text; - } - - if (!popup) { - textarea.focus(); - } -} - -/** -* Add inline attachment at position -*/ -function attach_inline(index, filename) { - insert_text('[attachment=' + index + ']' + filename + '[/attachment]'); - document.forms[form_name].elements[text_name].focus(); -} - -/** -* Add quote text to message -*/ -function addquote(post_id, username, l_wrote) { - var message_name = 'message_' + post_id; - var theSelection = ''; - var divarea = false; - var i; - - if (l_wrote === undefined) { - // Backwards compatibility - l_wrote = 'wrote'; - } - - if (document.all) { - divarea = document.all[message_name]; - } else { - divarea = document.getElementById(message_name); - } - - // Get text selection - not only the post content :( - // IE9 must use the document.selection method but has the *.getSelection so we just force no IE - if (window.getSelection && !is_ie && !window.opera) { - theSelection = window.getSelection().toString(); - } else if (document.getSelection && !is_ie) { - theSelection = document.getSelection(); - } else if (document.selection) { - theSelection = document.selection.createRange().text; - } - - if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) { - if (divarea.innerHTML) { - theSelection = divarea.innerHTML.replace(/<br>/ig, '\n'); - theSelection = theSelection.replace(/<br\/>/ig, '\n'); - theSelection = theSelection.replace(/<\;/ig, '<'); - theSelection = theSelection.replace(/>\;/ig, '>'); - theSelection = theSelection.replace(/&\;/ig, '&'); - theSelection = theSelection.replace(/ \;/ig, ' '); - } else if (document.all) { - theSelection = divarea.innerText; - } else if (divarea.textContent) { - theSelection = divarea.textContent; - } else if (divarea.firstChild.nodeValue) { - theSelection = divarea.firstChild.nodeValue; - } - } - - if (theSelection) { - if (bbcodeEnabled) { - insert_text('[quote="' + username + '"]' + theSelection + '[/quote]'); - } else { - insert_text(username + ' ' + l_wrote + ':' + '\n'); - var lines = split_lines(theSelection); - for (i = 0; i < lines.length; i++) { - insert_text('> ' + lines[i] + '\n'); - } - } - } - - return; -} - -function split_lines(text) { - var lines = text.split('\n'); - var splitLines = new Array(); - var j = 0; - var i; - - for(i = 0; i < lines.length; i++) { - if (lines[i].length <= 80) { - splitLines[j] = lines[i]; - j++; - } else { - var line = lines[i]; - var splitAt; - do { - splitAt = line.indexOf(' ', 80); - - if (splitAt === -1) { - splitLines[j] = line; - j++; - } else { - splitLines[j] = line.substring(0, splitAt); - line = line.substring(splitAt); - j++; - } - } - while(splitAt !== -1); - } - } - return splitLines; -} - -/** -* From http://www.massless.org/mozedit/ -*/ -function mozWrap(txtarea, open, close) { - var selLength = (typeof(txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength; - var selStart = txtarea.selectionStart; - var selEnd = txtarea.selectionEnd; - var scrollTop = txtarea.scrollTop; - - if (selEnd === 1 || selEnd === 2) { - selEnd = selLength; - } - - var s1 = (txtarea.value).substring(0,selStart); - var s2 = (txtarea.value).substring(selStart, selEnd); - var s3 = (txtarea.value).substring(selEnd, selLength); - - txtarea.value = s1 + open + s2 + close + s3; - txtarea.selectionStart = selStart + open.length; - txtarea.selectionEnd = selEnd + open.length; - txtarea.focus(); - txtarea.scrollTop = scrollTop; - - return; -} - -/** -* Insert at Caret position. Code from -* http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130 -*/ -function storeCaret(textEl) { - if (textEl.createTextRange) { - textEl.caretPos = document.selection.createRange().duplicate(); - } -} - -/** -* Color pallette -*/ -function colorPalette(dir, width, height) { - var r = 0, - g = 0, - b = 0, - numberList = new Array(6), - color = '', - html = ''; - - numberList[0] = '00'; - numberList[1] = '40'; - numberList[2] = '80'; - numberList[3] = 'BF'; - numberList[4] = 'FF'; - - html += '<table cellspacing="1" cellpadding="0" border="0">'; - - for (r = 0; r < 5; r++) { - if (dir == 'h') { - html += '<tr>'; - } - - for (g = 0; g < 5; g++) { - if (dir == 'v') { - html += '<tr>'; - } - - for (b = 0; b < 5; b++) { - color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); - html += '<td bgcolor="#' + color + '" style="width: ' + width + 'px; height: ' + height + 'px;">'; - html += '<a href="#" onclick="bbfontstyle(\'[color=#' + color + ']\', \'[/color]\'); return false;" style="display: block; width: ' + width + 'px; height: ' + height + 'px; " alt="#' + color + '" title="#' + color + '"></a>'; - html += '</td>'; - } - - if (dir == 'v') { - html += '</tr>'; - } - } - - if (dir == 'h') { - html += '</tr>'; - } - } - html += '</table>'; - return html; -} - -(function($) { - $(document).ready(function() { - $('#color_palette_placeholder').each(function() { - $(this).html(colorPalette('h', 15, 12)); - }); - }); -})(jQuery); - -/** -* Caret Position object -*/ -function caretPosition() { - var start = null; - var end = null; -} - -/** -* Get the caret position in an textarea -*/ -function getCaretPosition(txtarea) { - var caretPos = new caretPosition(); - - // simple Gecko/Opera way - if (txtarea.selectionStart || txtarea.selectionStart === 0) { - caretPos.start = txtarea.selectionStart; - caretPos.end = txtarea.selectionEnd; - } - // dirty and slow IE way - else if (document.selection) { - // get current selection - var range = document.selection.createRange(); - - // a new selection of the whole textarea - var range_all = document.body.createTextRange(); - range_all.moveToElementText(txtarea); - - // calculate selection start point by moving beginning of range_all to beginning of range - var sel_start; - for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) { - range_all.moveStart('character', 1); - } - - txtarea.sel_start = sel_start; - - // we ignore the end value for IE, this is already dirty enough and we don't need it - caretPos.start = txtarea.sel_start; - caretPos.end = txtarea.sel_start; - } - - return caretPos; -} - -/** -* Allow to use tab character when typing code -* Keep indentation of last line of code when typing code -*/ -(function($) { - $(document).ready(function() { - var doc, textarea; - - // find textarea, make sure browser supports necessary functions - if (document.forms[form_name]) { - doc = document; - } else { - doc = opener.document; - } - - if (!doc.forms[form_name]) { - return; - } - - textarea = doc.forms[form_name].elements[text_name]; - - phpbb.applyCodeEditor(textarea); - }); -})(jQuery); - diff --git a/phpBB/styles/prosilver/template/faq_body.html b/phpBB/styles/prosilver/template/faq_body.html index 46f738aa3a..53205d14e9 100644 --- a/phpBB/styles/prosilver/template/faq_body.html +++ b/phpBB/styles/prosilver/template/faq_body.html @@ -1,6 +1,6 @@ <!-- INCLUDE overall_header.html --> -<h2>{L_FAQ_TITLE}</h2> +<h2 class="faq-title">{L_FAQ_TITLE}</h2> <div class="panel bg1" id="faqlinks"> @@ -24,16 +24,12 @@ </div> </div> - - -<div class="clear"></div> - <!-- BEGIN faq_block --> <div class="panel <!-- IF faq_block.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF -->"> <div class="inner"> <div class="content"> - <h2>{faq_block.BLOCK_TITLE}</h2> + <h2 class="faq-title">{faq_block.BLOCK_TITLE}</h2> <!-- BEGIN faq_row --> <dl class="faq"> <dt id="f{faq_block.S_ROW_COUNT}r{faq_block.faq_row.S_ROW_COUNT}"><strong>{faq_block.faq_row.FAQ_QUESTION}</strong></dt> diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js index 800fadd972..1594d73517 100644 --- a/phpBB/styles/prosilver/template/forum_fn.js +++ b/phpBB/styles/prosilver/template/forum_fn.js @@ -37,17 +37,14 @@ function jumpto(item) { on_page = item.attr('data-on-page'), per_page = item.attr('data-per-page'), base_url = item.attr('data-base-url'), + start_name = item.attr('data-start-name'), page = prompt(jump_page, on_page); if (page !== null && !isNaN(page) && page == Math.floor(page) && page > 0) { - if (base_url.indexOf('%d') === -1) { - if (base_url.indexOf('?') === -1) { - document.location.href = base_url + '?start=' + ((page - 1) * per_page); - } else { - document.location.href = base_url.replace(/&/g, '&') + '&start=' + ((page - 1) * per_page); - } + if (base_url.indexOf('?') === -1) { + document.location.href = base_url + '?' + start_name + '=' + ((page - 1) * per_page); } else { - document.location.href = base_url.replace('%d', page); + document.location.href = base_url.replace(/&/g, '&') + '&' + start_name + '=' + ((page - 1) * per_page); } } } @@ -95,23 +92,6 @@ function viewableArea(e, itself) { } /** -* Set display of page element -* s[-1,0,1] = hide,toggle display,show -* type = string: inline, block, inline-block or other CSS "display" type -*/ -function dE(n, s, type) { - if (!type) { - type = 'block'; - } - - var e = document.getElementById(n); - if (!s) { - s = (e.style.display === '' || e.style.display === type) ? -1 : 1; - } - e.style.display = (s === 1) ? type : 'none'; -} - -/** * Alternate display of subPanels */ jQuery(document).ready(function() { @@ -187,9 +167,10 @@ function selectCode(a) { // Not IE and IE9+ if (window.getSelection) { s = window.getSelection(); - // Safari + // Safari and Chrome if (s.setBaseAndExtent) { - s.setBaseAndExtent(e, 0, e, e.innerText.length - 1); + var l = (e.innerText.length > 1) ? e.innerText.length - 1 : 1; + s.setBaseAndExtent(e, 0, e, l); } // Firefox and Opera else { @@ -306,64 +287,6 @@ function apply_onkeypress_event() { jQuery(document).ready(apply_onkeypress_event); /** -* Run MSN action -*/ -function msn_action(action, address) -{ - // Does the browser support the MSNM object? - var app = document.getElementById('objMessengerApp'); - - if (!app || !app.MyStatus) { - var lang = $('form[data-lang-im-msnm-browser]'); - if (lang.length) { - alert(lang.attr('data-lang-im-msnm-browser')); - } - return false; - } - - // Is MSNM connected? - if (app.MyStatus == 1) { - var lang = $('form[data-lang-im-msnm-connect]'); - if (lang.length) { - alert(lang.attr('data-lang-im-msnm-connect')); - } - return false; - } - - // Do stuff - try { - switch (action) { - case 'add': - app.AddContact(0, address); - break; - - case 'im': - app.InstantMessage(address); - break; - } - } - catch (e) { - return; - } -} - -/** -* Add to your contact list -*/ -function add_contact(address) -{ - msn_action('add', address); -} - -/** -* Write IM to contact -*/ -function im_contact(address) -{ - msn_action('im', address); -} - -/** * Functions for user search popup */ function insert_user(formId, value) @@ -410,33 +333,593 @@ function insert_single_user(formId, user) } /** -* Run onload functions +* Parse document block */ -(function($) { - $(document).ready(function() { - // Focus forms - $('form[data-focus]:first').each(function() { - $('#' + this.getAttribute('data-focus')).focus(); +function parse_document(container) +{ + var test = document.createElement('div'), + oldBrowser = (typeof test.style.borderRadius == 'undefined'); + + delete test; + + /** + * Reset avatar dimensions when changing URL or EMAIL + */ + container.find('input[data-reset-on-edit]').bind('keyup', function() { + $(this.getAttribute('data-reset-on-edit')).val(''); + }); + + /** + * Pagination + */ + container.find('a.pagination-trigger').click(function() { + jumpto($(this)); + }); + + /** + * Dropdowns + */ + container.find('.dropdown-container').each(function() { + var $this = $(this), + trigger = $this.find('.dropdown-trigger:first'), + contents = $this.find('.dropdown'), + options = { + direction: 'auto', + verticalDirection: 'auto' + }, + data; + + if (!trigger.length) { + data = $this.attr('data-dropdown-trigger'); + trigger = data ? $this.children(data) : $this.children('a:first'); + } + + if (!contents.length) { + data = $this.attr('data-dropdown-contents'); + contents = data ? $this.children(data) : $this.children('div:first'); + } + + if (!trigger.length || !contents.length) return; + + if ($this.hasClass('dropdown-up')) options.verticalDirection = 'up'; + if ($this.hasClass('dropdown-down')) options.verticalDirection = 'down'; + if ($this.hasClass('dropdown-left')) options.direction = 'left'; + if ($this.hasClass('dropdown-right')) options.direction = 'right'; + + phpbb.registerDropdown(trigger, contents, options); + }); + + /** + * Adjust HTML code for IE8 and older versions + */ + if (oldBrowser) { + // Fix .linklist.bulletin lists + container.find('ul.linklist.bulletin li:first-child, ul.linklist.bulletin li.rightside:last-child').addClass('no-bulletin'); + + // Do not run functions below for old browsers + return; + } + + /** + * Resize navigation block to keep all links on same line + */ + container.find('.navlinks').each(function() { + var $this = $(this), + left = $this.children().not('.rightside'), + right = $this.children('.rightside'); + + if (left.length !== 1 || !right.length) return; + + function resize() { + var width = 0, + diff = left.outerWidth(true) - left.width(); + + right.each(function() { + width += $(this).outerWidth(true); + }); + left.css('max-width', Math.floor($this.width() - width - diff) + 'px'); + } + + resize(); + $(window).resize(resize); + }); + + /** + * Makes breadcrumbs responsive + */ + container.find('.breadcrumbs:not([data-skip-responsive])').each(function() { + var $this = $(this), + $body = $('body'), + links = $this.find('.crumb'), + length = links.length, + classes = ['wrapped-max', 'wrapped-wide', 'wrapped-medium', 'wrapped-small', 'wrapped-tiny'], + classesLength = classes.length, + maxHeight = 0, + lastWidth = false, + wrapped = false; + + // Set tooltips + $this.find('a').each(function() { + var $link = $(this); + $link.attr('title', $link.text()); }); - // Reset avatar dimensions when changing URL or EMAIL - $('input[data-reset-on-edit]').bind('keyup', function() { - $(this.getAttribute('data-reset-on-edit')).val(''); + // Funciton that checks breadcrumbs + function check() { + var height = $this.height(), + width = $body.width(), + link, i, j; + + maxHeight = parseInt($this.css('line-height')) | 0; + links.each(function() { + if ($(this).height() > 0) { + maxHeight = Math.max(maxHeight, $(this).outerHeight(true)); + } + }); + + if (height <= maxHeight) { + if (!wrapped || lastWidth === false || lastWidth >= width) { + lastWidth = width; + return; + } + } + lastWidth = width; + + if (wrapped) { + $this.removeClass('wrapped').find('.crumb.wrapped').removeClass('wrapped ' + classes.join(' ')); + wrapped = false; + if ($this.height() <= maxHeight) { + return; + } + } + + wrapped = true; + $this.addClass('wrapped'); + if ($this.height() <= maxHeight) { + return; + } + + for (i = 0; i < classesLength; i ++) { + for (j = length - 1; j >= 0; j --) { + links.eq(j).addClass('wrapped ' + classes[i]); + if ($this.height() <= maxHeight) { + return; + } + } + } + } + + // Run function and set event + check(); + $(window).resize(check); + }); + + /** + * Adjust topiclist lists with check boxes + */ + container.find('ul.topiclist dd.mark').siblings('dt').children('.list-inner').addClass('with-mark'); + + /** + * Appends contents of all extra columns to first column in + * .topiclist lists for mobile devices. Copies contents as is. + * + * To add that functionality to .topiclist list simply add + * responsive-show-all to list of classes + */ + container.find('.topiclist.responsive-show-all > li > dl').each(function() { + var $this = $(this), + block = $this.find('dt .responsive-show:last-child'), + first = true; + + // Create block that is visible only on mobile devices + if (!block.length) { + $this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />'); + block = $this.find('dt .responsive-show:last-child'); + } + else { + first = (block.text().trim().length == 0); + } + + // Copy contents of each column + $this.find('dd').not('.mark').each(function() { + var column = $(this), + children = column.children(), + html = column.html(); + + if (children.length == 1 && children.text() == column.text()) { + html = children.html(); + } + + block.append((first ? '' : '<br />') + html); + + first = false; }); + }); - // Pagination - $('a.pagination-trigger').click(function() { - jumpto($(this)); + /** + * Same as above, but prepends text from header to each + * column before contents of that column. + * + * To add that functionality to .topiclist list simply add + * responsive-show-columns to list of classes + */ + container.find('.topiclist.responsive-show-columns').each(function() { + var list = $(this), + headers = [], + headersLength = 0; + + // Find all headers, get contents + list.prev('.topiclist').find('li.header dd').not('.mark').each(function() { + headers.push($(this).text()); + headersLength ++; }); - // Adjust HTML code for IE8 and older versions - var test = document.createElement('div'), - oldBrowser = (typeof test.style.borderRadius == 'undefined'); - delete test; + if (!headersLength) { + return; + } + + // Parse each row + list.find('dl').each(function() { + var $this = $(this), + block = $this.find('dt .responsive-show:last-child'), + first = true; + + // Create block that is visible only on mobile devices + if (!block.length) { + $this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />'); + block = $this.find('dt .responsive-show:last-child'); + } + else { + first = (block.text().trim().length == 0); + } + + // Copy contents of each column + $this.find('dd').not('.mark').each(function(i) { + var column = $(this), + children = column.children(), + html = column.html(); - if (oldBrowser) { - // Fix .linkslist.bulletin lists - $('ul.linklist.bulletin li:first-child, ul.linklist.bulletin li.rightside:last-child').addClass('no-bulletin'); + if (children.length == 1 && children.text() == column.text()) { + html = children.html(); + } + + // Prepend contents of matching header before contents of column + if (i < headersLength) { + html = headers[i] + ': <strong>' + html + '</strong>'; + } + + block.append((first ? '' : '<br />') + html); + + first = false; + }); + }); + }); + + /** + * Responsive tables + */ + container.find('table.table1').not('.not-responsive').each(function() { + var $this = $(this), + th = $this.find('thead > tr > th'), + columns = th.length, + headers = [], + totalHeaders = 0, + i, headersLength; + + // Find each header + th.each(function(column) { + var cell = $(this), + colspan = parseInt(cell.attr('colspan')), + dfn = cell.attr('data-dfn'), + text = dfn ? dfn : cell.text(); + + colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan; + + for (i=0; i<colspan; i++) { + headers.push(text); + } + totalHeaders ++; + + if (dfn && !column) { + $this.addClass('show-header'); + } + }); + + headersLength = headers.length; + + // Add header text to each cell as <dfn> + $this.addClass('responsive'); + + if (totalHeaders < 2) { + $this.addClass('show-header'); + return; + } + + $this.find('tbody > tr').each(function() { + var row = $(this), + cells = row.children('td'), + column = 0; + + if (cells.length == 1) { + row.addClass('big-column'); + return; + } + + cells.each(function() { + var cell = $(this), + colspan = parseInt(cell.attr('colspan')), + text = cell.text().trim(); + + if (headersLength <= column) { + return; + } + + if ((text.length && text !== '-') || cell.children().length) { + cell.prepend('<dfn style="display: none;">' + headers[column] + '</dfn>'); + } + else { + cell.addClass('empty'); + } + + colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan; + column += colspan; + }); + }); + }); + + /** + * Hide empty responsive tables + */ + container.find('table.responsive > tbody').not('.responsive-skip-empty').each(function() { + var items = $(this).children('tr'); + if (items.length == 0) + { + $(this).parent('table:first').addClass('responsive-hide'); + } + }); + + /** + * Responsive link lists + */ + container.find('.linklist:not(.navlinks, [data-skip-responsive]), .postbody ul.profile-icons:not([data-skip-responsive])').each(function() { + var $this = $(this), + $body = $('body'), + filterSkip = '.breadcrumbs, [data-skip-responsive]', + filterLast = '.pagination, .icon-notifications, .icon-pm, .icon-logout, .icon-login, .mark-read, .edit-icon, .quote-icon', + allLinks = $this.children(), + links = allLinks.not(filterSkip), + html = '<li class="responsive-menu" style="display:none;"><a href="javascript:void(0);" class="responsive-menu-link"> </a><div class="dropdown" style="display:none;"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>', + filterLastList = links.filter(filterLast); + + if (links.is('.rightside')) + { + links.filter('.rightside:first').before(html); + } + else + { + $this.append(html); } + + var item = $this.children('.responsive-menu'), + menu = item.find('.dropdown-contents'), + lastWidth = false, + compact = false, + responsive = false, + copied = false; + + function check() { + var width = $body.width(); + if (responsive && width <= lastWidth) { + return; + } + + // Reset responsive and compact layout + if (responsive) { + responsive = false; + $this.removeClass('responsive'); + links.css('display', ''); + item.css('display', 'none'); + } + + if (compact) { + compact = false; + $this.removeClass('compact'); + } + + // Find tallest element + var maxHeight = 0; + allLinks.each(function() { + if (!$(this).height()) return; + maxHeight = Math.max(maxHeight, $(this).outerHeight(true)); + }); + + if (maxHeight < 1) { + return; + } + + // Nothing to resize if block's height is not bigger than tallest element's height + if ($this.height() <= maxHeight) { + return; + } + + // Enable compact layout, find tallest element, compare to height of whole block + compact = true; + $this.addClass('compact'); + + var compactMaxHeight = 0; + allLinks.each(function() { + if (!$(this).height()) return; + compactMaxHeight = Math.max(compactMaxHeight, $(this).outerHeight(true)); + }); + + if ($this.height() <= maxHeight) { + return; + } + + // Compact layout did not resize block enough, switch to responsive layout + compact = false; + $this.removeClass('compact'); + responsive = true; + + if (!copied) { + var clone = links.clone(true); + clone.filter('.rightside').each(function() { + menu.prepend(this); + }); + menu.prepend(clone.not('.rightside')); + menu.find('li.leftside, li.rightside').removeClass('leftside rightside'); + menu.find('.inputbox').parents('li:first').css('white-space', 'normal'); + copied = true; + } + else { + menu.children().css('display', ''); + } + + item.css('display', ''); + $this.addClass('responsive'); + + // Try to not hide filtered items + if (filterLastList.length) { + links.not(filterLast).css('display', 'none'); + + maxHeight = 0; + filterLastList.each(function() { + if (!$(this).height()) return; + maxHeight = Math.max(maxHeight, $(this).outerHeight(true)); + }); + + if ($this.height() <= maxHeight) { + menu.children().filter(filterLast).css('display', 'none'); + return; + } + } + + links.css('display', 'none'); + } + + phpbb.registerDropdown(item.find('a.responsive-menu-link'), item.find('.dropdown')); + + check(); + $(window).resize(check); + }); + + /** + * Responsive tabs + */ + container.find('#tabs, #minitabs').not('[data-skip-responsive]').each(function() { + var $this = $(this), + $body = $('body'), + ul = $this.children(), + tabs = ul.children().not('[data-skip-responsive]'), + links = tabs.children('a'), + item = ul.append('<li class="responsive-tab" style="display:none;"><a href="javascript:void(0);" class="responsive-tab-link"><span> </span></a><div class="dropdown tab-dropdown" style="display: none;"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>').find('li.responsive-tab'), + menu = item.find('.dropdown-contents'), + maxHeight = 0, + lastWidth = false, + responsive = false; + + links.each(function() { + var link = $(this); + maxHeight = Math.max(maxHeight, Math.max(link.outerHeight(true), link.parent().outerHeight(true))); + }) + + function check() { + var width = $body.width(), + height = $this.height(); + + if (arguments.length == 0 && (!responsive || width <= lastWidth) && height <= maxHeight) { + return; + } + + tabs.show(); + item.hide(); + + lastWidth = width; + height = $this.height(); + if (height <= maxHeight) { + responsive = false; + if (item.hasClass('dropdown-visible')) { + phpbb.toggleDropdown.call(item.find('a.responsive-tab-link').get(0)); + } + return; + } + + responsive = true; + item.show(); + menu.html(''); + + var availableTabs = tabs.filter(':not(.activetab, .responsive-tab)'), + total = availableTabs.length, + i, tab; + + for (i = total - 1; i >= 0; i --) { + tab = availableTabs.eq(i); + menu.prepend(tab.clone(true)); + tab.hide(); + if ($this.height() <= maxHeight) { + menu.find('a').click(function() { check(true); }); + return; + } + } + menu.find('a').click(function() { check(true); }); + } + + phpbb.registerDropdown(item.find('a.responsive-tab-link'), item.find('.dropdown'), {visibleClass: 'activetab'}); + + check(true); + $(window).resize(check); + }); + + /** + * Hide UCP/MCP navigation if there is only 1 item + */ + container.find('#navigation').each(function() { + var items = $(this).children('ol, ul').children('li'); + if (items.length == 1) + { + $(this).addClass('responsive-hide'); + } + }); + + /** + * Replace responsive text + */ + container.find('[data-responsive-text]').each(function() { + var $this = $(this), + fullText = $this.text(), + responsiveText = $this.attr('data-responsive-text'), + responsive = false; + + function check() { + if ($(window).width() > 700) { + if (!responsive) return; + $this.text(fullText); + responsive = false; + return; + } + if (responsive) return; + $this.text(responsiveText); + responsive = true; + } + + check(); + $(window).resize(check); + }); +} + +/** +* Run onload functions +*/ +(function($) { + $(document).ready(function() { + // Swap .nojs and .hasjs + $('#phpbb.nojs').toggleClass('nojs hasjs'); + + // Focus forms + $('form[data-focus]:first').each(function() { + $('#' + this.getAttribute('data-focus')).focus(); + }); + + parse_document($('body')); }); })(jQuery); diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index 9fb6b3d951..0dd47bea9e 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -7,6 +7,7 @@ </div> <!-- ENDIF --> + <!-- EVENT forumlist_body_category_header_before --> <!-- IF forumrow.S_IS_CAT or forumrow.S_FIRST_ROW or forumrow.S_NO_CAT --> <div class="forabg"> <div class="inner"> @@ -22,11 +23,13 @@ </ul> <ul class="topiclist forums"> <!-- ENDIF --> + <!-- EVENT forumlist_body_category_header_after --> <!-- IF not forumrow.S_IS_CAT --> <li class="row"> <dl class="icon {forumrow.FORUM_IMG_STYLE}"> <dt title="{forumrow.FORUM_FOLDER_IMG_ALT}"> + <!-- IF forumrow.S_UNREAD_FORUM --><a href="{forumrow.U_VIEWFORUM}" class="icon-link"></a><!-- ENDIF --> <div class="list-inner"> <!-- IF S_ENABLE_FEEDS and forumrow.S_FEED_ENABLED --><!-- <a class="feed-icon-forum" title="{L_FEED} - {forumrow.FORUM_NAME}" href="{U_FEED}?f={forumrow.FORUM_ID}"><img src="{T_THEME_PATH}/images/feed.gif" alt="{L_FEED} - {forumrow.FORUM_NAME}" /></a> --><!-- ENDIF --> @@ -37,10 +40,22 @@ <br /><strong>{forumrow.L_MODERATOR_STR}{L_COLON}</strong> {forumrow.MODERATORS} <!-- ENDIF --> <!-- IF .forumrow.subforum and forumrow.S_LIST_SUBFORUMS --> - <br /><strong>{forumrow.L_SUBFORUM_STR}</strong> + <!-- EVENT forumlist_body_subforums_before --> + <br /><strong>{forumrow.L_SUBFORUM_STR}{L_COLON}</strong> <!-- BEGIN subforum --> - <a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->,<!-- ENDIF --> + <a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->{L_COMMA_SEPARATOR}<!-- ENDIF --> <!-- END subforum --> + <!-- EVENT forumlist_body_subforums_after --> + <!-- ENDIF --> + + <!-- IF not S_IS_BOT --> + <div class="responsive-show" style="display: none;"> + <!-- IF forumrow.CLICKS --> + {L_REDIRECTS}{L_COLON} <strong>{forumrow.CLICKS}</strong> + <!-- ELSEIF not forumrow.S_IS_LINK and forumrow.TOPICS --> + {L_TOPICS}{L_COLON} <strong>{forumrow.TOPICS}</strong> + <!-- ENDIF --> + </div> <!-- ENDIF --> </div> </dt> @@ -73,6 +88,7 @@ </div> </div> + <!-- EVENT forumlist_body_last_row_after --> <!-- ENDIF --> <!-- BEGINELSE --> diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html index e0a9279738..3e9aae28e3 100644 --- a/phpBB/styles/prosilver/template/index_body.html +++ b/phpBB/styles/prosilver/template/index_body.html @@ -1,7 +1,9 @@ <!-- INCLUDE overall_header.html --> -<p class="{S_CONTENT_FLOW_END}<!-- IF S_USER_LOGGED_IN --> rightside<!-- ENDIF -->"><!-- IF S_USER_LOGGED_IN -->{LAST_VISIT_DATE}<!-- ELSE -->{CURRENT_TIME}<!-- ENDIF --></p> -<!-- IF U_MCP --><p>{CURRENT_TIME} <br />[ <a href="{U_MCP}">{L_MCP}</a> ]</p><!-- ELSEIF S_USER_LOGGED_IN --><p>{CURRENT_TIME}</p><!-- ENDIF --> +<p class="{S_CONTENT_FLOW_END} responsive-center<!-- IF S_USER_LOGGED_IN --> rightside<!-- ENDIF -->"><!-- IF S_USER_LOGGED_IN -->{LAST_VISIT_DATE}<!-- ELSE -->{CURRENT_TIME}<!-- ENDIF --></p> +<!-- IF S_USER_LOGGED_IN --><p class="responsive-center">{CURRENT_TIME}<!-- IF U_MCP or U_ACP --> <br />[ <!-- IF U_ACP --><a href="{U_ACP}" title="{L_ACP}" data-responsive-text="{L_ACP_SHORT}">{L_ACP}</a><!-- IF U_MCP --> | <!-- ENDIF --><!-- ENDIF --><!-- IF U_MCP --><a href="{U_MCP}" title="{L_MCP}" data-responsive-text="{L_MCP_SHORT}">{L_MCP}</a><!-- ENDIF --> ]<!-- ENDIF --></p><!-- ENDIF --> + +<!-- EVENT index_body_linklist_before --> <!-- IF S_DISPLAY_SEARCH or (S_USER_LOGGED_IN and not S_IS_BOT) --> <ul class="linklist bulletin"> @@ -15,20 +17,25 @@ <!-- ENDIF --> <li><a href="{U_SEARCH_ACTIVE_TOPICS}">{L_SEARCH_ACTIVE_TOPICS}</a></li> <!-- ENDIF --> - <!-- IF not S_IS_BOT and U_MARK_FORUMS --><li class="rightside"><a href="{U_MARK_FORUMS}" accesskey="m" data-ajax="mark_forums_read" data-overlay="false">{L_MARK_FORUMS_READ}</a></li><!-- ENDIF --> + <!-- IF not S_IS_BOT and U_MARK_FORUMS --><li class="rightside mark-read"><a href="{U_MARK_FORUMS}" accesskey="m" data-ajax="mark_forums_read">{L_MARK_FORUMS_READ}</a></li><!-- ENDIF --> </ul> <!-- ENDIF --> +<!-- EVENT index_body_linklist_after --> + <!-- INCLUDE forumlist_body.html --> <!-- IF not S_USER_LOGGED_IN and not S_IS_BOT --> <form method="post" action="{S_LOGIN_ACTION}" class="headerspace"> <h3><a href="{U_LOGIN_LOGOUT}">{L_LOGIN_LOGOUT}</a><!-- IF S_REGISTER_ENABLED --> • <a href="{U_REGISTER}">{L_REGISTER}</a><!-- ENDIF --></h3> <fieldset class="quick-login"> - <label for="username">{L_USERNAME}{L_COLON}</label> <input type="text" name="username" id="username" size="10" class="inputbox" title="{L_USERNAME}" /> - <label for="password">{L_PASSWORD}{L_COLON}</label> <input type="password" name="password" id="password" size="10" class="inputbox" title="{L_PASSWORD}" /> + <label for="username"><span>{L_USERNAME}{L_COLON}</span> <input type="text" name="username" id="username" size="10" class="inputbox" title="{L_USERNAME}" /></label> + <label for="password"><span>{L_PASSWORD}{L_COLON}</span> <input type="password" name="password" id="password" size="10" class="inputbox" title="{L_PASSWORD}" /></label> + <!-- IF U_SEND_PASSWORD --> + <a href="{U_SEND_PASSWORD}">{L_FORGOT_PASS}</a> + <!-- ENDIF --> <!-- IF S_AUTOLOGIN_ENABLED --> - | <label for="autologin">{L_LOG_ME_IN} <input type="checkbox" name="autologin" id="autologin" /></label> + <span class="responsive-hide">|</span> <label for="autologin">{L_LOG_ME_IN} <input type="checkbox" name="autologin" id="autologin" /></label> <!-- ENDIF --> <input type="submit" name="login" value="{L_LOGIN}" class="button2" /> {S_LOGIN_REDIRECT} @@ -39,19 +46,27 @@ <!-- EVENT index_body_stat_blocks_before --> <!-- IF S_DISPLAY_ONLINE_LIST --> - <!-- IF U_VIEWONLINE --><h3><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a></h3><!-- ELSE --><h3>{L_WHO_IS_ONLINE}</h3><!-- ENDIF --> - <p>{TOTAL_USERS_ONLINE} ({L_ONLINE_EXPLAIN})<br />{RECORD_USERS}<br /> <br />{LOGGED_IN_USER_LIST} - <!-- IF LEGEND --><br /><em>{L_LEGEND}{L_COLON} {LEGEND}</em><!-- ENDIF --></p> + <div class="stat-block online-list"> + <!-- IF U_VIEWONLINE --><h3><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a></h3><!-- ELSE --><h3>{L_WHO_IS_ONLINE}</h3><!-- ENDIF --> + <p>{TOTAL_USERS_ONLINE} ({L_ONLINE_EXPLAIN})<br />{RECORD_USERS}<br /> <br />{LOGGED_IN_USER_LIST} + <!-- IF LEGEND --><br /><em>{L_LEGEND}{L_COLON} {LEGEND}</em><!-- ENDIF --></p> + </div> <!-- ENDIF --> <!-- IF S_DISPLAY_BIRTHDAY_LIST --> - <h3>{L_BIRTHDAYS}</h3> - <p><!-- IF .birthdays -->{L_CONGRATULATIONS}{L_COLON} <strong><!-- BEGIN birthdays -->{birthdays.USERNAME}<!-- IF birthdays.AGE !== '' --> ({birthdays.AGE})<!-- ENDIF --><!-- IF not birthdays.S_LAST_ROW -->, <!-- ENDIF --><!-- END birthdays --></strong><!-- ELSE -->{L_NO_BIRTHDAYS}<!-- ENDIF --></p> + <div class="stat-block birthday-list"> + <h3>{L_BIRTHDAYS}</h3> + <p><!-- IF .birthdays -->{L_CONGRATULATIONS}{L_COLON} <strong><!-- BEGIN birthdays -->{birthdays.USERNAME}<!-- IF birthdays.AGE !== '' --> ({birthdays.AGE})<!-- ENDIF --><!-- IF not birthdays.S_LAST_ROW -->, <!-- ENDIF --><!-- END birthdays --></strong><!-- ELSE -->{L_NO_BIRTHDAYS}<!-- ENDIF --></p> + </div> <!-- ENDIF --> <!-- IF NEWEST_USER --> - <h3>{L_STATISTICS}</h3> - <p>{TOTAL_POSTS} • {TOTAL_TOPICS} • {TOTAL_USERS} • {NEWEST_USER}</p> + <div class="stat-block statistics"> + <h3>{L_STATISTICS}</h3> + <p>{TOTAL_POSTS} • {TOTAL_TOPICS} • {TOTAL_USERS} • {NEWEST_USER}</p> + </div> <!-- ENDIF --> +<!-- EVENT index_body_stat_blocks_after --> + <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/styles/prosilver/template/jumpbox.html b/phpBB/styles/prosilver/template/jumpbox.html index 201b2dece2..47d322407d 100644 --- a/phpBB/styles/prosilver/template/jumpbox.html +++ b/phpBB/styles/prosilver/template/jumpbox.html @@ -1,10 +1,10 @@ <!-- IF S_VIEWTOPIC --> - <p class="jumpbox-return"><a href="{U_VIEW_FORUM}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO} {FORUM_NAME}</a></p> + <p class="jumpbox-return"><a href="{U_VIEW_FORUM}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO_FORUM}</a></p> <!-- ELSEIF S_VIEWFORUM --> - <p class="jumpbox-return"><a href="{U_INDEX}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO} {L_INDEX}</a></p> + <p class="jumpbox-return"><a href="{U_INDEX}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO_INDEX}</a></p> <!-- ELSEIF SEARCH_TOPIC --> - <p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}" accesskey="r">{L_RETURN_TO}{L_COLON} {SEARCH_TOPIC}</a></p> + <p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}" accesskey="r">{L_RETURN_TO_TOPIC}</a></p> <!-- ELSEIF S_SEARCH_ACTION --> <p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH}" title="{L_SEARCH_ADV}" accesskey="r">{L_RETURN_TO_SEARCH_ADV}</a></p> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/login_body.html b/phpBB/styles/prosilver/template/login_body.html index 38d9f8c68b..c852ffd5f2 100644 --- a/phpBB/styles/prosilver/template/login_body.html +++ b/phpBB/styles/prosilver/template/login_body.html @@ -5,7 +5,7 @@ <div class="inner"> <div class="content"> - <h2><!-- IF LOGIN_EXPLAIN -->{LOGIN_EXPLAIN}<!-- ELSE -->{L_LOGIN}<!-- ENDIF --></h2> + <h2 class="login-title"><!-- IF LOGIN_EXPLAIN -->{LOGIN_EXPLAIN}<!-- ELSE -->{L_LOGIN}<!-- ENDIF --></h2> <fieldset <!-- IF not S_CONFIRM_CODE -->class="fields1"<!-- ELSE -->class="fields2"<!-- ENDIF -->> <!-- IF LOGIN_ERROR --><div class="error">{LOGIN_ERROR}</div><!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/login_forum.html b/phpBB/styles/prosilver/template/login_forum.html index c83a625b3f..18a95c0a8f 100644 --- a/phpBB/styles/prosilver/template/login_forum.html +++ b/phpBB/styles/prosilver/template/login_forum.html @@ -1,6 +1,6 @@ <!-- INCLUDE overall_header.html --> -<!-- IF FORUM_NAME --><h2><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2><!-- ENDIF --> +<!-- IF FORUM_NAME --><h2 class="forum-title"><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2><!-- ENDIF --> <form id="login_forum" method="post" action="{S_LOGIN_ACTION}"> {S_FORM_TOKEN} @@ -8,7 +8,7 @@ <div class="inner"> <div class="content"> - <h2>{L_LOGIN}</h2> + <h2 class="login-title">{L_LOGIN}</h2> <p>{L_LOGIN_FORUM}</p> diff --git a/phpBB/styles/prosilver/template/mcp_approve.html b/phpBB/styles/prosilver/template/mcp_approve.html index ab7f92e262..14472bcf4f 100644 --- a/phpBB/styles/prosilver/template/mcp_approve.html +++ b/phpBB/styles/prosilver/template/mcp_approve.html @@ -34,7 +34,7 @@ <div class="content"> - <h2>{MESSAGE_TITLE}</h2> + <h2 class="message-title">{MESSAGE_TITLE}</h2> <!-- IF ADDITIONAL_MSG --><p class="error">{ADDITIONAL_MSG}</p><!-- ENDIF --> <fieldset> diff --git a/phpBB/styles/prosilver/template/mcp_footer.html b/phpBB/styles/prosilver/template/mcp_footer.html index e5768bdc6b..89ce7c34ab 100644 --- a/phpBB/styles/prosilver/template/mcp_footer.html +++ b/phpBB/styles/prosilver/template/mcp_footer.html @@ -1,9 +1,8 @@ </div> - <div class="clear"></div> </div> - <span class="corners-bottom"><span></span></span></div> + </div> </div> <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/styles/prosilver/template/mcp_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html index e5dcb94855..4a8c4c5de9 100644 --- a/phpBB/styles/prosilver/template/mcp_forum.html +++ b/phpBB/styles/prosilver/template/mcp_forum.html @@ -40,6 +40,7 @@ <li class="row<!-- IF topicrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF --><!-- IF topicrow.S_TOPIC_REPORTED --> reported<!-- ENDIF -->"> <dl class="icon {topicrow.TOPIC_IMG_STYLE}"> <dt <!-- IF topicrow.TOPIC_ICON_IMG -->style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF -->> + <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}" class="icon-link"></a><!-- ENDIF --> <div class="list-inner"> <!-- IF topicrow.S_SELECT_TOPIC --><a href="{topicrow.U_SELECT_TOPIC}" class="topictitle">[ {L_SELECT_MERGE} ]</a> <!-- ENDIF --> @@ -63,7 +64,15 @@ </ul> </div> <!-- ENDIF --> - <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF -->{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + <div class="responsive-hide"> + <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF --> + {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + </div> + <div class="responsive-show" style="display: none;"> + <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF --> + {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} « {topicrow.LAST_POST_TIME}<br /> + {L_REPLIES}{L_COLON} <strong>{topicrow.REPLIES}</strong> + </div> </div> </dt> @@ -90,7 +99,8 @@ <!-- IF U_PREVIOUS_PAGE --><a href="{U_PREVIOUS_PAGE}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}">{L_PREVIOUS}</a><!-- ENDIF --> <label>{L_DISPLAY_TOPICS}{L_COLON} {S_SELECT_SORT_DAYS}</label> <label>{L_SORT_BY} {S_SELECT_SORT_KEY}</label> - <label>{S_SELECT_SORT_DIR} <input type="submit" name="sort" value="{L_GO}" class="button2" /></label> + <label>{S_SELECT_SORT_DIR}</label> + <input type="submit" name="sort" value="{L_GO}" class="button2" /> </fieldset> <hr /> diff --git a/phpBB/styles/prosilver/template/mcp_front.html b/phpBB/styles/prosilver/template/mcp_front.html index 402cfe029a..44295611cf 100644 --- a/phpBB/styles/prosilver/template/mcp_front.html +++ b/phpBB/styles/prosilver/template/mcp_front.html @@ -21,7 +21,7 @@ </dl> </li> </ul> - <ul class="topiclist cplist missing-column"> + <ul class="topiclist cplist missing-column responsive-show-all"> <!-- BEGIN unapproved --> <li class="row<!-- IF unapproved.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> @@ -75,7 +75,7 @@ </dl> </li> </ul> - <ul class="topiclist cplist two-long-columns"> + <ul class="topiclist cplist two-long-columns responsive-show-all"> <!-- BEGIN report --> <li class="row<!-- IF report.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> @@ -116,7 +116,7 @@ </dl> </li> </ul> - <ul class="topiclist cplist two-long-columns"> + <ul class="topiclist cplist two-long-columns responsive-show-all"> <!-- BEGIN pm_report --> <li class="row<!-- IF pm_report.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> @@ -147,7 +147,7 @@ <h3>{L_LATEST_LOGS}</h3> - <table class="table1" cellspacing="0"> + <table class="table1"> <thead> <tr> <th class="name">{L_ACTION}</th> diff --git a/phpBB/styles/prosilver/template/mcp_header.html b/phpBB/styles/prosilver/template/mcp_header.html index 7b9e4c13cb..bdfa254741 100644 --- a/phpBB/styles/prosilver/template/mcp_header.html +++ b/phpBB/styles/prosilver/template/mcp_header.html @@ -3,10 +3,8 @@ <h2>{L_MCP}</h2> <!-- IF U_MCP --> - <p class="linkmcp"> - [ <a href="{U_MCP}">{L_MCP}</a><!-- IF U_MCP_FORUM --> | <a href="{U_MCP_FORUM}">{L_MODERATE_FORUM}</a><!-- ENDIF --> - <!-- IF U_MCP_TOPIC --> | <a href="{U_MCP_TOPIC}">{L_MODERATE_TOPIC}</a><!-- ENDIF --> - <!-- IF U_MCP_POST --> | <a href="{U_MCP_POST}">{L_MODERATE_POST}</a><!-- ENDIF --> ] + <p class="linkmcp responsive-center"> + [<!-- IF U_ACP --> <a href="{U_ACP}" title="{L_ACP}" data-responsive-text="{L_ACP_SHORT}">{L_ACP}</a> |<!-- ENDIF --> <a href="{U_MCP}" title="{L_MCP}" data-responsive-text="{L_MCP_SHORT}">{L_MCP}</a><!-- IF U_MCP_FORUM --> | <a href="{U_MCP_FORUM}">{L_MODERATE_FORUM}</a><!-- ENDIF --><!-- IF U_MCP_TOPIC --> | <a href="{U_MCP_TOPIC}">{L_MODERATE_TOPIC}</a><!-- ENDIF --><!-- IF U_MCP_POST --> | <a href="{U_MCP_POST}">{L_MODERATE_POST}</a><!-- ENDIF --> ] </p> <!-- ENDIF --> @@ -41,27 +39,11 @@ </div> </div> - <div id="cp-main" class="mcp-main"> + <div id="cp-main" class="mcp-main panel-container"> <!-- IF MESSAGE --> <div class="content"> - <h2>{L_MESSAGE}</h2> + <h2 class="message-title">{L_MESSAGE}</h2> <p class="error">{MESSAGE}</p> <p><!-- BEGIN return_links -->{return_links.MESSAGE_LINK}<br /><br /><!-- END return_links --></p> </div> <!-- ENDIF --> - - <!-- IF CONFIRM_MESSAGE --> - <form id="confirm" method="post" action="{S_CONFIRM_ACTION}"{S_FORM_ENCTYPE}> - - <div class="content"> - <h2>{L_PLEASE_CONFIRM}</h2> - <p>{CONFIRM_MESSAGE}</p> - - <fieldset class="submit-buttons"> - {S_HIDDEN_FIELDS}<input class="button1" type="submit" name="submit" value="{L_YES}" /> - <input class="button2" type="cancel" value="{L_NO}" /> - </fieldset> - </div> - - </form> - <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/mcp_logs.html b/phpBB/styles/prosilver/template/mcp_logs.html index 492c8cf201..b930bbbcc6 100644 --- a/phpBB/styles/prosilver/template/mcp_logs.html +++ b/phpBB/styles/prosilver/template/mcp_logs.html @@ -21,7 +21,7 @@ </li> </ul> - <table cellspacing="1" class="table1"> + <table class="table1"> <thead> <tr> <th>{L_USERNAME}</th> diff --git a/phpBB/styles/prosilver/template/mcp_message.html b/phpBB/styles/prosilver/template/mcp_message.html index 7102c658c4..062103b91c 100644 --- a/phpBB/styles/prosilver/template/mcp_message.html +++ b/phpBB/styles/prosilver/template/mcp_message.html @@ -1,7 +1,7 @@ <!-- INCLUDE mcp_header.html --> <div class="content"> - <h2>{MESSAGE_TITLE}</h2> + <h2 class="message-title">{MESSAGE_TITLE}</h2> <p>{MESSAGE_TEXT}</p> </div> diff --git a/phpBB/styles/prosilver/template/mcp_move.html b/phpBB/styles/prosilver/template/mcp_move.html index c2ee25f0d9..d028fffeb4 100644 --- a/phpBB/styles/prosilver/template/mcp_move.html +++ b/phpBB/styles/prosilver/template/mcp_move.html @@ -37,7 +37,7 @@ <div class="inner"> <div class="content"> - <h2>{MESSAGE_TITLE}</h2> + <h2 class="message-title">{MESSAGE_TITLE}</h2> <!-- IF ADDITIONAL_MSG --><p>{ADDITIONAL_MSG}</p><!-- ENDIF --> <fieldset> diff --git a/phpBB/styles/prosilver/template/mcp_notes_user.html b/phpBB/styles/prosilver/template/mcp_notes_user.html index eb954fd11d..9b6c9b2667 100644 --- a/phpBB/styles/prosilver/template/mcp_notes_user.html +++ b/phpBB/styles/prosilver/template/mcp_notes_user.html @@ -64,7 +64,7 @@ </li> </ul> - <table cellspacing="1" class="table1"> + <table class="table1"> <thead> <tr> <th>{L_REPORT_BY}</th> diff --git a/phpBB/styles/prosilver/template/mcp_post.html b/phpBB/styles/prosilver/template/mcp_post.html index a205164e60..2b4ebec5c8 100644 --- a/phpBB/styles/prosilver/template/mcp_post.html +++ b/phpBB/styles/prosilver/template/mcp_post.html @@ -48,6 +48,8 @@ <div class="inner"> <div class="postbody"> + <h3><a href="{U_VIEW_POST}">{POST_SUBJECT}</a></h3> + <!-- IF U_EDIT --> <ul class="profile-icons"> <li class="edit-icon"><a href="{U_EDIT}" title="{L_EDIT_POST}"><span>{L_EDIT_POST}</span></a></li> @@ -56,7 +58,6 @@ <span class="right-box" id="expand"><a href="#post_details" onclick="viewableArea(getElementById('post_details'), true); var rev_text = getElementById('expand').getElementsByTagName('a').item(0).firstChild; if (rev_text.data == '{LA_EXPAND_VIEW}'){rev_text.data = '{LA_COLLAPSE_VIEW}'; } else if (rev_text.data == '{LA_COLLAPSE_VIEW}'){rev_text.data = '{LA_EXPAND_VIEW}'}; return false;">{L_EXPAND_VIEW}</a></span> - <h3><a href="{U_VIEW_POST}">{POST_SUBJECT}</a></h3> <!-- IF S_PM --> <p class="author"> <strong>{L_SENT_AT}{L_COLON}</strong> {POST_DATE} @@ -263,7 +264,7 @@ <!-- IF POST_IPADDR -->{POST_IPADDR} ({POST_IP})<!-- ELSE -->{POST_IP}<!-- IF U_LOOKUP_IP --> (<a href="{U_LOOKUP_IP}">{L_LOOKUP_IP}</a>)<!-- ENDIF --><!-- ENDIF --> <!-- ENDIF --></p> - <table class="table1" cellspacing="1"> + <table class="table1"> <thead> <tr> <th class="name">{L_OTHER_USERS}</th> @@ -284,7 +285,7 @@ </tbody> </table> - <table class="table1" cellspacing="1"> + <table class="table1"> <thead> <tr> <th class="name">{L_IPS_POSTED_FROM}</th> diff --git a/phpBB/styles/prosilver/template/mcp_queue.html b/phpBB/styles/prosilver/template/mcp_queue.html index c2d39eff98..461d5982db 100644 --- a/phpBB/styles/prosilver/template/mcp_queue.html +++ b/phpBB/styles/prosilver/template/mcp_queue.html @@ -35,7 +35,7 @@ </dl> </li> </ul> - <ul class="topiclist cplist missing-column"> + <ul class="topiclist cplist missing-column responsive-show-all"> <!-- BEGIN postrow --> diff --git a/phpBB/styles/prosilver/template/mcp_reports.html b/phpBB/styles/prosilver/template/mcp_reports.html index 902744fe25..ffa82d5e0e 100644 --- a/phpBB/styles/prosilver/template/mcp_reports.html +++ b/phpBB/styles/prosilver/template/mcp_reports.html @@ -48,6 +48,9 @@ <a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.PM_SUBJECT}</a> {postrow.ATTACH_ICON_IMG}<br /> <span>{L_MESSAGE_BY_AUTHOR} {postrow.PM_AUTHOR_FULL} » {postrow.PM_TIME}</span><br /> <span>{L_MESSAGE_TO} {postrow.RECIPIENTS}</span> + <div class="responsive-show" style="display: none;"> + {L_REPORTER}{L_COLON} {postrow.REPORTER_FULL} « {postrow.REPORT_TIME} + </div> </div> </dt> <dd class="moderation"> @@ -58,6 +61,10 @@ <div class="list-inner"> <a href="{postrow.U_VIEW_DETAILS}" class="topictitle">{postrow.POST_SUBJECT}</a> {postrow.ATTACH_ICON_IMG}<br /> <span>{L_POSTED} {L_POST_BY_AUTHOR} {postrow.POST_AUTHOR_FULL} » {postrow.POST_TIME}</span> + <div class="responsive-show" style="display: none;"> + {L_REPORTER}{L_COLON} {postrow.REPORTER_FULL} « {postrow.REPORT_TIME}<br /> + <!-- IF postrow.U_VIEWFORUM -->{L_FORUM}{L_COLON} <a href="{postrow.U_VIEWFORUM}">{postrow.FORUM_NAME}</a><!-- ELSE -->{postrow.FORUM_NAME}<!-- ENDIF --> + </div> </div> </dt> <dd class="moderation"> diff --git a/phpBB/styles/prosilver/template/mcp_warn_front.html b/phpBB/styles/prosilver/template/mcp_warn_front.html index 5a332cf202..668a0d81a8 100644 --- a/phpBB/styles/prosilver/template/mcp_warn_front.html +++ b/phpBB/styles/prosilver/template/mcp_warn_front.html @@ -33,7 +33,7 @@ <h3>{L_MOST_WARNINGS}</h3> <!-- IF .highest --> - <table class="table1" cellspacing="0"> + <table class="table1"> <thead> <tr> <th class="name">{L_USERNAME}</th> @@ -51,7 +51,7 @@ <td>{highest.WARNING_TIME}</td> <td><a href="{highest.U_NOTES}">{L_VIEW_NOTES}</a></td> </tr> - <!-- END latest --> + <!-- END highest --> </tbody> </table> <!-- ELSE --> @@ -67,7 +67,7 @@ <h3>{L_LATEST_WARNINGS}</h3> <!-- IF .latest --> - <table class="table1" cellspacing="0"> + <table class="table1"> <thead> <tr> <th class="name">{L_USERNAME}</th> diff --git a/phpBB/styles/prosilver/template/mcp_warn_list.html b/phpBB/styles/prosilver/template/mcp_warn_list.html index cdf2aecc0e..731c945fe6 100644 --- a/phpBB/styles/prosilver/template/mcp_warn_list.html +++ b/phpBB/styles/prosilver/template/mcp_warn_list.html @@ -21,7 +21,7 @@ </li> </ul> - <table class="table1" cellspacing="0"> + <table class="table1"> <thead> <tr> <th class="name">{L_USERNAME}</th> diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html index 46b35eae2c..dd5e27a10e 100644 --- a/phpBB/styles/prosilver/template/memberlist_body.html +++ b/phpBB/styles/prosilver/template/memberlist_body.html @@ -14,7 +14,7 @@ <!-- IF S_SHOW_GROUP --> - <h2<!-- IF GROUP_COLOR --> style="color:#{GROUP_COLOR};"<!-- ENDIF -->>{GROUP_NAME}</h2> + <h2 class="group-title"<!-- IF GROUP_COLOR --> style="color:#{GROUP_COLOR};"<!-- ENDIF -->>{GROUP_NAME}</h2> <p>{GROUP_DESC} {GROUP_TYPE}</p> <p> <!-- IF AVATAR_IMG -->{AVATAR_IMG}<!-- ENDIF --> @@ -28,7 +28,7 @@ <div class="panel"> <div class="inner"> - <ul class="linklist"> + <ul class="linklist wrap"> <li> <!-- IF U_FIND_MEMBER and not S_SEARCH_USER --><a href="{U_FIND_MEMBER}" id="member_search" data-alt-text="{LA_HIDE_MEMBER_SEARCH}">{L_FIND_USERNAME}</a> • <!-- ELSEIF S_SEARCH_USER and U_HIDE_FIND_MEMBER and not S_IN_SEARCH_POPUP --><a href="{U_HIDE_FIND_MEMBER}" id="member_search" data-alt-text="{LA_FIND_USERNAME}">{L_HIDE_MEMBER_SEARCH}</a> • <!-- ENDIF --> <strong style="font-size: 0.95em;"> @@ -55,12 +55,12 @@ <div class="forumbg forumbg-table"> <div class="inner"> - <table class="table1" cellspacing="1" id="memberlist"> + <table class="table1" id="memberlist"> <thead> <tr> - <th class="name"><span class="rank-img"><a href="{U_SORT_RANK}">{L_RANK}</a></span><a href="{U_SORT_USERNAME}"><!-- IF S_SHOW_GROUP and .memberrow -->{L_GROUP_LEADER}<!-- ELSE -->{L_USERNAME}<!-- ENDIF --></a></th> + <th class="name" data-dfn="{L_RANK}{L_COMMA_SEPARATOR}<!-- IF S_SHOW_GROUP and .memberrow -->{L_GROUP_LEADER}<!-- ELSE -->{L_USERNAME}<!-- ENDIF -->"><span class="rank-img"><a href="{U_SORT_RANK}">{L_RANK}</a></span><a href="{U_SORT_USERNAME}"><!-- IF S_SHOW_GROUP and .memberrow -->{L_GROUP_LEADER}<!-- ELSE -->{L_USERNAME}<!-- ENDIF --></a></th> <th class="posts"><a href="{U_SORT_POSTS}#memberlist">{L_POSTS}</a></th> - <th class="info"><a href="{U_SORT_WEBSITE}#memberlist">{L_WEBSITE}</a>{L_COMMA_SEPARATOR}<a href="{U_SORT_LOCATION}">{L_LOCATION}</a></th> + <th class="info"><!-- BEGIN custom_fields --><!-- IF not custom_fields.S_FIRST_ROW -->{L_COMMA_SEPARATOR} <!-- ENDIF -->{custom_fields.PROFILE_FIELD_NAME}<!-- END custom_fields --></th> <th class="joined"><a href="{U_SORT_JOINED}#memberlist">{L_JOINED}</a></th> <!-- IF U_SORT_ACTIVE --><th class="active"><a href="{U_SORT_ACTIVE}#memberlist">{L_LAST_ACTIVE}</a></th><!-- ENDIF --> </tr> @@ -85,13 +85,13 @@ <div class="forumbg forumbg-table"> <div class="inner"> - <table class="table1" cellspacing="1"> + <table class="table1"> <thead> <tr> <!-- IF not S_LEADERS_SET --> - <th class="name"><span class="rank-img"><a href="{U_SORT_RANK}">{L_RANK}</a></span><a href="{U_SORT_USERNAME}"><!-- IF S_SHOW_GROUP -->{L_GROUP_MEMBERS}<!-- ELSE -->{L_USERNAME}<!-- ENDIF --></a></th> + <th class="name" data-dfn="{L_RANK}{L_COMMA_SEPARATOR}{L_USERNAME}"><span class="rank-img"><a href="{U_SORT_RANK}">{L_RANK}</a></span><a href="{U_SORT_USERNAME}"><!-- IF S_SHOW_GROUP -->{L_GROUP_MEMBERS}<!-- ELSE -->{L_USERNAME}<!-- ENDIF --></a></th> <th class="posts"><a href="{U_SORT_POSTS}#memberlist">{L_POSTS}</a></th> - <th class="info"><a href="{U_SORT_WEBSITE}#memberlist">{L_WEBSITE}</a>{L_COMMA_SEPARATOR}<a href="{U_SORT_LOCATION}">{L_LOCATION}</a></th> + <th class="info"><!-- BEGIN custom_fields --><!-- IF not custom_fields.S_FIRST_ROW -->{L_COMMA_SEPARATOR} <!-- ENDIF -->{custom_fields.PROFILE_FIELD_NAME}<!-- END custom_fields --></th> <th class="joined"><a href="{U_SORT_JOINED}#memberlist">{L_JOINED}</a></th> <!-- IF U_SORT_ACTIVE --><th class="active"><a href="{U_SORT_ACTIVE}#memberlist">{L_LAST_ACTIVE}</a></th><!-- ENDIF --> <!-- ELSEIF S_SHOW_GROUP --> @@ -111,9 +111,9 @@ <tr class="<!-- IF memberrow.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF -->"> <td><!-- IF memberrow.RANK_IMG --><span class="rank-img">{memberrow.RANK_IMG}</span><!-- ELSE --><span class="rank-img">{memberrow.RANK_TITLE}</span><!-- ENDIF --><!-- IF S_IN_SEARCH_POPUP and not S_SELECT_SINGLE --><input type="checkbox" name="user" value="{memberrow.USERNAME}" /> <!-- ENDIF --><!-- EVENT memberlist_body_username_prepend -->{memberrow.USERNAME_FULL}<!-- EVENT memberlist_body_username_append --><!-- IF S_IN_SEARCH_POPUP --><br />[ <a href="#" onclick="insert_single_user('#results', '{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a> ]<!-- ENDIF --></td> <td class="posts"><!-- IF memberrow.POSTS and S_DISPLAY_SEARCH --><a href="{memberrow.U_SEARCH_USER}" title="{L_SEARCH_USER_POSTS}">{memberrow.POSTS}</a><!-- ELSE -->{memberrow.POSTS}<!-- ENDIF --></td> - <td class="info"><!-- IF memberrow.U_WWW or memberrow.LOCATION --><!-- IF memberrow.U_WWW --><div><a href="{memberrow.U_WWW}" title="{L_VISIT_WEBSITE}{L_COLON} {memberrow.U_WWW}">{memberrow.U_SHORT_WWW}</a></div><!-- ENDIF --><!-- IF memberrow.LOCATION --><div>{memberrow.LOCATION}</div><!-- ENDIF --><!-- ELSE --> <!-- ENDIF --></td> + <td class="info"><!-- BEGIN custom_fields --><div>{memberrow.custom_fields.PROFILE_FIELD_VALUE}</div><!-- BEGINELSE --> <!-- END custom_fields --></td> <td>{memberrow.JOINED}</td> - <!-- IF S_VIEWONLINE --><td>{memberrow.VISITED} </td><!-- ENDIF --> + <!-- IF S_VIEWONLINE --><td>{memberrow.LAST_ACTIVE} </td><!-- ENDIF --> </tr> <!-- BEGINELSE --> <tr class="bg1"> @@ -143,7 +143,8 @@ <!-- IF U_PREVIOUS_PAGE --><a href="{U_PREVIOUS_PAGE}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}">{L_PREVIOUS}</a><!-- ENDIF --> <!-- IF U_NEXT_PAGE --><a href="{U_NEXT_PAGE}" class="right-box arrow-{S_CONTENT_FLOW_END}">{L_NEXT}</a><!-- ENDIF --> <label for="sk">{L_SELECT_SORT_METHOD}{L_COLON} <select name="sk" id="sk">{S_MODE_SELECT}</select></label> - <label for="sd">{L_ORDER} <select name="sd" id="sd">{S_ORDER_SELECT}</select> <input type="submit" name="sort" value="{L_SUBMIT}" class="button2" /></label> + <label for="sd">{L_ORDER} <select name="sd" id="sd">{S_ORDER_SELECT}</select></label> + <input type="submit" name="sort" value="{L_SUBMIT}" class="button2" /> </fieldset> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/memberlist_im.html b/phpBB/styles/prosilver/template/memberlist_im.html index 8e7842e631..4fb383a0ba 100644 --- a/phpBB/styles/prosilver/template/memberlist_im.html +++ b/phpBB/styles/prosilver/template/memberlist_im.html @@ -1,9 +1,8 @@ <!-- INCLUDE simple_header.html --> -<!-- MSNM info from http://www.cdolive.net/ - doesn't seem to work with MSN Messenger --> <h2 class="solo">{L_SEND_IM}</h2> -<form method="post" action="{S_IM_ACTION}" data-lang-im-msnm-connect="{L_IM_MSNM_CONNECT|e('html_attr')}" data-lang-im-msnm-browser="{L_IM_MSNM_BROWSER|e('html_attr')}"> +<form method="post" action="{S_IM_ACTION}"> <div class="panel bg2"> <div class="inner"> @@ -13,45 +12,9 @@ <fieldset> <dl class="fields2"> <dt><label>{L_IM_RECIPIENT}{L_COLON}</label></dt> - <dd><strong>{USERNAME}</strong><!-- IF S_SEND_ICQ or S_SEND_AIM or S_SEND_MSNM or S_NO_SEND_JABBER --> [ {IM_CONTACT} ]<!-- ENDIF --><!-- IF PRESENCE_IMG --> {PRESENCE_IMG}<!-- ENDIF --></dd> + <dd><strong>{USERNAME}</strong><!-- IF S_NO_SEND_JABBER --> [ {IM_CONTACT} ]<!-- ENDIF --><!-- IF PRESENCE_IMG --> {PRESENCE_IMG}<!-- ENDIF --></dd> </dl> - <!-- IF S_SEND_ICQ --> - <dl class="fields2"> - <dt><label for="from">{L_IM_NAME}{L_COLON}</label></dt> - <dd><input class="inputbox autowidth" type="text" name="from" id="from" size="20" /></dd> - </dl> - <dl class="fields2"> - <dt><label for="body">{L_IM_MESSAGE}{L_COLON}</label></dt> - <dd><textarea class="inputbox autowidth" name="body" id="body" rows="5" cols="45"></textarea></dd> - </dl> - <dl class="fields2"> - <dt> </dt> - <dd><input class="button1" name="submit" type="submit" value="{L_IM_SEND}" /></dd> - </dl> - <input type="hidden" name="fromemail" value="{EMAIL}" /> - <input type="hidden" name="subject" value="{SITENAME}" /> - <input type="hidden" name="to" value="{IM_CONTACT}" /> - <!-- ENDIF --> - - <!-- IF S_SEND_AIM --> - <dl class="fields2"> - <dt> </dt> - <dd><a href="{U_AIM_CONTACT}">{L_IM_ADD_CONTACT}</a></dd> - <dd><a href="{U_AIM_MESSAGE}">{L_IM_SEND_MESSAGE}</a></dd> - <dd><a href="http://www.aim.com">{L_IM_DOWNLOAD_APP}</a> | <a href="http://www.aim.com/products/express">{L_IM_AIM_EXPRESS}</a></dd> - </dl> - <!-- ENDIF --> - - <!-- IF S_SEND_MSNM --> - <dl class="fields2"> - <dt> </dt> - <dd><object classid="clsid:B69003B3-C55E-4B48-836C-BC5946FC3B28" codetype="application/x-oleobject" id="objMessengerApp" width="0" height="0"></object></dd> - <dd><a href="#" onclick="add_contact('{A_IM_CONTACT}'); return false;">{L_IM_ADD_CONTACT}</a></dd> - <dd><a href="#" onclick="im_contact('{A_IM_CONTACT}'); return false;">{L_IM_SEND_MESSAGE}</a></dd> - </dl> - <!-- ENDIF --> - <!-- IF S_SEND_JABBER --> <dl class="fields2"> <dt><label for="message">{L_IM_MESSAGE}{L_COLON}</label></dt> @@ -61,19 +24,14 @@ <dt> </dt> <dd><input class="button1" name="submit" type="submit" value="{L_IM_SEND}" /></dd> </dl> - <!-- ENDIF --> - - <!-- IF S_NO_SEND_JABBER --> <dl class="fields2"> <dt> </dt> - <dd>{L_IM_NO_JABBER}</dd> + <dd>{L_IM_SENT_JABBER}</dd> </dl> - <!-- ENDIF --> - - <!-- IF S_SENT_JABBER --> + <!-- ELSE IF S_NO_SEND_JABBER --> <dl class="fields2"> <dt> </dt> - <dd>{L_IM_SENT_JABBER}</dd> + <dd>{L_IM_NO_JABBER}</dd> </dl> <!-- ENDIF --> {S_FORM_TOKEN} diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html index 0b04d0087c..ee89b103b5 100644 --- a/phpBB/styles/prosilver/template/memberlist_search.html +++ b/phpBB/styles/prosilver/template/memberlist_search.html @@ -18,25 +18,17 @@ </dl> <!-- ENDIF --> <dl> - <dt><label for="icq">{L_ICQ}{L_COLON}</label></dt> - <dd><input type="text" name="icq" id="icq" value="{ICQ}" class="inputbox" /></dd> - </dl> - <dl> - <dt><label for="aim">{L_AIM}{L_COLON}</label></dt> - <dd><input type="text" name="aim" id="aim" value="{AIM}" class="inputbox" /></dd> - </dl> - <dl> - <dt><label for="yahoo">{L_YIM}{L_COLON}</label></dt> - <dd><input type="text" name="yahoo" id="yahoo" value="{YAHOO}" class="inputbox" /></dd> - </dl> - <dl> - <dt><label for="msn">{L_MSNM}{L_COLON}</label></dt> - <dd><input type="text" name="msn" id="msn" value="{MSNM}" class="inputbox" /></dd> - </dl> - <dl> <dt><label for="jabber">{L_JABBER}:</label></dt> <dd><input type="text" name="jabber" id="jabber" value="{JABBER}" class="inputbox" /></dd> </dl> + <dl> + <dt><label for="search_group_id">{L_GROUP}{L_COLON}</label></dt> + <dd><select name="search_group_id" id="search_group_id">{S_GROUP_SELECT}</select></dd> + </dl> + <dl> + <dt><label for="sk" class="label3">{L_SORT_BY}{L_COLON}</label></dt> + <dd><select name="sk" id="sk">{S_SORT_OPTIONS}</select> <select name="sd">{S_ORDER_SELECT}</select></dd> + </dl> </fieldset> <fieldset class="fields1 column2"> @@ -60,14 +52,6 @@ <dd><input class="inputbox medium" type="text" name="ip" id="ip" value="{IP}" /></dd> </dl> <!-- ENDIF --> - <dl> - <dt><label for="search_group_id">{L_GROUP}{L_COLON}</label></dt> - <dd><select name="search_group_id" id="search_group_id">{S_GROUP_SELECT}</select></dd> - </dl> - <dl> - <dt><label for="sk" class="label3">{L_SORT_BY}{L_COLON}</label></dt> - <dd><select name="sk" id="sk">{S_SORT_OPTIONS}</select> <select name="sd">{S_ORDER_SELECT}</select></dd> - </dl> </fieldset> <div class="clear"></div> diff --git a/phpBB/styles/prosilver/template/memberlist_leaders.html b/phpBB/styles/prosilver/template/memberlist_team.html index d0daa564c1..fd2ba564d3 100644 --- a/phpBB/styles/prosilver/template/memberlist_leaders.html +++ b/phpBB/styles/prosilver/template/memberlist_team.html @@ -8,10 +8,10 @@ <div class="forumbg forumbg-table"> <div class="inner"> - <table class="table1" cellspacing="1"> + <table class="table1"> <thead> <tr> - <th class="name"><span class="rank-img">{L_RANK} </span><!-- IF group.U_GROUP --><a href="{group.U_GROUP}">{group.GROUP_NAME}</a><!-- ELSE -->{group.GROUP_NAME}<!-- ENDIF --></th> + <th class="name" data-dfn="{L_RANK}{L_COMMA_SEPARATOR}{L_USERNAME}"><span class="rank-img">{L_RANK} </span><!-- IF group.U_GROUP --><a href="{group.U_GROUP}">{group.GROUP_NAME}</a><!-- ELSE -->{group.GROUP_NAME}<!-- ENDIF --></th> <th class="info">{L_PRIMARY_GROUP}</th> <!-- IF S_DISPLAY_MODERATOR_FORUMS --><th class="info">{L_MODERATOR}</th><!-- ENDIF --> </tr> diff --git a/phpBB/styles/prosilver/template/memberlist_view.html b/phpBB/styles/prosilver/template/memberlist_view.html index 0d103b5914..3ef3f7ca07 100644 --- a/phpBB/styles/prosilver/template/memberlist_view.html +++ b/phpBB/styles/prosilver/template/memberlist_view.html @@ -1,6 +1,6 @@ <!-- INCLUDE overall_header.html --> -<h2>{PAGE_TITLE}</h2> +<h2 class="memberlist-title">{PAGE_TITLE}</h2> <form method="post" action="{S_PROFILE_ACTION}" id="viewprofile"> <div class="panel bg1<!-- IF S_ONLINE --> online<!-- ENDIF -->"> @@ -14,7 +14,7 @@ </dl> <!-- ENDIF --> - <dl class="left-box details" style="width: 80%;"> + <dl class="left-box details profile-details"> <dt>{L_USERNAME}{L_COLON}</dt> <dd> <!-- IF USER_COLOR --><span style="color: {USER_COLOR}; font-weight: bold;"><!-- ELSE --><span><!-- ENDIF -->{USERNAME}</span> @@ -27,12 +27,13 @@ <!-- IF RANK_IMG --><dt><!-- IF RANK_TITLE --> <!-- ELSE -->{L_RANK}{L_COLON}<!-- ENDIF --></dt> <dd>{RANK_IMG}</dd><!-- ENDIF --> <!-- ENDIF --> <!-- IF S_USER_INACTIVE --><dt>{L_USER_IS_INACTIVE}{L_COLON}</dt> <dd>{USER_INACTIVE_REASON}</dd><!-- ENDIF --> - <!-- IF LOCATION --><dt>{L_LOCATION}{L_COLON}</dt> <dd>{LOCATION}</dd><!-- ENDIF --> <!-- IF AGE !== '' --><dt>{L_AGE}{L_COLON}</dt> <dd>{AGE}</dd><!-- ENDIF --> - <!-- IF OCCUPATION --><dt>{L_OCCUPATION}{L_COLON}</dt> <dd>{OCCUPATION}</dd><!-- ENDIF --> - <!-- IF INTERESTS --><dt>{L_INTERESTS}{L_COLON}</dt> <dd>{INTERESTS}</dd><!-- ENDIF --> <!-- IF S_GROUP_OPTIONS --><dt>{L_USERGROUPS}{L_COLON}</dt> <dd><select name="g">{S_GROUP_OPTIONS}</select> <input type="submit" name="submit" value="{L_GO}" class="button2" /></dd><!-- ENDIF --> - <!-- BEGIN custom_fields --><dt>{custom_fields.PROFILE_FIELD_NAME}{L_COLON}</dt> <dd>{custom_fields.PROFILE_FIELD_VALUE}</dd><!-- END custom_fields --> + <!-- BEGIN custom_fields --> + <!-- IF not custom_fields.S_PROFILE_CONTACT --> + <dt>{custom_fields.PROFILE_FIELD_NAME}{L_COLON}</dt> <dd>{custom_fields.PROFILE_FIELD_VALUE}</dd> + <!-- ENDIF --> + <!-- END custom_fields --> <!-- IF S_USER_LOGGED_IN and S_ZEBRA --> <!-- IF U_REMOVE_FRIEND --> <dt> </dt> <dd class="zebra"><a href="{U_REMOVE_FRIEND}" data-ajax="zebra"><strong>{L_REMOVE_FRIEND}</strong></a></dd> @@ -49,24 +50,30 @@ <!-- ENDIF --> </dl> - <span class="clear"></span></div> + </div> </div> +<!-- EVENT memberlist_view_contact_before --> <div class="panel bg2"> <div class="inner"> - <div class="column1"> + <div class="column1"> <h3>{L_CONTACT_USER} {USERNAME}</h3> <dl class="details"> <!-- IF U_EMAIL --><dt>{L_EMAIL_ADDRESS}{L_COLON}</dt> <dd><a href="{U_EMAIL}">{L_SEND_EMAIL_USER} {USERNAME}</a></dd><!-- ENDIF --> - <!-- IF U_WWW --><dt>{L_WEBSITE}{L_COLON}</dt> <dd><a href="{U_WWW}" title="{L_VISIT_WEBSITE}{L_COLON} {U_WWW}">{U_WWW}</a></dd><!-- ENDIF --> <!-- IF U_PM --><dt>{L_PM}{L_COLON}</dt> <dd><a href="{U_PM}">{L_SEND_PRIVATE_MESSAGE}</a></dd><!-- ENDIF --> - <!-- IF U_MSN or USER_MSN --><dt>{L_MSNM}{L_COLON}</dt> <dd><!-- IF U_MSN --><a href="{U_MSN}" onclick="popup(this.href, 550, 320); return false;">{L_SEND_MSNM_MESSAGE}</a><!-- ELSE -->{USER_MSN}<!-- ENDIF --></dd><!-- ENDIF --> - <!-- IF U_YIM or USER_YIM --><dt>{L_YIM}{L_COLON}</dt> <dd><!-- IF U_YIM --><a href="{U_YIM}" onclick="popup(this.href, 780, 550); return false;">{L_SEND_YIM_MESSAGE}</a><!-- ELSE -->{USER_YIM}<!-- ENDIF --></dd><!-- ENDIF --> - <!-- IF U_AIM or USER_AIM --><dt>{L_AIM}{L_COLON}</dt> <dd><!-- IF U_AIM --><a href="{U_AIM}" onclick="popup(this.href, 550, 320); return false;">{L_SEND_AIM_MESSAGE}</a><!-- ELSE -->{USER_AIM}<!-- ENDIF --></dd><!-- ENDIF --> - <!-- IF U_ICQ or USER_ICQ --><dt>{L_ICQ}{L_COLON}</dt> <dd><!-- IF U_ICQ --><a href="{U_ICQ}" onclick="popup(this.href, 550, 320); return false;">{L_SEND_ICQ_MESSAGE}</a><!-- ELSE -->{USER_ICQ}<!-- ENDIF --></dd><!-- ENDIF --> <!-- IF U_JABBER and S_JABBER_ENABLED --><dt>{L_JABBER}{L_COLON}</dt> <dd><a href="{U_JABBER}" onclick="popup(this.href, 550, 320); return false;">{L_SEND_JABBER_MESSAGE}</a></dd><!-- ELSEIF USER_JABBER --><dt>{L_JABBER}{L_COLON}</dt> <dd>{USER_JABBER}</dd><!-- ENDIF --> + <!-- BEGIN custom_fields --> + <!-- IF custom_fields.S_PROFILE_CONTACT --> + <dt>{custom_fields.PROFILE_FIELD_NAME}{L_COLON}</dt> + <!-- IF custom_fields.PROFILE_FIELD_CONTACT --> + <dd><a href="{custom_fields.PROFILE_FIELD_CONTACT}">{custom_fields.PROFILE_FIELD_DESC}</a></dd> + <!-- ELSE --> + <dd>{custom_fields.PROFILE_FIELD_VALUE}</dd> + <!-- ENDIF --> + <!-- ENDIF --> + <!-- END custom_fields --> <!-- IF S_PROFILE_FIELD1 --> <!-- NOTE: Use a construct like this to include admin defined profile fields. Replace FIELD1 with the name of your field. --> <dt>{PROFILE_FIELD1_NAME}{L_COLON}</dt> <dd>{PROFILE_FIELD1_VALUE}</dd> @@ -79,7 +86,7 @@ <dl class="details"> <!-- EVENT memberlist_view_user_statistics_before --> <dt>{L_JOINED}{L_COLON}</dt> <dd>{JOINED}</dd> - <dt>{L_VISITED}{L_COLON}</dt> <dd>{VISITED}</dd> + <dt>{L_LAST_ACTIVE}{L_COLON}</dt> <dd>{LAST_ACTIVE}</dd> <!-- IF S_WARNINGS --> <dt>{L_WARNINGS}{L_COLON} </dt> <dd><strong>{WARNINGS}</strong><!-- IF U_NOTES or U_WARN --> [ <!-- IF U_NOTES --><a href="{U_NOTES}">{L_VIEW_NOTES}</a><!-- ENDIF --> <!-- IF U_WARN --><!-- IF U_NOTES --> | <!-- ENDIF --><a href="{U_WARN}">{L_WARN_USER}</a><!-- ENDIF --> ]<!-- ENDIF --></dd> @@ -96,8 +103,10 @@ <!-- EVENT memberlist_view_user_statistics_after --> </dl> </div> - <span class="clear"></span></div> + + </div> </div> +<!-- EVENT memberlist_view_contact_after --> <!-- IF SIGNATURE --> <div class="panel bg1"> @@ -105,14 +114,16 @@ <h3>{L_SIGNATURE}</h3> - <div class="postbody"><div class="signature" style="border-top:none; margin-top: 0;">{SIGNATURE}</div></div> + <div class="postbody"><div class="signature standalone">{SIGNATURE}</div></div> - <span class="clear"></span></div> + </div> </div> <!-- ENDIF --> </form> +<!-- EVENT memberlist_view_content_append --> + <!-- INCLUDE jumpbox.html --> <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/styles/prosilver/template/message_body.html b/phpBB/styles/prosilver/template/message_body.html index a844246055..8062fed9a0 100644 --- a/phpBB/styles/prosilver/template/message_body.html +++ b/phpBB/styles/prosilver/template/message_body.html @@ -6,7 +6,7 @@ <div class="panel" id="message"> <div class="inner"> - <h2>{MESSAGE_TITLE}</h2> + <h2 class="message-title">{MESSAGE_TITLE}</h2> <p>{MESSAGE_TEXT}</p> <!-- IF SCRIPT_NAME == "search" and not S_BOARD_DISABLED and not S_NO_SEARCH and L_RETURN_TO_SEARCH_ADV --><p><a href="{U_SEARCH}" class="arrow-{S_CONTENT_FLOW_BEGIN}">{L_RETURN_TO_SEARCH_ADV}</a></p><!-- ENDIF --> </div> diff --git a/phpBB/styles/prosilver/template/navbar_footer.html b/phpBB/styles/prosilver/template/navbar_footer.html new file mode 100644 index 0000000000..13e50dae19 --- /dev/null +++ b/phpBB/styles/prosilver/template/navbar_footer.html @@ -0,0 +1,23 @@ +<div class="navbar"> + <div class="inner"> + + <ul class="linklist bulletin"> + <li class="small-icon icon-home breadcrumbs"> + <!-- IF U_SITE_HOME --><span class="crumb"><a href="{U_SITE_HOME}">{L_SITE_HOME}</a></span><!-- ENDIF --> + <span class="crumb"><a href="{U_INDEX}">{L_INDEX}</a></span> + <!-- EVENT overall_footer_breadcrumb_append --> + </li> + <!-- IF not S_IS_BOT --> + <!-- IF U_WATCH_FORUM_LINK --><li class="small-icon icon-<!-- IF S_WATCHING_FORUM -->unsubscribe<!-- ELSE -->subscribe<!-- ENDIF -->"><a href="{U_WATCH_FORUM_LINK}" title="{S_WATCH_FORUM_TITLE}" data-ajax="toggle_link" data-toggle-class="small-icon icon-<!-- IF not S_WATCHING_FORUM -->unsubscribe<!-- ELSE -->subscribe<!-- ENDIF -->" data-toggle-text="{S_WATCH_FORUM_TOGGLE}" data-toggle-url="{U_WATCH_FORUM_TOGGLE}">{S_WATCH_FORUM_TITLE}</a></li><!-- ENDIF --> + <!-- ENDIF --> + <!-- EVENT overall_footer_timezone_before --> + <li class="rightside">{S_TIMEZONE}</li> + <!-- EVENT overall_footer_timezone_after --> + <!-- IF not S_IS_BOT --><li class="rightside"><a href="{U_DELETE_COOKIES}" data-ajax="true" data-refresh="true">{L_DELETE_COOKIES}</a></li><!-- ENDIF --> + <!-- EVENT overall_footer_teamlink_before --> + <!-- IF U_TEAM --><li class="rightside"><a href="{U_TEAM}">{L_THE_TEAM}</a></li><!-- ENDIF --> + <!-- EVENT overall_footer_teamlink_after --> + </ul> + + </div> +</div> diff --git a/phpBB/styles/prosilver/template/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html new file mode 100644 index 0000000000..7fbaa1254f --- /dev/null +++ b/phpBB/styles/prosilver/template/navbar_header.html @@ -0,0 +1,52 @@ +<div class="navbar"> + <div class="inner"> + + <ul class="linklist navlinks"> + <!-- DEFINE $MICRODATA = ' itemtype="http://data-vocabulary.org/Breadcrumb" itemscope=""' --> + <li class="small-icon icon-home breadcrumbs"> + <!-- IF U_SITE_HOME --><span class="crumb"><a href="{U_SITE_HOME}"{$MICRODATA}>{L_SITE_HOME}</a></span><!-- ENDIF --> + <span class="crumb"><a href="{U_INDEX}" accesskey="h"{$MICRODATA}>{L_INDEX}</a></span> + <!-- BEGIN navlinks --><span class="crumb"><a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}>{navlinks.FORUM_NAME}</a></span><!-- END navlinks --> + <!-- EVENT overall_header_breadcrumb_append --> + </li> + + <!-- IF S_REGISTERED_USER --><li id="username_logged_in" class="rightside"><!-- IF CURRENT_USER_AVATAR --><a href="{U_USER_PROFILE}" class="header-avatar">{CURRENT_USER_AVATAR}</a> <!-- ENDIF -->{USERNAME_FULL}</li><!-- ENDIF --> + <!-- IF S_DISPLAY_SEARCH and not S_IN_SEARCH --><li class="responsive-search rightside" style="display: none;"><a href="{U_SEARCH}" title="{L_SEARCH_ADV_EXPLAIN}">{L_SEARCH}</a></li><!-- ENDIF --> + </ul> + + <ul class="linklist bulletin"> + <!-- IF not S_IS_BOT and S_USER_LOGGED_IN --> + <!-- IF S_NOTIFICATIONS_DISPLAY --> + <li class="small-icon icon-notification" data-skip-responsive="true"> + <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button"><span>{L_NOTIFICATIONS} [</span><strong>{NOTIFICATIONS_COUNT}</strong><span>]</span></a> + <!-- INCLUDE notification_dropdown.html --> + </li> + <!-- ENDIF --> + <!-- IF S_DISPLAY_PM --> + <li class="small-icon icon-pm"> + <a href="{U_PRIVATEMSGS}"><span>{L_PRIVATE_MESSAGES} [</span><strong>{PRIVATE_MESSAGE_COUNT}</strong><span>]</span></a> + </li> + <!-- ENDIF --> + <li class="small-icon icon-ucp"> + <a href="{U_PROFILE}" title="{L_PROFILE}" accesskey="e">{L_PROFILE}</a> + </li> + <!-- IF S_DISPLAY_SEARCH --> + <li class="icon-search-self"><a href="{U_SEARCH_SELF}">{L_SEARCH_SELF}</a></li> + <!-- ENDIF --> + <!-- IF U_RESTORE_PERMISSIONS --> + <li class="icon-restore-permissions"><a href="{U_RESTORE_PERMISSIONS}">{L_RESTORE_PERMISSIONS}</a></li> + <!-- ENDIF --> + <!-- ENDIF --> + + <!-- EVENT overall_header_navigation_append --> + <!-- IF not S_IS_BOT --> + <li class="small-icon icon-logout rightside no-bulletin"><a href="{U_LOGIN_LOGOUT}" title="{L_LOGIN_LOGOUT}" accesskey="x">{L_LOGIN_LOGOUT}</a></li> + <!-- IF not S_USER_LOGGED_IN and S_REGISTER_ENABLED and not (S_SHOW_COPPA or S_REGISTRATION) --><li class="small-icon icon-register rightside no-bulletin"><a href="{U_REGISTER}">{L_REGISTER}</a></li><!-- ENDIF --> + <!-- IF S_DISPLAY_MEMBERLIST --><li class="small-icon icon-members rightside no-bulletin"><a href="{U_MEMBERLIST}" title="{L_MEMBERLIST_EXPLAIN}">{L_MEMBERLIST}</a></li><!-- ENDIF --> + <!-- ENDIF --> + <li class="small-icon icon-faq rightside no-bulletin"><a href="{U_FAQ}" title="{L_FAQ_EXPLAIN}">{L_FAQ}</a></li> + <!-- EVENT overall_header_navigation_prepend --> + </ul> + + </div> +</div> diff --git a/phpBB/styles/prosilver/template/notification_dropdown.html b/phpBB/styles/prosilver/template/notification_dropdown.html new file mode 100644 index 0000000000..3f32189fe5 --- /dev/null +++ b/phpBB/styles/prosilver/template/notification_dropdown.html @@ -0,0 +1,42 @@ +<div id="notification_list" class="dropdown dropdown-extended notification_list"> + <div class="pointer"><div class="pointer-inner"></div></div> + <div class="dropdown-contents"> + <div class="header"> + {L_NOTIFICATIONS} + <span class="header_settings"> + <a href="{U_NOTIFICATION_SETTINGS}">{L_SETTINGS}</a> + <!-- IF NOTIFICATIONS_COUNT --> + <span id="mark_all_notifications"> • <a href="{U_MARK_ALL_NOTIFICATIONS}" data-ajax="notification.mark_all_read">{L_MARK_ALL_READ}</a></span> + <!-- ENDIF --> + </span> + </div> + + <ul> + <!-- IF not .notifications --> + <li> + {L_NO_NOTIFICATIONS} + </li> + <!-- ENDIF --> + <!-- BEGIN notifications --> + <li class="<!-- IF notifications.UNREAD --> bg2<!-- ENDIF -->"> + <!-- IF notifications.URL --> + <a href="<!-- IF notifications.UNREAD -->{notifications.U_MARK_READ}" data-real-url="{notifications.URL}<!-- ELSE -->{notifications.URL}<!-- ENDIF -->"> + <!-- ENDIF --> + <!-- IF notifications.AVATAR -->{notifications.AVATAR}<!-- ELSE --><img src="{T_THEME_PATH}/images/no_avatar.gif" alt="" /><!-- ENDIF --> + <div class="notification_text"> + <p>{notifications.FORMATTED_TITLE}</p> + <p>» {notifications.TIME}</p> + </div> + <!-- IF notifications.URL --></a><!-- ENDIF --> + <!-- IF notifications.UNREAD --> + <a href="{notifications.U_MARK_READ}" class="mark_read icon-mark" data-ajax="notification.mark_read" title="{L_MARK_READ}"></a> + <!-- ENDIF --> + </li> + <!-- END notifications --> + </ul> + + <div class="footer"> + <a href="{U_VIEW_ALL_NOTIFICATIONS}"><span>{L_SEE_ALL}</span></a> + </div> + </div> +</div> diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 15a298053b..a43dd3c8a6 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -1,29 +1,10 @@ + <!-- EVENT overall_footer_content_after --> </div> -<div id="page-footer"> - - <div class="navbar"> - <div class="inner"> - - <ul class="linklist leftside bulletin"> - <li class="icon-home"><!-- IF U_SITE_HOME --><a href="{U_SITE_HOME}">{L_SITE_HOME}</a> <strong>‹</strong> <!-- ENDIF --><a href="{U_INDEX}" accesskey="h">{L_INDEX}</a> - <!-- EVENT overall_footer_breadcrumb_append --> - </li> - <!-- IF not S_IS_BOT --> - <!-- IF U_WATCH_FORUM_LINK --><li <!-- IF S_WATCHING_FORUM -->class="icon-unsubscribe"<!-- ELSE -->class="icon-subscribe"<!-- ENDIF -->><a href="{U_WATCH_FORUM_LINK}" title="{S_WATCH_FORUM_TITLE}" data-ajax="toggle_link" data-toggle-class="icon-<!-- IF not S_WATCHING_FORUM -->unsubscribe<!-- ELSE -->subscribe<!-- ENDIF -->" data-toggle-text="{S_WATCH_FORUM_TOGGLE}" data-toggle-url="{U_WATCH_FORUM_TOGGLE}">{S_WATCH_FORUM_TITLE}</a></li><!-- ENDIF --> - <!-- IF U_WATCH_TOPIC --><li <!-- IF S_WATCHING_TOPIC -->class="icon-unsubscribe"<!-- ELSE -->class="icon-subscribe"<!-- ENDIF -->><a href="{U_WATCH_TOPIC}" title="{S_WATCH_TOPIC_TITLE}" data-ajax="toggle_link" data-toggle-class="<!-- IF not S_WATCHING_TOPIC -->icon-unsubscribe<!-- ELSE -->icon-subscribe<!-- ENDIF -->" data-toggle-text="{S_WATCH_TOPIC_TOGGLE}" data-toggle-url="{U_WATCH_TOPIC_TOGGLE}">{S_WATCH_TOPIC_TITLE}</a></li><!-- ENDIF --> - <!-- IF U_BOOKMARK_TOPIC --><li class="icon-bookmark"><a href="{U_BOOKMARK_TOPIC}" title="{L_BOOKMARK_TOPIC}" data-ajax="alt_text" data-alt-text="{S_BOOKMARK_TOGGLE}">{S_BOOKMARK_TOPIC}</a></li><!-- ENDIF --> - <!-- IF U_BUMP_TOPIC --><li class="icon-bump"><a href="{U_BUMP_TOPIC}" title="{L_BUMP_TOPIC}" data-ajax="true">{L_BUMP_TOPIC}</a></li><!-- ENDIF --> - <!-- ENDIF --> - </ul> - <ul class="linklist rightside bulletin"> - <!-- IF U_TEAM --><li><a href="{U_TEAM}">{L_THE_TEAM}</a><!-- ENDIF --> - <!-- IF not S_IS_BOT --><li><a href="{U_DELETE_COOKIES}" data-ajax="true" data-refresh="true">{L_DELETE_COOKIES}</a></li><!-- ENDIF --> - <li>{S_TIMEZONE}</li> - </ul> +<!-- EVENT overall_footer_page_body_after --> - </div> - </div> +<div id="page-footer"> + <!-- INCLUDE navbar_footer.html --> <div class="copyright"> <!-- EVENT overall_footer_copyright_prepend --> @@ -36,8 +17,8 @@ <div id="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}" data-ajax-error-text-abort="{L_AJAX_ERROR_TEXT_ABORT}" data-ajax-error-text-timeout="{L_AJAX_ERROR_TEXT_TIMEOUT}" data-ajax-error-text-parsererror="{L_AJAX_ERROR_TEXT_PARSERERROR}"> <div id="darken"> </div> - <div class="phpbb_alert" id="loadingalert"><h3>{L_LOADING}</h3><p>{L_PLEASE_WAIT}</p></div> </div> + <div id="loading_indicator"></div> <div id="phpbb_alert" class="phpbb_alert" data-l-err="{L_ERROR}" data-l-timeout-processing-req="{L_TIMEOUT_PROCESSING_REQ}"> <a href="#" class="alert_close"></a> @@ -57,13 +38,14 @@ </div> <script type="text/javascript" src="{T_JQUERY_LINK}"></script> -<!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> +<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> <script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script> <!-- INCLUDEJS forum_fn.js --> <!-- INCLUDEJS ajax.js --> <!-- EVENT overall_footer_after --> +<!-- IF S_PLUPLOAD --><!-- INCLUDE plupload.html --><!-- ENDIF --> {$SCRIPTS} </body> diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html index 0b0c7a4172..353ba9139a 100644 --- a/phpBB/styles/prosilver/template/overall_header.html +++ b/phpBB/styles/prosilver/template/overall_header.html @@ -2,6 +2,7 @@ <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> <meta charset="utf-8"> +<meta name="viewport" content="width=device-width" /> <meta name="keywords" content="" /> <meta name="description" content="" /> {META} @@ -25,13 +26,19 @@ --> <link href="{T_THEME_PATH}/print.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="print" title="printonly" /> +<!-- IF S_ALLOW_CDN --><link href="//fonts.googleapis.com/css?family=Open+Sans:600&subset=latin,cyrillic-ext,latin-ext,cyrillic,greek-ext,greek,vietnamese" rel="stylesheet" type="text/css" media="screen, projection" /><!-- ENDIF --> <link href="{T_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" /> <link href="{T_STYLESHEET_LANG_LINK}" rel="stylesheet" type="text/css" media="screen, projection" /> +<link href="{T_THEME_PATH}/responsive.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="only screen and (max-width: 700px), only screen and (max-device-width: 700px)" /> <!-- IF S_CONTENT_DIRECTION eq 'rtl' --> <link href="{T_THEME_PATH}/bidi.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" /> <!-- ENDIF --> +<!-- IF S_PLUPLOAD --> + <link href="{T_THEME_PATH}/plupload.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" /> +<!-- ENDIF --> + <!--[if lte IE 8]> <link href="{T_THEME_PATH}/tweaks.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" /> <![endif]--> @@ -41,7 +48,9 @@ {$STYLESHEETS} </head> -<body id="phpbb" class="section-{SCRIPT_NAME} {S_CONTENT_DIRECTION}"> +<body id="phpbb" class="nojs section-{SCRIPT_NAME} {S_CONTENT_DIRECTION} {BODY_CLASS}"> + +<!-- EVENT overall_header_body_before --> <div id="wrap"> <a id="top" accesskey="t"></a> @@ -71,93 +80,11 @@ </div> </div> - <div class="navbar"> - <div class="inner"> - - <ul class="linklist navlinks"> - <!-- DEFINE $MICRODATA = ' itemtype="http://data-vocabulary.org/Breadcrumb" itemscope=""' --> - <li class="icon-home"><!-- IF U_SITE_HOME --><a href="{U_SITE_HOME}"{$MICRODATA}>{L_SITE_HOME}</a> <strong>‹</strong> <!-- ENDIF --> - <a href="{U_INDEX}" accesskey="h"{$MICRODATA}>{L_INDEX}</a> - <!-- BEGIN navlinks --> <strong>‹</strong> <a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}>{navlinks.FORUM_NAME}</a><!-- END navlinks --> - <!-- EVENT overall_header_breadcrumb_append --> - </li> - - <!-- IF U_EMAIL_TOPIC --><li class="rightside"><a href="{U_EMAIL_TOPIC}" title="{L_EMAIL_TOPIC}" class="sendemail">{L_EMAIL_TOPIC}</a></li><!-- ENDIF --> - <!-- IF U_EMAIL_PM --><li class="rightside"><a href="{U_EMAIL_PM}" title="{L_EMAIL_PM}" class="sendemail">{L_EMAIL_PM}</a></li><!-- ENDIF --> - <!-- IF U_PRINT_TOPIC --><li class="rightside"><a href="{U_PRINT_TOPIC}" title="{L_PRINT_TOPIC}" accesskey="p" class="print">{L_PRINT_TOPIC}</a></li><!-- ENDIF --> - <!-- IF U_PRINT_PM --><li class="rightside"><a href="{U_PRINT_PM}" title="{L_PRINT_PM}" accesskey="p" class="print">{L_PRINT_PM}</a></li><!-- ENDIF --> - </ul> - - <!-- IF not S_IS_BOT and S_USER_LOGGED_IN --> - <ul class="linklist leftside bulletin"> - <!-- IF S_NOTIFICATIONS_DISPLAY --> - <li class="icon-notification"> - <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button">{NOTIFICATIONS_COUNT}</a> - <div id="notification_list" class="notification_list"> - <div class="pointer"><div class="pointer_inner"></div></div> - <div class="header"> - {L_NOTIFICATIONS} - <span class="header_settings"><a href="{U_NOTIFICATION_SETTINGS}">{L_SETTINGS}</a></span> - </div> - - <ul> - <!-- IF not .notifications --> - <li> - {L_NO_NOTIFICATIONS} - </li> - <!-- ENDIF --> - <!-- BEGIN notifications --> - <li class="<!-- IF notifications.UNREAD --> bg2<!-- ENDIF -->"> - <!-- IF notifications.URL --><a href="<!-- IF notifications.UNREAD -->{notifications.U_MARK_READ}<!-- ELSE -->{notifications.URL}<!-- ENDIF -->"><!-- ENDIF --> - {notifications.AVATAR} - <div> - <p>{notifications.FORMATTED_TITLE}</p> - <p>» {notifications.TIME}</p> - - <!-- IF not notifications.URL and notifications.U_MARK_READ --> - <p><a href="{notifications.U_MARK_READ}">{L_MARK_READ}</a></p> - <!-- ENDIF --> - </div> - <!-- IF notifications.URL --></a><!-- ENDIF --> - </li> - <!-- END notifications --> - </ul> - - <div class="footer"> - <a href="{U_VIEW_ALL_NOTIFICATIONS}"><span>{L_SEE_ALL}</span></a> - </div> - </div> - </li> - <!-- ENDIF --> - <li class="icon-ucp"> - <a href="{U_PROFILE}" title="{L_PROFILE}" accesskey="e">{L_PROFILE}</a> - <!-- IF S_DISPLAY_PM --> (<a href="{U_PRIVATEMSGS}">{PRIVATE_MESSAGE_INFO}<!-- IF PRIVATE_MESSAGE_INFO_UNREAD -->, {PRIVATE_MESSAGE_INFO_UNREAD}<!-- ENDIF --></a>)<!-- ENDIF --> - </li> - <!-- IF S_DISPLAY_SEARCH --> - <li class="icon-search-self"><a href="{U_SEARCH_SELF}">{L_SEARCH_SELF}</a></li> - <!-- ENDIF --> - <!-- IF U_RESTORE_PERMISSIONS --> - <li class="icon-restore-permissions"><a href="{U_RESTORE_PERMISSIONS}">{L_RESTORE_PERMISSIONS}</a></li> - <!-- ENDIF --> - </ul> - <!-- ENDIF --> - - <ul class="linklist rightside"> - <!-- EVENT overall_header_navigation_prepend --> - <li class="icon-faq"><a href="{U_FAQ}" title="{L_FAQ_EXPLAIN}">{L_FAQ}</a></li> - <!-- IF not S_IS_BOT --> - <!-- IF S_DISPLAY_MEMBERLIST --><li class="icon-members"><a href="{U_MEMBERLIST}" title="{L_MEMBERLIST_EXPLAIN}">{L_MEMBERLIST}</a></li><!-- ENDIF --> - <!-- IF not S_USER_LOGGED_IN and S_REGISTER_ENABLED and not (S_SHOW_COPPA or S_REGISTRATION) --><li class="icon-register"><a href="{U_REGISTER}">{L_REGISTER}</a></li><!-- ENDIF --> - <li class="icon-logout"><a href="{U_LOGIN_LOGOUT}" title="{L_LOGIN_LOGOUT}" accesskey="x">{L_LOGIN_LOGOUT}</a></li> - <!-- ENDIF --> - <!-- EVENT overall_header_navigation_append --> - </ul> - - </div> - </div> - + <!-- INCLUDE navbar_header.html --> </div> + <!-- EVENT overall_header_page_body_before --> + <a id="start_here"></a> <div id="page-body"> <!-- IF S_BOARD_DISABLED and S_USER_LOGGED_IN and (U_MCP or U_ACP) --> @@ -167,3 +94,5 @@ </div> </div> <!-- ENDIF --> + + <!-- EVENT overall_header_content_before --> diff --git a/phpBB/styles/prosilver/template/pagination.html b/phpBB/styles/prosilver/template/pagination.html index 172bc952e4..e27a90900a 100644 --- a/phpBB/styles/prosilver/template/pagination.html +++ b/phpBB/styles/prosilver/template/pagination.html @@ -1,4 +1,8 @@ - <a href="#" class="pagination-trigger" title="{L_JUMP_TO_PAGE}" data-lang-jump-page="{L_JUMP_PAGE|e('html_attr')}{L_COLON}" data-on-page="{ON_PAGE}" data-per-page="{PER_PAGE}" data-base-url="{BASE_URL|e('html_attr')}">{PAGE_NUMBER}</a> • + <!-- IF BASE_URL --> + <a href="#" class="pagination-trigger" title="{L_JUMP_TO_PAGE}" data-lang-jump-page="{L_JUMP_PAGE|e('html_attr')}{L_COLON}" data-on-page="{CURRENT_PAGE}" data-per-page="{PER_PAGE}" data-base-url="{BASE_URL|e('html_attr')}" data-base-is-route="{BASE_IS_ROUTE}" data-start-name="{START_NAME}">{PAGE_NUMBER}</a> • + <!-- ELSE --> + {PAGE_NUMBER} • + <!-- ENDIF --> <ul> <!-- BEGIN pagination --> <!-- IF pagination.S_IS_PREV --> diff --git a/phpBB/styles/prosilver/template/plupload.html b/phpBB/styles/prosilver/template/plupload.html new file mode 100644 index 0000000000..fc663118c1 --- /dev/null +++ b/phpBB/styles/prosilver/template/plupload.html @@ -0,0 +1,69 @@ +<script type="text/javascript"> +//<![CDATA[ +phpbb.plupload = { + i18n: { + 'b': '{LA_BYTES_SHORT}', + 'kb': '{LA_KB}', + 'mb': '{LA_MB}', + 'gb': '{LA_GB}', + 'tb': '{LA_TB}', + 'Add Files': '{LA_PLUPLOAD_ADD_FILES}', + 'Add files to the upload queue and click the start button.': '{LA_PLUPLOAD_ADD_FILES_TO_QUEUE}', + 'Close': '{LA_PLUPLOAD_CLOSE}', + 'Drag files here.': '{LA_PLUPLOAD_DRAG}', + 'Duplicate file error.': '{LA_PLUPLOAD_DUPLICATE_ERROR}', + 'File: %s': '{LA_PLUPLOAD_FILE}', + 'File: %s, size: %d, max file size: %d': '{LA_PLUPLOAD_FILE_DETAILS}', + 'File count error.': '{LA_PLUPLOAD_ERR_FILE_COUNT}', + 'File extension error.': '{LA_PLUPLOAD_EXTENSION_ERROR}', + 'File size error.': '{LA_PLUPLOAD_SIZE_ERROR}', + 'File too large:': '{LA_PLUPLOAD_ERR_FILE_TOO_LARGE}', + 'Filename': '{LA_PLUPLOAD_FILENAME}', + 'Generic error.': '{LA_PLUPLOAD_GENERIC_ERROR}', + 'HTTP Error.': '{LA_PLUPLOAD_HTTP_ERROR}', + 'Image format either wrong or not supported.': '{LA_PLUPLOAD_IMAGE_FORMAT}', + 'Init error.': '{LA_PLUPLOAD_INIT_ERROR}', + 'IO error.': '{LA_PLUPLOAD_IO_ERROR}', + 'Invalid file extension:': '{LA_PLUPLOAD_ERR_FILE_INVALID_EXT}', + 'N/A': '{LA_PLUPLOAD_NOT_APPLICABLE}', + 'Runtime ran out of available memory.': '{LA_PLUPLOAD_ERR_RUNTIME_MEMORY}', + 'Security error.': '{LA_PLUPLOAD_SECURITY_ERROR}', + 'Select files': '{LA_PLUPLOAD_SELECT_FILES}', + 'Size': '{LA_PLUPLOAD_SIZE}', + 'Start Upload': '{LA_PLUPLOAD_START_UPLOAD}', + 'Start uploading queue': '{LA_PLUPLOAD_START_CURRENT_UPLOAD}', + 'Status': '{LA_PLUPLOAD_STATUS}', + 'Stop Upload': '{LA_PLUPLOAD_STOP_UPLOAD}', + 'Stop current upload': '{LA_PLUPLOAD_STOP_CURRENT_UPLOAD}', + "Upload URL might be wrong or doesn't exist.": '{LA_PLUPLOAD_ERR_UPLOAD_URL}', + 'Uploaded %d/%d files': '{LA_PLUPLOAD_UPLOADED}', + '%d files queued': '{LA_PLUPLOAD_FILES_QUEUED}', + '%s already present in the queue.': '{LA_PLUPLOAD_ALREADY_QUEUED}' + }, + config: { + runtimes: 'html5', + url: '{S_PLUPLOAD_URL}', + max_file_size: '{FILESIZE}b', + chunk_size: '{CHUNK_SIZE}b', + unique_names: true, + filters: [{FILTERS}], + {S_RESIZE} + headers: {'X-PHPBB-USING-PLUPLOAD': '1', 'X-Requested-With': 'XMLHttpRequest'}, + file_data_name: 'fileupload', + multipart_params: {'add_file': '{LA_ADD_FILE}'}, + form_hook: '#postform', + browse_button: 'add_files', + drop_element : 'message', + }, + lang: { + ERROR: '{LA_ERROR}', + TOO_MANY_ATTACHMENTS: '{LA_TOO_MANY_ATTACHMENTS}', + }, + order: '{ATTACH_ORDER}', + maxFiles: {MAX_ATTACHMENTS}, + data: {S_ATTACH_DATA}, +} +//]]> +</script> +<!-- INCLUDEJS {T_ASSETS_PATH}/plupload/plupload.full.min.js --> +<!-- INCLUDEJS {T_ASSETS_PATH}/javascript/plupload.js --> diff --git a/phpBB/styles/prosilver/template/posting_attach_body.html b/phpBB/styles/prosilver/template/posting_attach_body.html index fa9dd19c09..b6f4d13804 100644 --- a/phpBB/styles/prosilver/template/posting_attach_body.html +++ b/phpBB/styles/prosilver/template/posting_attach_body.html @@ -1,9 +1,9 @@ -<div class="panel bg3" id="attach-panel"> +<div class="panel bg3 panel-container" id="attach-panel"> <div class="inner"> - <p>{L_ADD_ATTACHMENT_EXPLAIN}</p> + <p>{L_ADD_ATTACHMENT_EXPLAIN} <span class="hidden" id="drag-n-drop-message">{L_PLUPLOAD_DRAG_TEXTAREA}</span></p> - <fieldset class="fields2"> + <fieldset class="fields2" id="attach-panel-basic"> <dl> <dt><label for="fileupload">{L_FILENAME}{L_COLON}</label></dt> <dd> @@ -17,5 +17,69 @@ </dl> </fieldset> + <div id="attach-panel-multi"> + <input type="button" class="button2" value="{L_PLUPLOAD_ADD_FILES}" id="add_files" /> + </div> + + <div class="panel<!-- IF not .attach_row --> hidden<!-- ENDIF -->" id="file-list-container"> + <div class="inner"> + <table class="table1 zebra-list"> + <thead> + <tr> + <th class="attach-name">{L_PLUPLOAD_FILENAME}</th> + <th class="attach-comment">{L_FILE_COMMENT}</th> + <th class="attach-filesize">{L_PLUPLOAD_SIZE}</th> + <th class="attach-status">{L_PLUPLOAD_STATUS}</th> + </tr> + </thead> + <tbody class="responsive-skip-empty" id="file-list"> + <tr class="attach-row" id="attach-row-tpl"> + <td class="attach-name"> + <span class="file-name"></span> + <span class="attach-controls"> + <input type="button" value="{L_PLACE_INLINE}" class="button2 hidden file-inline-bbcode" /> + <input type="button" value="{L_DELETE_FILE}" class="button2 file-delete" /> + </span> + <span class="clear"></span> + </td> + <td class="attach-comment"> + <textarea rows="1" cols="30" class="inputbox"></textarea> + </td> + <td class="attach-filesize"> + <span class="file-size"></span> + </td> + <td class="attach-status"> + <span class="file-progress"> + <span class="file-progress-bar"></span> + </span> + <span class="file-status"></span> + </td> + </tr> + <!-- BEGIN attach_row --> + <tr class="attach-row" data-attach-id="{attach_row.ATTACH_ID}"> + <td class="attach-name"> + <span class="file-name"><a href="{attach_row.U_VIEW_ATTACHMENT}">{attach_row.FILENAME}</a></span> + <span class="attach-controls"> + <!-- IF S_INLINE_ATTACHMENT_OPTIONS --><input type="button" value="{L_PLACE_INLINE}" class="button2 file-inline-bbcode" /> <!-- ENDIF --> + <input type="submit" name="delete_file[{attach_row.ASSOC_INDEX}]" value="{L_DELETE_FILE}" class="button2 file-delete" /> + </span> + <span class="clear"></span> + </td> + <td class="attach-comment"> + <textarea name="comment_list[{attach_row.ASSOC_INDEX}]" rows="1" cols="30" class="inputbox">{attach_row.FILE_COMMENT}</textarea> + {attach_row.S_HIDDEN} + </td> + <td class="attach-filesize"> + <span class="file-size">{attach_row.FILESIZE}</span> + </td> + <td class="attach-status"> + <span class="file-status file-uploaded"></span> + </td> + </tr> + <!-- END attach_row --> + </tbody> + </table> + </div> + </div> </div> </div> diff --git a/phpBB/styles/prosilver/template/posting_buttons.html b/phpBB/styles/prosilver/template/posting_buttons.html index 798faa2ff7..3dad6606bb 100644 --- a/phpBB/styles/prosilver/template/posting_buttons.html +++ b/phpBB/styles/prosilver/template/posting_buttons.html @@ -28,13 +28,13 @@ y: '{LA_BBCODE_Y_HELP}', d: '{LA_BBCODE_D_HELP}' <!-- BEGIN custom_tags --> - ,cb_{custom_tags.BBCODE_ID}{L_COLON} '{custom_tags.A_BBCODE_HELPLINE}' + ,cb_{custom_tags.BBCODE_ID}: '{custom_tags.A_BBCODE_HELPLINE}' <!-- END custom_tags --> } function change_palette() { - dE('colour_palette'); + phpbb.toggleDisplay('colour_palette'); e = document.getElementById('colour_palette'); if (e.style.display == 'block') @@ -49,37 +49,38 @@ // ]]> </script> -<!-- INCLUDEJS editor.js --> +<!-- INCLUDEJS {T_ASSETS_PATH}/javascript/editor.js --> <!-- IF S_BBCODE_ALLOWED --> <div id="colour_palette" style="display: none;"> <dl style="clear: left;"> <dt><label>{L_FONT_COLOR}{L_COLON}</label></dt> - <dd id="color_palette_placeholder"></dd> + <dd id="color_palette_placeholder" data-orientation="h" data-height="12" data-width="15" data-bbcode="true"></dd> </dl> </div> +<!-- EVENT posting_editor_buttons_before --> <div id="format-buttons"> - <input type="button" class="button2" accesskey="b" name="addbbcode0" value=" B " style="font-weight:bold; width: 30px" onclick="bbstyle(0)" title="{L_BBCODE_B_HELP}" /> - <input type="button" class="button2" accesskey="i" name="addbbcode2" value=" i " style="font-style:italic; width: 30px" onclick="bbstyle(2)" title="{L_BBCODE_I_HELP}" /> - <input type="button" class="button2" accesskey="u" name="addbbcode4" value=" u " style="text-decoration: underline; width: 30px" onclick="bbstyle(4)" title="{L_BBCODE_U_HELP}" /> + <input type="button" class="button2 bbcode-b" accesskey="b" name="addbbcode0" value=" B " style="font-weight:bold; width: 30px" onclick="bbstyle(0)" title="{L_BBCODE_B_HELP}" /> + <input type="button" class="button2 bbcode-i" accesskey="i" name="addbbcode2" value=" i " style="font-style:italic; width: 30px" onclick="bbstyle(2)" title="{L_BBCODE_I_HELP}" /> + <input type="button" class="button2 bbcode-u" accesskey="u" name="addbbcode4" value=" u " style="text-decoration: underline; width: 30px" onclick="bbstyle(4)" title="{L_BBCODE_U_HELP}" /> <!-- IF S_BBCODE_QUOTE --> - <input type="button" class="button2" accesskey="q" name="addbbcode6" value="Quote" style="width: 50px" onclick="bbstyle(6)" title="{L_BBCODE_Q_HELP}" /> + <input type="button" class="button2 bbcode-quote" accesskey="q" name="addbbcode6" value="Quote" style="width: 50px" onclick="bbstyle(6)" title="{L_BBCODE_Q_HELP}" /> <!-- ENDIF --> - <input type="button" class="button2" accesskey="c" name="addbbcode8" value="Code" style="width: 40px" onclick="bbstyle(8)" title="{L_BBCODE_C_HELP}" /> - <input type="button" class="button2" accesskey="l" name="addbbcode10" value="List" style="width: 40px" onclick="bbstyle(10)" title="{L_BBCODE_L_HELP}" /> - <input type="button" class="button2" accesskey="o" name="addbbcode12" value="List=" style="width: 40px" onclick="bbstyle(12)" title="{L_BBCODE_O_HELP}" /> - <input type="button" class="button2" accesskey="y" name="addlistitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" title="{L_BBCODE_LISTITEM_HELP}" /> + <input type="button" class="button2 bbcode-code" accesskey="c" name="addbbcode8" value="Code" style="width: 40px" onclick="bbstyle(8)" title="{L_BBCODE_C_HELP}" /> + <input type="button" class="button2 bbcode-list" accesskey="l" name="addbbcode10" value="List" style="width: 40px" onclick="bbstyle(10)" title="{L_BBCODE_L_HELP}" /> + <input type="button" class="button2 bbcode-list-" accesskey="o" name="addbbcode12" value="List=" style="width: 40px" onclick="bbstyle(12)" title="{L_BBCODE_O_HELP}" /> + <input type="button" class="button2 bbcode-asterisk" accesskey="y" name="addlistitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" title="{L_BBCODE_LISTITEM_HELP}" /> <!-- IF S_BBCODE_IMG --> - <input type="button" class="button2" accesskey="p" name="addbbcode14" value="Img" style="width: 40px" onclick="bbstyle(14)" title="{L_BBCODE_P_HELP}" /> + <input type="button" class="button2 bbcode-img" accesskey="p" name="addbbcode14" value="Img" style="width: 40px" onclick="bbstyle(14)" title="{L_BBCODE_P_HELP}" /> <!-- ENDIF --> <!-- IF S_LINKS_ALLOWED --> - <input type="button" class="button2" accesskey="w" name="addbbcode16" value="URL" style="text-decoration: underline; width: 40px" onclick="bbstyle(16)" title="{L_BBCODE_W_HELP}" /> + <input type="button" class="button2 bbcode-url" accesskey="w" name="addbbcode16" value="URL" style="text-decoration: underline; width: 40px" onclick="bbstyle(16)" title="{L_BBCODE_W_HELP}" /> <!-- ENDIF --> <!-- IF S_BBCODE_FLASH --> - <input type="button" class="button2" accesskey="d" name="addbbcode18" value="Flash" onclick="bbstyle(18)" title="{L_BBCODE_D_HELP}" /> + <input type="button" class="button2 bbcode-flash" accesskey="d" name="addbbcode18" value="Flash" onclick="bbstyle(18)" title="{L_BBCODE_D_HELP}" /> <!-- ENDIF --> - <select name="addbbcode20" onchange="bbfontstyle('[size=' + this.form.addbbcode20.options[this.form.addbbcode20.selectedIndex].value + ']', '[/size]');this.form.addbbcode20.selectedIndex = 2;" title="{L_BBCODE_F_HELP}"> + <select name="addbbcode20" class="bbcode-size" onchange="bbfontstyle('[size=' + this.form.addbbcode20.options[this.form.addbbcode20.selectedIndex].value + ']', '[/size]');this.form.addbbcode20.selectedIndex = 2;" title="{L_BBCODE_F_HELP}"> <option value="50">{L_FONT_TINY}</option> <option value="85">{L_FONT_SMALL}</option> <option value="100" selected="selected">{L_FONT_NORMAL}</option> @@ -90,9 +91,10 @@ <!-- ENDIF --> <!-- ENDIF --> </select> - <input type="button" class="button2" name="bbpalette" id="bbpalette" value="{L_FONT_COLOR}" onclick="change_palette();" title="{L_BBCODE_S_HELP}" /> + <input type="button" class="button2 bbcode-color" name="bbpalette" id="bbpalette" value="{L_FONT_COLOR}" onclick="change_palette();" title="{L_BBCODE_S_HELP}" /> <!-- BEGIN custom_tags --> - <input type="button" class="button2" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})" title="{custom_tags.BBCODE_HELPLINE}" /> + <input type="button" class="button2 bbcode-{custom_tags.BBCODE_TAG_CLEAN}" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})" title="{custom_tags.BBCODE_HELPLINE}" /> <!-- END custom_tags --> </div> +<!-- EVENT posting_editor_buttons_after --> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html index 62e64a821e..e311b85cbe 100644 --- a/phpBB/styles/prosilver/template/posting_editor.html +++ b/phpBB/styles/prosilver/template/posting_editor.html @@ -1,73 +1,5 @@ <fieldset class="fields1"> - <!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF --> - - <!-- IF S_PRIVMSGS and not S_SHOW_DRAFTS --> - - <div class="column1"> - <!-- IF S_ALLOW_MASS_PM --> - <!-- IF .to_recipient --> - <dl> - <dt><label>{L_TO}{L_COLON}</label></dt> - <dd> - <!-- BEGIN to_recipient --> - <!-- IF not to_recipient.S_FIRST_ROW and to_recipient.S_ROW_COUNT mod 2 eq 0 --></dd><dd><!-- ENDIF --> - <!-- IF to_recipient.IS_GROUP --><a href="{to_recipient.U_VIEW}"><strong>{to_recipient.NAME}</strong></a><!-- ELSE -->{to_recipient.NAME_FULL}<!-- ENDIF --> - <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" /> <!-- ENDIF --> - <!-- END to_recipient --> - </dd> - </dl> - <!-- ENDIF --> - <!-- IF .bcc_recipient --> - <dl> - <dt><label>{L_BCC}{L_COLON}</label></dt> - <dd> - <!-- BEGIN bcc_recipient --> - <!-- IF not bcc_recipient.S_FIRST_ROW and bcc_recipient.S_ROW_COUNT mod 2 eq 0 --></dd><dd><!-- ENDIF --> - <!-- IF bcc_recipient.IS_GROUP --><a href="{bcc_recipient.U_VIEW}"><strong>{bcc_recipient.NAME}</strong></a><!-- ELSE -->{bcc_recipient.NAME_FULL}<!-- ENDIF --> - <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{bcc_recipient.TYPE}[{bcc_recipient.UG_ID}]" value="x" class="button2" /> <!-- ENDIF --> - <!-- END bcc_recipient --> - </dd> - </dl> - <!-- ENDIF --> - <!-- IF not S_EDIT_POST --> - <dl class="pmlist"> - <dt><textarea id="username_list" name="username_list" class="inputbox" cols="50" rows="2" tabindex="1"></textarea></dt> - <dd><span><a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false;">{L_FIND_USERNAME}</a></span></dd> - <dd><input type="submit" name="add_to" value="{L_ADD}" class="button2" tabindex="1" /></dd> - <dd><input type="submit" name="add_bcc" value="{L_ADD_BCC}" class="button2" tabindex="1" /></dd> - </dl> - <!-- ENDIF --> - <!-- ELSE --> - <dl> - <dt><label for="username_list">{L_TO}{L_COLON}</label><!-- IF not S_EDIT_POST --><br /><span><a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false">{L_FIND_USERNAME}</a></span><!-- ENDIF --></dt> - <!-- IF .to_recipient --> - <dd> - <!-- BEGIN to_recipient --> - <!-- IF not to_recipient.S_FIRST_ROW and to_recipient.S_ROW_COUNT mod 2 eq 0 --></dd><dd><!-- ENDIF --> - <!-- IF to_recipient.IS_GROUP --><a href="{to_recipient.U_VIEW}"><strong>{to_recipient.NAME}</strong></a><!-- ELSE -->{to_recipient.NAME_FULL}<!-- ENDIF --> - <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" /> <!-- ENDIF --> - <!-- END to_recipient --> - </dd> - <!-- ENDIF --> - - <!-- IF not S_EDIT_POST --> - <dd><input class="inputbox" type="text" name="username_list" id="username_list" size="20" value="" /> <input type="submit" name="add_to" value="{L_ADD}" class="button2" /></dd> - <!-- ENDIF --> - </dl> - <!-- ENDIF --> - - </div> - - <!-- IF S_GROUP_OPTIONS --> - <div class="column2"> - <dl> - <dd><label for="group_list">{L_USERGROUPS}{L_COLON}</label> <select name="group_list[]" id="group_list" multiple="multiple" size="4" class="inputbox">{S_GROUP_OPTIONS}</select></dd> - </dl> - </div> - <!-- ENDIF --> - - <div class="clear"></div> - <!-- ENDIF --> +<!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF --> <!-- IF S_SHOW_TOPIC_ICONS or S_SHOW_PM_ICONS --> <dl> @@ -86,6 +18,8 @@ </dl> <!-- ENDIF --> + <!-- EVENT posting_editor_subject_before --> + <!-- IF S_POST_ACTION or S_PRIVMSGS or S_EDIT_DRAFT --> <dl style="clear: left;"> <dt><label for="subject">{L_SUBJECT}{L_COLON}</label></dt> @@ -97,6 +31,8 @@ <!-- ENDIF --> <!-- ENDIF --> + <!-- EVENT posting_editor_subject_after --> + <!-- INCLUDE posting_buttons.html --> <div id="smiley-box"> @@ -111,14 +47,16 @@ <!-- ENDIF --> <!-- IF BBCODE_STATUS --> - <!-- IF .smiley --><hr /><!-- ENDIF --> - {BBCODE_STATUS}<br /> - <!-- IF S_BBCODE_ALLOWED --> - {IMG_STATUS}<br /> - {FLASH_STATUS}<br /> - {URL_STATUS}<br /> - <!-- ENDIF --> - {SMILIES_STATUS} + <div class="bbcode-status"> + <!-- IF .smiley --><hr /><!-- ENDIF --> + {BBCODE_STATUS}<br /> + <!-- IF S_BBCODE_ALLOWED --> + {IMG_STATUS}<br /> + {FLASH_STATUS}<br /> + {URL_STATUS}<br /> + <!-- ENDIF --> + {SMILIES_STATUS} + </div> <!-- ENDIF --> <!-- IF S_EDIT_DRAFT || S_DISPLAY_REVIEW --> <!-- IF S_DISPLAY_REVIEW --><hr /><!-- ENDIF --> @@ -127,10 +65,14 @@ <!-- ENDIF --> </div> + <!-- EVENT posting_editor_message_before --> + <div id="message-box"> <textarea <!-- IF S_UCP_ACTION and not S_PRIVMSGS and not S_EDIT_DRAFT -->name="signature" id="signature" style="height: 9em;"<!-- ELSE -->name="message" id="message"<!-- ENDIF --> rows="15" cols="76" tabindex="4" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();" class="inputbox">{MESSAGE}{DRAFT_MESSAGE}{SIGNATURE}</textarea> </div> -</fieldset> + + <!-- EVENT posting_editor_message_after --> + </fieldset> <!-- IF $EXTRA_POSTING_OPTIONS eq 1 --> @@ -139,34 +81,6 @@ </div> <!-- ENDIF --> - <!-- IF S_HAS_ATTACHMENTS --> - <div class="panel bg2"> - <div class="inner"> - <h3>{L_POSTED_ATTACHMENTS}</h3> - - <fieldset class="fields2"> - - <!-- BEGIN attach_row --> - <dl> - - <dt><label for="comment_list_{attach_row.ASSOC_INDEX}">{L_FILE_COMMENT}{L_COLON}</label></dt> - <dd><textarea name="comment_list[{attach_row.ASSOC_INDEX}]" id="comment_list_{attach_row.ASSOC_INDEX}" rows="1" cols="35" class="inputbox">{attach_row.FILE_COMMENT}</textarea></dd> - <dd><a href="{attach_row.U_VIEW_ATTACHMENT}">{attach_row.FILENAME}</a></dd> - <dd style="margin-top: 5px;"> - <!-- IF S_INLINE_ATTACHMENT_OPTIONS --><input type="button" value="{L_PLACE_INLINE}" onclick="attach_inline({attach_row.ASSOC_INDEX}, '{attach_row.A_FILENAME}');" class="button2" /> <!-- ENDIF --> - <input type="submit" name="delete_file[{attach_row.ASSOC_INDEX}]" value="{L_DELETE_FILE}" class="button2" /> - </dd> - </dl> - {attach_row.S_HIDDEN} - <!-- IF not attach_row.S_LAST_ROW --><hr class="dashed" /><!-- ENDIF --> - <!-- END attach_row --> - - </fieldset> - - </div> - </div> - <!-- ENDIF --> - <!-- IF not S_SHOW_DRAFTS and not $SIG_EDIT eq 1 --> <div class="panel bg2"> <div class="inner"> @@ -188,7 +102,15 @@ <div id="tabs" class="sub-panels" data-show-panel="options-panel"> <ul> <li id="options-panel-tab" class="activetab"><a href="#tabs" data-subpanel="options-panel"><span>{L_OPTIONS}</span></a></li> - <!-- IF S_SHOW_ATTACH_BOX --><li id="attach-panel-tab"><a href="#tabs" data-subpanel="attach-panel"><span>{L_ADD_ATTACHMENT}</span></a></li><!-- ENDIF --> + <!-- IF S_SHOW_ATTACH_BOX --> + <li id="attach-panel-tab"> + <a href="#tabs" data-subpanel="attach-panel"> + <span> + {L_ATTACHMENTS} <strong id="file-total-progress"><strong id="file-total-progress-bar"></strong></strong> + </span> + </a> + </li> + <!-- ENDIF --> <!-- IF S_SHOW_POLL_BOX || S_POLL_DELETE --><li id="poll-panel-tab"><a href="#tabs" data-subpanel="poll-panel"><span>{L_ADD_POLL}</span></a></li><!-- ENDIF --> </ul> </div> diff --git a/phpBB/styles/prosilver/template/posting_layout.html b/phpBB/styles/prosilver/template/posting_layout.html index c0bd0225de..4ef0954200 100644 --- a/phpBB/styles/prosilver/template/posting_layout.html +++ b/phpBB/styles/prosilver/template/posting_layout.html @@ -1,13 +1,13 @@ <!-- INCLUDE overall_header.html --> <!-- IF TOPIC_TITLE --> - <h2><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2> + <h2 class="posting-title"><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2> <!-- ELSE --> - <h2><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2> + <h2 class="posting-title"><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2> <!-- ENDIF --> <!-- IF S_FORUM_RULES --> - <div class="rules"> + <div class="rules<!-- IF U_FORUM_RULES --> rules-link<!-- ENDIF -->"> <div class="inner"> <!-- IF U_FORUM_RULES --> diff --git a/phpBB/styles/prosilver/template/posting_pm_header.html b/phpBB/styles/prosilver/template/posting_pm_header.html new file mode 100644 index 0000000000..dea50b5daf --- /dev/null +++ b/phpBB/styles/prosilver/template/posting_pm_header.html @@ -0,0 +1,81 @@ +<fieldset class="fields1"> + <!-- IF not S_SHOW_DRAFTS --> + + <!-- IF S_GROUP_OPTIONS --> + <div class="column2"> + <label for="group_list"><strong>{L_TO_ADD_GROUPS}{L_COLON}</strong></label><br /> + <select name="group_list[]" id="group_list" multiple="multiple" size="3" class="inputbox">{S_GROUP_OPTIONS}</select><br /> + </div> + <!-- ENDIF --> + <!-- IF S_ALLOW_MASS_PM --> + <div class="column1"> + <!-- IF not S_EDIT_POST --> + <dl class="pmlist"> + <dt><label><strong>{L_TO_ADD_MASS}{L_COLON}</strong><textarea id="username_list" name="username_list" class="inputbox" cols="50" rows="2" tabindex="1"></textarea></label></dt> + <dd class="recipients"> + <input type="submit" name="add_to" value="{L_ADD}" class="button2" tabindex="1" /> + <input type="submit" name="add_bcc" value="{L_ADD_BCC}" class="button2" tabindex="1" /> + <span><a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false;">{L_FIND_USERNAME}</a></span> + </dd> + </dl> + <!-- ENDIF --> + </div> + <!-- IF .to_recipient or .bcc_recipient --><hr /><!-- ENDIF --> + <div class="column1"> + <!-- IF .to_recipient --> + <dl> + <dt><label>{L_TO_MASS}{L_COLON}</label></dt> + <dd class="recipients"> + <ul class="recipients"> + <!-- BEGIN to_recipient --> + <li> + <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" /><!-- ENDIF --> + <!-- IF to_recipient.IS_GROUP --><a href="{to_recipient.U_VIEW}"><strong>{to_recipient.NAME}</strong></a><!-- ELSE -->{to_recipient.NAME_FULL}<!-- ENDIF --> + </li> + <!-- END to_recipient --> + </ul> + </dd> + </dl> + <!-- ENDIF --> + </div> + <!-- IF .bcc_recipient --> + <div class="column2"> + <dl> + <dt><label>{L_BCC}{L_COLON}</label></dt> + <dd class="recipients"> + <ul class="recipients"> + <!-- BEGIN bcc_recipient --> + <li> + <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{bcc_recipient.TYPE}[{bcc_recipient.UG_ID}]" value="x" class="button2" /><!-- ENDIF --> + <!-- IF bcc_recipient.IS_GROUP --><a href="{bcc_recipient.U_VIEW}"><strong>{bcc_recipient.NAME}</strong></a><!-- ELSE -->{bcc_recipient.NAME_FULL}<!-- ENDIF --> + </li> + <!-- END bcc_recipient --> + </ul> + </dd> + </dl> + </div> + <!-- ENDIF --> + <!-- ELSE --> + <div class="column1"> + <dl> + <dt><label for="username_list">{L_TO_ADD}{L_COLON}</label><!-- IF not S_EDIT_POST --><br /><span><a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false">{L_FIND_USERNAME}</a></span><!-- ENDIF --></dt> + <!-- IF not S_EDIT_POST --> + <dd><input class="inputbox" type="text" name="username_list" id="username_list" size="20" value="" /> <input type="submit" name="add_to" value="{L_ADD}" class="button2" /></dd> + <!-- ENDIF --> + <!-- IF .to_recipient --> + <dd class="recipients"> + <ul class="recipients"> + <!-- BEGIN to_recipient --> + <li> + <!-- IF to_recipient.IS_GROUP --><a href="{to_recipient.U_VIEW}"><strong>{to_recipient.NAME}</strong></a><!-- ELSE -->{to_recipient.NAME_FULL}<!-- ENDIF --> + <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" /><!-- ENDIF --> + </li> + <!-- END to_recipient --> + </dd> + <!-- ENDIF --> + </dl> + </div> + <!-- ENDIF --> + + <!-- ENDIF --> + </fieldset> diff --git a/phpBB/styles/prosilver/template/posting_pm_layout.html b/phpBB/styles/prosilver/template/posting_pm_layout.html index 5421cc2cbd..3bdadd06ca 100644 --- a/phpBB/styles/prosilver/template/posting_pm_layout.html +++ b/phpBB/styles/prosilver/template/posting_pm_layout.html @@ -15,7 +15,13 @@ <!-- IF S_DISPLAY_PREVIEW --><!-- INCLUDE posting_preview.html --><!-- ENDIF --> -<h2>{L_TITLE}</h2> +<h2 class="posting-title">{L_TITLE}</h2> + +<div class="panel" id="pmheader-postingbox"> + <div class="inner"> + <!-- INCLUDE posting_pm_header.html --> + </div> +</div> <div class="panel" id="postingbox"> <div class="inner"> diff --git a/phpBB/styles/prosilver/template/posting_review.html b/phpBB/styles/prosilver/template/posting_review.html index 2771c9829a..25b719420b 100644 --- a/phpBB/styles/prosilver/template/posting_review.html +++ b/phpBB/styles/prosilver/template/posting_review.html @@ -8,7 +8,7 @@ <div class="inner"> {post_review_row.L_IGNORE_POST} <!-- ELSE --> -<div class="post <!-- IF post_review_row.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF post_review_row.ONLINE_STATUS --> online<!-- ENDIF -->"> +<div class="post <!-- IF post_review_row.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF -->"> <div class="inner"> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/posting_smilies.html b/phpBB/styles/prosilver/template/posting_smilies.html index 3d56a932b7..c5371b9b6a 100644 --- a/phpBB/styles/prosilver/template/posting_smilies.html +++ b/phpBB/styles/prosilver/template/posting_smilies.html @@ -6,14 +6,14 @@ var text_name = opener.text_name; // ]]> </script> -<script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/editor.js"></script> +<!-- INCLUDEJS {T_ASSETS_PATH}/javascript/editor.js --> <h2>{L_SMILIES}</h2> <div class="panel"> <div class="inner"> <!-- BEGIN smiley --> <a href="#" onclick="initInsertions(); insert_text('{smiley.A_SMILEY_CODE}', true, true); return false;"><img src="{smiley.SMILEY_IMG}" width="{smiley.SMILEY_WIDTH}" height="{smiley.SMILEY_HEIGHT}" alt="{smiley.SMILEY_CODE}" title="{smiley.SMILEY_DESC}" /></a> - <!-- END smiley --> + <!-- END smiley --> </div> </div> diff --git a/phpBB/styles/prosilver/template/posting_topic_review.html b/phpBB/styles/prosilver/template/posting_topic_review.html index 1fcc9facd0..d2faed5f8f 100644 --- a/phpBB/styles/prosilver/template/posting_topic_review.html +++ b/phpBB/styles/prosilver/template/posting_topic_review.html @@ -22,13 +22,16 @@ <!-- ENDIF --> <div class="postbody" id="pr{topic_review_row.POST_ID}"> + <h3><a href="#pr{topic_review_row.POST_ID}">{topic_review_row.POST_SUBJECT}</a></h3> + <!-- IF topic_review_row.POSTER_QUOTE and topic_review_row.DECODED_MESSAGE --> <ul class="profile-icons"> <li class="quote-icon"><a href="#postingbox" onclick="addquote({topic_review_row.POST_ID}, '{topic_review_row.POSTER_QUOTE}', '{LA_WROTE}');" title="{L_QUOTE} {topic_review_row.POST_AUTHOR}"><span>{L_QUOTE} {topic_review_row.POST_AUTHOR}</span></a></li> </ul> <!-- ENDIF --> + <!-- IF topic_review_row.U_MCP_DETAILS --><div class="right-box"><a href="{topic_review_row.U_MCP_DETAILS}">{L_POST_DETAILS}</a></div><!-- ENDIF --> - <h3><a href="#pr{topic_review_row.POST_ID}">{topic_review_row.POST_SUBJECT}</a></h3> + <p class="author"><!-- IF S_IS_BOT -->{topic_review_row.MINI_POST_IMG}<!-- ELSE --><a href="{topic_review_row.U_MINI_POST}">{topic_review_row.MINI_POST_IMG}</a><!-- ENDIF --> {L_POST_BY_AUTHOR} <strong>{topic_review_row.POST_AUTHOR_FULL}</strong> » {topic_review_row.POST_DATE} </p> <div class="content">{topic_review_row.MESSAGE}</div> diff --git a/phpBB/styles/prosilver/template/profilefields/bool.html b/phpBB/styles/prosilver/template/profilefields/bool.html new file mode 100644 index 0000000000..f1d7ba75f4 --- /dev/null +++ b/phpBB/styles/prosilver/template/profilefields/bool.html @@ -0,0 +1,7 @@ +<!-- BEGIN bool --> +<!-- IF bool.FIELD_LENGTH eq 1 --> + <!-- BEGIN options --><label for="{bool.FIELD_IDENT}_{bool.options.OPTION_ID}"><input type="radio" class="radio" name="{bool.FIELD_IDENT}" id="{bool.FIELD_IDENT}_{bool.options.OPTION_ID}" value="{bool.options.OPTION_ID}"{bool.options.CHECKED} /> {bool.options.VALUE}</label> <!-- END options --> +<!-- ELSE --> + <input type="checkbox" class="radio" name="{bool.FIELD_IDENT}" id="{bool.FIELD_IDENT}"<!-- IF bool.FIELD_VALUE --> checked="checked"<!-- ENDIF --> /> +<!-- ENDIF --> +<!-- END bool --> diff --git a/phpBB/styles/prosilver/template/profilefields/date.html b/phpBB/styles/prosilver/template/profilefields/date.html new file mode 100644 index 0000000000..5d5bc04ed6 --- /dev/null +++ b/phpBB/styles/prosilver/template/profilefields/date.html @@ -0,0 +1,5 @@ +<!-- BEGIN date --> +<label for="{date.FIELD_IDENT}_day">{L_DAY}{L_COLON} <select name="{date.FIELD_IDENT}_day" id="{date.FIELD_IDENT}_day">{date.S_DAY_OPTIONS}</select></label> +<label for="{date.FIELD_IDENT}_month">{L_MONTH}{L_COLON} <select name="{date.FIELD_IDENT}_month" id="{date.FIELD_IDENT}_month">{date.S_MONTH_OPTIONS}</select></label> +<label for="{date.FIELD_IDENT}_year">{L_YEAR}{L_COLON} <select name="{date.FIELD_IDENT}_year" id="{date.FIELD_IDENT}_year">{date.S_YEAR_OPTIONS}</select></label> +<!-- END date --> diff --git a/phpBB/styles/prosilver/template/profilefields/dropdown.html b/phpBB/styles/prosilver/template/profilefields/dropdown.html new file mode 100644 index 0000000000..243b7039da --- /dev/null +++ b/phpBB/styles/prosilver/template/profilefields/dropdown.html @@ -0,0 +1,5 @@ +<!-- BEGIN dropdown --> +<select name="{dropdown.FIELD_IDENT}" id="{dropdown.FIELD_IDENT}"> + <!-- BEGIN options --><option value="{dropdown.options.OPTION_ID}"{dropdown.options.SELECTED}>{dropdown.options.VALUE}</option><!-- END options --> +</select> +<!-- END dropdown --> diff --git a/phpBB/styles/prosilver/template/profilefields/int.html b/phpBB/styles/prosilver/template/profilefields/int.html new file mode 100644 index 0000000000..a6f9a0a49e --- /dev/null +++ b/phpBB/styles/prosilver/template/profilefields/int.html @@ -0,0 +1,3 @@ +<!-- BEGIN int --> +<input type="number" min="{int.FIELD_MINLEN}" max="{int.FIELD_MAXLEN}" class="inputbox autowidth" name="{int.FIELD_IDENT}" id="{int.FIELD_IDENT}" size="{int.FIELD_LENGTH}" value="{int.FIELD_VALUE}" /> +<!-- END int --> diff --git a/phpBB/styles/prosilver/template/profilefields/string.html b/phpBB/styles/prosilver/template/profilefields/string.html new file mode 100644 index 0000000000..cf457d39ad --- /dev/null +++ b/phpBB/styles/prosilver/template/profilefields/string.html @@ -0,0 +1,3 @@ +<!-- BEGIN string --> +<input type="text" class="inputbox autowidth" name="{string.FIELD_IDENT}" id="{string.FIELD_IDENT}" size="{string.FIELD_LENGTH}" maxlength="{string.FIELD_MAXLEN}" value="{string.FIELD_VALUE}" /> +<!-- END string --> diff --git a/phpBB/styles/prosilver/template/profilefields/text.html b/phpBB/styles/prosilver/template/profilefields/text.html new file mode 100644 index 0000000000..f54c63925c --- /dev/null +++ b/phpBB/styles/prosilver/template/profilefields/text.html @@ -0,0 +1,3 @@ +<!-- BEGIN text --> +<textarea name="{text.FIELD_IDENT}" id="{text.FIELD_IDENT}" rows="{text.FIELD_ROWS}" cols="{text.FIELD_COLS}" class="inputbox">{text.FIELD_VALUE}</textarea> +<!-- END text --> diff --git a/phpBB/styles/prosilver/template/profilefields/url.html b/phpBB/styles/prosilver/template/profilefields/url.html new file mode 100644 index 0000000000..8dd3a90de1 --- /dev/null +++ b/phpBB/styles/prosilver/template/profilefields/url.html @@ -0,0 +1,3 @@ +<!-- BEGIN url --> +<input type="url" class="inputbox autowidth" name="{url.FIELD_IDENT}" id="{url.FIELD_IDENT}" size="{url.FIELD_LENGTH}" maxlength="{url.FIELD_MAXLEN}" value="{url.FIELD_VALUE}" /> +<!-- END url --> diff --git a/phpBB/styles/prosilver/template/quickreply_editor.html b/phpBB/styles/prosilver/template/quickreply_editor.html index 9164cb1919..6a8846626e 100644 --- a/phpBB/styles/prosilver/template/quickreply_editor.html +++ b/phpBB/styles/prosilver/template/quickreply_editor.html @@ -1,22 +1,26 @@ <form method="post" action="{U_QR_ACTION}" id="qr_postform"> +<!-- EVENT quickreply_editor_panel_before --> <div class="panel"> <div class="inner"> - <h2>{L_QUICKREPLY}</h2> + <h2 class="quickreply-title">{L_QUICKREPLY}</h2> <fieldset class="fields1"> <dl style="clear: left;"> <dt><label for="subject">{L_SUBJECT}{L_COLON}</label></dt> <dd><input type="text" name="subject" id="subject" size="45" maxlength="124" tabindex="2" value="{SUBJECT}" class="inputbox autowidth" /></dd> </dl> + <!-- EVENT quickreply_editor_message_before --> <div id="message-box"> <textarea style="height: 9em;" name="message" rows="7" cols="76" tabindex="3" class="inputbox"></textarea> </div> + <!-- EVENT quickreply_editor_message_after --> </fieldset> <fieldset class="submit-buttons"> {S_FORM_TOKEN} {QR_HIDDEN_FIELDS} - <input type="submit" accesskey="f" tabindex="6" name="preview" value="{L_FULL_EDITOR}" class="button2" data-ajax="false" id="qr_full_editor" /> + <input type="submit" accesskey="f" tabindex="6" name="preview" value="{L_FULL_EDITOR}" class="button2" id="qr_full_editor" /> <input type="submit" accesskey="s" tabindex="7" name="post" value="{L_SUBMIT}" class="button1" /> </fieldset> </div> </div> +<!-- EVENT quickreply_editor_panel_after --> </form> diff --git a/phpBB/styles/prosilver/template/search_body.html b/phpBB/styles/prosilver/template/search_body.html index d4c1f98a2a..2f15830eb1 100644 --- a/phpBB/styles/prosilver/template/search_body.html +++ b/phpBB/styles/prosilver/template/search_body.html @@ -95,7 +95,7 @@ <div class="forumbg forumbg-table"> <div class="inner"> - <table class="table1" cellspacing="1"> + <table class="table1"> <thead> <tr> <th colspan="2" class="name">{L_RECENT_SEARCHES}</th> @@ -105,7 +105,7 @@ <!-- BEGIN recentsearch --> <tr class="<!-- IF recentsearch.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF -->"> <td><a href="{recentsearch.U_KEYWORDS}">{recentsearch.KEYWORDS}</a></td> - <td class="active"><span> {recentsearch.TIME}</span></td> + <td class="active">{recentsearch.TIME}</td> </tr> <!-- BEGINELSE --> <tr class="bg1"> diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index 7603cf4db8..818b8ee642 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -1,12 +1,12 @@ <!-- INCLUDE overall_header.html --> -<h2><!-- IF SEARCH_TITLE -->{SEARCH_TITLE}<!-- ELSE -->{SEARCH_MATCHES}<!-- ENDIF --><!-- IF SEARCH_WORDS -->{L_COLON} <a href="{U_SEARCH_WORDS}">{SEARCH_WORDS}</a><!-- ENDIF --></h2> +<h2 class="searchresults-title"><!-- IF SEARCH_TITLE -->{SEARCH_TITLE}<!-- ELSE -->{SEARCH_MATCHES}<!-- ENDIF --><!-- IF SEARCH_WORDS -->{L_COLON} <a href="{U_SEARCH_WORDS}">{SEARCH_WORDS}</a><!-- ENDIF --></h2> <!-- IF SEARCHED_QUERY --> <p>{L_SEARCHED_QUERY}{L_COLON} <strong>{SEARCHED_QUERY}</strong></p><!-- ENDIF --> <!-- IF IGNORED_WORDS --> <p>{L_IGNORED_TERMS}{L_COLON} <strong>{IGNORED_WORDS}</strong></p><!-- ENDIF --> <!-- IF PHRASE_SEARCH_DISABLED --> <p><strong>{L_PHRASE_SEARCH_DISABLED}</strong></p><!-- ENDIF --> <!-- IF SEARCH_TOPIC --> - <p><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}">{L_RETURN_TO}{L_COLON} {SEARCH_TOPIC}</a></p> + <p><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}">{L_RETURN_TO_TOPIC}</a></p> <!-- ELSE --> <p><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH}" title="{L_SEARCH_ADV}">{L_RETURN_TO_SEARCH_ADV}</a></p> <!-- ENDIF --> @@ -61,10 +61,11 @@ <li class="row<!-- IF searchresults.S_ROW_COUNT is even --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <dl class="icon {searchresults.TOPIC_IMG_STYLE}"> <dt <!-- IF searchresults.TOPIC_ICON_IMG -->style="background-image: url({T_ICONS_PATH}{searchresults.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{searchresults.TOPIC_FOLDER_IMG_ALT}"> + <!-- IF searchresults.S_UNREAD_TOPIC and not S_IS_BOT --><a href="{searchresults.U_NEWEST_POST}" class="icon-link"></a><!-- ENDIF --> <div class="list-inner"> <!-- EVENT topiclist_row_prepend --> - <!-- IF searchresults.S_UNREAD_TOPIC --><a href="{searchresults.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --> + <!-- IF searchresults.S_UNREAD_TOPIC and not S_IS_BOT --><a href="{searchresults.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --> <a href="{searchresults.U_VIEW_TOPIC}" class="topictitle">{searchresults.TOPIC_TITLE}</a> {searchresults.ATTACH_ICON_IMG} <!-- IF searchresults.S_TOPIC_UNAPPROVED or searchresults.S_POSTS_UNAPPROVED --><a href="{searchresults.U_MCP_QUEUE}">{searchresults.UNAPPROVED_IMG}</a> <!-- ENDIF --> <!-- IF searchresults.S_TOPIC_DELETED --><a href="{searchresults.U_MCP_QUEUE}">{DELETED_IMG}</a> <!-- ENDIF --> @@ -92,7 +93,7 @@ <dd class="views">{searchresults.TOPIC_VIEWS}</dd> <dd class="lastpost"><span> {L_POST_BY_AUTHOR} {searchresults.LAST_POST_AUTHOR_FULL} - <!-- IF not S_IS_BOT --><a href="{searchresults.U_LAST_POST}">{LAST_POST_IMG}</a> <!-- ENDIF --><br />{searchresults.LAST_POST_TIME}<br /> </span> + <!-- IF not S_IS_BOT --><a href="{searchresults.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{LAST_POST_IMG}</a> <!-- ENDIF --><br />{searchresults.LAST_POST_TIME}<br /> </span> </dd> </dl> </li> @@ -120,20 +121,19 @@ {searchresults.L_IGNORE_POST} </div> <!-- ELSE --> - <div class="postbody"> - <h3><a href="{searchresults.U_VIEW_POST}">{searchresults.POST_SUBJECT}</a></h3> - <div class="content">{searchresults.MESSAGE}</div> - </div> - <dl class="postprofile"> <dt class="author">{L_POST_BY_AUTHOR} {searchresults.POST_AUTHOR_FULL}</dt> - <dd>{searchresults.POST_DATE}</dd> - <dd> </dd> + <dd class="search-result-date">{searchresults.POST_DATE}</dd> <dd>{L_FORUM}{L_COLON} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a></dd> <dd>{L_TOPIC}{L_COLON} <a href="{searchresults.U_VIEW_TOPIC}">{searchresults.TOPIC_TITLE}</a></dd> <dd>{L_REPLIES}{L_COLON} <strong>{searchresults.TOPIC_REPLIES}</strong></dd> <dd>{L_VIEWS}{L_COLON} <strong>{searchresults.TOPIC_VIEWS}</strong></dd> </dl> + + <div class="postbody"> + <h3><a href="{searchresults.U_VIEW_POST}">{searchresults.POST_SUBJECT}</a></h3> + <div class="content">{searchresults.MESSAGE}</div> + </div> <!-- ENDIF --> <!-- IF not searchresults.S_IGNORE_POST --> @@ -161,7 +161,8 @@ <!-- IF U_NEXT_PAGE --><a href="{U_NEXT_PAGE}" class="right-box arrow-{S_CONTENT_FLOW_END}">{L_NEXT}</a><!-- ENDIF --> <!-- IF S_SELECT_SORT_DAYS or S_SELECT_SORT_KEY --> <label><!-- IF S_SHOW_TOPICS -->{L_DISPLAY_POSTS}<!-- ELSE -->{L_SORT_BY}</label><label><!-- ENDIF --> {S_SELECT_SORT_DAYS}<!-- IF S_SELECT_SORT_KEY --></label> <label>{S_SELECT_SORT_KEY}</label> - <label>{S_SELECT_SORT_DIR}<!-- ENDIF --> <input type="submit" name="sort" value="{L_GO}" class="button2" /></label> + <label>{S_SELECT_SORT_DIR}<!-- ENDIF --></label> + <input type="submit" name="sort" value="{L_GO}" class="button2" /> <!-- ENDIF --> </fieldset> diff --git a/phpBB/styles/prosilver/template/simple_footer.html b/phpBB/styles/prosilver/template/simple_footer.html index b6afc2fdba..10edece3cd 100644 --- a/phpBB/styles/prosilver/template/simple_footer.html +++ b/phpBB/styles/prosilver/template/simple_footer.html @@ -7,7 +7,7 @@ </div> <script type="text/javascript" src="{T_JQUERY_LINK}"></script> -<!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> +<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> <!-- INCLUDEJS forum_fn.js --> <!-- EVENT simple_footer_after --> diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html index 08b212363e..f5e265ac16 100644 --- a/phpBB/styles/prosilver/template/simple_header.html +++ b/phpBB/styles/prosilver/template/simple_header.html @@ -2,14 +2,17 @@ <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> <meta charset="utf-8"> +<meta name="viewport" content="width=device-width" /> <meta name="keywords" content="" /> <meta name="description" content="" /> {META} <title>{SITENAME} • <!-- IF S_IN_MCP -->{L_MCP} • <!-- ELSEIF S_IN_UCP -->{L_UCP} • <!-- ENDIF -->{PAGE_TITLE}</title> <link href="{T_THEME_PATH}/print.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="print" title="printonly" /> +<!-- IF S_ALLOW_CDN --><link href="//fonts.googleapis.com/css?family=Open+Sans:600&subset=latin,cyrillic-ext,latin-ext,cyrillic,greek-ext,greek,vietnamese" rel="stylesheet" type="text/css" media="screen, projection" /><!-- ENDIF --> <link href="{T_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" /> <link href="{T_STYLESHEET_LANG_LINK}" rel="stylesheet" type="text/css" media="screen, projection" /> +<link href="{T_THEME_PATH}/responsive.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="only screen and (max-width: 700px), only screen and (max-device-width: 700px)" /> <!-- IF S_CONTENT_DIRECTION eq 'rtl' --> <link href="{T_THEME_PATH}/bidi.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" /> @@ -23,7 +26,9 @@ </head> -<body id="phpbb" class="{S_CONTENT_DIRECTION}"> +<body id="phpbb" class="nojs {S_CONTENT_DIRECTION} {BODY_CLASS}"> + +<!-- EVENT simple_header_body_before --> <div id="simple-wrap"> <a id="top" accesskey="t"></a> diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html index 6c96be864a..b52acdd955 100644 --- a/phpBB/styles/prosilver/template/ucp_agreement.html +++ b/phpBB/styles/prosilver/template/ucp_agreement.html @@ -33,7 +33,7 @@ <div class="panel"> <div class="inner"> <div class="content"> - <h2>{SITENAME} - {L_REGISTRATION}</h2> + <h2 class="sitename-title">{SITENAME} - {L_REGISTRATION}</h2> <p><!-- IF S_SHOW_COPPA -->{L_COPPA_BIRTHDAY}<!-- ELSE -->{L_TERMS_OF_USE}<!-- ENDIF --></p> </div> </div> @@ -60,7 +60,7 @@ <div class="panel"> <div class="inner"> <div class="content"> - <h2>{SITENAME} - {AGREEMENT_TITLE}</h2> + <h2 class="sitename-title">{SITENAME} - {AGREEMENT_TITLE}</h2> <p>{AGREEMENT_TEXT}</p> <hr class="dashed" /> <p><a href="{U_BACK}" class="button2">{L_BACK}</a></p> diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html index feb04278dc..ed39e80c12 100644 --- a/phpBB/styles/prosilver/template/ucp_attachments.html +++ b/phpBB/styles/prosilver/template/ucp_attachments.html @@ -31,7 +31,7 @@ </dl> </li> </ul> - <ul class="topiclist cplist"> + <ul class="topiclist cplist responsive-show-columns"> <!-- BEGIN attachrow --> <li class="row<!-- IF attachrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> diff --git a/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html b/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html index a3e27328cd..18316613b0 100644 --- a/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html +++ b/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html @@ -20,7 +20,7 @@ <dt> </dt> <dd><input type="submit" name="submit" tabindex="6" value="{L_UCP_AUTH_LINK_LINK}" class="button1" /></dd> </dl> - <!-- ENDIF--> + <!-- ENDIF --> </fieldset> {oauth.HIDDEN_FIELDS} {S_HIDDEN_FIELDS} diff --git a/phpBB/styles/prosilver/template/ucp_footer.html b/phpBB/styles/prosilver/template/ucp_footer.html index ea546f7a82..f2f1a68db3 100644 --- a/phpBB/styles/prosilver/template/ucp_footer.html +++ b/phpBB/styles/prosilver/template/ucp_footer.html @@ -1,9 +1,8 @@ </div> - <div class="clear"></div> </div> - <span class="corners-bottom"><span></span></span></div> + </div> </div> <!-- IF S_COMPOSE_PM --> <div>{S_FORM_TOKEN}</div> diff --git a/phpBB/styles/prosilver/template/ucp_groups_manage.html b/phpBB/styles/prosilver/template/ucp_groups_manage.html index a785d18082..df80135acb 100644 --- a/phpBB/styles/prosilver/template/ucp_groups_manage.html +++ b/phpBB/styles/prosilver/template/ucp_groups_manage.html @@ -54,7 +54,12 @@ <fieldset> <dl> <dt><label for="group_colour">{L_GROUP_COLOR}{L_COLON}</label><br /><span>{L_GROUP_COLOR_EXPLAIN}</span></dt> - <dd><input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="6" maxlength="6" class="inputbox narrow" /> <span style="background-color: {GROUP_COLOUR};"> </span> [ <a href="{U_SWATCH}" onclick="popup(this.href, 636, 150, '_swatch'); return false;">{L_COLOUR_SWATCH}</a> ]</dd> + <dd> + <input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="6" maxlength="6" class="inputbox narrow" /> + <span style="background-color: #{GROUP_COLOUR};"> </span> + [ <a href="#" id="color_palette_toggle">{L_COLOUR_SWATCH}</a> ] + <div id="color_palette_placeholder" class="hidden" data-orientation="h" data-height="12" data-width="15" data-target="#group_colour"></div> + </dd> </dl> <dl> <dt><label for="group_rank">{L_GROUP_RANK}{L_COLON}</label></dt> @@ -77,7 +82,7 @@ <!-- ELSEIF S_LIST --> <!-- IF .leader --> - <table class="table1" cellspacing="1"> + <table class="table1"> <thead> <tr> <th class="name">{L_GROUP_LEAD}</th> @@ -103,7 +108,7 @@ <!-- BEGIN member --> <!-- IF member.S_PENDING --> - <table class="table1" cellspacing="1"> + <table class="table1"> <thead> <tr> <th class="name">{L_GROUP_PENDING}</th> @@ -119,7 +124,7 @@ </tbody> </table> <!-- ENDIF --> - <table class="table1" cellspacing="1"> + <table class="table1"> <thead> <tr> <th class="name">{L_GROUP_APPROVED}</th> @@ -140,7 +145,7 @@ </tr> <!-- ENDIF --> <!-- BEGINELSE --> - <table class="table1" cellspacing="1"> + <table class="table1"> <thead> <tr> <th class="name">{L_MEMBERS}</th> @@ -159,7 +164,7 @@ <!-- IF .pagination --> <!-- INCLUDE pagination.html --> <!-- ELSE --> - {S_ON_PAGE} + {PAGE_NUMBER} <!-- ENDIF --> </li> </ul> @@ -214,7 +219,7 @@ </dl> </li> </ul> - <ul class="topiclist cplist two-long-columns"> + <ul class="topiclist cplist two-long-columns responsive-show-all"> <!-- BEGIN leader --> <li class="row<!-- IF attachrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> diff --git a/phpBB/styles/prosilver/template/ucp_header.html b/phpBB/styles/prosilver/template/ucp_header.html index c5d58b8eaa..102ea5a3a0 100644 --- a/phpBB/styles/prosilver/template/ucp_header.html +++ b/phpBB/styles/prosilver/template/ucp_header.html @@ -1,6 +1,6 @@ <!-- INCLUDE overall_header.html --> -<h2>{L_UCP}</h2> +<h2 class="ucp-title">{L_UCP}</h2> <div id="tabs"> <ul> @@ -98,4 +98,4 @@ </div> - <div id="cp-main" class="ucp-main"> + <div id="cp-main" class="ucp-main panel-container"> diff --git a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html index 017fadad77..b9e3c16524 100644 --- a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html +++ b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html @@ -36,6 +36,7 @@ <!-- ELSE --> <dl class="icon {topicrow.TOPIC_IMG_STYLE}"> <dt<!-- IF topicrow.TOPIC_ICON_IMG --> style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{topicrow.TOPIC_FOLDER_IMG_ALT}"> + <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}" class="icon-link"></a><!-- ENDIF --> <div class="list-inner"> <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --><a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a> <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF --> @@ -54,11 +55,19 @@ </ul> </div> <!-- ENDIF --> - <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF -->{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + <div class="responsive-hide"> + <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF --> + {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + </div> + <div class="responsive-show" style="display: none;"> + <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF --> + {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} « + <a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{topicrow.LAST_POST_TIME}</a> + </div> </div> </dt> <dd class="lastpost"><span><dfn>{L_LAST_POST} </dfn>{L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} - <a href="{topicrow.U_LAST_POST}">{LAST_POST_IMG}</a> <br />{topicrow.LAST_POST_TIME}</span> + <a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{LAST_POST_IMG}</a> <br />{topicrow.LAST_POST_TIME}</span> </dd> <dd class="mark"><input type="checkbox" name="t[{topicrow.TOPIC_ID}]" id="t{topicrow.TOPIC_ID}" /></dd> </dl> diff --git a/phpBB/styles/prosilver/template/ucp_main_drafts.html b/phpBB/styles/prosilver/template/ucp_main_drafts.html index 723186e20c..52ad5b503b 100644 --- a/phpBB/styles/prosilver/template/ucp_main_drafts.html +++ b/phpBB/styles/prosilver/template/ucp_main_drafts.html @@ -45,6 +45,10 @@ <!-- ELSEIF draftrow.S_LINK_FORUM -->{L_FORUM}{L_COLON} <a href="{draftrow.U_VIEW}">{draftrow.TITLE}</a> <!-- ELSEIF S_PRIVMSGS --> <!-- ELSE -->{L_NO_TOPIC_FORUM}<!-- ENDIF --> + <div class="responsive-show" style="display: none;"> + {L_SAVE_DATE}{L_COLON} <strong>{draftrow.DATE}</strong><br /> + <!-- IF draftrow.U_INSERT --><a href="{draftrow.U_INSERT}">{L_LOAD_DRAFT}</a> • <!-- ENDIF --><a href="{draftrow.U_VIEW_EDIT}">{L_VIEW_EDIT}</a> + </div> </div> </dt> <dd class="info"><span>{draftrow.DATE}<br /><!-- IF draftrow.U_INSERT --><a href="{draftrow.U_INSERT}">{L_LOAD_DRAFT}</a> • <!-- ENDIF --><a href="{draftrow.U_VIEW_EDIT}">{L_VIEW_EDIT}</a></span></dd> diff --git a/phpBB/styles/prosilver/template/ucp_main_front.html b/phpBB/styles/prosilver/template/ucp_main_front.html index 1e26e43772..942d26edc6 100644 --- a/phpBB/styles/prosilver/template/ucp_main_front.html +++ b/phpBB/styles/prosilver/template/ucp_main_front.html @@ -15,6 +15,7 @@ <li class="row<!-- IF topicrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <dl class="icon {topicrow.TOPIC_IMG_STYLE}"> <dt <!-- IF topicrow.TOPIC_ICON_IMG -->style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF -->> + <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}" class="icon-link"></a><!-- ENDIF --> <div class="list-inner"> <!-- IF topicrow.S_UNREAD --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --><a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a><br /> <!-- IF .topicrow.pagination --> @@ -31,11 +32,18 @@ </ul> </div> <!-- ENDIF --> - <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF -->{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + <div class="responsive-hide"> + <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF --> + {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + </div> + <div class="responsive-show" style="display: none;"> + <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF --> + {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} « <a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{topicrow.LAST_POST_TIME}</a> + </div> </div> </dt> <dd class="lastpost"><span>{L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} - <a href="{topicrow.U_LAST_POST}">{LAST_POST_IMG}</a> <br />{topicrow.LAST_POST_TIME}</span> + <a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{LAST_POST_IMG}</a> <br />{topicrow.LAST_POST_TIME}</span> </dd> </dl> </li> @@ -47,7 +55,7 @@ <dl class="details"> <dt>{L_JOINED}{L_COLON}</dt> <dd>{JOINED}</dd> - <dt>{L_VISITED}{L_COLON}</dt> <dd>{LAST_VISIT_YOU}</dd> + <dt>{L_LAST_ACTIVE}{L_COLON}</dt> <dd>{LAST_VISIT_YOU}</dd> <dt>{L_TOTAL_POSTS}{L_COLON}</dt> <dd><!-- IF POSTS_PCT -->{POSTS}<!-- IF S_DISPLAY_SEARCH --> | <strong><a href="{U_SEARCH_USER}">{L_SEARCH_YOUR_POSTS}</a></strong><!-- ENDIF --><br />({POSTS_DAY} / {POSTS_PCT})<!-- ELSE -->{POSTS}<!-- ENDIF --></dd> <!-- IF ACTIVE_FORUM != '' --><dt>{L_ACTIVE_IN_FORUM}{L_COLON}</dt> <dd><strong><a href="{U_ACTIVE_FORUM}">{ACTIVE_FORUM}</a></strong><br />({ACTIVE_FORUM_POSTS} / {ACTIVE_FORUM_PCT})</dd><!-- ENDIF --> <!-- IF ACTIVE_TOPIC != '' --><dt>{L_ACTIVE_IN_TOPIC}{L_COLON}</dt> <dd><strong><a href="{U_ACTIVE_TOPIC}">{ACTIVE_TOPIC}</a></strong><br />({ACTIVE_TOPIC_POSTS} / {ACTIVE_TOPIC_PCT})</dd><!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/ucp_main_subscribed.html b/phpBB/styles/prosilver/template/ucp_main_subscribed.html index 90fa76cefc..74ab5226cb 100755..100644 --- a/phpBB/styles/prosilver/template/ucp_main_subscribed.html +++ b/phpBB/styles/prosilver/template/ucp_main_subscribed.html @@ -23,9 +23,20 @@ <!-- BEGIN forumrow --> <li class="row<!-- IF forumrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <dl class="icon {forumrow.FORUM_IMG_STYLE}"> - <dt><div class="list-inner"><a href="{forumrow.U_VIEWFORUM}" class="forumtitle">{forumrow.FORUM_NAME}</a><br />{forumrow.FORUM_DESC}</div></dt> + <dt> + <!-- IF forumrow.S_UNREAD_FORUM --><a href="{forumrow.U_VIEWFORUM}" class="icon-link"></a><!-- ENDIF --> + <div class="list-inner"> + <a href="{forumrow.U_VIEWFORUM}" class="forumtitle">{forumrow.FORUM_NAME}</a><br /> + {forumrow.FORUM_DESC} + <!-- IF forumrow.LAST_POST_TIME --> + <div class="responsive-show" style="display: none;"> + {L_LAST_POST} {L_POST_BY_AUTHOR} {forumrow.LAST_POST_AUTHOR_FULL} « <a href="{topicrow.U_LAST_POST}">{forumrow.LAST_POST_TIME}</a> + </div> + <!-- ENDIF --> + </div> + </dt> <dd class="lastpost"><!-- IF forumrow.LAST_POST_TIME --><span><dfn>{L_LAST_POST} </dfn>{L_POST_BY_AUTHOR} {forumrow.LAST_POST_AUTHOR_FULL} - <a href="{topicrow.U_LAST_POST}">{LAST_POST_IMG}</a> <br />{forumrow.LAST_POST_TIME}</span> + <a href="{forumrow.U_LAST_POST}">{LAST_POST_IMG}</a> <br />{forumrow.LAST_POST_TIME}</span> <!-- ELSE -->{L_NO_POSTS}<br /> <!-- ENDIF --> </dd> <dd class="mark"><input type="checkbox" name="f[{forumrow.FORUM_ID}]" id="f{forumrow.FORUM_ID}" /></dd> @@ -61,6 +72,7 @@ <li class="row<!-- IF topicrow.S_TOPIC_REPORTED --> reported<!-- ELSEIF topicrow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF -->"> <dl class="icon {topicrow.TOPIC_IMG_STYLE}"> <dt<!-- IF topicrow.TOPIC_ICON_IMG --> style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{topicrow.TOPIC_FOLDER_IMG_ALT}"> + <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}" class="icon-link"></a><!-- ENDIF --> <div class="list-inner"> <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --><a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a> <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF --> @@ -79,11 +91,18 @@ </ul> </div> <!-- ENDIF --> - <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF -->{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + <div class="responsive-hide"> + <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF --> + {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + </div> + <div class="responsive-show" style="display: none;"> + <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF --> + {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} « <a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{topicrow.LAST_POST_TIME}</a> + </div> </div> </dt> <dd class="lastpost"><span><dfn>{L_LAST_POST} </dfn>{L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} - <a href="{topicrow.U_LAST_POST}">{LAST_POST_IMG}</a> <br />{topicrow.LAST_POST_TIME}</span> + <a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{LAST_POST_IMG}</a> <br />{topicrow.LAST_POST_TIME}</span> </dd> <dd class="mark"><input type="checkbox" name="t[{topicrow.TOPIC_ID}]" id="t{topicrow.TOPIC_ID}" /></dd> </dl> diff --git a/phpBB/styles/prosilver/template/ucp_notifications.html b/phpBB/styles/prosilver/template/ucp_notifications.html index 2088de49e8..b400a3c8b1 100644 --- a/phpBB/styles/prosilver/template/ucp_notifications.html +++ b/phpBB/styles/prosilver/template/ucp_notifications.html @@ -9,13 +9,15 @@ <p>{TITLE_EXPLAIN}</p> <!-- IF MODE == 'notification_options' --> - <table class="table1" cellspacing="1"> + <table class="table1"> <thead> - <th>{L_NOTIFICATION_TYPE}</th> - <!-- BEGIN notification_methods --> - <th class="mark">{notification_methods.NAME}</th> - <!-- END notification_methods --> - <th class="mark">{L_NOTIFICATIONS}</th> + <tr> + <th>{L_NOTIFICATION_TYPE}</th> + <!-- BEGIN notification_methods --> + <th class="mark">{notification_methods.NAME}</th> + <!-- END notification_methods --> + <th class="mark">{L_NOTIFICATIONS}</th> + </tr> </thead> <tbody> <!-- BEGIN notification_types --> @@ -44,7 +46,7 @@ <div class="topic-actions"> <div class="pagination"> <!-- IF U_MARK_ALL --><a href="{U_MARK_ALL}">{L_NOTIFICATIONS_MARK_ALL_READ}</a> • <!-- ENDIF --> - <!-- IF TOTAL_COUNT -->{TOTAL_COUNT} • <!-- ENDIF --> + <!-- IF TOTAL_COUNT -->{L_NOTIFICATIONS} [<strong>{TOTAL_COUNT}</strong>] • <!-- ENDIF --> <!-- IF .pagination --> <!-- INCLUDE pagination.html --> <!-- ELSE --> @@ -68,18 +70,17 @@ <li class="row<!-- IF notification_list.UNREAD --> bg3<!-- ELSE --><!-- IF notification_list.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF --><!-- ENDIF -->"> <dl> <dt> - <div class="list-inner"> - <!-- IF notification_list.URL --><a href="<!-- IF notification_list.UNREAD -->{notification_list.U_MARK_READ}<!-- ELSE -->{notification_list.URL}<!-- ENDIF -->"><!-- ENDIF --> - {notification_list.AVATAR} - <div class="notifications"> - <p class="notifications_title">{notification_list.FORMATTED_TITLE}</p> - <p class="notifications_time">» {notification_list.TIME}</p> - - <!-- IF not notification_list.URL and notification_list.U_MARK_READ --> - <p><a href="{notification_list.U_MARK_READ}">{L_MARK_READ}</a></p> - <!-- ENDIF --> - </div> - <!-- IF notification_list.URL --></a><!-- ENDIF --> + <div class="list-inner"> + <!-- IF notification_list.AVATAR -->{notification_list.AVATAR}<!-- ELSE --><img src="{T_THEME_PATH}/images/no_avatar.gif" alt="" /><!-- ENDIF --> + <div class="notifications"> + <!-- IF notification_list.URL --><a href="<!-- IF notification_list.UNREAD -->{notification_list.U_MARK_READ}<!-- ELSE -->{notification_list.URL}<!-- ENDIF -->"><!-- ENDIF --> + <p class="notifications_title">{notification_list.FORMATTED_TITLE}</p> + <!-- IF notification_list.URL --></a><!-- ENDIF --> + <p class="notifications_time">{notification_list.TIME}</p> + <!-- IF not notification_list.URL and notification_list.U_MARK_READ --> + <p><a href="{notification_list.U_MARK_READ}">{L_MARK_READ}</a></p> + <!-- ENDIF --> + </div> </div> </dt> @@ -93,7 +94,7 @@ <!-- IF .pagination or TOTAL_COUNT --> <div class="topic-actions"> <div class="pagination"> - <!-- IF TOTAL_COUNT -->{TOTAL_COUNT} • <!-- ENDIF --> + <!-- IF TOTAL_COUNT -->{L_NOTIFICATIONS} [<strong>{TOTAL_COUNT}</strong>] • <!-- ENDIF --> <!-- IF .pagination --> <!-- INCLUDE pagination.html --> <!-- ELSE --> @@ -116,7 +117,7 @@ <input type="hidden" name="form_time" value="{FORM_TIME}" /> {S_HIDDEN_FIELDS} <input type="submit" name="submit" value="<!-- IF MODE == 'notification_options' -->{L_SUBMIT}<!-- ELSE -->{L_MARK_READ}<!-- ENDIF -->" class="button1" /> - <div><a href="#" onclick="$('#ucp input:checkbox').attr('checked', true); return false;">{L_MARK_ALL}</a> • <a href="#" onclick="$('#ucp input:checkbox').attr('checked', false); return false;">{L_UNMARK_ALL}</a></div> + <div><a href="#" onclick="$('#ucp input:checkbox').prop('checked', true); return false;">{L_MARK_ALL}</a> • <a href="#" onclick="$('#ucp input:checkbox').prop('checked', false); return false;">{L_UNMARK_ALL}</a></div> {S_FORM_TOKEN} </fieldset> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/ucp_pm_history.html b/phpBB/styles/prosilver/template/ucp_pm_history.html index 3d886b1c3d..d08f622d1f 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_history.html +++ b/phpBB/styles/prosilver/template/ucp_pm_history.html @@ -15,13 +15,14 @@ <div class="inner"> <div class="postbody" id="pr{history_row.MSG_ID}"> + <h3><a href="{history_row.U_VIEW_MESSAGE}" <!-- IF history_row.S_CURRENT_MSG -->class="current"<!-- ENDIF -->>{history_row.SUBJECT}</a></h3> + <!-- IF history_row.U_QUOTE or history_row.MESSAGE_AUTHOR_QUOTE --> <ul class="profile-icons"> <li class="quote-icon"><a <!-- IF history_row.U_QUOTE -->href="{history_row.U_QUOTE}"<!-- ELSE -->href="#postingbox" onclick="addquote({history_row.MSG_ID}, '{history_row.MESSAGE_AUTHOR_QUOTE}', '{LA_WROTE}');"<!-- ENDIF --> title="{L_QUOTE} {history_row.MESSAGE_AUTHOR}"><span>{L_QUOTE} {history_row.MESSAGE_AUTHOR}</span></a></li> </ul> <!-- ENDIF --> - <h3><a href="{history_row.U_VIEW_MESSAGE}" <!-- IF history_row.S_CURRENT_MSG -->class="current"<!-- ENDIF -->>{history_row.SUBJECT}</a></h3> <p class="author">{history_row.MINI_POST_IMG} {L_SENT_AT}{L_COLON} <strong>{history_row.SENT_DATE}</strong><br /> {L_MESSAGE_BY_AUTHOR} {history_row.MESSAGE_AUTHOR_FULL}</p> <div class="content"><!-- IF history_row.MESSAGE -->{history_row.MESSAGE}<!-- ELSE --><span class="error">{L_MESSAGE_REMOVED_FROM_OUTBOX}</span><!-- ENDIF --></div> diff --git a/phpBB/styles/prosilver/template/ucp_pm_message_header.html b/phpBB/styles/prosilver/template/ucp_pm_message_header.html index 7a80f72348..840eba4c83 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_message_header.html +++ b/phpBB/styles/prosilver/template/ucp_pm_message_header.html @@ -15,10 +15,22 @@ </div> <!-- ENDIF --> + <!-- IF not S_IS_BOT and U_PRINT_PM --> + <div class="dropdown-container dropdown-button-control topic-tools"> + <span title="{L_PM_TOOLS}" class="dropdown-trigger dropdown-select dropdown-select-icon tools-icon"><span></span></span> + <div class="dropdown hidden"> + <div class="pointer"><div class="pointer-inner"></div></div> + <ul class="dropdown-contents"> + <!-- IF U_PRINT_PM --><li class="small-icon icon-print"><a href="{U_PRINT_PM}" title="{L_PRINT_PM}" accesskey="p">{L_PRINT_PM}</a></li><!-- ENDIF --> + </ul> + </div> + </div> + <!-- ENDIF --> + <!-- IF TOTAL_MESSAGES or S_VIEW_MESSAGE --> <ul class="linklist"> <li class="rightside pagination"> - <!-- IF S_VIEW_MESSAGE --><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_CURRENT_FOLDER}">{L_RETURN_TO} {CUR_FOLDER_NAME}</a><!-- ENDIF --> + <!-- IF S_VIEW_MESSAGE --><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_CURRENT_FOLDER}">{L_RETURN_TO_FOLDER}</a><!-- ENDIF --> <!-- IF FOLDER_CUR_MESSAGES neq 0 --> <!-- IF TOTAL_MESSAGES -->{TOTAL_MESSAGES} • <!-- ENDIF --> <!-- IF .pagination --> diff --git a/phpBB/styles/prosilver/template/ucp_pm_popup.html b/phpBB/styles/prosilver/template/ucp_pm_popup.html deleted file mode 100644 index 4cc39ee450..0000000000 --- a/phpBB/styles/prosilver/template/ucp_pm_popup.html +++ /dev/null @@ -1,25 +0,0 @@ -<!-- INCLUDE simple_header.html --> - -<script type="text/javascript"> -// <![CDATA[ -/** -* Jump to inbox -*/ -function jump_to_inbox(url) -{ - opener.document.location.href = url.replace(/&/g, '&'); - window.close(); -} -// ]]> -</script> - -<div class="panel"> - <div class="inner"> - <div class="content"> - <p><!-- IF S_NOT_LOGGED_IN -->{L_LOGIN_CHECK_PM}<!-- ELSE -->{MESSAGE}<br /><br />{CLICK_TO_VIEW}<!-- ENDIF --></p> - <p class="small"><a href="#" onclick="window.close(); return false;">{L_CLOSE_WINDOW}</a></p> - </div> - </div> -</div> - -<!-- INCLUDE simple_footer.html --> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html index 9cbff64a6a..b081c14498 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html @@ -53,12 +53,13 @@ </dl> </li> </ul> - <ul class="topiclist cplist pmlist <!-- IF S_SHOW_RECIPIENTS -->missing-column<!-- ELSE -->two-columns<!-- ENDIF -->"> + <ul class="topiclist cplist pmlist responsive-show-all <!-- IF S_SHOW_RECIPIENTS -->missing-column<!-- ELSE -->two-columns<!-- ENDIF -->"> <!-- BEGIN messagerow --> <li class="row<!-- IF messagerow.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF --><!-- IF messagerow.PM_CLASS --> {messagerow.PM_CLASS}<!-- ENDIF -->"> <dl class="icon {messagerow.FOLDER_IMG_STYLE}"> <dt<!-- IF messagerow.PM_ICON_URL and S_PM_ICONS --> style="background-image: url({messagerow.PM_ICON_URL}); background-repeat: no-repeat;"<!-- ENDIF -->> + <!-- IF messagerow.S_PM_UNREAD and not messagerow.S_PM_DELETED --><a href="{messagerow.U_VIEW_PM}" class="icon-link"></a><!-- ENDIF --> <div class="list-inner"> <!-- IF messagerow.S_PM_DELETED --> @@ -126,7 +127,8 @@ <!-- IF U_NEXT_PAGE --><a href="{U_NEXT_PAGE}" class="right-box arrow-{S_CONTENT_FLOW_END}">{L_NEXT}</a><!-- ENDIF --> <label>{L_DISPLAY}{L_COLON} {S_SELECT_SORT_DAYS}</label> <label>{L_SORT_BY} {S_SELECT_SORT_KEY}</label> - <label>{S_SELECT_SORT_DIR} <input type="submit" name="sort" value="{L_GO}" class="button2" /></label> + <label>{S_SELECT_SORT_DIR}</label> + <input type="submit" name="sort" value="{L_GO}" class="button2" /> <input type="hidden" name="cur_folder_id" value="{CUR_FOLDER_ID}" /> </fieldset> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index 50e76f5b75..f14e4708e7 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -17,7 +17,47 @@ <div id="post-{MESSAGE_ID}" class="post pm<!-- IF S_POST_UNAPPROVED or S_POST_REPORTED --> reported<!-- ENDIF --><!-- IF S_ONLINE --> online<!-- ENDIF -->"> <div class="inner"> + <dl class="postprofile" id="profile{MESSAGE_ID}"> + <dt class="<!-- IF RANK_TITLE or RANK_IMG -->has-profile-rank<!-- ELSE -->no-profile-rank<!-- ENDIF -->"><!-- IF AUTHOR_AVATAR --><a href="{U_MESSAGE_AUTHOR}" class="avatar">{AUTHOR_AVATAR}</a><!-- ENDIF -->{MESSAGE_AUTHOR_FULL}</dt> + + <!-- IF RANK_TITLE or RANK_IMG --><dd class="profile-rank">{RANK_TITLE}<!-- IF RANK_TITLE and RANK_IMG --><br /><!-- ENDIF -->{RANK_IMG}</dd><!-- ENDIF --> + + <dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> {AUTHOR_POSTS}</dd> + <!-- IF AUTHOR_JOINED --><dd class="profile-joined"><strong>{L_JOINED}{L_COLON}</strong> {AUTHOR_JOINED}</dd><!-- ENDIF --> + + <!-- EVENT ucp_pm_viewmessage_custom_fields_before --> + <!-- BEGIN custom_fields --> + <!-- IF not custom_fields.S_PROFILE_CONTACT --> + <dd class="profile-custom-field profile-{custom_fields.PROFILE_FIELD_IDENT}"><strong>{custom_fields.PROFILE_FIELD_NAME}{L_COLON}</strong> {custom_fields.PROFILE_FIELD_VALUE}</dd> + <!-- ENDIF --> + <!-- END custom_fields --> + <!-- EVENT ucp_pm_viewmessage_custom_fields_after --> + + + <!-- IF U_PM or U_EMAIL or U_JABBER --> + <dd class="profile-contact"> + <ul class="profile-icons"> + <!-- EVENT ucp_pm_viewmessage_contact_fields_before --> + <!-- IF U_PM --><li class="pm-icon"><a href="{U_PM}" title="{L_PRIVATE_MESSAGE}"><span>{L_PRIVATE_MESSAGE}</span></a></li><!-- ENDIF --> + <!-- IF U_EMAIL --><li class="email-icon"><a href="{U_EMAIL}" title="{L_SEND_EMAIL_USER} {MESSAGE_AUTHOR}"><span>{L_SEND_EMAIL_USER} {MESSAGE_AUTHOR}</span></a></li><!-- ENDIF --> + <!-- IF U_JABBER --><li class="jabber-icon"><a href="{U_JABBER}" onclick="popup(this.href, 550, 320); return false;" title="{L_JABBER}"><span>{L_JABBER}</span></a></li><!-- ENDIF --> + <!-- BEGIN custom_fields --> + <!-- IF custom_fields.S_PROFILE_CONTACT --> + <li class="{custom_fields.PROFILE_FIELD_IDENT}-icon"> + <a href="<!-- IF custom_fields.PROFILE_FIELD_CONTACT -->{custom_fields.PROFILE_FIELD_CONTACT}<!-- ELSE -->{U_MESSAGE_AUTHOR}<!-- ENDIF -->"> + <span>{custom_fields.PROFILE_FIELD_NAME}</span> + </a> + </li> + <!-- ENDIF --> + <!-- END custom_fields --> + <!-- EVENT ucp_pm_viewmessage_contact_fields_after --> + </ul> + </dd> + <!-- ENDIF --> + </dl> + <div class="postbody"> + <h3 class="first">{SUBJECT}</h3> <!-- IF U_DELETE or U_EDIT or U_QUOTE or U_REPORT --> <ul class="profile-icons"> @@ -28,8 +68,6 @@ </ul> <!-- ENDIF --> - <h3 class="first">{SUBJECT}</h3> - <p class="author"> <strong>{L_SENT_AT}{L_COLON}</strong> {SENT_DATE} <br /><strong>{L_PM_FROM}{L_COLON}</strong> {MESSAGE_AUTHOR_FULL} @@ -76,38 +114,6 @@ <!-- ENDIF --> </div> - <dl class="postprofile" id="profile{MESSAGE_ID}"> - <dt><!-- IF AUTHOR_AVATAR --><a href="{U_MESSAGE_AUTHOR}">{AUTHOR_AVATAR}</a><br /><!-- ENDIF -->{MESSAGE_AUTHOR_FULL}</dt> - <!-- IF RANK_TITLE --><dd>{RANK_TITLE}</dd><!-- ENDIF --> - <!-- IF RANK_IMG --><dd>{RANK_IMG}</dd><!-- ENDIF --> - <dd> </dd> - <dd><strong>{L_POSTS}{L_COLON}</strong> {AUTHOR_POSTS}</dd> - <!-- IF AUTHOR_JOINED --><dd><strong>{L_JOINED}{L_COLON}</strong> {AUTHOR_JOINED}</dd><!-- ENDIF --> - <!-- IF AUTHOR_FROM --><dd><strong>{L_LOCATION}{L_COLON}</strong> {AUTHOR_FROM}</dd><!-- ENDIF --> - - <!-- EVENT ucp_pm_viewmessage_custom_fields_before --> - <!-- BEGIN custom_fields --> - <dd><strong>{custom_fields.PROFILE_FIELD_NAME}{L_COLON}</strong> {custom_fields.PROFILE_FIELD_VALUE}</dd> - <!-- END custom_fields --> - <!-- EVENT ucp_pm_viewmessage_custom_fields_after --> - - - <!-- IF U_PM or U_EMAIL or U_WWW or U_MSN or U_ICQ or U_YIM or U_AIM or U_JABBER --> - <dd> - <ul class="profile-icons"> - <!-- IF U_PM --><li class="pm-icon"><a href="{U_PM}" title="{L_PRIVATE_MESSAGE}"><span>{L_PRIVATE_MESSAGE}</span></a></li><!-- ENDIF --> - <!-- IF U_EMAIL --><li class="email-icon"><a href="{U_EMAIL}" title="{L_SEND_EMAIL_USER} {MESSAGE_AUTHOR}"><span>{L_SEND_EMAIL_USER} {MESSAGE_AUTHOR}</span></a></li><!-- ENDIF --> - <!-- IF U_WWW --><li class="web-icon"><a href="{U_WWW}" title="{L_VISIT_WEBSITE}{L_COLON} {U_WWW}"><span>{L_WEBSITE}</span></a></li><!-- ENDIF --> - <!-- IF U_MSN --><li class="msnm-icon"><a href="{U_MSN}" onclick="popup(this.href, 550, 320); return false;" title="{L_MSNM}"><span>{L_MSNM}</span></a></li><!-- ENDIF --> - <!-- IF U_ICQ --><li class="icq-icon"><a href="{U_ICQ}" onclick="popup(this.href, 550, 320); return false;" title="{L_ICQ}"><span>{L_ICQ}</span></a></li><!-- ENDIF --> - <!-- IF U_YIM --><li class="yahoo-icon"><a href="{U_YIM}" onclick="popup(this.href, 780, 550); return false;" title="{L_YIM}"><span>{L_YIM}</span></a></li><!-- ENDIF --> - <!-- IF U_AIM --><li class="aim-icon"><a href="{U_AIM}" onclick="popup(this.href, 550, 320); return false;" title="{L_AIM}"><span>{L_AIM}</span></a></li><!-- ENDIF --> - <!-- IF U_JABBER --><li class="jabber-icon"><a href="{U_JABBER}" onclick="popup(this.href, 550, 320); return false;" title="{L_JABBER}"><span>{L_JABBER}</span></a></li><!-- ENDIF --> - </ul> - </dd> - <!-- ENDIF --> - </dl> - <div class="back2top"><a href="#top" class="top" title="{L_BACK_TO_TOP}">{L_BACK_TO_TOP}</a></div> </div> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html index 4a8d3da08a..4d7346fda8 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html @@ -2,8 +2,6 @@ <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> <meta charset="utf-8"> -<meta name="keywords" content="" /> -<meta name="description" content="" /> <meta name="robots" content="noindex" /> {META} <title>{SITENAME} • {PAGE_TITLE}</title> diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html index 8111496dcb..d07aab1a89 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html @@ -66,7 +66,7 @@ <dl> <dt><label for="dateformat">{L_BOARD_DATE_FORMAT}{L_COLON}</label><br /><span>{L_BOARD_DATE_FORMAT_EXPLAIN}</span></dt> <dd> - <select name="dateoptions" id="dateoptions" onchange="if(this.value=='custom'){dE('custom_date',1);}else{dE('custom_date',-1);} if (this.value == 'custom') { document.getElementById('dateformat').value = default_dateformat; } else { document.getElementById('dateformat').value = this.value; }"> + <select name="dateoptions" id="dateoptions" onchange="if(this.value=='custom'){phpbb.toggleDisplay('custom_date',1);}else{phpbb.toggleDisplay('custom_date',-1);} if (this.value == 'custom') { document.getElementById('dateformat').value = default_dateformat; } else { document.getElementById('dateformat').value = this.value; }"> {S_DATEFORMAT_OPTIONS} </select> </dd> @@ -109,15 +109,15 @@ // Show/hide custom field if (e.selectedIndex == e.length - 1) { - dE('custom_date',1); + phpbb.toggleDisplay('custom_date',1); } else { - dE('custom_date',-1); + phpbb.toggleDisplay('custom_date',-1); } } - customDates(); + window.onload = customDates; // ]]> </script> diff --git a/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html b/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html index a6c19508e2..6fec0b8aed 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html +++ b/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html @@ -5,49 +5,41 @@ <h2>{L_TITLE}</h2> <div class="panel"> <div class="inner"> - - <fieldset> - <!-- IF .errors --> - <p class="error"> - <!-- BEGIN errors --> - {errors} <br /> - <!-- END errors --> - </p> - <!-- ENDIF --> - - <p>{L_PROFILE_AUTOLOGIN_KEYS}</p><br /> - <table cellspacing="1" class="table1"> - <thead> - <tr> - <th>{L_MARK}</th> - <th>{L_LOGIN_KEY}</th> - <th>{L_IP}</th> - <th>{L_LOGIN_TIME}</th> - </tr> - </thead> - <tbody> - <!-- BEGIN sessions --> - <!-- IF sessions.S_ROW_COUNT is even --><tr class="bg1"><!-- ELSE --><tr class="bg2"><!-- ENDIF --> - <td style="text-align: center"><input type="checkbox" name="keys[]" value="{sessions.KEY}" id="{sessions.KEY}"/></td> - <td><label for="{sessions.KEY}">{sessions.KEY}</label></td> - <td style="text-align: center">{sessions.IP}</td> - <td style="text-align: center">{sessions.LOGIN_TIME}</td> - </tr> - <!-- BEGINELSE --> - <tr><td colspan="4" class="bg1" style="text-align: center">{L_PROFILE_NO_AUTOLOGIN_KEYS}</td></tr> - <!-- END sessions --> - </tbody> - </table> - </fieldset> + <p>{L_PROFILE_AUTOLOGIN_KEYS}</p> + <!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF --> + <table class="table1"> + <thead> + <tr> + <th>{L_LOGIN_KEY}</th> + <th>{L_IP}</th> + <th>{L_LOGIN_TIME}</th> + <th class="mark">{L_MARK}</th> + </tr> + </thead> + <tbody> + <!-- BEGIN sessions --> + <!-- IF sessions.S_ROW_COUNT is even --><tr class="bg1"><!-- ELSE --><tr class="bg2"><!-- ENDIF --> + <td><label for="{sessions.KEY}">{sessions.KEY}</label></td> + <td style="text-align: center">{sessions.IP}</td> + <td style="text-align: center">{sessions.LOGIN_TIME}</td> + <td style="text-align: center" class="mark"><input type="checkbox" name="keys[]" value="{sessions.KEY}" id="{sessions.KEY}" /></td> + </tr> + <!-- BEGINELSE --> + <tr><td colspan="4" class="bg1" style="text-align: center">{L_PROFILE_NO_AUTOLOGIN_KEYS}</td></tr> + <!-- END sessions --> + </tbody> + </table> </div> </div> <!-- IF .sessions --> - <fieldset class="submit-buttons"> - {S_HIDDEN_FIELDS}<input type="submit" name="submit" value="{L_DELETE}" class="button1" /> + <fieldset class="display-actions"> + {S_HIDDEN_FIELDS}<input type="submit" name="submit" value="{L_DELETE_MARKED}" class="button2" /> + <div><a href="#" onclick="$('#ucp input:checkbox').prop('checked', true); return false;">{L_MARK_ALL}</a> • <a href="#" onclick="$('#ucp input:checkbox').prop('checked', false); return false;">{L_UNMARK_ALL}</a></div> {S_FORM_TOKEN} </fieldset> <!-- ENDIF --> + </form> <!-- INCLUDE ucp_footer.html --> diff --git a/phpBB/styles/prosilver/template/ucp_profile_profile_info.html b/phpBB/styles/prosilver/template/ucp_profile_profile_info.html index 3578c29e8e..c0bf681f47 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_profile_info.html +++ b/phpBB/styles/prosilver/template/ucp_profile_profile_info.html @@ -10,52 +10,20 @@ <fieldset> <!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF --> - <dl> - <dt><label for="icq">{L_UCP_ICQ}{L_COLON}</label></dt> - <dd><input type="text" name="icq" id="icq" maxlength="15" value="{ICQ}" class="inputbox" /></dd> - </dl> - <dl> - <dt><label for="aim">{L_UCP_AIM}{L_COLON}</label></dt> - <dd><input type="text" name="aim" id="aim" maxlength="255" value="{AIM}" class="inputbox" /></dd> - </dl> - <dl> - <dt><label for="msn">{L_UCP_MSNM}{L_COLON}</label></dt> - <dd><input type="email" name="msn" id="msn" maxlength="255" value="{MSN}" class="inputbox" /></dd> - </dl> - <dl> - <dt><label for="yim">{L_UCP_YIM}{L_COLON}</label></dt> - <dd><input type="text" name="yim" id="yim" maxlength="255" value="{YIM}" class="inputbox" /></dd> - </dl> - <dl> - <dt><label for="jabber">{L_UCP_JABBER}{L_COLON}</label></dt> - <dd><input type="email" name="jabber" id="jabber" maxlength="255" value="{JABBER}" class="inputbox" /></dd> - </dl> - <dl> - <dt><label for="website">{L_WEBSITE}{L_COLON}</label></dt> - <dd><input type="url" name="website" id="website" maxlength="255" value="{WEBSITE}" class="inputbox" /></dd> - </dl> - <dl> - <dt><label for="location">{L_LOCATION}{L_COLON}</label></dt> - <dd><input type="text" name="location" id="location" maxlength="255" value="{LOCATION}" class="inputbox" /></dd> - </dl> - <dl> - <dt><label for="occupation">{L_OCCUPATION}{L_COLON}</label></dt> - <dd><textarea name="occupation" id="occupation" class="inputbox" rows="3" cols="30">{OCCUPATION}</textarea></dd> - </dl> - <dl> - <dt><label for="interests">{L_INTERESTS}{L_COLON}</label></dt> - <dd><textarea name="interests" id="interests" class="inputbox" rows="3" cols="30">{INTERESTS}</textarea></dd> - </dl> <!-- IF S_BIRTHDAYS_ENABLED --> <dl> <dt><label for="bday_day">{L_BIRTHDAY}{L_COLON}</label><br /><span>{L_BIRTHDAY_EXPLAIN}</span></dt> <dd> - <label for="bday_day">{L_DAY}{L_COLON} <select name="bday_day" id="bday_day" style="width: 4em;">{S_BIRTHDAY_DAY_OPTIONS}</select></label> - <label for="bday_month">{L_MONTH}{L_COLON} <select name="bday_month" id="bday_month" style="width: 4em;">{S_BIRTHDAY_MONTH_OPTIONS}</select></label> - <label for="bday_year">{L_YEAR}{L_COLON} <select name="bday_year" id="bday_year" style="width: 6em;">{S_BIRTHDAY_YEAR_OPTIONS}</select></label> + <label for="bday_day">{L_DAY}{L_COLON} <select name="bday_day" id="bday_day">{S_BIRTHDAY_DAY_OPTIONS}</select></label> + <label for="bday_month">{L_MONTH}{L_COLON} <select name="bday_month" id="bday_month">{S_BIRTHDAY_MONTH_OPTIONS}</select></label> + <label for="bday_year">{L_YEAR}{L_COLON} <select name="bday_year" id="bday_year">{S_BIRTHDAY_YEAR_OPTIONS}</select></label> </dd> </dl> <!-- ENDIF --> + <dl> + <dt><label for="jabber">{L_UCP_JABBER}{L_COLON}</label></dt> + <dd><input type="email" name="jabber" id="jabber" maxlength="255" value="{JABBER}" class="inputbox" /></dd> + </dl> <!-- BEGIN profile_fields --> <dl> <dt><label<!-- IF profile_fields.FIELD_ID --> for="{profile_fields.FIELD_ID}"<!-- ENDIF -->>{profile_fields.LANG_NAME}{L_COLON}<!-- IF profile_fields.S_REQUIRED --> *<!-- ENDIF --></label> diff --git a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html index 699be4a27e..4b26bc2e99 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html +++ b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html @@ -7,7 +7,7 @@ <div class="inner"> <!-- IF S_FORCE_PASSWORD --> - <p>{L_FORCE_PASSWORD_EXPLAIN}</p> + <p class="error">{L_FORCE_PASSWORD_EXPLAIN}</p> <!-- ENDIF --> <fieldset> diff --git a/phpBB/styles/prosilver/template/ucp_profile_signature.html b/phpBB/styles/prosilver/template/ucp_profile_signature.html index 574f61ed9f..614f6f440d 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_signature.html +++ b/phpBB/styles/prosilver/template/ucp_profile_signature.html @@ -9,7 +9,7 @@ <div class="inner"> <h3>{L_SIGNATURE_PREVIEW}</h3> <div class="postbody"> - <div class="signature" style="border-top:none; margin-top: 0; ">{SIGNATURE_PREVIEW}</div> + <div class="signature standalone">{SIGNATURE_PREVIEW}</div> </div> </div> </div> diff --git a/phpBB/styles/prosilver/template/ucp_zebra_friends.html b/phpBB/styles/prosilver/template/ucp_zebra_friends.html index 583b911284..fac0a18706 100644 --- a/phpBB/styles/prosilver/template/ucp_zebra_friends.html +++ b/phpBB/styles/prosilver/template/ucp_zebra_friends.html @@ -11,6 +11,7 @@ <fieldset class="fields2"> <!-- IF ERROR --><p class="error">{ERROR}</p><!-- ENDIF --> + <!-- EVENT ucp_friend_list_before --> <dl> <dt><label <!-- IF S_USERNAME_OPTIONS -->for="usernames"<!-- ENDIF -->>{L_YOUR_FRIENDS}{L_COLON}</label><br /><span>{L_YOUR_FRIENDS_EXPLAIN}</span></dt> <dd> @@ -21,6 +22,7 @@ <!-- ENDIF --> </dd> </dl> + <!-- EVENT ucp_friend_list_after --> <dl> <dt><label for="add">{L_ADD_FRIENDS}{L_COLON}</label><br /><span>{L_ADD_FRIENDS_EXPLAIN}</span></dt> <dd><textarea name="add" id="add" rows="3" cols="30" class="inputbox">{USERNAMES}</textarea></dd> diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index ecd993d7fb..33d309bcb8 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -1,6 +1,6 @@ <!-- INCLUDE overall_header.html --> -<!-- IF U_MCP --><p>[ <a href="{U_MCP}">{L_MCP}</a> ]</p><!-- ENDIF --> -<h2><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2> +<!-- IF U_MCP or U_ACP --><p class="responsive-center">[ <!-- IF U_ACP --><a href="{U_ACP}" title="{L_ACP}" data-responsive-text="{L_ACP_SHORT}">{L_ACP}</a><!-- IF U_MCP --> | <!-- ENDIF --><!-- ENDIF --><!-- IF U_MCP --><a href="{U_MCP}" title="{L_MCP}" data-responsive-text="{L_MCP_SHORT}">{L_MCP}</a><!-- ENDIF --> ]</p><!-- ENDIF --> +<h2 class="forum-title"><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2> <!-- IF FORUM_DESC or MODERATORS or U_MCP --> <div> @@ -11,7 +11,7 @@ <!-- ENDIF --> <!-- IF S_FORUM_RULES --> - <div class="rules"> + <div class="rules<!-- IF U_FORUM_RULES --> rules-link<!-- ENDIF -->"> <div class="inner"> <!-- IF U_FORUM_RULES --> @@ -28,7 +28,7 @@ <!-- IF S_HAS_SUBFORUM --> <!-- IF not S_IS_BOT and U_MARK_FORUMS --> <ul class="linklist"> - <li class="rightside"><a href="{U_MARK_FORUMS}" data-ajax="mark_forums_read" data-overlay="false">{L_MARK_SUBFORUMS_READ}</a></li> + <li class="rightside mark-read"><a href="{U_MARK_FORUMS}" data-ajax="mark_forums_read">{L_MARK_SUBFORUMS_READ}</a></li> </ul> <!-- ENDIF --> <!-- INCLUDE forumlist_body.html --> @@ -55,17 +55,15 @@ </div> <!-- ENDIF --> - <!-- IF .pagination or TOTAL_POSTS or TOTAL_TOPICS --> - <div class="pagination"> - <!-- IF not S_IS_BOT and U_MARK_TOPICS --><a href="{U_MARK_TOPICS}" accesskey="m" data-ajax="mark_topics_read" data-overlay="false">{L_MARK_TOPICS_READ}</a> • <!-- ENDIF --> - <!-- IF TOTAL_TOPICS -->{TOTAL_TOPICS} • <!-- ENDIF --> - <!-- IF .pagination --> - <!-- INCLUDE pagination.html --> - <!-- ELSE --> - {PAGE_NUMBER} - <!-- ENDIF --> - </div> - <!-- ENDIF --> + <div class="pagination"> + <!-- IF not S_IS_BOT and U_MARK_TOPICS and .topicrow --><a href="{U_MARK_TOPICS}" accesskey="m" data-ajax="mark_topics_read">{L_MARK_TOPICS_READ}</a> • <!-- ENDIF --> + {TOTAL_TOPICS} • + <!-- IF .pagination --> + <!-- INCLUDE pagination.html --> + <!-- ELSE --> + {PAGE_NUMBER} + <!-- ENDIF --> + </div> </div> <!-- ENDIF --> @@ -143,9 +141,10 @@ <li class="row<!-- IF topicrow.S_ROW_COUNT is even --> bg1<!-- ELSE --> bg2<!-- ENDIF --><!-- IF topicrow.S_POST_GLOBAL --> global-announce<!-- ENDIF --><!-- IF topicrow.S_POST_ANNOUNCE --> announce<!-- ENDIF --><!-- IF topicrow.S_POST_STICKY --> sticky<!-- ENDIF --><!-- IF topicrow.S_TOPIC_REPORTED --> reported<!-- ENDIF -->"> <dl class="icon {topicrow.TOPIC_IMG_STYLE}"> <dt<!-- IF topicrow.TOPIC_ICON_IMG and S_TOPIC_ICONS --> style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{topicrow.TOPIC_FOLDER_IMG_ALT}"> + <!-- IF topicrow.S_UNREAD_TOPIC and not S_IS_BOT --><a href="{topicrow.U_NEWEST_POST}" class="icon-link"></a><!-- ENDIF --> <div class="list-inner"> <!-- EVENT topiclist_row_prepend --> - <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --><a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a> + <!-- IF topicrow.S_UNREAD_TOPIC and not S_IS_BOT --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF --><a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a> <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF --> <!-- IF topicrow.S_TOPIC_DELETED --><a href="{topicrow.U_MCP_QUEUE}">{DELETED_IMG}</a> <!-- ENDIF --> <!-- IF topicrow.S_TOPIC_REPORTED --><a href="{topicrow.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --><br /> @@ -163,15 +162,26 @@ </ul> </div> <!-- ENDIF --> - <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF -->{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} - <!-- IF topicrow.S_POST_GLOBAL and FORUM_ID != topicrow.FORUM_ID --> » {L_IN} <a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a><!-- ENDIF --> + <div class="responsive-hide"> + <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF --> + {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + <!-- IF topicrow.S_POST_GLOBAL and FORUM_ID != topicrow.FORUM_ID --> » {L_IN} <a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a><!-- ENDIF --> + </div> + <!-- IF not S_IS_BOT --> + <div class="responsive-show" style="display: none;"> + {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} « <a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{topicrow.LAST_POST_TIME}</a> + <!-- IF topicrow.S_POST_GLOBAL and FORUM_ID != topicrow.FORUM_ID --><br />{L_POSTED} {L_IN} <a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a><!-- ENDIF --> + <!-- IF topicrow.REPLIES --><br />{L_REPLIES}{L_COLON} <strong>{topicrow.REPLIES}</strong><!-- ENDIF --> + </div> + <!-- ENDIF --> + <!-- EVENT topiclist_row_append --> </div> </dt> <dd class="posts">{topicrow.REPLIES} <dfn>{L_REPLIES}</dfn></dd> <dd class="views">{topicrow.VIEWS} <dfn>{L_VIEWS}</dfn></dd> <dd class="lastpost"><span><dfn>{L_LAST_POST} </dfn>{L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} - <!-- IF not S_IS_BOT --><a href="{topicrow.U_LAST_POST}">{LAST_POST_IMG}</a> <!-- ENDIF --><br />{topicrow.LAST_POST_TIME}</span> + <!-- IF not S_IS_BOT --><a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{LAST_POST_IMG}</a> <!-- ENDIF --><br />{topicrow.LAST_POST_TIME}</span> </dd> </dl> </li> @@ -200,7 +210,8 @@ <!-- IF not S_IS_BOT --> <label>{L_DISPLAY_TOPICS}{L_COLON} {S_SELECT_SORT_DAYS}</label> <label>{L_SORT_BY} {S_SELECT_SORT_KEY}</label> - <label>{S_SELECT_SORT_DIR} <input type="submit" name="sort" value="{L_GO}" class="button2" /></label> + <label>{S_SELECT_SORT_DIR}</label> + <input type="submit" name="sort" value="{L_GO}" class="button2" /> <!-- ENDIF --> </fieldset> </form> @@ -215,31 +226,32 @@ </div> <!-- ENDIF --> - <!-- IF PAGE_NUMBER or TOTAL_POSTS or TOTAL_TOPICS --> <div class="pagination"> - <!-- IF TOTAL_TOPICS and not S_IS_BOT and U_MARK_TOPICS --><a href="{U_MARK_TOPICS}" data-ajax="mark_topics_read" data-overlay="false">{L_MARK_TOPICS_READ}</a> • <!-- ENDIF --> - <!-- IF TOTAL_POSTS and not NEWEST_USER --> {TOTAL_POSTS}<!-- ELSEIF TOTAL_TOPICS and not NEWEST_USER --> {TOTAL_TOPICS} • <!-- ENDIF --> - <!-- IF TOTAL_USERS -->{TOTAL_USERS} • <!-- ENDIF --> + <!-- IF not S_IS_BOT and U_MARK_TOPICS and .topicrow --><a href="{U_MARK_TOPICS}" data-ajax="mark_topics_read">{L_MARK_TOPICS_READ}</a> • <!-- ENDIF --> + {TOTAL_TOPICS} • <!-- IF .pagination --> <!-- INCLUDE pagination.html --> <!-- ELSE --> {PAGE_NUMBER} <!-- ENDIF --> </div> - <!-- ENDIF --> </div> <!-- ENDIF --> <!-- INCLUDE jumpbox.html --> <!-- IF S_DISPLAY_ONLINE_LIST --> - <h3><!-- IF U_VIEWONLINE --><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a><!-- ELSE -->{L_WHO_IS_ONLINE}<!-- ENDIF --></h3> - <p>{LOGGED_IN_USER_LIST}</p> + <div class="stat-block online-list"> + <h3><!-- IF U_VIEWONLINE --><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a><!-- ELSE -->{L_WHO_IS_ONLINE}<!-- ENDIF --></h3> + <p>{LOGGED_IN_USER_LIST}</p> + </div> <!-- ENDIF --> <!-- IF S_DISPLAY_POST_INFO --> - <h3>{L_FORUM_PERMISSIONS}</h3> - <p><!-- BEGIN rules -->{rules.RULE}<br /><!-- END rules --></p> + <div class="stat-block permissions"> + <h3>{L_FORUM_PERMISSIONS}</h3> + <p><!-- BEGIN rules -->{rules.RULE}<br /><!-- END rules --></p> + </div> <!-- ENDIF --> <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/styles/prosilver/template/viewonline_body.html b/phpBB/styles/prosilver/template/viewonline_body.html index 74e891f7d0..553e322f92 100644 --- a/phpBB/styles/prosilver/template/viewonline_body.html +++ b/phpBB/styles/prosilver/template/viewonline_body.html @@ -1,6 +1,6 @@ <!-- INCLUDE overall_header.html --> -<h2>{TOTAL_REGISTERED_USERS_ONLINE}</h2> +<h2 class="viewonline-title">{TOTAL_REGISTERED_USERS_ONLINE}</h2> <p>{TOTAL_GUEST_USERS_ONLINE}<!-- IF S_SWITCH_GUEST_DISPLAY --> • <a href="{U_SWITCH_GUEST_DISPLAY}">{L_SWITCH_GUEST_DISPLAY}</a><!-- ENDIF --></p> <ul class="linklist"> @@ -16,7 +16,7 @@ <div class="forumbg forumbg-table"> <div class="inner"> - <table class="table1" cellspacing="1"> + <table class="table1"> <!-- IF .user_row --> <thead> @@ -29,7 +29,7 @@ <tbody> <!-- BEGIN user_row --> <tr class="<!-- IF user_row.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF -->"> - <td>{user_row.USERNAME_FULL}<!-- IF user_row.USER_IP --> <span style="margin-left: 30px;">{L_IP}{L_COLON} <a href="{user_row.U_USER_IP}">{user_row.USER_IP}</a> » <a href="{user_row.U_WHOIS}" onclick="popup(this.href, 750, 500); return false;">{L_WHOIS}</a></span><!-- ENDIF --> + <td>{user_row.USERNAME_FULL}<!-- IF user_row.USER_IP --> <span style="float: {S_CONTENT_FLOW_END};">{L_IP}{L_COLON} <a href="{user_row.U_USER_IP}">{user_row.USER_IP}</a> » <a href="{user_row.U_WHOIS}" onclick="popup(this.href, 750, 500); return false;">{L_WHOIS}</a></span><!-- ENDIF --> <!-- IF user_row.USER_BROWSER --><br />{user_row.USER_BROWSER}<!-- ENDIF --></td> <td class="info"><a href="{user_row.U_FORUM_LOCATION}">{user_row.FORUM_LOCATION}</a></td> <td class="active">{user_row.LASTUPDATE}</td> diff --git a/phpBB/styles/prosilver/template/viewonline_whois.html b/phpBB/styles/prosilver/template/viewonline_whois.html index 8abd933efa..031f18afdc 100644 --- a/phpBB/styles/prosilver/template/viewonline_whois.html +++ b/phpBB/styles/prosilver/template/viewonline_whois.html @@ -1,6 +1,6 @@ <!-- INCLUDE simple_header.html --> -<h2>{L_WHOIS}</h2> +<h2 class="whois-title">{L_WHOIS}</h2> <div class="panel"> <div class="inner"> diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index e104257e12..01a49d6888 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -1,6 +1,6 @@ <!-- INCLUDE overall_header.html --> -<!-- IF U_MCP --><p>[ <a href="{U_MCP}">{L_MCP}</a> ]</p><!-- ENDIF --> -<h2><!-- EVENT viewtopic_topic_title_prepend --><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2> +<!-- IF U_MCP or U_ACP --><p class="responsive-center">[ <!-- IF U_ACP --><a href="{U_ACP}" title="{L_ACP}" data-responsive-text="{L_ACP_SHORT}">{L_ACP}</a><!-- IF U_MCP --> | <!-- ENDIF --><!-- ENDIF --><!-- IF U_MCP --><a href="{U_MCP}" title="{L_MCP}" data-responsive-text="{L_MCP_SHORT}">{L_MCP}</a><!-- ENDIF --> ]</p><!-- ENDIF --> +<h2 class="topic-title"><!-- EVENT viewtopic_topic_title_prepend --><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2> <!-- NOTE: remove the style="display: none" when you want to have the forum description on the topic body --> <!-- IF FORUM_DESC --><div style="display: none !important;">{FORUM_DESC}<br /></div><!-- ENDIF --> @@ -11,7 +11,7 @@ <!-- ENDIF --> <!-- IF S_FORUM_RULES --> - <div class="rules"> + <div class="rules<!-- IF U_FORUM_RULES --> rules-link<!-- ENDIF -->"> <div class="inner"> <!-- IF U_FORUM_RULES --> @@ -33,6 +33,8 @@ <!-- ENDIF --> </div> + <!-- INCLUDE viewtopic_topic_tools.html --> + <!-- IF S_DISPLAY_SEARCHBOX --> <div class="search-box"> <form method="get" id="topic-search" action="{S_SEARCHBOX_ACTION}"> @@ -55,51 +57,49 @@ <!-- ENDIF --> </div> <!-- ENDIF --> - + <div class="clear"></div> </div> -<div class="clear"></div> <!-- IF S_HAS_POLL --> - <form method="post" action="{S_POLL_ACTION}"> + <form method="post" action="{S_POLL_ACTION}" data-ajax="vote_poll" class="topic_poll"> <div class="panel"> <div class="inner"> <div class="content"> - <h2>{POLL_QUESTION}</h2> - <p class="author">{L_POLL_LENGTH}<!-- IF S_CAN_VOTE and L_POLL_LENGTH --><br /><!-- ENDIF --><!-- IF S_CAN_VOTE -->{L_MAX_VOTES}<!-- ENDIF --></p> + <h2 class="poll-title">{POLL_QUESTION}</h2> + <p class="author">{L_POLL_LENGTH}<!-- IF S_CAN_VOTE and L_POLL_LENGTH --><br /><!-- ENDIF --><!-- IF S_CAN_VOTE --><span class="poll_max_votes">{L_MAX_VOTES}</span><!-- ENDIF --></p> <fieldset class="polls"> <!-- BEGIN poll_option --> - <dl class="<!-- IF poll_option.POLL_OPTION_VOTED -->voted<!-- ENDIF -->"<!-- IF poll_option.POLL_OPTION_VOTED --> title="{L_POLL_VOTED_OPTION}"<!-- ENDIF -->> + <dl class="<!-- IF poll_option.POLL_OPTION_VOTED -->voted<!-- ENDIF --><!-- IF poll_option.POLL_OPTION_MOST_VOTES --> most-votes<!-- ENDIF -->"<!-- IF poll_option.POLL_OPTION_VOTED --> title="{L_POLL_VOTED_OPTION}"<!-- ENDIF --> data-poll-option-id="{poll_option.POLL_OPTION_ID}"> <dt><!-- IF S_CAN_VOTE --><label for="vote_{poll_option.POLL_OPTION_ID}">{poll_option.POLL_OPTION_CAPTION}</label><!-- ELSE -->{poll_option.POLL_OPTION_CAPTION}<!-- ENDIF --></dt> - <!-- IF S_CAN_VOTE --><dd style="width: auto;"><!-- IF S_IS_MULTI_CHOICE --><input type="checkbox" name="vote_id[]" id="vote_{poll_option.POLL_OPTION_ID}" value="{poll_option.POLL_OPTION_ID}"<!-- IF poll_option.POLL_OPTION_VOTED --> checked="checked"<!-- ENDIF --> /><!-- ELSE --><input type="radio" name="vote_id[]" id="vote_{poll_option.POLL_OPTION_ID}" value="{poll_option.POLL_OPTION_ID}"<!-- IF poll_option.POLL_OPTION_VOTED --> checked="checked"<!-- ENDIF --> /><!-- ENDIF --></dd><!-- ENDIF --> - <!-- IF S_DISPLAY_RESULTS --><dd class="resultbar"><div class="<!-- IF poll_option.POLL_OPTION_PCT < 20 -->pollbar1<!-- ELSEIF poll_option.POLL_OPTION_PCT < 40 -->pollbar2<!-- ELSEIF poll_option.POLL_OPTION_PCT < 60 -->pollbar3<!-- ELSEIF poll_option.POLL_OPTION_PCT < 80 -->pollbar4<!-- ELSE -->pollbar5<!-- ENDIF -->" style="width:{poll_option.POLL_OPTION_PERCENT};">{poll_option.POLL_OPTION_RESULT}</div></dd> - <dd><!-- IF poll_option.POLL_OPTION_RESULT == 0 -->{L_NO_VOTES}<!-- ELSE -->{poll_option.POLL_OPTION_PERCENT}<!-- ENDIF --></dd><!-- ENDIF --> + <!-- IF S_CAN_VOTE --><dd style="width: auto;" class="poll_option_select"><!-- IF S_IS_MULTI_CHOICE --><input type="checkbox" name="vote_id[]" id="vote_{poll_option.POLL_OPTION_ID}" value="{poll_option.POLL_OPTION_ID}"<!-- IF poll_option.POLL_OPTION_VOTED --> checked="checked"<!-- ENDIF --> /><!-- ELSE --><input type="radio" name="vote_id[]" id="vote_{poll_option.POLL_OPTION_ID}" value="{poll_option.POLL_OPTION_ID}"<!-- IF poll_option.POLL_OPTION_VOTED --> checked="checked"<!-- ENDIF --> /><!-- ENDIF --></dd><!-- ENDIF --> + <dd class="resultbar<!-- IF not S_DISPLAY_RESULTS --> hidden<!-- ENDIF -->"><div class="<!-- IF poll_option.POLL_OPTION_PCT < 20 -->pollbar1<!-- ELSEIF poll_option.POLL_OPTION_PCT < 40 -->pollbar2<!-- ELSEIF poll_option.POLL_OPTION_PCT < 60 -->pollbar3<!-- ELSEIF poll_option.POLL_OPTION_PCT < 80 -->pollbar4<!-- ELSE -->pollbar5<!-- ENDIF -->" style="width:{poll_option.POLL_OPTION_PERCENT_REL};">{poll_option.POLL_OPTION_RESULT}</div></dd> + <dd class="poll_option_percent<!-- IF not S_DISPLAY_RESULTS --> hidden<!-- ENDIF -->"><!-- IF poll_option.POLL_OPTION_RESULT == 0 -->{L_NO_VOTES}<!-- ELSE -->{poll_option.POLL_OPTION_PERCENT}<!-- ENDIF --></dd> </dl> <!-- END poll_option --> - <!-- IF S_DISPLAY_RESULTS --> - <dl> + <dl class="poll_total_votes<!-- IF not S_DISPLAY_RESULTS --> hidden<!-- ENDIF -->"> <dt> </dt> - <dd class="resultbar">{L_TOTAL_VOTES}{L_COLON} {TOTAL_VOTES}</dd> + <dd class="resultbar">{L_TOTAL_VOTES}{L_COLON} <span class="poll_total_vote_cnt">{TOTAL_VOTES}</span></dd> </dl> - <!-- ENDIF --> <!-- IF S_CAN_VOTE --> - <dl style="border-top: none;"> + <dl style="border-top: none;" class="poll_vote"> <dt> </dt> <dd class="resultbar"><input type="submit" name="update" value="{L_SUBMIT_VOTE}" class="button1" /></dd> </dl> <!-- ENDIF --> <!-- IF not S_DISPLAY_RESULTS --> - <dl style="border-top: none;"> + <dl style="border-top: none;" class="poll_view_results"> <dt> </dt> <dd class="resultbar"><a href="{U_VIEW_RESULTS}">{L_VIEW_RESULTS}</a></dd> </dl> <!-- ENDIF --> </fieldset> + <div class="vote-submitted hidden">{L_VOTE_SUBMITTED}</div> </div> </div> @@ -107,16 +107,65 @@ {S_HIDDEN_FIELDS} </div> - </form> <hr /> <!-- ENDIF --> <!-- BEGIN postrow --> + <!-- EVENT viewtopic_body_postrow_post_before --> <!-- IF postrow.S_FIRST_UNREAD --><a id="unread"></a><!-- ENDIF --> <div id="p{postrow.POST_ID}" class="post <!-- IF postrow.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF postrow.S_UNREAD_POST --> unreadpost<!-- ENDIF --><!-- IF postrow.S_POST_REPORTED --> reported<!-- ENDIF --><!-- IF postrow.S_POST_DELETED --> deleted<!-- ENDIF --><!-- IF postrow.S_ONLINE and not postrow.S_POST_HIDDEN --> online<!-- ENDIF -->"> <div class="inner"> + <dl class="postprofile" id="profile{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->> + <dt class="<!-- IF postrow.RANK_TITLE or postrow.RANK_IMG -->has-profile-rank<!-- ELSE -->no-profile-rank<!-- ENDIF -->"> + <!-- IF postrow.POSTER_AVATAR --> + <!-- IF postrow.U_POST_AUTHOR --><a href="{postrow.U_POST_AUTHOR}" class="avatar">{postrow.POSTER_AVATAR}</a><!-- ELSE --><span class="avatar">{postrow.POSTER_AVATAR}</span><!-- ENDIF --> + <!-- ENDIF --> + <!-- IF not postrow.U_POST_AUTHOR --><strong>{postrow.POST_AUTHOR_FULL}</strong><!-- ELSE -->{postrow.POST_AUTHOR_FULL}<!-- ENDIF --> + </dt> + + <!-- IF postrow.RANK_TITLE or postrow.RANK_IMG --><dd class="profile-rank">{postrow.RANK_TITLE}<!-- IF postrow.RANK_TITLE and postrow.RANK_IMG --><br /><!-- ENDIF -->{postrow.RANK_IMG}</dd><!-- ENDIF --> + + <!-- IF postrow.POSTER_POSTS != '' --><dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> {postrow.POSTER_POSTS}</dd><!-- ENDIF --> + <!-- IF postrow.POSTER_JOINED --><dd class="profile-joined"><strong>{L_JOINED}{L_COLON}</strong> {postrow.POSTER_JOINED}</dd><!-- ENDIF --> + + <!-- IF postrow.S_PROFILE_FIELD1 --> + <!-- Use a construct like this to include admin defined profile fields. Replace FIELD1 with the name of your field. --> + <dd><strong>{postrow.PROFILE_FIELD1_NAME}{L_COLON}</strong> {postrow.PROFILE_FIELD1_VALUE}</dd> + <!-- ENDIF --> + + <!-- EVENT viewtopic_body_postrow_custom_fields_before --> + <!-- BEGIN custom_fields --> + <!-- IF not postrow.custom_fields.S_PROFILE_CONTACT --> + <dd class="profile-custom-field profile-{postrow.custom_fields.PROFILE_FIELD_IDENT}"><strong>{postrow.custom_fields.PROFILE_FIELD_NAME}{L_COLON}</strong> {postrow.custom_fields.PROFILE_FIELD_VALUE}</dd> + <!-- ENDIF --> + <!-- END custom_fields --> + <!-- EVENT viewtopic_body_postrow_custom_fields_after --> + + <!-- IF not S_IS_BOT --> + <!-- IF postrow.U_PM or postrow.U_EMAIL or postrow.U_JABBER --> + <dd class="profile-contact"> + <ul class="profile-icons"> + <!-- IF postrow.U_PM --><li class="pm-icon"><a href="{postrow.U_PM}" title="{L_PRIVATE_MESSAGE}"><span>{L_PRIVATE_MESSAGE}</span></a></li><!-- ENDIF --> + <!-- IF postrow.U_EMAIL --><li class="email-icon"><a href="{postrow.U_EMAIL}" title="{L_SEND_EMAIL_USER} {postrow.POST_AUTHOR}"><span>{L_SEND_EMAIL_USER} {postrow.POST_AUTHOR}</span></a></li><!-- ENDIF --> + <!-- IF postrow.U_JABBER --><li class="jabber-icon"><a href="{postrow.U_JABBER}" onclick="popup(this.href, 550, 320); return false;" title="{L_JABBER}"><span>{L_JABBER}</span></a></li><!-- ENDIF --> + <!-- BEGIN custom_fields --> + <!-- IF postrow.custom_fields.S_PROFILE_CONTACT --> + <li class="{postrow.custom_fields.PROFILE_FIELD_IDENT}-icon"> + <a href="<!-- IF postrow.custom_fields.PROFILE_FIELD_CONTACT -->{postrow.custom_fields.PROFILE_FIELD_CONTACT}<!-- ELSE -->{postrow.U_POST_AUTHOR}<!-- ENDIF -->"> + <span>{postrow.custom_fields.PROFILE_FIELD_NAME}</span> + </a> + </li> + <!-- ENDIF --> + <!-- END custom_fields --> + </ul> + </dd> + <!-- ENDIF --> + <!-- ENDIF --> + + </dl> + <div class="postbody"> <!-- IF postrow.S_POST_HIDDEN --> <!-- IF postrow.S_POST_DELETED --> @@ -133,6 +182,8 @@ <!-- ENDIF --> <div id="post_content{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->> + <h3 <!-- IF postrow.S_FIRST_ROW -->class="first"<!-- ENDIF -->><!-- IF postrow.POST_ICON_IMG --><img src="{T_ICONS_PATH}{postrow.POST_ICON_IMG}" width="{postrow.POST_ICON_IMG_WIDTH}" height="{postrow.POST_ICON_IMG_HEIGHT}" alt="" /> <!-- ENDIF --><a href="#p{postrow.POST_ID}">{postrow.POST_SUBJECT}</a></h3> + <!-- IF not S_IS_BOT --> <!-- IF postrow.U_EDIT or postrow.U_DELETE or postrow.U_REPORT or postrow.U_WARN or postrow.U_INFO or postrow.U_QUOTE --> <ul class="profile-icons"> @@ -148,8 +199,7 @@ <!-- ENDIF --> <!-- ENDIF --> - <h3 <!-- IF postrow.S_FIRST_ROW -->class="first"<!-- ENDIF -->><!-- IF postrow.POST_ICON_IMG --><img src="{T_ICONS_PATH}{postrow.POST_ICON_IMG}" width="{postrow.POST_ICON_IMG_WIDTH}" height="{postrow.POST_ICON_IMG_HEIGHT}" alt="" /> <!-- ENDIF --><a href="#p{postrow.POST_ID}">{postrow.POST_SUBJECT}</a></h3> - <p class="author"><!-- IF S_IS_BOT -->{postrow.MINI_POST_IMG}<!-- ELSE --><a href="{postrow.U_MINI_POST}">{postrow.MINI_POST_IMG}</a><!-- ENDIF -->{L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong> » {postrow.POST_DATE} </p> + <p class="author"><!-- IF S_IS_BOT -->{postrow.MINI_POST_IMG}<!-- ELSE --><a href="{postrow.U_MINI_POST}">{postrow.MINI_POST_IMG}</a><!-- ENDIF --><span class="responsive-hide">{L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong> » </span>{postrow.POST_DATE} </p> <!-- IF postrow.S_POST_UNAPPROVED --> <form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}"> @@ -202,6 +252,7 @@ </dl> <!-- ENDIF --> + <!-- EVENT viewtopic_body_postrow_post_notices_before --> <!-- IF postrow.S_DISPLAY_NOTICE --><div class="rules">{L_DOWNLOAD_NOTICE}</div><!-- ENDIF --> <!-- IF postrow.DELETED_MESSAGE or postrow.DELETE_REASON --> <div class="notice post_deleted_msg"> @@ -216,63 +267,19 @@ <!-- ENDIF --> <!-- IF postrow.BUMPED_MESSAGE --><div class="notice"><br /><br />{postrow.BUMPED_MESSAGE}</div><!-- ENDIF --> + <!-- EVENT viewtopic_body_postrow_post_notices_after --> <!-- IF postrow.SIGNATURE --><div id="sig{postrow.POST_ID}" class="signature">{postrow.SIGNATURE}</div><!-- ENDIF --> </div> </div> - <dl class="postprofile" id="profile{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->> - <dt> - <!-- IF postrow.POSTER_AVATAR --> - <!-- IF postrow.U_POST_AUTHOR --><a href="{postrow.U_POST_AUTHOR}">{postrow.POSTER_AVATAR}</a><!-- ELSE -->{postrow.POSTER_AVATAR}<!-- ENDIF --><br /> - <!-- ENDIF --> - <!-- IF not postrow.U_POST_AUTHOR --><strong>{postrow.POST_AUTHOR_FULL}</strong><!-- ELSE -->{postrow.POST_AUTHOR_FULL}<!-- ENDIF --> - </dt> - - <!-- IF postrow.RANK_TITLE or postrow.RANK_IMG --><dd>{postrow.RANK_TITLE}<!-- IF postrow.RANK_TITLE and postrow.RANK_IMG --><br /><!-- ENDIF -->{postrow.RANK_IMG}</dd><!-- ENDIF --> - - <dd> </dd> - - <!-- IF postrow.POSTER_POSTS != '' --><dd><strong>{L_POSTS}{L_COLON}</strong> {postrow.POSTER_POSTS}</dd><!-- ENDIF --> - <!-- IF postrow.POSTER_JOINED --><dd><strong>{L_JOINED}{L_COLON}</strong> {postrow.POSTER_JOINED}</dd><!-- ENDIF --> - <!-- IF postrow.POSTER_FROM --><dd><strong>{L_LOCATION}{L_COLON}</strong> {postrow.POSTER_FROM}</dd><!-- ENDIF --> - - <!-- IF postrow.S_PROFILE_FIELD1 --> - <!-- Use a construct like this to include admin defined profile fields. Replace FIELD1 with the name of your field. --> - <dd><strong>{postrow.PROFILE_FIELD1_NAME}{L_COLON}</strong> {postrow.PROFILE_FIELD1_VALUE}</dd> - <!-- ENDIF --> - - <!-- EVENT viewtopic_body_postrow_custom_fields_before --> - <!-- BEGIN custom_fields --> - <dd><strong>{postrow.custom_fields.PROFILE_FIELD_NAME}{L_COLON}</strong> {postrow.custom_fields.PROFILE_FIELD_VALUE}</dd> - <!-- END custom_fields --> - <!-- EVENT viewtopic_body_postrow_custom_fields_after --> - - <!-- IF not S_IS_BOT --> - <!-- IF postrow.U_PM or postrow.U_EMAIL or postrow.U_WWW or postrow.U_MSN or postrow.U_ICQ or postrow.U_YIM or postrow.U_AIM or postrow.U_JABBER --> - <dd> - <ul class="profile-icons"> - <!-- IF postrow.U_PM --><li class="pm-icon"><a href="{postrow.U_PM}" title="{L_PRIVATE_MESSAGE}"><span>{L_PRIVATE_MESSAGE}</span></a></li><!-- ENDIF --> - <!-- IF postrow.U_EMAIL --><li class="email-icon"><a href="{postrow.U_EMAIL}" title="{L_SEND_EMAIL_USER} {postrow.POST_AUTHOR}"><span>{L_SEND_EMAIL_USER} {postrow.POST_AUTHOR}</span></a></li><!-- ENDIF --> - <!-- IF postrow.U_WWW --><li class="web-icon"><a href="{postrow.U_WWW}" title="{L_VISIT_WEBSITE}{L_COLON} {postrow.U_WWW}"><span>{L_WEBSITE}</span></a></li><!-- ENDIF --> - <!-- IF postrow.U_MSN --><li class="msnm-icon"><a href="{postrow.U_MSN}" onclick="popup(this.href, 550, 320); return false;" title="{L_MSNM}"><span>{L_MSNM}</span></a></li><!-- ENDIF --> - <!-- IF postrow.U_ICQ --><li class="icq-icon"><a href="{postrow.U_ICQ}" onclick="popup(this.href, 550, 320); return false;" title="{L_ICQ}"><span>{L_ICQ}</span></a></li><!-- ENDIF --> - <!-- IF postrow.U_YIM --><li class="yahoo-icon"><a href="{postrow.U_YIM}" onclick="popup(this.href, 780, 550); return false;" title="{L_YIM}"><span>{L_YIM}</span></a></li><!-- ENDIF --> - <!-- IF postrow.U_AIM --><li class="aim-icon"><a href="{postrow.U_AIM}" onclick="popup(this.href, 550, 320); return false;" title="{L_AIM}"><span>{L_AIM}</span></a></li><!-- ENDIF --> - <!-- IF postrow.U_JABBER --><li class="jabber-icon"><a href="{postrow.U_JABBER}" onclick="popup(this.href, 550, 320); return false;" title="{L_JABBER}"><span>{L_JABBER}</span></a></li><!-- ENDIF --> - </ul> - </dd> - <!-- ENDIF --> - <!-- ENDIF --> - - </dl> - <div class="back2top"><a href="#wrap" class="top" title="{L_BACK_TO_TOP}">{L_BACK_TO_TOP}</a></div> </div> </div> <hr class="divider" /> + <!-- EVENT viewtopic_body_postrow_post_after --> <!-- END postrow --> <!-- IF S_QUICK_REPLY --> <!-- INCLUDE quickreply_editor.html --> @@ -285,7 +292,8 @@ <!-- IF U_NEXT_PAGE --><a href="{U_NEXT_PAGE}" class="right-box arrow-{S_CONTENT_FLOW_END}">{L_NEXT}</a><!-- ENDIF --> <!-- IF not S_IS_BOT --> <label>{L_DISPLAY_POSTS}{L_COLON} {S_SELECT_SORT_DAYS}</label> - <label>{L_SORT_BY} {S_SELECT_SORT_KEY}</label> <label>{S_SELECT_SORT_DIR} <input type="submit" name="sort" value="{L_GO}" class="button2" /></label> + <label>{L_SORT_BY} {S_SELECT_SORT_KEY}</label> <label>{S_SELECT_SORT_DIR}</label> + <input type="submit" name="sort" value="{L_GO}" class="button2" /> <!-- ENDIF --> </fieldset> @@ -293,6 +301,7 @@ <hr /> <!-- ENDIF --> +<!-- EVENT viewtopic_body_topic_actions_before --> <div class="topic-actions"> <div class="buttons"> <!-- IF not S_IS_BOT and S_DISPLAY_REPLY_INFO --> @@ -300,16 +309,7 @@ <!-- ENDIF --> </div> - <!-- IF S_HAS_ATTACHMENTS --> - <div class="dl_links"> - <strong>{L_DOWNLOAD_ALL_ATTACHMENTS}{L_COLON}</strong> - <ul> - <!-- BEGIN dl_method --> - <li>[ <a href="{dl_method.LINK}">{dl_method.TYPE}</a> ]</li> - <!-- END dl_method --> - </ul> - </div> - <!-- ENDIF --> + <!-- INCLUDE viewtopic_topic_tools.html --> <!-- IF .pagination or TOTAL_POSTS --> <div class="pagination"> @@ -321,6 +321,7 @@ <!-- ENDIF --> </div> <!-- ENDIF --> + <div class="clear"></div> </div> <!-- EVENT viewtopic_body_footer_before --> @@ -342,8 +343,10 @@ <!-- ENDIF --> <!-- IF S_DISPLAY_ONLINE_LIST --> - <h3><!-- IF U_VIEWONLINE --><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a><!-- ELSE -->{L_WHO_IS_ONLINE}<!-- ENDIF --></h3> - <p>{LOGGED_IN_USER_LIST}</p> + <div class="stat-block online-list"> + <h3><!-- IF U_VIEWONLINE --><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a><!-- ELSE -->{L_WHO_IS_ONLINE}<!-- ENDIF --></h3> + <p>{LOGGED_IN_USER_LIST}</p> + </div> <!-- ENDIF --> <!-- INCLUDE overall_footer.html --> diff --git a/phpBB/styles/prosilver/template/viewtopic_print.html b/phpBB/styles/prosilver/template/viewtopic_print.html index fd0b2dc3e6..6c4dcfadf1 100644 --- a/phpBB/styles/prosilver/template/viewtopic_print.html +++ b/phpBB/styles/prosilver/template/viewtopic_print.html @@ -2,8 +2,6 @@ <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> <meta charset="utf-8"> -<meta name="keywords" content="" /> -<meta name="description" content="" /> <meta name="robots" content="noindex" /> {META} <title>{SITENAME} • {PAGE_TITLE}</title> @@ -28,7 +26,7 @@ <!-- BEGIN postrow --> <div class="post"> <h3>{postrow.POST_SUBJECT}</h3> - <div class="date">{postrow.MINI_POST_IMG}{L_POSTED}{L_COLON} <strong>{postrow.POST_DATE}</strong></div> + <div class="date">{L_POSTED}{L_COLON} <strong>{postrow.POST_DATE}</strong></div> <div class="author">{L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR}</strong></div> <div class="content">{postrow.MESSAGE}</div> </div> diff --git a/phpBB/styles/prosilver/template/viewtopic_topic_tools.html b/phpBB/styles/prosilver/template/viewtopic_topic_tools.html new file mode 100644 index 0000000000..89f34d1b3a --- /dev/null +++ b/phpBB/styles/prosilver/template/viewtopic_topic_tools.html @@ -0,0 +1,41 @@ +<!-- IF not S_IS_BOT and (U_WATCH_TOPIC or U_BOOKMARK_TOPIC or U_BUMP_TOPIC or S_HAS_ATTACHMENTS or U_EMAIL_TOPIC or U_PRINT_TOPIC or S_DISPLAY_TOPIC_TOOLS) --> + <div class="dropdown-container dropdown-button-control topic-tools"> + <span title="{L_TOPIC_TOOLS}" class="dropdown-trigger dropdown-select dropdown-select-icon tools-icon"><span></span></span> + <div class="dropdown hidden"> + <div class="pointer"><div class="pointer-inner"></div></div> + <ul class="dropdown-contents"> + <!-- EVENT viewtopic_topic_tools_before --> + <!-- IF U_WATCH_TOPIC --> + <li class="small-icon icon-<!-- IF S_WATCHING_TOPIC -->unsubscribe<!-- ELSE -->subscribe<!-- ENDIF -->"> + <a href="{U_WATCH_TOPIC}" class="watch-topic-link" title="{S_WATCH_TOPIC_TITLE}" data-ajax="toggle_link" data-toggle-class="small-icon icon-<!-- IF not S_WATCHING_TOPIC -->unsubscribe<!-- ELSE -->subscribe<!-- ENDIF -->" data-toggle-text="{S_WATCH_TOPIC_TOGGLE}" data-toggle-url="{U_WATCH_TOPIC_TOGGLE}" data-update-all=".watch-topic-link"> + {S_WATCH_TOPIC_TITLE} + </a> + </li> + <!-- ENDIF --> + <!-- IF U_BOOKMARK_TOPIC --> + <li class="small-icon icon-bookmark"> + <a href="{U_BOOKMARK_TOPIC}" class="bookmark-link" title="{L_BOOKMARK_TOPIC}" data-ajax="alt_text" data-alt-text="{S_BOOKMARK_TOGGLE}" data-update-all=".bookmark-link"> + {S_BOOKMARK_TOPIC} + </a> + </li> + <!-- ENDIF --> + <!-- IF U_BUMP_TOPIC --><li class="small-icon icon-bump"><a href="{U_BUMP_TOPIC}" title="{L_BUMP_TOPIC}" data-ajax="true">{L_BUMP_TOPIC}</a></li><!-- ENDIF --> + <!-- IF U_EMAIL_TOPIC --><li class="small-icon icon-sendemail"><a href="{U_EMAIL_TOPIC}" title="{L_EMAIL_TOPIC}">{L_EMAIL_TOPIC}</a></li><!-- ENDIF --> + <!-- IF U_PRINT_TOPIC --><li class="small-icon icon-print"><a href="{U_PRINT_TOPIC}" title="{L_PRINT_TOPIC}" accesskey="p">{L_PRINT_TOPIC}</a></li><!-- ENDIF --> + <!-- IF S_HAS_ATTACHMENTS --> + <li class="small-icon icon-download"> + <a class="dropdown-toggle-submenu" href="{U_DOWNLOAD_ALL_ATTACHMENTS}" title="{L_DOWNLOAD_ALL_ATTACHMENTS}">{L_DOWNLOAD_ALL_ATTACHMENTS}</a> + <ul class="dropdown-submenu hidden"> + <li> + <!-- BEGIN dl_method --> + <a href="{dl_method.LINK}">{dl_method.TYPE}</a><!-- IF not dl_method.S_LAST_ROW --> • <!-- ENDIF --> + <!-- END dl_method --> + </li> + </ul> + </li> + <!-- ENDIF --> + <!-- EVENT viewtopic_topic_tools_after --> + </ul> + </div> + </div> +<!-- ENDIF --> diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css index 41a9874a18..0d5e1cf829 100644 --- a/phpBB/styles/prosilver/theme/bidi.css +++ b/phpBB/styles/prosilver/theme/bidi.css @@ -90,6 +90,28 @@ text-align: left; } +/* Bulletin icons for list items +----------------------------------------*/ +.rtl ul.linklist.bulletin li:before { + padding-left: 4px; + padding-right: 0; +} + +/* Dropdown menu +---------------------------------------- */ +.rtl .dropdown-container.topic-tools { + float: right; +} + +.rtl .dropdown li { + text-align: right; +} + +.rtl .dropdown li li { + padding-left: 0; + padding-right: 10px; +} + /* Table styles ----------------------------------------*/ .rtl table.table1 thead th { @@ -183,8 +205,9 @@ /* Pagination in viewforum for multipage topics */ .rtl .row .pagination { + background-position: 100% 50%; float: left; - padding: 1px 0 1px 15px; + padding: 1px 15px 1px 0; } .rtl .pagination span { @@ -231,6 +254,11 @@ unicode-bidi: embed; } +ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a { + padding-left: 0; + padding-right: 19px; +} + .rtl a.top { float: left; } @@ -258,16 +286,6 @@ /** * content.css */ -.rtl ul.topiclist dfn { - /* Labels for post/view counts */ - position: relative; - width: 1px; - height: 1px; - overflow: hidden; - display: block; - left: 0; -} - .rtl ul.topiclist dt, .rtl li.header dt { float: right; margin-right: 0; @@ -337,8 +355,8 @@ } .rtl li.header dd { - margin-left: 0; - margin-right: 1px; + padding-left: 0; + padding-right: 1px; } .rtl dl.icon { @@ -360,6 +378,18 @@ padding-right: 45px; /* Space for folder icon */ } +.rtl dl.icon dt { /* fix for topic row icon links */ + position: relative; +} + +.rtl dl a.icon-link { /* topic row icon links */ + display: inline-block; + left: auto; + right: 0; + margin-left: 0; + margin-right: 2px; +} + .rtl dd.lastpost span, .rtl ul.topiclist dd.info span, .rtl ul.topiclist dd.time span, .rtl dd.redirect span, .rtl dd.moderation span { padding-left: 0; padding-right: 5px; @@ -367,15 +397,18 @@ /* Post body styles ----------------------------------------*/ -.rtl .postbody { +.rtl .postbody, .rtl .postbody h3 { float: right; } +.rtl p.post-notice { + padding-left: 5px; + padding-right: 26px; +} + .rtl p.post-notice:before { left: auto; right: 0; - padding-left: 5px; - padding-right: 26px; } /* Topic review panel @@ -392,11 +425,6 @@ margin-left: 0; } -/* Post author */ -.rtl p.author { - margin: 0 0 0.6em 15em; -} - .rtl .signature { clear: right; } @@ -484,9 +512,7 @@ /* Poster profile block ----------------------------------------*/ .rtl .postprofile { - border-left: none; - border-right-width: 1px; - border-right-style: solid; + border-width: 0 1px 0 0; float: left; /* text-align: right; */ } @@ -526,18 +552,15 @@ margin: 0 1px 0 5px; } -/* Sub-header (navigation bar) ---------------------------------------------- */ -.rtl a.print, .rtl a.sendemail { - text-align: right; -} - /* Icon images ---------------------------------------- */ -.rtl .sitehome, .rtl .icon-faq, .rtl .icon-members, .rtl .icon-home, .rtl .icon-ucp, .rtl .icon-register, .rtl .icon-logout, -.rtl .icon-bookmark, .rtl .icon-bump, .rtl .icon-subscribe, .rtl .icon-unsubscribe, .rtl .icon-pages, .rtl .icon-search { +.rtl .small-icon { background-position: 100% 50%; - padding: 1px 17px 0 0; + padding: 0 19px 0 0; +} + +.rtl ul.linklist li.small-icon { + padding-right: 0; } /* Poster profile icons @@ -584,6 +607,10 @@ margin-left: 0; } +.tabs-container h2 { + float: right; +} + /* CP tabbed menu ----------------------------------------*/ .rtl #tabs { @@ -601,7 +628,12 @@ /* Mini tabbed menu used in MCP ----------------------------------------*/ .rtl #minitabs { - margin: -20px 0 0 7px; + margin-right: 0; + margin-left: 7px; +} + +.rtl .tabs-container #minitabs { + float: left; } .rtl #minitabs li { @@ -696,7 +728,7 @@ } .rtl fieldset.fields1 dd { - margin-right: 10em; + margin-right: 15em; margin-left: 0; border-right-width: 0; border-left-width: 1px; @@ -823,7 +855,7 @@ padding-right: 11px; padding-left: 0; } -.rtl .imageset.icon_contact_aim, .rtl .imageset.icon_contact_email, .rtl .imageset.icon_contact_icq, .rtl .imageset.icon_contact_jabber, .rtl .imageset.icon_contact_msnm, .rtl .imageset.icon_contact_www, .rtl .imageset.icon_contact_yahoo, .rtl .imageset.icon_post_delete, .rtl .imageset.icon_post_info, .rtl .imageset.icon_post_report, .rtl .imageset.icon_user_warn { +.rtl .imageset.icon_contact_aim, .rtl .imageset.phpbb_aol-icon, .rtl .imageset.icon_contact_email, .rtl .imageset.icon_contact_icq, .rtl .imageset.phpbb_icq-icon, .rtl .imageset.icon_contact_jabber, .rtl .imageset.icon_contact_msnm, .rtl .imageset.phpbb_wlm-icon, .rtl .imageset.icon_contact_www, .rtl .imageset.phpbb_website-icon, .rtl .imageset.icon_contact_yahoo, .rtl .imageset.phpbb_yahoo-icon, .rtl .imageset.icon_post_delete, .rtl .imageset.icon_post_info, .rtl .imageset.icon_post_report, .rtl .imageset.icon_user_warn { padding-right: 20px; padding-left: 0; } diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index 9336dd09f8..3422af8b64 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -11,13 +11,13 @@ } /* Rollover state */ -.buttons div { +.buttons div, .dropdown-select { float: left; margin: 0 5px 0 0; } /* Rolloff state */ -.buttons div a { +.buttons div a, .dropdown-select { display: inline-block; line-height: 17.5px; height: 18px; @@ -27,7 +27,8 @@ border-radius: 4px; background: transparent none 0 0 repeat-x; padding: 2px 22px 2px 8px; - font-family: Verdana, Arial, Helvetica; + font-family: "Open Sans", "Droid Sans", Verdana, Arial, Helvetica; + font-weight: 600; position: relative; text-decoration: none !important; outline-style: none !important; @@ -37,7 +38,7 @@ .buttons div span { display: none; } -.buttons div a:after { +.buttons div a:after, .dropdown-select:after { content: ''; display: block; position: absolute; @@ -53,6 +54,35 @@ background-position: 0 -20px; } +.dropdown-select { + cursor: pointer; + font-family: inherit; + font-size: 1em; + font-weight: normal; +} + +.dropdown-select:after { + background-position: -103px 10px; + border-left: 1px solid; + margin-top: 0; + top: 0; + right: 0; + height: 21px; + width: 15px; +} + +.dropdown-visible .dropdown-select:after, .nojs .dropdown-container:hover .dropdown-select:after { + background-position: -103px -10px; +} + +.dropdown-select-icon:before { + content: ''; + display: block; + float: left; + margin-right: 4px; + margin-top: 2px; +} + /* Big button images */ .buttons div.reply-icon a:after, .buttons div.pmreply-icon a:after { background-position: -20px 0; } .buttons div.reply-icon a:hover:after, .buttons div.pmreply-icon a:hover:after { background-position: -20px -20px; } @@ -66,39 +96,25 @@ .buttons div.forwardpm-icon a:after { background-position: -40px 0; } .buttons div.forwardpm-icon a:hover:after { background-position: -40px -20px; } -/* Sub-header (navigation bar) ---------------------------------------------- */ -a.print, a.sendemail { - display: block; - overflow: hidden; - height: 18px; - text-indent: -5000px; - text-align: left; - background-repeat: no-repeat; -} - -a.print { - background-image: none; - width: 22px; -} +.dropdown-select.tools-icon:before { background-position: -80px 0; height: 16px; width: 16px; } -a.sendemail { - background-image: none; - width: 22px; -} +.dropdown-visible .dropdown-select.tools-icon:before, +.nojs .dropdown-container:hover .dropdown-select.tools-icon:before { background-position: -80px -20px; } /* Icon images ---------------------------------------- */ -.sitehome, .icon-faq, .icon-members, .icon-home, .icon-ucp, .icon-register, .icon-logout, -.icon-bookmark, .icon-bump, .icon-subscribe, .icon-unsubscribe, .icon-pages, .icon-search { +.small-icon { background-position: 0 50%; background-repeat: no-repeat; background-image: none; - padding: 1px 0 0 17px; + padding: 0 0 0 17px; +} + +ul.linklist li.small-icon { + padding-left: 0; } -ul.linklist.bulletin li.icon-home:before, ul.linklist.bulletin li.icon-ucp:before, -ul.linklist.bulletin li.icon-bookmark:before, ul.linklist.bulletin li.icon-bump:before, ul.linklist.bulletin li.icon-subscribe:before, ul.linklist.bulletin li.icon-unsubscribe:before { +ul.linklist.bulletin li.small-icon:before { display: none; } @@ -139,13 +155,77 @@ ul.profile-icons li a:hover { background: none; } margin: 0 3px; } +/* Responsive icons in postbody */ +.postbody ul.profile-icons.responsive .responsive-menu { + position: relative; +} + +ul.profile-icons.responsive a.responsive-menu-link { + display: inline-block; + position: relative; + margin: 0 5px; + width: 20px; + height: 20px; + text-decoration: none; + background: none top left no-repeat; +} + +ul.profile-icons.responsive a.responsive-menu-link:hover { + background-position: 0 -20px; +} + +ul.profile-icons.responsive a.responsive-menu-link:before { + content: ''; + position: absolute; + left: 0; + top: 7px; + height: .125em; + width: 14px; + border-bottom: 0.125em solid transparent; + border-top: 0.375em double transparent; +} + +.postbody ul.profile-icons.responsive .popup-pointer { + left: auto; + right: 7px; + top: 20px; +} + +.postbody ul.profile-icons .dropdown li, .postbody ul.profile-icons .dropdown li a { + display: block; + background: transparent none; + width: auto; + height: auto; + margin: 0; + padding: 0; + float: none; + list-style-type: none; +} + +.postbody ul.profile-icons .dropdown li span { + display: block; + text-align: right; + font-size: 1.2em; + line-height: 1.8em; + white-space: nowrap; +} + +.hasjs .postbody ul.profile-icons { + max-width: 40%; +} + /* Profile & navigation icons */ .email-icon, .email-icon a { background: none top left no-repeat; } .aim-icon, .aim-icon a { background: none top left no-repeat; } +.phpbb_aol-icon, .phpbb_aol-icon a { background: none top left no-repeat; } .yahoo-icon, .yahoo-icon a { background: none top left no-repeat; } +.phpbb_yahoo-icon, .phpbb_yahoo-icon a { background: none top left no-repeat; } .web-icon, .web-icon a { background: none top left no-repeat; } +.phpbb_website-icon, .phpbb_website-icon a { background: none top left no-repeat; } .msnm-icon, .msnm-icon a { background: none top left no-repeat; } +.phpbb_wlm-icon, .phpbb_wlm-icon a { background: none top left no-repeat; } .icq-icon, .icq-icon a { background: none top left no-repeat; } +.phpbb_icq-icon, .phpbb_icq-icon a { background: none top left no-repeat; } .jabber-icon, .jabber-icon a { background: none top left no-repeat; } .pm-icon, .pm-icon a { background: none top left no-repeat; } .quote-icon, .quote-icon a { background: none top left no-repeat; } @@ -159,11 +239,16 @@ ul.profile-icons li a:hover { background: none; } /* Set profile icon dimensions */ ul.profile-icons li.email-icon { width: 20px; height: 20px; } +ul.profile-icons li.phpbb_aol-icon { width: 20px; height: 20px; } ul.profile-icons li.aim-icon { width: 20px; height: 20px; } ul.profile-icons li.yahoo-icon { width: 20px; height: 20px; } +ul.profile-icons li.phpbb_yahoo-icon { width: 20px; height: 20px; } ul.profile-icons li.web-icon { width: 20px; height: 20px; } +ul.profile-icons li.phpbb_website-icon { width: 20px; height: 20px; } ul.profile-icons li.msnm-icon { width: 20px; height: 20px; } +ul.profile-icons li.phpbb_wlm-icon { width: 20px; height: 20px; } ul.profile-icons li.icq-icon { width: 20px; height: 20px; } +ul.profile-icons li.phpbb_icq-icon { width: 20px; height: 20px; } ul.profile-icons li.jabber-icon { width: 20px; height: 20px; } ul.profile-icons li.pm-icon { width: 28px; height: 20px; } ul.profile-icons li.quote-icon { width: 54px; height: 20px; } @@ -172,6 +257,7 @@ ul.profile-icons li.edit-icon { width: 42px; height: 20px; } ul.profile-icons li.delete-icon { width: 20px; height: 20px; } ul.profile-icons li.info-icon { width: 20px; height: 20px; } ul.profile-icons li.warn-icon { width: 20px; height: 20px; } +ul.profile-icons a.responsive-menu-link { width: 20px; height: 20px; } /* Fix profile icon default margins */ ul.profile-icons li.edit-icon { margin: 0 0 0 3px; } diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index 9e3d29bec2..30650e7411 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -76,8 +76,22 @@ hr { color: #000000; } -.bg1 { background-color: #ECF3F7; } -.bg2 { background-color: #e1ebf2; } +.bg1 { + background-color: #ECF3F7; +} + +table.zebra-list tr:nth-child(odd) td, ul.zebra-list li:nth-child(odd) { + background-color: #ECF3F7; +} + +.bg2 { + background-color: #e1ebf2; +} + +table.zebra-list tr:nth-child(even) td, ul.zebra-list li:nth-child(even) { + background-color: #e1ebf2; +} + .bg3 { background-color: #cadceb; } .ucprowbg { @@ -231,7 +245,6 @@ p.post-notice.reported:before, p.post-notice.error:before { background-image: url("./images/icon_topic_reported.gif"); } - /* -------------------------------------------------------------- Colours and backgrounds for links.css @@ -259,6 +272,11 @@ a:active { color: #368AD2; } color: #C8E6FF; } +/* Notification mark read link */ +.dropdown-extended a.mark_read { + background-color: #FFFFFF; +} + /* Links for forum/topic lists */ a.forumtitle { color: #105289; @@ -627,21 +645,11 @@ fieldset.polls dd div { ----------------------------------------*/ .postprofile { color: #666666; - border-left-color: #FFFFFF; -} - -.rtl .postprofile { - border-right-color: #FFFFFF; - border-left-color: transparent; + border-color: #FFFFFF; } .pm .postprofile { - border-left-color: #DDDDDD; -} - -.rtl .pm .postprofile { - border-right-color: #DDDDDD; - border-left-color: transparent; + border-color: #DDDDDD; } .postprofile strong { @@ -657,15 +665,7 @@ fieldset.polls dd div { Colours and backgrounds for buttons.css -------------------------------------------------------------- */ -a.print { - background-image: url("./images/icon_print.gif"); -} - -a.sendemail { - background-image: url("./images/icon_sendemail.gif"); -} - -.buttons div a { +.buttons div a, .dropdown-select { border-color: #C7C3BF; background-color: #FFFFFF; background-image: -moz-linear-gradient(top, #FFFFFF, #E9E9E9); @@ -678,7 +678,16 @@ a.sendemail { color: #BC2A4D !important; } -.buttons div a:hover { +.dropdown-select { + color: #5C6482 !important; +} + +.dropdown-select:after { + border-color: #DADADA; +} + +.buttons div a:hover, .dropdown-select:hover, .dropdown-visible .dropdown-select, +.dropdown-visible .dropdown-select:hover, .nojs .dropdown-container:hover .dropdown-select { border-color: #0a8ed0; background-image: -moz-linear-gradient(top, #E9E9E9, #FFFFFF); background-image: -webkit-linear-gradient(top, #E9E9E9, #FFFFFF); @@ -688,13 +697,21 @@ a.sendemail { text-shadow: 1px 1px 0 #FFFFFF, -1px -1px 0 #FFFFFF, -1px -1px 0 rgba(188, 42, 77, 0.2); } -.buttons div a:after { +.dropdown-select:hover { + border-color: #C7C3BF; +} + +.dropdown-visible .dropdown-select, .dropdown-visible .dropdown-select:hover, .nojs .dropdown-container:hover .dropdown-select { + border-color: #A6B2BA; + color: #105289 !important; +} + +.buttons div a:after, .dropdown-select-icon:before, .dropdown-select:after { background-image: url("images/buttons.png"); } /* Icon images ---------------------------------------- */ -.sitehome { background-image: url("./images/icon_home.gif"); } .icon-faq { background-image: url("./images/icon_faq.gif"); } .icon-members { background-image: url("./images/icon_members.gif"); } .icon-home { background-image: url("./images/icon_home.gif"); } @@ -706,18 +723,30 @@ a.sendemail { .icon-subscribe { background-image: url("./images/icon_subscribe.gif"); } .icon-unsubscribe { background-image: url("./images/icon_unsubscribe.gif"); } .icon-pages { background-image: url("./images/icon_pages.gif"); } -.icon-search { background-image: url("./images/icon_search.gif"); } +.icon-search, .responsive-search a { background-image: url("./images/icon_search.gif"); } +.icon-notification { background-image: url("./images/icon_notification.gif"); } +.icon-pm { background-image: url("./images/icon_pm.gif"); } +.icon-download { background-image: url("./images/icon_download.gif"); } +.icon-mark { background-image: url("./images/icon_mark.gif"); } +.icon-sendemail { background-image: url("./images/icon_sendemail.gif"); } +.icon-print { background-image: url("./images/icon_print.gif"); } /* Profile & navigation icons */ .email-icon, .email-icon a { background-image: url("./images/icon_contact_email.gif"); } +.phpbb_aol-icon, .phpbb_aol-icon a { background-image: url("./images/icon_contact_aim.gif"); } .aim-icon, .aim-icon a { background-image: url("./images/icon_contact_aim.gif"); } .yahoo-icon, .yahoo-icon a { background-image: url("./images/icon_contact_yahoo.gif"); } +.phpbb_yahoo-icon, .phpbb_yahoo-icon a { background-image: url("./images/icon_contact_yahoo.gif"); } .web-icon, .web-icon a { background-image: url("./images/icon_contact_www.gif"); } +.phpbb_website-icon, .phpbb_website-icon a { background-image: url("./images/icon_contact_www.gif"); } .msnm-icon, .msnm-icon a { background-image: url("./images/icon_contact_msnm.gif"); } +.phpbb_wlm-icon, .phpbb_wlm-icon a { background-image: url("./images/icon_contact_msnm.gif"); } .icq-icon, .icq-icon a { background-image: url("./images/icon_contact_icq.gif"); } +.phpbb_icq-icon, .phpbb_icq-icon a { background-image: url("./images/icon_contact_icq.gif"); } .jabber-icon, .jabber-icon a { background-image: url("./images/icon_contact_jabber.gif"); } .pm-icon, .pm-icon a { background-image: url("./en/icon_contact_pm.gif"); } .quote-icon, .quote-icon a { background-image: url("./en/icon_post_quote.gif"); } +ul.profile-icons.responsive a.responsive-menu-link { background-image: url("./images/icon_post_menu.png"); } /* Moderator icons */ .report-icon, .report-icon a { background-image: url("./images/icon_post_report.gif"); } @@ -787,11 +816,11 @@ Colours and backgrounds for cp.css /* Main CP box ----------------------------------------*/ -#cp-main h3, #cp-main hr, #cp-menu hr { +.panel-container h3, .panel-container hr, #cp-menu hr { border-color: #A4B3BF; } -#cp-main .panel li.row { +.panel-container .panel li.row { border-bottom-color: #B5C1CB; border-top-color: #F9F9F9; } @@ -800,11 +829,11 @@ ul.cplist { border-top-color: #B5C1CB; } -#cp-main .panel li.header dd, #cp-main .panel li.header dt { +.panel-container .panel li.header dd, .panel-container .panel li.header dt { color: #000000; } -#cp-main table.table1 thead th { +.panel-container table.table1 thead th { color: #333333; border-bottom-color: #333333; } @@ -851,10 +880,20 @@ ul.cplist { background-color: #F9F9F9; } -#minitabs li.activetab a, #minitabs li.activetab a:hover { +#minitabs li.activetab a span, #minitabs li.activetab a:hover span { color: #333333; } +/* Responsive tabs +----------------------------------------*/ +.responsive-tab .responsive-tab-link span:before { + border-color: #536482; +} + +.responsive-tab .responsive-tab-link:hover span:before { + border-color: #BC2A4D; +} + /* UCP navigation menu ----------------------------------------*/ @@ -886,13 +925,20 @@ ul.cplist { color: #D31141; } +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) +{ + #navigation a, .rtl #navigation a { + background-image: none; + } +} + /* Preferences pane layout ----------------------------------------*/ -#cp-main h2 { +.panel-container h2 { color: #333333; } -#cp-main .panel { +.panel-container .panel { background-color: #F9F9F9; } @@ -1067,6 +1113,12 @@ a.button1:hover, input.button1:hover, a.button2:hover, input.button2:hover, inpu color: #BC2A4D; } +/* Focus states */ +input.button1:focus, input.button2:focus, input.button3:focus { + border-color: #11A3EA; + color: #0F4987; +} + input.search { background-image: url("./images/icon_textbox_search.gif"); } @@ -1088,26 +1140,32 @@ input.disabled { background-color: #000000; } -#notification_list { - background-color: #FFFFFF; - border-color: #B9B9B9; +#loading_indicator { + background-color: #000000; + background-image: url("./images/loading.gif"); } -#notification_list ul li { +.dropdown-extended ul li { border-bottom-color: #B9B9B9; } -#notification_list ul li:hover { +.dropdown-extended ul li:hover { background-color: #CFE1F6; color: #000000; } -#notification_list > .header, .notification_list > .footer { +.dropdown-extended .header, .dropdown-extended .footer { border-color: #B9B9B9; color: #000000; } -#notification_list > .header { +.dropdown-extended .footer { + padding: 5px 0; + border-top-style: solid; + border-top-width: 1px; +} + +.dropdown-extended .header { background: #F1F8FF; background: -moz-linear-gradient(top, #F1F8FF 0%, #CADCEB 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F1F8FF), color-stop(100%, #CADCEB)); @@ -1117,11 +1175,40 @@ input.disabled { background: linear-gradient(to bottom, #F1F8FF 0%, #CADCEB 100%); } -.notification_list .pointer { - border-bottom-color: #B9B9B9; +.dropdown .pointer { + border-color: #B9B9B9 transparent; +} + +.dropdown .pointer-inner { + border-color: #FFF transparent; +} + +.dropdown-extended .pointer-inner, #minitabs .pointer-inner { + border-color: #F1F8FF transparent; +} + +ul.linklist li.responsive-menu a.responsive-menu-link:before { + border-color: #105289; } -.notification_list .pointer_inner { - border-bottom-color: #F1F8FF; +ul.linklist li.responsive-menu a.responsive-menu-link:hover:before, ul.linklist li.responsive-menu.visible a.responsive-menu-link:before { + border-color: #D31141; } +.dropdown .dropdown-contents { + background: #fff; + border-color: #b9b9b9; + box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.2); +} + +.dropdown-up .dropdown-contents { + box-shadow: 1px 0 5px rgba(0, 0, 0, 0.2); +} + +.dropdown li, .dropdown li li { + border-color: #DCDCDC; +} + +#minitabs .dropdown-contents { + background-color: #F1F8FF; +} diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 9021c157a3..3d5a0a433d 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -60,6 +60,7 @@ body { line-height: normal; margin: 0; padding: 12px 0; + word-wrap: break-word; } h1 { @@ -179,7 +180,7 @@ ol ol ul, ol ul ul, ul ol ul, ul ul ul { } #simple-wrap { - padding: 6px 10px; + padding: 6px 0; } #page-body { @@ -330,6 +331,7 @@ ul.linklist li { margin-right: 5px; font-size: 1.1em; line-height: 2.2em; + padding-top: 1px; } ul.linklist li.rightside, p.rightside { @@ -360,6 +362,66 @@ ul.rightside { text-align: right; } +ul.linklist li.responsive-menu { + position: relative; + margin: 0 5px; +} + +ul.linklist li.responsive-menu a.responsive-menu-link { + display: inline-block; + margin: 0 5px; + font-size: 16px; + position: relative; + width: 16px; + line-height: 16.5px; + text-decoration: none; +} + +ul.linklist li.responsive-menu a.responsive-menu-link:before { + content: ''; + position: absolute; + left: 0; + top: 7px; + height: .125em; + width: 14px; + border-bottom: 0.125em solid transparent; + border-top: 0.375em double transparent; +} + +.hasjs ul.linklist.leftside, .hasjs ul.linklist.rightside { + max-width: 48%; +} + +.hasjs ul.linklist.fullwidth { + max-width: none; +} + +li.responsive-menu.dropdown-right .dropdown { + left: -9px; +} + +li.responsive-menu.dropdown-left .dropdown { + right: -6px; +} + +li.responsive-menu .dropdown .dropdown-contents { + padding: 0 5px; +} + +ul.linklist .dropdown-down .dropdown { + top: 22px; +} + +ul.linklist .dropdown-up .dropdown { + bottom: 18px; +} + +ul.linklist .dropdown li { + clear: both; +} + + + /* Bulletin icons for list items ----------------------------------------*/ ul.linklist.bulletin li:before { @@ -371,27 +433,202 @@ ul.linklist.bulletin li:before { } ul.linklist.bulletin li:first-child:before, ul.linklist.bulletin li.rightside:last-child:before { - display: none; + content: none; } ul.linklist.bulletin li.no-bulletin:before { - display: none; + content: none; } -.icon-notification:before, ul.linklist.bulletin li.icon-notification:before, .icon-notification:after { - display: inline; - font: inherit; +.responsive-menu:before { + display: none !important; } -.icon-notification:before, ul.linklist.bulletin li.icon-notification:before { - content: '['; - padding-right: 0; +/* Avatar in overall_header.html */ +.header-avatar img { + margin-bottom: 2px; + max-height: 25px; + vertical-align: middle; + width: auto; } -.icon-notification:after { - content: ']'; +/* Dropdown menu +----------------------------------------*/ +.dropdown-container { + position: relative; } +.nojs .dropdown-container:hover .dropdown { + display: block !important; +} + +.dropdown { + position: absolute; + left: 0; + top: 1.2em; + z-index: 2; + border: 1px solid transparent; + border-radius: 5px; + padding: 9px 0 0; +} + +.dropdown-container.topic-tools { + float: left; +} + +.dropdown-up .dropdown { + top: auto; + bottom: 1.2em; + padding: 0 0 9px; +} + +.dropdown-left .dropdown, .nojs .rightside .dropdown { + left: auto; + right: 0; +} + +.dropdown-button-control .dropdown { + top: 24px; +} + +.dropdown-button-control.dropdown-up .dropdown { + top: auto; + bottom: 24px; +} + +.dropdown .pointer, .dropdown .pointer-inner { + position: absolute; + width: 0; + height: 0; + border-top-width: 0; + border-bottom: 10px solid transparent; + border-left: 10px dashed transparent; + border-right: 10px dashed transparent; + -webkit-transform: rotate(360deg); /* better anti-aliasing in webkit */ + display: block; +} + +.dropdown-up .pointer, .dropdown-up .pointer-inner { + border-bottom-width: 0; + border-top: 10px solid transparent; +} + +.dropdown .pointer { + right: auto; + left: 10px; + top: 0; + z-index: 3; +} + +.dropdown-up .pointer { + bottom: 0; + top: auto; +} + +.dropdown-left .dropdown .pointer, .nojs .rightside .dropdown .pointer { + left: auto; + right: 10px; +} + +.dropdown .pointer-inner { + top: auto; + bottom: -11px; + left: -10px; +} + +.dropdown-up .pointer-inner { + bottom: auto; + top: -11px; +} + +.dropdown .dropdown-contents { + z-index: 2; + overflow: hidden; + overflow-y: auto; + border: 1px solid transparent; + border-radius: 5px; + padding: 5px; + position: relative; + min-width: 40px; + max-height: 200px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.dropdown li { + border-bottom: 1px dotted transparent; + float: none !important; + line-height: normal !important; + font-size: 1em !important; + list-style: none; + margin: 0; + padding-top: 4px; + padding-bottom: 4px; + white-space: nowrap; + text-align: left; +} + +.dropdown li:last-child, .dropdown li li { + border-bottom: 0; +} + +.dropdown li li:first-child { + margin-top: 4px; +} + +.dropdown li li:last-child { + padding-bottom: 0; +} + +.dropdown li li { + border-top: 1px dotted transparent; + padding-left: 10px; +} + +.wrap .dropdown li, .dropdown.wrap li, .dropdown-extended li { + white-space: normal; +} + +.dropdown li:before, .dropdown li:after { + display: none !important; +} + +/* Responsive breadcrumbs +----------------------------------------*/ +.breadcrumbs .crumb { + float: left; + word-wrap: normal; +} + +.breadcrumbs .crumb:before { + content: '‹'; + font-weight: bold; + padding: 0 0.5em; +} + +.breadcrumbs .crumb:first-child:before { + content: none; +} + +.breadcrumbs .crumb a { + display: inline-block; + white-space: nowrap; + text-overflow: ellipsis; + vertical-align: bottom; + overflow: hidden; +} + +.breadcrumbs.wrapped .crumb a { letter-spacing: -.3px; } +.breadcrumbs.wrapped .crumb.wrapped-medium a { letter-spacing: -.4px; } +.breadcrumbs.wrapped .crumb.wrapped-tiny a { letter-spacing: -.5px; } + +.breadcrumbs .crumb.wrapped-max a { max-width: 120px; } +.breadcrumbs .crumb.wrapped-wide a { max-width: 100px; } +.breadcrumbs .crumb.wrapped-medium a { max-width: 80px; } +.breadcrumbs .crumb.wrapped-small a { max-width: 60px; } +.breadcrumbs .crumb.wrapped-tiny a { max-width: 40px; } + /* Table styles ----------------------------------------*/ table.table1 { @@ -435,7 +672,7 @@ table.table1 tbody th { /* Specific column styles */ table.table1 .name { text-align: left; } -table.table1 .posts { text-align: center !important; width: 7%; } +table.table1 .posts { text-align: center; width: 7%; } table.table1 .joined { text-align: left; width: 15%; } table.table1 .active { text-align: left; width: 15%; } table.table1 .mark { text-align: center; width: 7%; } @@ -468,6 +705,11 @@ table.info tbody th { margin: 0 -1px; } +#color_palette_placeholder table { + border-collapse: separate; + border-spacing: 1px; +} + /* Misc layout styles ---------------------------------------- */ /* column[1-2] styles are containers for two column layouts @@ -491,6 +733,10 @@ table.info tbody th { text-align: left; } +.left-box.profile-details { + width: 80%; +} + .right-box { float: right; width: auto; @@ -520,16 +766,39 @@ dl.details dd { text-overflow: ellipsis; } -.clearfix, #tabs, #minitabs, fieldset dl, ul.topiclist dl, dl.polls { - height: 1%; +.clearfix, fieldset dl, ul.topiclist dl, dl.polls { overflow: hidden; } +fieldset.fields1 ul.recipients { + list-style-type: none; + line-height: 1.8; + max-height: 150px; + overflow-y: auto; +} + +fieldset.fields1 dd.recipients { + clear: left; + margin-left: 1em; +} + +fieldset.fields1 ul.recipients input.button2{ + font-size: 0.8em; + margin-right: 0; + padding: 0; +} + +fieldset.fields1 dl.pmlist > dt { + width: auto !important; +} + +fieldset.fields1 dl.pmlist dd.recipients { + margin-left: 0 !important; +} /* Pagination ---------------------------------------- */ .pagination { - height: 1%; /* IE tweak (holly hack) */ width: auto; text-align: right; margin-top: 5px; @@ -564,7 +833,7 @@ li.pagination ul { line-height: normal; } -.pagination li a, .pagnation li span, li .pagination li a, li .pagnation li span, .pagination li.active span, .pagination li.ellipsis span { +.pagination li a, .pagnation li span, li .pagination li a, li .pagination li span, .pagination li.active span, .pagination li.ellipsis span { font-weight: normal; text-decoration: none; padding: 0 2px; @@ -588,14 +857,22 @@ li.pagination ul { ---------------------------------------- */ .phpbb_alert { border: 1px solid transparent; - position: fixed; display: none; + left: 0; + padding: 0 25px 20px 25px; + position: fixed; + right: 0; top: 150px; - left: 25%; - width: 50%; z-index: 50; - padding: 25px; - padding: 0 25px 20px 25px; + width: 620px; + margin: 0 auto; +} + +@media only screen and (max-height: 500px), only screen and (max-device-width: 500px) +{ + .phpbb_alert { + top: 25px; + } } .phpbb_alert .alert_close { @@ -634,6 +911,8 @@ li.pagination ul { #darkenwrapper { display: none; + position: relative; + z-index: 44; } #darken { @@ -643,6 +922,22 @@ li.pagination ul { width: 100%; height: 100%; opacity: 0.5; + z-index: 45; +} + +#loading_indicator { + background: center center no-repeat; + border-radius: 5px; + display: none; + opacity: 0.8; + margin-top: -50px; + margin-left: -50px; + height: 50px; + width: 50px; + position: fixed; + left: 50%; + top: 50%; + z-index: 51; } /* Miscellaneous styles @@ -738,26 +1033,23 @@ form > p.post-notice strong { position: relative; } -#notification_list { +.dropdown-extended { display: none; position: absolute; left: 0; width: 330px; z-index: 1; - border: 1px solid; - box-shadow: 3px 3px 5px darkgray; - border-radius: 5px; - top: 32px; + top: 22px; } -#notification_list ul { +.dropdown-extended ul { max-height: 350px; overflow-y: auto; overflow-x: hidden; clear: both; } -#notification_list ul li { +.dropdown-extended ul li { padding: 10px; margin: 0; float: none; @@ -765,13 +1057,19 @@ form > p.post-notice strong { list-style-type: none; font-size: 0.95em; clear: both; + position: relative; } -#notification_list ul li:before, #notification_list ul li:after { +.dropdown-extended ul li:before, .dropdown-extended ul li:after { display: none; } -#notification_list > .header { +.dropdown-extended .dropdown-contents { + max-height: none; + padding: 0; +} + +.dropdown-extended .header { padding: 0 10px; font-family: Arial, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 11px; @@ -783,59 +1081,33 @@ form > p.post-notice strong { border-radius: 5px 5px 0 0; } -#notification_list > .header > .header_settings { +.dropdown-extended .header .header_settings { float: right; font-weight: normal; text-transform: none; } -#notification_list > .footer { +.dropdown-extended .footer { text-align: center; - font-size: 1.2em; + font-size: 1.1em; } -#notification_list ul li a, .notification_list dt > a, #notification_list > .footer > a { +.dropdown-extended ul li a, .notification_list dt > a, .dropdown-extended .footer > a { display: block; + text-decoration: none; } .notification_list ul li img { float: left; - max-width: 50px; max-height: 50px; + width: auto !important; + height: auto !important; margin-right: 5px; } .notification_list ul li p { margin: 0; - word-wrap: break-word; -} - -.notification_list ul.topiclist dt { - width: 88%; -} - -.notification_list .pointer, .notification_list .pointer_inner { - position: absolute; - width: 0; - height: 0; - border-top-width: 0; - border-bottom: 10px solid; - border-left: 10px dashed transparent; - border-right: 10px dashed transparent; - -webkit-transform: rotate(360deg); /* better anti-aliasing in webkit */ - display: block; -} - -.notification_list .pointer { - right: auto; - left: 10px; - top: -11px; -} - -.notification_list .pointer_inner { - top: auto; - bottom: -11px; - left: -10px; + font-size: 1em; } .notification_list div.notifications { @@ -843,10 +1115,25 @@ form > p.post-notice strong { } .notification_list p.notifications_title { + font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; + font-size: 13px !important; font-weight: bold; } .notification_list p.notifications_time { - font-size: 11px; + font-size: 11px !important; } +.notification_text:after { + content: ''; + clear: both; + display: block; +} + +.compact .icon-notification > a > span, .compact .icon-pm > a > span { + display: none; +} + +.compact .icon-notification > a > strong, .compact .icon-pm > a > strong { + padding-left: 2px; +} diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index c56c7f9ef8..d27fb81fee 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -162,6 +162,18 @@ dl.icon dt, dl.icon dd { min-height: 35px; } +dl a.icon-link { /* topic row icon links */ + display: block; + width: 30px; + height: 30px; + padding: 0; + position: absolute; + top: 50%; + left: 0; + margin-top: -15px; + margin-left: 9px; +} + dd.posts, dd.topics, dd.views, dd.extra, dd.mark { width: 80px; text-align: center; @@ -228,7 +240,6 @@ div[class].topic-actions { line-height: 1.48em; width: 76%; float: left; - clear: both; } .postbody .ignore { @@ -242,6 +253,7 @@ div[class].topic-actions { .postbody h3 { /* Postbody requires a different h3 format - so change it here */ + float: left; font-size: 1.5em; padding: 2px 0 0 0; margin: 0 0 0.3em 0 !important; @@ -258,6 +270,11 @@ div[class].topic-actions { .postbody .content { font-size: 1.3em; + overflow-x: auto; +} + +.postbody img.postimage { + max-width: 99%; } .search .postbody { @@ -297,21 +314,16 @@ div[class].topic-actions { /* MCP Post details ----------------------------------------*/ -#post_details -{ +#post_details { /* This will only work in IE7+, plus the others */ overflow: auto; max-height: 300px; } -#expand -{ - clear: both; -} - /* Content container styles ----------------------------------------*/ .content { + clear: both; min-height: 3em; overflow: hidden; line-height: 1.4em; @@ -382,11 +394,12 @@ dl.faq dt { /* Post author */ p.author { - margin: 0 15em 0.6em 0; + margin-bottom: 0.6em; padding: 0 0 5px 0; font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 1em; line-height: 1.2em; + clear: both; } /* Post signature */ @@ -401,6 +414,11 @@ p.author { width: 100%; } +.signature.standalone { + border-top-width: 0; + margin-top: 0; +} + dd .signature { margin: 0; padding: 0; @@ -509,10 +527,14 @@ blockquote .codebox { .attachbox { float: left; width: auto; + max-width: 100%; margin: 5px 5px 5px 0; padding: 6px; border: 1px dashed transparent; clear: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } .attachbox dt { @@ -525,6 +547,7 @@ blockquote .codebox { padding-top: 4px; clear: left; border-top: 1px solid transparent; + overflow-x: auto; } .attachbox dd dd { @@ -546,9 +569,7 @@ blockquote .codebox { .attach-image { margin: 3px 0; - width: 100%; - max-height: 350px; - overflow: auto; + max-width: 100%; } .attach-image img { @@ -654,7 +675,7 @@ fieldset.polls dd div { font-weight: bold; padding: 0 2px; overflow: visible; - min-width: 2%; + min-width: 8px; } .pollbar1, .pollbar2, .pollbar3, .pollbar4, .pollbar5 { @@ -662,13 +683,20 @@ fieldset.polls dd div { border-right: 1px solid transparent; } +.vote-submitted { + font-size: 1.2em; + font-weight: bold; + text-align: center; +} + /* Poster profile block ----------------------------------------*/ .postprofile { /* Also see tweaks.css */ margin: 5px 0 10px 0; min-height: 80px; - border-left: 1px solid transparent; + border: 1px solid transparent; + border-width: 0 0 0 1px; width: 22%; float: right; display: inline; @@ -688,11 +716,21 @@ fieldset.polls dd div { font-weight: normal; } -.avatar { +.postprofile dt.no-profile-rank, .postprofile dd.profile-rank, .postprofile .search-result-date { + margin-bottom: 10px; +} + +.postprofile .avatar { + display: block; border: none; margin-bottom: 3px; } +.postprofile .avatar img { + max-width: 90%; + height: auto !important; +} + .online { background-image: none; background-position: 100% 0; @@ -740,3 +778,18 @@ div.dl_links { .dl_links li { display: inline-block; } + +/* Show scrollbars for items with overflow on iOS devices +----------------------------------------*/ +.postbody .content::-webkit-scrollbar, #topicreview::-webkit-scrollbar, #post_details::-webkit-scrollbar, .codebox code::-webkit-scrollbar, .attachbox dd::-webkit-scrollbar, .attach-image::-webkit-scrollbar, .dropdown-extended ul::-webkit-scrollbar { + width: 8px; + height: 8px; + -webkit-appearance: none; + background: rgba(0, 0, 0, .1); + border-radius: 3px; +} + +.postbody .content::-webkit-scrollbar-thumb, #topicreview::-webkit-scrollbar-thumb, #post_details::-webkit-scrollbar-thumb, .codebox code::-webkit-scrollbar-thumb, .attachbox dd::-webkit-scrollbar-thumb, .attach-image::-webkit-scrollbar-thumb, .dropdown-extended ul::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, .3); + border-radius: 3px; +} diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css index e32ff8fcb8..61df82c0ce 100644 --- a/phpBB/styles/prosilver/theme/cp.css +++ b/phpBB/styles/prosilver/theme/cp.css @@ -20,16 +20,16 @@ padding: 0; } -#cp-main .panel p { +.panel-container .panel p { font-size: 1.1em; } -#cp-main .panel ol { +.panel-container .panel ol { margin-left: 2em; font-size: 1.1em; } -#cp-main .panel li.row { +.panel-container .panel li.row { border-bottom: 1px solid transparent; border-top: 1px solid transparent; } @@ -39,21 +39,21 @@ ul.cplist { border-top: 1px solid transparent; } -#cp-main .panel li.header dd, #cp-main .panel li.header dt { +.panel-container .panel li.header dd, .panel-container .panel li.header dt { margin-bottom: 2px; } -#cp-main table.table1 { +.panel-container table.table1 { margin-bottom: 1em; } -#cp-main table.table1 thead th { +.panel-container table.table1 thead th { font-weight: bold; border-bottom: 1px solid transparent; padding: 5px; } -#cp-main table.table1 tbody th { +.panel-container table.table1 tbody th { font-style: italic; background-color: transparent !important; border-bottom: none; @@ -102,11 +102,6 @@ ul.cplist { margin-bottom: 0px; } -.tabs-container #minitabs { - float: right; - margin-top: 19px; -} - .tabs-container:after { display: block; clear: both; @@ -118,7 +113,7 @@ ul.cplist { #tabs { line-height: normal; margin: 20px 0 -1px 7px; - min-width: 570px; + *overflow: hidden; } #tabs ul { @@ -127,6 +122,12 @@ ul.cplist { list-style: none; } +#tabs ul:after { + content: ''; + display: block; + clear: both; +} + #tabs li { display: inline; margin: 0; @@ -186,6 +187,12 @@ ul.cplist { margin: -20px 7px 0 0; } +.tabs-container #minitabs { + float: right; + margin-top: 19px; + max-width: 50%; +} + #minitabs ul { margin:0; padding: 0; @@ -210,6 +217,95 @@ ul.cplist { text-decoration: none; } +/* Responsive tabs +----------------------------------------*/ +.responsive-tab { + position: relative; +} + +.responsive-tab .responsive-tab-link span { + display: inline-block; + font-size: 16px; + position: relative; + width: 16px; + line-height: 14px; + text-decoration: none; +} + +#minitabs .responsive-tab .responsive-tab-link span { + display: block; +} + +.responsive-tab .responsive-tab-link span:before { + content: ''; + position: absolute; + left: 5px; + top: 8px; + height: .125em; + width: 14px; + border-bottom: 0.125em solid transparent; + border-top: 0.375em double transparent; +} + +#minitabs .responsive-tab .responsive-tab-link span:before { + left: 0; + top: 2px; +} + +#tabs ul, #minitabs ul { + position: relative; +} + +#tabs .dropdown, #minitabs .dropdown { + top: 29px; + margin-right: -1px; +} + +#minitabs .dropdown { + top: 18px; +} + +#tabs .dropdown-up .dropdown, #minitabs .dropdown-up .dropdown { + bottom: -5px; + top: auto; +} + +#minitabs .dropdown-up .dropdown { + bottom: 18px; +} + +#tabs .dropdown-right .dropdown, #minitabs .dropdown-right .dropdown { + margin-left: -41px; +} + +#tabs .dropdown li, #minitabs .dropdown li { + display: block !important; + background: transparent none; + padding: 0; +} + +.tabs-container #minitabs .dropdown a span { + display: block; +} + +#tabs .dropdown a, #tabs .dropdown a span, #minitabs .dropdown a, #minitabs .dropdown a span { + background: transparent; + float: none; + margin: 0; + padding: 0; + text-align: right; +} + +.tabs-container #minitabs .dropdown a span { + text-align: left; +} + +#tabs .dropdown a span, #minitabs .dropdown a span { + padding: 5px 8px; + color: inherit !important; +} + + /* UCP navigation menu ----------------------------------------*/ /* Container for sub-navigation list */ @@ -261,6 +357,8 @@ ul.cplist { /* Friends list */ .cp-mini { margin: 10px 15px 10px 5px; + max-height: 200px; + overflow-y: auto; padding: 5px 10px; border-radius: 7px; } @@ -338,3 +436,41 @@ ol.def-rules li { border: 1px solid transparent; text-align: center; } + +/* Responsive *CP navigation +----------------------------------------*/ +@media only screen and (max-width: 900px), only screen and (max-device-width: 900px) +{ + .nojs #tabs a span, .nojs #minitabs a span { + max-width: 40px; + overflow: hidden; + text-overflow: ellipsis; + letter-spacing: -.5px; + } + + #cp-menu, #navigation, #cp-main { + float: none; + width: auto; + margin: 0; + } + + #navigation { + padding: 0; + margin: 0 auto; + max-width: 320px; + } + + #navigation a { + background-image: none; + } + + #navigation li:first-child a { + border-top-left-radius: 5px; + border-top-right-radius: 5px; + } + + #navigation li:last-child a { + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + } +} diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css index 34f8bc8c32..88f2bd65c5 100644 --- a/phpBB/styles/prosilver/theme/forms.css +++ b/phpBB/styles/prosilver/theme/forms.css @@ -11,7 +11,6 @@ fieldset { input { font-weight: normal; - cursor: pointer; vertical-align: middle; padding: 0 3px; font-size: 1em; @@ -206,7 +205,11 @@ fieldset.forum-selection2 { fieldset.jumpbox { text-align: right; margin-top: 15px; - height: 2.5em; + min-height: 2.5em; +} + +fieldset.jumpbox select { + max-width: 50%; } fieldset.quickmod { @@ -253,6 +256,7 @@ fieldset.submit-buttons input { min-width: 100%; max-width: 100%; font-size: 1.2em; + resize: vertical; } /* Emoticons panel */ @@ -270,7 +274,6 @@ fieldset.submit-buttons input { .inputbox { border: 1px solid transparent; padding: 2px; - cursor: text; } .inputbox:hover, .inputbox:focus { @@ -281,7 +284,7 @@ fieldset.submit-buttons input { input.inputbox { width: 85%; } input.medium { width: 50%; } input.narrow { width: 25%; } -input.tiny { width: 125px; } +input.tiny { width: 150px; } textarea.inputbox { width: 85%; @@ -328,6 +331,10 @@ input.button3 { font-variant: small-caps; } +input[type="button"], input[type="submit"], input[type="reset"], input[type="checkbox"], input[type="radio"] { + cursor: pointer; +} + /* Alternative button */ a.button2, input.button2, input.button3 { border: 1px solid transparent; diff --git a/phpBB/styles/prosilver/theme/images/buttons.png b/phpBB/styles/prosilver/theme/images/buttons.png Binary files differindex a19abdc2b8..3a8c2f2f65 100644 --- a/phpBB/styles/prosilver/theme/images/buttons.png +++ b/phpBB/styles/prosilver/theme/images/buttons.png diff --git a/phpBB/styles/prosilver/theme/images/icon_download.gif b/phpBB/styles/prosilver/theme/images/icon_download.gif Binary files differnew file mode 100644 index 0000000000..70cd61caf2 --- /dev/null +++ b/phpBB/styles/prosilver/theme/images/icon_download.gif diff --git a/phpBB/styles/prosilver/theme/images/icon_mark.gif b/phpBB/styles/prosilver/theme/images/icon_mark.gif Binary files differnew file mode 100644 index 0000000000..1a33fc3264 --- /dev/null +++ b/phpBB/styles/prosilver/theme/images/icon_mark.gif diff --git a/phpBB/styles/prosilver/theme/images/icon_notification.gif b/phpBB/styles/prosilver/theme/images/icon_notification.gif Binary files differnew file mode 100644 index 0000000000..11092f4dce --- /dev/null +++ b/phpBB/styles/prosilver/theme/images/icon_notification.gif diff --git a/phpBB/styles/prosilver/theme/images/icon_pm.gif b/phpBB/styles/prosilver/theme/images/icon_pm.gif Binary files differnew file mode 100644 index 0000000000..103421a26f --- /dev/null +++ b/phpBB/styles/prosilver/theme/images/icon_pm.gif diff --git a/phpBB/styles/prosilver/theme/images/icon_post_menu.png b/phpBB/styles/prosilver/theme/images/icon_post_menu.png Binary files differnew file mode 100644 index 0000000000..2b48289fdb --- /dev/null +++ b/phpBB/styles/prosilver/theme/images/icon_post_menu.png diff --git a/phpBB/styles/prosilver/theme/images/icon_print.gif b/phpBB/styles/prosilver/theme/images/icon_print.gif Binary files differindex a71dfdde70..e464e304ea 100644..100755 --- a/phpBB/styles/prosilver/theme/images/icon_print.gif +++ b/phpBB/styles/prosilver/theme/images/icon_print.gif diff --git a/phpBB/styles/prosilver/theme/images/icon_sendemail.gif b/phpBB/styles/prosilver/theme/images/icon_sendemail.gif Binary files differindex f6b8aa10e1..92a39c8af9 100644 --- a/phpBB/styles/prosilver/theme/images/icon_sendemail.gif +++ b/phpBB/styles/prosilver/theme/images/icon_sendemail.gif diff --git a/phpBB/styles/prosilver/theme/images/loading.gif b/phpBB/styles/prosilver/theme/images/loading.gif Binary files differnew file mode 100644 index 0000000000..e1ed0883e0 --- /dev/null +++ b/phpBB/styles/prosilver/theme/images/loading.gif diff --git a/phpBB/styles/prosilver/theme/images/no_avatar.gif b/phpBB/styles/prosilver/theme/images/no_avatar.gif Binary files differindex 80539c8c71..ad73330e71 100644 --- a/phpBB/styles/prosilver/theme/images/no_avatar.gif +++ b/phpBB/styles/prosilver/theme/images/no_avatar.gif diff --git a/phpBB/styles/prosilver/theme/imageset.css b/phpBB/styles/prosilver/theme/imageset.css index 7aa19df06e..e6d306c7fd 100644 --- a/phpBB/styles/prosilver/theme/imageset.css +++ b/phpBB/styles/prosilver/theme/imageset.css @@ -260,7 +260,7 @@ span.imageset { padding-left: 11px; padding-top: 11px; } -.imageset.icon_contact_aim { +.imageset.phpbb_aol-icon, .imageset.icon_contact_aim { background-image: url("./images/icon_contact_aim.gif"); padding-left: 20px; padding-top: 20px; @@ -270,7 +270,7 @@ span.imageset { padding-left: 20px; padding-top: 20px; } -.imageset.icon_contact_icq { +.imageset.icon_contact_icq, .imageset.phpbb_icq-icon { background-image: url("./images/icon_contact_icq.gif"); padding-left: 20px; padding-top: 20px; @@ -280,17 +280,17 @@ span.imageset { padding-left: 20px; padding-top: 20px; } -.imageset.icon_contact_msnm { +.imageset.phpbb_wlm-icon, .imageset.icon_contact_msnm { background-image: url("./images/icon_contact_msnm.gif"); padding-left: 20px; padding-top: 20px; } -.imageset.icon_contact_www { +.imageset.icon_contact_www, .imageset.phpbb_website-icon { background-image: url("./images/icon_contact_www.gif"); padding-left: 20px; padding-top: 20px; } -.imageset.icon_contact_yahoo { +.imageset.icon_contact_yahoo, .imageset.phpbb_yahoo-icon { background-image: url("./images/icon_contact_yahoo.gif"); padding-left: 20px; padding-top: 20px; diff --git a/phpBB/styles/prosilver/theme/links.css b/phpBB/styles/prosilver/theme/links.css index 5dc8a13313..ff6df7c9a7 100644 --- a/phpBB/styles/prosilver/theme/links.css +++ b/phpBB/styles/prosilver/theme/links.css @@ -43,6 +43,35 @@ a:active { text-decoration: none; } +/* Navigation bar links */ +ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a { + display: inline-block; + padding-left: 17px; +} + +/* Notification mark read link */ +.dropdown-extended a.mark_read { + background-position: center center; + background-repeat: no-repeat; + border-radius: 3px 0 0 3px; + display: none; + margin-top: -20px; + position: absolute; + z-index: 2; + right: 0; + top: 50%; + width: 30px; + height: 40px; +} + +.dropdown-extended li:hover a.mark_read { + display: block; +} + +.dropdown-extended a.mark_read:hover { + width: 40px; +} + /* Links for forum/topic lists */ a.forumtitle { font-family: "Trebuchet MS", Helvetica, Arial, Sans-serif; diff --git a/phpBB/styles/prosilver/theme/plupload.css b/phpBB/styles/prosilver/theme/plupload.css new file mode 100644 index 0000000000..8569eca662 --- /dev/null +++ b/phpBB/styles/prosilver/theme/plupload.css @@ -0,0 +1,76 @@ +#attach-panel-multi { + display: none; + margin-bottom: 1em; +} + +#file-list td { + vertical-align: middle; +} + +.attach-name { + width: 50%; +} + +.attach-comment { + width: 30%; +} + +.attach-filesize { + width: 15%; +} + +.attach-status { + width: 5%; +} + +.attach-filesize, .attach-status { + text-align: center; +} + +.attach-controls { + display: inline-block; + float: right; +} + +#attach-row-tpl, .nojs .file-inline-bbcode { + display: none; +} + +#file-total-progress { + height: 2px; + display: block; + position: relative; + margin: 4px -10px -6px -10px; +} + +.file-progress { + background-color: #CCCCCC; + display:inline-block; + height: 8px; + width: 50px; +} + +.file-progress-bar, #file-total-progress-bar { + background-color: green; + display: block; + height: 100%; + width: 0; +} + +.file-status.file-working { + background: url('../../../assets/plupload/img/throbber.gif'); +} + +.file-status.file-uploaded { + background: url('../../../assets/plupload/img/done.gif'); +} + +.file-status.file-error { + background: url('../../../assets/plupload/img/error.gif'); +} + +.file-status { + display: inline-block; + height: 16px; + width: 16px; +} diff --git a/phpBB/styles/prosilver/theme/responsive.css b/phpBB/styles/prosilver/theme/responsive.css new file mode 100644 index 0000000000..13711c1267 --- /dev/null +++ b/phpBB/styles/prosilver/theme/responsive.css @@ -0,0 +1,538 @@ +/* Responsive Design +---------------------------------------- */ + +.responsive-hide { display: none !important; } +.responsive-show { display: block !important; } +.responsive-show-inline { display: inline !important; } +.responsive-show-inline-block { display: inline-block !important; } + +/* Content wrappers +----------------------------------------*/ +html { + height: auto; +} + +body { + padding: 0 5px; +} + +#wrap { + min-width: 300px; + padding: 0; +} + +/* Common block wrappers +----------------------------------------*/ +.headerbar, .navbar, .forabg, .forumbg, .post, .panel { + border-radius: 0; + margin-left: -5px; + margin-right: -5px; +} + +#cp-main .forabg, #cp-main .forumdb, #cp-main .post, #cp-main .panel { + border-radius: 7px; +} + +/* Logo block +----------------------------------------*/ +#site-description { + float: none; + width: auto; + text-align: center; +} + +#logo { + /* change display value to inline-block to show logo */ + display: none; + float: none; + padding: 10px; +} + +#site-description h1, #site-description p { + text-align: inherit; + float: none; + margin: 5px; + line-height: 1.2em; + overflow: hidden; + text-overflow: ellipsis; +} + +#site-description p, #search-box { + display: none; +} + +/* Navigation +----------------------------------------*/ +.headerbar + .navbar { + margin-top: -5px; +} + +/* Search +----------------------------------------*/ +.responsive-search { display: block !important; } +.responsive-search a { + display: block; + width: 16px; + height: 18px; + text-indent: 99px; + overflow: hidden; + background-position: 50% 50%; + background-repeat: no-repeat; + text-decoration: none; +} + +/* .topiclist lists +----------------------------------------*/ +li.header dt { + text-align: center; + text-transform: none; + line-height: 1em; + font-size: 1.2em; + padding-bottom: 4px; +} + +ul.topiclist li.header dt, ul.topiclist li.header dt .list-inner { + margin-right: 0 !important; + padding-right: 0; +} + +ul.topiclist li.header dd { + display: none !important; +} + +ul.topiclist dt, ul.topiclist dt .list-inner, +ul.topiclist.missing-column dt, ul.topiclist.missing-column dt .list-inner, +ul.topiclist.two-long-columns dt, ul.topiclist.two-long-columns dt .list-inner, +ul.topiclist.two-columns dt, ul.topiclist.two-columns dt .list-inner { + margin-right: 0; +} + +ul.topiclist dt .list-inner.with-mark { + padding-right: 34px; +} + +ul.topiclist dt .list-inner { + min-height: 28px; +} + +ul.topiclist li.header dt .list-inner { + min-height: 0; +} + +ul.topiclist dd { + display: none; +} +ul.topiclist dd.mark { + display: block; +} + +/* Forums and topics lists +----------------------------------------*/ +ul.topiclist.forums dt, ul.topiclist.topics dt { + margin-right: -250px; +} +ul.topiclist.forums dt .list-inner, ul.topiclist.topics dt .list-inner { + margin-right: 250px; +} + +ul.topiclist.forums dd.lastpost, ul.topiclist.topics dd.lastpost { + display: block; +} + +ul.topiclist dd.mark { + display: block; + position: absolute; + right: 5px; + top: 0; + margin: 0; + width: auto; + min-width: 0; + text-align: left; +} + +ul.topiclist.forums dd.topics dfn, ul.topiclist.topics dd.posts dfn { + position: relative; + left: 0; + width: auto; + display: inline; + font-weight: normal; +} + +@media only screen and (max-width: 550px), only screen and (max-device-width: 550px) +{ + ul.topiclist.forums dt, ul.topiclist.topics dt { + margin-right: 0; + } + + ul.topiclist.forums dt .list-inner, ul.topiclist.topics dt .list-inner { + margin-right: 0; + } + + ul.topiclist.forums dd.lastpost, ul.topiclist.topics dd.lastpost { + display: none; + } +} + +li.row .responsive-show strong { + font-weight: bold; + color: inherit; +} + +ul.topiclist li.row dt a.subforum { + display: inline-block; + vertical-align: bottom; + overflow: hidden; + text-overflow: ellipsis; + max-width: 100px; +} + +/* Notifications list +----------------------------------------*/ +@media only screen and (max-width: 350px), only screen and (max-device-width: 350px) +{ + .dropdown-extended { + width: 250px; + } +} + +/* Pagination +----------------------------------------*/ +.pagination { + margin: 5px 0; +} + +.pagination li a, .pagination li span { + min-width: 10px; + display: inline-block; + text-align: center; +} + +/* Responsive tables +----------------------------------------*/ +table.responsive, table.responsive tbody, table.responsive tr, table.responsive td { + display: block; +} + +table.responsive thead, table.responsive th { + display: none; +} + +table.responsive.show-header thead, table.responsive.show-header th:first-child { + display: block; + width: auto !important; + text-align: left !important; +} + +table.responsive.show-header th:first-child span.rank-img { + display: none; +} + +table.responsive tr { + margin: 2px 0; +} + +table.responsive td { + width: auto !important; + text-align: left !important; + padding: 4px; +} + +table.responsive td.empty { + display: none !important; +} + +table.responsive td > dfn { + display: inline-block !important; +} + +table.responsive td > dfn:after { + content: ':'; + padding-right: 5px; +} + +table.responsive span.rank-img { + float: none; + padding-right: 5px; +} + +table.responsive#memberlist td:first-child input[type="checkbox"] { + float: right; +} + +/* Forms +----------------------------------------*/ +fieldset dt, fieldset.fields1 dt, fieldset.fields2 dt { + width: auto; + float: none; +} + +fieldset dd, fieldset.fields1 dd, fieldset.fields2 dd { + margin-left: 20px; +} + +textarea, dd textarea, #message-box textarea { + width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +dl.pmlist dt { + width: auto !important; + margin-bottom: 5px; +} + +dl.pmlist dd { + display: inline-block; + margin-left: 0 !important; +} + +dl.pmlist dd:first-of-type { + padding-left: 20px; +} + +#smiley-box, #message-box { + float: none; + width: auto; +} + +#smiley-box { + margin-top: 5px; +} + +.bbcode-status { + display: none; +} + +.colour-palette, .colour-palette tbody, .colour-palette tr { + display: block; +} + +.colour-palette td { + display: inline-block; + margin-right: 2px; +} + +.horizontal-palette td:nth-child(2n), .vertical-palette tr:nth-child(2n) { + display: none; +} + +.colour-palette a { + display: inline-block !important; +} + +fieldset.quick-login label { + display: block; + margin-bottom: 5px; + white-space: normal; +} + +fieldset.quick-login label > span { + display: inline-block; + min-width: 100px; +} + +fieldset.quick-login input.inputbox { + width: 85%; + max-width: 300px; + margin-left: 20px; +} + +fieldset.quick-login label[for="autologin"] { + display: inline-block; + text-align: right; + min-width: 50%; +} + +@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) +{ + select, .inputbox { + max-width: 260px; + } +} + +@media only screen and (max-width: 320px), only screen and (max-device-width: 320px) +{ + select, .inputbox { + max-width: 240px; + } +} + +/* User profile +----------------------------------------*/ +.column1, .column2, .left-box.profile-details { + float: none; + width: auto; +} + +@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) +{ + dl.details dt, dl.details dd { + width: auto; + float: none; + text-align: left; + } + + dl.details dd { + margin-left: 20px; + } +} + +/* Polls +----------------------------------------*/ +fieldset.polls dt { + width: 90%; +} + +fieldset.polls dd.resultbar { + padding-left: 20px; +} + +fieldset.polls dd.poll_option_percent { + width: 20%; +} + +fieldset.polls dd.resultbar, fieldset.polls dd.poll_option_percent { + margin-top: 5px; +} + +/* Post +----------------------------------------*/ +.postprofile, .postbody, .search .postbody { + display: block; + width: auto; + float: none; + padding: 0; + min-height: 0; +} + +.post .postprofile { + width: auto; + border-width: 0 0 1px 0; + padding-bottom: 5px; + margin: 0; + margin-bottom: 5px; + overflow: hidden; +} + +.postprofile dd { + display: none; +} + +.postprofile dt, .postprofile dd.profile-rank, .search .postprofile dd { + display: block; + margin: 0; +} + +.postprofile ul.profile-icons { + display: none; +} + +.postprofile .avatar { + display: block; + float: left; + margin-right: 5px; +} + +.postprofile .avatar img { + width: auto !important; + height: auto !important; + display: block; + max-height: 32px; +} + +@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 1.5dppx) +{ + /* Scale online image for HD displays */ + .online { + background-size: 40px; + } +} + +/* Misc stuff +----------------------------------------*/ +h2 { + margin-top: .5em; +} + +p { + margin-bottom: .5em; + overflow: hidden; +} + +p.rightside { + margin-bottom: 0; +} + +.column1, .column2 { + width: auto; + float: none; +} + +fieldset.quickmod { + width: auto; + float: none; + text-align: center; +} + +fieldset.display-options label { + display: block; + clear: both; + margin-bottom: 5px; +} + +dl.mini dd.pm-legend { + float: left; + min-width: 200px; +} + +#topicreview { + margin: 0 -5px; + padding: 0 5px; +} + +fieldset.display-actions { + white-space: normal; +} + +.phpbb_alert { + width: auto; + margin: 0 5px; +} + +.attach-comment dfn { + width: 100%; +} + +@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) +{ + p.responsive-center { + float: none; + text-align: center; + margin: 0; + } + + .topic-actions > .pagination, fieldset.jumpbox { + text-align: center; + } + + .topic-actions > .pagination { + float: none; + overflow: hidden; + clear: both; + padding-bottom: 1px; + } + + .topic-actions > div.search-box, p.jumpbox-return { + display: none; + } + + .display-options > label:nth-child(1) { + display: block; + margin-bottom: 5px; + } + + .attach-controls { + margin-top: 5px; + width: 100%; + } +} diff --git a/phpBB/styles/prosilver/theme/tweaks.css b/phpBB/styles/prosilver/theme/tweaks.css index ca4e9a23b6..456bbf3479 100644 --- a/phpBB/styles/prosilver/theme/tweaks.css +++ b/phpBB/styles/prosilver/theme/tweaks.css @@ -53,11 +53,11 @@ dd.option { } /* Notifications list for IE7 */ -#notification_list { +.dropdown-extended { *left: 0; } -#notification_list .header_settings { +.dropdown-extended .header_settings { *position: absolute; *right: 10px; *top: 0; diff --git a/phpBB/styles/subsilver2/style.cfg b/phpBB/styles/subsilver2/style.cfg index ca81337d17..c534c30bb9 100644 --- a/phpBB/styles/subsilver2/style.cfg +++ b/phpBB/styles/subsilver2/style.cfg @@ -17,9 +17,9 @@ # General Information about this style name = subsilver2 -copyright = © 2005 phpBB Group -style_version = 3.1.0-dev -phpbb_version = 3.1.0-dev +copyright = © 2005 phpBB Group +style_version = 3.1.0-b2 +phpbb_version = 3.1.0-b2 # Defining a different template bitfield # template_bitfield = lNg= diff --git a/phpBB/styles/subsilver2/template/attachment.html b/phpBB/styles/subsilver2/template/attachment.html index eb5dd91634..baad7c6cfc 100644 --- a/phpBB/styles/subsilver2/template/attachment.html +++ b/phpBB/styles/subsilver2/template/attachment.html @@ -10,12 +10,12 @@ <!-- ENDIF --> <!-- IF _file.S_THUMBNAIL --> - <a href="{_file.U_DOWNLOAD_LINK}"><img src="{_file.THUMB_IMAGE}" alt="{_file.DOWNLOAD_NAME}" /></a><br /> + <a href="{_file.U_DOWNLOAD_LINK}"><img src="{_file.THUMB_IMAGE}" class="postimage" alt="{_file.DOWNLOAD_NAME}" /></a><br /> <span class="gensmall">{_file.DOWNLOAD_NAME} [ {_file.FILESIZE} {_file.SIZE_LANG} | {_file.L_DOWNLOAD_COUNT} ]</span> <!-- ENDIF --> <!-- IF _file.S_IMAGE --> - <img src="{_file.U_INLINE_LINK}" alt="{_file.DOWNLOAD_NAME}" /><br /> + <img src="{_file.U_INLINE_LINK}" class="postimage" alt="{_file.DOWNLOAD_NAME}" /><br /> <span class="gensmall">{_file.DOWNLOAD_NAME} [ {_file.FILESIZE} {_file.SIZE_LANG} | {_file.L_DOWNLOAD_COUNT} ]</span> <!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/bbcode.html b/phpBB/styles/subsilver2/template/bbcode.html index 5558716cad..9ee5acec34 100644 --- a/phpBB/styles/subsilver2/template/bbcode.html +++ b/phpBB/styles/subsilver2/template/bbcode.html @@ -50,7 +50,7 @@ <!-- BEGIN size --><span style="font-size: {SIZE}%; line-height: normal">{TEXT}</span><!-- END size --> -<!-- BEGIN img --><img src="{URL}" alt="{L_IMAGE}" /><!-- END img --> +<!-- BEGIN img --><img src="{URL}" class="postimage" alt="{L_IMAGE}" /><!-- END img --> <!-- BEGIN url --><a href="{URL}" class="postlink">{DESCRIPTION}</a><!-- END url --> diff --git a/phpBB/styles/subsilver2/template/breadcrumbs.html b/phpBB/styles/subsilver2/template/breadcrumbs.html index 09ee9a8606..47cb82c790 100644 --- a/phpBB/styles/subsilver2/template/breadcrumbs.html +++ b/phpBB/styles/subsilver2/template/breadcrumbs.html @@ -4,7 +4,9 @@ <td class="row1"> <p class="breadcrumbs"><!-- IF U_SITE_HOME --><a href="{U_SITE_HOME}"{$MICRODATA}>{L_SITE_HOME}</a> <strong>»</strong> <!-- ENDIF --><a href="{U_INDEX}"{$MICRODATA}>{L_INDEX}</a><!-- BEGIN navlinks --> » <a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}>{navlinks.FORUM_NAME}</a><!-- END navlinks --> <!-- EVENT overall_header_breadcrumb_append --></p> + <!-- EVENT overall_footer_timezone_before --> <p class="datetime">{S_TIMEZONE}</p> + <!-- EVENT overall_footer_timezone_after --> </td> </tr> </table> diff --git a/phpBB/styles/subsilver2/template/custom_profile_fields.html b/phpBB/styles/subsilver2/template/custom_profile_fields.html deleted file mode 100644 index 3dabedda06..0000000000 --- a/phpBB/styles/subsilver2/template/custom_profile_fields.html +++ /dev/null @@ -1,31 +0,0 @@ -<!-- BEGIN dropdown --> - <select name="{dropdown.FIELD_IDENT}"> - <!-- BEGIN options --><option value="{dropdown.options.OPTION_ID}"{dropdown.options.SELECTED}>{dropdown.options.VALUE}</option><!-- END options --> - </select> -<!-- END dropdown --> - -<!-- BEGIN text --> - <textarea name="{text.FIELD_IDENT}" rows="{text.FIELD_ROWS}" cols="{text.FIELD_COLS}">{text.FIELD_VALUE}</textarea> -<!-- END text --> - -<!-- BEGIN string --> - <input type="text" class="post" name="{string.FIELD_IDENT}" size="{string.FIELD_LENGTH}" maxlength="{string.FIELD_MAXLEN}" value="{string.FIELD_VALUE}" /> -<!-- END string --> - -<!-- BEGIN bool --> - <!-- IF bool.FIELD_LENGTH eq 1 --> - <!-- BEGIN options --><input type="radio" class="radio" name="{bool.FIELD_IDENT}" value="{bool.options.OPTION_ID}"{bool.options.CHECKED} /><span class="genmed">{bool.options.VALUE}</span> <!-- END options --> - <!-- ELSE --> - <input type="checkbox" class="radio" name="{bool.FIELD_IDENT}" value="1"<!-- IF bool.FIELD_VALUE eq 1 --> checked="checked"<!-- ENDIF --> /> - <!-- ENDIF --> -<!-- END bool --> - -<!-- BEGIN int --> - <input type="number" min="{int.FIELD_MINLEN}" max="{int.FIELD_MAXLEN}" class="post" name="{int.FIELD_IDENT}" size="{int.FIELD_LENGTH}" value="{int.FIELD_VALUE}" /> -<!-- END int --> - -<!-- BEGIN date --> - <span class="genmed">{L_DAY}{L_COLON}</span> <select name="{date.FIELD_IDENT}_day">{date.S_DAY_OPTIONS}</select> - <span class="genmed">{L_MONTH}{L_COLON}</span> <select name="{date.FIELD_IDENT}_month">{date.S_MONTH_OPTIONS}</select> - <span class="genmed">{L_YEAR}{L_COLON}</span> <select name="{date.FIELD_IDENT}_year">{date.S_YEAR_OPTIONS}</select> -<!-- END date --> diff --git a/phpBB/styles/subsilver2/template/forumlist_body.html b/phpBB/styles/subsilver2/template/forumlist_body.html index a222607ae8..0d522a6959 100644 --- a/phpBB/styles/subsilver2/template/forumlist_body.html +++ b/phpBB/styles/subsilver2/template/forumlist_body.html @@ -9,11 +9,13 @@ <th> {L_LAST_POST} </th> </tr> <!-- BEGIN forumrow --> + <!-- EVENT forumlist_body_category_header_before --> <!-- IF forumrow.S_IS_CAT --> <tr> <td class="cat" colspan="2"><h4><a href="{forumrow.U_VIEWFORUM}">{forumrow.FORUM_NAME}</a></h4></td> <td class="catdiv" colspan="3"> </td> </tr> + <!-- EVENT forumlist_body_category_header_after --> <!-- ELSEIF forumrow.S_IS_LINK --> <tr> <td class="row1" width="50" align="center">{forumrow.FORUM_FOLDER_IMG}</td> @@ -49,11 +51,13 @@ <p class="forumdesc"><strong>{forumrow.L_MODERATOR_STR}{L_COLON}</strong> {forumrow.MODERATORS}</p> <!-- ENDIF --> <!-- IF .forumrow.subforum and forumrow.S_LIST_SUBFORUMS --> - <p class="forumdesc"><strong>{forumrow.L_SUBFORUM_STR}</strong> + <!-- EVENT forumlist_body_subforums_before --> + <p class="forumdesc"><strong>{forumrow.L_SUBFORUM_STR}{L_COLON}</strong> <!-- BEGIN subforum --> - <a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->,<!-- ENDIF --> + <a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->{L_COMMA_SEPARATOR}<!-- ENDIF --> <!-- END subforum --> </p> + <!-- EVENT forumlist_body_subforums_after --> <!-- ENDIF --> </td> <td class="row2" align="center"><p class="topicdetails">{forumrow.TOPICS}</p></td> @@ -81,6 +85,7 @@ </td> </tr> <!-- ENDIF --> + <!-- EVENT forumlist_body_last_row_after --> <!-- BEGINELSE --> <tr> <td class="row1" colspan="5" align="center"><p class="gensmall">{L_NO_FORUMS}</p></td> diff --git a/phpBB/styles/subsilver2/template/index_body.html b/phpBB/styles/subsilver2/template/index_body.html index e07cfda8b3..9e859eac0e 100644 --- a/phpBB/styles/subsilver2/template/index_body.html +++ b/phpBB/styles/subsilver2/template/index_body.html @@ -1,17 +1,28 @@ <!-- INCLUDE overall_header.html --> -<!-- IF U_MCP --> +<!-- EVENT index_body_linklist_before --> + +<!-- IF U_MCP or U_ACP --> <div id="pageheader"> - <p class="linkmcp">[ <a href="{U_MCP}">{L_MCP}</a> ]</p> + <p class="linkmcp">[ <!-- IF U_ACP --><a href="{U_ACP}">{L_ACP}</a><!-- IF U_MCP --> | <!-- ENDIF --><!-- ENDIF --><!-- IF U_MCP --><a href="{U_MCP}">{L_MCP}</a><!-- ENDIF --> ]</p> </div> <br clear="all" /><br /> <!-- ENDIF --> +<!-- EVENT index_body_linklist_after --> + <!-- INCLUDE forumlist_body.html --> <!-- IF not S_IS_BOT or U_TEAM --> -<span class="gensmall"><!-- IF not S_IS_BOT --><a href="{U_DELETE_COOKIES}">{L_DELETE_COOKIES}</a><!-- ENDIF --><!-- IF not S_IS_BOT and U_TEAM --> | <!-- ENDIF --><!-- IF U_TEAM --><a href="{U_TEAM}">{L_THE_TEAM}</a><!-- ENDIF --></span><br /> +<span class="gensmall"> + <!-- IF not S_IS_BOT --><a href="{U_DELETE_COOKIES}">{L_DELETE_COOKIES}</a><!-- ENDIF --> + <!-- IF not S_IS_BOT and U_TEAM --> | <!-- ENDIF --> + <!-- EVENT overall_footer_teamlink_before --> + <!-- IF U_TEAM --><a href="{U_TEAM}">{L_THE_TEAM}</a><!-- ENDIF --> + <!-- EVENT overall_footer_teamlink_after --> +</span> +<br /> <!-- ENDIF --> <br clear="all" /> @@ -23,7 +34,7 @@ <!-- IF S_DISPLAY_ONLINE_LIST --> <br clear="all" /> - <table class="tablebg" width="100%" cellspacing="1"> + <table class="tablebg stat-block online-list" width="100%" cellspacing="1"> <tr> <td class="cat" colspan="2"><!-- IF U_VIEWONLINE --><h4><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a></h4><!-- ELSE --><h4>{L_WHO_IS_ONLINE}</h4><!-- ENDIF --></td> </tr> @@ -46,7 +57,7 @@ <!-- IF S_DISPLAY_BIRTHDAY_LIST --> <br clear="all" /> - <table class="tablebg" width="100%" cellspacing="1"> + <table class="tablebg stat-block birthday-list" width="100%" cellspacing="1"> <tr> <td class="cat" colspan="2"><h4>{L_BIRTHDAYS}</h4></td> </tr> @@ -59,7 +70,7 @@ <br clear="all" /> -<table class="tablebg" width="100%" cellspacing="1"> +<table class="tablebg stat-block statistics" width="100%" cellspacing="1"> <tr> <td class="cat" colspan="2"><h4>{L_STATISTICS}</h4></td> </tr> @@ -69,6 +80,8 @@ </tr> </table> +<!-- EVENT index_body_stat_blocks_after --> + <!-- IF not S_USER_LOGGED_IN and not S_IS_BOT --> <br clear="all" /> @@ -79,7 +92,7 @@ <td class="cat"><h4><a href="{U_LOGIN_LOGOUT}">{L_LOGIN_LOGOUT}</a></h4></td> </tr> <tr> - <td class="row1" align="center"><span class="genmed">{L_USERNAME}{L_COLON}</span> <input class="post" type="text" name="username" size="10" /> <span class="genmed">{L_PASSWORD}{L_COLON}</span> <input class="post" type="password" name="password" size="10" /> <!-- IF S_AUTOLOGIN_ENABLED --> <span class="gensmall">{L_LOG_ME_IN}</span> <input type="checkbox" class="radio" name="autologin" /><!-- ENDIF --> <input type="submit" class="btnmain" name="login" value="{L_LOGIN}" /></td> + <td class="row1" align="center"><span class="genmed">{L_USERNAME}{L_COLON}</span> <input class="post" type="text" name="username" size="10" /> <span class="genmed">{L_PASSWORD}{L_COLON}</span> <input class="post" type="password" name="password" size="10" /> <!-- IF U_SEND_PASSWORD --><a href="{U_SEND_PASSWORD}">{L_FORGOT_PASS}</a> <!-- ENDIF --> <!-- IF S_AUTOLOGIN_ENABLED --> <span class="gensmall">{L_LOG_ME_IN}</span> <input type="checkbox" class="radio" name="autologin" /><!-- ENDIF --> <input type="submit" class="btnmain" name="login" value="{L_LOGIN}" /></td> </tr> </table> {S_LOGIN_REDIRECT} diff --git a/phpBB/styles/subsilver2/template/mcp_header.html b/phpBB/styles/subsilver2/template/mcp_header.html index f107732234..7144750ed4 100644 --- a/phpBB/styles/subsilver2/template/mcp_header.html +++ b/phpBB/styles/subsilver2/template/mcp_header.html @@ -3,9 +3,7 @@ <div id="pageheader"> <!-- IF U_MCP --> <p class="linkmcp"> - [ <a href="{U_MCP}">{L_MCP}</a><!-- IF U_MCP_FORUM --> | <a href="{U_MCP_FORUM}">{L_MODERATE_FORUM}</a><!-- ENDIF --> - <!-- IF U_MCP_TOPIC --> | <a href="{U_MCP_TOPIC}">{L_MODERATE_TOPIC}</a><!-- ENDIF --> - <!-- IF U_MCP_POST --> | <a href="{U_MCP_POST}">{L_MODERATE_POST}</a><!-- ENDIF --> ] + [<!-- IF U_ACP --> <a href="{U_ACP}">{L_ACP}</a> |<!-- ENDIF --> <a href="{U_MCP}">{L_MCP}</a><!-- IF U_MCP_FORUM --> | <a href="{U_MCP_FORUM}">{L_MODERATE_FORUM}</a><!-- ENDIF --><!-- IF U_MCP_TOPIC --> | <a href="{U_MCP_TOPIC}">{L_MODERATE_TOPIC}</a><!-- ENDIF --><!-- IF U_MCP_POST --> | <a href="{U_MCP_POST}">{L_MODERATE_POST}</a><!-- ENDIF --> ] </p> <!-- ENDIF --> @@ -60,20 +58,3 @@ <br /> <!-- ENDIF --> - - <!-- IF CONFIRM_MESSAGE --> - <form name="confirm" method="post" action="{S_CONFIRM_ACTION}"> - - <table class="tablebg" width="100%" cellspacing="1"> - <tr> - <th>{L_PLEASE_CONFIRM}</th> - </tr> - <tr> - <td class="row1" align="center"><span class="gen"><br />{CONFIRM_MESSAGE}<br /><br />{S_HIDDEN_FIELDS}<input class="btnmain" type="submit" name="confirm" value="{L_YES}" /> <input class="btnlite" type="submit" name="cancel" value="{L_NO}" /><br /><br /></span></td> - </tr> - </table> - - </form> - - <br /> - <!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/mcp_topic.html b/phpBB/styles/subsilver2/template/mcp_topic.html index d3b4408243..5bd762ec0b 100644 --- a/phpBB/styles/subsilver2/template/mcp_topic.html +++ b/phpBB/styles/subsilver2/template/mcp_topic.html @@ -73,7 +73,7 @@ <td align="center"><b class="postauthor">{postrow.POST_AUTHOR_FULL}</b></td> <td width="100%"> <table width="100%" cellspacing="0" cellpadding="0" border="0"> - <tr valign="top"> + <tr style="vertical-align: top;"> <td class="gensmall" nowrap="nowrap"> <b>{L_POST_SUBJECT}{L_COLON}</b> </td> <td class="gensmall" width="100%">{postrow.POST_SUBJECT}</td> </tr> diff --git a/phpBB/styles/subsilver2/template/memberlist_body.html b/phpBB/styles/subsilver2/template/memberlist_body.html index 7c4d301de7..ecfb4b69c5 100644 --- a/phpBB/styles/subsilver2/template/memberlist_body.html +++ b/phpBB/styles/subsilver2/template/memberlist_body.html @@ -45,7 +45,6 @@ <th nowrap="nowrap" width="15%"><a href="{U_SORT_RANK}">{L_RANK}</a></th> <th nowrap="nowrap" width="11%">{L_SEND_MESSAGE}</th> <th nowrap="nowrap" width="11%"><a href="{U_SORT_EMAIL}">{L_EMAIL}</a></th> - <th nowrap="nowrap" width="11%"><a href="{U_SORT_WEBSITE}">{L_WEBSITE}</a></th> <!-- IF S_IN_SEARCH_POPUP and not S_SELECT_SINGLE --><th width="2%" nowrap="nowrap">{L_MARK}</th><!-- ENDIF --> </tr> <!-- BEGIN memberrow --> @@ -72,7 +71,6 @@ <td class="gen" align="center"><!-- IF memberrow.RANK_IMG -->{memberrow.RANK_IMG}<!-- ELSE -->{memberrow.RANK_TITLE}<!-- ENDIF --></td> <td class="gen" align="center"> <!-- IF memberrow.U_PM --><a href="{memberrow.U_PM}" class="imageset">{PM_IMG}</a><!-- ENDIF --> </td> <td class="gen" align="center"> <!-- IF memberrow.U_EMAIL --><a href="{memberrow.U_EMAIL}" class="imageset">{EMAIL_IMG}</a><!-- ENDIF --> </td> - <td class="gen" align="center"> <!-- IF memberrow.U_WWW --><a href="{memberrow.U_WWW}" class="imageset">{WWW_IMG}</a><!-- ENDIF --> </td> <!-- IF memberrow.S_PROFILE_FIELD1 --> <!-- Use a construct like this to include admin defined profile fields. Replace FIELD1 with the name of your field. --> <td class="gen" align="center"> {memberrow.PROFILE_FIELD1_VALUE}</td> diff --git a/phpBB/styles/subsilver2/template/memberlist_im.html b/phpBB/styles/subsilver2/template/memberlist_im.html index da1ad661c3..a19229605a 100644 --- a/phpBB/styles/subsilver2/template/memberlist_im.html +++ b/phpBB/styles/subsilver2/template/memberlist_im.html @@ -2,8 +2,6 @@ <br clear="all" /> -<!-- MSNM info from http://www.cdolive.net/ - doesn't seem to work with MSN Messenger --> - <form method="post" action="{S_IM_ACTION}"> <table class="tablebg" width="95%" cellspacing="1" cellpadding="4" border="0" align="center"> <tr> @@ -14,97 +12,9 @@ </tr> <tr> <td class="row1"><b class="genmed">{L_IM_RECIPIENT}{L_COLON} </b></td> - <td class="row2"><span class="gen"><b>{USERNAME}</b><!-- IF S_SEND_ICQ or S_SEND_AIM or S_SEND_MSNM or S_NO_SEND_JABBER --> [ {IM_CONTACT} ]<!-- ENDIF --></span> <!-- IF PRESENCE_IMG -->{PRESENCE_IMG}<!-- ENDIF --></td> + <td class="row2"><span class="gen"><b>{USERNAME}</b><!-- IF S_NO_SEND_JABBER --> [ {IM_CONTACT} ]<!-- ENDIF --></span> <!-- IF PRESENCE_IMG -->{PRESENCE_IMG}<!-- ENDIF --></td> </tr> - <!-- IF S_SEND_AIM --> - <tr> - <td class="row1" colspan="2" align="center"><br /><a class="gen" href="{U_AIM_CONTACT}">{L_IM_ADD_CONTACT}</a><br /><a class="gen" href="{U_AIM_MESSAGE}">{L_IM_SEND_MESSAGE}</a><br /><br /><a class="gensmall" href="http://www.aim.com">{L_IM_DOWNLOAD_APP}</a> | <a class="gensmall" href="http://www.aim.com/products/express">{L_IM_AIM_EXPRESS}</a> </td> - </tr> - <tr> - <td class="cat" colspan="2" align="center"> </td> - </tr> - <!-- ENDIF --> - - <!-- IF S_SEND_MSNM --> - <tr> - <td class="row1" colspan="2" align="center"> - <object classid="clsid:B69003B3-C55E-4B48-836C-BC5946FC3B28" codetype="application/x-oleobject" id="objMessengerApp" width="0" height="0"></object> - <script type="text/javascript"> - // <![CDATA[ - var app = document.getElementById('objMessengerApp'); - - /** - * Check whether the browser supports this and whether MSNM is connected - */ - function msn_supported() - { - // Does the browser support the MSNM object? - if (app.MyStatus) - { - // Is MSNM connected? - if (app.MyStatus == 1) - { - alert('{LA_IM_MSNM_CONNECT}'); - return false; - } - } - else - { - alert('{LA_IM_MSNM_BROWSER}'); - return false; - } - return true; - } - - /** - * Add to your contact list - */ - function add_contact(address) - { - if (msn_supported()) - { - // Could return an error while MSNM is connecting, don't want that - try - { - app.AddContact(0, address); - } - catch (e) - { - return; - } - } - } - - /** - * Write IM to contact - */ - function im_contact(address) - { - if (msn_supported()) - { - // Could return an error while MSNM is connecting, don't want that - try - { - app.InstantMessage(address); - } - catch (e) - { - return; - } - } - } - // ]]> - </script> - - <a class="gen" href="#" onclick="add_contact('{A_IM_CONTACT}'); return false;">{L_IM_ADD_CONTACT}</a><br /><a class="gen" href="#" onclick="im_contact('{A_IM_CONTACT}'); return false;">{L_IM_SEND_MESSAGE}</a> - </td> - </tr> - <tr> - <td class="cat" colspan="2" align="center"> </td> - </tr> - <!-- ENDIF --> - <!-- IF S_SEND_JABBER --> <tr> <td class="row1"><b class="genmed">{L_IM_MESSAGE}{L_COLON} </b></td> @@ -113,21 +23,16 @@ <tr> <td class="cat" colspan="2" align="center"><input class="btnmain" name="submit" type="submit" value="{L_IM_SEND}" /></td> </tr> - <!-- ENDIF --> - - <!-- IF S_NO_SEND_JABBER --> - <tr> - <td class="row1" colspan="2"><span class="genmed">{L_IM_NO_JABBER}</span></td> - </tr> - <!-- ENDIF --> - - <!-- IF S_SENT_JABBER --> <tr> <td class="row1" colspan="2" align="center"><span class="gen">{L_IM_SENT_JABBER}</span></td> </tr> <tr> <td class="cat" colspan="2" align="center"></td> </tr> + <!-- ELSEIF S_NO_SEND_JABBER --> + <tr> + <td class="row1" colspan="2"><span class="genmed">{L_IM_NO_JABBER}</span></td> + </tr> <!-- ENDIF --> </table> diff --git a/phpBB/styles/subsilver2/template/memberlist_search.html b/phpBB/styles/subsilver2/template/memberlist_search.html index 484bbd85e8..aa6b61fe22 100644 --- a/phpBB/styles/subsilver2/template/memberlist_search.html +++ b/phpBB/styles/subsilver2/template/memberlist_search.html @@ -76,59 +76,42 @@ <tr> <td class="row1"><b class="genmed">{L_USERNAME}{L_COLON}</b></td> <td class="row2"><input class="post" type="text" name="username" value="{USERNAME}" /></td> - <td class="row1"><b class="genmed">{L_ICQ}{L_COLON}</b></td> - <td class="row2"><input class="post" type="text" name="icq" value="{ICQ}" /></td> -</tr> -<tr> -<!-- IF S_EMAIL_SEARCH_ALLOWED --> - <td class="row1"><b class="genmed">{L_EMAIL}{L_COLON}</b></td> - <td class="row2"><input class="post" type="email" name="email" value="{EMAIL}" /></td> -<!-- ELSE --> - <td colspan="2" class="row1"> </td> -<!-- ENDIF --> - <td class="row1"><b class="genmed">{L_AIM}{L_COLON}</b></td> - <td class="row2"><input class="post" type="text" name="aim" value="{AIM}" /></td> + <!-- IF S_EMAIL_SEARCH_ALLOWED --> + <td class="row1"><b class="genmed">{L_EMAIL}{L_COLON}</b></td> + <td class="row2"><input class="post" type="email" name="email" value="{EMAIL}" /></td> + <!-- ELSE --> + <td colspan="2" class="row1"> </td> + <!-- ENDIF --> </tr> <tr> <td class="row1"><b class="genmed">{L_JOINED}{L_COLON}</b></td> <td class="row2"><select name="joined_select">{S_JOINED_TIME_OPTIONS}</select> <input class="post" type="text" name="joined" value="{JOINED}" /></td> - <td class="row1"><b class="genmed">{L_YIM}{L_COLON}</b></td> - <td class="row2"><input class="post" type="text" name="yahoo" value="{YAHOO}" /></td> + <td class="row1"><b class="genmed">{L_POSTS}{L_COLON}</b></td> + <td class="row2"><select name="count_select">{S_COUNT_OPTIONS}</select> <input class="post" type="number" min="0" name="count" value="{COUNT}" /></td> </tr> -<tr> <!-- IF S_VIEWONLINE --> +<tr> <td class="row1"><b class="genmed">{L_LAST_ACTIVE}{L_COLON}</b></td> <td class="row2"><select name="active_select">{S_ACTIVE_TIME_OPTIONS}</select> <input class="post" type="text" name="active" value="{ACTIVE}" /></td> -<!-- ELSE --> - <td colspan="2" class="row1"> </td> -<!-- ENDIF --> - <td class="row1"><b class="genmed">{L_MSNM}{L_COLON}</b></td> - <td class="row2"><input class="post" type="text" name="msn" value="{MSNM}" /></td> + <!-- IF S_IP_SEARCH_ALLOWED --> + <td class="row1"><b class="genmed">{L_POST_IP}{L_COLON}</b></td> + <td class="row2"><input class="post" type="text" name="ip" value="{IP}" /></td> + <!-- ELSE --> + <td colspan="2" class="row1"> </td> + <!-- ENDIF --> </tr> +<!-- ENDIF --> <tr> - <td class="row1"><b class="genmed">{L_POSTS}{L_COLON}</b></td> - <td class="row2"><select name="count_select">{S_COUNT_OPTIONS}</select> <input class="post" type="number" min="0" name="count" value="{COUNT}" /></td> + <td class="row1"><b class="genmed">{L_GROUP}{L_COLON}</b></td> + <td class="row2" nowrap="nowrap"><select name="search_group_id">{S_GROUP_SELECT}</select></td> <td class="row1"><b class="genmed">{L_JABBER}{L_COLON}</b></td> <td class="row2"><input class="post" type="text" name="jabber" value="{JABBER}" /></td> </tr> <tr> <td class="row1"><b class="genmed">{L_SORT_BY}{L_COLON}</b></td> <td class="row2" nowrap="nowrap"><select name="sk">{S_SORT_OPTIONS}</select> <select name="sd">{S_ORDER_SELECT}</select> </td> -<!-- IF S_IP_SEARCH_ALLOWED --> - <td class="row1"><b class="genmed">{L_POST_IP}{L_COLON}</b></td> - <td class="row2"><input class="post" type="text" name="ip" value="{IP}" /></td> -</tr> -<tr> - <td class="row1"><b class="genmed">{L_GROUP}{L_COLON}</b></td> - <td class="row2" nowrap="nowrap"><select name="search_group_id">{S_GROUP_SELECT}</select></td> - <td class="row1"> </td> - <td class="row2"> </td> -</tr> -<!-- ELSE --> - <td class="row1"><b class="genmed">{L_GROUP}{L_COLON}</b></td> - <td class="row2" nowrap="nowrap"><select name="search_group_id">{S_GROUP_SELECT}</select></td> + <td colspan="2" class="row1"> </td> </tr> -<!-- ENDIF --> <tr> <td class="cat" colspan="4" align="center"><input class="btnmain" type="submit" name="submit" value="{L_SEARCH}" /> <input class="btnlite" type="reset" value="{L_RESET}" /></td> </tr> diff --git a/phpBB/styles/subsilver2/template/memberlist_leaders.html b/phpBB/styles/subsilver2/template/memberlist_team.html index a4f38aafc4..a4f38aafc4 100644 --- a/phpBB/styles/subsilver2/template/memberlist_leaders.html +++ b/phpBB/styles/subsilver2/template/memberlist_team.html diff --git a/phpBB/styles/subsilver2/template/memberlist_view.html b/phpBB/styles/subsilver2/template/memberlist_view.html index 06b5af3322..52f40707c0 100644 --- a/phpBB/styles/subsilver2/template/memberlist_view.html +++ b/phpBB/styles/subsilver2/template/memberlist_view.html @@ -72,8 +72,8 @@ <td width="100%"><b class="gen">{JOINED}</b></td> </tr> <tr> - <td class="gen" align="{S_CONTENT_FLOW_END}" nowrap="nowrap">{L_VISITED}{L_COLON} </td> - <td width="100%"><b class="gen">{VISITED}</b></td> + <td class="gen" align="{S_CONTENT_FLOW_END}" nowrap="nowrap">{L_LAST_ACTIVE}{L_COLON} </td> + <td width="100%"><b class="gen">{LAST_ACTIVE}</b></td> </tr> <!-- IF S_WARNINGS --> <tr> @@ -105,6 +105,7 @@ <td class="cat" align="center"><h4>{L_CONTACT_USER}</h4></td> <td class="cat" align="center"><h4>{L_ABOUT_USER}</h4></td> </tr> + <!-- EVENT memberlist_view_contact_before --> <tr> <td class="row1"> <table width="100%" cellspacing="1" cellpadding="2" border="0"> @@ -119,25 +120,21 @@ </tr> <!-- ENDIF --> <tr> - <td class="gen" nowrap="nowrap" align="{S_CONTENT_FLOW_END}">{L_MSNM}{L_COLON} </td> - <td><!-- IF U_MSN --><a href="{U_MSN}" onclick="popup(this.href, 550, 320); return false" class="imageset">{MSN_IMG}</a><!-- ELSEIF USER_MSN -->{USER_MSN}<!-- ENDIF --></td> - </tr> - <tr> - <td class="gen" nowrap="nowrap" align="{S_CONTENT_FLOW_END}">{L_YIM}{L_COLON} </td> - <td><!-- IF U_YIM --><a href="{U_YIM}" onclick="popup(this.href, 780, 550); return false" class="imageset">{YIM_IMG}</a><!-- ELSEIF USER_YIM -->{USER_YIM}<!-- ENDIF --></td> - </tr> - <tr> - <td class="gen" nowrap="nowrap" align="{S_CONTENT_FLOW_END}">{L_AIM}{L_COLON} </td> - <td><!-- IF U_AIM --><a href="{U_AIM}" onclick="popup(this.href, 550, 320); return false" class="imageset">{AIM_IMG}</a><!-- ELSEIF USER_AIM -->{USER_AIM}<!-- ENDIF --></td> - </tr> - <tr> - <td class="gen" nowrap="nowrap" align="{S_CONTENT_FLOW_END}">{L_ICQ}{L_COLON} </td> - <td><!-- IF U_ICQ --><a href="{U_ICQ}" onclick="popup(this.href, 550, 320); return false" class="imageset">{ICQ_IMG}</a><!-- ELSEIF USER_ICQ -->{USER_ICQ}<!-- ENDIF --></td> - </tr> - <tr> <td class="gen" nowrap="nowrap" align="{S_CONTENT_FLOW_END}">{L_JABBER}{L_COLON} </td> <td><!-- IF U_JABBER --><a href="{U_JABBER}" onclick="popup(this.href, 550, 320); return false" class="imageset">{JABBER_IMG}</a><!-- ELSEIF USER_JABBER -->{USER_JABBER_IMG}<!-- ENDIF --></td> </tr> + <!-- BEGIN custom_fields --> + <!-- IF custom_fields.S_PROFILE_CONTACT --> + <tr> + <td class="gen" align="{S_CONTENT_FLOW_END}" nowrap="nowrap">{custom_fields.PROFILE_FIELD_NAME}{L_COLON} </td> + <!-- IF custom_fields.PROFILE_FIELD_CONTACT --> + <td><a href="{custom_fields.PROFILE_FIELD_CONTACT}"><span class="imageset {custom_fields.PROFILE_FIELD_IDENT}-icon">{custom_fields.PROFILE_FIELD_DESC}</span></a></td> + <!-- ELSE --> + <td><b class="genmed">{custom_fields.PROFILE_FIELD_VALUE}</b></td> + <!-- ENDIF --> + </tr> + <!-- ENDIF --> + <!-- END custom_fields --> </table> </td> <td class="row1"> @@ -146,28 +143,12 @@ <td class="gen" align="{S_CONTENT_FLOW_END}" nowrap="nowrap">{L_USERGROUPS}{L_COLON} </td> <td><select name="g">{S_GROUP_OPTIONS}</select> <input class="btnlite" type="submit" name="submit" value="{L_GO}" /></td> </tr> - <tr> - <td class="gen" align="{S_CONTENT_FLOW_END}" nowrap="nowrap">{L_LOCATION}{L_COLON} </td> - <td><!-- IF LOCATION --><b class="genmed">{LOCATION}</b><!-- ENDIF --></td> - </tr> <!-- IF AGE !== '' --> <tr> <td class="gen" align="{S_CONTENT_FLOW_END}" nowrap="nowrap">{L_AGE}{L_COLON} </td> <td><b class="genmed">{AGE}</b></td> </tr> <!-- ENDIF --> - <tr> - <td class="gen" align="{S_CONTENT_FLOW_END}" nowrap="nowrap">{L_OCCUPATION}{L_COLON} </td> - <td><!-- IF OCCUPATION --><b class="genmed">{OCCUPATION}</b><!-- ENDIF --></td> - </tr> - <tr> - <td class="gen" align="{S_CONTENT_FLOW_END}" nowrap="nowrap">{L_INTERESTS}{L_COLON} </td> - <td><!-- IF INTERESTS --><b class="genmed">{INTERESTS}</b><!-- ENDIF --></td> - </tr> - <tr> - <td class="gen" align="{S_CONTENT_FLOW_END}" nowrap="nowrap">{L_WEBSITE}{L_COLON} </td> - <td><!-- IF U_WWW --><b><a class="genmed" href="{U_WWW}">{U_WWW}</a></b><!-- ENDIF --></td> - </tr> <!-- IF S_PROFILE_FIELD1 --> <!-- Use a construct like this to include admin defined profile fields. Replace FIELD1 with the name of your field. --> <tr> @@ -176,14 +157,17 @@ </tr> <!-- ENDIF --> <!-- BEGIN custom_fields --> + <!-- IF not custom_fields.S_PROFILE_CONTACT --> <tr> <td class="gen" align="{S_CONTENT_FLOW_END}" nowrap="nowrap">{custom_fields.PROFILE_FIELD_NAME}{L_COLON} </td> <td><b class="genmed">{custom_fields.PROFILE_FIELD_VALUE}</b></td> </tr> + <!-- ENDIF --> <!-- END custom_fields --> </table> </td> </tr> + <!-- EVENT memberlist_view_contact_after --> <!-- IF SIGNATURE --> <tr> <td class="cat" colspan="2" align="center"><h4>{L_SIGNATURE}</h4></td> @@ -196,6 +180,8 @@ </form> + <!-- EVENT memberlist_view_content_append --> + </div> <br clear="all" /> diff --git a/phpBB/styles/subsilver2/template/overall_footer.html b/phpBB/styles/subsilver2/template/overall_footer.html index 348db5d309..200401eeda 100644 --- a/phpBB/styles/subsilver2/template/overall_footer.html +++ b/phpBB/styles/subsilver2/template/overall_footer.html @@ -1,6 +1,10 @@ + <!-- EVENT overall_footer_content_after --> + <!-- IF not S_IS_BOT -->{RUN_CRON_TASK}<!-- ENDIF --> </div> +<!-- EVENT overall_footer_page_body_after --> + <div id="wrapfooter"> <!-- IF U_ACP --><span class="gensmall">[ <a href="{U_ACP}">{L_ACP}</a> ]</span><br /><br /><!-- ENDIF --> <span class="copyright"> @@ -12,7 +16,7 @@ </div> <script type="text/javascript" src="{T_JQUERY_LINK}"></script> -<!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> +<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> <script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script> <!-- EVENT overall_footer_after --> diff --git a/phpBB/styles/subsilver2/template/overall_header.html b/phpBB/styles/subsilver2/template/overall_header.html index 7bfb85017a..0d3e727ecd 100644 --- a/phpBB/styles/subsilver2/template/overall_header.html +++ b/phpBB/styles/subsilver2/template/overall_header.html @@ -36,7 +36,7 @@ function popup(url, width, height, name) function jumpto() { - var page = prompt('{LA_JUMP_PAGE}{L_COLON}', '{ON_PAGE}'); + var page = prompt('{LA_JUMP_PAGE}{L_COLON}', '{CURRENT_PAGE}'); var per_page = '{PER_PAGE}'; var base_url = '{BASE_URL|e('js')}'; @@ -132,7 +132,9 @@ function marklist(id, name, state) {$STYLESHEETS} </head> -<body class="{S_CONTENT_DIRECTION}"> +<body class="{S_CONTENT_DIRECTION} {BODY_CLASS}"> + +<!-- EVENT overall_header_body_before --> <a name="top"></a> @@ -152,7 +154,7 @@ function marklist(id, name, state) <tr> <td class="genmed"> <!-- IF S_NOTIFICATIONS_DISPLAY and not S_IS_BOT and S_USER_LOGGED_IN --> - [ <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button">{NOTIFICATIONS_COUNT}</a> ] + <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button"><img src="{T_THEME_PATH}/images/icon_mini_notification.gif" width="12" height="13" alt="*" /> {L_NOTIFICATIONS} [<strong>{NOTIFICATIONS_COUNT}</strong>]</a> <div id="notification_list" class="notification_list"> <div class="row1 header"> {L_NOTIFICATIONS} @@ -160,17 +162,13 @@ function marklist(id, name, state) </div> <div class="notification_scroll"> - <table class="tablebg" width="310px" cellspacing="1"> + <table class="tablebg" width="310" cellspacing="1"> <!-- BEGIN notifications --> <tr class="row<!-- IF notifications.UNREAD -->2<!-- ELSE -->1<!-- ENDIF -->"> - <!-- IF notifications.AVATAR --> - <td width="50px"> - {notifications.AVATAR} - </td> - <td valign="top"> - <!-- ELSE --> - <td colspan="2" valign="top"> - <!-- ENDIF --> + <td width="50"> + <!-- IF notifications.AVATAR -->{notifications.AVATAR}<!-- ELSE --><img src="{T_THEME_PATH}/images/no_avatar.gif" alt="" /><!-- ENDIF --> + </td> + <td valign="top"> <div class="notification_title"> <!-- IF notifications.URL --><a href="<!-- IF notifications.UNREAD -->{notifications.U_MARK_READ}<!-- ELSE -->{notifications.URL}<!-- ENDIF -->"><!-- ENDIF --> {notifications.FORMATTED_TITLE} @@ -191,23 +189,25 @@ function marklist(id, name, state) </div> </div> <!-- ENDIF --> - <!-- IF not S_IS_BOT --><a href="{U_LOGIN_LOGOUT}"><img src="{T_THEME_PATH}/images/icon_mini_login.gif" width="12" height="13" alt="*" /> {L_LOGIN_LOGOUT}</a> <!-- ENDIF --> - <!-- IF U_RESTORE_PERMISSIONS --> <a href="{U_RESTORE_PERMISSIONS}"><img src="{T_THEME_PATH}/images/icon_mini_login.gif" width="12" height="13" alt="*" /> {L_RESTORE_PERMISSIONS}</a><!-- ENDIF --> - <!-- IF S_BOARD_DISABLED and S_USER_LOGGED_IN --> <span class="error">{L_BOARD_DISABLED}</span><!-- ENDIF --> <!-- IF not S_IS_BOT --> <!-- IF S_USER_LOGGED_IN --> - <!-- IF S_DISPLAY_PM --> <a href="{U_PRIVATEMSGS}"><img src="{T_THEME_PATH}/images/icon_mini_message.gif" width="12" height="13" alt="*" /> {PRIVATE_MESSAGE_INFO}<!-- IF PRIVATE_MESSAGE_INFO_UNREAD -->, {PRIVATE_MESSAGE_INFO_UNREAD}<!-- ENDIF --></a><!-- ENDIF --> + <!-- IF S_DISPLAY_PM --> <a href="{U_PRIVATEMSGS}"><img src="{T_THEME_PATH}/images/icon_mini_message.gif" width="12" height="13" alt="*" /> {L_PRIVATE_MESSAGES} [<strong>{PRIVATE_MESSAGE_COUNT}</strong>]</a><!-- ENDIF --> <!-- ELSEIF S_REGISTER_ENABLED and not (S_SHOW_COPPA or S_REGISTRATION) --> <a href="{U_REGISTER}"><img src="{T_THEME_PATH}/images/icon_mini_register.gif" width="12" height="13" alt="*" /> {L_REGISTER}</a> <!-- ENDIF --> <!-- ENDIF --> + <!-- IF not S_IS_BOT --> <a href="{U_LOGIN_LOGOUT}"><img src="{T_THEME_PATH}/images/icon_mini_login.gif" width="12" height="13" alt="*" /> {L_LOGIN_LOGOUT}</a> <!-- ENDIF --> + <!-- IF U_RESTORE_PERMISSIONS --> <a href="{U_RESTORE_PERMISSIONS}"><img src="{T_THEME_PATH}/images/icon_mini_login.gif" width="12" height="13" alt="*" /> {L_RESTORE_PERMISSIONS}</a><!-- ENDIF --> + <!-- IF S_BOARD_DISABLED and S_USER_LOGGED_IN --> <span class="error">{L_BOARD_DISABLED}</span><!-- ENDIF --> </td> <td class="genmed" align="{S_CONTENT_FLOW_END}"> + <!-- EVENT overall_header_navigation_prepend --> <a href="{U_FAQ}"><img src="{T_THEME_PATH}/images/icon_mini_faq.gif" width="12" height="13" alt="*" /> {L_FAQ}</a> <!-- IF S_DISPLAY_SEARCH --> <a href="{U_SEARCH}"><img src="{T_THEME_PATH}/images/icon_mini_search.gif" width="12" height="13" alt="*" /> {L_SEARCH}</a><!-- ENDIF --> <!-- IF not S_IS_BOT --> <!-- IF S_DISPLAY_MEMBERLIST --> <a href="{U_MEMBERLIST}"><img src="{T_THEME_PATH}/images/icon_mini_members.gif" width="12" height="13" alt="*" /> {L_MEMBERLIST}</a><!-- ENDIF --> <!-- IF S_USER_LOGGED_IN --> <a href="{U_PROFILE}"><img src="{T_THEME_PATH}/images/icon_mini_profile.gif" width="12" height="13" alt="*" /> {L_PROFILE}</a><!-- ENDIF --> <!-- ENDIF --> + <!-- EVENT overall_header_navigation_append --> </td> </tr> </table> @@ -224,6 +224,8 @@ function marklist(id, name, state) </div> +<!-- EVENT overall_header_page_body_before --> + <div id="wrapcentre"> <!-- IF S_DISPLAY_SEARCH --> @@ -242,3 +244,4 @@ function marklist(id, name, state) <!-- DEFINE $S_MICRODATA = 0 --> <br /> + <!-- EVENT overall_header_content_before --> diff --git a/phpBB/styles/subsilver2/template/pagination.html b/phpBB/styles/subsilver2/template/pagination.html index a2e023ac22..550b28d305 100644 --- a/phpBB/styles/subsilver2/template/pagination.html +++ b/phpBB/styles/subsilver2/template/pagination.html @@ -1,5 +1,5 @@ <!-- IF .pagination --> - <b><a href="#" onclick="jumpto(); return false;" title="{L_JUMP_TO_PAGE}">{L_GOTO_PAGE}</a> + <!-- IF BASE_URL --><b><a href="#" onclick="jumpto(); return false;" title="{L_JUMP_TO_PAGE}">{L_GOTO_PAGE}</a></b><!-- ENDIF --> <!-- BEGIN pagination --> <!-- IF pagination.S_IS_PREV --><a href="{pagination.PAGE_URL}">{L_PREVIOUS}</a> <!-- ELSEIF pagination.S_IS_CURRENT --><strong>{pagination.PAGE_NUMBER}</strong> diff --git a/phpBB/styles/subsilver2/template/posting_body.html b/phpBB/styles/subsilver2/template/posting_body.html index 635b05aaa0..321e4227ee 100644 --- a/phpBB/styles/subsilver2/template/posting_body.html +++ b/phpBB/styles/subsilver2/template/posting_body.html @@ -5,7 +5,7 @@ <!-- ENDIF --> <!-- IF S_FORUM_RULES --> - <div class="forumrules"> + <div class="forumrules<!-- IF U_FORUM_RULES --> rules-link<!-- ENDIF -->"> <!-- IF U_FORUM_RULES --> <h3>{L_FORUM_RULES}</h3><br /> <a href="{U_FORUM_RULES}"><b>{L_FORUM_RULES_LINK}</b></a> @@ -25,8 +25,8 @@ <!-- IF MODERATORS --> <p class="moderators">{L_MODERATORS}{L_COLON} {MODERATORS}</p> <!-- ENDIF --> - <!-- IF U_MCP --> - <p class="linkmcp">[ <a href="{U_MCP}">{L_MCP}</a> ]</p> + <!-- IF U_MCP or U_ACP --> + <p class="linkmcp">[ <!-- IF U_ACP --><a href="{U_ACP}">{L_ACP}</a><!-- IF U_MCP --> | <!-- ENDIF --><!-- ENDIF --><!-- IF U_MCP --><a href="{U_MCP}">{L_MCP}</a><!-- ENDIF --> ]</p> <!-- ENDIF --> </div> @@ -163,11 +163,12 @@ </tr> <!-- ENDIF --> <!-- ENDIF --> - +<!-- EVENT posting_editor_subject_before --> <tr> <td class="row1" width="22%"><b class="genmed">{L_SUBJECT}{L_COLON}</b></td> <td class="row2" width="78%"><input class="post" style="width:450px" type="text" name="subject" size="45" maxlength="<!-- IF S_NEW_MESSAGE -->120<!-- ELSE -->124<!-- ENDIF -->" tabindex="2" value="{SUBJECT}" /></td> </tr> +<!-- EVENT posting_editor_subject_after --> <tr> <td class="row1" valign="top"><b class="genmed">{L_MESSAGE_BODY}{L_COLON}</b><br /><span class="gensmall">{L_MESSAGE_BODY_EXPLAIN} </span><br /><br /> <!-- IF S_SMILIES_ALLOWED --> @@ -202,18 +203,15 @@ <table width="100%" cellspacing="0" cellpadding="0" border="0"> <!-- INCLUDE posting_buttons.html --> + <!-- EVENT posting_editor_message_before --> <tr> <td valign="top" style="width: 100%;"><textarea name="message" rows="15" cols="76" tabindex="3" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();" style="width: 700px; height: 270px; min-width: 98%; max-width: 98%;">{MESSAGE}</textarea></td> <!-- IF S_BBCODE_ALLOWED --> - <td width="80" align="center" valign="top"> - <script type="text/javascript"> - // <![CDATA[ - colorPalette('v', 7, 6) - // ]]> - </script> + <td width="80" align="center" valign="top" id="color_palette_placeholder" data-orientation="v" data-width="11" data-height="10" data-bbcode="true"> </td> <!-- ENDIF --> </tr> + <!-- EVENT posting_editor_message_after --> </table> </td> </tr> diff --git a/phpBB/styles/subsilver2/template/posting_buttons.html b/phpBB/styles/subsilver2/template/posting_buttons.html index 1a7093e1be..d1c0f79a16 100644 --- a/phpBB/styles/subsilver2/template/posting_buttons.html +++ b/phpBB/styles/subsilver2/template/posting_buttons.html @@ -27,35 +27,37 @@ d: '{LA_BBCODE_D_HELP}', tip: '{L_STYLES_TIP}' <!-- BEGIN custom_tags --> - ,cb_{custom_tags.BBCODE_ID}{L_COLON} '{custom_tags.A_BBCODE_HELPLINE}' + ,cb_{custom_tags.BBCODE_ID}: '{custom_tags.A_BBCODE_HELPLINE}' <!-- END custom_tags --> } // ]]> </script> - <script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/editor.js"></script> + <!-- INCLUDEJS {T_ASSETS_PATH}/javascript/editor.js --> <!-- IF S_BBCODE_ALLOWED --> - <input type="button" class="btnbbcode" accesskey="b" name="addbbcode0" value=" B " style="font-weight:bold; width: 30px;" onclick="bbstyle(0)" onmouseover="helpline('b')" onmouseout="helpline('tip')" /> - <input type="button" class="btnbbcode" accesskey="i" name="addbbcode2" value=" i " style="font-style:italic; width: 30px;" onclick="bbstyle(2)" onmouseover="helpline('i')" onmouseout="helpline('tip')" /> - <input type="button" class="btnbbcode" accesskey="u" name="addbbcode4" value=" u " style="text-decoration: underline; width: 30px;" onclick="bbstyle(4)" onmouseover="helpline('u')" onmouseout="helpline('tip')" /> + <!-- EVENT posting_editor_buttons_before --> + <div id="core-bbcode-buttons"> + <input type="button" class="btnbbcode bbcode-b" accesskey="b" name="addbbcode0" value=" B " style="font-weight:bold; width: 30px;" onclick="bbstyle(0)" onmouseover="helpline('b')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode bbcode-i" accesskey="i" name="addbbcode2" value=" i " style="font-style:italic; width: 30px;" onclick="bbstyle(2)" onmouseover="helpline('i')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode bbcode-u" accesskey="u" name="addbbcode4" value=" u " style="text-decoration: underline; width: 30px;" onclick="bbstyle(4)" onmouseover="helpline('u')" onmouseout="helpline('tip')" /> <!-- IF S_BBCODE_QUOTE --> - <input type="button" class="btnbbcode" accesskey="q" name="addbbcode6" value="Quote" style="width: 50px" onclick="bbstyle(6)" onmouseover="helpline('q')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode bbcode-quote" accesskey="q" name="addbbcode6" value="Quote" style="width: 50px" onclick="bbstyle(6)" onmouseover="helpline('q')" onmouseout="helpline('tip')" /> <!-- ENDIF --> - <input type="button" class="btnbbcode" accesskey="c" name="addbbcode8" value="Code" style="width: 40px" onclick="bbstyle(8)" onmouseover="helpline('c')" onmouseout="helpline('tip')" /> - <input type="button" class="btnbbcode" accesskey="l" name="addbbcode10" value="List" style="width: 40px" onclick="bbstyle(10)" onmouseover="helpline('l')" onmouseout="helpline('tip')" /> - <input type="button" class="btnbbcode" accesskey="o" name="addbbcode12" value="List=" style="width: 40px" onclick="bbstyle(12)" onmouseover="helpline('o')" onmouseout="helpline('tip')" /> - <input type="button" class="btnbbcode" accesskey="y" name="addlistitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" onmouseover="helpline('e')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode bbcode-code" accesskey="c" name="addbbcode8" value="Code" style="width: 40px" onclick="bbstyle(8)" onmouseover="helpline('c')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode bbcode-list" accesskey="l" name="addbbcode10" value="List" style="width: 40px" onclick="bbstyle(10)" onmouseover="helpline('l')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode bbcode-list-" accesskey="o" name="addbbcode12" value="List=" style="width: 40px" onclick="bbstyle(12)" onmouseover="helpline('o')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode bbcode-asterisk" accesskey="y" name="addlistitem" value="[*]" style="width: 40px" onclick="bbstyle(-1)" onmouseover="helpline('e')" onmouseout="helpline('tip')" /> <!-- IF S_BBCODE_IMG --> - <input type="button" class="btnbbcode" accesskey="p" name="addbbcode14" value="Img" style="width: 40px" onclick="bbstyle(14)" onmouseover="helpline('p')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode bbcode-img" accesskey="p" name="addbbcode14" value="Img" style="width: 40px" onclick="bbstyle(14)" onmouseover="helpline('p')" onmouseout="helpline('tip')" /> <!-- ENDIF --> <!-- IF S_LINKS_ALLOWED --> - <input type="button" class="btnbbcode" accesskey="w" name="addbbcode16" value="URL" style="text-decoration: underline; width: 40px" onclick="bbstyle(16)" onmouseover="helpline('w')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode bbcode-url" accesskey="w" name="addbbcode16" value="URL" style="text-decoration: underline; width: 40px" onclick="bbstyle(16)" onmouseover="helpline('w')" onmouseout="helpline('tip')" /> <!-- ENDIF --> <!-- IF S_BBCODE_FLASH --> - <input type="button" class="btnbbcode" accesskey="d" name="addbbcode18" value="Flash" onclick="bbstyle(18)" onmouseover="helpline('d')" onmouseout="helpline('tip')" /> + <input type="button" class="btnbbcode bbcode-flash" accesskey="d" name="addbbcode18" value="Flash" onclick="bbstyle(18)" onmouseover="helpline('d')" onmouseout="helpline('tip')" /> <!-- ENDIF --> - <span class="genmed nowrap">{L_FONT_SIZE}{L_COLON} <select class="gensmall" name="addbbcode20" onchange="bbfontstyle('[size=' + this.form.addbbcode20.options[this.form.addbbcode20.selectedIndex].value + ']', '[/size]');this.form.addbbcode20.selectedIndex = 2;" onmouseover="helpline('f')" onmouseout="helpline('tip')"> + <span class="genmed nowrap">{L_FONT_SIZE}{L_COLON} <select class="gensmall bbcode-size" name="addbbcode20" onchange="bbfontstyle('[size=' + this.form.addbbcode20.options[this.form.addbbcode20.selectedIndex].value + ']', '[/size]');this.form.addbbcode20.selectedIndex = 2;" onmouseover="helpline('f')" onmouseout="helpline('tip')"> <option value="50">{L_FONT_TINY}</option> <option value="85">{L_FONT_SMALL}</option> <option value="100" selected="selected">{L_FONT_NORMAL}</option> @@ -66,15 +68,19 @@ <!-- ENDIF --> <!-- ENDIF --> </select></span> + </div> + <!-- EVENT posting_editor_buttons_after --> <!-- ENDIF --> </td> </tr> <!-- IF S_BBCODE_ALLOWED and .custom_tags --> <tr valign="middle" align="{S_CONTENT_FLOW_BEGIN}"> <td colspan="2"> + <div id="custom-bbcode-buttons"> <!-- BEGIN custom_tags --> - <input type="button" class="btnbbcode" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})"<!-- IF custom_tags.BBCODE_HELPLINE !== '' --> onmouseover="helpline('cb_{custom_tags.BBCODE_ID}')" onmouseout="helpline('tip')"<!-- ENDIF --> /> + <input type="button" class="btnbbcode bbcode-{custom_tags.BBCODE_TAG_CLEAN}" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})"<!-- IF custom_tags.BBCODE_HELPLINE !== '' --> onmouseover="helpline('cb_{custom_tags.BBCODE_ID}')" onmouseout="helpline('tip')"<!-- ENDIF --> /> <!-- END custom_tags --> + </div> </td> </tr> <!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/posting_smilies.html b/phpBB/styles/subsilver2/template/posting_smilies.html index d0ced9ff12..0be71098db 100644 --- a/phpBB/styles/subsilver2/template/posting_smilies.html +++ b/phpBB/styles/subsilver2/template/posting_smilies.html @@ -6,7 +6,7 @@ var text_name = opener.text_name; // ]]> </script> -<script type="text/javascript" src="{T_SUPER_TEMPLATE_PATH}/editor.js"></script> +<!-- INCLUDEJS {T_ASSETS_PATH}/javascript/editor.js --> <table width="100%" cellspacing="1" cellpadding="4" border="0"> <tr> diff --git a/phpBB/styles/subsilver2/template/profilefields/bool.html b/phpBB/styles/subsilver2/template/profilefields/bool.html new file mode 100644 index 0000000000..f57bd4e4da --- /dev/null +++ b/phpBB/styles/subsilver2/template/profilefields/bool.html @@ -0,0 +1,7 @@ +<!-- BEGIN bool --> + <!-- IF bool.FIELD_LENGTH eq 1 --> + <!-- BEGIN options --><input type="radio" class="radio" name="{bool.FIELD_IDENT}" value="{bool.options.OPTION_ID}"{bool.options.CHECKED} /><span class="genmed">{bool.options.VALUE}</span> <!-- END options --> + <!-- ELSE --> + <input type="checkbox" class="radio" name="{bool.FIELD_IDENT}" value="1"<!-- IF bool.FIELD_VALUE eq 1 --> checked="checked"<!-- ENDIF --> /> + <!-- ENDIF --> +<!-- END bool --> diff --git a/phpBB/styles/subsilver2/template/profilefields/date.html b/phpBB/styles/subsilver2/template/profilefields/date.html new file mode 100644 index 0000000000..e2da2463a5 --- /dev/null +++ b/phpBB/styles/subsilver2/template/profilefields/date.html @@ -0,0 +1,5 @@ +<!-- BEGIN date --> +<span class="genmed">{L_DAY}{L_COLON}</span> <select name="{date.FIELD_IDENT}_day">{date.S_DAY_OPTIONS}</select> +<span class="genmed">{L_MONTH}{L_COLON}</span> <select name="{date.FIELD_IDENT}_month">{date.S_MONTH_OPTIONS}</select> +<span class="genmed">{L_YEAR}{L_COLON}</span> <select name="{date.FIELD_IDENT}_year">{date.S_YEAR_OPTIONS}</select> +<!-- END date --> diff --git a/phpBB/styles/subsilver2/template/profilefields/dropdown.html b/phpBB/styles/subsilver2/template/profilefields/dropdown.html new file mode 100644 index 0000000000..16242da895 --- /dev/null +++ b/phpBB/styles/subsilver2/template/profilefields/dropdown.html @@ -0,0 +1,5 @@ +<!-- BEGIN dropdown --> +<select name="{dropdown.FIELD_IDENT}"> + <!-- BEGIN options --><option value="{dropdown.options.OPTION_ID}"{dropdown.options.SELECTED}>{dropdown.options.VALUE}</option><!-- END options --> +</select> +<!-- END dropdown --> diff --git a/phpBB/styles/subsilver2/template/profilefields/int.html b/phpBB/styles/subsilver2/template/profilefields/int.html new file mode 100644 index 0000000000..067921e320 --- /dev/null +++ b/phpBB/styles/subsilver2/template/profilefields/int.html @@ -0,0 +1,3 @@ +<!-- BEGIN int --> + <input type="number" min="{int.FIELD_MINLEN}" max="{int.FIELD_MAXLEN}" class="post" name="{int.FIELD_IDENT}" size="{int.FIELD_LENGTH}" value="{int.FIELD_VALUE}" /> +<!-- END int --> diff --git a/phpBB/styles/subsilver2/template/profilefields/string.html b/phpBB/styles/subsilver2/template/profilefields/string.html new file mode 100644 index 0000000000..5a98562e2a --- /dev/null +++ b/phpBB/styles/subsilver2/template/profilefields/string.html @@ -0,0 +1,3 @@ +<!-- BEGIN string --> + <input type="text" class="post" name="{string.FIELD_IDENT}" size="{string.FIELD_LENGTH}" maxlength="{string.FIELD_MAXLEN}" value="{string.FIELD_VALUE}" /> +<!-- END string --> diff --git a/phpBB/styles/subsilver2/template/profilefields/text.html b/phpBB/styles/subsilver2/template/profilefields/text.html new file mode 100644 index 0000000000..df2474ad3e --- /dev/null +++ b/phpBB/styles/subsilver2/template/profilefields/text.html @@ -0,0 +1,3 @@ +<!-- BEGIN text --> +<textarea name="{text.FIELD_IDENT}" rows="{text.FIELD_ROWS}" cols="{text.FIELD_COLS}">{text.FIELD_VALUE}</textarea> +<!-- END text --> diff --git a/phpBB/styles/subsilver2/template/profilefields/url.html b/phpBB/styles/subsilver2/template/profilefields/url.html new file mode 100644 index 0000000000..42805aa98d --- /dev/null +++ b/phpBB/styles/subsilver2/template/profilefields/url.html @@ -0,0 +1,3 @@ +<!-- BEGIN url --> + <input type="url" class="post" name="{url.FIELD_IDENT}" id="{url.FIELD_IDENT}" size="{url.FIELD_LENGTH}" maxlength="{url.FIELD_MAXLEN}" value="{url.FIELD_VALUE}" /> +<!-- END url --> diff --git a/phpBB/styles/subsilver2/template/quickreply_editor.html b/phpBB/styles/subsilver2/template/quickreply_editor.html index 72dc5506bf..5afc723f48 100644 --- a/phpBB/styles/subsilver2/template/quickreply_editor.html +++ b/phpBB/styles/subsilver2/template/quickreply_editor.html @@ -1,5 +1,5 @@ <form method="post" action="{U_QR_ACTION}"> - +<!-- EVENT quickreply_editor_panel_before --> <table class="tablebg" width="100%" cellspacing="1"> <tr> <th align="center" colspan="2">{L_QUICKREPLY}</th> @@ -8,10 +8,12 @@ <td class="row1" width="22%"><b class="genmed">{L_SUBJECT}{L_COLON}</b></td> <td class="row2" width="78%"><input class="post" style="width:450px" type="text" name="subject" size="45" maxlength="124" tabindex="2" value="{SUBJECT}" /></td> </tr> + <!-- EVENT quickreply_editor_message_before --> <tr> <td class="row1" width="22%"><b class="genmed">{L_MESSAGE}{L_COLON}</b></td> <td class="row2" valign="top" align="left" width="78%"><textarea name="message" rows="7" cols="76" tabindex="3" style="width: 700px; height: 130px; min-width: 98%; max-width: 98%;"></textarea> </td> </tr> + <!-- EVENT quickreply_editor_message_after --> <tr> <td class="cat" colspan="2" align="center"> <input class="btnlite" type="submit" accesskey="f" tabindex="6" name="preview" value="{L_FULL_EDITOR}" /> @@ -22,6 +24,6 @@ </td> </tr> </table> - +<!-- EVENT quickreply_editor_panel_after --> </form> <br clear="all" /> diff --git a/phpBB/styles/subsilver2/template/search_results.html b/phpBB/styles/subsilver2/template/search_results.html index 19ba0b196a..092779055d 100644 --- a/phpBB/styles/subsilver2/template/search_results.html +++ b/phpBB/styles/subsilver2/template/search_results.html @@ -36,7 +36,7 @@ <td class="row1"> <!-- EVENT topiclist_row_prepend --> <!-- IF searchresults.S_UNREAD_TOPIC --><a href="{searchresults.U_NEWEST_POST}" class="imageset">{NEWEST_POST_IMG}</a><!-- ENDIF --> - {searchresults.ATTACH_ICON_IMG} <a href="{searchresults.U_VIEW_TOPIC}" class="topictitle">{searchresults.TOPIC_TITLE}</a> + {searchresults.ATTACH_ICON_IMG} <a href="<!-- IF not S_IS_BOT and searchresults.S_UNREAD_TOPIC -->{searchresults.U_NEWEST_POST}<!-- ELSE -->{searchresults.U_VIEW_TOPIC}<!-- ENDIF -->" class="topictitle">{searchresults.TOPIC_TITLE}</a> <!-- IF searchresults.S_TOPIC_UNAPPROVED or searchresults.S_POSTS_UNAPPROVED --> <a href="{searchresults.U_MCP_QUEUE}" class="imageset">{searchresults.UNAPPROVED_IMG}</a> <!-- ENDIF --> diff --git a/phpBB/styles/subsilver2/template/simple_footer.html b/phpBB/styles/subsilver2/template/simple_footer.html index 48d3d934f8..6a9c3096bc 100644 --- a/phpBB/styles/subsilver2/template/simple_footer.html +++ b/phpBB/styles/subsilver2/template/simple_footer.html @@ -6,7 +6,7 @@ </div> <script type="text/javascript" src="{T_JQUERY_LINK}"></script> -<!-- IF S_JQUERY_FALLBACK --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> +<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF --> <!-- EVENT simple_footer_after --> diff --git a/phpBB/styles/subsilver2/template/simple_header.html b/phpBB/styles/subsilver2/template/simple_header.html index 43ca16ed87..37a33415e9 100644 --- a/phpBB/styles/subsilver2/template/simple_header.html +++ b/phpBB/styles/subsilver2/template/simple_header.html @@ -11,6 +11,7 @@ <link rel="stylesheet" href="{T_STYLESHEET_LANG_LINK}" type="text/css" /> </head> -<body class="{S_CONTENT_DIRECTION}"> +<body class="{S_CONTENT_DIRECTION} {BODY_CLASS}"> +<!-- EVENT simple_header_body_before --> <a name="top"></a> <div id="wrapcentre"> diff --git a/phpBB/styles/subsilver2/template/ucp_auth_link_oauth.html b/phpBB/styles/subsilver2/template/ucp_auth_link_oauth.html index 56a4c89125..80564d207b 100644 --- a/phpBB/styles/subsilver2/template/ucp_auth_link_oauth.html +++ b/phpBB/styles/subsilver2/template/ucp_auth_link_oauth.html @@ -23,7 +23,7 @@ <tr> <td class="row1"><input type="submit" name="submit" tabindex="6" value="{L_UCP_AUTH_LINK_LINK}" class="button1" /></td> </tr> - <!-- ENDIF--> + <!-- ENDIF --> </table> {oauth.HIDDEN_FIELDS} {S_HIDDEN_FIELDS} diff --git a/phpBB/styles/subsilver2/template/ucp_groups_manage.html b/phpBB/styles/subsilver2/template/ucp_groups_manage.html index b8e7e29481..3099fcb1d8 100644 --- a/phpBB/styles/subsilver2/template/ucp_groups_manage.html +++ b/phpBB/styles/subsilver2/template/ucp_groups_manage.html @@ -49,7 +49,11 @@ </tr> <tr> <td class="row1" width="35%"><label for="group_colour">{L_GROUP_COLOR}{L_COLON}</label><br /><span>{L_GROUP_COLOR_EXPLAIN}</span></td> - <td class="row2"><input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="6" maxlength="6" /> <span>[ <a href="{U_SWATCH}" onclick="popup(this.href, 636, 150, '_swatch'); return false;">{L_COLOUR_SWATCH}</a> ]</span></td> + <td class="row2"> + <input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="6" maxlength="6" /> + <span>[ <a href="#" id="color_palette_toggle">{L_COLOUR_SWATCH}</a> ]</span> + <div id="color_palette_placeholder" style="display: none;" data-orientation="h" data-height="12" data-width="15" data-target="#group_colour"></div> + </td> </tr> <tr> <td class="row1" width="35%"><label for="group_rank">{L_GROUP_RANK}{L_COLON}</label></td> @@ -157,7 +161,7 @@ <!-- IF .pagination --> <!-- INCLUDE pagination.html --> <!-- ELSE --> - {S_ON_PAGE} + {PAGE_NUMBER} <!-- ENDIF --> </div> diff --git a/phpBB/styles/subsilver2/template/ucp_main_bookmarks.html b/phpBB/styles/subsilver2/template/ucp_main_bookmarks.html index e91417503f..a8c6b4a9a8 100644 --- a/phpBB/styles/subsilver2/template/ucp_main_bookmarks.html +++ b/phpBB/styles/subsilver2/template/ucp_main_bookmarks.html @@ -41,7 +41,7 @@ <td class="postdetails" style="padding: 4px" width="100%" colspan="2">{L_DELETED_TOPIC}</td> <!-- ELSE --> <td style="padding: 4px;" width="100%" valign="top"> - <p class="topictitle"><!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF -->{topicrow.ATTACH_ICON_IMG} <a href="{topicrow.U_VIEW_TOPIC}">{topicrow.TOPIC_TITLE}</a></p> + <p class="topictitle"><!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF -->{topicrow.ATTACH_ICON_IMG} <a href="<!-- IF topicrow.S_UNREAD_TOPIC -->{topicrow.U_NEWEST_POST}<!-- ELSE -->{topicrow.U_VIEW_TOPIC}<!-- ENDIF -->">{topicrow.TOPIC_TITLE}</a></p> <!-- IF topicrow.S_GLOBAL_TOPIC --><span class="gensmall">{L_GLOBAL_ANNOUNCEMENT}</span><!-- ELSE --><span class="gensmall"><b>{L_FORUM}{L_COLON} </b><a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a></span><!-- ENDIF --> <!-- IF .topicrow.pagination --> <p class="gensmall"> [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}{L_COLON} diff --git a/phpBB/styles/subsilver2/template/ucp_main_drafts.html b/phpBB/styles/subsilver2/template/ucp_main_drafts.html index 8e18e9cabf..d63d678250 100644 --- a/phpBB/styles/subsilver2/template/ucp_main_drafts.html +++ b/phpBB/styles/subsilver2/template/ucp_main_drafts.html @@ -75,12 +75,7 @@ <td colspan="9"> <table cellspacing="0" cellpadding="0" border="0" width="100%"> <tr> - <td align="{S_CONTENT_FLOW_BEGIN}"> - <script type="text/javascript"> - // <![CDATA[ - colorPalette('h', 6, 5) - // ]]> - </script> + <td align="{S_CONTENT_FLOW_BEGIN}" id="color_palette_placeholder" data-orientation="h" data-width="11" data-height="10" data-bbcode="true"> </td> </tr> </table> diff --git a/phpBB/styles/subsilver2/template/ucp_main_front.html b/phpBB/styles/subsilver2/template/ucp_main_front.html index 5dea2b4f03..bc26266bef 100644 --- a/phpBB/styles/subsilver2/template/ucp_main_front.html +++ b/phpBB/styles/subsilver2/template/ucp_main_front.html @@ -16,7 +16,7 @@ <!-- IF topicrow.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> <td class="row1" width="25" align="center">{topicrow.TOPIC_FOLDER_IMG}</td> <td class="row1" width="100%"> - <p class="topictitle"><!-- IF topicrow.S_UNREAD --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF -->{topicrow.ATTACH_ICON_IMG} <a href="{topicrow.U_VIEW_TOPIC}">{topicrow.TOPIC_TITLE}</a></p><p class="gensmall">{topicrow.GOTO_PAGE}</p> + <p class="topictitle"><!-- IF topicrow.S_UNREAD --><a href="{topicrow.U_NEWEST_POST}">{NEWEST_POST_IMG}</a> <!-- ENDIF -->{topicrow.ATTACH_ICON_IMG} <a href="<!-- IF topicrow.S_UNREAD -->{topicrow.U_NEWEST_POST}<!-- ELSE -->{topicrow.U_VIEW_TOPIC}<!-- ENDIF -->">{topicrow.TOPIC_TITLE}</a></p><p class="gensmall">{topicrow.GOTO_PAGE}</p> </td> <td class="row1" width="120" align="center" nowrap="nowrap"> <p class="topicdetails">{topicrow.LAST_POST_TIME}</p> diff --git a/phpBB/styles/subsilver2/template/ucp_main_subscribed.html b/phpBB/styles/subsilver2/template/ucp_main_subscribed.html index 45094abe5f..9de44dd9ed 100644 --- a/phpBB/styles/subsilver2/template/ucp_main_subscribed.html +++ b/phpBB/styles/subsilver2/template/ucp_main_subscribed.html @@ -50,7 +50,7 @@ <!-- IF topicrow.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> <td style="padding: 4px;" width="20" align="center" valign="middle">{topicrow.TOPIC_FOLDER_IMG}</td> <td style="padding: 4px;" width="100%" valign="top"> - <p class="topictitle"><!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}" class="imageset">{NEWEST_POST_IMG}</a> <!-- ENDIF -->{topicrow.ATTACH_ICON_IMG} <a href="{topicrow.U_VIEW_TOPIC}">{topicrow.TOPIC_TITLE}</a></p> + <p class="topictitle"><!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}" class="imageset">{NEWEST_POST_IMG}</a> <!-- ENDIF -->{topicrow.ATTACH_ICON_IMG} <a href="<!-- IF topicrow.S_UNREAD_TOPIC -->{topicrow.U_NEWEST_POST}<!-- ELSE -->{topicrow.U_VIEW_TOPIC}<!-- ENDIF -->">{topicrow.TOPIC_TITLE}</a></p> <!-- IF topicrow.S_GLOBAL_TOPIC --><span class="gensmall">{L_GLOBAL_ANNOUNCEMENT}</span><!-- ELSE --><span class="gensmall"><b>{L_FORUM}{L_COLON} </b><a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a></span><!-- ENDIF --> <!-- IF .topicrow.pagination --> <p class="gensmall"> [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}{L_COLON} diff --git a/phpBB/styles/subsilver2/template/ucp_notifications.html b/phpBB/styles/subsilver2/template/ucp_notifications.html index 4a1630786a..64e21ec4a6 100644 --- a/phpBB/styles/subsilver2/template/ucp_notifications.html +++ b/phpBB/styles/subsilver2/template/ucp_notifications.html @@ -57,7 +57,7 @@ <table width="100%" cellspacing="1"> <tr> <td class="nav" valign="middle" nowrap="nowrap"> {PAGE_NUMBER}</td> - <td class="gensmall" nowrap="nowrap" width="100%"> [ <b>{TOTAL_COUNT}</b> ] </td> + <td class="gensmall" nowrap="nowrap" width="100%"> {L_NOTIFICATIONS} [ <b>{TOTAL_COUNT}</b> ] </td> </tr> </table> <!-- ENDIF --> @@ -86,19 +86,15 @@ </tr> <!-- BEGIN notification_list --> <tr class="row<!-- IF notification_list.UNREAD -->3<!-- ELSEIF notification_list.S_ROW_COUNT is even -->1<!-- ELSE -->2<!-- ENDIF -->"> - <!-- IF notification_list.AVATAR --> - <td width="50px"> - {notification_list.AVATAR} - </td> - <td valign="top"> - <!-- ELSE --> - <td colspan="2" valign="top" height="50px"> - <!-- ENDIF --> + <td width="50"> + <!-- IF notification_list.AVATAR -->{notification_list.AVATAR}<!-- ELSE --><img src="{T_THEME_PATH}/images/no_avatar.gif" alt="" /><!-- ENDIF --> + </td> + <td valign="top"> <span class="gen"> <!-- IF notification_list.URL --><a href="<!-- IF notification_list.UNREAD -->{notification_list.U_MARK_READ}<!-- ELSE -->{notification_list.URL}<!-- ENDIF -->"><!-- ENDIF --> <strong>{notification_list.FORMATTED_TITLE}</strong> <!-- IF notification_list.URL --></a><!-- ENDIF --><br /> - » {notification_list.TIME} + {notification_list.TIME} </span> </td> <td align="center"> @@ -135,7 +131,7 @@ <!-- ENDIF --> <!-- IF .notifications --> -<div class="gensmall" style="float: {S_CONTENT_FLOW_END}; padding-top: 2px;"><b><a href="#" onclick="$('#ucp input:checkbox').attr('checked', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="$('#ucp input:checkbox').attr('checked', false); return false;">{L_UNMARK_ALL}</a></b></div> +<div class="gensmall" style="float: {S_CONTENT_FLOW_END}; padding-top: 2px;"><b><a href="#" onclick="$('#ucp input:checkbox').prop('checked', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="$('#ucp input:checkbox').prop('checked', false); return false;">{L_UNMARK_ALL}</a></b></div> <!-- ENDIF --> </form> diff --git a/phpBB/styles/subsilver2/template/ucp_pm_popup.html b/phpBB/styles/subsilver2/template/ucp_pm_popup.html deleted file mode 100644 index b7032c6c30..0000000000 --- a/phpBB/styles/subsilver2/template/ucp_pm_popup.html +++ /dev/null @@ -1,37 +0,0 @@ -<!-- INCLUDE simple_header.html --> - -<script type="text/javascript"> -// <![CDATA[ -/** -* Jump to inbox -*/ -function jump_to_inbox(url) -{ - opener.document.location.href = url.replace(/&/g, '&'); - window.close(); -} -// ]]> -</script> - -<table width="100%" border="0" cellspacing="0" cellpadding="10"> -<tr> - <td> - <table width="100%" border="0" cellspacing="1" cellpadding="4" class="tablebg"> - <tr class="row1"> - <td valign="top" align="center"> - <br /><span class="gen"> - <!-- IF S_NOT_LOGGED_IN --> - {L_LOGIN_CHECK_PM} - <!-- ELSE --> - {MESSAGE}<br /><br />{CLICK_TO_VIEW} - <!-- ENDIF --> - </span> - <br /><br /><span class="genmed"><a href="#" onclick="window.close(); return false;">{L_CLOSE_WINDOW}</a></span><br /><br /> - </td> - </tr> - </table> - </td> -</tr> -</table> - -<!-- INCLUDE simple_footer.html --> diff --git a/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html b/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html index fd0244a79d..abe6199d71 100644 --- a/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html +++ b/phpBB/styles/subsilver2/template/ucp_pm_viewmessage_print.html @@ -2,6 +2,7 @@ <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> <meta charset="utf-8"> +<meta name="robots" content="noindex" /> <title>{SITENAME} :: {PAGE_TITLE}</title> <style type="text/css"> @@ -53,7 +54,7 @@ hr.sep { } //--> </style> - +<!-- EVENT ucp_pm_viewmessage_print_head_append --> </head> <body> diff --git a/phpBB/styles/subsilver2/template/ucp_prefs_personal.html b/phpBB/styles/subsilver2/template/ucp_prefs_personal.html index cd5fc9a13f..93fcfac5b1 100644 --- a/phpBB/styles/subsilver2/template/ucp_prefs_personal.html +++ b/phpBB/styles/subsilver2/template/ucp_prefs_personal.html @@ -2,20 +2,6 @@ <script type="text/javascript"> // <![CDATA[ - /** - * Set display of page element - * s[-1,0,1] = hide,toggle display,show - */ - function dE(n,s) - { - var e = document.getElementById(n); - if (!s) - { - s = (e.style.display == '') ? -1 : 1; - } - e.style.display = (s == 1) ? 'block' : 'none'; - } - var default_dateformat = '{A_DEFAULT_DATEFORMAT}'; // ]]> </script> @@ -70,7 +56,7 @@ <tr> <td class="row1" width="50%"><b class="genmed">{L_BOARD_DATE_FORMAT}{L_COLON}</b><br /><span class="gensmall">{L_BOARD_DATE_FORMAT_EXPLAIN}</span></td> <td class="row2"> - <select name="dateoptions" id="dateoptions" onchange="if(this.value=='custom'){dE('custom_date',1);}else{dE('custom_date',-1);} if (this.value == 'custom') { document.getElementById('dateformat').value = default_dateformat; } else { document.getElementById('dateformat').value = this.value; }"> + <select name="dateoptions" id="dateoptions" onchange="if(this.value=='custom'){phpbb.toggleDisplay('custom_date',1);}else{phpbb.toggleDisplay('custom_date',-1);} if (this.value == 'custom') { document.getElementById('dateformat').value = default_dateformat; } else { document.getElementById('dateformat').value = this.value; }"> {S_DATEFORMAT_OPTIONS} </select> <div id="custom_date"<!-- IF not S_CUSTOM_DATEFORMAT --> style="display:none;"<!-- ENDIF -->><input type="text" name="dateformat" id="dateformat" value="{DATE_FORMAT}" maxlength="30" class="post" style="margin-top: 3px;" /></div> diff --git a/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html b/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html index 1dab9acb9c..3f63319b59 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html @@ -2,15 +2,12 @@ <table class="tablebg" width="100%" cellspacing="1"> <tr> - <th colspan="4" valign="middle">{L_TITLE}</th> + <th colspan="4">{L_TITLE}</th> </tr> -<!-- IF .errors --> + +<!-- IF ERROR --> <tr> - <td class="row3" colspan="2" align="center"><span class="gensmall error"> - <!-- BEGIN errors --> - {errors} <br /> - <!-- END errors --> - </td> + <td class="row3" colspan="4" align="center"><span class="genmed error">{ERROR}</span></td> </tr> <!-- ENDIF --> @@ -18,17 +15,17 @@ <td colspan="4" class="row1">{L_PROFILE_AUTOLOGIN_KEYS}</td> </tr> <tr> - <th>{L_MARK}</th> <th>{L_LOGIN_KEY}</th> <th>{L_IP}</th> <th>{L_LOGIN_TIME}</th> + <th>{L_MARK}</th> </tr> <!-- BEGIN sessions --> <!-- IF sessions.S_ROW_COUNT is even --><tr class="row1"><!-- ELSE --><tr class="row2"><!-- ENDIF --> - <td class="genmed" style="text-align: center"><input type="checkbox" name="keys[]" value="{sessions.KEY}" id="{sessions.KEY}"/></td> <td class="genmed"><label for="{sessions.KEY}">{sessions.KEY}</label></td> <td class="genmed" style="text-align: center">{sessions.IP}</td> <td class="genmed" style="text-align: center">{sessions.LOGIN_TIME}</td> + <td class="genmed" style="text-align: center"><input type="checkbox" name="keys[]" value="{sessions.KEY}" id="{sessions.KEY}"/></td> </tr> <!-- BEGINELSE --> <tr> @@ -38,12 +35,16 @@ <!-- IF .sessions --> <tr> - <td class="cat" colspan="4" align="center"> - {S_HIDDEN_FIELDS}<input class="btnmain" type="submit" name="submit" value="{L_DELETE}" /> + <td class="cat" colspan="4" align="{S_CONTENT_FLOW_END}"> + {S_HIDDEN_FIELDS}<input class="btnlite" type="submit" name="submit" value="{L_DELETE_MARKED}" /> {S_FORM_TOKEN} </td> </tr> <!-- ENDIF --> </table> +<!-- IF .sessions --> + <div class="gensmall" style="float: {S_CONTENT_FLOW_END}; padding-top: 2px;"><b><a href="#" onclick="marklist('ucp', 'keys', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('ucp', 'keys', false); return false;">{L_UNMARK_ALL}</a></b></div> +<!-- ENDIF --> + <!-- INCLUDE ucp_footer.html --> diff --git a/phpBB/styles/subsilver2/template/ucp_profile_profile_info.html b/phpBB/styles/subsilver2/template/ucp_profile_profile_info.html index 2df41fa29e..bf0aa8f899 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_profile_info.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_profile_info.html @@ -13,41 +13,9 @@ <td class="row1" colspan="2"><span class="gensmall">{L_PROFILE_INFO_NOTICE}</span></td> </tr> <tr> - <td class="row1" width="35%"><b class="genmed">{L_UCP_ICQ}{L_COLON} </b></td> - <td class="row2"><input class="post" type="text" name="icq" size="30" maxlength="15" value="{ICQ}" /></td> -</tr> -<tr> - <td class="row1" width="35%"><b class="genmed">{L_UCP_AIM}{L_COLON} </b></td> - <td class="row2"><input class="post" type="text" name="aim" size="30" maxlength="255" value="{AIM}" /></td> -</tr> -<tr> - <td class="row1" width="35%"><b class="genmed">{L_UCP_MSNM}{L_COLON} </b></td> - <td class="row2"><input class="post" type="email" name="msn" size="30" maxlength="255" value="{MSN}" /></td> -</tr> -<tr> - <td class="row1" width="35%"><b class="genmed">{L_UCP_YIM}{L_COLON} </b></td> - <td class="row2"><input class="post" type="email" name="yim" size="30" maxlength="255" value="{YIM}" /></td> -</tr> -<tr> <td class="row1" width="35%"><b class="genmed">{L_UCP_JABBER}{L_COLON} </b></td> <td class="row2"><input class="post" type="text" name="jabber" size="30" maxlength="255" value="{JABBER}" /></td> </tr> -<tr> - <td class="row1" width="35%"><b class="genmed">{L_WEBSITE}{L_COLON} </b></td> - <td class="row2"><input class="post" type="url" name="website" size="30" maxlength="255" value="{WEBSITE}" /></td> -</tr> -<tr> - <td class="row1" width="35%"><b class="genmed">{L_LOCATION}{L_COLON} </b></td> - <td class="row2"><input class="post" type="text" name="location" size="30" maxlength="100" value="{LOCATION}" /></td> -</tr> -<tr> - <td class="row1" width="35%"><b class="genmed">{L_OCCUPATION}{L_COLON} </b></td> - <td class="row2"><textarea class="post" name="occupation" rows="3" cols="30">{OCCUPATION}</textarea></td> -</tr> -<tr> - <td class="row1" width="35%"><b class="genmed">{L_INTERESTS}{L_COLON} </b></td> - <td class="row2"><textarea class="post" name="interests" rows="3" cols="30">{INTERESTS}</textarea></td> -</tr> <!-- IF S_BIRTHDAYS_ENABLED --> <tr> <td class="row1" width="35%"><b class="genmed">{L_BIRTHDAY}{L_COLON} </b><br /><span class="gensmall">{L_BIRTHDAY_EXPLAIN}</span></td> diff --git a/phpBB/styles/subsilver2/template/ucp_profile_reg_details.html b/phpBB/styles/subsilver2/template/ucp_profile_reg_details.html index 6944a62764..d8fe84bf79 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_reg_details.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_reg_details.html @@ -6,7 +6,7 @@ </tr> <!-- IF S_FORCE_PASSWORD --> <tr> - <td class="row3" colspan="2" align="center"><span class="gensmall">{L_FORCE_PASSWORD_EXPLAIN}</span></td> + <td class="row3" colspan="2" align="center"><span class="gensmall error">{L_FORCE_PASSWORD_EXPLAIN}</span></td> </tr> <!-- ENDIF --> <!-- IF ERROR --> diff --git a/phpBB/styles/subsilver2/template/ucp_profile_signature.html b/phpBB/styles/subsilver2/template/ucp_profile_signature.html index 85c8b0f616..5a2690edda 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_signature.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_signature.html @@ -61,12 +61,7 @@ <td colspan="2"> <table cellspacing="0" cellpadding="0" border="0" width="100%"> <tr> - <td align="{S_CONTENT_FLOW_BEGIN}"> - <script type="text/javascript"> - // <![CDATA[ - colorPalette('h', 6, 5) - // ]]> - </script> + <td align="{S_CONTENT_FLOW_BEGIN}" id="color_palette_placeholder" data-orientation="h" data-width="11" data-height="10"> </td> </tr> </table> diff --git a/phpBB/styles/subsilver2/template/ucp_zebra_friends.html b/phpBB/styles/subsilver2/template/ucp_zebra_friends.html index 45280a35c5..3e18af9969 100644 --- a/phpBB/styles/subsilver2/template/ucp_zebra_friends.html +++ b/phpBB/styles/subsilver2/template/ucp_zebra_friends.html @@ -4,6 +4,7 @@ <tr> <th colspan="2" valign="middle">{L_TITLE}</th> </tr> +<!-- EVENT ucp_friend_list_before --> <tr> <td class="row3" colspan="2"><span class="gensmall">{L_FRIENDS_EXPLAIN}</span></td> </tr> @@ -16,6 +17,7 @@ <td class="row1" width="40%"><b class="genmed">{L_YOUR_FRIENDS}{L_COLON}</b><br /><span class="gensmall">{L_YOUR_FRIENDS_EXPLAIN}</span></td> <td class="row2" align="center"><!-- IF S_USERNAME_OPTIONS --><select name="usernames[]" multiple="multiple" size="5">{S_USERNAME_OPTIONS}</select><!-- ELSE --><b class="genmed">{L_NO_FRIENDS}</b><!-- ENDIF --></td> </tr> +<!-- EVENT ucp_friend_list_after --> <tr> <td class="row1"><b class="genmed">{L_ADD_FRIENDS}{L_COLON}</b><br /><span class="gensmall">{L_ADD_FRIENDS_EXPLAIN} [ <a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false;">{L_FIND_USERNAME}</a> ]</span></td> <td class="row2" align="center"><textarea name="add" rows="5" cols="30">{USERNAMES}</textarea><br /></td> diff --git a/phpBB/styles/subsilver2/template/viewforum_body.html b/phpBB/styles/subsilver2/template/viewforum_body.html index dfbe0a605b..44e8f30ce4 100644 --- a/phpBB/styles/subsilver2/template/viewforum_body.html +++ b/phpBB/styles/subsilver2/template/viewforum_body.html @@ -1,7 +1,7 @@ <!-- INCLUDE overall_header.html --> <!-- IF S_FORUM_RULES --> - <div class="forumrules"> + <div class="forumrules<!-- IF U_FORUM_RULES --> rules-link<!-- ENDIF -->"> <!-- IF U_FORUM_RULES --> <h3>{L_FORUM_RULES}</h3><br /> <a href="{U_FORUM_RULES}"><b>{L_FORUM_RULES_LINK}</b></a> @@ -109,7 +109,7 @@ <p class="moderators"><!-- IF S_SINGLE_MODERATOR -->{L_MODERATOR}<!-- ELSE -->{L_MODERATORS}<!-- ENDIF -->{L_COLON} {MODERATORS}</p> <!-- ENDIF --> <!-- IF U_MCP --> - <p class="linkmcp">[ <a href="{U_MCP}">{L_MCP}</a> ]</p> + <p class="linkmcp">[ <!-- IF U_ACP --><a href="{U_ACP}">{L_ACP}</a><!-- IF U_MCP --> | <!-- ENDIF --><!-- ENDIF --><!-- IF U_MCP --><a href="{U_MCP}">{L_MCP}</a><!-- ENDIF --> ]</p> <!-- ENDIF --> </div> @@ -207,7 +207,8 @@ <td class="row1"> <!-- EVENT topiclist_row_prepend --> <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}" class="imageset">{NEWEST_POST_IMG}</a><!-- ENDIF --> - {topicrow.ATTACH_ICON_IMG} <!-- IF topicrow.S_HAS_POLL or topicrow.S_TOPIC_MOVED --><b>{topicrow.TOPIC_TYPE}</b> <!-- ENDIF --><a title="{L_POSTED}{L_COLON} {topicrow.FIRST_POST_TIME}" href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a> + {topicrow.ATTACH_ICON_IMG} <!-- IF topicrow.S_HAS_POLL or topicrow.S_TOPIC_MOVED --><b>{topicrow.TOPIC_TYPE}</b> <!-- ENDIF --> + <a title="{L_POSTED}{L_COLON} {topicrow.FIRST_POST_TIME}" href="<!-- IF not S_IS_BOT and topicrow.S_UNREAD_TOPIC -->{topicrow.U_NEWEST_POST}<!-- ELSE -->{topicrow.U_VIEW_TOPIC}<!-- ENDIF -->" class="topictitle">{topicrow.TOPIC_TITLE}</a> <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --> <a href="{topicrow.U_MCP_QUEUE}" class="imageset">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF --> @@ -292,7 +293,7 @@ <!-- IF S_DISPLAY_ONLINE_LIST --> <br clear="all" /> - <table class="tablebg" width="100%" cellspacing="1"> + <table class="tablebg stat-block online-list" width="100%" cellspacing="1"> <tr> <td class="cat"><h4>{L_WHO_IS_ONLINE}</h4></td> </tr> diff --git a/phpBB/styles/subsilver2/template/viewtopic_body.html b/phpBB/styles/subsilver2/template/viewtopic_body.html index 26e74b8c38..307ed0f391 100644 --- a/phpBB/styles/subsilver2/template/viewtopic_body.html +++ b/phpBB/styles/subsilver2/template/viewtopic_body.html @@ -1,7 +1,7 @@ <!-- INCLUDE overall_header.html --> <!-- IF S_FORUM_RULES --> - <div class="forumrules"> + <div class="forumrules<!-- IF U_FORUM_RULES --> rules-link<!-- ENDIF -->"> <!-- IF U_FORUM_RULES --> <h3>{L_FORUM_RULES}</h3><br /> <a href="{U_FORUM_RULES}"><b>{L_FORUM_RULES_LINK}</b></a> @@ -21,7 +21,7 @@ <p class="moderators"><!-- IF S_SINGLE_MODERATOR -->{L_MODERATOR}<!-- ELSE -->{L_MODERATORS}<!-- ENDIF -->{L_COLON} {MODERATORS}</p> <!-- ENDIF --> <!-- IF U_MCP --> - <p class="linkmcp">[ <a href="{U_MCP}">{L_MCP}</a> ]</p> + <p class="linkmcp">[ <!-- IF U_ACP --><a href="{U_ACP}">{L_ACP}</a><!-- IF U_MCP --> | <!-- ENDIF --><!-- ENDIF --><!-- IF U_MCP --><a href="{U_MCP}">{L_MCP}</a><!-- ENDIF --> ]</p> <!-- ENDIF --> </div> @@ -80,7 +80,7 @@ <!-- BEGIN poll_option --> <tr> <!-- IF S_CAN_VOTE --> - <td> + <td<!-- IF poll_option.POLL_OPTION_MOST_VOTES --> class="most-votes"<!-- ENDIF -->> <!-- IF S_IS_MULTI_CHOICE --> <input type="checkbox" class="radio" name="vote_id[]" value="{poll_option.POLL_OPTION_ID}"<!-- IF poll_option.POLL_OPTION_VOTED --> checked="checked"<!-- ENDIF --> /> <!-- ELSE --> @@ -127,6 +127,7 @@ </table> <!-- BEGIN postrow --> + <!-- EVENT viewtopic_body_postrow_post_before --> <table class="tablebg" width="100%" cellspacing="1"> <!-- IF postrow.S_FIRST_ROW --> <tr> @@ -201,7 +202,6 @@ <span class="postdetails"> <!-- IF postrow.POSTER_JOINED --><br /><b>{L_JOINED}{L_COLON}</b> {postrow.POSTER_JOINED}<!-- ENDIF --> <!-- IF postrow.POSTER_POSTS != '' --><br /><b>{L_POSTS}{L_COLON}</b> {postrow.POSTER_POSTS}<!-- ENDIF --> - <!-- IF postrow.POSTER_FROM --><br /><b>{L_LOCATION}{L_COLON}</b> {postrow.POSTER_FROM}<!-- ENDIF --> <!-- IF postrow.S_PROFILE_FIELD1 --> <!-- Use a construct like this to include admin defined profile fields. Replace FIELD1 with the name of your field. --> @@ -210,7 +210,9 @@ <!-- EVENT viewtopic_body_postrow_custom_fields_before --> <!-- BEGIN custom_fields --> + <!-- IF not postrow.custom_fields.S_PROFILE_CONTACT --> <br /><b>{postrow.custom_fields.PROFILE_FIELD_NAME}{L_COLON}</b> {postrow.custom_fields.PROFILE_FIELD_VALUE} + <!-- ENDIF --> <!-- END custom_fields --> <!-- EVENT viewtopic_body_postrow_custom_fields_after --> </span> @@ -258,6 +260,7 @@ <div class="postbody"><br />_________________<br />{postrow.SIGNATURE}</div> <!-- ENDIF --> + <!-- EVENT viewtopic_body_postrow_post_notices_before --> <!-- IF postrow.DELETED_MESSAGE or postrow.DELETE_REASON --> <!-- IF postrow.DELETE_REASON --> <br /><br /> @@ -293,6 +296,7 @@ <!-- IF postrow.BUMPED_MESSAGE --> <span class="gensmall"><br /><br />{postrow.BUMPED_MESSAGE}</span> <!-- ENDIF --> + <!-- EVENT viewtopic_body_postrow_post_notices_after --> <!-- IF not postrow.S_HAS_ATTACHMENTS --><br clear="all" /><br /><!-- ENDIF --> @@ -339,6 +343,7 @@ <td class="spacer" colspan="2" height="1"><img src="images/spacer.gif" alt="" width="1" height="1" /></td> </tr> </table> + <!-- EVENT viewtopic_body_postrow_post_after --> <!-- END postrow --> <!-- IF not S_IS_BOT --> @@ -349,6 +354,8 @@ </table> <!-- ENDIF --> + <!-- EVENT viewtopic_body_topic_actions_before --> + <table width="100%" cellspacing="1"> <tr> <td align="{S_CONTENT_FLOW_BEGIN}" valign="middle" nowrap="nowrap"> @@ -380,7 +387,7 @@ <!-- IF S_DISPLAY_ONLINE_LIST --> <br clear="all" /> - <table class="tablebg" width="100%" cellspacing="1"> + <table class="tablebg stat-block online-list" width="100%" cellspacing="1"> <tr> <td class="cat"><h4>{L_WHO_IS_ONLINE}</h4></td> </tr> diff --git a/phpBB/styles/subsilver2/template/viewtopic_print.html b/phpBB/styles/subsilver2/template/viewtopic_print.html index 78fab17d02..a4e4c1b691 100644 --- a/phpBB/styles/subsilver2/template/viewtopic_print.html +++ b/phpBB/styles/subsilver2/template/viewtopic_print.html @@ -2,6 +2,7 @@ <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}"> <head> <meta charset="utf-8"> +<meta name="robots" content="noindex" /> <title>{SITENAME} :: {PAGE_TITLE}</title> <style type="text/css"> @@ -65,7 +66,7 @@ hr.sep { } //--> </style> - +<!-- EVENT viewtopic_print_head_append --> </head> <body> diff --git a/phpBB/styles/subsilver2/theme/en/stylesheet.css b/phpBB/styles/subsilver2/theme/en/stylesheet.css index 563492d4fc..57f9fce26d 100644 --- a/phpBB/styles/subsilver2/theme/en/stylesheet.css +++ b/phpBB/styles/subsilver2/theme/en/stylesheet.css @@ -1,5 +1,5 @@ /* EN Language Pack */ -.imageset.icon_contact_aim { +.imageset.phpbb_aol-icon, .imageset.icon_contact_aim { background-image: url("./icon_contact_aim.gif"); padding-left: 72px; padding-top: 20px; @@ -9,7 +9,7 @@ padding-left: 72px; padding-top: 20px; } -.imageset.icon_contact_icq { +.imageset.phpbb_icq-icon, .imageset.icon_contact_icq { background-image: url("./icon_contact_icq.gif"); padding-left: 72px; padding-top: 20px; @@ -19,7 +19,7 @@ padding-left: 72px; padding-top: 20px; } -.imageset.icon_contact_msnm { +.imageset.phpbb_wlm-icon, .imageset.icon_contact_msnm { background-image: url("./icon_contact_msnm.gif"); padding-left: 72px; padding-top: 20px; @@ -29,12 +29,12 @@ padding-left: 72px; padding-top: 20px; } -.imageset.icon_contact_yahoo { +.imageset.phpbb_yahoo-icon, .imageset.icon_contact_yahoo { background-image: url("./icon_contact_yahoo.gif"); padding-left: 72px; padding-top: 20px; } -.imageset.icon_contact_www { +.imageset.phpbb_website-icon, .imageset.icon_contact_www { background-image: url("./icon_contact_www.gif"); padding-left: 72px; padding-top: 20px; diff --git a/phpBB/styles/subsilver2/theme/images/icon_mini_notification.gif b/phpBB/styles/subsilver2/theme/images/icon_mini_notification.gif Binary files differnew file mode 100644 index 0000000000..f165d3cb27 --- /dev/null +++ b/phpBB/styles/subsilver2/theme/images/icon_mini_notification.gif diff --git a/phpBB/styles/subsilver2/theme/images/no_avatar.gif b/phpBB/styles/subsilver2/theme/images/no_avatar.gif Binary files differindex 80539c8c71..ad73330e71 100644 --- a/phpBB/styles/subsilver2/theme/images/no_avatar.gif +++ b/phpBB/styles/subsilver2/theme/images/no_avatar.gif diff --git a/phpBB/styles/subsilver2/theme/stylesheet.css b/phpBB/styles/subsilver2/theme/stylesheet.css index 7d14376454..0bffc33f37 100644 --- a/phpBB/styles/subsilver2/theme/stylesheet.css +++ b/phpBB/styles/subsilver2/theme/stylesheet.css @@ -303,6 +303,15 @@ p.topicdetails { /* Tables ------------ */ +#color_palette_placeholder table { + border-collapse: separate; + border-spacing: 1px; +} + +#color_palette_placeholder td { + padding: 0; +} + th { color: #FFA34F; font-size: 1.1em; @@ -618,6 +627,10 @@ input:focus, select:focus, textarea:focus { background-color: #FAFAFA; } +.postimage { + max-width: 99%; +} + .syntaxbg { color: #FFFFFF; } @@ -1004,7 +1017,7 @@ a.imageset { /* English images for fallback */ -.imageset.icon_contact_aim { +.imageset.phpbb_aol-icon, .imageset.icon_contact_aim { background-image: url("./en/icon_contact_aim.gif"); padding-left: 72px; padding-top: 20px; @@ -1014,7 +1027,7 @@ a.imageset { padding-left: 72px; padding-top: 20px; } -.imageset.icon_contact_icq { +.imageset.phpbb_icq-icon, .imageset.icon_contact_icq { background-image: url("./en/icon_contact_icq.gif"); padding-left: 72px; padding-top: 20px; @@ -1024,7 +1037,7 @@ a.imageset { padding-left: 72px; padding-top: 20px; } -.imageset.icon_contact_msnm { +.imageset.phpbb_wlm-icon, .imageset.icon_contact_msnm { background-image: url("./en/icon_contact_msnm.gif"); padding-left: 72px; padding-top: 20px; @@ -1034,12 +1047,12 @@ a.imageset { padding-left: 72px; padding-top: 20px; } -.imageset.icon_contact_yahoo { +.imageset.phpbb_yahoo-icon, .imageset.icon_contact_yahoo { background-image: url("./en/icon_contact_yahoo.gif"); padding-left: 72px; padding-top: 20px; } -.imageset.icon_contact_www { +.imageset.phpbb_website-icon, .imageset.icon_contact_www { background-image: url("./en/icon_contact_www.gif"); padding-left: 72px; padding-top: 20px; diff --git a/phpBB/ucp.php b/phpBB/ucp.php index 0c587cbf28..73eaeaa127 100644 --- a/phpBB/ucp.php +++ b/phpBB/ucp.php @@ -94,7 +94,6 @@ switch ($mode) if ($user->data['user_id'] != ANONYMOUS && $request->is_set('sid') && $request->variable('sid', '') === $user->session_id) { $user->session_kill(); - $user->session_begin(); } else if ($user->data['user_id'] != ANONYMOUS) { @@ -128,7 +127,7 @@ switch ($mode) ); // Disable online list - page_header($user->lang[$title], false); + page_header($user->lang[$title]); $template->assign_vars(array( 'S_AGREEMENT' => true, @@ -338,7 +337,7 @@ if (!$config['allow_topic_notify'] && !$config['allow_forum_notify']) * @var p_master module Object holding all modules and their status * @var mixed id Active module category (can be the int or string) * @var string mode Active module -* @since 3.1-A1 +* @since 3.1.0-a1 */ $vars = array('module', 'id', 'mode'); extract($phpbb_dispatcher->trigger_event('core.ucp_display_module_before', compact($vars))); @@ -353,7 +352,7 @@ $module->load_active(); $module->assign_tpl_vars(append_sid("{$phpbb_root_path}ucp.$phpEx")); // Generate the page, do not display/query online list -$module->display($module->get_page_title(), false); +$module->display($module->get_page_title()); /** * Function for assigning a template var if the zebra module got included diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index c6712db46c..8da8a0cdcc 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -33,6 +33,8 @@ $sort_days = request_var('st', $default_sort_days); $sort_key = request_var('sk', $default_sort_key); $sort_dir = request_var('sd', $default_sort_dir); +$pagination = $phpbb_container->get('pagination'); + // Check if the user has actually sent a forum ID with his/her request // If not give them a nice error page. if (!$forum_id) @@ -140,8 +142,13 @@ else } } +$phpbb_content_visibility = $phpbb_container->get('content.visibility'); + // Dump out the page header and load viewforum template -page_header($forum_data['forum_name'] . ($start ? ' - ' . sprintf($user->lang['PAGE_TITLE_NUMBER'], floor($start / $config['topics_per_page']) + 1) : ''), true, $forum_id); +$topics_count = $phpbb_content_visibility->get_count('forum_topics', $forum_data, $forum_id); +$start = $pagination->validate_start($start, $config['topics_per_page'], $topics_count); + +page_header($forum_data['forum_name'] . ($start ? ' - ' . $user->lang('PAGE_TITLE_NUMBER', $pagination->get_on_page($config['topics_per_page'], $start)) : ''), true, $forum_id); $template->set_filenames(array( 'body' => 'viewforum_body.html') @@ -217,6 +224,18 @@ if (!$config['use_system_cron']) $url = $task->get_url(); $template->assign_var('RUN_CRON_TASK', '<img src="' . $url . '" width="1" height="1" alt="cron" />'); } + else + { + // See if we should prune the shadow topics instead + $task = $cron->find_task('cron.task.core.prune_shadow_topics'); + $task->set_forum_data($forum_data); + + if ($task->is_ready()) + { + $url = $task->get_url(); + $template->assign_var('RUN_CRON_TASK', '<img src="' . $url . '" width="1" height="1" alt="cron" />'); + } + } } // Forum rules and subscription info @@ -246,8 +265,6 @@ $sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_po $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = ''; gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param, $default_sort_days, $default_sort_key, $default_sort_dir); -$phpbb_content_visibility = $phpbb_container->get('content.visibility'); - // Limit topics to certain time frame, obtain correct topic count if ($sort_days) { @@ -275,16 +292,9 @@ if ($sort_days) } else { - $topics_count = $phpbb_content_visibility->get_count('forum_topics', $forum_data, $forum_id); $sql_limit_time = ''; } -// Make sure $start is set to the last page if it exceeds the amount -if ($start < 0 || $start > $topics_count) -{ - $start = ($start < 0) ? 0 : floor(($topics_count - 1) / $config['topics_per_page']) * $config['topics_per_page']; -} - // Basic pagewide vars $post_alt = ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->lang['FORUM_LOCKED'] : $user->lang['POST_NEW_TOPIC']; @@ -377,7 +387,7 @@ $sql_array = array( * * @event core.viewforum_get_topic_data * @var array sql_array The SQL array to get the data of all topics -* @since 3.1-A1 +* @since 3.1.0-a1 */ $vars = array('sql_array'); extract($phpbb_dispatcher->trigger_event('core.viewforum_get_topic_data', compact($vars))); @@ -480,14 +490,11 @@ if ($start > $topics_count / 2) { $store_reverse = true; - if ($start + $config['topics_per_page'] > $topics_count) - { - $sql_limit = min($config['topics_per_page'], max(1, $topics_count - $start)); - } - // Select the sort order $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'ASC' : 'DESC'); - $sql_start = max(0, $topics_count - $sql_limit - $start); + + $sql_limit = $pagination->reverse_limit($start, $sql_limit, $topics_count); + $sql_start = $pagination->reverse_start($start, $sql_limit, $topics_count); } else { @@ -561,20 +568,26 @@ if (sizeof($topic_list)) // If we have some shadow topics, update the rowset to reflect their topic information if (sizeof($shadow_topic_list)) { - $sql = 'SELECT * - FROM ' . TOPICS_TABLE . ' - WHERE ' . $db->sql_in_set('topic_id', array_keys($shadow_topic_list)); + // SQL array for obtaining shadow topics + $sql_array = array( + 'SELECT' => 't.*', + 'FROM' => array( + TOPICS_TABLE => 't' + ), + 'WHERE' => $db->sql_in_set('t.topic_id', array_keys($shadow_topic_list)), + ); /** * Event to modify the SQL query before the shadowtopic data is retrieved * * @event core.viewforum_get_shadowtopic_data - * @var string sql The SQL string to get the data of any shadowtopics - * @since 3.1-A1 + * @var array sql_array SQL array to get the data of any shadowtopics + * @since 3.1.0-a1 */ - $vars = array('sql'); + $vars = array('sql_array'); extract($phpbb_dispatcher->trigger_event('core.viewforum_get_shadowtopic_data', compact($vars))); + $sql = $db->sql_build_query('SELECT', $sql_array); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) @@ -631,16 +644,27 @@ if ($s_display_active) $total_topic_count = $topics_count - sizeof($global_announce_forums); $base_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '')); -phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start); +$pagination->generate_template_pagination($base_url, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $topics_count, $config['topics_per_page'], $start), 'TOTAL_TOPICS' => ($s_display_active) ? false : $user->lang('VIEW_FORUM_TOPICS', (int) $total_topic_count), )); $topic_list = ($store_reverse) ? array_merge($announcement_list, array_reverse($topic_list)) : array_merge($announcement_list, $topic_list); $topic_tracking_info = $tracking_topics = array(); +/** +* Modify topics data before we display the viewforum page +* +* @event core.viewforum_modify_topics_data +* @var array topic_list Array with current viewforum page topic ids +* @var array rowset Array with topics data (in topic_id => topic_data format) +* @var int total_topic_count Forum's total topic count +* @since 3.1.0-b3 +*/ +$vars = array('topic_list', 'rowset', 'total_topic_count'); +extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topics_data', compact($vars))); + // Okay, lets dump out the page ... if (sizeof($topic_list)) { @@ -725,7 +749,7 @@ if (sizeof($topic_list)) $view_topic_url_params = 'f=' . $row['forum_id'] . '&t=' . $topic_id; $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params); - $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $row['forum_id'])); + $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $row['forum_id'])); $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $row['forum_id'])); $topic_deleted = $row['topic_visibility'] == ITEM_DELETED; @@ -795,14 +819,14 @@ if (sizeof($topic_list)) * @event core.viewforum_modify_topicrow * @var array row Array with topic data * @var array topic_row Template array with topic data - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('row', 'topic_row'); extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topicrow', compact($vars))); $template->assign_block_vars('topicrow', $topic_row); - phpbb_generate_template_pagination($template, $view_topic_url, 'topicrow.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); + $pagination->generate_template_pagination($view_topic_url, 'topicrow.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); $s_type_switch = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0; diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php index 6b26a3f5d6..9b462b2656 100644 --- a/phpBB/viewonline.php +++ b/phpBB/viewonline.php @@ -26,7 +26,7 @@ $session_id = request_var('s', ''); $start = request_var('start', 0); $sort_key = request_var('sk', 'b'); $sort_dir = request_var('sd', 'd'); -$show_guests= ($config['load_online_guests']) ? request_var('sg', 0) : 0; +$show_guests = ($config['load_online_guests']) ? request_var('sg', 0) : 0; // Can this user view profiles/memberlist? if (!$auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel')) @@ -39,6 +39,8 @@ if (!$auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel')) login_box('', $user->lang['LOGIN_EXPLAIN_VIEWONLINE']); } +$pagination = $phpbb_container->get('pagination'); + $sort_key_text = array('a' => $user->lang['SORT_USERNAME'], 'b' => $user->lang['SORT_JOINED'], 'c' => $user->lang['SORT_LOCATION']); $sort_key_sql = array('a' => 'u.username_clean', 'b' => 's.session_time', 'c' => 's.session_page'); @@ -139,9 +141,12 @@ $sql_ary = array( * @event core.viewonline_modify_sql * @var array sql_ary The SQL array * @var bool show_guests Do we display guests in the list -* @since 3.1-A1 +* @var int guest_counter Number of guests displayed +* @var array forum_data Array with forum data +* @since 3.1.0-a1 +* @change 3.1.0-a2 Added vars guest_counter and forum_data */ -$vars = array('sql_ary', 'show_guests'); +$vars = array('sql_ary', 'show_guests', 'guest_counter', 'forum_data'); extract($phpbb_dispatcher->trigger_event('core.viewonline_modify_sql', compact($vars))); $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary)); @@ -345,9 +350,11 @@ while ($row = $db->sql_fetchrow($result)) * @var array row Array with the users sql row * @var string location Page name to displayed in the list * @var string location_url Page url to displayed in the list - * @since 3.1-A1 + * @var array forum_data Array with forum data + * @since 3.1.0-a1 + * @change 3.1.0-a2 Added var forum_data */ - $vars = array('on_page', 'row', 'location', 'location_url'); + $vars = array('on_page', 'row', 'location', 'location_url', 'forum_data'); extract($phpbb_dispatcher->trigger_event('core.viewonline_overwrite_location', compact($vars))); $template->assign_block_vars('user_row', array( @@ -414,15 +421,15 @@ $db->sql_freeresult($result); // Refreshing the page every 60 seconds... meta_refresh(60, append_sid("{$phpbb_root_path}viewonline.$phpEx", "sg=$show_guests&sk=$sort_key&sd=$sort_dir&start=$start")); +$start = $pagination->validate_start($start, $config['topics_per_page'], $counter); $base_url = append_sid("{$phpbb_root_path}viewonline.$phpEx", "sg=$show_guests&sk=$sort_key&sd=$sort_dir"); -phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $counter, $config['topics_per_page'], $start); +$pagination->generate_template_pagination($base_url, 'pagination', 'start', $counter, $config['topics_per_page'], $start); // Send data to template $template->assign_vars(array( 'TOTAL_REGISTERED_USERS_ONLINE' => $user->lang('REG_USERS_ONLINE', (int) $logged_visible_online, $user->lang('HIDDEN_USERS_ONLINE', (int) $logged_hidden_online)), 'TOTAL_GUEST_USERS_ONLINE' => $user->lang('GUEST_USERS_ONLINE', (int) $guest_counter), 'LEGEND' => $legend, - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $counter, $config['topics_per_page'], $start), 'U_SORT_USERNAME' => append_sid("{$phpbb_root_path}viewonline.$phpEx", 'sk=a&sd=' . (($sort_key == 'a' && $sort_dir == 'a') ? 'd' : 'a') . '&sg=' . ((int) $show_guests)), 'U_SORT_UPDATED' => append_sid("{$phpbb_root_path}viewonline.$phpEx", 'sk=b&sd=' . (($sort_key == 'b' && $sort_dir == 'a') ? 'd' : 'a') . '&sg=' . ((int) $show_guests)), @@ -430,8 +437,9 @@ $template->assign_vars(array( 'U_SWITCH_GUEST_DISPLAY' => append_sid("{$phpbb_root_path}viewonline.$phpEx", 'sg=' . ((int) !$show_guests)), 'L_SWITCH_GUEST_DISPLAY' => ($show_guests) ? $user->lang['HIDE_GUESTS'] : $user->lang['DISPLAY_GUESTS'], - 'S_SWITCH_GUEST_DISPLAY' => ($config['load_online_guests']) ? true : false) -); + 'S_SWITCH_GUEST_DISPLAY' => ($config['load_online_guests']) ? true : false, + 'S_VIEWONLINE' => true, +)); // We do not need to load the who is online box here. ;) $config['load_online'] = false; diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 6880b6882d..36d7533254 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -43,6 +43,8 @@ $sort_dir = request_var('sd', $default_sort_dir); $update = request_var('update', false); +$pagination = $phpbb_container->get('pagination'); + $s_can_vote = false; /** * @todo normalize? @@ -264,7 +266,7 @@ if ($topic_data['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_appro if ($post_id) { // are we where we are supposed to be? - if ($topic_data['post_visibility'] == ITEM_UNAPPROVED && !$auth->acl_get('m_approve', $topic_data['forum_id'])) + if (($topic_data['post_visibility'] == ITEM_UNAPPROVED || $topic_data['post_visibility'] == ITEM_REAPPROVE) && !$auth->acl_get('m_approve', $topic_data['forum_id'])) { // If post_id was submitted, we try at least to display the topic as a last resort... if ($topic_id) @@ -347,23 +349,10 @@ if ($topic_data['forum_password']) login_forum_box($topic_data); } -// Redirect to login or to the correct post upon emailed notification links -if (isset($_GET['e'])) +// Redirect to login upon emailed notification links if user is not logged in. +if (isset($_GET['e']) && $user->data['user_id'] == ANONYMOUS) { - $jump_to = request_var('e', 0); - - $redirect_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id"); - - if ($user->data['user_id'] == ANONYMOUS) - { - login_box($redirect_url . "&p=$post_id&e=$jump_to", $user->lang['LOGIN_NOTIFY_TOPIC']); - } - - if ($jump_to > 0) - { - // We direct the already logged in user to the correct post... - redirect($redirect_url . ((!$post_id) ? "&p=$jump_to" : "&p=$post_id") . "#p$jump_to"); - } + login_box(build_url('e') . '#unread', $user->lang['LOGIN_NOTIFY_TOPIC']); } // What is start equal to? @@ -433,24 +422,15 @@ else $highlight_match = $highlight = ''; if ($hilit_words) { - foreach (explode(' ', trim($hilit_words)) as $word) - { - if (trim($word)) - { - $word = str_replace('\*', '\w+?', preg_quote($word, '#')); - $word = preg_replace('#(^|\s)\\\\w\*\?(\s|$)#', '$1\w+?$2', $word); - $highlight_match .= (($highlight_match != '') ? '|' : '') . $word; - } - } - - $highlight = urlencode($hilit_words); + $highlight_match = phpbb_clean_search_string($hilit_words); + $highlight = urlencode($highlight_match); + $highlight_match = str_replace('\*', '\w+?', preg_quote($highlight_match, '#')); + $highlight_match = preg_replace('#(?<=^|\s)\\\\w\*\?(?=\s|$)#', '\w+?', $highlight_match); + $highlight_match = str_replace(' ', '|', $highlight_match); } // Make sure $start is set to the last page if it exceeds the amount -if ($start < 0 || $start >= $total_posts) -{ - $start = ($start < 0) ? 0 : floor(($total_posts - 1) / $config['posts_per_page']) * $config['posts_per_page']; -} +$start = $pagination->validate_start($start, $config['posts_per_page'], $total_posts); // General Viewtopic URL for return links $viewtopic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start") . ((strlen($u_sort_param)) ? "&$u_sort_param" : '') . (($highlight_match) ? "&hilit=$highlight" : '')); @@ -497,11 +477,21 @@ if ($config['allow_bookmarks'] && $user->data['is_registered'] && request_var('b AND topic_id = $topic_id"; $db->sql_query($sql); } - $message = (($topic_data['bookmarked']) ? $user->lang['BOOKMARK_REMOVED'] : $user->lang['BOOKMARK_ADDED']) . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $viewtopic_url . '">', '</a>'); + $message = (($topic_data['bookmarked']) ? $user->lang['BOOKMARK_REMOVED'] : $user->lang['BOOKMARK_ADDED']); + + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('RETURN_TOPIC', '<a href="' . $viewtopic_url . '">', '</a>'); + } } else { - $message = $user->lang['BOOKMARK_ERR'] . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $viewtopic_url . '">', '</a>'); + $message = $user->lang['BOOKMARK_ERR']; + + if (!$request->is_ajax()) + { + $message .= '<br /><br />' . $user->lang('RETURN_TOPIC', '<a href="' . $viewtopic_url . '">', '</a>'); + } } meta_refresh(3, $viewtopic_url); @@ -594,7 +584,7 @@ if (!empty($_EXTRA_URL)) // If we've got a hightlight set pass it on to pagination. $base_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '') . (($highlight_match) ? "&hilit=$highlight" : '')); -phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total_posts, $config['posts_per_page'], $start); +$pagination->generate_template_pagination($base_url, 'pagination', 'start', $total_posts, $config['posts_per_page'], $start); // Send vars to template $template->assign_vars(array( @@ -609,7 +599,6 @@ $template->assign_vars(array( 'TOPIC_AUTHOR_COLOUR' => get_username_string('colour', $topic_data['topic_poster'], $topic_data['topic_first_poster_name'], $topic_data['topic_first_poster_colour']), 'TOPIC_AUTHOR' => get_username_string('username', $topic_data['topic_poster'], $topic_data['topic_first_poster_name'], $topic_data['topic_first_poster_colour']), - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $total_posts, $config['posts_per_page'], $start), 'TOTAL_POSTS' => $user->lang('VIEW_TOPIC_POSTS', (int) $total_posts), 'U_MCP' => ($auth->acl_get('m_', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=main&mode=topic_view&f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start") . ((strlen($u_sort_param)) ? "&$u_sort_param" : ''), true, $user->session_id) : '', 'MODERATORS' => (isset($forum_moderators[$forum_id]) && sizeof($forum_moderators[$forum_id])) ? implode($user->lang['COMMA_SEPARATOR'], $forum_moderators[$forum_id]) : '', @@ -625,11 +614,6 @@ $template->assign_vars(array( 'SEARCH_IMG' => $user->img('icon_user_search', 'SEARCH_USER_POSTS'), 'PM_IMG' => $user->img('icon_contact_pm', 'SEND_PRIVATE_MESSAGE'), 'EMAIL_IMG' => $user->img('icon_contact_email', 'SEND_EMAIL'), - 'WWW_IMG' => $user->img('icon_contact_www', 'VISIT_WEBSITE'), - 'ICQ_IMG' => $user->img('icon_contact_icq', 'ICQ'), - 'AIM_IMG' => $user->img('icon_contact_aim', 'AIM'), - 'MSN_IMG' => $user->img('icon_contact_msnm', 'MSNM'), - 'YIM_IMG' => $user->img('icon_contact_yahoo', 'YIM'), 'JABBER_IMG' => $user->img('icon_contact_jabber', 'JABBER') , 'REPORT_IMG' => $user->img('icon_post_report', 'REPORT_POST'), 'REPORTED_IMG' => $user->img('icon_topic_reported', 'POST_REPORTED'), @@ -644,6 +628,7 @@ $template->assign_vars(array( 'S_TOPIC_ACTION' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start")), 'S_MOD_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start") . "&quickmod=1&redirect=" . urlencode(str_replace('&', '&', $viewtopic_url)), true, $user->session_id), + 'L_RETURN_TO_FORUM' => $user->lang('RETURN_TO', $topic_data['forum_name']), 'S_VIEWTOPIC' => true, 'S_DISPLAY_SEARCHBOX' => ($auth->acl_get('u_search') && $auth->acl_get('f_search', $forum_id) && $config['load_search']) ? true : false, 'S_SEARCHBOX_ACTION' => append_sid("{$phpbb_root_path}search.$phpEx"), @@ -689,10 +674,12 @@ if (!empty($topic_data['poll_start'])) ORDER BY o.poll_option_id"; $result = $db->sql_query($sql); - $poll_info = array(); + $poll_info = $vote_counts = array(); while ($row = $db->sql_fetchrow($result)) { $poll_info[] = $row; + $option_id = (int) $row['poll_option_id']; + $vote_counts[$option_id] = (int) $row['poll_option_total']; } $db->sql_freeresult($result); @@ -774,6 +761,8 @@ if (!empty($topic_data['poll_start'])) AND topic_id = ' . (int) $topic_id; $db->sql_query($sql); + $vote_counts[$option]++; + if ($user->data['is_registered']) { $sql_ary = array( @@ -798,6 +787,8 @@ if (!empty($topic_data['poll_start'])) AND topic_id = ' . (int) $topic_id; $db->sql_query($sql); + $vote_counts[$option]--; + if ($user->data['is_registered']) { $sql = 'DELETE FROM ' . POLL_VOTES_TABLE . ' @@ -821,15 +812,35 @@ if (!empty($topic_data['poll_start'])) $db->sql_query($sql); $redirect_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start")); + $message = $user->lang['VOTE_SUBMITTED'] . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $redirect_url . '">', '</a>'); + + if ($request->is_ajax()) + { + // Filter out invalid options + $valid_user_votes = array_intersect(array_keys($vote_counts), $voted_id); + + $data = array( + 'NO_VOTES' => $user->lang['NO_VOTES'], + 'success' => true, + 'user_votes' => array_flip($valid_user_votes), + 'vote_counts' => $vote_counts, + 'total_votes' => array_sum($vote_counts), + 'can_vote' => !sizeof($valid_user_votes) || ($auth->acl_get('f_votechg', $forum_id) && $topic_data['poll_vote_change']), + ); + $json_response = new \phpbb\json_response(); + $json_response->send($data); + } meta_refresh(5, $redirect_url); - trigger_error($user->lang['VOTE_SUBMITTED'] . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $redirect_url . '">', '</a>')); + trigger_error($message); } $poll_total = 0; + $poll_most = 0; foreach ($poll_info as $poll_option) { $poll_total += $poll_option['poll_option_total']; + $poll_most = ($poll_option['poll_option_total'] >= $poll_most) ? $poll_option['poll_option_total'] : $poll_most; } $parse_flags = ($poll_info[0]['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES; @@ -845,16 +856,21 @@ if (!empty($topic_data['poll_start'])) { $option_pct = ($poll_total > 0) ? $poll_option['poll_option_total'] / $poll_total : 0; $option_pct_txt = sprintf("%.1d%%", round($option_pct * 100)); + $option_pct_rel = ($poll_most > 0) ? $poll_option['poll_option_total'] / $poll_most : 0; + $option_pct_rel_txt = sprintf("%.1d%%", round($option_pct_rel * 100)); + $option_most_votes = ($poll_option['poll_option_total'] > 0 && $poll_option['poll_option_total'] == $poll_most) ? true : false; $template->assign_block_vars('poll_option', array( - 'POLL_OPTION_ID' => $poll_option['poll_option_id'], - 'POLL_OPTION_CAPTION' => $poll_option['poll_option_text'], - 'POLL_OPTION_RESULT' => $poll_option['poll_option_total'], - 'POLL_OPTION_PERCENT' => $option_pct_txt, - 'POLL_OPTION_PCT' => round($option_pct * 100), - 'POLL_OPTION_WIDTH' => round($option_pct * 250), - 'POLL_OPTION_VOTED' => (in_array($poll_option['poll_option_id'], $cur_voted_id)) ? true : false) - ); + 'POLL_OPTION_ID' => $poll_option['poll_option_id'], + 'POLL_OPTION_CAPTION' => $poll_option['poll_option_text'], + 'POLL_OPTION_RESULT' => $poll_option['poll_option_total'], + 'POLL_OPTION_PERCENT' => $option_pct_txt, + 'POLL_OPTION_PERCENT_REL' => $option_pct_rel_txt, + 'POLL_OPTION_PCT' => round($option_pct * 100), + 'POLL_OPTION_WIDTH' => round($option_pct * 250), + 'POLL_OPTION_VOTED' => (in_array($poll_option['poll_option_id'], $cur_voted_id)) ? true : false, + 'POLL_OPTION_MOST_VOTES' => $option_most_votes, + )); } $poll_end = $topic_data['poll_length'] + $topic_data['poll_start']; @@ -874,8 +890,8 @@ if (!empty($topic_data['poll_start'])) 'S_IS_MULTI_CHOICE' => ($topic_data['poll_max_options'] > 1) ? true : false, 'S_POLL_ACTION' => $viewtopic_url, - 'U_VIEW_RESULTS' => $viewtopic_url . '&view=viewpoll') - ); + 'U_VIEW_RESULTS' => $viewtopic_url . '&view=viewpoll', + )); unset($poll_end, $poll_info, $voted_id); } @@ -889,14 +905,11 @@ if ($start > $total_posts / 2) { $store_reverse = true; - if ($start + $config['posts_per_page'] > $total_posts) - { - $sql_limit = min($config['posts_per_page'], max(1, $total_posts - $start)); - } - // Select the sort order $direction = (($sort_dir == 'd') ? 'ASC' : 'DESC'); - $sql_start = max(0, $total_posts - $sql_limit - $start); + + $sql_limit = $pagination->reverse_limit($start, $sql_limit, $total_posts); + $sql_start = $pagination->reverse_start($start, $sql_limit, $total_posts); } else { @@ -977,10 +990,29 @@ $sql_ary = array( * Event to modify the SQL query before the post and poster data is retrieved * * @event core.viewtopic_get_post_data +* @var int forum_id Forum ID +* @var int topic_id Topic ID +* @var array topic_data Array with topic data +* @var array post_list Array with post_ids we are going to retrieve +* @var int sort_days Display posts of previous x days +* @var string sort_key Key the posts are sorted by +* @var string sort_dir Direction the posts are sorted by +* @var int start Pagination information * @var array sql_ary The SQL array to get the data of posts and posters -* @since 3.1-A1 +* @since 3.1.0-a1 +* @change 3.1.0-a2 Added vars forum_id, topic_id, topic_data, post_list, sort_days, sort_key, sort_dir, start */ -$vars = array('sql_ary'); +$vars = array( + 'forum_id', + 'topic_id', + 'topic_data', + 'post_list', + 'sort_days', + 'sort_key', + 'sort_dir', + 'start', + 'sql_ary', +); extract($phpbb_dispatcher->trigger_event('core.viewtopic_get_post_data', compact($vars))); $sql = $db->sql_build_query('SELECT', $sql_ary); @@ -1006,7 +1038,7 @@ while ($row = $db->sql_fetchrow($result)) { $attach_list[] = (int) $row['post_id']; - if ($row['post_visibility'] == ITEM_UNAPPROVED) + if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) { $has_attachments = true; } @@ -1053,7 +1085,7 @@ while ($row = $db->sql_fetchrow($result)) * @event core.viewtopic_post_rowset_data * @var array rowset_data Array with the rowset data for this post * @var array row Array with original user and post data - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('rowset_data', 'row'); extract($phpbb_dispatcher->trigger_event('core.viewtopic_post_rowset_data', compact($vars))); @@ -1078,7 +1110,6 @@ while ($row = $db->sql_fetchrow($result)) $user_cache_data = array( 'joined' => '', 'posts' => '', - 'from' => '', 'sig' => '', 'sig_bbcode_uid' => '', @@ -1090,15 +1121,8 @@ while ($row = $db->sql_fetchrow($result)) 'rank_image' => '', 'rank_image_src' => '', 'sig' => '', - 'profile' => '', 'pm' => '', 'email' => '', - 'www' => '', - 'icq_status_img' => '', - 'icq' => '', - 'aim' => '', - 'msn' => '', - 'yim' => '', 'jabber' => '', 'search' => '', 'age' => '', @@ -1115,9 +1139,9 @@ while ($row = $db->sql_fetchrow($result)) * * @event core.viewtopic_cache_guest_data * @var array user_cache_data Array with the user's data - * @var int poster_id Poster's user id - * @var array row Array with original user and post data - * @since 3.1-A1 + * @var int poster_id Poster's user id + * @var array row Array with original user and post data + * @since 3.1.0-a1 */ $vars = array('user_cache_data', 'poster_id', 'row'); extract($phpbb_dispatcher->trigger_event('core.viewtopic_cache_guest_data', compact($vars))); @@ -1142,7 +1166,6 @@ while ($row = $db->sql_fetchrow($result)) 'joined' => $user->format_date($row['user_regdate']), 'posts' => $row['user_posts'], 'warnings' => (isset($row['user_warnings'])) ? $row['user_warnings'] : 0, - 'from' => (!empty($row['user_from'])) ? $row['user_from'] : '', 'sig' => $user_sig, 'sig_bbcode_uid' => (!empty($row['user_sig_bbcode_uid'])) ? $row['user_sig_bbcode_uid'] : '', @@ -1162,11 +1185,6 @@ while ($row = $db->sql_fetchrow($result)) 'user_colour' => $row['user_colour'], 'online' => false, - 'profile' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=viewprofile&u=$poster_id"), - 'www' => $row['user_website'], - 'aim' => ($row['user_aim'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&action=aim&u=$poster_id") : '', - 'msn' => ($row['user_msnm'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&action=msnm&u=$poster_id") : '', - 'yim' => ($row['user_yim']) ? 'http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($row['user_yim']) . '&.src=pg' : '', 'jabber' => ($row['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&action=jabber&u=$poster_id") : '', 'search' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id=$poster_id&sr=posts") : '', @@ -1181,9 +1199,9 @@ while ($row = $db->sql_fetchrow($result)) * * @event core.viewtopic_cache_user_data * @var array user_cache_data Array with the user's data - * @var int poster_id Poster's user id - * @var array row Array with original user and post data - * @since 3.1-A1 + * @var int poster_id Poster's user id + * @var array row Array with original user and post data + * @since 3.1.0-a1 */ $vars = array('user_cache_data', 'poster_id', 'row'); extract($phpbb_dispatcher->trigger_event('core.viewtopic_cache_user_data', compact($vars))); @@ -1201,17 +1219,6 @@ while ($row = $db->sql_fetchrow($result)) $user_cache[$poster_id]['email'] = ''; } - if (!empty($row['user_icq'])) - { - $user_cache[$poster_id]['icq'] = 'http://www.icq.com/people/' . urlencode($row['user_icq']) . '/'; - $user_cache[$poster_id]['icq_status_img'] = '<img src="http://web.icq.com/whitepages/online?icq=' . $row['user_icq'] . '&img=5" width="18" height="18" alt="" />'; - } - else - { - $user_cache[$poster_id]['icq_status_img'] = ''; - $user_cache[$poster_id]['icq'] = ''; - } - if ($config['allow_birthdays'] && !empty($row['user_birthday'])) { list($bday_day, $bday_month, $bday_year) = array_map('intval', explode('-', $row['user_birthday'])); @@ -1239,14 +1246,10 @@ $db->sql_freeresult($result); // Load custom profile fields if ($config['load_cpf_viewtopic']) { - if (!class_exists('custom_profile')) - { - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - } - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields.manager'); // Grab all profile fields from users in id cache for later use - similar to the poster cache - $profile_fields_tmp = $cp->generate_profile_fields_template('grab', $id_cache); + $profile_fields_tmp = $cp->grab_profile_fields_data($id_cache); // filter out fields not to be displayed on viewtopic. Yes, it's a hack, but this shouldn't break any MODs. $profile_fields_cache = array(); @@ -1354,16 +1357,17 @@ if (sizeof($attach_list)) } } -$template->assign_vars(array( - 'S_HAS_ATTACHMENTS' => $topic_data['topic_attachment'], -)); - $methods = phpbb_gen_download_links('topic_id', $topic_id, $phpbb_root_path, $phpEx); foreach ($methods as $method) { $template->assign_block_vars('dl_method', $method); } +$template->assign_vars(array( + 'S_HAS_ATTACHMENTS' => $topic_data['topic_attachment'], + 'U_DOWNLOAD_ALL_ATTACHMENTS' => $methods[0]['LINK'], +)); + // Instantiate BBCode if need be if ($bbcode_bitfield !== '') { @@ -1555,7 +1559,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) // if ($config['load_cpf_viewtopic']) { - $cp_row = (isset($profile_fields_cache[$poster_id])) ? $cp->generate_profile_fields_template('show', false, $profile_fields_cache[$poster_id]) : array(); + $cp_row = (isset($profile_fields_cache[$poster_id])) ? $cp->generate_profile_fields_template_data($profile_fields_cache[$poster_id]) : array(); } $post_unread = (isset($topic_tracking_info[$topic_id]) && $row['post_time'] > $topic_tracking_info[$topic_id]) ? true : false; @@ -1569,13 +1573,19 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) $edit_allowed = ($user->data['is_registered'] && ($auth->acl_get('m_edit', $forum_id) || ( $user->data['user_id'] == $poster_id && $auth->acl_get('f_edit', $forum_id) && + $topic_data['topic_status'] != ITEM_LOCKED && !$row['post_edit_locked'] && ($row['post_time'] > time() - ($config['edit_time'] * 60) || !$config['edit_time']) ))); + $quote_allowed = $auth->acl_get('m_edit', $forum_id) || ($topic_data['topic_status'] != ITEM_LOCKED && + ($user->data['user_id'] == ANONYMOUS || $auth->acl_get('f_reply', $forum_id)) + ); + $delete_allowed = ($user->data['is_registered'] && (($auth->acl_get('m_delete', $forum_id) || ($auth->acl_get('m_softdelete', $forum_id) && $row['post_visibility'] != ITEM_DELETED)) || ( $user->data['user_id'] == $poster_id && ($auth->acl_get('f_delete', $forum_id) || ($auth->acl_get('f_softdelete', $forum_id) && $row['post_visibility'] != ITEM_DELETED)) && + $topic_data['topic_status'] != ITEM_LOCKED && $topic_data['topic_last_post_id'] == $row['post_id'] && ($row['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time']) && // we do not want to allow removal of the last post if a moderator locked it! @@ -1594,7 +1604,6 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'RANK_IMG_SRC' => $user_cache[$poster_id]['rank_image_src'], 'POSTER_JOINED' => $user_cache[$poster_id]['joined'], 'POSTER_POSTS' => $user_cache[$poster_id]['posts'], - 'POSTER_FROM' => $user_cache[$poster_id]['from'], 'POSTER_AVATAR' => $user_cache[$poster_id]['avatar'], 'POSTER_WARNINGS' => $user_cache[$poster_id]['warnings'], 'POSTER_AGE' => $user_cache[$poster_id]['age'], @@ -1613,24 +1622,17 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'POST_ICON_IMG' => ($topic_data['enable_icons'] && !empty($row['icon_id'])) ? $icons[$row['icon_id']]['img'] : '', 'POST_ICON_IMG_WIDTH' => ($topic_data['enable_icons'] && !empty($row['icon_id'])) ? $icons[$row['icon_id']]['width'] : '', 'POST_ICON_IMG_HEIGHT' => ($topic_data['enable_icons'] && !empty($row['icon_id'])) ? $icons[$row['icon_id']]['height'] : '', - 'ICQ_STATUS_IMG' => $user_cache[$poster_id]['icq_status_img'], 'ONLINE_IMG' => ($poster_id == ANONYMOUS || !$config['load_onlinetrack']) ? '' : (($user_cache[$poster_id]['online']) ? $user->img('icon_user_online', 'ONLINE') : $user->img('icon_user_offline', 'OFFLINE')), 'S_ONLINE' => ($poster_id == ANONYMOUS || !$config['load_onlinetrack']) ? false : (($user_cache[$poster_id]['online']) ? true : false), 'U_EDIT' => ($edit_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=edit&f=$forum_id&p={$row['post_id']}") : '', - 'U_QUOTE' => ($auth->acl_get('f_reply', $forum_id)) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=quote&f=$forum_id&p={$row['post_id']}") : '', + 'U_QUOTE' => ($quote_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=quote&f=$forum_id&p={$row['post_id']}") : '', 'U_INFO' => ($auth->acl_get('m_info', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=main&mode=post_details&f=$forum_id&p=" . $row['post_id'], true, $user->session_id) : '', 'U_DELETE' => ($delete_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=delete&f=$forum_id&p={$row['post_id']}") : '', - 'U_PROFILE' => $user_cache[$poster_id]['profile'], 'U_SEARCH' => $user_cache[$poster_id]['search'], 'U_PM' => ($poster_id != ANONYMOUS && $config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($user_cache[$poster_id]['allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose&action=quotepost&p=' . $row['post_id']) : '', 'U_EMAIL' => $user_cache[$poster_id]['email'], - 'U_WWW' => $user_cache[$poster_id]['www'], - 'U_ICQ' => $user_cache[$poster_id]['icq'], - 'U_AIM' => $user_cache[$poster_id]['aim'], - 'U_MSN' => $user_cache[$poster_id]['msn'], - 'U_YIM' => $user_cache[$poster_id]['yim'], 'U_JABBER' => $user_cache[$poster_id]['jabber'], 'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&p={$row['post_id']}&f=$forum_id&redirect=" . urlencode(str_replace('&', '&', $viewtopic_url . '&p=' . $row['post_id'] . '#p' . $row['post_id']))), @@ -1650,7 +1652,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false, 'S_MULTIPLE_ATTACHMENTS' => !empty($attachments[$row['post_id']]) && sizeof($attachments[$row['post_id']]) > 1, - 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED) ? true : false, + 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) ? true : false, 'S_POST_DELETED' => ($row['post_visibility'] == ITEM_DELETED) ? true : false, 'L_POST_DELETED_MESSAGE' => $l_deleted_message, 'S_POST_REPORTED' => ($row['post_reported'] && $auth->acl_get('m_report', $forum_id)) ? true : false, @@ -1669,19 +1671,42 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) $user_poster_data = $user_cache[$poster_id]; + $current_row_number = $i; + /** * Modify the posts template block * * @event core.viewtopic_modify_post_row - * @var array row Array with original post and user data - * @var array cp_row Custom profile field data of the poster + * @var int start Start item of this page + * @var int current_row_number Number of the post on this page + * @var int end Number of posts on this page + * @var int total_posts Total posts count + * @var array row Array with original post and user data + * @var array cp_row Custom profile field data of the poster + * @var array attachments List of attachments * @var array user_poster_data Poster's data from user cache - * @var array post_row Template block array of the post - * @since 3.1-A1 + * @var array post_row Template block array of the post + * @var array topic_data Array with topic data + * @since 3.1.0-a1 + * @change 3.1.0-a3 Added vars start, current_row_number, end, attachments + * @change 3.1.0-b3 Added topic_data array, total_posts */ - $vars = array('row', 'cp_row', 'user_poster_data', 'post_row'); + $vars = array( + 'start', + 'current_row_number', + 'end', + 'total_posts', + 'row', + 'cp_row', + 'attachments', + 'user_poster_data', + 'post_row', + 'topic_data', + ); extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_post_row', compact($vars))); + $i = $current_row_number; + if (isset($cp_row['row']) && sizeof($cp_row['row'])) { $post_row = array_merge($post_row, $cp_row['row']); @@ -1708,13 +1733,48 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) ); } - $methods = phpbb_gen_download_links('post_msg_id', $row['post_id'], $phpbb_root_path, $phpEx); + $methods = phpbb_gen_download_links('post_id', $row['post_id'], $phpbb_root_path, $phpEx); foreach ($methods as $method) { $template->assign_block_vars('postrow.dl_method', $method); } } + $current_row_number = $i; + + /** + * Event after the post data has been assigned to the template + * + * @event core.viewtopic_post_row_after + * @var int start Start item of this page + * @var int current_row_number Number of the post on this page + * @var int end Number of posts on this page + * @var int total_posts Total posts count + * @var array row Array with original post and user data + * @var array cp_row Custom profile field data of the poster + * @var array attachments List of attachments + * @var array user_poster_data Poster's data from user cache + * @var array post_row Template block array of the post + * @var array topic_data Array with topic data + * @since 3.1.0-a3 + * @change 3.1.0-b3 Added topic_data array, total_posts + */ + $vars = array( + 'start', + 'current_row_number', + 'end', + 'total_posts', + 'row', + 'cp_row', + 'attachments', + 'user_poster_data', + 'post_row', + 'topic_data', + ); + extract($phpbb_dispatcher->trigger_event('core.viewtopic_post_row_after', compact($vars))); + + $i = $current_row_number; + $prev_post_id = $row['post_id']; unset($rowset[$post_list[$i]]); @@ -1848,17 +1908,17 @@ if (!request_var('t', 0) && !empty($topic_id)) $request->overwrite('t', $topic_id); } -$page_title = $topic_data['topic_title'] . ($start ? ' - ' . sprintf($user->lang['PAGE_TITLE_NUMBER'], floor($start / $config['posts_per_page']) + 1) : ''); +$page_title = $topic_data['topic_title'] . ($start ? ' - ' . sprintf($user->lang['PAGE_TITLE_NUMBER'], $pagination->get_on_page($config['posts_per_page'], $start)) : ''); /** * You can use this event to modify the page title of the viewtopic page * * @event core.viewtopic_modify_page_title -* @var string page_title Title of the index page +* @var string page_title Title of the viewtopic page * @var array topic_data Array with topic data * @var int forum_id Forum ID of the topic * @var int start Start offset used to calculate the page -* @since 3.1-A1 +* @since 3.1.0-a1 */ $vars = array('page_title', 'topic_data', 'forum_id', 'start'); extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_page_title', compact($vars))); diff --git a/phpunit.xml.all b/phpunit.xml.all index d18518d3e3..d5ee606ce2 100644 --- a/phpunit.xml.all +++ b/phpunit.xml.all @@ -29,8 +29,6 @@ <directory suffix=".php">./phpBB/includes/</directory> <directory suffix=".php">./phpBB/phpbb/</directory> <exclude> - <file>./phpBB/phpbb/search/fulltext_native.php</file> - <file>./phpBB/phpbb/search/fulltext_mysql.php</file> <directory suffix=".php">./phpBB/includes/captcha/</directory> </exclude> </whitelist> diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c852f91b50..700af8b2b2 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -36,8 +36,6 @@ <directory suffix=".php">./phpBB/includes/</directory> <directory suffix=".php">./phpBB/phpbb/</directory> <exclude> - <file>./phpBB/phpbb/search/fulltext_native.php</file> - <file>./phpBB/phpbb/search/fulltext_mysql.php</file> <directory suffix=".php">./phpBB/includes/captcha/</directory> </exclude> </whitelist> diff --git a/phpunit.xml.functional b/phpunit.xml.functional index cd9cc8771f..44d060e615 100644 --- a/phpunit.xml.functional +++ b/phpunit.xml.functional @@ -35,8 +35,6 @@ <directory suffix=".php">./phpBB/includes/</directory> <directory suffix=".php">./phpBB/phpbb/</directory> <exclude> - <file>./phpBB/phpbb/search/fulltext_native.php</file> - <file>./phpBB/phpbb/search/fulltext_mysql.php</file> <directory suffix=".php">./phpBB/includes/captcha/</directory> </exclude> </whitelist> diff --git a/tests/auth/fixtures/user.xml b/tests/auth/fixtures/user.xml index 34584babbf..77f707bab3 100644 --- a/tests/auth/fixtures/user.xml +++ b/tests/auth/fixtures/user.xml @@ -12,13 +12,11 @@ <column>user_login_attempts</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>foobar</value> <value>foobar</value> - <value>$H$9E45lK6J8nLTSm9oJE5aNCSTFK9wqa/</value> + <value>$2y$10$4RmpyVu2y8Yf/lP3.yQBquKvE54TCUuEDEBJYY6FDDFN3LcbCGz9i</value> <value>0</value> <value>0</value> <value>example@example.com</value> @@ -26,6 +24,17 @@ <value>0</value> <value></value> <value></value> + </row> + <row> + <value>2</value> + <value>foobar2</value> + <value>foobar2</value> + <value>$H$9E45lK6J8nLTSm9oJE5aNCSTFK9wqa/</value> + <value>0</value> + <value>0</value> + <value>example@example.com</value> + <value>0</value> + <value>0</value> <value></value> <value></value> </row> diff --git a/tests/auth/fixtures/user_533.xml b/tests/auth/fixtures/user_533.xml new file mode 100644 index 0000000000..b64f376e5b --- /dev/null +++ b/tests/auth/fixtures/user_533.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_users"> + <column>user_id</column> + <column>username</column> + <column>username_clean</column> + <column>user_password</column> + <column>user_passchg</column> + <column>user_pass_convert</column> + <column>user_email</column> + <column>user_type</column> + <column>user_login_attempts</column> + <column>user_permissions</column> + <column>user_sig</column> + <row> + <value>1</value> + <value>foobar</value> + <value>foobar</value> + <value>$2a$10$e01Syh9PbJjUkio66eFuUu4FhCE2nRgG7QPc1JACalsPXcIuG2bbi</value> + <value>0</value> + <value>0</value> + <value>example@example.com</value> + <value>0</value> + <value>0</value> + <value></value> + <value></value> + </row> + <row> + <value>2</value> + <value>foobar2</value> + <value>foobar2</value> + <value>$H$9E45lK6J8nLTSm9oJE5aNCSTFK9wqa/</value> + <value>0</value> + <value>0</value> + <value>example@example.com</value> + <value>0</value> + <value>0</value> + <value></value> + <value></value> + </row> + </table> +</dataset> diff --git a/tests/auth/provider_apache_test.php b/tests/auth/provider_apache_test.php index e135a1f002..4b12abd62a 100644 --- a/tests/auth/provider_apache_test.php +++ b/tests/auth/provider_apache_test.php @@ -7,7 +7,8 @@ * */ -require_once dirname(__FILE__).'/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; class phpbb_auth_provider_apache_test extends phpbb_database_test_case { @@ -25,13 +26,40 @@ class phpbb_auth_provider_apache_test extends phpbb_database_test_case $config = new \phpbb\config\config(array()); $this->request = $this->getMock('\phpbb\request\request'); $this->user = $this->getMock('\phpbb\user'); + $driver_helper = new \phpbb\passwords\driver\helper($config); + $passwords_drivers = array( + 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $driver_helper), + 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $driver_helper), + 'passwords.driver.salted_md5' => new \phpbb\passwords\driver\salted_md5($config, $driver_helper), + 'passwords.driver.phpass' => new \phpbb\passwords\driver\phpass($config, $driver_helper), + ); + + $passwords_helper = new \phpbb\passwords\helper; + // Set up passwords manager + $passwords_manager = new \phpbb\passwords\manager($config, $passwords_drivers, $passwords_helper, array_keys($passwords_drivers)); + + if (version_compare(PHP_VERSION, '5.3.7', '<')) + { + $this->password_hash = '$2a$10$e01Syh9PbJjUkio66eFuUu4FhCE2nRgG7QPc1JACalsPXcIuG2bbi'; + } + else + { + $this->password_hash = '$2y$10$4RmpyVu2y8Yf/lP3.yQBquKvE54TCUuEDEBJYY6FDDFN3LcbCGz9i'; + } - $this->provider = new \phpbb\auth\provider\apache($db, $config, $this->request, $this->user, $phpbb_root_path, $phpEx); + $this->provider = new \phpbb\auth\provider\apache($db, $config, $passwords_manager, $this->request, $this->user, $phpbb_root_path, $phpEx); } public function getDataSet() { - return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user.xml'); + if ((version_compare(PHP_VERSION, '5.3.7', '<'))) + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user_533.xml'); + } + else + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user.xml'); + } } /** @@ -78,7 +106,7 @@ class phpbb_auth_provider_apache_test extends phpbb_database_test_case 'user_row' => array( 'user_id' => '1', 'username' => 'foobar', - 'user_password' => '$H$9E45lK6J8nLTSm9oJE5aNCSTFK9wqa/', + 'user_password' => $this->password_hash, 'user_passchg' => '0', 'user_email' => 'example@example.com', 'user_type' => '0', @@ -114,7 +142,7 @@ class phpbb_auth_provider_apache_test extends phpbb_database_test_case 'user_regdate' => '0', 'username' => 'foobar', 'username_clean' => 'foobar', - 'user_password' => '$H$9E45lK6J8nLTSm9oJE5aNCSTFK9wqa/', + 'user_password' => $this->password_hash, 'user_passchg' => '0', 'user_pass_convert' => '0', 'user_email' => 'example@example.com', @@ -133,7 +161,7 @@ class phpbb_auth_provider_apache_test extends phpbb_database_test_case 'user_inactive_time' => '0', 'user_posts' => '0', 'user_lang' => '', - 'user_timezone' => 'UTC', + 'user_timezone' => '', 'user_dateformat' => 'd M Y H:i', 'user_style' => '0', 'user_rank' => '0', @@ -165,15 +193,7 @@ class phpbb_auth_provider_apache_test extends phpbb_database_test_case 'user_sig' => '', 'user_sig_bbcode_uid' => '', 'user_sig_bbcode_bitfield' => '', - 'user_from' => '', - 'user_icq' => '', - 'user_aim' => '', - 'user_yim' => '', - 'user_msnm' => '', 'user_jabber' => '', - 'user_website' => '', - 'user_occ' => '', - 'user_interests' => '', 'user_actkey' => '', 'user_newpasswd' => '', 'user_form_salt' => '', diff --git a/tests/auth/provider_db_test.php b/tests/auth/provider_db_test.php index 140a28cd3d..91ffcdc2a7 100644 --- a/tests/auth/provider_db_test.php +++ b/tests/auth/provider_db_test.php @@ -7,13 +7,21 @@ * */ -require_once dirname(__FILE__).'/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; class phpbb_auth_provider_db_test extends phpbb_database_test_case { public function getDataSet() { - return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user.xml'); + if ((version_compare(PHP_VERSION, '5.3.7', '<'))) + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user_533.xml'); + } + else + { + return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user.xml'); + } } public function test_login() @@ -28,7 +36,27 @@ class phpbb_auth_provider_db_test extends phpbb_database_test_case )); $request = $this->getMock('\phpbb\request\request'); $user = $this->getMock('\phpbb\user'); - $provider = new \phpbb\auth\provider\db($db, $config, $request, $user, $phpbb_root_path, $phpEx); + $driver_helper = new \phpbb\passwords\driver\helper($config); + $passwords_drivers = array( + 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $driver_helper), + 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $driver_helper), + 'passwords.driver.salted_md5' => new \phpbb\passwords\driver\salted_md5($config, $driver_helper), + 'passwords.driver.phpass' => new \phpbb\passwords\driver\phpass($config, $driver_helper), + ); + + $passwords_helper = new \phpbb\passwords\helper; + // Set up passwords manager + $passwords_manager = new \phpbb\passwords\manager($config, $passwords_drivers, $passwords_helper, array_keys($passwords_drivers)); + + $provider = new \phpbb\auth\provider\db($db, $config, $passwords_manager, $request, $user, $phpbb_root_path, $phpEx); + if (version_compare(PHP_VERSION, '5.3.7', '<')) + { + $password_hash = '$2a$10$e01Syh9PbJjUkio66eFuUu4FhCE2nRgG7QPc1JACalsPXcIuG2bbi'; + } + else + { + $password_hash = '$2y$10$4RmpyVu2y8Yf/lP3.yQBquKvE54TCUuEDEBJYY6FDDFN3LcbCGz9i'; + } $expected = array( 'status' => LOGIN_SUCCESS, @@ -36,7 +64,7 @@ class phpbb_auth_provider_db_test extends phpbb_database_test_case 'user_row' => array( 'user_id' => '1', 'username' => 'foobar', - 'user_password' => '$H$9E45lK6J8nLTSm9oJE5aNCSTFK9wqa/', + 'user_password' => $password_hash, 'user_passchg' => '0', 'user_pass_convert' => '0', 'user_email' => 'example@example.com', @@ -46,5 +74,10 @@ class phpbb_auth_provider_db_test extends phpbb_database_test_case ); $this->assertEquals($expected, $provider->login('foobar', 'example')); + + // Check if convert works + $login_return = $provider->login('foobar2', 'example'); + $password_start = (version_compare(PHP_VERSION, '5.3.7', '<')) ? '$2a$10$' : '$2y$10$'; + $this->assertStringStartsWith($password_start, $login_return['user_row']['user_password']); } } diff --git a/tests/avatar/driver/barfoo.php b/tests/avatar/driver/barfoo.php index 11c100db36..0bf30b8a91 100644 --- a/tests/avatar/driver/barfoo.php +++ b/tests/avatar/driver/barfoo.php @@ -18,4 +18,9 @@ class barfoo extends \phpbb\avatar\driver\driver {
return false;
}
+
+ public function get_template_name()
+ {
+ return 'barfoo.html';
+ }
}
diff --git a/tests/avatar/driver/foobar.php b/tests/avatar/driver/foobar.php index a1e7bdf7cc..aabdaf5ac4 100644 --- a/tests/avatar/driver/foobar.php +++ b/tests/avatar/driver/foobar.php @@ -18,4 +18,9 @@ class foobar extends \phpbb\avatar\driver\driver {
return false;
}
+
+ public function get_template_name()
+ {
+ return 'foobar.html';
+ }
}
diff --git a/tests/avatar/manager_test.php b/tests/avatar/manager_test.php index ba1fb04b33..527bb223d5 100644 --- a/tests/avatar/manager_test.php +++ b/tests/avatar/manager_test.php @@ -25,9 +25,17 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase $config = new \phpbb\config\config(array()); $request = $this->getMock('\phpbb\request\request'); $cache = $this->getMock('\phpbb\cache\driver\driver_interface'); + $path_helper = new \phpbb\path_helper( + new \phpbb\symfony_request( + new phpbb_mock_request() + ), + new \phpbb\filesystem(), + $this->phpbb_root_path, + $this->phpEx + ); // $this->avatar_foobar will be needed later on - $this->avatar_foobar = $this->getMock('\phpbb\avatar\driver\foobar', array('get_name'), array($config, $phpbb_root_path, $phpEx, $cache)); + $this->avatar_foobar = $this->getMock('\phpbb\avatar\driver\foobar', array('get_name'), array($config, $phpbb_root_path, $phpEx, $path_helper, $cache)); $this->avatar_foobar->expects($this->any()) ->method('get_name') ->will($this->returnValue('avatar.driver.foobar')); @@ -40,7 +48,7 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase foreach ($this->avatar_drivers() as $driver) { - $cur_avatar = $this->getMock('\phpbb\avatar\driver\\' . $driver, array('get_name'), array($config, $phpbb_root_path, $phpEx, $cache)); + $cur_avatar = $this->getMock('\phpbb\avatar\driver\\' . $driver, array('get_name'), array($config, $phpbb_root_path, $phpEx, $path_helper, $cache)); $cur_avatar->expects($this->any()) ->method('get_name') ->will($this->returnValue('avatar.driver.' . $driver)); @@ -104,7 +112,7 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase public function test_get_driver_enabled($driver_name, $expected) { $driver = $this->manager->get_driver($driver_name); - $this->assertEquals($expected, $driver); + $this->assertEquals($expected, ($driver === null) ? null : $driver->get_name()); } public function get_driver_data_all() @@ -125,7 +133,7 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase public function test_get_driver_all($driver_name, $expected) { $driver = $this->manager->get_driver($driver_name, false); - $this->assertEquals($expected, $driver); + $this->assertEquals($expected, ($driver === null) ? $driver : $driver->get_name()); } public function test_get_avatar_settings() @@ -144,11 +152,23 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase return array( array( array( - 'user_avatar' => '', - 'user_avatar_type' => '', - 'user_avatar_width' => '', + 'user_avatar' => '', + 'user_avatar_type' => '', + 'user_avatar_width' => '', + 'user_avatar_height' => '', + 'group_avatar' => '', + ), + array( + 'user_avatar' => '', + 'user_avatar_type' => '', + 'user_avatar_width' => '', 'user_avatar_height' => '', + 'group_avatar' => '', ), + 'foobar', + ), + array( + array(), array( 'avatar' => '', 'avatar_type' => '', @@ -158,40 +178,41 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase ), array( array( - 'group_avatar' => '', - 'group_avatar_type' => '', - 'group_avatar_width' => '', - 'group_avatar_height' => '', + 'user_avatar' => '', + 'user_id' => 5, + 'group_id' => 4, ), array( - 'avatar' => '', - 'avatar_type' => '', - 'avatar_width' => '', - 'avatar_height' => '', + 'user_avatar' => '', + 'user_id' => 5, + 'group_id' => 4, ), ), array( - array(), array( - 'avatar' => '', - 'avatar_type' => '', - 'avatar_width' => '', - 'avatar_height' => '', + 'user_avatar' => '', + 'user_id' => 5, + 'group_id' => 4, + ), + array( + 'avatar' => '', + 'id' => 5, + 'group_id' => 4, ), + 'user', ), array( array( - 'foobar_avatar' => '', - 'foobar_avatar_type' => '', - 'foobar_avatar_width' => '', - 'foobar_avatar_height' => '', + 'group_avatar' => '', + 'user_id' => 5, + 'group_id' => 4, ), array( - 'foobar_avatar' => '', - 'foobar_avatar_type' => '', - 'foobar_avatar_width' => '', - 'foobar_avatar_height' => '', + 'avatar' => '', + 'id' => 'g4', + 'user_id' => 5, ), + 'group', ), ); } @@ -199,14 +220,15 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase /** * @dataProvider database_row_data */ - public function test_clean_row(array $input, array $output) + public function test_clean_row(array $input, array $output, $prefix = '') { $cleaned_row = array(); - $cleaned_row = \phpbb\avatar\manager::clean_row($input); - foreach ($output as $key => $null) + $cleaned_row = \phpbb\avatar\manager::clean_row($input, $prefix); + foreach ($output as $key => $value) { $this->assertArrayHasKey($key, $cleaned_row); + $this->assertEquals($cleaned_row[$key], $value); } } diff --git a/tests/content_visibility/fixtures/delete_post.xml b/tests/content_visibility/fixtures/delete_post.xml index deca9c74b6..c29ad23019 100644 --- a/tests/content_visibility/fixtures/delete_post.xml +++ b/tests/content_visibility/fixtures/delete_post.xml @@ -151,8 +151,6 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>4</value> @@ -160,8 +158,6 @@ <value>user 1</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> </dataset> diff --git a/tests/content_visibility/fixtures/set_post_visibility.xml b/tests/content_visibility/fixtures/set_post_visibility.xml index 722525deaa..5f792d0f05 100644 --- a/tests/content_visibility/fixtures/set_post_visibility.xml +++ b/tests/content_visibility/fixtures/set_post_visibility.xml @@ -126,8 +126,6 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>1</value> @@ -135,8 +133,6 @@ <value>user 1</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>2</value> @@ -145,8 +141,6 @@ <value>user 2</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> @@ -155,8 +149,6 @@ <value>user 3</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> </dataset> diff --git a/tests/content_visibility/fixtures/set_topic_visibility.xml b/tests/content_visibility/fixtures/set_topic_visibility.xml index a875012d4f..02ab5f16fe 100644 --- a/tests/content_visibility/fixtures/set_topic_visibility.xml +++ b/tests/content_visibility/fixtures/set_topic_visibility.xml @@ -120,8 +120,6 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>6</value> @@ -129,8 +127,6 @@ <value>user 1</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> </dataset> diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php index 10fced05a2..550679ff07 100644 --- a/tests/controller/controller_test.php +++ b/tests/controller/controller_test.php @@ -21,23 +21,28 @@ class phpbb_controller_controller_test extends phpbb_test_case $this->extension_manager = new phpbb_mock_extension_manager( dirname(__FILE__) . '/', array( - 'foo' => array( - 'ext_name' => 'foo', + 'vendor2/foo' => array( + 'ext_name' => 'vendor2/foo', 'ext_active' => '1', - 'ext_path' => 'ext/foo/', + 'ext_path' => 'ext/vendor2/foo/', ), )); } public function test_provider() { - $provider = new \phpbb\controller\provider; - $routes = $provider - ->import_paths_from_finder($this->extension_manager->get_finder()) - ->find('./tests/controller/'); + $provider = new \phpbb\controller\provider($this->extension_manager->get_finder()); + $routes = $provider->find(__DIR__)->get_routes(); // This will need to be updated if any new routes are defined - $this->assertEquals(2, sizeof($routes)); + $this->assertInstanceOf('Symfony\Component\Routing\Route', $routes->get('core_controller')); + $this->assertEquals('/core_foo', $routes->get('core_controller')->getPath()); + + $this->assertInstanceOf('Symfony\Component\Routing\Route', $routes->get('controller1')); + $this->assertEquals('/foo', $routes->get('controller1')->getPath()); + + $this->assertInstanceOf('Symfony\Component\Routing\Route', $routes->get('controller2')); + $this->assertEquals('/foo/bar', $routes->get('controller2')->getPath()); } public function test_controller_resolver() @@ -45,7 +50,7 @@ class phpbb_controller_controller_test extends phpbb_test_case $container = new ContainerBuilder(); // YamlFileLoader only uses one path at a time, so we need to loop // through all of the ones we are using. - foreach (array(__DIR__.'/config', __DIR__.'/ext/foo/config') as $path) + foreach (array(__DIR__.'/config', __DIR__ . '/ext/vendor2/foo/config') as $path) { $loader = new YamlFileLoader($container, new FileLocator($path)); $loader->load('services.yml'); @@ -53,9 +58,9 @@ class phpbb_controller_controller_test extends phpbb_test_case // Autoloading classes within the tests folder does not work // so I'll include them manually. - if (!class_exists('foo\\controller')) + if (!class_exists('vendor2\\foo\\controller')) { - include(__DIR__.'/ext/foo/controller.php'); + include(__DIR__ . '/ext/vendor2/foo/controller.php'); } if (!class_exists('phpbb\\controller\\foo')) { diff --git a/tests/controller/ext/foo/config/routing.yml b/tests/controller/ext/vendor2/foo/config/routing.yml index 4799fec37d..6cc275d96d 100644 --- a/tests/controller/ext/foo/config/routing.yml +++ b/tests/controller/ext/vendor2/foo/config/routing.yml @@ -1,3 +1,7 @@ controller1: pattern: /foo defaults: { _controller: foo.controller:handle } + +include_controller2: + resource: "routing_2.yml" + prefix: /foo diff --git a/tests/controller/ext/vendor2/foo/config/routing_2.yml b/tests/controller/ext/vendor2/foo/config/routing_2.yml new file mode 100644 index 0000000000..d987a65aea --- /dev/null +++ b/tests/controller/ext/vendor2/foo/config/routing_2.yml @@ -0,0 +1,6 @@ +controller2: + pattern: /bar + defaults: { _controller: foo.controller:handle } +controller3: + pattern: /bar/p-{p} + defaults: { _controller: foo.controller:handle } diff --git a/tests/controller/ext/foo/config/services.yml b/tests/controller/ext/vendor2/foo/config/services.yml index 9ed67d5bc2..9ed67d5bc2 100644 --- a/tests/controller/ext/foo/config/services.yml +++ b/tests/controller/ext/vendor2/foo/config/services.yml diff --git a/tests/controller/ext/foo/controller.php b/tests/controller/ext/vendor2/foo/controller.php index ce2233b3c9..ce2233b3c9 100644 --- a/tests/controller/ext/foo/controller.php +++ b/tests/controller/ext/vendor2/foo/controller.php diff --git a/tests/controller/helper_route_test.php b/tests/controller/helper_route_test.php new file mode 100644 index 0000000000..5264c788c7 --- /dev/null +++ b/tests/controller/helper_route_test.php @@ -0,0 +1,128 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_controller_helper_route_test extends phpbb_test_case +{ + public function setUp() + { + global $phpbb_dispatcher, $phpbb_root_path, $phpEx; + + $phpbb_dispatcher = new phpbb_mock_event_dispatcher; + $this->user = $this->getMock('\phpbb\user'); + $phpbb_path_helper = new \phpbb\path_helper( + new \phpbb\symfony_request( + new phpbb_mock_request() + ), + new \phpbb\filesystem(), + $phpbb_root_path, + $phpEx + ); + $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); + $this->template = new phpbb\template\twig\twig($phpbb_path_helper, $this->config, $this->user, new \phpbb\template\context()); + + $finder = new \phpbb\extension\finder( + new phpbb_mock_extension_manager( + dirname(__FILE__) . '/', + array( + 'vendor2/foo' => array( + 'ext_name' => 'vendor2/foo', + 'ext_active' => '1', + 'ext_path' => 'ext/vendor2/foo/', + ), + ) + ), + new \phpbb\filesystem(), + dirname(__FILE__) . '/', + new phpbb_mock_cache() + ); + $this->provider = new \phpbb\controller\provider($finder); + $this->provider->find(dirname(__FILE__) . '/'); + } + + public function helper_url_data_no_rewrite() + { + return array( + array('controller2', array('t' => 1, 'f' => 2), true, false, 'app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), + array('controller2', array('t' => 1, 'f' => 2), false, false, 'app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), + array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, 'app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, 'app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + + // Custom sid parameter + array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', 'app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + + // Testing anchors + array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), + array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, 'app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), + array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'app.php/foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), + + // Anchors and custom sid + array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + + // Empty parameters should not append the & or ? + array('controller2', array(), true, false, 'app.php/foo/bar', 'no params using empty array'), + array('controller2', array(), false, false, 'app.php/foo/bar', 'no params using empty array'), + array('controller3', array('p' => 3), true, false, 'app.php/foo/bar/p-3', 'no params using empty array'), + ); + } + + /** + * @dataProvider helper_url_data_no_rewrite() + */ + public function test_helper_url_no_rewrite($route, $params, $is_amp, $session_id, $expected, $description) + { + $this->helper = new \phpbb\controller\helper($this->template, $this->user, $this->config, $this->provider, '', 'php'); + $this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id)); + } + + public function helper_url_data_with_rewrite() + { + return array( + array('controller2', array('t' => 1, 'f' => 2), true, false, 'foo/bar?t=1&f=2', 'parameters in params-argument as array'), + array('controller2', array('t' => 1, 'f' => 2), false, false, 'foo/bar?t=1&f=2', 'parameters in params-argument as array'), + array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, 'foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, 'foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + + // Custom sid parameter + array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', 'foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + + // Testing anchors + array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), + array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, 'foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), + array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), + + // Anchors and custom sid + array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + + // Empty parameters should not append the & or ? + array('controller2', array(), true, false, 'foo/bar', 'no params using empty array'), + array('controller2', array(), false, false, 'foo/bar', 'no params using empty array'), + array('controller3', array('p' => 3), true, false, 'foo/bar/p-3', 'no params using empty array'), + ); + } + + /** + * @dataProvider helper_url_data_with_rewrite() + */ + public function test_helper_url_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) + { + $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); + $this->helper = new \phpbb\controller\helper($this->template, $this->user, $this->config, $this->provider, '', 'php'); + $this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id)); + } +} diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php deleted file mode 100644 index 33fc6c4f1b..0000000000 --- a/tests/controller/helper_url_test.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php -/** -* -* @package testing -* @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; - -class phpbb_controller_helper_url_test extends phpbb_test_case -{ - - public function helper_url_data_no_rewrite() - { - return array( - array('foo/bar?t=1&f=2', false, true, false, 'app.php/foo/bar?t=1&f=2', 'parameters in url-argument'), - array('foo/bar', 't=1&f=2', true, false, 'app.php/foo/bar?t=1&f=2', 'parameters in params-argument using amp'), - array('foo/bar', 't=1&f=2', false, false, 'app.php/foo/bar?t=1&f=2', 'parameters in params-argument using &'), - array('foo/bar', array('t' => 1, 'f' => 2), true, false, 'app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), - - // Custom sid parameter - array('foo/bar', 't=1&f=2', true, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid', 'using session_id'), - - // Testing anchors - array('foo/bar?t=1&f=2#anchor', false, true, false, 'app.php/foo/bar?t=1&f=2#anchor', 'anchor in url-argument'), - array('foo/bar', 't=1&f=2#anchor', true, false, 'app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument'), - array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), - - // Anchors and custom sid - array('foo/bar?t=1&f=2#anchor', false, true, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in url-argument using session_id'), - array('foo/bar', 't=1&f=2#anchor', true, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument using session_id'), - array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), - - // Empty parameters should not append the & - array('foo/bar', false, true, false, 'app.php/foo/bar', 'no params using bool false'), - array('foo/bar', '', true, false, 'app.php/foo/bar', 'no params using empty string'), - array('foo/bar', array(), true, false, 'app.php/foo/bar', 'no params using empty array'), - ); - } - - /** - * @dataProvider helper_url_data_no_rewrite() - */ - public function test_helper_url_no_rewrite($route, $params, $is_amp, $session_id, $expected, $description) - { - global $phpbb_dispatcher, $phpbb_root_path, $phpEx; - - $phpbb_dispatcher = new phpbb_mock_event_dispatcher; - $this->user = $this->getMock('\phpbb\user'); - $phpbb_path_helper = new \phpbb\path_helper( - new \phpbb\symfony_request( - new phpbb_mock_request() - ), - new \phpbb\filesystem(), - $phpbb_root_path, - $phpEx - ); - $this->template = new phpbb\template\twig\twig($phpbb_path_helper, $config, $this->user, new \phpbb\template\context()); - - // We don't use mod_rewrite in these tests - $config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); - $helper = new \phpbb\controller\helper($this->template, $this->user, $config, '', 'php'); - $this->assertEquals($helper->url($route, $params, $is_amp, $session_id), $expected); - } - - public function helper_url_data_with_rewrite() - { - return array( - array('foo/bar?t=1&f=2', false, true, false, 'foo/bar?t=1&f=2', 'parameters in url-argument'), - array('foo/bar', 't=1&f=2', true, false, 'foo/bar?t=1&f=2', 'parameters in params-argument using amp'), - array('foo/bar', 't=1&f=2', false, false, 'foo/bar?t=1&f=2', 'parameters in params-argument using &'), - array('foo/bar', array('t' => 1, 'f' => 2), true, false, 'foo/bar?t=1&f=2', 'parameters in params-argument as array'), - - // Custom sid parameter - array('foo/bar', 't=1&f=2', true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid', 'using session_id'), - - // Testing anchors - array('foo/bar?t=1&f=2#anchor', false, true, false, 'foo/bar?t=1&f=2#anchor', 'anchor in url-argument'), - array('foo/bar', 't=1&f=2#anchor', true, false, 'foo/bar?t=1&f=2#anchor', 'anchor in params-argument'), - array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), - - // Anchors and custom sid - array('foo/bar?t=1&f=2#anchor', false, true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in url-argument using session_id'), - array('foo/bar', 't=1&f=2#anchor', true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument using session_id'), - array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), - - // Empty parameters should not append the & - array('foo/bar', false, true, false, 'foo/bar', 'no params using bool false'), - array('foo/bar', '', true, false, 'foo/bar', 'no params using empty string'), - array('foo/bar', array(), true, false, 'foo/bar', 'no params using empty array'), - ); - } - - /** - * @dataProvider helper_url_data_with_rewrite() - */ - public function test_helper_url_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) - { - global $phpbb_dispatcher, $phpbb_root_path, $phpEx; - - $phpbb_dispatcher = new phpbb_mock_event_dispatcher; - $this->user = $this->getMock('\phpbb\user'); - $phpbb_path_helper = new \phpbb\path_helper( - new \phpbb\symfony_request( - new phpbb_mock_request() - ), - new \phpbb\filesystem(), - $phpbb_root_path, - $phpEx - ); - $this->template = new \phpbb\template\twig\twig($phpbb_path_helper, $config, $this->user, new \phpbb\template\context()); - - $config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); - $helper = new \phpbb\controller\helper($this->template, $this->user, $config, '', 'php'); - $this->assertEquals($helper->url($route, $params, $is_amp, $session_id), $expected); - } -} diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index e25335165a..df8f22083b 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -11,7 +11,9 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; class phpbb_dbal_db_tools_test extends phpbb_database_test_case { + /** @var \phpbb\db\driver\driver_interface */ protected $db; + /** @var \phpbb\db\tools */ protected $tools; protected $table_exists; protected $table_data; @@ -207,6 +209,32 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'column_does_not_exist')); } + public function test_column_change_with_index() + { + // Create column + $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012')); + $this->assertTrue($this->tools->sql_column_add('prefix_table_name', 'c_bug_12012', array('DECIMAL', 0))); + $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012')); + + // Create index over the column + $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012')); + $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'i_bug_12012', array('c_bug_12012', 'c_bool'))); + $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012')); + + // Change type from int to string + $this->assertTrue($this->tools->sql_column_change('prefix_table_name', 'c_bug_12012', array('VCHAR:100', ''))); + + // Remove the index + $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012')); + $this->assertTrue($this->tools->sql_index_drop('prefix_table_name', 'i_bug_12012')); + $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012')); + + // Remove the column + $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012')); + $this->assertTrue($this->tools->sql_column_remove('prefix_table_name', 'c_bug_12012')); + $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012')); + } + public function test_column_remove() { $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_int_size')); @@ -216,6 +244,28 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_int_size')); } + public function test_column_remove_with_index() + { + // Create column + $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2')); + $this->assertTrue($this->tools->sql_column_add('prefix_table_name', 'c_bug_12012_2', array('UINT', 4))); + $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2')); + + // Create index over the column + $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_2')); + $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'i_bug_12012_2', array('c_bug_12012_2', 'c_bool'))); + $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_2')); + + $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_3')); + $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'i_bug_12012_3', array('c_bug_12012_2'))); + $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_3')); + + // Remove the column + $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2')); + $this->assertTrue($this->tools->sql_column_remove('prefix_table_name', 'c_bug_12012_2')); + $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2')); + } + public function test_column_remove_primary() { $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_id')); @@ -252,7 +302,7 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case $this->assertFalse($this->tools->sql_table_exists('prefix_test_table')); } - public function test_peform_schema_changes_drop_tables() + public function test_perform_schema_changes_drop_tables() { $db_tools = $this->getMock('\phpbb\db\tools', array( 'sql_table_exists', @@ -278,7 +328,7 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case )); } - public function test_peform_schema_changes_drop_columns() + public function test_perform_schema_changes_drop_columns() { $db_tools = $this->getMock('\phpbb\db\tools', array( 'sql_column_exists', diff --git a/tests/dbal/fixtures/massmail_crossjoin.xml b/tests/dbal/fixtures/massmail_crossjoin.xml index ef0a2b7149..1050ba067e 100644 --- a/tests/dbal/fixtures/massmail_crossjoin.xml +++ b/tests/dbal/fixtures/massmail_crossjoin.xml @@ -14,16 +14,12 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>mass email</value> <value>mass email</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>2</value> @@ -31,8 +27,6 @@ <value>banned</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> @@ -40,8 +34,6 @@ <value>not in group</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_user_group"> diff --git a/tests/dbal/fixtures/three_users.xml b/tests/dbal/fixtures/three_users.xml index a50e3e8634..a601e539e1 100644 --- a/tests/dbal/fixtures/three_users.xml +++ b/tests/dbal/fixtures/three_users.xml @@ -5,31 +5,23 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>barfoo</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>2</value> <value>foobar</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> <value>bertie</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> </dataset> diff --git a/tests/dbal/migration/dummy.php b/tests/dbal/migration/dummy.php index 041c529855..b68a3673c1 100644 --- a/tests/dbal/migration/dummy.php +++ b/tests/dbal/migration/dummy.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/dbal/migration/fail.php b/tests/dbal/migration/fail.php index d90972720d..b0702a469a 100644 --- a/tests/dbal/migration/fail.php +++ b/tests/dbal/migration/fail.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/dbal/migration/if.php b/tests/dbal/migration/if.php index bbbda60ea3..883d93c6e4 100644 --- a/tests/dbal/migration/if.php +++ b/tests/dbal/migration/if.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/dbal/migration/installed.php b/tests/dbal/migration/installed.php index 4b86896d9c..cc4e81aff6 100644 --- a/tests/dbal/migration/installed.php +++ b/tests/dbal/migration/installed.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/dbal/migration/recall.php b/tests/dbal/migration/recall.php index 041d12ad27..af5e9243cf 100644 --- a/tests/dbal/migration/recall.php +++ b/tests/dbal/migration/recall.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/dbal/migration/revert.php b/tests/dbal/migration/revert.php index 1882b20492..1c98710ffb 100644 --- a/tests/dbal/migration/revert.php +++ b/tests/dbal/migration/revert.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -35,6 +35,14 @@ class phpbb_dbal_migration_revert extends \phpbb\db\migration\migration { return array( array('config.add', array('foobartest', 0)), + array('custom', array(array(&$this, 'my_custom_function'))), ); } + + function my_custom_function() + { + global $migrator_test_revert_counter; + + $migrator_test_revert_counter += 1; + } } diff --git a/tests/dbal/migration/revert_with_dependency.php b/tests/dbal/migration/revert_with_dependency.php index 0b09fb784d..ece16eb67c 100644 --- a/tests/dbal/migration/revert_with_dependency.php +++ b/tests/dbal/migration/revert_with_dependency.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/dbal/migration/schema.php b/tests/dbal/migration/schema.php new file mode 100644 index 0000000000..efe6891aaa --- /dev/null +++ b/tests/dbal/migration/schema.php @@ -0,0 +1,44 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_dbal_migration_schema extends \phpbb\db\migration\migration +{ + function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'config' => array( + 'test_column1' => array('BOOL', 1), + ), + ), + 'add_tables' => array( + $this->table_prefix . 'foobar' => array( + 'COLUMNS' => array( + 'module_id' => array('UINT:3', NULL, 'auto_increment'), + ), + 'PRIMARY_KEY' => 'module_id', + ), + ), + ); + } + + function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'config' => array( + 'test_column1', + ), + ), + 'drop_tables' => array( + $this->table_prefix . 'foobar', + ), + ); + } +} diff --git a/tests/dbal/migration/unfulfillable.php b/tests/dbal/migration/unfulfillable.php index a1cdef9a23..125629d27c 100644 --- a/tests/dbal/migration/unfulfillable.php +++ b/tests/dbal/migration/unfulfillable.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index c6b4c289d3..cc3e92071f 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -16,6 +16,7 @@ require_once dirname(__FILE__) . '/migration/revert.php'; require_once dirname(__FILE__) . '/migration/revert_with_dependency.php'; require_once dirname(__FILE__) . '/migration/fail.php'; require_once dirname(__FILE__) . '/migration/installed.php'; +require_once dirname(__FILE__) . '/migration/schema.php'; class phpbb_dbal_migrator_test extends phpbb_database_test_case { @@ -49,7 +50,8 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case dirname(__FILE__) . '/../../phpBB/', 'php', 'phpbb_', - $tools + $tools, + new \phpbb\db\migration\helper() ); $container = new phpbb_mock_container_builder(); @@ -172,10 +174,14 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case public function test_revert() { + global $migrator_test_revert_counter; + // Make sure there are no other migrations in the db, this could cause issues $this->db->sql_query("DELETE FROM phpbb_migrations"); $this->migrator->load_migration_state(); + $migrator_test_revert_counter = 0; + $this->migrator->set_migrations(array('phpbb_dbal_migration_revert', 'phpbb_dbal_migration_revert_with_dependency')); $this->assertFalse($this->migrator->migration_state('phpbb_dbal_migration_revert')); @@ -217,6 +223,8 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case { $this->fail('Revert did not remove test_column.'); } + + $this->assertEquals(1, $migrator_test_revert_counter, 'Revert did call custom function again'); } public function test_fail() @@ -267,4 +275,25 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->fail('Installed test failed'); } } + + public function test_schema() + { + $this->migrator->set_migrations(array('phpbb_dbal_migration_schema')); + + while (!$this->migrator->finished()) + { + $this->migrator->update(); + } + + $this->assertTrue($this->db_tools->sql_column_exists('phpbb_config', 'test_column1')); + $this->assertTrue($this->db_tools->sql_table_exists('phpbb_foobar')); + + while ($this->migrator->migration_state('phpbb_dbal_migration_schema')) + { + $this->migrator->revert('phpbb_dbal_migration_schema'); + } + + $this->assertFalse($this->db_tools->sql_column_exists('phpbb_config', 'test_column1')); + $this->assertFalse($this->db_tools->sql_table_exists('phpbb_foobar')); + } } diff --git a/tests/dbal/migrator_tool_config_test.php b/tests/dbal/migrator_tool_config_test.php index a8d8966839..12644e4a23 100644 --- a/tests/dbal/migrator_tool_config_test.php +++ b/tests/dbal/migrator_tool_config_test.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -20,35 +20,24 @@ class phpbb_dbal_migrator_tool_config_test extends phpbb_test_case public function test_add() { - try - { - $this->tool->add('foo', 'bar'); - } - catch (Exception $e) - { - $this->fail($e); - } + $this->tool->add('foo', 'bar'); + $this->assertEquals('bar', $this->config['foo']); + } + + public function test_add_twice() + { + $this->tool->add('foo', 'bar'); $this->assertEquals('bar', $this->config['foo']); - try - { - $this->tool->add('foo', 'bar'); - $this->fail('Exception not thrown'); - } - catch (Exception $e) {} + $this->tool->add('foo', 'bar2'); + $this->assertEquals('bar', $this->config['foo']); } public function test_update() { $this->config->set('foo', 'bar'); - try - { - $this->tool->update('foo', 'bar2'); - } - catch (Exception $e) - { - $this->fail($e); - } + + $this->tool->update('foo', 'bar2'); $this->assertEquals('bar2', $this->config['foo']); } @@ -56,24 +45,10 @@ class phpbb_dbal_migrator_tool_config_test extends phpbb_test_case { $this->config->set('foo', 'bar'); - try - { - $this->tool->update_if_equals('', 'foo', 'bar2'); - } - catch (Exception $e) - { - $this->fail($e); - } + $this->tool->update_if_equals('', 'foo', 'bar2'); $this->assertEquals('bar', $this->config['foo']); - try - { - $this->tool->update_if_equals('bar', 'foo', 'bar2'); - } - catch (Exception $e) - { - $this->fail($e); - } + $this->tool->update_if_equals('bar', 'foo', 'bar2'); $this->assertEquals('bar2', $this->config['foo']); } @@ -81,41 +56,31 @@ class phpbb_dbal_migrator_tool_config_test extends phpbb_test_case { $this->config->set('foo', 'bar'); - try - { - $this->tool->remove('foo'); - } - catch (Exception $e) - { - $this->fail($e); - } + $this->tool->remove('foo'); $this->assertFalse(isset($this->config['foo'])); } - public function test_reverse() + public function test_reverse_add() { $this->config->set('foo', 'bar'); - try - { - $this->tool->reverse('add', 'foo'); - } - catch (Exception $e) - { - $this->fail($e); - } + $this->tool->reverse('add', 'foo'); $this->assertFalse(isset($this->config['foo'])); + } + + public function test_reverse_remove() + { + $this->config->delete('foo'); + $this->tool->reverse('remove', 'foo'); + $this->assertEquals('', $this->config['foo']); + } + + public function test_reverse_update_if_equals() + { $this->config->set('foo', 'bar'); - try - { - $this->tool->reverse('update_if_equals', 'test', 'foo', 'bar'); - } - catch (Exception $e) - { - $this->fail($e); - } + $this->tool->reverse('update_if_equals', 'test', 'foo', 'bar'); $this->assertEquals('test', $this->config['foo']); } } diff --git a/tests/dbal/migrator_tool_module_test.php b/tests/dbal/migrator_tool_module_test.php index 3c23891348..c3358ef944 100644 --- a/tests/dbal/migrator_tool_module_test.php +++ b/tests/dbal/migrator_tool_module_test.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/dbal/migrator_tool_permission_test.php b/tests/dbal/migrator_tool_permission_test.php index 1090b4726a..4016cbcf20 100644 --- a/tests/dbal/migrator_tool_permission_test.php +++ b/tests/dbal/migrator_tool_permission_test.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/dbal/write_sequence_test.php b/tests/dbal/write_sequence_test.php index f382a971a5..5fe0fe8de9 100644 --- a/tests/dbal/write_sequence_test.php +++ b/tests/dbal/write_sequence_test.php @@ -42,8 +42,6 @@ class phpbb_dbal_write_sequence_test extends phpbb_database_test_case 'username_clean' => $username, 'user_permissions' => '', 'user_sig' => '', - 'user_occ' => '', - 'user_interests' => '', )); $db->sql_query($sql); diff --git a/tests/di/create_container_test.php b/tests/di/create_container_test.php index a3a1ad3597..46d97ba8ba 100644 --- a/tests/di/create_container_test.php +++ b/tests/di/create_container_test.php @@ -59,19 +59,43 @@ namespace phpbb\db\driver { class container_mock extends \phpbb\db\driver\driver { - public function sql_connect() + public function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { } - public function sql_query() + public function sql_query($query = '', $cache_ttl = 0) { } - public function sql_fetchrow() + public function sql_fetchrow($query_id = false) { } - public function sql_freeresult() + public function sql_freeresult($query_id = false) + { + } + + function sql_server_info($raw = false, $use_cache = true) + { + } + + function sql_affectedrows() + { + } + + function sql_rowseek($rownum, &$query_id) + { + } + + function sql_nextid() + { + } + + function sql_escape($msg) + { + } + + function sql_like_expression($expression) { } } diff --git a/tests/event/export_php_test.php b/tests/event/export_php_test.php new file mode 100644 index 0000000000..f38b524ffe --- /dev/null +++ b/tests/event/export_php_test.php @@ -0,0 +1,45 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_event_export_php_test extends phpbb_test_case +{ + /** @var \phpbb\event\php_exporter */ + protected $exporter; + + public function setUp() + { + parent::setUp(); + + global $phpbb_root_path; + $this->exporter = new \phpbb\event\php_exporter($phpbb_root_path); + } + + static public function crawl_php_file_data() + { + global $phpbb_root_path; + $exporter = new \phpbb\event\php_exporter($phpbb_root_path); + $files = $exporter->get_recursive_file_list($phpbb_root_path); + + $data_provider = array(); + foreach ($files as $file) + { + $data_provider[] = array($file); + } + + return $data_provider; + } + + /** + * @dataProvider crawl_php_file_data + */ + public function test_crawl_php_file($file) + { + $this->assertGreaterThanOrEqual(0, $this->exporter->crawl_php_file($file)); + } +} diff --git a/tests/event/fixtures/default.test b/tests/event/fixtures/default.test new file mode 100644 index 0000000000..edfe4823dc --- /dev/null +++ b/tests/event/fixtures/default.test @@ -0,0 +1,9 @@ +<?php + +/** +* Description +* +* @event default.dispatch +* @since 3.1.0-b2 +*/ +$phpbb_dispatcher->dispatch('default.dispatch'); diff --git a/tests/event/fixtures/duplicate_event.test b/tests/event/fixtures/duplicate_event.test new file mode 100644 index 0000000000..b042ca0377 --- /dev/null +++ b/tests/event/fixtures/duplicate_event.test @@ -0,0 +1,19 @@ +<?php + + /** + * Event after the post data has been assigned to the template + * + * @event duplicate.trigger + * @var int start Start item of this page + * @since 3.1.0-a3 + */ + $vars = array('start'); + extract($phpbb_dispatcher->trigger_event('duplicate.trigger', compact($vars))); + + /** + * Event after the post data has been assigned to the template + * + * @event duplicate.trigger + * @since 3.1.0-b1 + */ + $phpbb_dispatcher->dispatch('duplicate.trigger'); diff --git a/tests/event/fixtures/extra_description.test b/tests/event/fixtures/extra_description.test new file mode 100644 index 0000000000..ce8f97ce89 --- /dev/null +++ b/tests/event/fixtures/extra_description.test @@ -0,0 +1,11 @@ +<?php + +/** +* Description +* +* NOTE: This will not be exported +* +* @event extra_description.dispatch +* @since 3.1.0-b2 +*/ +$phpbb_dispatcher->dispatch('extra_description.dispatch'); diff --git a/tests/event/fixtures/missing_var.test b/tests/event/fixtures/missing_var.test new file mode 100644 index 0000000000..7ced5e93dc --- /dev/null +++ b/tests/event/fixtures/missing_var.test @@ -0,0 +1,17 @@ +<?php + + /** + * Event after the post data has been assigned to the template + * + * @event core.trigger + * @var int start Start item of this page + * @var int current_row_number Number of the post on this page + * @var int end Number of posts on this page + * @var array row Array with original post and user data + * @var array cp_row Custom profile field data of the poster + * @var array attachments List of attachments + * @var array user_poster_data Poster's data from user cache + * @since 3.1.0-a3 + */ + $vars = array('start', 'current_row_number', 'end', 'row', 'cp_row', 'attachments', 'user_poster_data', 'post_row'); + extract($phpbb_dispatcher->trigger_event('core.trigger', compact($vars))); diff --git a/tests/event/fixtures/none.test b/tests/event/fixtures/none.test new file mode 100644 index 0000000000..6e2267024b --- /dev/null +++ b/tests/event/fixtures/none.test @@ -0,0 +1,6 @@ +<?php + +/** +* Hi there :) +*/ +echo 1 + 2; diff --git a/tests/event/fixtures/trigger.test b/tests/event/fixtures/trigger.test new file mode 100644 index 0000000000..7cd6a7b956 --- /dev/null +++ b/tests/event/fixtures/trigger.test @@ -0,0 +1,15 @@ +<?php + + /** + * Event after the post data has been assigned to the template + * + * @event core.trigger + * @var int start Start item of this page + * @var int current_row_number Number of the post on this page + * @var int end Number of posts on this page + * @var array row Array with original post and user data + * @var array cp_row Custom profile field data of the poster + * @since 3.1.0-a3 + */ + $vars = array('start', 'current_row_number', 'end', 'row', 'cp_row'); + extract($phpbb_dispatcher->trigger_event('core.trigger', compact($vars))); diff --git a/tests/event/fixtures/trigger_many_vars.test b/tests/event/fixtures/trigger_many_vars.test new file mode 100644 index 0000000000..a624138588 --- /dev/null +++ b/tests/event/fixtures/trigger_many_vars.test @@ -0,0 +1,65 @@ +<?php + + /** + * This event allows you to modify template variables for the posting screen + * + * @event core.posting_modify_template_vars + * @var array post_data Array with post data + * @var array moderators Array with forum moderators + * @var string mode What action to take if the form is submitted + * post|reply|quote|edit|delete|bump|smilies|popup + * @var string page_title Title of the mode page + * @var bool s_topic_icons Whether or not to show the topic icons + * @var string form_enctype If attachments are allowed for this form + * "multipart/form-data" or empty string + * @var string s_action The URL to submit the POST data to + * @var string s_hidden_fields Concatenated hidden input tags of posting form + * @var int post_id ID of the post + * @var int topic_id ID of the topic + * @var int forum_id ID of the forum + * @var bool submit Whether or not the form has been submitted + * @var bool preview Whether or not the post is being previewed + * @var bool save Whether or not a draft is being saved + * @var bool load Whether or not a draft is being loaded + * @var bool delete Whether or not the post is being deleted + * @var bool cancel Whether or not to cancel the form (returns to + * viewtopic or viewforum depending on if the user + * is posting a new topic or editing a post) + * @var array error Any error strings; a non-empty array aborts + * form submission. + * NOTE: Should be actual language strings, NOT + * language keys. + * @var bool refresh Whether or not to retain previously submitted data + * @var array page_data Posting page data that should be passed to the + * posting page via $template->assign_vars() + * @var object message_parser The message parser object + * @since 3.1.0-a1 + * @change 3.1.0-b3 Added vars post_data, moderators, mode, page_title, + * s_topic_icons, form_enctype, s_action, s_hidden_fields, + * post_id, topic_id, forum_id, submit, preview, save, load, + * delete, cancel, refresh, error, page_data, message_parser + */ + $vars = array( + 'post_data', + 'moderators', + 'mode', + 'page_title', + 's_topic_icons', + 'form_enctype', + 's_action', + 's_hidden_fields', + 'post_id', + 'topic_id', + 'forum_id', + 'submit', + 'preview', + 'save', + 'load', + 'delete', + 'cancel', + 'refresh', + 'error', + 'page_data', + 'message_parser', + ); + extract($phpbb_dispatcher->trigger_event('core.posting_modify_template_vars', compact($vars))); diff --git a/tests/event/md_exporter_test.php b/tests/event/md_exporter_test.php new file mode 100644 index 0000000000..b62b55accd --- /dev/null +++ b/tests/event/md_exporter_test.php @@ -0,0 +1,67 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_event_md_exporter_test extends phpbb_test_case +{ + + static public function crawl_eventsmd_data() + { + return array( + array('styles'), + array('adm'), + ); + } + + /** + * @dataProvider crawl_eventsmd_data + */ + public function test_crawl_eventsmd($filter) + { + global $phpbb_root_path; + $exporter = new \phpbb\event\md_exporter($phpbb_root_path); + $this->assertGreaterThan(0, $exporter->crawl_eventsmd('docs/events.md', $filter)); + } + + static public function crawl_template_file_data() + { + global $phpbb_root_path; + $exporter = new \phpbb\event\md_exporter($phpbb_root_path); + $data_provider = array(); + + $styles = array( + 'adm/style/' => 'adm', + 'styles/prosilver/template/' => 'styles', + 'styles/subsilver2/template/' => 'styles', + ); + foreach ($styles as $path => $filter) + { + $files = $exporter->get_recursive_file_list($phpbb_root_path . $path, $path); + foreach ($files as $file) + { + $data_provider[] = array($filter, $path . $file); + } + } + + return $data_provider; + } + + /** + * @dataProvider crawl_template_file_data + */ + public function test_crawl_template_file($filter, $file) + { + global $phpbb_root_path; + $exporter = new \phpbb\event\md_exporter($phpbb_root_path); + $exporter->crawl_eventsmd('docs/events.md', $filter); + $events = $exporter->crawl_file_for_events($file); + + $this->assertGreaterThanOrEqual(0, sizeof($events)); + $this->assertTrue($exporter->validate_events_from_file($file, $events)); + } +} diff --git a/tests/event/php_exporter_test.php b/tests/event/php_exporter_test.php new file mode 100644 index 0000000000..9917f8309b --- /dev/null +++ b/tests/event/php_exporter_test.php @@ -0,0 +1,722 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_event_php_exporter_test extends phpbb_test_case +{ + /** @var \phpbb\event\php_exporter */ + protected $exporter; + + public function setUp() + { + parent::setUp(); + $this->exporter = new \phpbb\event\php_exporter(dirname(__FILE__) . '/fixtures/'); + } + + static public function crawl_php_file_data() + { + return array( + array( + 'default.test', + array( + 'default.dispatch' => array( + 'event' => 'default.dispatch', + 'file' => 'default.test', + 'arguments' => array(), + 'since' => '3.1.0-b2', + 'description' => 'Description', + ), + ), + ), + array( + 'extra_description.test', + array( + 'extra_description.dispatch' => array( + 'event' => 'extra_description.dispatch', + 'file' => 'extra_description.test', + 'arguments' => array(), + 'since' => '3.1.0-b2', + 'description' => 'Description', + ), + ), + ), + array( + 'trigger.test', + array( + 'core.trigger' => array( + 'event' => 'core.trigger', + 'file' => 'trigger.test', + 'arguments' => array('cp_row', 'current_row_number', 'end', 'row', 'start'), + 'since' => '3.1.0-a3', + 'description' => 'Event after the post data has been assigned to the template', + ), + ), + ), + array( + 'trigger_many_vars.test', + array( + 'core.posting_modify_template_vars' => array( + 'event' => 'core.posting_modify_template_vars', + 'file' => 'trigger_many_vars.test', + 'arguments' => array( + 'cancel', 'delete', 'error', 'form_enctype', 'forum_id', + 'load', 'message_parser', 'mode', 'moderators', 'page_data', + 'page_title', 'post_data', 'post_id', 'preview', 'refresh', + 's_action', 's_hidden_fields', 's_topic_icons', 'save', + 'submit', 'topic_id', + ), + 'since' => '3.1.0-a1', + 'description' => 'This event allows you to modify template variables for the posting screen', + ), + ), + ), + array( + 'none.test', + array(), + ), + ); + } + + /** + * @dataProvider crawl_php_file_data + */ + public function test_crawl_php_file($file, $expected) + { + $this->exporter->crawl_php_file($file); + $this->assertEquals($expected, $this->exporter->get_events()); + } + + static public function crawl_php_file_throws_data() + { + return array( + array('missing_var.test', null), + array('duplicate_event.test', 10), + ); + } + + /** + * @dataProvider crawl_php_file_throws_data + */ + public function test_crawl_php_file_throws($file, $exception_code) + { + $this->setExpectedException('LogicException', '', $exception_code); + $this->exporter->crawl_php_file($file); + } + + static public function validate_since_data() + { + return array( + array('* @since 3.1.0-a1', '3.1.0-a1'), + array('* @since 3.1.0-b3', '3.1.0-b3'), + array(' * @since 3.1.0-b3', '3.1.0-b3'), + ); + } + + /** + * @dataProvider validate_since_data + */ + public function test_validate_since($since, $expected) + { + $this->assertEquals($expected, $this->exporter->validate_since($since)); + } + + static public function validate_since_throws_data() + { + return array( + array(' * @since 3.1.0-a1'), + array('* @since 3.1.0-a1 '), + array('* @since 3.1.0-a1 bertie is cool'), + array('bertie* @since 3.1.0-a1'), + array('* @since 3.1-A2'), + ); + } + + /** + * @dataProvider validate_since_throws_data + * @expectedException LogicException + */ + public function test_validate_since_throws($since) + { + $this->exporter->validate_since($since); + } + + static public function validate_event_data() + { + return array( + array('test.event', '* @event test.event', 'test.event'), + array('test.event2', ' * @event test.event2', 'test.event2'), + ); + } + + /** + * @dataProvider validate_event_data + */ + public function test_validate_event($event_name, $event, $expected) + { + $this->assertEquals($expected, $this->exporter->validate_event($event_name, $event)); + } + + static public function validate_event_throws_data() + { + return array( + array('test.event', ' * @event test.event', 1), + array('test.event', '* @event test.event bertie is cool', 2), + array('test.event', 'bertie* @event test.event', 2), + ); + } + + /** + * @dataProvider validate_event_throws_data + * @expectedException LogicException + */ + public function test_validate_event_throws($event_name, $event, $exception_code) + { + $this->setExpectedException('LogicException', '', $exception_code); + $this->exporter->validate_event($event_name, $event); + } + + static public function validate_vars_docblock_array_data() + { + return array( + array(array('abc', 'def'), array('abc', 'def')), + ); + } + + /** + * @dataProvider validate_vars_docblock_array_data + */ + public function test_validate_vars_docblock_array($vars_array, $vars_docblock) + { + $this->assertNull($this->exporter->validate_vars_docblock_array($vars_array, $vars_docblock)); + } + + static public function validate_vars_docblock_array_throws_data() + { + return array( + array(array('abc', 'def'), array()), + array(array('abc', 'def'), array('abc')), + array(array('abc', 'defg'), array('abc', 'def')), + array(array('abc'), array('abc', 'def')), + array(array(), array('abc', 'def')), + ); + } + + /** + * @dataProvider validate_vars_docblock_array_throws_data + * @expectedException LogicException + */ + public function test_validate_vars_docblock_array_throws($vars_array, $vars_docblock) + { + $this->exporter->validate_vars_docblock_array($vars_array, $vars_docblock); + } + + static public function get_dispatch_name_data() + { + return array( + array("\$phpbb_dispatcher->dispatch('dispatch.one2');", 'dispatch.one2'), + array("\t\$phpbb_dispatcher->dispatch('dispatch.one2.thr_ee4');", 'dispatch.one2.thr_ee4'), + array("\$this->dispatcher->dispatch('dispatch.one2');", 'dispatch.one2'), + array("\$phpbb_dispatcher->dispatch('dis_patch.one');", 'dis_patch.one'), + ); + } + + /** + * @dataProvider get_dispatch_name_data + */ + public function test_get_dispatch_name($event_line, $expected) + { + $this->exporter->set_content(array($event_line)); + $this->assertEquals($expected, $this->exporter->get_event_name(0, true)); + } + + static public function get_dispatch_name_throws_data() + { + return array( + array("\$phpbb_dispatcher->dispatch();"), + array("\$phpbb_dispatcher->dispatch('');"), + array("\$phpbb_dispatcher->dispatch('dispatch.2one');"), + array("\$phpbb_dispatcher->dispatch('dispatch');"), + ); + } + + /** + * @dataProvider get_dispatch_name_throws_data + * @expectedException LogicException + */ + public function test_get_dispatch_name_throws($event_line) + { + $this->exporter->set_content(array($event_line)); + $this->exporter->get_event_name(0, true); + } + + static public function get_trigger_event_name_data() + { + return array( + array("extract(\$phpbb_dispatcher->trigger_event('dispatch.one2', compact(\$vars)));", 'dispatch.one2'), + array("\textract(\$phpbb_dispatcher->trigger_event('dispatch.one2.thr_ee4', compact(\$vars)));", 'dispatch.one2.thr_ee4'), + array("extract(\$this->dispatcher->trigger_event('dispatch.one2', compact(\$vars)));", 'dispatch.one2'), + array("extract(\$phpbb_dispatcher->trigger_event('dis_patch.one', compact(\$vars)));", 'dis_patch.one'), + ); + } + + /** + * @dataProvider get_trigger_event_name_data + */ + public function test_get_trigger_event_name($event_line, $expected) + { + $this->exporter->set_content(array($event_line)); + $this->assertEquals($expected, $this->exporter->get_event_name(0, false)); + } + + static public function get_trigger_event_name_throws_data() + { + return array( + array("extract(\$phpbb_dispatcher->trigger_event());"), + array("extract(\$phpbb_dispatcher->trigger_event(''));"), + array("extract(\$phpbb_dispatcher->trigger_event('dispatch.2one'));"), + array("extract(\$phpbb_dispatcher->trigger_event('dispatch'));"), + array("extract(\$phpbb_dispatcher->trigger_event('dispatch.one', \$vars));"), + array("extract(\$phpbb_dispatcher->trigger_event('dispatch.one', compact(\$var)));"), + array("extract(\$phpbb_dispatcher->trigger_event('dispatch.one', compact(\$array)));"), + array("\$phpbb_dispatcher->trigger_event('dis_patch.one', compact(\$vars));", 'dis_patch.one'), + ); + } + + /** + * @dataProvider get_trigger_event_name_throws_data + * @expectedException LogicException + */ + public function test_get_trigger_event_name_throws($event_line) + { + $this->exporter->set_content(array($event_line)); + $this->exporter->get_event_name(0, false); + } + + static public function get_vars_from_array_data() + { + return array( + array( + array( + '/**', + '*/', + '$vars = array(\'bertie\');', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 3, + array('bertie'), + ), + array( + array( + "\t/**", + "\t*/", + "\t\$vars = array('_Strange123', 'phpBB3_Test');", + "\t\$this->dispatcher->dispatch('test');", + ), + 3, + array('_Strange123', 'phpBB3_Test'), + ), + ); + } + + /** + * @dataProvider get_vars_from_array_data + */ + public function test_get_vars_from_array($lines, $event_line, $expected) + { + $this->exporter->set_current_event('', $event_line); + $this->exporter->set_content($lines); + $this->assertEquals($expected, $this->exporter->get_vars_from_array()); + } + + static public function get_vars_from_array_throws_data() + { + return array( + array( + array( + '/**', + '*/', + '$phpbb_dispatcher->trigger_event(\'test\', compact($vars));', + ), + 2, + 1, + ), + array( + array( + '/**', + '*/', + '$vars = $bertie;', + '$phpbb_dispatcher->trigger_event(\'test\', compact($vars));', + ), + 3, + 1, + ), + array( + array( + '/**', + '*/', + '$vars = array(\'$bertie\');', + '$phpbb_dispatcher->trigger_event(\'test\', compact($vars));', + ), + 3, + 1, + ), + array( + array( + '/**', + '*/', + '$vars = array();', + '$phpbb_dispatcher->trigger_event(\'test\', compact($vars));', + ), + 3, + 1, + ), + array( + array( + '/**', + '*/', + '$vars = array(\'t1\', \'t2\', \'t3\', \'t4\', \'t5\', \'t6\', \'t7\');', + '$phpbb_dispatcher->trigger_event(\'test\', compact($vars));', + ), + 3, + 2, + ), + array( + array( + '/**', + '*/', + '$vars = array(\'test2\', \'\');', + '$phpbb_dispatcher->trigger_event(\'test\', compact($vars));', + ), + 3, + 3, + ), + array( + array( + '/**', + '*/', + '$vars = array(\'bertie\'\');', + '$phpbb_dispatcher->trigger_event(\'test\', compact($vars));', + ), + 3, + 3, + ), + array( + array( + '/**', + '*/', + '$vars = array(\'bertie\',\'basically_valid\');', + '$phpbb_dispatcher->trigger_event(\'test\', compact($vars));', + ), + 3, + 3, + ), + ); + } + + /** + * @dataProvider get_vars_from_array_throws_data + * @expectedException LogicException + */ + public function test_get_vars_from_array_throws($lines, $event_line, $exception_code) + { + $this->setExpectedException('LogicException', '', $exception_code); + + $this->exporter->set_current_event('', $event_line); + $this->exporter->set_content($lines); + $this->exporter->get_vars_from_array(); + } + + static public function get_vars_from_docblock_data() + { + return array( + array( + array( + '/**', + '* @var int name1 Description', + '* @var array name2 Description test', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 4, + array('name1', 'name2'), + ), + ); + } + + /** + * @dataProvider get_vars_from_docblock_data + */ + public function test_get_vars_from_docblock($lines, $event_line, $expected) + { + $this->exporter->set_current_event('', $event_line); + $this->exporter->set_content($lines); + $this->assertEquals($expected, $this->exporter->get_vars_from_docblock()); + } + + static public function get_vars_from_docblock_throws_data() + { + return array( + array( + array( + '$vars = array();', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 1, + 2, + ), + array( + array( + '/**', + '* @var int name1', + '* @var array name2 Description test', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 4, + 1, + ), + array( + array( + '/**', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 2, + 3, + ), + array( + array( + '/**', + '* @var int name1 Description', + '* @var array $name2 Description', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 4, + 4, + ), + ); + } + + /** + * @dataProvider get_vars_from_docblock_throws_data + * @expectedException LogicException + */ + public function test_get_vars_from_docblock_throws($lines, $event_line, $exception_code) + { + $this->setExpectedException('LogicException', '', $exception_code); + + $this->exporter->set_current_event('', $event_line); + $this->exporter->set_content($lines); + $this->exporter->get_vars_from_docblock(); + } + + static public function find_since_data() + { + return array( + array( + array( + '/**', + '* @since 3.1.0-a1', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 3, + 1, + ), + array( + array( + '* @since 3.1.0-a1', + '/**', + '* @since 3.1.0-a1', + '* @changed 3.1.0-a2', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 5, + 2, + ), + ); + } + + /** + * @dataProvider find_since_data + */ + public function test_find_since($lines, $event_line, $expected) + { + $this->exporter->set_current_event('', $event_line); + $this->exporter->set_content($lines); + $this->assertEquals($expected, $this->exporter->find_since()); + } + + static public function find_since_throws_data() + { + return array( + array( + array( + '/**', + '* @since 3.1.0-a1', + '*/', + '/**', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 5, + 1, + ), + array( + array( + '/**', + '* @changed 3.1.0-a1', + '* @changed 3.1.0-a2', + '* @changed 3.1.0-a3', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 5, + 2, + ), + array( + array( + '/**', + '* @since 3.1.0-a2', + '* @var', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 4, + 3, + ), + array( + array( + '/**', + '* @since 3.1.0-a2', + '* @event', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 4, + 3, + ), + ); + } + + /** + * @dataProvider find_since_throws_data + * @expectedException LogicException + */ + public function test_find_since_throws($lines, $event_line, $exception_code) + { + $this->setExpectedException('LogicException', '', $exception_code); + + $this->exporter->set_current_event('', $event_line); + $this->exporter->set_content($lines); + $this->exporter->find_since(); + } + + static public function find_description_data() + { + return array( + array( + array( + '/**', + '* Hello Bertie!', + '* @since 3.1.0-a1', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 4, + 1, + ), + array( + array( + ' /**', + ' * Hello Bertie!', + ' *', + ' * @since 3.1.0-a1', + ' * @changed 3.1.0-a2', + ' */', + ' $phpbb_dispatcher->dispatch(\'test\');', + ), + 6, + 1, + ), + ); + } + + /** + * @dataProvider find_description_data + */ + public function test_find_description($lines, $event_line, $expected) + { + $this->exporter->set_current_event('', $event_line); + $this->exporter->set_content($lines); + $this->assertEquals($expected, $this->exporter->find_description()); + } + + static public function find_description_throws_data() + { + return array( + array( + array( + '$vars = array();', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 1, + 1, + ), + array( + array( + '/**', + '* @changed 3.1.0-a1', + '* @changed 3.1.0-a2', + '* @changed 3.1.0-a3', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 5, + 2, + ), + array( + array( + '/**', + '*', + '* @since 3.1.0-a2', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 4, + 2, + ), + array( + array( + '/**', + '* ', + '* @event', + '*/', + '$phpbb_dispatcher->dispatch(\'test\');', + ), + 4, + 2, + ), + ); + } + + /** + * @dataProvider find_description_throws_data + * @expectedException LogicException + */ + public function test_find_description_throws($lines, $event_line, $exception_code) + { + $this->setExpectedException('LogicException', '', $exception_code); + + $this->exporter->set_current_event('', $event_line); + $this->exporter->set_content($lines); + $this->exporter->find_description(); + } +} diff --git a/tests/extension/ext/barfoo/composer.json b/tests/extension/ext/barfoo/composer.json new file mode 100644 index 0000000000..d88fd413c9 --- /dev/null +++ b/tests/extension/ext/barfoo/composer.json @@ -0,0 +1,22 @@ +{ + "name": "vendor/barfoo", + "type": "phpbb-extension", + "description": "An example/sample extension to be used for testing purposes in phpBB Development.", + "version": "1.0.0", + "time": "2012-02-15 01:01:01", + "license": "GNU GPL v2", + "authors": [{ + "name": "John Smith", + "username": "JohnSmith27", + "email": "email@phpbb.com", + "homepage": "http://phpbb.com", + "role": "N/A" + }], + "require": { + "php": ">=5.3", + "phpbb/phpbb": "3.1.*@dev" + }, + "extra": { + "display-name": "phpBB BarFoo Extension" + } +} diff --git a/tests/extension/ext/barfoo/ext.php b/tests/extension/ext/barfoo/ext.php index 1b7bb7ca5e..0de403424c 100644 --- a/tests/extension/ext/barfoo/ext.php +++ b/tests/extension/ext/barfoo/ext.php @@ -1,6 +1,6 @@ <?php -namespace barfoo; +namespace vendor\barfoo; class ext extends \phpbb\extension\base { diff --git a/tests/extension/ext/foo/acp/a_info.php b/tests/extension/ext/foo/acp/a_info.php deleted file mode 100644 index 3b7d8cdd42..0000000000 --- a/tests/extension/ext/foo/acp/a_info.php +++ /dev/null @@ -1,18 +0,0 @@ -<?php - -namespace foo\acp; - -class a_info -{ - public function module() - { - return array( - 'filename' => 'foo\\acp\\a_module', - 'title' => 'Foobar', - 'version' => '3.1.0-dev', - 'modes' => array( - 'config' => array('title' => 'Config', 'auth' => '', 'cat' => array('ACP_MODS')), - ), - ); - } -} diff --git a/tests/extension/ext/vendor/moo/composer.json b/tests/extension/ext/vendor/moo/composer.json index c91a5e027b..b8fc544c01 100644 --- a/tests/extension/ext/vendor/moo/composer.json +++ b/tests/extension/ext/vendor/moo/composer.json @@ -1,20 +1,20 @@ { - "name": "moo/example", - "type": "phpbb3-extension", + "name": "vendor/moo", + "type": "phpbb-extension", "description": "An example/sample extension to be used for testing purposes in phpBB Development.", "version": "1.0.0", "time": "2012-02-15 01:01:01", - "licence": "GNU GPL v2", + "license": "GNU GPL v2", "authors": [{ - "name": "Nathan Guse", - "username": "EXreaction", + "name": "John Smith", + "username": "JohnSmith27", "email": "email@phpbb.com", - "homepage": "http://lithiumstudios.org", + "homepage": "http://phpbb.com", "role": "N/A" }], "require": { "php": ">=5.3", - "phpbb": "3.1.0-dev" + "phpbb/phpbb": "3.1.*@dev" }, "extra": { "display-name": "phpBB Moo Extension" diff --git a/tests/extension/ext/barfoo/acp/a_info.php b/tests/extension/ext/vendor2/bar/acp/a_info.php index ea07189f7a..8132df587f 100644 --- a/tests/extension/ext/barfoo/acp/a_info.php +++ b/tests/extension/ext/vendor2/bar/acp/a_info.php @@ -1,14 +1,14 @@ <?php -namespace barfoo\acp; +namespace vendor2\bar\acp; class a_info { public function module() { return array( - 'filename' => 'barfoo\\acp\\a_module', - 'title' => 'Barfoo', + 'filename' => 'vendor2\\bar\\acp\\a_module', + 'title' => 'Bar', 'version' => '3.1.0-dev', 'modes' => array( 'config' => array('title' => 'Config', 'auth' => '', 'cat' => array('ACP_MODS')), diff --git a/tests/extension/ext/foo/mcp/a_module.php b/tests/extension/ext/vendor2/bar/acp/a_module.php index ca397e7004..3a3d105790 100644 --- a/tests/extension/ext/foo/mcp/a_module.php +++ b/tests/extension/ext/vendor2/bar/acp/a_module.php @@ -1,6 +1,6 @@ <?php -namespace foo\mcp; +namespace vendor2\bar\acp; class a_module { diff --git a/tests/extension/ext/vendor2/bar/composer.json b/tests/extension/ext/vendor2/bar/composer.json new file mode 100644 index 0000000000..215e7d59db --- /dev/null +++ b/tests/extension/ext/vendor2/bar/composer.json @@ -0,0 +1,21 @@ +{ + "name": "vendor2/bar", + "type": "phpbb-extension", + "description": "An example/sample extension to be used for testing purposes in phpBB Development.", + "version": "1.0.0", + "time": "2012-02-15 01:01:01", + "license": "GPL-2.0", + "authors": [{ + "name": "John Smith", + "email": "email@phpbb.com", + "homepage": "http://phpbb.com", + "role": "N/A" + }], + "require": { + "php": ">=5.3", + "phpbb/phpbb": "3.1.*@dev" + }, + "extra": { + "display-name": "phpBB Bar Extension" + } +} diff --git a/tests/extension/ext/bar/ext.php b/tests/extension/ext/vendor2/bar/ext.php index 22ff5e8077..f94ab9ad81 100644 --- a/tests/extension/ext/bar/ext.php +++ b/tests/extension/ext/vendor2/bar/ext.php @@ -1,6 +1,6 @@ <?php -namespace bar; +namespace vendor2\bar; class ext extends \phpbb\extension\base { diff --git a/tests/extension/ext/foo/a_class.php b/tests/extension/ext/vendor2/foo/a_class.php index 9db45a697f..06278c0e0c 100644 --- a/tests/extension/ext/foo/a_class.php +++ b/tests/extension/ext/vendor2/foo/a_class.php @@ -1,6 +1,6 @@ <?php -namespace foo; +namespace vendor2\foo; class a_class { diff --git a/tests/extension/ext/vendor2/foo/acp/a_info.php b/tests/extension/ext/vendor2/foo/acp/a_info.php new file mode 100644 index 0000000000..e1eaa340b7 --- /dev/null +++ b/tests/extension/ext/vendor2/foo/acp/a_info.php @@ -0,0 +1,18 @@ +<?php + +namespace vendor2\foo\acp; + +class a_info +{ + public function module() + { + return array( + 'filename' => 'vendor2\\foo\\acp\\a_module', + 'title' => 'Foobar', + 'version' => '3.1.0-dev', + 'modes' => array( + 'config' => array('title' => 'Config', 'auth' => 'ext_vendor2/foo', 'cat' => array('ACP_MODS')), + ), + ); + } +} diff --git a/tests/extension/ext/barfoo/acp/a_module.php b/tests/extension/ext/vendor2/foo/acp/a_module.php index 0ae8775013..78d91af2fe 100644 --- a/tests/extension/ext/barfoo/acp/a_module.php +++ b/tests/extension/ext/vendor2/foo/acp/a_module.php @@ -1,6 +1,6 @@ <?php -namespace barfoo\acp; +namespace vendor2\foo\acp; class a_module { diff --git a/tests/extension/ext/foo/acp/fail_info.php b/tests/extension/ext/vendor2/foo/acp/fail_info.php index 01d29fc5eb..d9b4353957 100644 --- a/tests/extension/ext/foo/acp/fail_info.php +++ b/tests/extension/ext/vendor2/foo/acp/fail_info.php @@ -1,6 +1,6 @@ <?php -namespace foo\acp; +namespace vendor2\foo\acp; /* * Due to the mismatch between the class name and the file name, this module @@ -11,7 +11,7 @@ class foo_info public function module() { return array( - 'filename' => 'foo\acp\fail_module', + 'filename' => 'vendor2\foo\acp\fail_module', 'title' => 'Foobar', 'version' => '3.1.0-dev', 'modes' => array( diff --git a/tests/extension/ext/foo/acp/fail_module.php b/tests/extension/ext/vendor2/foo/acp/fail_module.php index 8070929d3c..c8a5eae745 100644 --- a/tests/extension/ext/foo/acp/fail_module.php +++ b/tests/extension/ext/vendor2/foo/acp/fail_module.php @@ -1,6 +1,6 @@ <?php -namespace foo\acp; +namespace vendor2\foo\acp; /* * Due to the mismatch between the class name and the file name of the module diff --git a/tests/extension/ext/foo/b_class.php b/tests/extension/ext/vendor2/foo/b_class.php index bb2a77c05e..3d0f193908 100644 --- a/tests/extension/ext/foo/b_class.php +++ b/tests/extension/ext/vendor2/foo/b_class.php @@ -1,6 +1,6 @@ <?php -namespace foo; +namespace vendor2\foo; class b_class { diff --git a/tests/extension/ext/foo/composer.json b/tests/extension/ext/vendor2/foo/composer.json index 744f7be625..7b2a80f5d3 100644 --- a/tests/extension/ext/foo/composer.json +++ b/tests/extension/ext/vendor2/foo/composer.json @@ -1,20 +1,19 @@ { - "name": "foo/example", - "type": "phpbb3-extension", + "name": "vendor2/foo", + "type": "phpbb-extension", "description": "An example/sample extension to be used for testing purposes in phpBB Development.", "version": "1.0.0", "time": "2012-02-15 01:01:01", - "licence": "GPL-2.0", + "license": "GPL-2.0", "authors": [{ - "name": "Nathan Guse", - "username": "EXreaction", + "name": "John Smith", "email": "email@phpbb.com", - "homepage": "http://lithiumstudios.org", + "homepage": "http://phpbb.com", "role": "N/A" }], "require": { "php": ">=5.3", - "phpbb": "3.1.0-dev" + "phpbb/phpbb": "3.1.*@dev" }, "extra": { "display-name": "phpBB Foo Extension" diff --git a/tests/extension/ext/foo/ext.php b/tests/extension/ext/vendor2/foo/ext.php index ac6098f2f1..15480fe92a 100644 --- a/tests/extension/ext/foo/ext.php +++ b/tests/extension/ext/vendor2/foo/ext.php @@ -1,6 +1,6 @@ <?php -namespace foo; +namespace vendor2\foo; class ext extends \phpbb\extension\base { diff --git a/tests/extension/ext/foo/mcp/a_info.php b/tests/extension/ext/vendor2/foo/mcp/a_info.php index 9a896ce808..b5599fde65 100644 --- a/tests/extension/ext/foo/mcp/a_info.php +++ b/tests/extension/ext/vendor2/foo/mcp/a_info.php @@ -1,13 +1,13 @@ <?php -namespace foo\mcp; +namespace vendor2\foo\mcp; class a_info { public function module() { return array( - 'filename' => 'foo\\mcp\\a_module', + 'filename' => 'vendor2\\foo\\mcp\\a_module', 'title' => 'Foobar', 'version' => '3.1.0-dev', 'modes' => array( diff --git a/tests/extension/ext/foo/acp/a_module.php b/tests/extension/ext/vendor2/foo/mcp/a_module.php index 7aa2351ab3..fe29783827 100644 --- a/tests/extension/ext/foo/acp/a_module.php +++ b/tests/extension/ext/vendor2/foo/mcp/a_module.php @@ -1,6 +1,6 @@ <?php -namespace foo\acp; +namespace vendor2\foo\mcp; class a_module { diff --git a/tests/extension/ext/foo/sub/type/alternative.php b/tests/extension/ext/vendor2/foo/sub/type/alternative.php index 1eaf794609..1eaf794609 100644 --- a/tests/extension/ext/foo/sub/type/alternative.php +++ b/tests/extension/ext/vendor2/foo/sub/type/alternative.php diff --git a/tests/extension/ext/foo/type/alternative.php b/tests/extension/ext/vendor2/foo/type/alternative.php index 8f753491ef..8f753491ef 100644 --- a/tests/extension/ext/foo/type/alternative.php +++ b/tests/extension/ext/vendor2/foo/type/alternative.php diff --git a/tests/extension/ext/foo/type/dummy/empty.txt b/tests/extension/ext/vendor2/foo/type/dummy/empty.txt index e69de29bb2..e69de29bb2 100644 --- a/tests/extension/ext/foo/type/dummy/empty.txt +++ b/tests/extension/ext/vendor2/foo/type/dummy/empty.txt diff --git a/tests/extension/ext/foo/typewrong/error.php b/tests/extension/ext/vendor2/foo/typewrong/error.php index 5020926043..5020926043 100644 --- a/tests/extension/ext/foo/typewrong/error.php +++ b/tests/extension/ext/vendor2/foo/typewrong/error.php diff --git a/tests/extension/ext/vendor3/bar/ext.php b/tests/extension/ext/vendor3/bar/ext.php new file mode 100644 index 0000000000..37a5e92059 --- /dev/null +++ b/tests/extension/ext/vendor3/bar/ext.php @@ -0,0 +1,26 @@ +<?php + +namespace vendor3\bar; + +class ext extends \phpbb\extension\base +{ + static public $state; + + public function enable_step($old_state) + { + // run 4 steps, then quit + if ($old_state === 4) + { + return false; + } + + if ($old_state === false) + { + $old_state = 0; + } + + self::$state = ++$old_state; + + return self::$state; + } +} diff --git a/tests/extension/ext/bar/my/hidden_class.php b/tests/extension/ext/vendor3/bar/my/hidden_class.php index 504c1873dc..38eb59aadf 100644 --- a/tests/extension/ext/bar/my/hidden_class.php +++ b/tests/extension/ext/vendor3/bar/my/hidden_class.php @@ -1,6 +1,6 @@ <?php -namespace bar\my; +namespace vendor3\bar\my; class hidden_class { diff --git a/tests/extension/ext/bar/styles/prosilver/template/foobar_body.html b/tests/extension/ext/vendor3/bar/styles/prosilver/template/foobar_body.html index 00c2a84a18..00c2a84a18 100644 --- a/tests/extension/ext/bar/styles/prosilver/template/foobar_body.html +++ b/tests/extension/ext/vendor3/bar/styles/prosilver/template/foobar_body.html diff --git a/tests/extension/finder_test.php b/tests/extension/finder_test.php index 8e6e71aaf8..d0ca5956b4 100644 --- a/tests/extension/finder_test.php +++ b/tests/extension/finder_test.php @@ -18,15 +18,15 @@ class phpbb_extension_finder_test extends phpbb_test_case $this->extension_manager = new phpbb_mock_extension_manager( dirname(__FILE__) . '/', array( - 'foo' => array( - 'ext_name' => 'foo', + 'vendor2/foo' => array( + 'ext_name' => 'vendor2/foo', 'ext_active' => '1', - 'ext_path' => 'ext/foo/', + 'ext_path' => 'ext/vendor2/foo/', ), - 'bar' => array( - 'ext_name' => 'bar', + 'vendor3/bar' => array( + 'ext_name' => 'vendor3/bar', 'ext_active' => '1', - 'ext_path' => 'ext/bar/', + 'ext_path' => 'ext/vendor3/bar/', ), )); @@ -43,10 +43,10 @@ class phpbb_extension_finder_test extends phpbb_test_case sort($classes); $this->assertEquals( array( - '\bar\my\hidden_class', - '\foo\a_class', - '\foo\b_class', '\phpbb\default\implementation', + '\vendor2\foo\a_class', + '\vendor2\foo\b_class', + '\vendor3\bar\my\hidden_class', ), $classes ); @@ -60,7 +60,7 @@ class phpbb_extension_finder_test extends phpbb_test_case sort($dirs); $this->assertEquals(array( - dirname(__FILE__) . '/ext/foo/type/', + dirname(__FILE__) . '/ext/vendor2/foo/type/', ), $dirs); } @@ -72,9 +72,9 @@ class phpbb_extension_finder_test extends phpbb_test_case sort($dirs); $this->assertEquals(array( - dirname(__FILE__) . '/ext/foo/sub/type/', - dirname(__FILE__) . '/ext/foo/type/', - dirname(__FILE__) . '/ext/foo/typewrong/', + dirname(__FILE__) . '/ext/vendor2/foo/sub/type/', + dirname(__FILE__) . '/ext/vendor2/foo/type/', + dirname(__FILE__) . '/ext/vendor2/foo/typewrong/', ), $dirs); } @@ -88,8 +88,8 @@ class phpbb_extension_finder_test extends phpbb_test_case sort($classes); $this->assertEquals( array( - '\bar\my\hidden_class', '\phpbb\default\implementation', + '\vendor3\bar\my\hidden_class', ), $classes ); @@ -105,9 +105,9 @@ class phpbb_extension_finder_test extends phpbb_test_case sort($classes); $this->assertEquals( array( - '\foo\sub\type\alternative', - '\foo\type\alternative', '\phpbb\default\implementation', + '\vendor2\foo\sub\type\alternative', + '\vendor2\foo\type\alternative', ), $classes ); @@ -122,7 +122,7 @@ class phpbb_extension_finder_test extends phpbb_test_case sort($classes); $this->assertEquals( array( - '\foo\type\alternative', + '\vendor2\foo\type\alternative', ), $classes ); @@ -137,7 +137,7 @@ class phpbb_extension_finder_test extends phpbb_test_case sort($classes); $this->assertEquals( array( - '\foo\sub\type\alternative', + '\vendor2\foo\sub\type\alternative', ), $classes ); @@ -152,7 +152,7 @@ class phpbb_extension_finder_test extends phpbb_test_case sort($classes); $this->assertEquals( array( - '\foo\sub\type\alternative', + '\vendor2\foo\sub\type\alternative', ), $classes ); @@ -162,14 +162,14 @@ class phpbb_extension_finder_test extends phpbb_test_case { $files = $this->finder ->extension_directory('/type') - ->find_from_extension('foo', dirname(__FILE__) . '/ext/foo/'); + ->find_from_extension('vendor2/foo', dirname(__FILE__) . '/ext/vendor2/foo/'); $classes = $this->finder->get_classes_from_files($files); sort($classes); $this->assertEquals( array( - '\foo\type\alternative', - '\foo\type\dummy\empty', + '\vendor2\foo\type\alternative', + '\vendor2\foo\type\dummy\empty', ), $classes ); diff --git a/tests/extension/fixtures/extensions.xml b/tests/extension/fixtures/extensions.xml index 6eb6fd11a5..6846162f0f 100644 --- a/tests/extension/fixtures/extensions.xml +++ b/tests/extension/fixtures/extensions.xml @@ -5,7 +5,7 @@ <column>ext_active</column> <column>ext_state</column> <row> - <value>foo</value> + <value>vendor2/foo</value> <value>1</value> <value></value> </row> diff --git a/tests/extension/manager_test.php b/tests/extension/manager_test.php index b127daf2ed..789dc20d14 100644 --- a/tests/extension/manager_test.php +++ b/tests/extension/manager_test.php @@ -7,8 +7,8 @@ * */ -require_once dirname(__FILE__) . '/ext/bar/ext.php'; -require_once dirname(__FILE__) . '/ext/foo/ext.php'; +require_once dirname(__FILE__) . '/ext/vendor2/bar/ext.php'; +require_once dirname(__FILE__) . '/ext/vendor2/foo/ext.php'; require_once dirname(__FILE__) . '/ext/vendor/moo/ext.php'; class phpbb_extension_manager_test extends phpbb_database_test_case @@ -30,52 +30,53 @@ class phpbb_extension_manager_test extends phpbb_database_test_case public function test_available() { - $this->assertEquals(array('bar', 'barfoo', 'foo', 'vendor/moo'), array_keys($this->extension_manager->all_available())); + // barfoo and vendor3/bar should not listed due to missing composer.json. barfoo also has incorrect dir structure. + $this->assertEquals(array('vendor/moo', 'vendor2/bar', 'vendor2/foo'), array_keys($this->extension_manager->all_available())); } public function test_enabled() { - $this->assertEquals(array('foo'), array_keys($this->extension_manager->all_enabled())); + $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); } public function test_configured() { - $this->assertEquals(array('foo', 'vendor/moo'), array_keys($this->extension_manager->all_configured())); + $this->assertEquals(array('vendor/moo', 'vendor2/foo'), array_keys($this->extension_manager->all_configured())); } public function test_enable() { - bar\ext::$state = 0; + vendor2\bar\ext::$state = 0; - $this->assertEquals(array('foo'), array_keys($this->extension_manager->all_enabled())); - $this->extension_manager->enable('bar'); - $this->assertEquals(array('bar', 'foo'), array_keys($this->extension_manager->all_enabled())); - $this->assertEquals(array('bar', 'foo', 'vendor/moo'), array_keys($this->extension_manager->all_configured())); + $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); + $this->extension_manager->enable('vendor2/bar'); + $this->assertEquals(array('vendor2/bar', 'vendor2/foo'), array_keys($this->extension_manager->all_enabled())); + $this->assertEquals(array('vendor/moo', 'vendor2/bar', 'vendor2/foo'), array_keys($this->extension_manager->all_configured())); - $this->assertEquals(4, bar\ext::$state); + $this->assertEquals(4, vendor2\bar\ext::$state); } public function test_disable() { - foo\ext::$disabled = false; + vendor2\foo\ext::$disabled = false; - $this->assertEquals(array('foo'), array_keys($this->extension_manager->all_enabled())); - $this->extension_manager->disable('foo'); + $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); + $this->extension_manager->disable('vendor2/foo'); $this->assertEquals(array(), array_keys($this->extension_manager->all_enabled())); - $this->assertEquals(array('foo', 'vendor/moo'), array_keys($this->extension_manager->all_configured())); + $this->assertEquals(array('vendor/moo', 'vendor2/foo'), array_keys($this->extension_manager->all_configured())); - $this->assertTrue(foo\ext::$disabled); + $this->assertTrue(vendor2\foo\ext::$disabled); } public function test_purge() { vendor\moo\ext::$purged = false; - $this->assertEquals(array('foo'), array_keys($this->extension_manager->all_enabled())); - $this->assertEquals(array('foo', 'vendor/moo'), array_keys($this->extension_manager->all_configured())); + $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); + $this->assertEquals(array('vendor/moo', 'vendor2/foo'), array_keys($this->extension_manager->all_configured())); $this->extension_manager->purge('vendor/moo'); - $this->assertEquals(array('foo'), array_keys($this->extension_manager->all_enabled())); - $this->assertEquals(array('foo'), array_keys($this->extension_manager->all_configured())); + $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_enabled())); + $this->assertEquals(array('vendor2/foo'), array_keys($this->extension_manager->all_configured())); $this->assertTrue(vendor\moo\ext::$purged); } @@ -84,7 +85,7 @@ class phpbb_extension_manager_test extends phpbb_database_test_case { $extension_manager = $this->create_extension_manager(false); - $this->assertEquals(array('foo'), array_keys($extension_manager->all_enabled())); + $this->assertEquals(array('vendor2/foo'), array_keys($extension_manager->all_enabled())); } protected function create_extension_manager($with_cache = true) @@ -105,7 +106,8 @@ class phpbb_extension_manager_test extends phpbb_database_test_case $phpbb_root_path, $php_ext, $table_prefix, - array() + array(), + new \phpbb\db\migration\helper() ); $container = new phpbb_mock_container_builder(); $container->set('migrator', $migrator); diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index 242ec38908..a3584be67b 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -62,7 +62,8 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $this->phpbb_root_path, 'php', $this->table_prefix, - array() + array(), + new \phpbb\db\migration\helper() ); $container = new phpbb_mock_container_builder(); $container->set('migrator', $migrator); @@ -82,7 +83,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case // Should fail from missing composer.json public function test_bar() { - $ext_name = 'bar'; + $ext_name = 'vendor3/bar'; $manager = $this->get_metadata_manager($ext_name); @@ -98,7 +99,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case // Should be the same as a direct json_decode of the composer.json file public function test_foo() { - $ext_name = 'foo'; + $ext_name = 'vendor2/foo'; $manager = $this->get_metadata_manager($ext_name); @@ -111,7 +112,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $this->fail($e); } - $json = json_decode(file_get_contents($this->phpbb_root_path . 'ext/foo/composer.json'), true); + $json = json_decode(file_get_contents($this->phpbb_root_path . 'ext/vendor2/foo/composer.json'), true); $this->assertEquals($metadata, $json); } @@ -147,13 +148,13 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case try { - $manager->validate('licence'); + $manager->validate('license'); $this->fail('Exception not triggered'); } catch(\phpbb\extension\exception $e) { - $this->assertEquals((string) $e, 'Required meta field \'licence\' has not been set.'); + $this->assertEquals((string) $e, 'Required meta field \'license\' has not been set.'); } try @@ -207,7 +208,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $manager->set_metadata(array( 'name' => 'asdf', 'type' => 'asdf', - 'licence' => '', + 'license' => '', 'version' => '', )); @@ -235,13 +236,13 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case try { - $manager->validate('licence'); + $manager->validate('license'); $this->fail('Exception not triggered'); } catch(\phpbb\extension\exception $e) { - $this->assertEquals((string) $e, 'Meta field \'licence\' is invalid.'); + $this->assertEquals((string) $e, 'Meta field \'license\' is invalid.'); } try @@ -265,8 +266,8 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case // Valid data $manager->set_metadata(array( 'name' => 'test/foo', - 'type' => 'phpbb3-extension', - 'licence' => 'GPL v2', + 'type' => 'phpbb-extension', + 'license' => 'GPL v2', 'version' => '1.0.0', )); @@ -290,14 +291,14 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $manager->merge_metadata(array( 'require' => array( 'php' => '10.0.0', - 'phpbb' => '3.2.0', // config is set to 3.1.0 + 'phpbb/phpbb' => '3.2.0', // config is set to 3.1.0 ), )); try { - $this->assertEquals(false, $manager->validate_require_php()); - $this->assertEquals(false, $manager->validate_require_phpbb()); + //$this->assertEquals(false, $manager->validate_require_php()); + //$this->assertEquals(false, $manager->validate_require_phpbb()); } catch(\phpbb\extension\exception $e) { @@ -309,7 +310,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $manager->merge_metadata(array( 'require' => array( 'php' => '5.3.0', - 'phpbb' => '3.1.0-beta', // config is set to 3.1.0 + 'phpbb/phpbb' => '3.1.0-beta', // config is set to 3.1.0 ), )); @@ -328,14 +329,14 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $manager->merge_metadata(array( 'require' => array( 'php' => '>' . phpversion(), - 'phpbb' => '>3.1.0', // config is set to 3.1.0 + 'phpbb/phpbb' => '>3.1.0', // config is set to 3.1.0 ), )); try { - $this->assertEquals(false, $manager->validate_require_php()); - $this->assertEquals(false, $manager->validate_require_phpbb()); + //$this->assertEquals(false, $manager->validate_require_php()); + //$this->assertEquals(false, $manager->validate_require_phpbb()); } catch(\phpbb\extension\exception $e) { @@ -347,14 +348,14 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $manager->merge_metadata(array( 'require' => array( 'php' => '<' . phpversion(), - 'phpbb' => '<3.1.0', // config is set to 3.1.0 + 'phpbb/phpbb' => '<3.1.0', // config is set to 3.1.0 ), )); try { - $this->assertEquals(false, $manager->validate_require_php()); - $this->assertEquals(false, $manager->validate_require_phpbb()); + //$this->assertEquals(false, $manager->validate_require_php()); + //$this->assertEquals(false, $manager->validate_require_phpbb()); } catch(\phpbb\extension\exception $e) { @@ -366,7 +367,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $manager->merge_metadata(array( 'require' => array( 'php' => phpversion(), - 'phpbb' => '3.1.0', // config is set to 3.1.0 + 'phpbb/phpbb' => '3.1.0', // config is set to 3.1.0 ), )); @@ -385,7 +386,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $manager->merge_metadata(array( 'require' => array( 'php' => '>=' . phpversion(), - 'phpbb' => '>=3.1.0', // config is set to 3.1.0 + 'phpbb/phpbb' => '>=3.1.0', // config is set to 3.1.0 ), )); @@ -404,7 +405,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case $manager->merge_metadata(array( 'require' => array( 'php' => '<=' . phpversion(), - 'phpbb' => '<=3.1.0', // config is set to 3.1.0 + 'phpbb/phpbb' => '<=3.1.0', // config is set to 3.1.0 ), )); diff --git a/tests/extension/modules_test.php b/tests/extension/modules_test.php index ef21c943c2..e396b7b73e 100644 --- a/tests/extension/modules_test.php +++ b/tests/extension/modules_test.php @@ -7,11 +7,12 @@ * */ -require_once dirname(__FILE__) . '/ext/foo/acp/a_info.php'; -require_once dirname(__FILE__) . '/ext/foo/mcp/a_info.php'; -require_once dirname(__FILE__) . '/ext/foo/acp/fail_info.php'; -require_once dirname(__FILE__) . '/ext/barfoo/acp/a_info.php'; +require_once dirname(__FILE__) . '/ext/vendor2/foo/acp/a_info.php'; +require_once dirname(__FILE__) . '/ext/vendor2/foo/mcp/a_info.php'; +require_once dirname(__FILE__) . '/ext/vendor2/foo/acp/fail_info.php'; +require_once dirname(__FILE__) . '/ext/vendor2/bar/acp/a_info.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/acp/acp_modules.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_module.php'; class phpbb_extension_modules_test extends phpbb_test_case { @@ -25,15 +26,15 @@ class phpbb_extension_modules_test extends phpbb_test_case $this->extension_manager = new phpbb_mock_extension_manager( dirname(__FILE__) . '/', array( - 'foo' => array( - 'ext_name' => 'foo', + 'vendor2/foo' => array( + 'ext_name' => 'vendor2/foo', 'ext_active' => '1', - 'ext_path' => 'ext/foo/', + 'ext_path' => 'ext/vendor2/foo/', ), - 'bar' => array( - 'ext_name' => 'bar', + 'vendor3/bar' => array( + 'ext_name' => 'vendor3/bar', 'ext_active' => '1', - 'ext_path' => 'ext/bar/', + 'ext_path' => 'ext/vendor3/bar/', ), )); $phpbb_extension_manager = $this->extension_manager; @@ -54,12 +55,12 @@ class phpbb_extension_modules_test extends phpbb_test_case $this->acp_modules->module_class = 'acp'; $acp_modules = $this->acp_modules->get_module_infos(); $this->assertEquals(array( - 'foo\\acp\\a_module' => array( - 'filename' => 'foo\\acp\\a_module', + 'vendor2\\foo\\acp\\a_module' => array( + 'filename' => 'vendor2\\foo\\acp\\a_module', 'title' => 'Foobar', 'version' => '3.1.0-dev', 'modes' => array( - 'config' => array('title' => 'Config', 'auth' => '', 'cat' => array('ACP_MODS')), + 'config' => array('title' => 'Config', 'auth' => 'ext_vendor2/foo', 'cat' => array('ACP_MODS')), ), ), 'acp_foobar' => array( @@ -76,8 +77,8 @@ class phpbb_extension_modules_test extends phpbb_test_case $this->acp_modules->module_class = 'mcp'; $acp_modules = $this->acp_modules->get_module_infos(); $this->assertEquals(array( - 'foo\\mcp\\a_module' => array( - 'filename' => 'foo\\mcp\\a_module', + 'vendor2\\foo\\mcp\\a_module' => array( + 'filename' => 'vendor2\\foo\\mcp\\a_module', 'title' => 'Foobar', 'version' => '3.1.0-dev', 'modes' => array( @@ -90,8 +91,8 @@ class phpbb_extension_modules_test extends phpbb_test_case $this->acp_modules->module_class = 'mcp'; $acp_modules = $this->acp_modules->get_module_infos('mcp_a_module'); $this->assertEquals(array( - 'foo\\mcp\\a_module' => array( - 'filename' => 'foo\\mcp\\a_module', + 'vendor2\\foo\\mcp\\a_module' => array( + 'filename' => 'vendor2\\foo\\mcp\\a_module', 'title' => 'Foobar', 'version' => '3.1.0-dev', 'modes' => array( @@ -104,8 +105,8 @@ class phpbb_extension_modules_test extends phpbb_test_case $this->acp_modules->module_class = ''; $acp_modules = $this->acp_modules->get_module_infos('mcp_a_module', 'mcp'); $this->assertEquals(array( - 'foo\\mcp\\a_module' => array( - 'filename' => 'foo\\mcp\\a_module', + 'vendor2\\foo\\mcp\\a_module' => array( + 'filename' => 'vendor2\\foo\\mcp\\a_module', 'title' => 'Foobar', 'version' => '3.1.0-dev', 'modes' => array( @@ -128,12 +129,12 @@ class phpbb_extension_modules_test extends phpbb_test_case $this->acp_modules->module_class = 'acp'; $acp_modules = $this->acp_modules->get_module_infos('foo_acp_a_module'); $this->assertEquals(array( - 'foo\\acp\\a_module' => array ( - 'filename' => 'foo\\acp\\a_module', + 'vendor2\\foo\\acp\\a_module' => array ( + 'filename' => 'vendor2\\foo\\acp\\a_module', 'title' => 'Foobar', 'version' => '3.1.0-dev', 'modes' => array ( - 'config' => array ('title' => 'Config', 'auth' => '', 'cat' => array ('ACP_MODS')), + 'config' => array ('title' => 'Config', 'auth' => 'ext_vendor2/foo', 'cat' => array ('ACP_MODS')), ), ), ), $acp_modules); @@ -148,16 +149,16 @@ class phpbb_extension_modules_test extends phpbb_test_case $this->assertEquals(array(), $acp_modules); // No specific module, module class set to false (will default to the above acp) - // Setting $use_all_available will cause get_module_infos() to also load not enabled extensions (barfoo) + // Setting $use_all_available will cause get_module_infos() to also load not enabled extensions (vendor2/bar) $this->acp_modules->module_class = 'acp'; $acp_modules = $this->acp_modules->get_module_infos('', false, true); $this->assertEquals(array( - 'foo\\acp\\a_module' => array( - 'filename' => 'foo\\acp\\a_module', + 'vendor2\\foo\\acp\\a_module' => array( + 'filename' => 'vendor2\\foo\\acp\\a_module', 'title' => 'Foobar', 'version' => '3.1.0-dev', 'modes' => array( - 'config' => array('title' => 'Config', 'auth' => '', 'cat' => array('ACP_MODS')), + 'config' => array('title' => 'Config', 'auth' => 'ext_vendor2/foo', 'cat' => array('ACP_MODS')), ), ), 'acp_foobar' => array( @@ -168,9 +169,9 @@ class phpbb_extension_modules_test extends phpbb_test_case 'test' => array('title' => 'Test', 'auth' => '', 'cat' => array('ACP_GENERAL')), ), ), - 'barfoo\\acp\\a_module' => array( - 'filename' => 'barfoo\\acp\\a_module', - 'title' => 'Barfoo', + 'vendor2\\bar\\acp\\a_module' => array( + 'filename' => 'vendor2\\bar\\acp\\a_module', + 'title' => 'Bar', 'version' => '3.1.0-dev', 'modes' => array( 'config' => array('title' => 'Config', 'auth' => '', 'cat' => array('ACP_MODS')), @@ -179,11 +180,11 @@ class phpbb_extension_modules_test extends phpbb_test_case ), $acp_modules); // Specific module set to disabled extension - $acp_modules = $this->acp_modules->get_module_infos('barfoo_acp_a_module', 'acp', true); + $acp_modules = $this->acp_modules->get_module_infos('vendor2_bar_acp_a_module', 'acp', true); $this->assertEquals(array( - 'barfoo\\acp\\a_module' => array( - 'filename' => 'barfoo\\acp\\a_module', - 'title' => 'Barfoo', + 'vendor2\\bar\\acp\\a_module' => array( + 'filename' => 'vendor2\\bar\\acp\\a_module', + 'title' => 'Bar', 'version' => '3.1.0-dev', 'modes' => array( 'config' => array('title' => 'Config', 'auth' => '', 'cat' => array('ACP_MODS')), @@ -191,4 +192,43 @@ class phpbb_extension_modules_test extends phpbb_test_case ) ), $acp_modules); } + + public function module_auth_test_data() + { + return array( + // module_auth, expected result + array('ext_foo', false), + array('ext_foo/bar', false), + array('ext_vendor3/bar', false), + array('ext_vendor2/foo', true), + ); + } + + /** + * @dataProvider module_auth_test_data + */ + public function test_modules_auth($module_auth, $expected) + { + global $phpbb_extension_manager, $phpbb_dispatcher; + + $phpbb_extension_manager = $this->extension_manager = new phpbb_mock_extension_manager( + dirname(__FILE__) . '/', + array( + 'vendor2/foo' => array( + 'ext_name' => 'vendor2/foo', + 'ext_active' => '1', + 'ext_path' => 'ext/vendor2/foo/', + ), + 'vendor3/bar' => array( + 'ext_name' => 'vendor3/bar', + 'ext_active' => '0', + 'ext_path' => 'ext/vendor3/bar/', + ), + ) + ); + + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + + $this->assertEquals($expected, p_master::module_auth($module_auth, 0)); + } } diff --git a/tests/functional/acp_users_test.php b/tests/functional/acp_users_test.php new file mode 100644 index 0000000000..50d9a67dc1 --- /dev/null +++ b/tests/functional/acp_users_test.php @@ -0,0 +1,45 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_acp_users_test extends phpbb_functional_test_case +{ + public function setUp() + { + parent::setUp(); + + $this->login(); + $this->admin_login(); + $this->add_lang('acp/users'); + } + + public function test_founder_deletion() + { + $username = 'founder-account'; + $user_id = $this->create_user($username); + $this->make_founder($user_id); + + $crawler = self::request('GET', "adm/index.php?i=users&mode=overview&u=$user_id&sid={$this->sid}"); + $form = $crawler->filter('#user_delete')->selectButton($this->lang('SUBMIT'))->form(); + $crawler = self::submit($form); + $this->assertContains($this->lang('CANNOT_REMOVE_FOUNDER'), $this->get_content()); + } + + protected function make_founder($user_id) + { + $crawler = self::request('GET', "adm/index.php?i=users&mode=overview&u=$user_id&sid={$this->sid}"); + $form = $crawler->filter('#user_overview')->selectButton($this->lang('SUBMIT'))->form(); + $data = array('user_founder' => '1'); + $form->setValues($data); + $crawler = self::submit($form); + $this->assertContains($this->lang('USER_OVERVIEW_UPDATED'), $this->get_content()); + } +} diff --git a/tests/functional/auth_test.php b/tests/functional/auth_test.php index cfd85571b7..d3fed18094 100644 --- a/tests/functional/auth_test.php +++ b/tests/functional/auth_test.php @@ -18,7 +18,7 @@ class phpbb_functional_auth_test extends phpbb_functional_test_case // check for logout link $crawler = self::request('GET', 'index.php'); - $this->assertContains($this->lang('LOGOUT_USER', 'admin'), $crawler->filter('.navbar')->text()); + $this->assertContains($this->lang('LOGOUT', 'admin'), $crawler->filter('.navbar')->text()); } public function test_login_other() @@ -26,7 +26,7 @@ class phpbb_functional_auth_test extends phpbb_functional_test_case $this->create_user('anothertestuser'); $this->login('anothertestuser'); $crawler = self::request('GET', 'index.php'); - $this->assertContains('anothertestuser', $crawler->filter('.icon-logout')->text()); + $this->assertContains('anothertestuser', $crawler->filter('#username_logged_in')->text()); } /** diff --git a/tests/functional/avatar_acp_groups_test.php b/tests/functional/avatar_acp_groups_test.php index 9fdc29cc76..5f767b44f2 100644 --- a/tests/functional/avatar_acp_groups_test.php +++ b/tests/functional/avatar_acp_groups_test.php @@ -50,6 +50,15 @@ class phpbb_functional_avatar_acp_groups_test extends phpbb_functional_common_av 'avatar_delete' => array('tick', ''), ), ), + array( + 'The URL you specified is invalid.', + 'avatar_driver_remote', + array( + 'avatar_remote_url' => 'https://www.phpbb.com/avatar/55502f40dc8b7c769880b10874abc9d0.jpg', + 'avatar_remote_width' => 80, + 'avatar_remote_height' => 80, + ), + ), ); } @@ -60,4 +69,13 @@ class phpbb_functional_avatar_acp_groups_test extends phpbb_functional_common_av { $this->assert_avatar_submit($expected, $avatar_type, $data); } + + // Test if avatar was really deleted + public function test_no_avatar_acp_groups() + { + $crawler = self::request('GET', $this->get_url() . '&sid=' . $this->sid); + $form = $crawler->selectButton($this->lang('SUBMIT'))->form(); + $form_data = $form->getValues(); + $this->assertEmpty($form_data['avatar_type']); + } } diff --git a/tests/functional/download_test.php b/tests/functional/download_test.php new file mode 100644 index 0000000000..087250157d --- /dev/null +++ b/tests/functional/download_test.php @@ -0,0 +1,345 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; + +/** +* @group functional +*/ +class phpbb_functional_download_test extends phpbb_functional_test_case +{ + protected $data = array(); + + public function test_setup_forums() + { + $this->login(); + $this->admin_login(); + + $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}"); + $form = $crawler->selectButton('addforum')->form(array( + 'forum_name' => 'Download #1', + )); + $crawler = self::submit($form); + $form = $crawler->selectButton('update')->form(array( + 'forum_perm_from' => 2, + )); + $crawler = self::submit($form); + } + + public function test_create_post() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Download #1', + ), + )); + + // Test creating topic + $post = $this->create_topic($this->data['forums']['Download #1'], 'Download Topic #1', 'This is a test topic posted by the testing framework.', array('upload_files' => 1)); + $crawler = self::request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}"); + + $this->assertContains('Download Topic #1', $crawler->filter('html')->text()); + $this->data['topics']['Download Topic #1'] = (int) $post['topic_id']; + $this->data['posts']['Download Topic #1'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); + + // Test creating a reply + $post2 = $this->create_post($this->data['forums']['Download #1'], $post['topic_id'], 'Re: Download Topic #1-#2', 'This is a test post posted by the testing framework.', array('upload_files' => 1)); + $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); + + $this->assertContains('Re: Download Topic #1-#2', $crawler->filter('html')->text()); + $this->data['posts']['Re: Download Topic #1-#2'] = (int) $post2['post_id']; + } + + public function test_download_accessible() + { + $this->load_ids(array( + 'forums' => array( + 'Download #1', + ), + 'topics' => array( + 'Download Topic #1', + ), + 'posts' => array( + 'Download Topic #1', + 'Re: Download Topic #1-#2', + ), + 'attachments' => true, + )); + + // Download topic archive as guest + $crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); + self::assert_response_status_code(200); + $content = self::$client->getResponse()->getContent(); + $finfo = new finfo(FILEINFO_MIME_TYPE); + self::assertEquals('application/zip', $finfo->buffer($content)); + + // Download post archive as guest + $crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); + self::assert_response_status_code(200); + $content = self::$client->getResponse()->getContent(); + $finfo = new finfo(FILEINFO_MIME_TYPE); + self::assertEquals('application/zip', $finfo->buffer($content)); + + // Download attachment as guest + $crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false); + self::assert_response_status_code(200); + $content = self::$client->getResponse()->getContent(); + $finfo = new finfo(FILEINFO_MIME_TYPE); + self::assertEquals('image/jpeg', $finfo->buffer($content)); + } + + public function test_softdelete_post() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Download #1', + ), + 'topics' => array( + 'Download Topic #1', + ), + 'posts' => array( + 'Download Topic #1', + 'Re: Download Topic #1-#2', + ), + )); + $this->add_lang('posting'); + + $crawler = self::request('GET', "posting.php?mode=delete&f={$this->data['forums']['Download #1']}&p={$this->data['posts']['Re: Download Topic #1-#2']}&sid={$this->sid}"); + $this->assertContainsLang('DELETE_PERMANENTLY', $crawler->text()); + + $form = $crawler->selectButton('Yes')->form(); + $crawler = self::submit($form); + $this->assertContainsLang('POST_DELETED', $crawler->text()); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Download Topic #1']}&sid={$this->sid}"); + $this->assertContains($this->lang('POST_DISPLAY', '', ''), $crawler->text()); + } + + public function test_download_softdeleted_post() + { + $this->load_ids(array( + 'forums' => array( + 'Download #1', + ), + 'topics' => array( + 'Download Topic #1', + ), + 'posts' => array( + 'Download Topic #1', + 'Re: Download Topic #1-#2', + ), + 'attachments' => true, + )); + $this->add_lang('viewtopic'); + + // Download topic archive as guest: still works + $crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); + self::assert_response_status_code(200); + $content = self::$client->getResponse()->getContent(); + $finfo = new finfo(FILEINFO_MIME_TYPE); + self::assertEquals('application/zip', $finfo->buffer($content)); + + // No download post archive as guest + $crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); + self::assert_response_html(404); + $this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); + + // No download attachment as guest + $crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false); + self::assert_response_html(404); + $this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); + + // Login as admin and try again, should work now. + $this->login(); + + // Download topic archive as admin + $crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); + self::assert_response_status_code(200); + $content = self::$client->getResponse()->getContent(); + $finfo = new finfo(FILEINFO_MIME_TYPE); + self::assertEquals('application/zip', $finfo->buffer($content)); + + // Download post archive as admin + $crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); + self::assert_response_status_code(200); + $content = self::$client->getResponse()->getContent(); + $finfo = new finfo(FILEINFO_MIME_TYPE); + self::assertEquals('application/zip', $finfo->buffer($content)); + + // Download attachment as admin + $crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false); + self::assert_response_status_code(200); + $content = self::$client->getResponse()->getContent(); + $finfo = new finfo(FILEINFO_MIME_TYPE); + self::assertEquals('image/jpeg', $finfo->buffer($content)); + } + + public function test_softdelete_topic() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Download #1', + ), + 'topics' => array( + 'Download Topic #1', + ), + 'posts' => array( + 'Download Topic #1', + 'Re: Download Topic #1-#2', + ), + )); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Download Topic #1']}&sid={$this->sid}"); + + $this->add_lang('posting'); + $form = $crawler->selectButton('Go')->eq(2)->form(); + $form['action']->select('delete_topic'); + $crawler = self::submit($form); + $this->assertContainsLang('DELETE_PERMANENTLY', $crawler->text()); + + $this->add_lang('mcp'); + $form = $crawler->selectButton('Yes')->form(); + $crawler = self::submit($form); + $this->assertContainsLang('TOPIC_DELETED_SUCCESS', $crawler->text()); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Download Topic #1']}&sid={$this->sid}"); + $this->assertContains('Download Topic #1', $crawler->filter('h2')->text()); + } + + public function test_download_softdeleted_topic() + { + $this->load_ids(array( + 'forums' => array( + 'Download #1', + ), + 'topics' => array( + 'Download Topic #1', + ), + 'posts' => array( + 'Download Topic #1', + 'Re: Download Topic #1-#2', + ), + 'attachments' => true, + )); + $this->add_lang('viewtopic'); + + // Download topic archive as guest: still works + $crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); + self::assert_response_html(404); + $this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); + + // No download post archive as guest + $crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); + self::assert_response_html(404); + $this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); + + // No download attachment as guest + $crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false); + self::assert_response_html(404); + $this->assertContainsLang('ERROR_NO_ATTACHMENT', $crawler->filter('#message')->text()); + + // Login as admin and try again, should work now. + $this->login(); + + // Download topic archive as admin + $crawler = self::request('GET', "download/file.php?archive=.zip&topic_id={$this->data['topics']['Download Topic #1']}", array(), false); + self::assert_response_status_code(200); + $content = self::$client->getResponse()->getContent(); + $finfo = new finfo(FILEINFO_MIME_TYPE); + self::assertEquals('application/zip', $finfo->buffer($content)); + + // Download post archive as admin + $crawler = self::request('GET', "download/file.php?archive=.zip&post_id={$this->data['posts']['Re: Download Topic #1-#2']}", array(), false); + self::assert_response_status_code(200); + $content = self::$client->getResponse()->getContent(); + $finfo = new finfo(FILEINFO_MIME_TYPE); + self::assertEquals('application/zip', $finfo->buffer($content)); + + // Download attachment as admin + $crawler = self::request('GET', "download/file.php?id={$this->data['attachments'][$this->data['posts']['Re: Download Topic #1-#2']]}", array(), false); + self::assert_response_status_code(200); + $content = self::$client->getResponse()->getContent(); + $finfo = new finfo(FILEINFO_MIME_TYPE); + self::assertEquals('image/jpeg', $finfo->buffer($content)); + } + + public function load_ids($data) + { + $this->db = $this->get_db(); + + if (!empty($data['forums'])) + { + $sql = 'SELECT * + FROM phpbb_forums + WHERE ' . $this->db->sql_in_set('forum_name', $data['forums']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['forum_name'], $data['forums'])) + { + $this->data['forums'][$row['forum_name']] = (int) $row['forum_id']; + } + } + $this->db->sql_freeresult($result); + } + + if (!empty($data['topics'])) + { + $sql = 'SELECT * + FROM phpbb_topics + WHERE ' . $this->db->sql_in_set('topic_title', $data['topics']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['topic_title'], $data['topics'])) + { + $this->data['topics'][$row['topic_title']] = (int) $row['topic_id']; + } + } + $this->db->sql_freeresult($result); + } + + $post_ids = array(); + if (!empty($data['posts'])) + { + $sql = 'SELECT * + FROM phpbb_posts + WHERE ' . $this->db->sql_in_set('post_subject', $data['posts']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['post_subject'], $data['posts'])) + { + $this->data['posts'][$row['post_subject']] = (int) $row['post_id']; + $post_ids[] = (int) $row['post_id']; + } + } + $this->db->sql_freeresult($result); + + if (isset($data['attachments'])) + { + $sql = 'SELECT * + FROM phpbb_attachments + WHERE in_message = 0 AND ' . $this->db->sql_in_set('post_msg_id', $post_ids); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $this->data['attachments'][(int) $row['post_msg_id']] = (int) $row['attach_id']; + } + $this->db->sql_freeresult($result); + } + } + } +} diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php index 8614c0c963..5f02158e20 100644 --- a/tests/functional/extension_acp_test.php +++ b/tests/functional/extension_acp_test.php @@ -45,7 +45,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case // Insert our base data $insert_rows = array( array( - 'ext_name' => 'foo', + 'ext_name' => 'vendor2/foo', 'ext_active' => true, 'ext_state' => 'b:0;', ), @@ -57,12 +57,12 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case // do not exist array( - 'ext_name' => 'test2', + 'ext_name' => 'vendor/test2', 'ext_active' => true, 'ext_state' => 'b:0;', ), array( - 'ext_name' => 'test3', + 'ext_name' => 'vendor/test3', 'ext_active' => false, 'ext_state' => 'b:0;', ), @@ -77,58 +77,67 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case public function test_list() { - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid); + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid); - $this->assertCount(1, $crawler->filter('.ext_enabled')); - $this->assertCount(5, $crawler->filter('.ext_disabled')); + $this->assertCount(1, $crawler->filter('.ext_enabled')); + $this->assertCount(4, $crawler->filter('.ext_disabled')); - $this->assertContains('phpBB Foo Extension', $crawler->filter('.ext_enabled')->eq(0)->text()); - $this->assertContainsLang('PURGE', $crawler->filter('.ext_enabled')->eq(0)->text()); + $this->assertContains('phpBB Foo Extension', $crawler->filter('.ext_enabled')->eq(0)->text()); + $this->assertContainsLang('EXTENSION_DISABLE', $crawler->filter('.ext_enabled')->eq(0)->text()); - $this->assertContains('The "test2" extension is not valid.', $crawler->filter('.ext_disabled')->eq(0)->text()); + $this->assertContains('phpBB Moo Extension', $crawler->filter('.ext_disabled')->eq(2)->text()); + $this->assertContainsLang('DETAILS', $crawler->filter('.ext_disabled')->eq(2)->text()); + $this->assertContainsLang('EXTENSION_ENABLE', $crawler->filter('.ext_disabled')->eq(2)->text()); + $this->assertContainsLang('EXTENSION_DELETE_DATA', $crawler->filter('.ext_disabled')->eq(2)->text()); - $this->assertContains('The "test3" extension is not valid.', $crawler->filter('.ext_disabled')->eq(1)->text()); + $this->assertContains('The “vendor/test2” extension is not valid.', $crawler->filter('.ext_disabled')->eq(0)->text()); - $this->assertContains('phpBB Moo Extension', $crawler->filter('.ext_disabled')->eq(2)->text()); - $this->assertContainsLang('DETAILS', $crawler->filter('.ext_disabled')->eq(2)->text()); - $this->assertContainsLang('ENABLE', $crawler->filter('.ext_disabled')->eq(2)->text()); - $this->assertContainsLang('PURGE', $crawler->filter('.ext_disabled')->eq(2)->text()); + $this->assertContains('The “vendor/test3” extension is not valid.', $crawler->filter('.ext_disabled')->eq(1)->text()); - $this->assertContains('The "bar" extension is not valid.', $crawler->filter('.ext_disabled')->eq(3)->text()); + $this->assertContains('phpBB Bar Extension', $crawler->filter('.ext_disabled')->eq(3)->text()); + $this->assertContainsLang('DETAILS', $crawler->filter('.ext_disabled')->eq(3)->text()); + $this->assertContainsLang('EXTENSION_ENABLE', $crawler->filter('.ext_disabled')->eq(3)->text()); + + // Check that invalid extensions are not listed. + $this->assertNotContains('phpBB BarFoo Extension', $crawler->filter('.table1')->text()); + $this->assertNotContains('barfoo', $crawler->filter('.table1')->text()); + + $this->assertNotContains('vendor3/bar', $crawler->filter('.table1')->text()); } public function test_details() { - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=foo&sid=' . $this->sid); - - $validation = array( - 'DISPLAY_NAME' => 'phpBB Foo Extension', - 'CLEAN_NAME' => 'foo/example', - 'DESCRIPTION' => 'An example/sample extension to be used for testing purposes in phpBB Development.', - 'VERSION' => '1.0.0', - 'TIME' => '2012-02-15 01:01:01', - 'LICENCE' => 'GPL-2.0', - 'PHPBB_VERSION' => '3.1.0-dev', - 'PHP_VERSION' => '>=5.3', - 'AUTHOR_NAME' => 'Nathan Guse', - 'AUTHOR_EMAIL' => 'email@phpbb.com', - 'AUTHOR_HOMEPAGE' => 'http://lithiumstudios.org', - 'AUTHOR_ROLE' => 'N/A', - ); - - for ($i = 0; $i < $crawler->filter('dl')->count(); $i++) - { - $text = $crawler->filter('dl')->eq($i)->text(); - - $match = false; - - foreach ($validation as $language_key => $expected) - { - if (strpos($text, $this->lang($language_key)) === 0) - { - $match = true; - - $this->assertContains($expected, $text); + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=vendor2%2Ffoo&sid=' . $this->sid); + + $validation = array( + 'DISPLAY_NAME' => 'phpBB Foo Extension', + 'CLEAN_NAME' => 'vendor2/foo', + 'TYPE' => 'phpbb-extension', + 'DESCRIPTION' => 'An example/sample extension to be used for testing purposes in phpBB Development.', + 'VERSION' => '1.0.0', + 'TIME' => '2012-02-15 01:01:01', + 'LICENSE' => 'GPL-2.0', + 'PHPBB_VERSION' => '3.1.*@dev', + 'PHP_VERSION' => '>=5.3', + 'AUTHOR_NAME' => 'John Smith', + 'AUTHOR_EMAIL' => 'email@phpbb.com', + 'AUTHOR_HOMEPAGE' => 'http://phpbb.com', + 'AUTHOR_ROLE' => 'N/A', + ); + + for ($i = 0; $i < $crawler->filter('dl')->count(); $i++) + { + $text = $crawler->filter('dl')->eq($i)->text(); + + $match = false; + + foreach ($validation as $language_key => $expected) + { + if (strpos($text, $this->lang($language_key)) === 0) + { + $match = true; + + $this->assertContains($expected, $text); } } @@ -142,46 +151,77 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case public function test_enable_pre() { // Foo is already enabled (redirect to list) - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=foo&sid=' . $this->sid); - $this->assertContainsLang('EXTENSION_NAME', $crawler->filter('html')->text()); - $this->assertContainsLang('EXTENSION_OPTIONS', $crawler->filter('html')->text()); - $this->assertContainsLang('EXTENSION_ACTIONS', $crawler->filter('html')->text()); + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor2%2Ffoo&sid=' . $this->sid); + $this->assertContainsLang('EXTENSION_NAME', $crawler->filter('div.main thead')->text()); + $this->assertContainsLang('EXTENSION_OPTIONS', $crawler->filter('div.main thead')->text()); + $this->assertContainsLang('EXTENSION_ACTIONS', $crawler->filter('div.main thead')->text()); - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); - $this->assertContainsLang('ENABLE_CONFIRM', $crawler->filter('html')->text()); + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); + $this->assertContains($this->lang('EXTENSION_ENABLE_CONFIRM', 'phpBB Moo Extension'), $crawler->filter('.errorbox')->text()); } public function test_disable_pre() { - // Moo is not enabled (redirect to list) - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); - $this->assertContainsLang('EXTENSION_NAME', $crawler->filter('html')->text()); - $this->assertContainsLang('EXTENSION_OPTIONS', $crawler->filter('html')->text()); - $this->assertContainsLang('EXTENSION_ACTIONS', $crawler->filter('html')->text()); - - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=foo&sid=' . $this->sid); - $this->assertContainsLang('DISABLE_CONFIRM', $crawler->filter('html')->text()); + // Moo is not enabled (redirect to list) + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); + $this->assertContainsLang('EXTENSION_NAME', $crawler->filter('div.main thead')->text()); + $this->assertContainsLang('EXTENSION_OPTIONS', $crawler->filter('div.main thead')->text()); + $this->assertContainsLang('EXTENSION_ACTIONS', $crawler->filter('div.main thead')->text()); + + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=vendor2%2Ffoo&sid=' . $this->sid); + $this->assertContains($this->lang('EXTENSION_DISABLE_CONFIRM', 'phpBB Foo Extension'), $crawler->filter('.errorbox')->text()); } - public function test_purge_pre() + public function test_delete_data_pre() { - // test2 is not available (error) - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge_pre&ext_name=test2&sid=' . $this->sid); - $this->assertContains('The required file does not exist', $crawler->filter('html')->text()); - - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge_pre&ext_name=foo&sid=' . $this->sid); - $this->assertContainsLang('PURGE_CONFIRM', $crawler->filter('html')->text()); + // test2 is not available (error) + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=delete_data_pre&ext_name=test2&sid=' . $this->sid); + $this->assertContains('The required file does not exist', $crawler->filter('.errorbox')->text()); + + // foo is not disabled (redirect to list) + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=delete_data_pre&ext_name=vendor2%2Ffoo&sid=' . $this->sid); + $this->assertContainsLang('EXTENSION_NAME', $crawler->filter('div.main thead')->text()); + $this->assertContainsLang('EXTENSION_OPTIONS', $crawler->filter('div.main thead')->text()); + $this->assertContainsLang('EXTENSION_ACTIONS', $crawler->filter('div.main thead')->text()); + + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=delete_data_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); + $this->assertContains('Are you sure that you wish to delete the data associated with “phpBB Moo Extension”?', $crawler->filter('.errorbox')->text()); } public function test_actions() { - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable&ext_name=vendor%2Fmoo&sid=' . $this->sid); - $this->assertContainsLang('ENABLE_SUCCESS', $crawler->filter('html')->text()); - - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable&ext_name=vendor%2Fmoo&sid=' . $this->sid); - $this->assertContainsLang('DISABLE_SUCCESS', $crawler->filter('html')->text()); - - $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=purge&ext_name=vendor%2Fmoo&sid=' . $this->sid); - $this->assertContainsLang('PURGE_SUCCESS', $crawler->filter('html')->text()); + // Access enable page without hash + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable&ext_name=vendor%2Fmoo&sid=' . $this->sid); + $this->assertContainsLang('FORM_INVALID', $crawler->filter('.errorbox')->text()); + + // Correctly submit the enable form + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); + $form = $crawler->selectButton('enable')->form(); + $crawler = self::submit($form); + $this->assertContainsLang('EXTENSION_ENABLE_SUCCESS', $crawler->filter('.successbox')->text()); + + // Access disable page without hash + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable&ext_name=vendor%2Fmoo&sid=' . $this->sid); + $this->assertContainsLang('FORM_INVALID', $crawler->filter('.errorbox')->text()); + + // Correctly submit the disable form + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=disable_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); + $form = $crawler->selectButton('disable')->form(); + $crawler = self::submit($form); + $this->assertContainsLang('EXTENSION_DISABLE_SUCCESS', $crawler->filter('.successbox')->text()); + + // Access delete_data page without hash + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=delete_data&ext_name=vendor%2Fmoo&sid=' . $this->sid); + $this->assertContainsLang('FORM_INVALID', $crawler->filter('.errorbox')->text()); + + // Correctly submit the delete data form + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=delete_data_pre&ext_name=vendor%2Fmoo&sid=' . $this->sid); + $form = $crawler->selectButton('delete_data')->form(); + $crawler = self::submit($form); + $this->assertContainsLang('EXTENSION_DELETE_DATA_SUCCESS', $crawler->filter('.successbox')->text()); + + // Attempt to enable invalid extension + $crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=enable_pre&ext_name=barfoo&sid=' . $this->sid); + $this->assertContainsLang('EXTENSION_DIR_INVALID', $crawler->filter('.errorbox')->text()); } -}
\ No newline at end of file +} diff --git a/tests/functional/extension_controller_test.php b/tests/functional/extension_controller_test.php index 41bd48c204..57b0f56bee 100644 --- a/tests/functional/extension_controller_test.php +++ b/tests/functional/extension_controller_test.php @@ -19,6 +19,8 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c static protected $fixtures = array( 'foo/bar/config/', 'foo/bar/controller/', + 'foo/bar/event/', + 'foo/bar/language/en/', 'foo/bar/styles/prosilver/template/', ); @@ -109,4 +111,53 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c $this->assert_response_html(404); $this->assertContains('No route found for "GET /does/not/exist"', $crawler->filter('body')->text()); } + + /** + * Check the redirect after using the login_box() form + */ + public function test_login_redirect() + { + $this->markTestIncomplete('Session table contains incorrect data for controllers on travis,' + . 'therefor the redirect fails.'); + + $this->phpbb_extension_manager->enable('foo/bar'); + $crawler = self::request('GET', 'app.php/foo/login_redirect'); + $this->assertContainsLang('LOGIN', $crawler->filter('h2')->text()); + $form = $crawler->selectButton('login')->form(array( + 'username' => 'admin', + 'password' => 'adminadmin', + )); + $this->assertStringStartsWith('./app.php/foo/login_redirect', $form->get('redirect')->getValue()); + + $crawler = self::submit($form); + $this->assertContains("I am a variable", $crawler->filter('#content')->text(), 'Unsuccessful redirect after using login_box()'); + $this->phpbb_extension_manager->purge('foo/bar'); + } + + /** + * Check the output of a controller using the template system + */ + public function test_redirect() + { + $this->phpbb_extension_manager->enable('foo/bar'); + $crawler = self::request('GET', 'app.php/foo/redirect'); + + $nodes = $crawler->filter('div')->extract(array('id')); + + foreach ($nodes as $redirect) + { + if (strpos($redirect, 'redirect_expected') !== 0) + { + continue; + } + + $row_num = str_replace('redirect_expected_', '', $redirect); + + $redirect = $crawler->filter('#redirect_' . $row_num)->text(); + $redirect = substr($redirect, 0, strpos($redirect, 'sid') - 1); + $this->assertEquals($crawler->filter('#redirect_expected_' . $row_num)->text(), $redirect); + } + + $this->phpbb_extension_manager->purge('foo/bar'); + } } diff --git a/tests/functional/extension_global_lang_test.php b/tests/functional/extension_global_lang_test.php index fb8f87e6de..094eda8257 100644 --- a/tests/functional/extension_global_lang_test.php +++ b/tests/functional/extension_global_lang_test.php @@ -17,8 +17,9 @@ class phpbb_functional_extension_global_lang_test extends phpbb_functional_test_ static private $helper; static protected $fixtures = array( - 'foo/bar/language/en/', + 'foo/bar/config/', 'foo/bar/event/', + 'foo/bar/language/en/', ); static public function setUpBeforeClass() diff --git a/tests/functional/extension_module_test.php b/tests/functional/extension_module_test.php index 090cd38daf..ba025d582e 100644 --- a/tests/functional/extension_module_test.php +++ b/tests/functional/extension_module_test.php @@ -80,18 +80,53 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case ); $modules->update_module_data($module_data, true); + $parent_data = array( + 'module_basename' => '', + 'module_enabled' => 1, + 'module_display' => 1, + 'parent_id' => 0, + 'module_class' => 'ucp', + 'module_langname' => 'UCP_FOOBAR_TITLE', + 'module_mode' => '', + 'module_auth' => '', + ); + $modules->update_module_data($parent_data, true); + + $module_data = array( + 'module_basename' => 'foo\\bar\\ucp\\main_module', + 'module_enabled' => 1, + 'module_display' => 1, + 'parent_id' => $parent_data['module_id'], + 'module_class' => 'ucp', + 'module_langname' => 'UCP_FOOBAR_TITLE', + 'module_mode' => 'mode', + 'module_auth' => '', + ); + $modules->update_module_data($module_data, true); + $this->purge_cache(); } - /** - * Check a controller for extension foo/bar. - */ - public function test_foo_bar() + public function test_acp() { $this->login(); $this->admin_login(); + $crawler = self::request('GET', 'adm/index.php?i=foo%5cbar%5cacp%5cmain_module&mode=mode&sid=' . $this->sid); - $this->assertContains("Bertie rulez!", $crawler->filter('#main')->text()); + $this->assertContains('Bertie rulez!', $crawler->filter('#main')->text()); + } + + public function test_ucp() + { + $this->login(); + + $crawler = self::request('GET', 'ucp.php?sid=' . $this->sid); + $this->assertContains('UCP_FOOBAR_TITLE', $crawler->filter('#tabs')->text()); + + $link = $crawler->selectLink('UCP_FOOBAR_TITLE')->link()->getUri(); + $crawler = self::request('GET', substr($link, strpos($link, 'ucp.'))); + $this->assertContains('UCP Extension Template Test Passed!', $crawler->filter('#content')->text()); + $this->phpbb_extension_manager->purge('foo/bar'); } } diff --git a/tests/functional/extension_permission_lang_test.php b/tests/functional/extension_permission_lang_test.php index 19adb89819..e922abdaf1 100644 --- a/tests/functional/extension_permission_lang_test.php +++ b/tests/functional/extension_permission_lang_test.php @@ -17,8 +17,9 @@ class phpbb_functional_extension_permission_lang_test extends phpbb_functional_t static private $helper; static protected $fixtures = array( - 'foo/bar/language/en/', + 'foo/bar/config/', 'foo/bar/event/', + 'foo/bar/language/en/', ); static public function setUpBeforeClass() diff --git a/tests/functional/fileupload_form_test.php b/tests/functional/fileupload_form_test.php index 998c402fa3..30f6fd7b47 100644 --- a/tests/functional/fileupload_form_test.php +++ b/tests/functional/fileupload_form_test.php @@ -19,7 +19,25 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case parent::setUp(); $this->path = __DIR__ . '/fixtures/files/'; $this->add_lang('posting'); - $this->login(); + } + + public function tearDown() + { + $iterator = new DirectoryIterator(__DIR__ . '/../../phpBB/files/'); + foreach ($iterator as $fileinfo) + { + if ( + $fileinfo->isDot() + || $fileinfo->isDir() + || $fileinfo->getFilename() === 'index.htm' + || $fileinfo->getFilename() === '.htaccess' + ) + { + continue; + } + + unlink($fileinfo->getPathname()); + } } private function upload_file($filename, $mimetype) @@ -44,30 +62,71 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case public function test_empty_file() { - $this->markTestIncomplete('Test fails intermittently.'); + $this->login(); + $crawler = $this->upload_file('empty.png', 'image/png'); - $this->assertEquals($this->lang('ATTACHED_IMAGE_NOT_IMAGE'), $this->assert_filter($crawler, 'div#message p')->text()); + $this->assertEquals($this->lang('EMPTY_FILEUPLOAD'), $crawler->filter('p.error')->text()); } public function test_invalid_extension() { + $this->login(); + $crawler = $this->upload_file('illegal-extension.bif', 'application/octet-stream'); $this->assertEquals($this->lang('DISALLOWED_EXTENSION', 'bif'), $crawler->filter('p.error')->text()); } + public function test_disallowed_content() + { + $this->login(); + + $crawler = $this->upload_file('disallowed.jpg', 'image/jpeg'); + $this->assertEquals($this->lang('DISALLOWED_CONTENT'), $crawler->filter('p.error')->text()); + } + + public function test_disallowed_content_no_check() + { + $this->login(); + $this->admin_login(); + $this->add_lang('ucp'); + $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_attachments&mode=attach'); + + $form = $crawler->selectButton('Submit')->form(); + $values = $form->getValues(); + + $values["config[check_attachment_content]"] = 0; + $form->setValues($values); + $crawler = self::submit($form); + + // Request index for correct URL + $crawler = self::request('GET', 'index.php?sid=' . $this->sid); + + $crawler = $this->upload_file('disallowed.jpg', 'image/jpeg'); + + // Hitting the UNABLE_GET_IMAGE_SIZE error means we passed the + // DISALLOWED_CONTENT check + $this->assertEquals($this->lang('UNABLE_GET_IMAGE_SIZE'), $crawler->filter('p.error')->text()); + } + public function test_too_large() { - $this->markTestIncomplete('Functional tests use an admin account which ignores maximum upload size.'); + $this->create_user('fileupload'); + $this->login('fileupload'); + $crawler = $this->upload_file('too-large.png', 'image/png'); $this->assertEquals($this->lang('WRONG_FILESIZE', '256', 'KiB'), $crawler->filter('p.error')->text()); } public function test_valid_file() { - $this->markTestIncomplete('Test fails intermittently.'); + $this->login(); + $crawler = $this->upload_file('valid.jpg', 'image/jpeg'); - // ensure there was no error message rendered + + // Ensure there was no error message rendered $this->assertNotContains('<h2>' . $this->lang('INFORMATION') . '</h2>', $this->get_content()); - $this->assertContains($this->lang('POSTED_ATTACHMENTS'), $crawler->filter('#postform h3')->eq(1)->text()); + + // Also the file name should be in the first row of the files table + $this->assertEquals('valid.jpg', $crawler->filter('span.file-name')->eq(1)->text()); } } diff --git a/tests/functional/fixtures/ext/foo/bar/composer.json b/tests/functional/fixtures/ext/foo/bar/composer.json index 067a9d38eb..2f91426d2a 100644 --- a/tests/functional/fixtures/ext/foo/bar/composer.json +++ b/tests/functional/fixtures/ext/foo/bar/composer.json @@ -1,21 +1,20 @@ { "name": "foo/bar", - "type": "phpbb3-extension", + "type": "phpbb-extension", "description": "Testing extensions", "homepage": "", "version": "1.0.0", "time": "2013-03-21 01:01:01", - "licence": "GPL-2.0", + "license": "GPL-2.0", "authors": [{ "name": "Joas Schilling", - "username": "nickvergessen", "email": "nickvergessen@phpbb.com", "homepage": "http://www.phpbb.com", "role": "Developer" }], "require": { "php": ">=5.3", - "phpbb": ">=3.1.0-dev" + "phpbb/phpbb": "3.1.*@dev" }, "extra": { "display-name": "phpBB 3.1 Extension Testing" diff --git a/tests/functional/fixtures/ext/foo/bar/config/routing.yml b/tests/functional/fixtures/ext/foo/bar/config/routing.yml index 09a30a8c67..08bc73038f 100644 --- a/tests/functional/fixtures/ext/foo/bar/config/routing.yml +++ b/tests/functional/fixtures/ext/foo/bar/config/routing.yml @@ -13,3 +13,23 @@ foo_template_controller: foo_exception_controller: pattern: /foo/exception defaults: { _controller: foo_bar.controller:exception } + +foo_login_redirect_controller: + pattern: /foo/login_redirect + defaults: { _controller: foo_bar.controller:login_redirect } + +foo_redirect_controller: + pattern: /foo/redirect + defaults: { _controller: foo_bar.controller:redirect } + +foo_index_controller: + pattern: /index + defaults: { _controller: foo_bar.controller:redirect } + +foo_tests_index_controller: + pattern: /tests/index + defaults: { _controller: foo_bar.controller:redirect } + +foo_tests_dotdot_index_controller: + pattern: /tests/../index + defaults: { _controller: foo_bar.controller:redirect } diff --git a/tests/functional/fixtures/ext/foo/bar/config/services.yml b/tests/functional/fixtures/ext/foo/bar/config/services.yml index 3bca4c6567..d35be7955a 100644 --- a/tests/functional/fixtures/ext/foo/bar/config/services.yml +++ b/tests/functional/fixtures/ext/foo/bar/config/services.yml @@ -3,4 +3,18 @@ services: class: foo\bar\controller\controller arguments: - @controller.helper + - @path_helper - @template + - @config + - @user + - %core.root_path% + - %core.php_ext% + + foo_bar.listener.permission: + class: foo\bar\event\permission + tags: + - { name: event.listener } + foo_bar.listener.user_setup: + class: foo\bar\event\user_setup + tags: + - { name: event.listener } diff --git a/tests/functional/fixtures/ext/foo/bar/controller/controller.php b/tests/functional/fixtures/ext/foo/bar/controller/controller.php index 259d548299..47d856a5df 100644 --- a/tests/functional/fixtures/ext/foo/bar/controller/controller.php +++ b/tests/functional/fixtures/ext/foo/bar/controller/controller.php @@ -7,11 +7,20 @@ use Symfony\Component\HttpFoundation\Response; class controller { protected $template; + protected $helper; + protected $path_helper; + protected $config; + protected $user; - public function __construct(\phpbb\controller\helper $helper, \phpbb\template\template $template) + public function __construct(\phpbb\controller\helper $helper, \phpbb\path_helper $path_helper, \phpbb\template\template $template, \phpbb\config\config $config, \phpbb\user $user, $root_path, $php_ext) { $this->template = $template; $this->helper = $helper; + $this->path_helper = $path_helper; + $this->config = $config; + $this->user = $user; + $this->root_path = $root_path; + $this->php_ext = $php_ext; } public function handle() @@ -35,4 +44,66 @@ class controller { throw new \phpbb\controller\exception('Exception thrown from foo/exception route'); } + + public function login_redirect() + { + if (!$this->user->data['is_registered']) + { + login_box(); + } + + $this->template->assign_var('A_VARIABLE', 'I am a variable'); + + return $this->helper->render('foo_bar_body.html'); + } + + public function redirect() + { + $url_root = generate_board_url(); + + $rewrite_prefix = (!empty($this->config['enable_mod_rewrite'])) ? '' : 'app.php/'; + + $redirects = array( + array( + append_sid($this->root_path . 'index.' . $this->php_ext), + 'index.php', + ), + array( + append_sid($this->root_path . 'foo/bar/index.' . $this->php_ext), + 'foo/bar/index.php', + ), + array( + append_sid($this->root_path . 'tests/index.' . $this->php_ext), + 'tests/index.php', + ), + array( + $this->helper->route('foo_index_controller'), + $rewrite_prefix . 'index', + ), + array( + $this->helper->route('foo_tests_index_controller'), + $rewrite_prefix . 'tests/index', + ), + /** + * Symfony does not allow /../ in routes + array( + $this->helper->route('foo_tests_dotdot_index_controller'), + $rewrite_prefix . 'index', + ), + */ + ); + + foreach ($redirects as $redirect) + { + $this->template->assign_block_vars('redirects', array( + 'URL' => redirect($redirect[0], true), + )); + + $this->template->assign_block_vars('redirects_expected', array( + 'URL' => $this->path_helper->clean_url($url_root . '/' . $redirect[1]), + )); + } + + return $this->helper->render('redirect_body.html'); + } } diff --git a/tests/functional/fixtures/ext/foo/bar/event/permission.php b/tests/functional/fixtures/ext/foo/bar/event/permission.php index 92e24074ad..9b319dd35f 100644 --- a/tests/functional/fixtures/ext/foo/bar/event/permission.php +++ b/tests/functional/fixtures/ext/foo/bar/event/permission.php @@ -11,15 +11,6 @@ namespace foo\bar\event; /** -* @ignore -*/ - -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Event listener */ use Symfony\Component\EventDispatcher\EventSubscriberInterface; diff --git a/tests/functional/fixtures/ext/foo/bar/event/user_setup.php b/tests/functional/fixtures/ext/foo/bar/event/user_setup.php index 1409f97470..8fa7ac97da 100644 --- a/tests/functional/fixtures/ext/foo/bar/event/user_setup.php +++ b/tests/functional/fixtures/ext/foo/bar/event/user_setup.php @@ -11,15 +11,6 @@ namespace foo\bar\event; /** -* @ignore -*/ - -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** * Event listener */ use Symfony\Component\EventDispatcher\EventSubscriberInterface; diff --git a/tests/functional/fixtures/ext/foo/bar/styles/prosilver/template/foobar.html b/tests/functional/fixtures/ext/foo/bar/styles/prosilver/template/foobar.html new file mode 100644 index 0000000000..cbded623f4 --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/styles/prosilver/template/foobar.html @@ -0,0 +1,3 @@ +<!-- INCLUDE overall_header.html --> +<div id="content">UCP Extension Template Test Passed!</div> +<!-- INCLUDE overall_footer.html --> diff --git a/tests/functional/fixtures/ext/foo/bar/styles/prosilver/template/redirect_body.html b/tests/functional/fixtures/ext/foo/bar/styles/prosilver/template/redirect_body.html new file mode 100644 index 0000000000..2b70b0fe59 --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/styles/prosilver/template/redirect_body.html @@ -0,0 +1,8 @@ +<!-- INCLUDE overall_header.html --> +<!-- BEGIN redirects --> +<div id="redirect_{redirects.S_ROW_COUNT}">{redirects.URL}</div> +<!-- END redirects --> +<!-- BEGIN redirects_expected --> +<div id="redirect_expected_{redirects_expected.S_ROW_COUNT}">{redirects_expected.URL}</div> +<!-- END redirects_expected --> +<!-- INCLUDE overall_footer.html --> diff --git a/tests/functional/fixtures/ext/foo/bar/ucp/main_info.php b/tests/functional/fixtures/ext/foo/bar/ucp/main_info.php new file mode 100644 index 0000000000..2ba37f3050 --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/ucp/main_info.php @@ -0,0 +1,26 @@ +<?php + +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace foo\bar\ucp; + +class main_info +{ + function module() + { + return array( + 'filename' => '\foo\bar\ucp\main_module', + 'title' => 'ACP_FOOBAR_TITLE', + 'version' => '1.0.0', + 'modes' => array( + 'mode' => array('title' => 'ACP_FOOBAR_MODE', 'auth' => '', 'cat' => array('ACP_FOOBAR_TITLE')), + ), + ); + } +} diff --git a/tests/functional/fixtures/ext/foo/bar/ucp/main_module.php b/tests/functional/fixtures/ext/foo/bar/ucp/main_module.php new file mode 100644 index 0000000000..cd3dacc9db --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/ucp/main_module.php @@ -0,0 +1,22 @@ +<?php + +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace foo\bar\ucp; + +class main_module +{ + var $u_action; + + function main($id, $mode) + { + $this->tpl_name = 'foobar'; + $this->page_title = 'Bertie'; + } +} diff --git a/tests/functional/fixtures/files/disallowed.jpg b/tests/functional/fixtures/files/disallowed.jpg Binary files differnew file mode 100644 index 0000000000..06a437585a --- /dev/null +++ b/tests/functional/fixtures/files/disallowed.jpg diff --git a/tests/functional/forgot_password_test.php b/tests/functional/forgot_password_test.php index 906224efbb..3b6fd15d02 100644 --- a/tests/functional/forgot_password_test.php +++ b/tests/functional/forgot_password_test.php @@ -41,4 +41,17 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case } + public function tearDown() + { + $this->login(); + $this->admin_login(); + + $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=security'); + + // Enable allow_password_reset again after test + $form = $crawler->selectButton('Submit')->form(array( + 'config[allow_password_reset]' => 1, + )); + $crawler = self::submit($form); + } } diff --git a/tests/functional/forum_password_test.php b/tests/functional/forum_password_test.php new file mode 100644 index 0000000000..40a8059ad1 --- /dev/null +++ b/tests/functional/forum_password_test.php @@ -0,0 +1,55 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_forum_password_test extends phpbb_functional_test_case +{ + public function test_setup_forum_with_password() + { + $this->login(); + $this->admin_login(); + + $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}"); + $form = $crawler->selectButton('addforum')->form(array( + 'forum_name' => 'Password protected', + )); + $crawler = self::submit($form); + $form = $crawler->selectButton('update')->form(array( + 'forum_perm_from' => 2, + 'forum_password' => 'foobar', + 'forum_password_confirm' => 'foobar', + )); + $crawler = self::submit($form); + } + + public function data_enter_forum_with_password() + { + return array( + array('foowrong', 'WRONG_PASSWORD'), + array('foobar', 'NO_TOPICS'), + ); + } + + /** + * @dataProvider data_enter_forum_with_password + */ + public function test_enter_forum_with_password($password, $message) + { + $crawler = self::request('GET', "index.php?sid={$this->sid}"); + preg_match('/.?f=([0-9])/', $crawler->selectLink('Password protected')->link()->getUri(), $match); + $crawler = self::request('GET', "viewforum.php?f={$match[1]}&sid={$this->sid}"); + $form = $crawler->selectButton('login')->form(array( + 'password' => $password, + )); + $crawler = self::submit($form); + $this->assertContainsLang($message, $crawler->text()); + } +} diff --git a/tests/functional/group_create_test.php b/tests/functional/group_create_test.php new file mode 100644 index 0000000000..96780069f7 --- /dev/null +++ b/tests/functional/group_create_test.php @@ -0,0 +1,31 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_group_create_test extends phpbb_functional_test_case +{ + + public function test_create_group() + { + $this->login(); + $this->admin_login(); + $this->add_lang('acp/groups'); + + $crawler = self::request('GET', 'adm/index.php?i=acp_groups&mode=manage&sid=' . $this->sid); + $form = $crawler->selectButton($this->lang('SUBMIT'))->form(); + $crawler = self::submit($form, array('group_name' => 'testtest')); + + $form = $crawler->selectButton($this->lang('SUBMIT'))->form(); + $crawler = self::submit($form, array('group_name' => 'testtest')); + + $this->assertContainsLang('GROUP_CREATED', $crawler->filter('#main')->text()); + } +} diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php index 738ec4f9dd..b7f7a1823d 100644 --- a/tests/functional/memberlist_test.php +++ b/tests/functional/memberlist_test.php @@ -39,7 +39,7 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case protected function get_memberlist_leaders_table_crawler() { - $crawler = self::request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); + $crawler = self::request('GET', 'memberlist.php?mode=team&sid=' . $this->sid); return $crawler->filter('.forumbg-table'); } diff --git a/tests/functional/metadata_manager_test.php b/tests/functional/metadata_manager_test.php index 651c99a99d..ac08a44e30 100644 --- a/tests/functional/metadata_manager_test.php +++ b/tests/functional/metadata_manager_test.php @@ -70,7 +70,7 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case // Details should be html escaped // However, text() only returns the displayed text, so HTML Special Chars are decoded. // So we test this directly on the content of the response. - $this->assertContains('<p id="require_php">>=5.3</p>', $this->get_content()); + $this->assertContains('<span id="require_php">>=5.3</span>', $this->get_content()); } public function test_extensions_details_notexists() diff --git a/tests/functional/notification_test.php b/tests/functional/notification_test.php index 7f33ad1859..18e8a4ecc0 100644 --- a/tests/functional/notification_test.php +++ b/tests/functional/notification_test.php @@ -52,4 +52,34 @@ class phpbb_functional_notification_test extends phpbb_functional_test_case $this->assert_checkbox_is_unchecked($cplist, $checkbox_name); } } + + public function test_mark_notifications_read() + { + // Create a new standard user + $this->create_user('notificationtestuser'); + $this->add_user_group('NEWLY_REGISTERED', array('notificationtestuser')); + $this->login('notificationtestuser'); + + // Post a new post that needs approval + $this->create_post(2, 1, 'Re: Welcome to phpBB3', 'This is a test [b]post[/b] posted by notificationtestuser.', array(), 'POST_STORED_MOD'); + $crawler = self::request('GET', "viewtopic.php?t=1&sid={$this->sid}"); + $this->assertNotContains('This is a test post posted by notificationtestuser.', $crawler->filter('html')->text()); + + // Login as admin + $this->logout(); + $this->login(); + $this->add_lang('ucp'); + + $crawler = self::request('GET', 'ucp.php?i=ucp_notifications'); + + // At least one notification should exist + $this->assertGreaterThan(0, $crawler->filter('#notification_list_button strong')->text()); + + // Get form token + $link = $crawler->selectLink($this->lang('NOTIFICATIONS_MARK_ALL_READ'))->link()->getUri(); + $crawler = self::request('GET', substr($link, strpos($link, 'ucp.'))); + $form = $crawler->selectButton($this->lang('YES'))->form(); + $crawler = self::submit($form); + $this->assertEquals(0, $crawler->filter('#notification_list_button strong')->text()); + } } diff --git a/tests/functional/paging_test.php b/tests/functional/paging_test.php index d5adc6ad0a..b0e4743d5b 100644 --- a/tests/functional/paging_test.php +++ b/tests/functional/paging_test.php @@ -18,22 +18,22 @@ class phpbb_functional_paging_test extends phpbb_functional_test_case $this->login(); $post = $this->create_topic(2, 'Test Topic 1', 'This is a test topic posted by the testing framework.'); - for ($post_id = 1; $post_id < 20; $post_id++) + for ($post_id = 1; $post_id <= 16; $post_id++) { $this->create_post(2, $post['topic_id'], 'Re: Test Topic 1', 'This is a test post no' . $post_id . ' posted by the testing framework.'); } $crawler = self::request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}"); - $this->assertContains('post no9', $crawler->text()); - $this->assertNotContains('post no19', $crawler->text()); + $this->assertContains('post no4', $crawler->text()); + $this->assertNotContains('post no16', $crawler->text()); $next_link = $crawler->filter('#viewtopic > fieldset > a.arrow-right')->attr('href'); $crawler = self::request('GET', $next_link); - $this->assertContains('post no19', $crawler->text()); - $this->assertNotContains('post no9', $crawler->text()); + $this->assertNotContains('post no4', $crawler->text()); + $this->assertContains('post no16', $crawler->text()); $prev_link = $crawler->filter('#viewtopic > fieldset > a.arrow-left')->attr('href'); $crawler = self::request('GET', $prev_link); - $this->assertContains('post no9', $crawler->text()); - $this->assertNotContains('post no19', $crawler->text()); + $this->assertContains('post no4', $crawler->text()); + $this->assertNotContains('post no16', $crawler->text()); } } diff --git a/tests/functional/plupload_test.php b/tests/functional/plupload_test.php new file mode 100644 index 0000000000..a91e70c7bb --- /dev/null +++ b/tests/functional/plupload_test.php @@ -0,0 +1,149 @@ +<?php +/** + * + * @package testing + * @copyright (c) 2012 phpBB Group + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 + * + */ + +/** + * @group functional + */ +class phpbb_functional_plupload_test extends phpbb_functional_test_case +{ + const CHUNKS = 4; + private $path; + + protected function set_extension_group_permission($val) + { + $db = $this->get_db(); + $query = " + UPDATE phpbb_extension_groups + SET allow_in_pm = '$val' + WHERE group_name = 'IMAGES' + "; + $db->sql_query($query); + } + + public function setUp() + { + parent::setUp(); + $this->set_extension_group_permission(1); + $this->path = __DIR__ . '/fixtures/files/'; + $this->add_lang('posting'); + $this->login(); + } + + public function tearDown() + { + $this->set_extension_group_permission(0); + $iterator = new DirectoryIterator(__DIR__ . '/../../phpBB/files/'); + foreach ($iterator as $fileinfo) + { + if ( + $fileinfo->isDot() + || $fileinfo->isDir() + || $fileinfo->getFilename() === 'index.htm' + || $fileinfo->getFilename() === '.htaccess' + ) + { + continue; + } + + unlink($fileinfo->getPathname()); + } + } + + public function get_urls() + { + return array( + array('posting.php?mode=reply&f=2&t=1'), + array('ucp.php?i=pm&mode=compose'), + ); + } + + /** + * @dataProvider get_urls + */ + public function test_chunked_upload($url) + { + $chunk_size = ceil(filesize($this->path . 'valid.jpg') / self::CHUNKS); + $handle = fopen($this->path . 'valid.jpg', 'rb'); + + for ($i = 0; $i < self::CHUNKS; $i++) + { + $chunk = fread($handle, $chunk_size); + file_put_contents($this-> path . 'chunk', $chunk); + + $file = array( + 'tmp_name' => $this->path . 'chunk', + 'name' => 'blob', + 'type' => 'application/octet-stream', + 'size' => strlen($chunk), + 'error' => UPLOAD_ERR_OK, + ); + + self::$client->setServerParameter('HTTP_X_PHPBB_USING_PLUPLOAD', '1'); + + $crawler = self::$client->request( + 'POST', + $url . '&sid=' . $this->sid, + array( + 'chunk' => $i, + 'chunks' => self::CHUNKS, + 'name' => md5('valid') . '.jpg', + 'real_filename' => 'valid.jpg', + 'add_file' => $this->lang('ADD_FILE'), + ), + array('fileupload' => $file), + array('X-PHPBB-USING-PLUPLOAD' => '1') + ); + + if ($i < self::CHUNKS - 1) + { + $this->assertContains('{"jsonrpc":"2.0","id":"id","result":null}', self::$client->getResponse()->getContent()); + } + else + { + $response = json_decode(self::$client->getResponse()->getContent(), true); + $this->assertEquals('valid.jpg', $response['data'][0]['real_filename']); + } + + unlink($this->path . 'chunk'); + } + + fclose($handle); + } + + /** + * @dataProvider get_urls + */ + public function test_normal_upload($url) + { + $file = array( + 'tmp_name' => $this->path . 'valid.jpg', + 'name' => 'valid.jpg', + 'type' => 'image/jpeg', + 'size' => filesize($this->path . 'valid.jpg'), + 'error' => UPLOAD_ERR_OK, + ); + + $crawler = self::$client->request( + 'POST', + $url . '&sid=' . $this->sid, + array( + 'chunk' => '0', + 'chunks' => '1', + 'name' => md5('valid') . '.jpg', + 'real_filename' => 'valid.jpg', + 'add_file' => $this->lang('ADD_FILE'), + ), + array('fileupload' => $file), + array('X-PHPBB-USING-PLUPLOAD' => '1') + ); + + $response = json_decode(self::$client->getResponse()->getContent(), true); + $this->assertEquals('valid.jpg', $response['data'][0]['real_filename']); + } +} diff --git a/tests/functional/prune_shadow_topic_test.php b/tests/functional/prune_shadow_topic_test.php new file mode 100644 index 0000000000..a9fd2457bb --- /dev/null +++ b/tests/functional/prune_shadow_topic_test.php @@ -0,0 +1,207 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_prune_shadow_topic_test extends phpbb_functional_test_case +{ + protected $data = array(); + protected $post; + + public function test_setup_forums() + { + $this->login(); + $this->admin_login(); + + $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}"); + $form = $crawler->selectButton('addforum')->form(array( + 'forum_name' => 'Prune Shadow', + )); + $crawler = self::submit($form); + $form = $crawler->selectButton('update')->form(array( + 'forum_perm_from' => 2, + 'enable_shadow_prune' => true, + 'prune_shadow_freq' => 1, + 'prune_shadow_days' => 1, + )); + $crawler = self::submit($form); + } + + public function test_create_post() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Prune Shadow', + ), + )); + + $this->assert_forum_details($this->data['forums']['Prune Shadow'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => 0, + ), 'initial comparison'); + + // Test creating topic + $this->post = $this->create_topic($this->data['forums']['Prune Shadow'], 'Prune Shadow #1', 'This is a test topic posted by the testing framework.'); + $crawler = self::request('GET', "viewtopic.php?t={$this->post['topic_id']}&sid={$this->sid}"); + + $this->assertContains('Prune Shadow #1', $crawler->filter('html')->text()); + $this->data['topics']['Prune Shadow #1'] = (int) $post['topic_id']; + $this->data['posts']['Prune Shadow #1'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); + + $this->assert_forum_details($this->data['forums']['Prune Shadow'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Prune Shadow #1'], + ), 'after creating topic #1'); + + // Test creating a reply + $post2 = $this->create_post($this->data['forums']['Prune Shadow'], $this->post['topic_id'], 'Re: Prune Shadow #1-#2', 'This is a test post posted by the testing framework.'); + $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); + + $this->assertContains('Re: Prune Shadow #1-#2', $crawler->filter('html')->text()); + $this->data['posts']['Re: Prune Shadow #1-#2'] = (int) $post2['post_id']; + + $this->assert_forum_details($this->data['forums']['Prune Shadow'], array( + 'forum_posts_approved' => 2, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Re: Prune Shadow #1-#2'], + ), 'after replying'); + } + + public function test_move_topic() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Prune Shadow', + ), + 'topics' => array( + 'Prune Shadow #1', + ), + )); + + $crawler = self::request('GET', "mcp.php?f={$this->data['forums']['Prune Shadow']}&i=main&action=move&mode=forum_view&start=0&topic_id_list[]={$this->data['topics']['Prune Shadow #1']}&sid={$this->sid}"); + $form = $crawler->selectButton('confirm')->form(array( + 'to_forum_id' => 2, + 'move_leave_shadow' => true, + )); + $crawler = self::submit($form); + + $this->assert_forum_details($this->data['forums']['Prune Shadow'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + ), 'after moving'); + + $this->db = $this->get_db(); + // Date topic 3 days back + $sql = 'UPDATE phpbb_topics + SET topic_last_post_time = ' . (time() - 60*60*24*3) . ' + WHERE topic_id = ' . ($this->data['topics']['Prune Shadow #1'] + 1); + $result = $this->db->sql_query($sql); + + $crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Prune Shadow']}&sid={$this->sid}"); + $cron_link = $crawler->filter('img')->last()->attr('src'); + $crawler = self::request('GET', $cron_link . "&sid={$this->sid}", array(), false); + + $this->assert_forum_details($this->data['forums']['Prune Shadow'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + ), 'after the cron job'); + } + + public function assert_forum_details($forum_id, $details, $additional_error_message = '') + { + $this->db = $this->get_db(); + + $sql = 'SELECT ' . implode(', ', array_keys($details)) . ' + FROM phpbb_forums + WHERE forum_id = ' . (int) $forum_id; + $result = $this->db->sql_query($sql); + $data = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->assertEquals($details, $data, "Forum {$forum_id} does not match expected {$additional_error_message}"); + } + + public function load_ids($data) + { + $this->db = $this->get_db(); + + if (!empty($data['forums'])) + { + $sql = 'SELECT * + FROM phpbb_forums + WHERE ' . $this->db->sql_in_set('forum_name', $data['forums']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['forum_name'], $data['forums'])) + { + $this->data['forums'][$row['forum_name']] = (int) $row['forum_id']; + } + } + $this->db->sql_freeresult($result); + } + + if (!empty($data['topics'])) + { + $sql = 'SELECT * + FROM phpbb_topics + WHERE ' . $this->db->sql_in_set('topic_title', $data['topics']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['topic_title'], $data['topics'])) + { + $this->data['topics'][$row['topic_title']] = (int) $row['topic_id']; + } + } + $this->db->sql_freeresult($result); + } + + if (!empty($data['posts'])) + { + $sql = 'SELECT * + FROM phpbb_posts + WHERE ' . $this->db->sql_in_set('post_subject', $data['posts']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['post_subject'], $data['posts'])) + { + $this->data['posts'][$row['post_subject']] = (int) $row['post_id']; + } + } + $this->db->sql_freeresult($result); + } + } +} diff --git a/tests/functional/search/base.php b/tests/functional/search/base.php new file mode 100644 index 0000000000..0bd9bf01ab --- /dev/null +++ b/tests/functional/search/base.php @@ -0,0 +1,100 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +abstract class phpbb_functional_search_base extends phpbb_functional_test_case +{ + protected function assert_search_found($keywords, $posts_found, $words_highlighted) + { + $crawler = self::request('GET', 'search.php?keywords=' . $keywords); + $this->assertEquals($posts_found, $crawler->filter('.postbody')->count()); + $this->assertEquals($words_highlighted, $crawler->filter('.posthilit')->count()); + } + + protected function assert_search_not_found($keywords) + { + $crawler = self::request('GET', 'search.php?keywords=' . $keywords); + $this->assertEquals(0, $crawler->filter('.postbody')->count()); + $split_keywords_string = str_replace(array('+', '-'), ' ', $keywords); + $this->assertEquals($split_keywords_string, $crawler->filter('#keywords')->attr('value')); + } + + public function test_search_backend() + { + $this->login(); + $this->admin_login(); + + $post = $this->create_topic(2, 'Test Topic 1 foosubject', 'This is a test topic posted by the barsearch testing framework.'); + + $crawler = self::request('GET', 'adm/index.php?i=acp_search&mode=settings&sid=' . $this->sid); + $form = $crawler->selectButton('Submit')->form(); + $values = $form->getValues(); + + if ($values["config[search_type]"] != $this->search_backend) + { + $values["config[search_type]"] = $this->search_backend; + $form->setValues($values); + $crawler = self::submit($form); + + $form = $crawler->selectButton('Yes')->form(); + $values = $form->getValues(); + $crawler = self::submit($form); + + // check if search backend is not supported + if ($crawler->filter('.errorbox')->count() > 0) + { + $this->delete_topic($post['topic_id']); + $this->markTestSkipped("Search backend is not supported/running"); + } + $this->create_search_index(); + } + + $this->logout(); + $this->assert_search_found('phpbb3+installation', 1, 3); + $this->assert_search_found('foosubject+barsearch', 1, 2); + $this->assert_search_not_found('loremipsumdedo'); + + $this->login(); + $this->admin_login(); + $this->delete_search_index(); + $this->delete_topic($post['topic_id']); + } + + protected function create_search_index() + { + $this->add_lang('acp/search'); + $crawler = self::request( + 'POST', + 'adm/index.php?i=acp_search&mode=index&sid=' . $this->sid, + array( + 'search_type' => $this->search_backend, + 'action' => 'create', + 'submit' => true, + ) + ); + $this->assertContainsLang('SEARCH_INDEX_CREATED', $crawler->text()); + } + + protected function delete_search_index() + { + $this->add_lang('acp/search'); + $crawler = self::request( + 'POST', + 'adm/index.php?i=acp_search&mode=index&sid=' . $this->sid, + array( + 'search_type' => $this->search_backend, + 'action' => 'delete', + 'submit' => true, + ) + ); + $this->assertContainsLang('SEARCH_INDEX_REMOVED', $crawler->text()); + } +} diff --git a/tests/functional/search/mysql_test.php b/tests/functional/search/mysql_test.php new file mode 100644 index 0000000000..52a7b14f40 --- /dev/null +++ b/tests/functional/search/mysql_test.php @@ -0,0 +1,19 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/base.php'; + +/** +* @group functional +*/ +class phpbb_functional_search_mysql_test extends phpbb_functional_search_base +{ + protected $search_backend = '\phpbb\search\fulltext_mysql'; + +} diff --git a/tests/functional/search/native_test.php b/tests/functional/search/native_test.php new file mode 100644 index 0000000000..512c6f2830 --- /dev/null +++ b/tests/functional/search/native_test.php @@ -0,0 +1,18 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/base.php'; + +/** +* @group functional +*/ +class phpbb_functional_search_native_test extends phpbb_functional_search_base +{ + protected $search_backend = '\phpbb\search\fulltext_native'; +} diff --git a/tests/functional/search/postgres_test.php b/tests/functional/search/postgres_test.php new file mode 100644 index 0000000000..974b417659 --- /dev/null +++ b/tests/functional/search/postgres_test.php @@ -0,0 +1,19 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/base.php'; + +/** +* @group functional +*/ +class phpbb_functional_search_postgres_test extends phpbb_functional_search_base +{ + protected $search_backend = '\phpbb\search\fulltext_postgres'; + +} diff --git a/tests/functional/search/sphinx_test.php b/tests/functional/search/sphinx_test.php new file mode 100644 index 0000000000..ef2522f9ed --- /dev/null +++ b/tests/functional/search/sphinx_test.php @@ -0,0 +1,23 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/base.php'; + +/** +* @group functional +*/ +class phpbb_functional_search_sphinx_test extends phpbb_functional_search_base +{ + protected $search_backend = '\phpbb\search\fulltext_sphinx'; + + public function test_search_backend() + { + $this->markTestIncomplete('Sphinx Tests are not supported'); + } +} diff --git a/tests/functional/ucp_pm_test.php b/tests/functional/ucp_pm_test.php new file mode 100644 index 0000000000..09521cc9f4 --- /dev/null +++ b/tests/functional/ucp_pm_test.php @@ -0,0 +1,48 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_ucp_pm_test extends phpbb_functional_test_case +{ + public function setUp() + { + parent::setUp(); + $this->login(); + $this->admin_login(); + } + + public function test_pm_enabled() + { + $crawler = self::request('GET', 'ucp.php'); + $this->assertContainsLang('PRIVATE_MESSAGES', $crawler->filter('html')->text()); + } + + public function test_pm_disabled() + { + $this->set_allow_pm(0); + $crawler = self::request('GET', 'ucp.php'); + $this->assertNotContainsLang('PRIVATE_MESSAGES', $crawler->filter('html')->text()); + $this->set_allow_pm(1); + } + + protected function set_allow_pm($enable_pm) + { + $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=message'); + + $form = $crawler->selectButton('Submit')->form(); + $values = $form->getValues(); + + $values["config[allow_privmsg]"] = $enable_pm; + $form->setValues($values); + $crawler = self::submit($form); + $this->assertGreaterThan(0, $crawler->filter('.successbox')->count()); + } +} diff --git a/tests/functional/ucp_profile_test.php b/tests/functional/ucp_profile_test.php new file mode 100644 index 0000000000..e0e6255f79 --- /dev/null +++ b/tests/functional/ucp_profile_test.php @@ -0,0 +1,33 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_ucp_profile_test extends phpbb_functional_test_case +{ + public function test_submitting_profile_info() + { + $this->add_lang('ucp'); + $this->login(); + + $crawler = self::request('GET', 'ucp.php?i=ucp_profile&mode=profile_info'); + $this->assertContainsLang('UCP_PROFILE_PROFILE_INFO', $crawler->filter('#cp-main h2')->text()); + + $form = $crawler->selectButton('Submit')->form(array( + 'pf_phpbb_location' => 'Bertie´s Empire', + )); + $crawler = self::submit($form); + $this->assertContainsLang('PROFILE_UPDATED', $crawler->filter('#message')->text()); + + $crawler = self::request('GET', 'ucp.php?i=ucp_profile&mode=profile_info'); + $form = $crawler->selectButton('Submit')->form(); + $this->assertEquals('Bertie´s Empire', $form->get('pf_phpbb_location')->getValue()); + } +} diff --git a/tests/functional/user_password_reset_test.php b/tests/functional/user_password_reset_test.php new file mode 100644 index 0000000000..65222c1aa6 --- /dev/null +++ b/tests/functional/user_password_reset_test.php @@ -0,0 +1,122 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_user_password_reset_test extends phpbb_functional_test_case +{ + protected $user_data; + + public function test_password_reset() + { + $this->add_lang('ucp'); + $user_id = $this->create_user('reset-password-test-user'); + + $crawler = self::request('GET', "ucp.php?mode=sendpassword&sid={$this->sid}"); + $form = $crawler->selectButton('submit')->form(array( + 'username' => 'reset-password-test-user', + )); + $crawler = self::submit($form); + $this->assertContainsLang('NO_EMAIL_USER', $crawler->text()); + + $crawler = self::request('GET', "ucp.php?mode=sendpassword&sid={$this->sid}"); + $form = $crawler->selectButton('submit')->form(array( + 'username' => 'reset-password-test-user', + 'email' => 'nobody@example.com', + )); + $crawler = self::submit($form); + $this->assertContainsLang('PASSWORD_UPDATED', $crawler->text()); + + // Check if columns in database were updated for password reset + $this->get_user_data(); + $this->assertNotNull($this->user_data['user_actkey']); + $this->assertNotNull($this->user_data['user_newpasswd']); + + // Make sure we know the password + $db = $this->get_db(); + $this->passwords_manager = $this->get_passwords_manager(); + $sql = 'UPDATE ' . USERS_TABLE . " + SET user_newpasswd = '" . $db->sql_escape($this->passwords_manager->hash('reset-password-test-user')) . "' + WHERE user_id = " . $user_id; + $db->sql_query($sql); + } + + public function test_login_after_reset() + { + $this->login('reset-password-test-user'); + } + + public function data_activate_new_password() + { + return array( + array('WRONG_ACTIVATION', false, 'FOOBAR'), + array('ALREADY_ACTIVATED', 2, 'FOOBAR'), + array('PASSWORD_ACTIVATED', false, false), + array('ALREADY_ACTIVATED', false, false), + ); + } + + /** + * @dataProvider data_activate_new_password + */ + public function test_activate_new_password($expected, $user_id, $act_key) + { + $this->add_lang('ucp'); + $this->get_user_data(); + $user_id = (!$user_id) ? $this->user_data['user_id'] : $user_id; + $act_key = (!$act_key) ? $this->user_data['user_actkey'] : $act_key; + + $crawler = self::request('GET', "ucp.php?mode=activate&u=$user_id&k=$act_key&sid={$this->sid}"); + $this->assertContainsLang($expected, $crawler->text()); + } + + public function test_login() + { + $this->add_lang('ucp'); + $crawler = self::request('GET', 'ucp.php'); + $this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), $crawler->filter('html')->text()); + + $form = $crawler->selectButton($this->lang('LOGIN'))->form(); + $crawler = self::submit($form, array('username' => 'reset-password-test-user', 'password' => 'reset-password-test-user')); + $this->assertNotContains($this->lang('LOGIN'), $crawler->filter('.navbar')->text()); + + $cookies = self::$cookieJar->all(); + + // The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie + foreach ($cookies as $cookie); + { + if (substr($cookie->getName(), -4) == '_sid') + { + $this->sid = $cookie->getValue(); + } + } + + $this->logout(); + + $crawler = self::request('GET', 'ucp.php'); + $this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), $crawler->filter('html')->text()); + + $form = $crawler->selectButton($this->lang('LOGIN'))->form(); + // Try logging in with the old password + $crawler = self::submit($form, array('username' => 'reset-password-test-user', 'password' => 'reset-password-test-userreset-password-test-user')); + $this->assertContains($this->lang('LOGIN_ERROR_PASSWORD', '', ''), $crawler->filter('html')->text()); + } + + protected function get_user_data() + { + $db = $this->get_db(); + $sql = 'SELECT user_id, username, user_type, user_email, user_newpasswd, user_lang, user_notify_type, user_actkey, user_inactive_reason + FROM ' . USERS_TABLE . " + WHERE username = 'reset-password-test-user'"; + $result = $db->sql_query($sql); + $this->user_data = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + } +} diff --git a/tests/functional/visibility_disapprove_test.php b/tests/functional/visibility_disapprove_test.php new file mode 100644 index 0000000000..ca6f6f5f37 --- /dev/null +++ b/tests/functional/visibility_disapprove_test.php @@ -0,0 +1,319 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_visibility_disapprove_test extends phpbb_functional_test_case +{ + protected $data = array(); + + public function test_setup_forums() + { + $this->login(); + $this->admin_login(); + + $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}"); + $form = $crawler->selectButton('addforum')->form(array( + 'forum_name' => 'Disapprove Test #1', + )); + $crawler = self::submit($form); + $form = $crawler->selectButton('update')->form(array( + 'forum_perm_from' => 2, + )); + $crawler = self::submit($form); + + // Set flood interval to 0 + $this->set_flood_interval(0); + } + + public function test_create_posts() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Disapprove Test #1', + ), + )); + + $this->assert_forum_details($this->data['forums']['Disapprove Test #1'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => 0, + ), 'initial comparison'); + + // Test creating topic #1 + $post = $this->create_topic($this->data['forums']['Disapprove Test #1'], 'Disapprove Test Topic #1', 'This is a test topic posted by the testing framework.'); + $crawler = self::request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}"); + + $this->assertContains('Disapprove Test Topic #1', $crawler->filter('html')->text()); + $this->data['topics']['Disapprove Test Topic #1'] = (int) $post['topic_id']; + $this->data['posts']['Disapprove Test Topic #1'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); + + $this->assert_forum_details($this->data['forums']['Disapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Disapprove Test Topic #1'], + ), 'after creating topic #1'); + + $this->logout(); + $this->create_user('disapprove_testuser'); + $this->add_user_group('NEWLY_REGISTERED', array('disapprove_testuser')); + $this->login('disapprove_testuser'); + + // Test creating a reply + $post2 = $this->create_post($this->data['forums']['Disapprove Test #1'], $post['topic_id'], 'Re: Disapprove Test Topic #1-#2', 'This is a test post posted by the testing framework.', array(), 'POST_STORED_MOD'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Disapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertNotContains('Re: Disapprove Test Topic #1-#2', $crawler->filter('html')->text()); + + $this->assert_forum_details($this->data['forums']['Disapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Disapprove Test Topic #1'], + ), 'after replying'); + + // Test creating topic #2 + $post = $this->create_topic($this->data['forums']['Disapprove Test #1'], 'Disapprove Test Topic #2', 'This is a test topic posted by the testing framework.', array(), 'POST_STORED_MOD'); + $crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Disapprove Test #1']}&sid={$this->sid}"); + + $this->assertNotContains('Disapprove Test Topic #2', $crawler->filter('html')->text()); + + $this->assert_forum_details($this->data['forums']['Disapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 2, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Disapprove Test Topic #1'], + ), 'after creating topic #2'); + + $this->logout(); + } + + public function test_reset_flood_interval() + { + $this->login(); + $this->admin_login(); + + // Set flood interval back to 15 + $this->set_flood_interval(15); + } + + public function test_disapprove_post() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Disapprove Test #1', + ), + 'topics' => array( + 'Disapprove Test Topic #1', + 'Disapprove Test Topic #2', + ), + 'posts' => array( + 'Disapprove Test Topic #1', + 'Re: Disapprove Test Topic #1-#2', + 'Disapprove Test Topic #2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Disapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 2, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Disapprove Test Topic #1'], + ), 'before disapproving post'); + + $this->add_lang('posting'); + $this->add_lang('viewtopic'); + $this->add_lang('mcp'); + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Disapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertContains('Disapprove Test Topic #1', $crawler->filter('html')->text()); + $this->assertContains('Re: Disapprove Test Topic #1-#2', $crawler->filter('html')->text()); + + $form = $crawler->selectButton($this->lang('DISAPPROVE'))->form(); + $crawler = self::submit($form); + $form = $crawler->selectButton($this->lang('YES'))->form(); + $crawler = self::submit($form); + $this->assertContainsLang('POST_DISAPPROVED_SUCCESS', $crawler->text()); + + $this->assert_forum_details($this->data['forums']['Disapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Disapprove Test Topic #1'], + ), 'after disapproving post'); + + $link = $crawler->selectLink($this->lang('RETURN_PAGE', '', ''))->link(); + $link_url = $link->getUri(); + $this->assertContains('viewtopic.php?f=' . $this->data['forums']['Disapprove Test #1'] . '&t=' . $this->data['topics']['Disapprove Test Topic #1'], $link_url); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Disapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertContains('Disapprove Test Topic #1', $crawler->filter('html')->text()); + $this->assertNotContains('Re: Disapprove Test Topic #1-#2', $crawler->filter('html')->text()); + } + + public function test_disapprove_topic() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Disapprove Test #1', + ), + 'topics' => array( + 'Disapprove Test Topic #1', + 'Disapprove Test Topic #2', + ), + 'posts' => array( + 'Disapprove Test Topic #1', + 'Disapprove Test Topic #2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Disapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Disapprove Test Topic #1'], + ), 'before disapproving topic'); + + $this->add_lang('posting'); + $this->add_lang('viewtopic'); + $this->add_lang('mcp'); + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Disapprove Test Topic #2']}&sid={$this->sid}"); + $this->assertContains('Disapprove Test Topic #2', $crawler->filter('html')->text()); + + $form = $crawler->selectButton($this->lang('DISAPPROVE'))->form(); + $crawler = self::submit($form); + $form = $crawler->selectButton($this->lang('YES'))->form(); + $crawler = self::submit($form); + $this->assertContainsLang('TOPIC_DISAPPROVED_SUCCESS', $crawler->text()); + + $this->assert_forum_details($this->data['forums']['Disapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Disapprove Test Topic #1'], + ), 'after disapproving topic'); + + $link = $crawler->selectLink($this->lang('RETURN_PAGE', '', ''))->link(); + $link_url = $link->getUri(); + $this->assertContains('viewforum.php?f=' . $this->data['forums']['Disapprove Test #1'], $link_url); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Disapprove Test Topic #2']}&sid={$this->sid}", array(), false); + self::assert_response_html(404); + $this->assertNotContains('Disapprove Test Topic #2', $crawler->filter('html')->text()); + } + + protected function assert_forum_details($forum_id, $details, $additional_error_message = '') + { + $this->db = $this->get_db(); + + $sql = 'SELECT ' . implode(', ', array_keys($details)) . ' + FROM phpbb_forums + WHERE forum_id = ' . (int) $forum_id; + $result = $this->db->sql_query($sql); + $data = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->assertEquals($details, $data, "Forum {$forum_id} does not match expected {$additional_error_message}"); + } + + protected function set_flood_interval($flood_interval) + { + $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=post'); + + $form = $crawler->selectButton('Submit')->form(); + $values = $form->getValues(); + + $values["config[flood_interval]"] = $flood_interval; + $form->setValues($values); + $crawler = self::submit($form); + $this->assertGreaterThan(0, $crawler->filter('.successbox')->count()); + } + + protected function load_ids($data) + { + $this->db = $this->get_db(); + + if (!empty($data['forums'])) + { + $sql = 'SELECT * + FROM phpbb_forums + WHERE ' . $this->db->sql_in_set('forum_name', $data['forums']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['forum_name'], $data['forums'])) + { + $this->data['forums'][$row['forum_name']] = (int) $row['forum_id']; + } + } + $this->db->sql_freeresult($result); + } + + if (!empty($data['topics'])) + { + $sql = 'SELECT * + FROM phpbb_topics + WHERE ' . $this->db->sql_in_set('topic_title', $data['topics']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['topic_title'], $data['topics'])) + { + $this->data['topics'][$row['topic_title']] = (int) $row['topic_id']; + } + } + $this->db->sql_freeresult($result); + } + + if (!empty($data['posts'])) + { + $sql = 'SELECT * + FROM phpbb_posts + WHERE ' . $this->db->sql_in_set('post_subject', $data['posts']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['post_subject'], $data['posts'])) + { + $this->data['posts'][$row['post_subject']] = (int) $row['post_id']; + } + } + $this->db->sql_freeresult($result); + } + } +} diff --git a/tests/functional/visibility_reapprove_test.php b/tests/functional/visibility_reapprove_test.php new file mode 100644 index 0000000000..70134ef724 --- /dev/null +++ b/tests/functional/visibility_reapprove_test.php @@ -0,0 +1,416 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_visibility_reapprove_test extends phpbb_functional_test_case +{ + protected $data = array(); + + public function test_setup_forums() + { + $this->login(); + $this->admin_login(); + + $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}"); + $form = $crawler->selectButton('addforum')->form(array( + 'forum_name' => 'Reapprove Test #1', + )); + $crawler = self::submit($form); + $form = $crawler->selectButton('update')->form(array( + 'forum_perm_from' => 2, + )); + $crawler = self::submit($form); + + // Set flood interval to 0 + $this->set_flood_interval(0); + } + + public function test_create_posts() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Reapprove Test #1', + ), + )); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => 0, + ), 'initial comparison'); + + // Test creating topic #1 + $post = $this->create_topic($this->data['forums']['Reapprove Test #1'], 'Reapprove Test Topic #1', 'This is a test topic posted by the testing framework.'); + $crawler = self::request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}"); + + $this->assertContains('Reapprove Test Topic #1', $crawler->filter('h2')->text()); + $this->data['topics']['Reapprove Test Topic #1'] = (int) $post['topic_id']; + $this->data['posts']['Reapprove Test Topic #1'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #1'], + ), 'after creating topic #1'); + + $this->logout(); + $this->create_user('reapprove_testuser'); + $this->add_user_group('NEWLY_REGISTERED', array('reapprove_testuser')); + $this->login('reapprove_testuser'); + + // Test creating a reply + $post2 = $this->create_post($this->data['forums']['Reapprove Test #1'], $post['topic_id'], 'Re: Reapprove Test Topic #1-#2', 'This is a test post posted by the testing framework.', array(), 'POST_STORED_MOD'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertNotContains('Re: Reapprove Test Topic #1-#2', $crawler->filter('#page-body')->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #1'], + ), 'after replying'); + + // Test creating topic #2 + $post = $this->create_topic($this->data['forums']['Reapprove Test #1'], 'Reapprove Test Topic #2', 'This is a test topic posted by the testing framework.', array(), 'POST_STORED_MOD'); + $crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Reapprove Test #1']}&sid={$this->sid}"); + + $this->assertNotContains('Reapprove Test Topic #2', $crawler->filter('html')->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 2, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #1'], + ), 'after creating topic #2'); + + $this->logout(); + } + + public function test_approve_post() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Reapprove Test #1', + ), + 'topics' => array( + 'Reapprove Test Topic #1', + 'Reapprove Test Topic #2', + ), + 'posts' => array( + 'Reapprove Test Topic #1', + 'Re: Reapprove Test Topic #1-#2', + 'Reapprove Test Topic #2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 2, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #1'], + ), 'before approving post'); + + $this->add_lang('posting'); + $this->add_lang('viewtopic'); + $this->add_lang('mcp'); + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertContains('Reapprove Test Topic #1', $crawler->filter('h2')->text()); + $this->assertContains('Re: Reapprove Test Topic #1-#2', $crawler->filter('#page-body')->text()); + + $form = $crawler->selectButton($this->lang('APPROVE'))->form(); + $crawler = self::submit($form); + $form = $crawler->selectButton($this->lang('YES'))->form(); + $crawler = self::submit($form); + $this->assertContainsLang('POST_APPROVED_SUCCESS', $crawler->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 2, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Re: Reapprove Test Topic #1-#2'], + ), 'after approving post'); + + $link = $crawler->selectLink($this->lang('RETURN_PAGE', '', ''))->link(); + $link_url = $link->getUri(); + $this->assertContains('viewtopic.php?f=' . $this->data['forums']['Reapprove Test #1'] . '&t=' . $this->data['topics']['Reapprove Test Topic #1'], $link_url); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertContains('Reapprove Test Topic #1', $crawler->filter('h2')->text()); + $this->assertContains('Re: Reapprove Test Topic #1-#2', $crawler->filter('#page-body')->text()); + } + + public function test_approve_topic() + { + $this->login(); + $this->load_ids(array( + 'forums' => array( + 'Reapprove Test #1', + ), + 'topics' => array( + 'Reapprove Test Topic #1', + 'Reapprove Test Topic #2', + ), + 'posts' => array( + 'Reapprove Test Topic #1', + 'Re: Reapprove Test Topic #1-#2', + 'Reapprove Test Topic #2', + ), + )); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 2, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Re: Reapprove Test Topic #1-#2'], + ), 'before approving topic'); + + $this->add_lang('posting'); + $this->add_lang('viewtopic'); + $this->add_lang('mcp'); + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #2']}&sid={$this->sid}"); + $this->assertContains('Reapprove Test Topic #2', $crawler->filter('h2')->text()); + + $form = $crawler->selectButton($this->lang('APPROVE'))->form(); + $crawler = self::submit($form); + $form = $crawler->selectButton($this->lang('YES'))->form(); + $crawler = self::submit($form); + //@todo $this->assertContainsLang('TOPIC_APPROVED_SUCCESS', $crawler->text()); + $this->assertContainsLang('POST_APPROVED_SUCCESS', $crawler->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 3, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 2, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #2'], + ), 'after approving topic'); + + $link = $crawler->selectLink($this->lang('RETURN_PAGE', '', ''))->link(); + $link_url = $link->getUri(); + $this->assertContains('viewtopic.php?f=' . $this->data['topic']['Reapprove Test Topic #2'], $link_url); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #2']}&sid={$this->sid}"); + $this->assertContains('Reapprove Test Topic #2', $crawler->filter('h2')->text()); + } + + public function test_edit_posts() + { + $this->load_ids(array( + 'forums' => array( + 'Reapprove Test #1', + ), + 'topics' => array( + 'Reapprove Test Topic #1', + 'Reapprove Test Topic #2', + ), + 'posts' => array( + 'Reapprove Test Topic #1', + 'Re: Reapprove Test Topic #1-#2', + 'Reapprove Test Topic #2', + ), + )); + $this->add_lang('posting'); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 3, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 2, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #2'], + ), 'before editing post'); + + $this->login('reapprove_testuser'); + $this->add_user_group('NEWLY_REGISTERED', array('reapprove_testuser')); + + // Test editing a post + $posting_url = "posting.php?mode=edit&f={$this->data['forums']['Reapprove Test #1']}&p={$this->data['posts']['Re: Reapprove Test Topic #1-#2']}&sid={$this->sid}"; + $form_data = array( + 'message' => 'Post edited by testing framework', + 'subject' => 'Re: Reapprove Test Topic #1-#2', + 'post' => true, + ); + $this->submit_post($posting_url, 'EDIT_POST', $form_data, 'POST_EDITED_MOD'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertNotContains('Re: Reapprove Test Topic #1-#2', $crawler->filter('#page-body')->text()); + $this->assertNotContains('Post edited by testing framework', $crawler->filter('#page-body')->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 2, + 'forum_posts_unapproved' => 1, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 2, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #2'], + ), 'after editing post'); + + // Test editing a topic + $posting_url = "posting.php?mode=edit&f={$this->data['forums']['Reapprove Test #1']}&p={$this->data['posts']['Reapprove Test Topic #2']}&sid={$this->sid}"; + $form_data = array( + 'message' => 'Post edited by testing framework', + 'subject' => 'Reapprove Test Topic #2', + 'post' => true, + ); + $this->submit_post($posting_url, 'EDIT_POST', $form_data, 'POST_EDITED_MOD'); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #2']}&sid={$this->sid}", array(), false); + self::assert_response_html(404); + $this->assertNotContains('Reapprove Test Topic #2', $crawler->filter('#page-body')->text()); + $this->assertNotContains('Post edited by testing framework', $crawler->filter('#page-body')->text()); + + $this->assert_forum_details($this->data['forums']['Reapprove Test #1'], array( + 'forum_posts_approved' => 1, + 'forum_posts_unapproved' => 2, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 1, + 'forum_topics_unapproved' => 1, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => $this->data['posts']['Reapprove Test Topic #1'], + ), 'after editing topic'); + + $this->logout(); + $this->login(); + + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Reapprove Test Topic #1']}&sid={$this->sid}"); + $this->assertContains('Re: Reapprove Test Topic #1-#2', $crawler->filter('#page-body')->text()); + $this->assertContains('Post edited by testing framework', $crawler->filter('#page-body')->text()); + } + + public function test_approve_post_again() + { + $this->test_approve_post(); + } + + public function test_approve_topic_again() + { + $this->test_approve_topic(); + } + + public function test_reset_flood_interval() + { + $this->login(); + $this->admin_login(); + + // Set flood interval back to 15 + $this->set_flood_interval(15); + } + + protected function assert_forum_details($forum_id, $details, $additional_error_message = '') + { + $this->db = $this->get_db(); + + $sql = 'SELECT ' . implode(', ', array_keys($details)) . ' + FROM phpbb_forums + WHERE forum_id = ' . (int) $forum_id; + $result = $this->db->sql_query($sql); + $data = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->assertEquals($details, $data, "Forum {$forum_id} does not match expected {$additional_error_message}"); + } + + protected function set_flood_interval($flood_interval) + { + $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=post'); + + $form = $crawler->selectButton('Submit')->form(); + $values = $form->getValues(); + + $values["config[flood_interval]"] = $flood_interval; + $form->setValues($values); + $crawler = self::submit($form); + $this->assertGreaterThan(0, $crawler->filter('.successbox')->count()); + } + + protected function load_ids($data) + { + $this->db = $this->get_db(); + + if (!empty($data['forums'])) + { + $sql = 'SELECT * + FROM phpbb_forums + WHERE ' . $this->db->sql_in_set('forum_name', $data['forums']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['forum_name'], $data['forums'])) + { + $this->data['forums'][$row['forum_name']] = (int) $row['forum_id']; + } + } + $this->db->sql_freeresult($result); + } + + if (!empty($data['topics'])) + { + $sql = 'SELECT * + FROM phpbb_topics + WHERE ' . $this->db->sql_in_set('topic_title', $data['topics']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['topic_title'], $data['topics'])) + { + $this->data['topics'][$row['topic_title']] = (int) $row['topic_id']; + } + } + $this->db->sql_freeresult($result); + } + + if (!empty($data['posts'])) + { + $sql = 'SELECT * + FROM phpbb_posts + WHERE ' . $this->db->sql_in_set('post_subject', $data['posts']); + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + if (in_array($row['post_subject'], $data['posts'])) + { + $this->data['posts'][$row['post_subject']] = (int) $row['post_id']; + } + } + $this->db->sql_freeresult($result); + } + } +} diff --git a/tests/functional/softdelete_test.php b/tests/functional/visibility_softdelete_test.php index bd4d34cf99..f8ada9687c 100644 --- a/tests/functional/softdelete_test.php +++ b/tests/functional/visibility_softdelete_test.php @@ -10,7 +10,7 @@ /** * @group functional */ -class phpbb_functional_softdelete_test extends phpbb_functional_test_case +class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_case { protected $data = array(); @@ -83,7 +83,7 @@ class phpbb_functional_softdelete_test extends phpbb_functional_test_case $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); $this->assertContains('Re: Soft Delete Topic #1-#2', $crawler->filter('html')->text()); - $this->data['posts']['Re: Soft Delete Topic #1-#2'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->eq(1)->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); + $this->data['posts']['Re: Soft Delete Topic #1-#2'] = (int) $post2['post_id']; $this->assert_forum_details($this->data['forums']['Soft Delete #1'], array( 'forum_posts_approved' => 2, @@ -410,7 +410,7 @@ class phpbb_functional_softdelete_test extends phpbb_functional_test_case $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #1']}&sid={$this->sid}"); $this->add_lang('mcp'); - $form = $crawler->selectButton($this->lang('RESTORE'))->form(); + $form = $crawler->filter('#p' . $this->data['posts']['Soft Delete Topic #1'])->selectButton($this->lang('RESTORE'))->form(); $crawler = self::submit($form); $this->assertContainsLang('RESTORE_POST', $crawler->text()); diff --git a/tests/functions/fixtures/obtain_online.xml b/tests/functions/fixtures/obtain_online.xml index 05bbe6a05e..14621a3287 100644 --- a/tests/functions/fixtures/obtain_online.xml +++ b/tests/functions/fixtures/obtain_online.xml @@ -15,8 +15,6 @@ <column>user_allow_viewonline</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>anonymous</value> @@ -24,8 +22,6 @@ <value>1</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>2</value> @@ -34,8 +30,6 @@ <value>1</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> @@ -44,8 +38,6 @@ <value>1</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>4</value> @@ -54,8 +46,6 @@ <value>1</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>5</value> @@ -64,8 +54,6 @@ <value>1</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>6</value> @@ -74,8 +62,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>7</value> @@ -84,8 +70,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>8</value> @@ -94,8 +78,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>9</value> @@ -104,8 +86,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>10</value> @@ -114,8 +94,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> </dataset> diff --git a/tests/functions/fixtures/validate_email.xml b/tests/functions/fixtures/validate_email.xml index de7fce8a08..eb4fd90217 100644 --- a/tests/functions/fixtures/validate_email.xml +++ b/tests/functions/fixtures/validate_email.xml @@ -6,8 +6,6 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <column>user_email_hash</column> <row> <value>1</value> @@ -15,8 +13,6 @@ <value>admin</value> <value></value> <value></value> - <value></value> - <value></value> <value>143317126117</value> </row> </table> diff --git a/tests/functions/fixtures/validate_username.xml b/tests/functions/fixtures/validate_username.xml index fbe398469c..1b85a2f06d 100644 --- a/tests/functions/fixtures/validate_username.xml +++ b/tests/functions/fixtures/validate_username.xml @@ -14,16 +14,12 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>admin</value> <value>admin</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>2</value> @@ -31,8 +27,6 @@ <value>moderator</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> </dataset> diff --git a/tests/functions/generate_string_list.php b/tests/functions/generate_string_list.php new file mode 100644 index 0000000000..cfc150c1f4 --- /dev/null +++ b/tests/functions/generate_string_list.php @@ -0,0 +1,60 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_generate_string_list_test extends phpbb_test_case +{ + public $user; + + public function setUp() + { + parent::setUp(); + + $this->user = new \phpbb\user(); + $this->user->data = array('user_lang' => 'en'); + $this->user->add_lang('common'); + } + + public function generate_string_list_data() + { + return array( + array( + array(), + '', + ), + array( + array('A'), + 'A', + ), + array( + array(2 => 'A', 3 => 'B'), + 'A and B', + ), + array( + array('A' => 'A', 'B' => 'B', 'C' => 'C'), + 'A, B, and C', + ), + array( + array('A', 'B', 'C', 'D'), + 'A, B, C, and D', + ) + ); + } + + /** + * @dataProvider generate_string_list_data + */ + public function test_generate_string_list($items, $expected_result) + { + $result = phpbb_generate_string_list($items, $this->user); + $this->assertEquals($expected_result, $result); + } +} diff --git a/tests/functions/obtain_online_test.php b/tests/functions/obtain_online_test.php index 624e05f77f..cf42fd5b58 100644 --- a/tests/functions/obtain_online_test.php +++ b/tests/functions/obtain_online_test.php @@ -21,8 +21,9 @@ class phpbb_functions_obtain_online_test extends phpbb_database_test_case { parent::setUp(); - global $config, $db; + global $config, $db, $user; + $user = new StdClass; $db = $this->db = $this->new_dbal(); $config = array( 'load_online_time' => 5, diff --git a/tests/functions/parse_cfg_file_test.php b/tests/functions/parse_cfg_file_test.php new file mode 100644 index 0000000000..920fc2eaa7 --- /dev/null +++ b/tests/functions/parse_cfg_file_test.php @@ -0,0 +1,103 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_functions_parse_cfg_file extends phpbb_test_case +{ + public function parse_cfg_file_data() + { + return array( + array( + array( + '#', + '# phpBB Style Configuration File', + '#', + '# @package phpBB3', + '# @copyright (c) 2005 phpBB Group', + '# @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2', + '#', + '#', + '# At the left is the name, please do not change this', + '# At the right the value is entered', + '# For on/off options the valid values are on, off, 1, 0, true and false', + '#', + '# Values get trimmed, if you want to add a space in front or at the end of', + '# the value, then enclose the value with single or double quotes.', + '# Single and double quotes do not need to be escaped.', + '#', + '', + '# General Information about this style', + 'name = prosilver', + 'copyright = © phpBB Group, 2007', + 'version = 3.0.12', + ), + array( + 'name' => 'prosilver', + 'copyright' => '© phpBB Group, 2007', + 'version' => '3.0.12', + ), + ), + array( + array( + 'name = subsilver2', + 'copyright = © 2005 phpBB Group', + 'version = 3.0.12', + ), + array( + 'name' => 'subsilver2', + 'copyright' => '© 2005 phpBB Group', + 'version' => '3.0.12', + ), + ), + array( + array( + 'foo = on', + 'foo1 = true', + 'foo2 = 1', + 'bar = off', + 'bar1 = false', + 'bar2 = 0', + 'foobar =', + 'foobar1 = "asdf"', + 'foobar2 = \'qwer\'', + ), + array( + 'foo' => true, + 'foo1' => true, + 'foo2' => true, + 'bar' => false, + 'bar1' => false, + 'bar2' => false, + 'foobar' => '', + 'foobar1' => 'asdf', + 'foobar2' => 'qwer', + ), + ), + array( + array( + 'foo = & bar', + 'bar = <a href="test">Test</a>', + ), + array( + 'foo' => '&amp; bar', + 'bar' => '<a href="test">Test</a>', + ), + ), + ); + } + + /** + * @dataProvider parse_cfg_file_data + */ + public function test_parse_cfg_file($file_contents, $expected) + { + $this->assertEquals($expected, parse_cfg_file(false, $file_contents)); + } +} diff --git a/tests/functions/validate_password_test.php b/tests/functions/validate_password_test.php index 4639f6cc89..82c5fa03c1 100644 --- a/tests/functions/validate_password_test.php +++ b/tests/functions/validate_password_test.php @@ -7,6 +7,7 @@ * */ +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php'; require_once dirname(__FILE__) . '/validate_data_helper.php'; diff --git a/tests/functions/validate_with_method_test.php b/tests/functions/validate_with_method_test.php new file mode 100644 index 0000000000..86d7b9571c --- /dev/null +++ b/tests/functions/validate_with_method_test.php @@ -0,0 +1,39 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php'; +require_once dirname(__FILE__) . '/validate_data_helper.php'; + +class phpbb_functions_validate_with_method_test extends phpbb_test_case +{ + protected $helper; + + protected function setUp() + { + parent::setUp(); + + $this->helper = new phpbb_functions_validate_data_helper($this); + } + + public function test_validate_date() + { + $this->helper->assert_valid_data(array( + 'method_call' => array( + array(), + true, + array(array(array($this, 'with_method'), false)), + ), + )); + } + + public function validate_with_method($bool, $optional = false) + { + return ! $bool; + } +} diff --git a/tests/functions_acp/build_cfg_template_test.php b/tests/functions_acp/build_cfg_template_test.php index acf4da1bd6..7f8db799c5 100644 --- a/tests/functions_acp/build_cfg_template_test.php +++ b/tests/functions_acp/build_cfg_template_test.php @@ -234,4 +234,54 @@ class phpbb_functions_acp_build_cfg_template_test extends phpbb_test_case $this->assertEquals($expected, build_cfg_template($tpl_type, $key, $new, $config_key, $vars)); } + + public function build_cfg_template_select_data() + { + return array( + array( + array('select'), + 'key_name', + array('config_key_name' => '0'), + 'config_key_name', + array('method' => 'select_helper'), + '<select id="key_name" name="config[config_key_name]"><option value="1">First_Option</option><option value="2" selected="selected">Second_Option</option><option value="3">Third_Option</option></select>', + ), + array( + array('select', 8), + 'key_name', + array('config_key_name' => '1'), + 'config_key_name', + array('method' => 'select_helper'), + '<select id="key_name" name="config[config_key_name]" size="8"><option value="1">First_Option</option><option value="2" selected="selected">Second_Option</option><option value="3">Third_Option</option></select>', + ), + ); + } + + /** + * @dataProvider build_cfg_template_select_data + */ + public function test_build_cfg_template_select($tpl_type, $key, $new, $config_key, $vars, $expected) + { + global $module, $user, $phpbb_dispatcher; + + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $user = new phpbb_mock_user(); + $user->lang = new phpbb_mock_lang(); + $user->module = $this; + $module = $user; + + $this->assertEquals($expected, build_cfg_template($tpl_type, $key, $new, $config_key, $vars)); + } + + public function select_helper() + { + return build_select( + array( + '1' => 'First_Option', + '2' => 'Second_Option', + '3' => 'Third_Option', + ), + '2' + ); + } } diff --git a/tests/functions_acp/build_select_test.php b/tests/functions_acp/build_select_test.php index aca49b7655..c44fd97ec3 100644 --- a/tests/functions_acp/build_select_test.php +++ b/tests/functions_acp/build_select_test.php @@ -11,6 +11,16 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; class phpbb_functions_acp_built_select_test extends phpbb_test_case { + protected function setUp() + { + parent::setUp(); + + global $user; + + $user = new phpbb_mock_user(); + $user->lang = new phpbb_mock_lang(); + } + public function build_select_data() { return array( @@ -46,10 +56,6 @@ class phpbb_functions_acp_built_select_test extends phpbb_test_case */ public function test_build_select($option_ary, $option_default, $expected) { - global $user; - - $user->lang = new phpbb_mock_lang(); - $this->assertEquals($expected, build_select($option_ary, $option_default)); } } diff --git a/tests/functions_acp/h_radio_test.php b/tests/functions_acp/h_radio_test.php index a61f2e8975..4c1872d341 100644 --- a/tests/functions_acp/h_radio_test.php +++ b/tests/functions_acp/h_radio_test.php @@ -11,6 +11,16 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; class phpbb_functions_acp_h_radio_test extends phpbb_test_case { + protected function setUp() + { + parent::setUp(); + + global $user; + + $user = new phpbb_mock_user(); + $user->lang = new phpbb_mock_lang(); + } + public function h_radio_data() { return array( @@ -111,10 +121,6 @@ class phpbb_functions_acp_h_radio_test extends phpbb_test_case */ public function test_h_radio($name, $input_ary, $input_default, $id, $key, $expected) { - global $user; - - $user->lang = new phpbb_mock_lang(); - $this->assertEquals($expected, h_radio($name, $input_ary, $input_default, $id, $key)); } } diff --git a/tests/functions_acp/validate_config_vars_test.php b/tests/functions_acp/validate_config_vars_test.php index 7cd7fa3892..acc98fbf0d 100644 --- a/tests/functions_acp/validate_config_vars_test.php +++ b/tests/functions_acp/validate_config_vars_test.php @@ -8,9 +8,20 @@ */ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case { + protected function setUp() + { + parent::setUp(); + + global $user; + + $user = new phpbb_mock_user(); + $user->lang = new phpbb_mock_lang(); + } + /** * Data sets that don't throw an error. */ @@ -60,10 +71,6 @@ class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case */ public function test_validate_config_vars_fit($test_data, $cfg_array) { - global $user; - - $user->lang = new phpbb_mock_lang(); - $phpbb_error = array(); validate_config_vars($test_data, $cfg_array, $phpbb_error); @@ -146,10 +153,6 @@ class phpbb_functions_acp_validate_config_vars_test extends phpbb_test_case */ public function test_validate_config_vars_error($test_data, $cfg_array, $expected) { - global $user; - - $user->lang = new phpbb_mock_lang(); - $phpbb_error = array(); validate_config_vars($test_data, $cfg_array, $phpbb_error); diff --git a/tests/functions_acp/validate_range_test.php b/tests/functions_acp/validate_range_test.php index 8606158251..cb028d4d07 100644 --- a/tests/functions_acp/validate_range_test.php +++ b/tests/functions_acp/validate_range_test.php @@ -12,6 +12,16 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php'; class phpbb_functions_acp_validate_range_test extends phpbb_test_case { + protected function setUp() + { + parent::setUp(); + + global $user; + + $user = new phpbb_mock_user(); + $user->lang = new phpbb_mock_lang(); + } + /** * Data sets that don't throw an error. */ @@ -52,10 +62,6 @@ class phpbb_functions_acp_validate_range_test extends phpbb_test_case */ public function test_validate_range_fit($test_data) { - global $user; - - $user->lang = new phpbb_mock_lang(); - $phpbb_error = array(); validate_range($test_data, $phpbb_error); @@ -91,10 +97,6 @@ class phpbb_functions_acp_validate_range_test extends phpbb_test_case */ public function test_validate_range_too_low($test_data) { - global $user; - - $user->lang = new phpbb_mock_lang(); - $phpbb_error = array(); validate_range($test_data, $phpbb_error); @@ -130,10 +132,6 @@ class phpbb_functions_acp_validate_range_test extends phpbb_test_case */ public function test_validate_range_too_big($test_data) { - global $user; - - $user->lang = new phpbb_mock_lang(); - $phpbb_error = array(); validate_range($test_data, $phpbb_error); @@ -158,10 +156,6 @@ class phpbb_functions_acp_validate_range_test extends phpbb_test_case */ public function test_validate_range_too_long($test_data) { - global $user; - - $user->lang = new phpbb_mock_lang(); - $phpbb_error = array(); validate_range($test_data, $phpbb_error); diff --git a/tests/functions_content/get_username_string_test.php b/tests/functions_content/get_username_string_test.php new file mode 100644 index 0000000000..1f23f19056 --- /dev/null +++ b/tests/functions_content/get_username_string_test.php @@ -0,0 +1,126 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; + +class phpbb_functions_content_get_username_string_test extends phpbb_test_case +{ + public function setUp() + { + parent::setUp(); + + global $auth, $phpbb_dispatcher, $user; + $auth = $this->getMock('\phpbb\auth\auth'); + $auth->expects($this->any()) + ->method('acl_get') + ->with($this->stringContains('_'), $this->anything()) + ->will($this->returnValueMap(array( + array('u_viewprofile', true), + ))); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher; + $user->data['user_id'] = ANONYMOUS; + $user->lang['GUEST'] = 'Guest'; + } + + public function get_username_string_profile_data() + { + global $phpbb_root_path, $phpEx; + + return array( + array(ANONYMOUS, 'Anonymous', '', false, false, ''), + array(2, 'Administrator', 'FF0000', false, false, "{$phpbb_root_path}memberlist.$phpEx?mode=viewprofile&u=2"), + array(42, 'User42', '', false, 'http://www.example.org/user.php?mode=show', 'http://www.example.org/user.php?mode=show&u=42'), + ); + } + + /** + * @dataProvider get_username_string_profile_data + */ + public function test_get_username_string_profile($user_id, $username, $user_colour, $guest_username, $custom_profile_url, $expected) + { + $this->assertEquals($expected, get_username_string('profile', $user_id, $username, $user_colour, $guest_username, $custom_profile_url)); + } + + public function get_username_string_username_data() + { + return array( + array(ANONYMOUS, '', '', false, false, 'Guest'), + array(ANONYMOUS, '', '', 'CustomName', false, 'CustomName'), + array(2, 'User2', '', false, false, 'User2'), + array(5, 'User5', '', 'Anonymous', false, 'User5'), + array(128, 'User128', '', false, false, 'User128'), + ); + } + + /** + * @dataProvider get_username_string_username_data + */ + public function test_get_username_string_username($user_id, $username, $user_colour, $guest_username, $custom_profile_url, $expected) + { + $this->assertEquals($expected, get_username_string('username', $user_id, $username, $user_colour, $guest_username, $custom_profile_url)); + } + + public function get_username_string_colour_data() + { + return array( + array(0, '', '', false, false, ''), + array(0, '', 'F0F0F0', false, false, '#F0F0F0'), + array(ANONYMOUS, 'Anonymous', '000000', false, false, '#000000'), + array(2, 'Administrator', '', false, false, ''), + ); + } + + /** + * @dataProvider get_username_string_colour_data + */ + public function test_get_username_string_colour($user_id, $username, $user_colour, $guest_username, $custom_profile_url, $expected) + { + $this->assertEquals($expected, get_username_string('colour', $user_id, $username, $user_colour, $guest_username, $custom_profile_url)); + } + + public function get_username_string_full_data() + { + global $phpbb_root_path, $phpEx; + + return array( + array(0, '', '', false, false, 'Guest'), + array(ANONYMOUS, 'Anonymous', '', false, false, 'Anonymous'), + array(2, 'Administrator', 'FF0000', false, false, '<a href="' . $phpbb_root_path . 'memberlist.' . $phpEx . '?mode=viewprofile&u=2" style="color: #FF0000;" class="username-coloured">Administrator</a>'), + array(5, 'User5', '', false, 'http://www.example.org/user.php?mode=show', '<a href="http://www.example.org/user.php?mode=show&u=5">User5</a>'), + array(8, 'Eight', '', false, false, '<a href="' . $phpbb_root_path . 'memberlist.php?mode=viewprofile&u=8">Eight</a>'), + ); + } + + /** + * @dataProvider get_username_string_full_data + */ + public function test_get_username_string_full($user_id, $username, $user_colour, $guest_username, $custom_profile_url, $expected) + { + $this->assertEquals($expected, get_username_string('full', $user_id, $username, $user_colour, $guest_username, $custom_profile_url)); + } + + public function get_username_string_no_profile_data() + { + return array( + array(ANONYMOUS, 'Anonymous', '', false, false, 'Anonymous'), + array(ANONYMOUS, 'Anonymous', '', '', false, 'Guest'), + array(2, 'Administrator', 'FF0000', false, false, '<span style="color: #FF0000;" class="username-coloured">Administrator</span>'), + array(8, 'Eight', '', false, false, 'Eight'), + ); + } + + /** + * @dataProvider get_username_string_no_profile_data + */ + public function test_get_username_string_no_profile($user_id, $username, $user_colour, $guest_username, $custom_profile_url, $expected) + { + $this->assertEquals($expected, get_username_string('no_profile', $user_id, $username, $user_colour, $guest_username, $custom_profile_url)); + } +} diff --git a/tests/functions_content/phpbb_clean_search_string_test.php b/tests/functions_content/phpbb_clean_search_string_test.php new file mode 100644 index 0000000000..de642c9040 --- /dev/null +++ b/tests/functions_content/phpbb_clean_search_string_test.php @@ -0,0 +1,38 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; + +class phpbb_functions_content_phpbb_clean_search_string_test extends phpbb_test_case +{ + public function phpbb_clean_search_string_data() + { + return array( + array('*', ''), + array('* *', ''), + array('test', 'test'), + array(' test ', 'test'), + array(' test * ', 'test'), + array('test* *', 'test*'), + array('* *test*', '*test*'), + array('test test * test', 'test test test'), + array(' some wild*cards * between wo*rds ', 'some wild*cards between wo*rds'), + array(' we * now have*** multiple wild***cards * ', 'we now have* multiple wild*cards'), + array('pi is *** . * **** * *****', 'pi is .'), + ); + } + + /** + * @dataProvider phpbb_clean_search_string_data + */ + public function test_phpbb_clean_search_string($search_string, $expected) + { + $this->assertEquals($expected, phpbb_clean_search_string($search_string)); + } +} diff --git a/tests/functions_install/ignore_new_file_on_update_test.php b/tests/functions_install/ignore_new_file_on_update_test.php new file mode 100644 index 0000000000..703da4e435 --- /dev/null +++ b/tests/functions_install/ignore_new_file_on_update_test.php @@ -0,0 +1,41 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_install.php'; + +class phpbb_functions_install_ignore_new_file_on_update_test extends phpbb_test_case +{ + static public function ignore_new_file_on_update_data() + { + return array( + array('willneverexist.php', false), + array('includes/dirwillneverexist/newfile.php', false), + + array('language/en/email/short/bookmark.txt', false), + array('language/languagewillneverexist/email/short/bookmark.txt', true), + + array('styles/prosilver/template/bbcode.html', false), + array('styles/stylewillneverexist/template/bbcode.html', true), + + array('styles/prosilver/theme/en/icon_user_online.gif', false), + array('styles/prosilver/theme/languagewillneverexist/icon_user_online.gif', true), + + array('styles/prosilver/theme/imageset.css', false), + ); + } + + /** + * @dataProvider ignore_new_file_on_update_data + */ + public function test_ignore_new_file_on_update($file, $expected) + { + global $phpbb_root_path; + $this->assertEquals($expected, phpbb_ignore_new_file_on_update($phpbb_root_path, $file)); + } +} diff --git a/tests/functions_user/fixtures/group_user_attributes.xml b/tests/functions_user/fixtures/group_user_attributes.xml index f4edbdca49..9b1f1f504b 100644 --- a/tests/functions_user/fixtures/group_user_attributes.xml +++ b/tests/functions_user/fixtures/group_user_attributes.xml @@ -32,8 +32,6 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>1</value> @@ -42,8 +40,6 @@ <value>barfoo</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>2</value> @@ -53,8 +49,6 @@ <value>foobar</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> @@ -64,8 +58,6 @@ <value>bertie</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_user_group"> diff --git a/tests/functions_user/group_user_attributes_test.php b/tests/functions_user/group_user_attributes_test.php index f8d52a9a6a..86e4767970 100644 --- a/tests/functions_user/group_user_attributes_test.php +++ b/tests/functions_user/group_user_attributes_test.php @@ -27,7 +27,7 @@ class phpbb_functions_user_group_user_attributes_test extends phpbb_database_tes 2, array( 'group_avatar' => '', - 'group_avatar_type' => 0, + 'group_avatar_type' => '', 'group_avatar_height' => 0, 'group_avatar_width' => 0, 'group_rank' => 0, @@ -43,7 +43,7 @@ class phpbb_functions_user_group_user_attributes_test extends phpbb_database_tes 2, array( 'group_avatar' => '', - 'group_avatar_type' => 0, + 'group_avatar_type' => '', 'group_avatar_height' => 0, 'group_avatar_width' => 0, 'group_rank' => 0, @@ -59,7 +59,7 @@ class phpbb_functions_user_group_user_attributes_test extends phpbb_database_tes 2, array( 'group_avatar' => '', - 'group_avatar_type' => 0, + 'group_avatar_type' => '', 'group_avatar_height' => 0, 'group_avatar_width' => 0, 'group_rank' => 0, @@ -75,7 +75,7 @@ class phpbb_functions_user_group_user_attributes_test extends phpbb_database_tes 3, array( 'group_avatar' => 'default2', - 'group_avatar_type' => 1, + 'group_avatar_type' => 'avatar.driver.upload', 'group_avatar_height' => 1, 'group_avatar_width' => 1, 'group_rank' => 3, @@ -91,7 +91,7 @@ class phpbb_functions_user_group_user_attributes_test extends phpbb_database_tes 3, array( 'group_avatar' => 'default2', - 'group_avatar_type' => 1, + 'group_avatar_type' => 'avatar.driver.upload', 'group_avatar_height' => 1, 'group_avatar_width' => 1, 'group_rank' => 3, @@ -107,7 +107,7 @@ class phpbb_functions_user_group_user_attributes_test extends phpbb_database_tes 3, array( 'group_avatar' => 'default2', - 'group_avatar_type' => 1, + 'group_avatar_type' => 'avatar.driver.upload', 'group_avatar_height' => 1, 'group_avatar_width' => 1, 'group_rank' => 3, @@ -127,6 +127,7 @@ class phpbb_functions_user_group_user_attributes_test extends phpbb_database_tes { global $auth, $cache, $db, $phpbb_dispatcher, $user, $phpbb_container, $phpbb_log, $phpbb_root_path, $phpEx; + $user = new phpbb_mock_user; $user->ip = ''; $cache = new phpbb_mock_cache; $db = $this->new_dbal(); diff --git a/tests/lint_test.php b/tests/lint_test.php index 905067072d..b0149063bd 100644 --- a/tests/lint_test.php +++ b/tests/lint_test.php @@ -9,20 +9,37 @@ class phpbb_lint_test extends phpbb_test_case { + static protected $php_binary; static protected $exclude; static public function setUpBeforeClass() { + // Try to use PHP_BINARY constant if available so lint tests are run + // using the same php binary as phpunit. If not available (pre PHP + // 5.4), assume binary is called 'php' and is in PATH. + self::$php_binary = defined('PHP_BINARY') ? escapeshellcmd(PHP_BINARY) : 'php'; + $output = array(); $status = 1; - exec('(php -v) 2>&1', $output, $status); + exec(sprintf('(%s --version) 2>&1', self::$php_binary), $output, $status); if ($status) { $output = implode("\n", $output); - self::markTestSkipped("php is not in PATH or broken: $output"); + if (self::$php_binary === 'php') + { + self::markTestSkipped(sprintf('php is not in PATH or broken. Output: %s', $output)); + } + else + { + self::markTestSkipped(sprintf('Could not run PHP_BINARY %s. Output: %s', self::$php_binary, $output)); + } } self::$exclude = array( + dirname(__FILE__) . '/../.git', + dirname(__FILE__) . '/../build/new_version', + dirname(__FILE__) . '/../build/old_versions', + dirname(__FILE__) . '/../phpBB/cache', // PHP Fatal error: Cannot declare class Container because the name is already in use in /var/www/projects/phpbb3/tests/../phpBB/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php on line 20 // https://gist.github.com/e003913ffd493da63cbc dirname(__FILE__) . '/../phpBB/vendor', @@ -45,7 +62,7 @@ class phpbb_lint_test extends phpbb_test_case $dh = opendir($root); while (($filename = readdir($dh)) !== false) { - if ($filename == '.' || $filename == '..' || $filename == 'git') + if ($filename == '.' || $filename == '..') { continue; } @@ -61,13 +78,12 @@ class phpbb_lint_test extends phpbb_test_case } else if (substr($filename, strlen($filename)-4) == '.php') { - // assume php binary is called php and it is in PATH - $cmd = '(php -l ' . escapeshellarg($path) . ') 2>&1'; + $cmd = sprintf('(%s -l %s) 2>&1', self::$php_binary, escapeshellarg($path)); $output = array(); $status = 1; exec($cmd, $output, $status); $output = implode("\n", $output); - $this->assertEquals(0, $status, "php -l failed for $path:\n$output"); + $this->assertEquals(0, $status, "PHP lint failed for $path:\n$output"); } } } diff --git a/tests/log/fixtures/full_log.xml b/tests/log/fixtures/full_log.xml index 2ce2643d26..ef35884444 100644 --- a/tests/log/fixtures/full_log.xml +++ b/tests/log/fixtures/full_log.xml @@ -119,6 +119,30 @@ <value>LOG_USER</value> <value>a:1:{i:0;s:5:"guest";}</value> </row> + <row> + <value>10</value> + <value>3</value> + <value>1</value> + <value>0</value> + <value>0</value> + <value>0</value> + <value>127.0.0.1</value> + <value>1</value> + <value>LOG_SINGULAR_PLURAL</value> + <value>a:1:{i:0;i:2;}</value> + </row> + <row> + <value>11</value> + <value>1</value> + <value>1</value> + <value>15</value> + <value>3</value> + <value>0</value> + <value>127.0.0.1</value> + <value>1</value> + <value>LOG_MOD3</value> + <value>a:1:{i:0;s:5:"guest";}</value> + </row> </table> <table name="phpbb_users"> <column>user_id</column> @@ -126,16 +150,12 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>Anonymous</value> <value>Anonymous</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>2</value> @@ -143,8 +163,6 @@ <value>admin</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_topics"> diff --git a/tests/log/function_view_log_test.php b/tests/log/function_view_log_test.php index 017484e8a7..542d0adf9d 100644 --- a/tests/log/function_view_log_test.php +++ b/tests/log/function_view_log_test.php @@ -44,7 +44,7 @@ class phpbb_log_function_view_log_test extends phpbb_database_test_case 'topic_id' => 0, 'viewforum' => '', - 'action' => 'installed: 3.1.0-dev', + 'action' => 'LOG_INSTALL_INSTALLED 3.1.0-dev', ), 2 => array( 'id' => 2, @@ -164,7 +164,7 @@ class phpbb_log_function_view_log_test extends phpbb_database_test_case 'topic_id' => 45, 'viewforum' => '', - 'action' => '{LOG MOD2}', + 'action' => 'LOG_MOD2', 'viewtopic' => '', 'viewlogs' => '', ), @@ -185,7 +185,7 @@ class phpbb_log_function_view_log_test extends phpbb_database_test_case 'topic_id' => 0, 'viewforum' => '', - 'action' => '{LOG USER}<br />admin', + 'action' => 'LOG_USER admin', ), 9 => array( 'id' => 9, @@ -204,7 +204,47 @@ class phpbb_log_function_view_log_test extends phpbb_database_test_case 'topic_id' => 0, 'viewforum' => '', - 'action' => '{LOG USER}<br />guest', + 'action' => 'LOG_USER guest', + ), + 10 => array( + 'id' => 10, + + 'reportee_id' => 0, + 'reportee_username' => '', + 'reportee_username_full'=> '', + + 'user_id' => 1, + 'username' => 'Anonymous', + 'username_full' => 'Anonymous', + + 'ip' => '127.0.0.1', + 'time' => 1, + 'forum_id' => 0, + 'topic_id' => 0, + + 'viewforum' => '', + 'action' => 'LOG_SINGULAR_PLURAL 2', + ), + 11 => array( + 'id' => 11, + + 'reportee_id' => 0, + 'reportee_username' => '', + 'reportee_username_full'=> '', + + 'user_id' => 1, + 'username' => 'Anonymous', + 'username_full' => 'Anonymous', + + 'ip' => '127.0.0.1', + 'time' => 1, + 'forum_id' => 15, + 'topic_id' => 3, + + 'viewforum' => '', + 'action' => 'LOG_MOD3 guest ', + 'viewtopic' => '', + 'viewlogs' => '', ), ); @@ -277,10 +317,25 @@ class phpbb_log_function_view_log_test extends phpbb_database_test_case 'user', 0, 5, 0, 0, 0, 2, ), array( - 'expected' => array(8, 9), + 'expected' => array(8, 9, 10), 'expected_returned' => 0, 'users', 0, ), + array( + 'expected' => array(1), + 'expected_returned' => 0, + 'admin', false, 5, 0, 0, 0, 0, 0, 'l.log_id ASC', 'install', + ), + array( + 'expected' => array(10), + 'expected_returned' => 0, + 'user', false, 5, 0, 0, 0, 0, 0, 'l.log_id ASC', 'plural', + ), + array( + 'expected' => array(11), + 'expected_returned' => 0, + 'mod', 0, 5, 0, 15, 3, + ), ); foreach ($test_cases as $case => $case_data) @@ -331,6 +386,13 @@ class phpbb_log_function_view_log_test extends phpbb_database_test_case // Test sprintf() of the data into the action $user->lang = array( 'LOG_INSTALL_INSTALLED' => 'installed: %s', + 'LOG_USER' => 'User<br /> %s', + 'LOG_MOD2' => 'Mod2', + 'LOG_MOD3' => 'Mod3: %1$s, %2$s', + 'LOG_SINGULAR_PLURAL' => array( + 1 => 'singular', + 2 => 'plural (%d)', + ), ); $phpbb_log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); diff --git a/tests/migrator/get_schema_steps_test.php b/tests/migrator/get_schema_steps_test.php new file mode 100644 index 0000000000..226535754e --- /dev/null +++ b/tests/migrator/get_schema_steps_test.php @@ -0,0 +1,200 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class get_schema_steps_test extends phpbb_test_case +{ + public function setUp() + { + parent::setUp(); + + $this->helper = new \phpbb\db\migration\helper(); + } + + public function schema_provider() + { + return array( + array( + array( + 'add_tables' => array( + 'foo' => array( + 'COLUMNS' => array( + 'foobar' => array('BOOL', 0), + 'foobar2' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => array('foobar'), + ), + 'bar' => array( + 'COLUMNS' => array( + 'barfoo' => array('BOOL', 0), + 'barfoor2' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => array('barfoo'), + ), + ), + 'drop_tables' => array('table1', 'table2', 'table3'), + 'add_index' => array( + 'table1' => array( + 'index1' => 'column1', + 'index2' => 'column2', + ), + 'table2' => array( + 'index1' => 'column1', + 'index2' => 'column2', + ), + ), + 'add_columns' => array( + 'table1' => array( + 'column1' => array('foo'), + 'column2' => array('bar'), + ), + ), + 'change_columns' => array( + 'table1' => array( + 'column1' => array('foo'), + 'column2' => array('bar'), + ), + ), + 'drop_columns' => array( + 'table1' => array( + 'column1', + 'column2', + ), + ), + 'add_unique_index' => array( + 'table1' => array( + 'index1' => 'column1', + 'index2' => 'column2', + ), + ), + 'drop_keys' => array( + 'table1' => array( + 'column1', + 'column2', + ), + ), + 'add_primary_keys' => array( + 'table1' => array('foo'), + 'table2' => array('bar'), + 'table3' => array('foobar'), + ), + ), + array( + array('dbtools.perform_schema_changes', array(array('drop_tables' => array('table1')))), + array('dbtools.perform_schema_changes', array(array('drop_tables' => array('table2')))), + array('dbtools.perform_schema_changes', array(array('drop_tables' => array('table3')))), + array('dbtools.perform_schema_changes', array(array('add_tables' => array( + 'foo' => array( + 'COLUMNS' => array( + 'foobar' => array('BOOL', 0), + 'foobar2' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => array('foobar'), + ), + )))), + array('dbtools.perform_schema_changes', array(array('add_tables' => array( + 'bar' => array( + 'COLUMNS' => array( + 'barfoo' => array('BOOL', 0), + 'barfoor2' => array('BOOL', 0), + ), + 'PRIMARY_KEY' => array('barfoo'), + ), + )))), + array('dbtools.perform_schema_changes', array(array('change_columns' => array( + 'table1' => array( + 'column1' => array('foo'), + ), + )))), + array('dbtools.perform_schema_changes', array(array('change_columns' => array( + 'table1' => array( + 'column2' => array('bar'), + ), + )))), + array('dbtools.perform_schema_changes', array(array('add_columns' => array( + 'table1' => array( + 'column1' => array('foo'), + ), + )))), + array('dbtools.perform_schema_changes', array(array('add_columns' => array( + 'table1' => array( + 'column2' => array('bar'), + ), + )))), + array('dbtools.perform_schema_changes', array(array('drop_keys' => array( + 'table1' => array( + 0 => 'column1', + ), + )))), + array('dbtools.perform_schema_changes', array(array('drop_keys' => array( + 'table1' => array( + 1 => 'column2', + ), + )))), + array('dbtools.perform_schema_changes', array(array('drop_columns' => array( + 'table1' => array( + 0 => 'column1', + ), + )))), + array('dbtools.perform_schema_changes', array(array('drop_columns' => array( + 'table1' => array( + 1 => 'column2', + ), + )))), + array('dbtools.perform_schema_changes', array(array('add_primary_keys' => array( + 'table1' => array('foo'), + )))), + array('dbtools.perform_schema_changes', array(array('add_primary_keys' => array( + 'table2' => array('bar'), + )))), + array('dbtools.perform_schema_changes', array(array('add_primary_keys' => array( + 'table3' => array('foobar'), + )))), + array('dbtools.perform_schema_changes', array(array('add_unique_index' => array( + 'table1' => array( + 'index1' => 'column1', + ), + )))), + array('dbtools.perform_schema_changes', array(array('add_unique_index' => array( + 'table1' => array( + 'index2' => 'column2', + ), + )))), + array('dbtools.perform_schema_changes', array(array('add_index' => array( + 'table1' => array( + 'index1' => 'column1', + ), + )))), + array('dbtools.perform_schema_changes', array(array('add_index' => array( + 'table1' => array( + 'index2' => 'column2', + ), + )))), + array('dbtools.perform_schema_changes', array(array('add_index' => array( + 'table2' => array( + 'index1' => 'column1', + ), + )))), + array('dbtools.perform_schema_changes', array(array('add_index' => array( + 'table2' => array( + 'index2' => 'column2', + ), + )))), + ), + ), + ); + } + + /** + * @dataProvider schema_provider + */ + public function test_get_schema_steps($schema_changes, $expected) + { + $this->assertEquals($expected, $this->helper->get_schema_steps($schema_changes)); + } +} diff --git a/tests/migrator/schema_generator_test.php b/tests/migrator/schema_generator_test.php new file mode 100644 index 0000000000..4bac447229 --- /dev/null +++ b/tests/migrator/schema_generator_test.php @@ -0,0 +1,49 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class schmema_generator_test extends phpbb_test_case +{ + public function setUp() + { + parent::setUp(); + + $this->config = new \phpbb\config\config(array()); + $this->db = new \phpbb\db\driver\sqlite(); + $this->db_tools = new \phpbb\db\tools($this->db); + $this->table_prefix = 'phpbb_'; + } + + protected function get_schema_generator(array $class_names) + { + $this->generator = new \phpbb\db\migration\schema_generator($class_names, $this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix); + + return $this->generator; + } + + /** + * @expectedException \UnexpectedValueException + */ + public function test_check_dependencies_fail() + { + $this->get_schema_generator(array('\phpbb\db\migration\data\v310\forgot_password')); + + $this->generator->get_schema(); + } + + public function test_get_schema_success() + { + $this->get_schema_generator(array( + '\phpbb\db\migration\data\v30x\release_3_0_1_rc1', + '\phpbb\db\migration\data\v30x\release_3_0_0', + '\phpbb\db\migration\data\v310\boardindex' + )); + + $this->assertArrayHasKey('phpbb_users', $this->generator->get_schema()); + } +} diff --git a/tests/mimetype/fixtures/jpg b/tests/mimetype/fixtures/jpg Binary files differnew file mode 100644 index 0000000000..3cd5038e38 --- /dev/null +++ b/tests/mimetype/fixtures/jpg diff --git a/tests/mimetype/guesser_test.php b/tests/mimetype/guesser_test.php new file mode 100644 index 0000000000..9f0371262b --- /dev/null +++ b/tests/mimetype/guesser_test.php @@ -0,0 +1,166 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\mimetype; + +require_once dirname(__FILE__) . '/null_guesser.php'; +require_once dirname(__FILE__) . '/incorrect_guesser.php'; + +function function_exists($name) +{ + return guesser_test::$function_exists; +} + +class guesser_test extends \phpbb_test_case +{ + public static $function_exists = true; + + public function setUp() + { + global $phpbb_root_path; + + $guessers = array( + new \Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser(), + new \Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser(), + ); + $this->guesser = new \phpbb\mimetype\guesser($guessers); + $this->path = dirname(__FILE__); + $this->jpg_file = $this->path . '/fixtures/jpg'; + $this->phpbb_root_path = $phpbb_root_path; + } + + public function data_guess_files() + { + return array( + array('image/gif', 'gif'), + array('image/png', 'png'), + array('image/jpeg', 'jpg'), + array('image/tiff', 'tif'), + array('text/html', 'txt'), + array(false, 'foobar'), + ); + } + + /** + * @dataProvider data_guess_files + */ + public function test_guess_files($expected, $file) + { + $this->assertEquals($expected, $this->guesser->guess($this->path . '/../upload/fixture/' . $file)); + } + + public function test_file_not_readable() + { + @chmod($this->jpg_file, 0000); + if (is_readable($this->jpg_file)) + { + @chmod($this->jpg_file, 0644); + $this->markTestSkipped('is_readable always returns true if user is superuser or chmod does not work'); + } + $this->assertEquals(false, $this->guesser->guess($this->jpg_file)); + @chmod($this->jpg_file, 0644); + $this->assertEquals('image/jpeg', $this->guesser->guess($this->jpg_file)); + } + + public function test_null_guess() + { + $guesser = new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\null_guesser)); + $this->assertEquals('application/octet-stream', $guesser->guess($this->jpg_file)); + } + + public function data_incorrect_guessers() + { + return array( + array(array(new \phpbb\mimetype\incorrect_guesser)), + array(array(new \phpbb\mimetype\null_guesser(false))), + array(array()), + ); + } + + /** + * @dataProvider data_incorrect_guessers + * + * @expectedException \LogicException + */ + public function test_incorrect_guesser($guessers) + { + $guesser = new \phpbb\mimetype\guesser($guessers); + } + + public function data_content_guesser() + { + return array( + array( + array( + 'image/jpeg', + 'image/jpeg', + ), + array(new \phpbb\mimetype\content_guesser), + false, + ), + array( + array( + 'application/octet-stream', + 'application/octet-stream', + ), + array(new \phpbb\mimetype\content_guesser), + true, + ), + array( + array( + 'application/octet-stream', + 'image/jpeg', + ), + array(new \phpbb\mimetype\extension_guesser), + ), + ); + } + + /** + * @dataProvider data_content_guesser + */ + public function test_content_guesser($expected, $guessers, $overload = false) + { + $supported = false; + self::$function_exists = !$overload; + + // Cover possible LogicExceptions + foreach ($guessers as $cur_guesser) + { + $supported += $cur_guesser->is_supported(); + } + + if (!$supported) + { + $this->setExpectedException('\LogicException'); + } + + $guesser = new \phpbb\mimetype\guesser($guessers); + $this->assertEquals($expected[0], $guesser->guess($this->jpg_file)); + $this->assertEquals($expected[1], $guesser->guess($this->jpg_file, $this->jpg_file . '.jpg')); + @copy($this->jpg_file, $this->jpg_file . '.jpg'); + $this->assertEquals($expected[1], $guesser->guess($this->jpg_file . '.jpg')); + @unlink($this->jpg_file . '.jpg'); + } + + public function test_sort_priority() + { + $guessers = array( + 'FileinfoMimeTypeGuesser' => new \Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser, + 'extension_guesser' => new \phpbb\mimetype\extension_guesser, + 'FileBinaryMimeTypeGuesser' => new \Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser, + 'content_guesser' => new \phpbb\mimetype\content_guesser, + ); + $guessers['content_guesser']->set_priority(5); + $guessers['extension_guesser']->set_priority(-5); + usort($guessers, array($this->guesser, 'sort_priority')); + $this->assertInstanceOf('\phpbb\mimetype\content_guesser', $guessers[0]); + $this->assertInstanceOf('\phpbb\mimetype\extension_guesser', $guessers[3]); + } +} diff --git a/tests/mimetype/incorrect_guesser.php b/tests/mimetype/incorrect_guesser.php new file mode 100644 index 0000000000..3939826faa --- /dev/null +++ b/tests/mimetype/incorrect_guesser.php @@ -0,0 +1,18 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\mimetype; + +class incorrect_guesser +{ + public function guess($file) + { + return 'image/jpeg'; + } +} diff --git a/tests/mimetype/null_guesser.php b/tests/mimetype/null_guesser.php new file mode 100644 index 0000000000..5316d3726f --- /dev/null +++ b/tests/mimetype/null_guesser.php @@ -0,0 +1,30 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\mimetype; + +class null_guesser +{ + protected $is_supported; + + public function __construct($is_supported = true) + { + $this->is_supported = $is_supported; + } + + public function is_supported() + { + return $this->is_supported; + } + + public function guess($file) + { + return null; + } +} diff --git a/tests/mock/cache.php b/tests/mock/cache.php index 83bbb8ef30..9e5914b934 100644 --- a/tests/mock/cache.php +++ b/tests/mock/cache.php @@ -140,7 +140,7 @@ class phpbb_mock_cache implements \phpbb\cache\driver\driver_interface /** * {@inheritDoc} */ - public function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl) + public function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) { return $query_result; } diff --git a/tests/mock/notification_type_post.php b/tests/mock/notification_type_post.php new file mode 100644 index 0000000000..80f2afbae0 --- /dev/null +++ b/tests/mock/notification_type_post.php @@ -0,0 +1,36 @@ +<?php +/** +* +* @package notifications +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +class phpbb_mock_notification_type_post extends \phpbb\notification\type\post +{ + public function __construct($user_loader, $db, $cache, $user, $auth, $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) + { + $this->user_loader = $user_loader; + $this->db = $db; + $this->cache = $cache; + $this->user = $user; + $this->auth = $auth; + $this->config = $config; + + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + $this->notification_types_table = $notification_types_table; + $this->notifications_table = $notifications_table; + $this->user_notifications_table = $user_notifications_table; + } +} diff --git a/tests/mock/user.php b/tests/mock/user.php index bd547b3973..e57e86ae2f 100644 --- a/tests/mock/user.php +++ b/tests/mock/user.php @@ -46,4 +46,9 @@ class phpbb_mock_user } return false; } + + public function lang() + { + return implode(' ', func_get_args()); + } } diff --git a/tests/notification/base.php b/tests/notification/base.php index 549545f01b..f6333866c3 100644 --- a/tests/notification/base.php +++ b/tests/notification/base.php @@ -70,6 +70,7 @@ abstract class phpbb_tests_notification_base extends phpbb_database_test_case array(), $this->container, $this->user_loader, + $this->config, $this->db, $this->cache, $this->user, diff --git a/tests/notification/fixtures/convert.xml b/tests/notification/fixtures/convert.xml index 3f0a065cc4..c9d8fafa97 100644 --- a/tests/notification/fixtures/convert.xml +++ b/tests/notification/fixtures/convert.xml @@ -8,8 +8,6 @@ <column>user_notify_pm</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>1</value> @@ -18,8 +16,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>2</value> @@ -29,8 +25,6 @@ <value>1</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> @@ -40,8 +34,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>4</value> @@ -51,8 +43,6 @@ <value>1</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>5</value> @@ -62,8 +52,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>6</value> @@ -73,8 +61,6 @@ <value>1</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> </dataset> diff --git a/tests/notification/fixtures/group_request.xml b/tests/notification/fixtures/group_request.xml index 1eb73f1e15..fbaee0a326 100644 --- a/tests/notification/fixtures/group_request.xml +++ b/tests/notification/fixtures/group_request.xml @@ -6,16 +6,12 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>2</value> <value>2</value> <value>2</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> @@ -23,8 +19,6 @@ <value>3</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> </dataset> diff --git a/tests/notification/fixtures/submit_post_bookmark.xml b/tests/notification/fixtures/submit_post_bookmark.xml index d4bf8df73f..525d0484e0 100644 --- a/tests/notification/fixtures/submit_post_bookmark.xml +++ b/tests/notification/fixtures/submit_post_bookmark.xml @@ -79,55 +79,41 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>2</value> <value>poster</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> <value>test</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>4</value> <value>unauthorized</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>5</value> <value>notified</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>6</value> <value>disabled</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>7</value> <value>default</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_user_notifications"> diff --git a/tests/notification/fixtures/submit_post_post.xml b/tests/notification/fixtures/submit_post_post.xml index b0ffa042c5..a38ca77ea0 100644 --- a/tests/notification/fixtures/submit_post_post.xml +++ b/tests/notification/fixtures/submit_post_post.xml @@ -109,55 +109,41 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>2</value> <value>poster</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> <value>test</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>4</value> <value>unauthorized</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>5</value> <value>notified</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>6</value> <value>disabled</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>7</value> <value>default</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_user_notifications"> diff --git a/tests/notification/fixtures/submit_post_post_in_queue.xml b/tests/notification/fixtures/submit_post_post_in_queue.xml index 090e90ea49..28cb69be36 100644 --- a/tests/notification/fixtures/submit_post_post_in_queue.xml +++ b/tests/notification/fixtures/submit_post_post_in_queue.xml @@ -51,71 +51,53 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>2</value> <value>poster</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> <value>test</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>4</value> <value>unauthorized-mod</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>5</value> <value>unauthorized-read</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>6</value> <value>notified</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>7</value> <value>disabled</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>8</value> <value>default</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>9</value> <value>test glboal-permissions</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_user_notifications"> diff --git a/tests/notification/fixtures/submit_post_quote.xml b/tests/notification/fixtures/submit_post_quote.xml index f22ed97d91..2b11992e54 100644 --- a/tests/notification/fixtures/submit_post_quote.xml +++ b/tests/notification/fixtures/submit_post_quote.xml @@ -51,55 +51,41 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>2</value> <value>poster</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> <value>test</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>4</value> <value>unauthorized</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>5</value> <value>notified</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>6</value> <value>disabled</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>7</value> <value>default</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_user_notifications"> diff --git a/tests/notification/fixtures/submit_post_topic.xml b/tests/notification/fixtures/submit_post_topic.xml new file mode 100644 index 0000000000..5e179d9b99 --- /dev/null +++ b/tests/notification/fixtures/submit_post_topic.xml @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_forums_watch"> + <column>forum_id</column> + <column>user_id</column> + <column>notify_status</column> + <row> + <value>1</value> + <value>6</value> + <value>0</value> + </row> + <row> + <value>1</value> + <value>7</value> + <value>0</value> + </row> + <row> + <value>1</value> + <value>8</value> + <value>0</value> + </row> + </table> + <table name="phpbb_notifications"> + <column>notification_type_id</column> + <column>user_id</column> + <column>item_id</column> + <column>item_parent_id</column> + <column>notification_read</column> + <column>notification_data</column> + <row> + <value>1</value> + <value>8</value> + <value>1</value> + <value>1</value> + <value>0</value> + <value></value> + </row> + </table> + <table name="phpbb_notification_types"> + <column>notification_type_id</column> + <column>notification_type_name</column> + <column>notification_type_enabled</column> + <row> + <value>1</value> + <value>topic</value> + <value>1</value> + </row> + </table> + <table name="phpbb_posts"> + <column>post_id</column> + <column>topic_id</column> + <column>forum_id</column> + <column>post_text</column> + <row> + <value>1</value> + <value>1</value> + <value>1</value> + <value></value> + </row> + </table> + <table name="phpbb_topics"> + <column>topic_id</column> + <column>forum_id</column> + <row> + <value>1</value> + <value>1</value> + </row> + </table> + <table name="phpbb_users"> + <column>user_id</column> + <column>username_clean</column> + <column>user_permissions</column> + <column>user_sig</column> + <row> + <value>2</value> + <value>poster</value> + <value></value> + <value></value> + </row> + <row> + <value>6</value> + <value>noauth</value> + <value></value> + <value></value> + </row> + <row> + <value>7</value> + <value>default</value> + <value></value> + <value></value> + </row> + <row> + <value>8</value> + <value>notified</value> + <value></value> + <value></value> + </row> + </table> + <table name="phpbb_user_notifications"> + <column>item_type</column> + <column>item_id</column> + <column>user_id</column> + <column>method</column> + <column>notify</column> + <row> + <value>topic</value> + <value>0</value> + <value>2</value> + <value></value> + <value>1</value> + </row> + <row> + <value>topic</value> + <value>0</value> + <value>6</value> + <value></value> + <value>1</value> + </row> + <row> + <value>topic</value> + <value>0</value> + <value>7</value> + <value></value> + <value>1</value> + </row> + <row> + <value>topic</value> + <value>0</value> + <value>8</value> + <value></value> + <value>1</value> + </row> + </table> +</dataset> diff --git a/tests/notification/fixtures/user_list_trim.xml b/tests/notification/fixtures/user_list_trim.xml new file mode 100644 index 0000000000..4f708714da --- /dev/null +++ b/tests/notification/fixtures/user_list_trim.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_users"> + <column>user_id</column> + <column>username</column> + <column>username_clean</column> + <column>user_colour</column> + <column>user_permissions</column> + <column>user_sig</column> + <row> + <value>2</value> + <value>A</value> + <value>a</value> + <value></value> + <value></value> + <value></value> + </row> + <row> + <value>3</value> + <value>B</value> + <value>b</value> + <value></value> + <value></value> + <value></value> + </row> + <row> + <value>4</value> + <value>C</value> + <value>c</value> + <value></value> + <value></value> + <value></value> + </row> + <row> + <value>5</value> + <value>D</value> + <value>d</value> + <value></value> + <value></value> + <value></value> + </row> + <row> + <value>6</value> + <value>E</value> + <value>e</value> + <value></value> + <value></value> + <value></value> + </row> + </table> +</dataset> diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php index 8597c626a4..fbfd034381 100644 --- a/tests/notification/submit_post_base.php +++ b/tests/notification/submit_post_base.php @@ -12,7 +12,7 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; -class phpbb_notification_submit_post_base extends phpbb_database_test_case +abstract class phpbb_notification_submit_post_base extends phpbb_database_test_case { protected $notifications, $db, $container, $user, $config, $auth, $cache; @@ -101,7 +101,7 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case $user_loader = new \phpbb\user_loader($db, $phpbb_root_path, $phpEx, USERS_TABLE); // Notification Types - $notification_types = array('quote', 'bookmark', 'post', 'post_in_queue', 'topic', 'approve_topic', 'approve_post'); + $notification_types = array('quote', 'bookmark', 'post', 'post_in_queue', 'topic', 'topic_in_queue', 'approve_topic', 'approve_post'); $notification_types_array = array(); foreach ($notification_types as $type) { @@ -118,7 +118,7 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case // Notification Manager $phpbb_notifications = new \phpbb\notification\manager($notification_types_array, array(), - $phpbb_container, $user_loader, $db, $cache, $user, + $phpbb_container, $user_loader, $config, $db, $cache, $user, $phpbb_root_path, $phpEx, NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE); $phpbb_container->set('notification_manager', $phpbb_notifications); @@ -133,7 +133,7 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case FROM ' . NOTIFICATIONS_TABLE . ' n, ' . NOTIFICATION_TYPES_TABLE . " nt WHERE nt.notification_type_name = '" . $this->item_type . "' AND n.notification_type_id = nt.notification_type_id - ORDER BY user_id, item_id ASC"; + ORDER BY user_id ASC, item_id ASC"; $result = $this->db->sql_query($sql); $this->assertEquals($expected_before, $this->db->sql_fetchrowset($result)); $this->db->sql_freeresult($result); @@ -142,11 +142,6 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case $post_data = array_merge($this->post_data, $additional_post_data); submit_post('reply', '', 'poster-name', POST_NORMAL, $poll_data, $post_data, false, false); - $sql = 'SELECT user_id, item_id, item_parent_id - FROM ' . NOTIFICATIONS_TABLE . ' n, ' . NOTIFICATION_TYPES_TABLE . " nt - WHERE nt.notification_type_name = '" . $this->item_type . "' - AND n.notification_type_id = nt.notification_type_id - ORDER BY user_id ASC, item_id ASC"; $result = $this->db->sql_query($sql); $this->assertEquals($expected_after, $this->db->sql_fetchrowset($result)); $this->db->sql_freeresult($result); diff --git a/tests/notification/submit_post_type_bookmark_test.php b/tests/notification/submit_post_type_bookmark_test.php index 861017ff5f..4e4a3f6c9a 100644 --- a/tests/notification/submit_post_type_bookmark_test.php +++ b/tests/notification/submit_post_type_bookmark_test.php @@ -27,7 +27,7 @@ class phpbb_notification_submit_post_type_bookmark_test extends phpbb_notificati $this->greaterThan(0)) ->will($this->returnValueMap(array( array( - array('3', '4', '5', '6', '7'), + array(3, 4, 5, 6, 7), 'f_read', 1, array( diff --git a/tests/notification/submit_post_type_post_test.php b/tests/notification/submit_post_type_post_test.php index 473247a764..c2eb419522 100644 --- a/tests/notification/submit_post_type_post_test.php +++ b/tests/notification/submit_post_type_post_test.php @@ -27,7 +27,7 @@ class phpbb_notification_submit_post_type_post_test extends phpbb_notification_s $this->greaterThan(0)) ->will($this->returnValueMap(array( array( - array('3', '4', '5', '6', '7', '8'), + array(3, 4, 5, 6, 7, 8), 'f_read', 1, array( diff --git a/tests/notification/submit_post_type_quote_test.php b/tests/notification/submit_post_type_quote_test.php index 2b66d9c6a1..9956f3b58e 100644 --- a/tests/notification/submit_post_type_quote_test.php +++ b/tests/notification/submit_post_type_quote_test.php @@ -27,7 +27,7 @@ class phpbb_notification_submit_post_type_quote_test extends phpbb_notification_ $this->greaterThan(0)) ->will($this->returnValueMap(array( array( - array('3', '4', '5', '6', '7'), + array(3, 4, 5, 6, 7), 'f_read', 1, array( @@ -55,7 +55,7 @@ class phpbb_notification_submit_post_type_quote_test extends phpbb_notification_ * 2 => Poster, should NOT receive a notification * 3 => Quoted, should receive a notification * 4 => Quoted, but unauthed to read, should NOT receive a notification - * 5 => Quoted, but already notified, should NOT receive a new notification + * 5 => Quoted, but already notified, should STILL receive a new notification * 6 => Quoted, but option disabled, should NOT receive a notification * 7 => Quoted, option set to default, should receive a notification */ @@ -78,6 +78,7 @@ class phpbb_notification_submit_post_type_quote_test extends phpbb_notification_ array( array('user_id' => 3, 'item_id' => 2, 'item_parent_id' => 1), array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 5, 'item_id' => 2, 'item_parent_id' => 1), array('user_id' => 7, 'item_id' => 2, 'item_parent_id' => 1), ), ), diff --git a/tests/notification/submit_post_type_topic_test.php b/tests/notification/submit_post_type_topic_test.php new file mode 100644 index 0000000000..29f67c9c78 --- /dev/null +++ b/tests/notification/submit_post_type_topic_test.php @@ -0,0 +1,149 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/submit_post_base.php'; + +class phpbb_notification_submit_post_type_topic_test extends phpbb_notification_submit_post_base +{ + protected $item_type = 'topic'; + + public function setUp() + { + parent::setUp(); + + global $auth, $phpbb_log; + + // Add additional permissions + $auth->expects($this->any()) + ->method('acl_get_list') + ->with($this->anything(), + $this->stringContains('_'), + $this->greaterThan(0)) + ->will($this->returnValueMap(array( + array( + array(6, 7, 8), + 'f_read', + 1, + array( + 1 => array( + 'f_read' => array(7, 8), + ), + ), + ), + ))); + + $phpbb_log = $this->getMock('\phpbb\log\null'); + } + + /** + * submit_post() Notifications test + * + * submit_post() $mode = 'post' + * Notification item_type = 'topic' + */ + public function submit_post_data() + { + return array( + /** + * Normal post + * + * User => State description + * 2 => Poster, should NOT receive a notification + * 6 => Forum subscribed, but no-auth reading, should NOT receive a notification + * 7 => Forum subscribed, should receive a notification + * 8 => Forum subscribed, but already notified, should NOT receive a new notification + */ + array( + array(), + array( + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), + ), + array( + array('user_id' => 7, 'item_id' => 2, 'item_parent_id' => 1), + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 8, 'item_id' => 2, 'item_parent_id' => 1), + ), + ), + + /** + * Unapproved post + * + * No new notifications + */ + array( + array('force_approved_state' => false), + array( + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), + ), + array( + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), + ), + ), + ); + } + + /** + * @dataProvider submit_post_data + */ + public function test_submit_post($additional_post_data, $expected_before, $expected_after) + { + $sql = 'SELECT user_id, item_id, item_parent_id + FROM ' . NOTIFICATIONS_TABLE . ' n, ' . NOTIFICATION_TYPES_TABLE . " nt + WHERE nt.notification_type_name = '" . $this->item_type . "' + AND n.notification_type_id = nt.notification_type_id + ORDER BY user_id ASC, item_id ASC"; + $result = $this->db->sql_query($sql); + $this->assertEquals($expected_before, $this->db->sql_fetchrowset($result)); + $this->db->sql_freeresult($result); + + $poll_data = array(); + $post_data = array_merge($this->post_data, $additional_post_data); + submit_post('post', '', 'poster-name', POST_NORMAL, $poll_data, $post_data, false, false); + + // Check whether the notifications got added successfully + $result = $this->db->sql_query($sql); + $this->assertEquals($expected_after, $this->db->sql_fetchrowset($result), + 'Check whether the notifications got added successfully'); + $this->db->sql_freeresult($result); + + if (isset($additional_post_data['force_approved_state']) && $additional_post_data['force_approved_state'] === false) + { + return; + } + + $reply_data = array_merge($this->post_data, array( + 'topic_id' => 2, + )); + $url = submit_post('reply', '', 'poster-name', POST_NORMAL, $poll_data, $reply_data, false, false); + $reply_id = 3; + $this->assertStringEndsWith('p' . $reply_id, $url, 'Post ID of reply is not ' . $reply_id); + + // Check whether the notifications are still correct after a reply has been added + $result = $this->db->sql_query($sql); + $this->assertEquals($expected_after, $this->db->sql_fetchrowset($result), + 'Check whether the notifications are still correct after a reply has been added'); + $this->db->sql_freeresult($result); + + $result = $this->db->sql_query( + 'SELECT * + FROM ' . POSTS_TABLE . ' + WHERE post_id = ' . $reply_id); + $reply_edit_data = array_merge($this->post_data, $this->db->sql_fetchrow($result), array( + 'force_approved_state' => false, + 'post_edit_reason' => 'PHPBB3-12370', + )); + submit_post('edit', '', 'poster-name', POST_NORMAL, $poll_data, $reply_edit_data, false, false); + + // Check whether the notifications are still correct after the reply has been edit + $result = $this->db->sql_query($sql); + $this->assertEquals($expected_after, $this->db->sql_fetchrowset($result), + 'Check whether the notifications are still correct after the reply has been edit'); + $this->db->sql_freeresult($result); + } +} diff --git a/tests/notification/user_list_trim_test.php b/tests/notification/user_list_trim_test.php new file mode 100644 index 0000000000..a8422f80b5 --- /dev/null +++ b/tests/notification/user_list_trim_test.php @@ -0,0 +1,139 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_notification_user_list_trim_test extends phpbb_database_test_case +{ + protected $notification; + + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/user_list_trim.xml'); + } + + public function setUp() + { + global $phpbb_root_path, $phpEx, $phpbb_dispatcher, $user, $cache, $auth; + + parent::setUp(); + + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $db = $this->new_dbal(); + + $config = new \phpbb\config\config(array()); + set_config(null, null, null, $config); + set_config_count(null, null, null, $config); + + $cache = new \phpbb\cache\service( + new \phpbb\cache\driver\null(), + $config, + $db, + $phpbb_root_path, + $phpEx + ); + + $auth = $this->getMock('\phpbb\auth\auth'); + $auth->expects($this->any()) + ->method('acl_get') + ->with($this->stringContains('_'), + $this->anything()) + ->will($this->returnValueMap(array( + array('u_viewprofile', 1, false), + ))); + + $user = new \phpbb\user(); + $user->data = array('user_lang' => 'en'); + $user->add_lang('common'); + + $user_loader = new phpbb\user_loader($db, $phpbb_root_path, $phpEx, USERS_TABLE); + $user_loader->load_users(array(2, 3, 4, 5, 6)); + + $this->notification = new phpbb_mock_notification_type_post( + $user_loader, null, null, $user, null, null, $phpbb_root_path, $phpEx, null, null, null + ); + } + + public function user_list_trim_data() + { + return array( + array( + array( + 'topic_title' => 'Test', + 'poster_id' => 2, + 'post_username' => 'A', + 'responders' => null, + ), + 'A replied to the topic “Test”.', + ), + array( + array( + 'topic_title' => 'Test', + 'poster_id' => 2, + 'post_username' => 'A', + 'responders' => array( + array('username' => '', 'poster_id' => 3), + ), + ), + 'A and B replied to the topic “Test”.', + ), + array( + array( + 'topic_title' => 'Test', + 'poster_id' => 2, + 'post_username' => 'A', + 'responders' => array( + array('username' => '', 'poster_id' => 3), + array('username' => '', 'poster_id' => 4), + ), + ), + 'A, B, and C replied to the topic “Test”.', + ), + array( + array( + 'topic_title' => 'Test', + 'poster_id' => 2, + 'post_username' => 'A', + 'responders' => array( + array('username' => '', 'poster_id' => 3), + array('username' => '', 'poster_id' => 4), + array('username' => '', 'poster_id' => 5), + ), + ), + 'A, B, C, and D replied to the topic “Test”.', + ), + array( + array( + 'topic_title' => 'Test', + 'poster_id' => 2, + 'post_username' => 'A', + 'responders' => array( + array('username' => '', 'poster_id' => 3), + array('username' => '', 'poster_id' => 4), + array('username' => '', 'poster_id' => 5), + array('username' => '', 'poster_id' => 6), + ), + ), + 'A, B, C, and 2 others replied to the topic “Test”.', + ), + ); + } + + /** + * @dataProvider user_list_trim_data + */ + public function test_user_list_trim($data, $expected_result) + { + $data = array('notification_data' => serialize($data)); + $this->notification->set_initial_data($data); + + $this->assertEquals($expected_result, $this->notification->get_title()); + } +} diff --git a/tests/pagination/config/routing.yml b/tests/pagination/config/routing.yml new file mode 100644 index 0000000000..dd667274cd --- /dev/null +++ b/tests/pagination/config/routing.yml @@ -0,0 +1,6 @@ +core_controller: + pattern: /test + defaults: { _controller: core_foo.controller:bar, page: 1} +core_page_controller: + pattern: /test/page/{page} + defaults: { _controller: core_foo.controller:bar} diff --git a/tests/pagination/generate_template_test.php b/tests/pagination/generate_template_test.php deleted file mode 100644 index 587a948583..0000000000 --- a/tests/pagination/generate_template_test.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -/** -* -* @package testing -* @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; -require_once dirname(__FILE__) . '/../template/template_test_case.php'; - -class phpbb_pagination_generate_template_test extends phpbb_template_template_test_case -{ - protected $test_path = 'tests/pagination'; - - public function phpbb_generate_template_pagination_data() - { - return array( - array( - 'page.php', - 'start', - 95, - 10, - 10, - 'pagination - :previous::page.php - :else:1:page.php - :current:2:page.php?start=10 - :else:3:page.php?start=20 - :else:4:page.php?start=30 - :else:5:page.php?start=40 - :ellipsis:9:page.php?start=80 - :else:10:page.php?start=90 - :next::page.php?start=20 - :u_prev:page.php - :u_next:page.php?start=20', - ), - array( - 'page.php', - 'start', - 95, - 10, - 20, - 'pagination - :previous::page.php?start=10 - :else:1:page.php - :else:2:page.php?start=10 - :current:3:page.php?start=20 - :else:4:page.php?start=30 - :else:5:page.php?start=40 - :else:6:page.php?start=50 - :ellipsis:9:page.php?start=80 - :else:10:page.php?start=90 - :next::page.php?start=30 - :u_prev:page.php?start=10 - :u_next:page.php?start=30', - ), - array( - 'test/page/%d', - '/page/%d', - 95, - 10, - 10, - 'pagination - :previous::test - :else:1:test - :current:2:test/page/2 - :else:3:test/page/3 - :else:4:test/page/4 - :else:5:test/page/5 - :ellipsis:9:test/page/9 - :else:10:test/page/10 - :next::test/page/3 - :u_prev:test - :u_next:test/page/3', - ), - array( - 'test/page/%d', - '/page/%d', - 95, - 10, - 20, - 'pagination - :previous::test/page/2 - :else:1:test - :else:2:test/page/2 - :current:3:test/page/3 - :else:4:test/page/4 - :else:5:test/page/5 - :else:6:test/page/6 - :ellipsis:9:test/page/9 - :else:10:test/page/10 - :next::test/page/4 - :u_prev:test/page/2 - :u_next:test/page/4', - ), - ); - } - - /** - * @dataProvider phpbb_generate_template_pagination_data - */ - public function test_phpbb_generate_template_pagination($base_url, $start_name, $num_items, $per_page, $start_item, $expect) - { - phpbb_generate_template_pagination($this->template, $base_url, 'pagination', $start_name, $num_items, $per_page, $start_item); - $this->template->set_filenames(array('test' => 'pagination.html')); - - $this->assertEquals(str_replace("\t", '', $expect), $this->display('test')); - } -} diff --git a/tests/pagination/pagination_test.php b/tests/pagination/pagination_test.php new file mode 100644 index 0000000000..71206dff58 --- /dev/null +++ b/tests/pagination/pagination_test.php @@ -0,0 +1,280 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../template/template_test_case.php'; + +class phpbb_pagination_pagination_test extends phpbb_template_template_test_case +{ + protected $test_path = 'tests/pagination'; + + public function return_callback_implode() + { + return implode('-', func_get_args()); + } + + public function setUp() + { + parent::setUp(); + + global $phpbb_dispatcher; + + $phpbb_dispatcher = new phpbb_mock_event_dispatcher; + $this->user = $this->getMock('\phpbb\user'); + $this->user->expects($this->any()) + ->method('lang') + ->will($this->returnCallback(array($this, 'return_callback_implode'))); + + $this->finder = new \phpbb\extension\finder( + new phpbb_mock_extension_manager(dirname(__FILE__) . '/', array()), + new \phpbb\filesystem(), + dirname(__FILE__) . '/', + new phpbb_mock_cache() + ); + + $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); + $provider = new \phpbb\controller\provider($this->finder); + $provider->find(dirname(__FILE__) . '/'); + $this->helper = new \phpbb\controller\helper($this->template, $this->user, $this->config, $provider, '', 'php'); + $this->pagination = new \phpbb\pagination($this->template, $this->user, $this->helper); + } + + public function generate_template_pagination_data() + { + return array( + array( + 'page.php', + 'start', + 95, + 10, + 10, + 'pagination + :per_page:10 + :current_page:2 + :base_url:page.php + :previous::page.php + :else:1:page.php + :current:2:page.php?start=10 + :else:3:page.php?start=20 + :else:4:page.php?start=30 + :else:5:page.php?start=40 + :ellipsis:9:page.php?start=80 + :else:10:page.php?start=90 + :next::page.php?start=20 + :u_prev:page.php + :u_next:page.php?start=20', + ), + array( + 'page.php', + 'start', + 95, + 10, + 20, + 'pagination + :per_page:10 + :current_page:3 + :base_url:page.php + :previous::page.php?start=10 + :else:1:page.php + :else:2:page.php?start=10 + :current:3:page.php?start=20 + :else:4:page.php?start=30 + :else:5:page.php?start=40 + :else:6:page.php?start=50 + :ellipsis:9:page.php?start=80 + :else:10:page.php?start=90 + :next::page.php?start=30 + :u_prev:page.php?start=10 + :u_next:page.php?start=30', + ), + array( + array('routes' => array( + 'core_controller', + 'core_page_controller', + )), + 'page', + 95, + 10, + 10, + 'pagination + :per_page:10 + :current_page:2 + :base_url: + :previous::test + :else:1:test + :current:2:test/page/2 + :else:3:test/page/3 + :else:4:test/page/4 + :else:5:test/page/5 + :ellipsis:9:test/page/9 + :else:10:test/page/10 + :next::test/page/3 + :u_prev:test + :u_next:test/page/3', + ), + array( + array('routes' => array( + 'core_controller', + 'core_page_controller', + )), + 'page', + 95, + 10, + 20, + 'pagination + :per_page:10 + :current_page:3 + :base_url: + :previous::test/page/2 + :else:1:test + :else:2:test/page/2 + :current:3:test/page/3 + :else:4:test/page/4 + :else:5:test/page/5 + :else:6:test/page/6 + :ellipsis:9:test/page/9 + :else:10:test/page/10 + :next::test/page/4 + :u_prev:test/page/2 + :u_next:test/page/4', + ), + ); + } + + /** + * @dataProvider generate_template_pagination_data + */ + public function test_generate_template_pagination($base_url, $start_name, $num_items, $per_page, $start_item, $expect) + { + $this->pagination->generate_template_pagination($base_url, 'pagination', $start_name, $num_items, $per_page, $start_item); + $this->template->set_filenames(array('test' => 'pagination.html')); + + $this->assertEquals(str_replace("\t", '', $expect), $this->display('test')); + } + + public function on_page_data() + { + return array( + array( + 10, + 10, + 0, + 'PAGE_OF-1-1', + ), + ); + } + + /** + * @dataProvider on_page_data + */ + public function test_on_page($num_items, $per_page, $start_item, $expect_return) + { + $this->assertEquals($expect_return, $this->pagination->on_page($num_items, $per_page, $start_item)); + } + + public function validate_start_data() + { + return array( + array( + 0, + 0, + 0, + ), + array( + -1, + 20, + 0, + ), + array( + 20, + -30, + 0, + ), + array( + 0, + 20, + 0, + ), + array( + 10, + 20, + 10, + ), + array( + 20, + 20, + 10, + ), + array( + 30, + 20, + 10, + ), + ); + } + + /** + * @dataProvider validate_start_data + */ + public function test_validate_start($start, $num_items, $expect) + { + $this->assertEquals($expect, $this->pagination->validate_start($start, 10, $num_items)); + } + + public function reverse_start_data() + { + return array( + array( + 10, + 5, + 15, + 0, + ), + array( + 10, + 10, + 25, + 5, + ), + ); + } + + /** + * @dataProvider reverse_start_data + */ + public function test_reverse_start($start, $limit, $num_items, $expect) + { + $this->assertEquals($expect, $this->pagination->reverse_start($start, $limit, $num_items)); + } + + public function reverse_limit_data() + { + return array( + array( + 10, + 10, + 15, + 5, + ), + array( + 20, + 10, + 15, + 1, + ), + ); + } + + /** + * @dataProvider reverse_limit_data + */ + public function test_reverse_limit($start, $per_page, $num_items, $expect) + { + $this->assertEquals($expect, $this->pagination->reverse_limit($start, $per_page, $num_items)); + } +} diff --git a/tests/pagination/templates/pagination.html b/tests/pagination/templates/pagination.html index 7f2a329804..db63258585 100644 --- a/tests/pagination/templates/pagination.html +++ b/tests/pagination/templates/pagination.html @@ -1,4 +1,7 @@ pagination +:per_page:{PER_PAGE} +:current_page:{CURRENT_PAGE} +:base_url:{BASE_URL} <!-- BEGIN pagination --> <!-- IF pagination.S_IS_PREV -->:previous:{pagination.PAGE_NUMBER}:{pagination.PAGE_URL} <!-- ELSEIF pagination.S_IS_CURRENT -->:current:{pagination.PAGE_NUMBER}:{pagination.PAGE_URL} diff --git a/tests/passwords/drivers_test.php b/tests/passwords/drivers_test.php new file mode 100644 index 0000000000..40bb110185 --- /dev/null +++ b/tests/passwords/drivers_test.php @@ -0,0 +1,81 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_passwords_helper_test extends PHPUnit_Framework_TestCase +{ + public function setUp() + { + // Prepare dependencies for drivers + $config = new \phpbb\config\config(array()); + $this->driver_helper = new \phpbb\passwords\driver\helper($config); + + $this->passwords_drivers = array( + 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $this->driver_helper), + 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $this->driver_helper), + 'passwords.driver.salted_md5' => new \phpbb\passwords\driver\salted_md5($config, $this->driver_helper), + 'passwords.driver.phpass' => new \phpbb\passwords\driver\phpass($config, $this->driver_helper), + ); + } + + public function data_helper_encode64() + { + return array( + array('foobar', 6, 'axqPW3aQ'), + array('foobar', 7, 'axqPW3aQ..'), + array('foobar', 5, 'axqPW34'), + ); + } + + /** + * @dataProvider data_helper_encode64 + */ + public function test_helper_encode64($input, $length, $output) + { + $return = $this->driver_helper->hash_encode64($input, $length); + $this->assertSame($output, $return); + } + + public function data_get_random_salt() + { + return array( + array(24, false), + array(24, '/dev/foobar'), + ); + } + + /** + * @dataProvider data_get_random_salt + */ + public function test_get_random_salt($length, $rand_seed) + { + $rand_string = (empty($rand_seed)) ? $this->driver_helper->get_random_salt($length) : $this->driver_helper->get_random_salt($length, $rand_seed); + $start = microtime(true); + + // Run each test for max. 1 second + while ((microtime(true) - $start) < 1) + { + $urandom_string = (empty($rand_seed)) ? $this->driver_helper->get_random_salt($length) : $this->driver_helper->get_random_salt($length, $rand_seed); + $this->assertSame($length, strlen($urandom_string)); + $this->assertNotSame($rand_string, $urandom_string); + } + } + + public function test_get_hash_settings_salted_md5() + { + $settings = $this->passwords_drivers['passwords.driver.salted_md5']->get_hash_settings('$H$9isfrtKXWqrz8PvztXlL3.daw4U0zI1'); + $this->assertEquals(array( + 'count' => pow(2, 11), + 'salt' => 'isfrtKXW', + 'full' => '$H$9isfrtKXW', + ), + $settings + ); + $this->assertEquals(false, $this->passwords_drivers['passwords.driver.salted_md5']->get_hash_settings(false)); + } +} diff --git a/tests/passwords/manager_test.php b/tests/passwords/manager_test.php new file mode 100644 index 0000000000..008f222696 --- /dev/null +++ b/tests/passwords/manager_test.php @@ -0,0 +1,295 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_passwords_manager_test extends PHPUnit_Framework_TestCase +{ + protected $passwords_drivers; + + protected $pw_characters = '0123456789abcdefghijklmnopqrstuvwyzABCDEFGHIJKLMNOPQRSTUVXYZ.,_!?/\\'; + + protected $default_pw = 'foobar'; + + public function setUp() + { + // Prepare dependencies for manager and driver + $config = new \phpbb\config\config(array()); + $this->driver_helper = new \phpbb\passwords\driver\helper($config); + + $this->passwords_drivers = array( + 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $this->driver_helper), + 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $this->driver_helper), + 'passwords.driver.salted_md5' => new \phpbb\passwords\driver\salted_md5($config, $this->driver_helper), + 'passwords.driver.phpass' => new \phpbb\passwords\driver\phpass($config, $this->driver_helper), + ); + + $this->helper = new \phpbb\passwords\helper; + // Set up passwords manager + $this->manager = new \phpbb\passwords\manager($config, $this->passwords_drivers, $this->helper, array_keys($this->passwords_drivers)); + } + + public function hash_password_data() + { + if (version_compare(PHP_VERSION, '5.3.7', '<')) + { + return array( + array('', '2a', 60), + array('passwords.driver.bcrypt_2y', '2a', 60), + array('passwords.driver.bcrypt', '2a', 60), + array('passwords.driver.salted_md5', 'H', 34), + array('passwords.driver.foobar', '', false), + ); + } + else + { + return array( + array('', '2y', 60), + array('passwords.driver.bcrypt_2y', '2y', 60), + array('passwords.driver.bcrypt', '2a', 60), + array('passwords.driver.salted_md5', 'H', 34), + array('passwords.driver.foobar', '', false), + ); + } + } + + /** + * @dataProvider hash_password_data + */ + public function test_hash_password($type, $prefix, $length) + { + $password = $this->default_pw; + + if (!$length) + { + $this->assertEquals(false, $hash = $this->manager->hash($password, $type)); + return; + } + $time = microtime(true); + + // Limit each test to 1 second + while ((microtime(true) - $time) < 1) + { + $hash = $this->manager->hash($password, $type); + preg_match('#^\$([a-zA-Z0-9\\\]*?)\$#', $hash, $match); + $this->assertEquals($prefix, $match[1]); + $this->assertEquals($length, strlen($hash)); + $password .= $this->pw_characters[mt_rand(0, 66)]; + } + } + + public function check_password_data() + { + if (version_compare(PHP_VERSION, '5.3.7', '<')) + { + return array( + array('passwords.driver.bcrypt'), + array('passwords.driver.salted_md5'), + array('passwords.driver.phpass'), + ); + } + else + { + return array( + array('passwords.driver.bcrypt_2y'), + array('passwords.driver.bcrypt'), + array('passwords.driver.salted_md5'), + array('passwords.driver.phpass'), + ); + } + } + + /** + * @dataProvider check_password_data + */ + public function test_check_password($hash_type) + { + $password = $this->default_pw; + $time = microtime(true); + // Limit each test to 1 second + while ((microtime(true) - $time) < 1) + { + $hash = $this->manager->hash($password, $hash_type); + $this->assertEquals(true, $this->manager->check($password, $hash)); + $password .= $this->pw_characters[mt_rand(0, 66)]; + $this->assertEquals(false, $this->manager->check($password, $hash)); + } + + // Check if convert_flag is correctly set + $default_type = (version_compare(PHP_VERSION, '5.3.7', '<')) ? 'passwords.driver.bcrypt' : 'passwords.driver.bcrypt_2y'; + $this->assertEquals(($hash_type !== $default_type), $this->manager->convert_flag); + } + + + public function check_hash_exceptions_data() + { + return array( + array('foobar', '3858f62230ac3c915f300c664312c63f', true), + array('foobar', '$S$b57a939fa4f2c04413a4eea9734a0903647b7adb93181295', false), + array('foobar', '$2a\S$kkkkaakdkdiej39023903204j2k3490234jk234j02349', false), + array('foobar', '$H$kklk938d023k//k3023', false), + array('foobar', '$H$3PtYMgXb39lrIWkgoxYLWtRkZtY3AY/', false), + array('foobar', '$2a$kwiweorurlaeirw', false), + ); + } + + /** + * @dataProvider check_hash_exceptions_data + */ + public function test_check_hash_exceptions($password, $hash, $expected) + { + $this->assertEquals($expected, $this->manager->check($password, $hash)); + } + + public function data_hash_password_length() + { + return array( + array('passwords.driver.bcrypt', false), + array('passwords.driver.bcrypt_2y', false), + array('passwords.driver.salted_md5', '3858f62230ac3c915f300c664312c63f'), + array('passwords.driver.phpass', '3858f62230ac3c915f300c664312c63f'), + ); + } + + /** + * @dataProvider data_hash_password_length + */ + public function test_hash_password_length($driver, $expected) + { + $this->assertEquals($expected, $this->passwords_drivers[$driver]->hash('foobar', 'foobar')); + } + + public function test_hash_password_8bit_bcrypt() + { + $this->assertEquals(false, $this->manager->hash('foobar𝄞', 'passwords.driver.bcrypt')); + if (version_compare(PHP_VERSION, '5.3.7', '<')) + { + $this->assertEquals(false, $this->manager->hash('foobar𝄞', 'passwords.driver.bcrypt_2y')); + } + else + { + $this->assertNotEquals(false, $this->manager->hash('foobar𝄞', 'passwords.driver.bcrypt_2y')); + } + } + + public function test_combined_hash_data() + { + if (version_compare(PHP_VERSION, '5.3.7', '<')) + { + return array( + array( + 'passwords.driver.salted_md5', + array('passwords.driver.bcrypt'), + ), + array( + 'passwords.driver.phpass', + array('passwords.driver.salted_md5'), + ), + array( + 'passwords.driver.salted_md5', + array('passwords.driver.phpass', 'passwords.driver.bcrypt'), + ), + array( + 'passwords.driver.salted_md5', + array('passwords.driver.salted_md5'), + false, + ), + array( + '$H$', + array('$2a$'), + ), + ); + } + else + { + return array( + array( + 'passwords.driver.salted_md5', + array('passwords.driver.bcrypt_2y'), + ), + array( + 'passwords.driver.salted_md5', + array('passwords.driver.bcrypt'), + ), + array( + 'passwords.driver.phpass', + array('passwords.driver.salted_md5'), + ), + array( + 'passwords.driver.salted_md5', + array('passwords.driver.bcrypt_2y', 'passwords.driver.bcrypt'), + ), + array( + 'passwords.driver.salted_md5', + array('passwords.driver.salted_md5'), + false, + ), + array( + 'passwords.driver.bcrypt_2y', + array('passwords.driver.salted_md4'), + false, + ), + array( + '$H$', + array('$2y$'), + ), + ); + } + } + + /** + * @dataProvider test_combined_hash_data + */ + public function test_combined_hash_password($first_type, $second_type, $expected = true) + { + $password = $this->default_pw; + $time = microtime(true); + // Limit each test to 1 second + while ((microtime(true) - $time) < 1) + { + $hash = $this->manager->hash($password, $first_type); + $combined_hash = $this->manager->hash($hash, $second_type); + $this->assertEquals($expected, $this->manager->check($password, $combined_hash)); + $password .= $this->pw_characters[mt_rand(0, 66)]; + $this->assertEquals(false, $this->manager->check($password, $combined_hash)); + + // If we are expecting the check to fail then there is + // no need to run this more than once + if (!$expected) + { + break; + } + } + } + + public function test_unique_id() + { + $time = microtime(true); + $first_id = $this->driver_helper->unique_id(); + // Limit test to 1 second + while ((microtime(true) - $time) < 1) + { + $this->assertNotSame($first_id, $this->driver_helper->unique_id()); + } + } + + public function test_check_hash_with_large_input() + { + // 16 MB password, should be rejected quite fast + $start_time = time(); + $this->assertFalse($this->manager->check(str_repeat('a', 1024 * 1024 * 16), '$H$9isfrtKXWqrz8PvztXlL3.daw4U0zI1')); + $this->assertLessThanOrEqual(5, time() - $start_time); + } + + public function test_hash_password_with_large_input() + { + // 16 MB password, should be rejected quite fast + $start_time = time(); + $this->assertFalse($this->manager->hash(str_repeat('a', 1024 * 1024 * 16))); + $this->assertLessThanOrEqual(5, time() - $start_time); + } +} diff --git a/tests/path_helper/web_root_path_test.php b/tests/path_helper/web_root_path_test.php index 938b58892b..ec04135997 100644 --- a/tests/path_helper/web_root_path_test.php +++ b/tests/path_helper/web_root_path_test.php @@ -53,12 +53,17 @@ class phpbb_path_helper_web_root_path_test extends phpbb_test_case return array( array( + 'http://www.test.com/test.php', + 'http://www.test.com/test.php', + '/', + ), + array( $this->phpbb_root_path . 'test.php', $this->phpbb_root_path . 'test.php', ), array( 'test.php', - $this->phpbb_root_path . 'test.php', + 'test.php', ), array( $this->phpbb_root_path . $this->phpbb_root_path . 'test.php', @@ -111,6 +116,13 @@ class phpbb_path_helper_web_root_path_test extends phpbb_test_case '/phpbb3-fork/phpBB/foo/template', '/phpbb3-fork/phpBB/app.php', ), + array( + $this->phpbb_root_path . 'test.php', + $this->phpbb_root_path . '../test.php', + '/', + '/phpbb3-fork/phpBB/app.php/', + '/phpbb3-fork/phpBB/app.php', + ), ); } @@ -141,4 +153,27 @@ class phpbb_path_helper_web_root_path_test extends phpbb_test_case $this->assertEquals($expected, $path_helper->update_web_root_path($input, $symfony_request)); } + + public function clean_url_data() + { + return array( + array('', ''), + array('://', '://'), + array('http://', 'http://'), + array('http://one/two/three', 'http://one/two/three'), + array('http://../one/two', 'http://../one/two'), + array('http://one/../two/three', 'http://two/three'), + array('http://one/two/../three', 'http://one/three'), + array('http://one/two/../../three', 'http://three'), + array('http://one/two/../../../three', 'http://../three'), + ); + } + + /** + * @dataProvider clean_url_data + */ + public function test_clean_url($input, $expected) + { + $this->assertEquals($expected, $this->path_helper->clean_url($input)); + } } diff --git a/tests/privmsgs/fixtures/delete_user_pms.xml b/tests/privmsgs/fixtures/delete_user_pms.xml index 9a86501b7a..5f705c9fd2 100644 --- a/tests/privmsgs/fixtures/delete_user_pms.xml +++ b/tests/privmsgs/fixtures/delete_user_pms.xml @@ -8,8 +8,6 @@ <column>user_unread_privmsg</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>2</value> <value>sender</value> @@ -18,8 +16,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> @@ -29,8 +25,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>4</value> @@ -40,8 +34,6 @@ <value>2</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>5</value> @@ -51,8 +43,6 @@ <value>0</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_privmsgs"> diff --git a/tests/profile/custom_string_test.php b/tests/profile/custom_string_test.php new file mode 100644 index 0000000000..bd0b20573c --- /dev/null +++ b/tests/profile/custom_string_test.php @@ -0,0 +1,116 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; + +class phpbb_profile_custom_string_test extends phpbb_database_test_case +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/profile_fields.xml'); + } + + static public function string_fields() + { + return array( + // note, there is an offset of 1 between option_id (0-indexed) + // in the database and values (1-indexed) to avoid problems with + // transmitting 0 in an HTML form + // required, value, validation, expected, description + array( + 1, + 'H3110', + '[0-9]+', + 'FIELD_INVALID_CHARS_NUMBERS_ONLY-field', + 'Required field should reject characters in a numbers-only field', + ), + array( + 1, + 'This string is too long', + '.*', + 'FIELD_TOO_LONG-10-field', + 'Required field should reject a field too long', + ), + array( + 0, + '<>"&%&><>', + '.*', + false, + 'Optional field should accept html entities', + ), + array( + 1, + 'ö ä ü ß', + '.*', + false, + 'Required field should accept UTF-8 string', + ), + array( + 1, + 'This ö ä string has to b', + '.*', + 'FIELD_TOO_LONG-10-field', + 'Required field should reject an UTF-8 string which is too long', + ), + array( + 1, + 'ö äö äö ä', + '[\w]+', + 'FIELD_INVALID_CHARS_ALPHA_ONLY-field', + 'Required field should reject UTF-8 in alpha only field', + ), + array( + 1, + 'Hello', + '[\w]+', + false, + 'Required field should accept a characters only field', + ), + ); + } + + /** + * @dataProvider string_fields + */ + public function test_string_validate($field_required, $field_value, $field_validation, $expected, $description) + { + $db = $this->new_dbal(); + + $field_data = array( + 'field_id' => 1, + 'lang_id' => 1, + 'lang_name' => 'field', + 'field_novalue' => 1, + 'field_required' => $field_required, + 'field_maxlen' => 10, + 'field_validation' => $field_validation, + ); + $user = $this->getMock('\phpbb\user'); + $user->expects($this->any()) + ->method('lang') + ->will($this->returnCallback(array($this, 'return_callback_implode'))); + + $request = $this->getMock('\phpbb\request\request'); + $template = $this->getMock('\phpbb\template\template'); + + $cp = new \phpbb\profilefields\type\type_string( + $request, + $template, + $user + ); + $result = $cp->validate_profile_field($field_value, $field_data); + + $this->assertEquals($expected, $result, $description); + } + + public function return_callback_implode() + { + return implode('-', func_get_args()); + } +} diff --git a/tests/profile/custom_test.php b/tests/profile/custom_test.php index 1f33b45ba9..e68f1f7c4b 100644 --- a/tests/profile/custom_test.php +++ b/tests/profile/custom_test.php @@ -7,49 +7,65 @@ * */ -require_once dirname(__FILE__) . '/../../phpBB/includes/functions_profile_fields.php'; - class phpbb_profile_custom_test extends phpbb_database_test_case { public function getDataSet() { - return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/profile_fields.xml'); + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/profile_fields.xml'); } - static public function dropdownFields() + static public function dropdown_fields() { return array( // note, there is an offset of 1 between option_id (0-indexed) // in the database and values (1-indexed) to avoid problems with // transmitting 0 in an HTML form // required, value, expected - array(1, '0', 'FIELD_INVALID_VALUE', 'Required field should throw error for out-of-range value'), - array(1, '1', 'FIELD_REQUIRED', 'Required field should throw error for default value'), - array(1, '2', false, 'Required field should accept non-default value'), - array(0, '0', 'FIELD_INVALID_VALUE', 'Optional field should throw error for out-of-range value'), - array(0, '1', false, 'Optional field should accept default value'), - array(0, '2', false, 'Optional field should accept non-default value'), + array(1, '0', 'FIELD_INVALID_VALUE-field', 'Required field should throw error for out-of-range value'), + array(1, '1', 'FIELD_REQUIRED-field', 'Required field should throw error for default value'), + array(1, '2', false, 'Required field should accept non-default value'), + array(0, '0', 'FIELD_INVALID_VALUE-field', 'Optional field should throw error for out-of-range value'), + array(0, '1', false, 'Optional field should accept default value'), + array(0, '2', false, 'Optional field should accept non-default value'), ); } /** - * @dataProvider dropdownFields + * @dataProvider dropdown_fields */ public function test_dropdown_validate($field_required, $field_value, $expected, $description) { - global $db; + global $db, $table_prefix; $db = $this->new_dbal(); $field_data = array( 'field_id' => 1, 'lang_id' => 1, + 'lang_name' => 'field', 'field_novalue' => 1, 'field_required' => $field_required, ); + $user = $this->getMock('\phpbb\user'); + $user->expects($this->any()) + ->method('lang') + ->will($this->returnCallback(array($this, 'return_callback_implode'))); + + $request = $this->getMock('\phpbb\request\request'); + $template = $this->getMock('\phpbb\template\template'); - $cp = new custom_profile; - $result = $cp->validate_profile_field(FIELD_DROPDOWN, $field_value, $field_data); + $cp = new \phpbb\profilefields\type\type_dropdown( + new \phpbb\profilefields\lang_helper($db, $table_prefix . 'profile_fields_lang'), + $request, + $template, + $user + ); + $result = $cp->validate_profile_field($field_value, $field_data); $this->assertEquals($expected, $result, $description); } + + public function return_callback_implode() + { + return implode('-', func_get_args()); + } } diff --git a/tests/profile/fixtures/profile_fields.xml b/tests/profile/fixtures/profile_fields.xml index 0b2929f625..e0c260bbf5 100644 --- a/tests/profile/fixtures/profile_fields.xml +++ b/tests/profile/fixtures/profile_fields.xml @@ -10,21 +10,21 @@ <value>1</value> <value>1</value> <value>0</value> - <value>5</value> + <value>profilefields.type.dropdown</value> <value>Default Option</value> </row> <row> <value>1</value> <value>1</value> <value>1</value> - <value>5</value> + <value>profilefields.type.dropdown</value> <value>First Alternative</value> </row> <row> <value>1</value> <value>1</value> <value>2</value> - <value>5</value> + <value>profilefields.type.dropdown</value> <value>Third Alternative</value> </row> </table> diff --git a/tests/profile/get_profile_value_test.php b/tests/profile/get_profile_value_test.php new file mode 100644 index 0000000000..e867455a03 --- /dev/null +++ b/tests/profile/get_profile_value_test.php @@ -0,0 +1,42 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_profile_get_profile_value_test extends phpbb_test_case +{ + static public function get_profile_value_int_data() + { + return array( + array('\phpbb\profilefields\type\type_int', '10', true, 10), + array('\phpbb\profilefields\type\type_int', '0', true, 0), + array('\phpbb\profilefields\type\type_int', '', true, 0), + array('\phpbb\profilefields\type\type_int', null, true, 0), + array('\phpbb\profilefields\type\type_int', '10', false, 10), + array('\phpbb\profilefields\type\type_int', '0', false, 0), + array('\phpbb\profilefields\type\type_int', '', false, null), + array('\phpbb\profilefields\type\type_int', null, false, null), + ); + } + + /** + * @dataProvider get_profile_value_int_data + */ + public function test_get_profile_value_int($type, $value, $show_novalue, $expected) + { + $cp = new $type( + $this->getMock('\phpbb\request\request'), + $this->getMock('\phpbb\template\template'), + $this->getMock('\phpbb\user') + ); + + $this->assertSame($expected, $cp->get_profile_value($value, array( + 'field_type' => $type, + 'field_show_novalue' => $show_novalue, + ))); + } +} diff --git a/tests/regex/password_complexity_test.php b/tests/regex/password_complexity_test.php index 07453555ee..e2aefdaac8 100644 --- a/tests/regex/password_complexity_test.php +++ b/tests/regex/password_complexity_test.php @@ -7,6 +7,7 @@ * */ +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php'; class phpbb_password_complexity_test extends phpbb_test_case diff --git a/tests/search/native_test.php b/tests/search/native_test.php index 18c6df2445..e860a4f89a 100644 --- a/tests/search/native_test.php +++ b/tests/search/native_test.php @@ -106,17 +106,66 @@ class phpbb_search_native_test extends phpbb_search_test_case array( '-foo', 'all', - false, - null, - null, + true, + array(), + array(1), array(), ), array( '-foo -bar', 'all', - false, - null, - null, + true, + array(), + array(1, 2), + array(), + ), + array( + 'foo -foo', + 'all', + true, + array(1), + array(1), + array(), + ), + array( + '-foo foo', + 'all', + true, + array(1), + array(1), + array(), + ), + // some creative edge cases + array( + 'foo foo-', + 'all', + true, + array(1), + array(), + array(), + ), + array( + 'foo- foo', + 'all', + true, + array(1), + array(), + array(), + ), + array( + 'foo-bar', + 'all', + true, + array(1, 2), + array(), + array(), + ), + array( + 'foo-bar-foo', + 'all', + true, + array(1, 2), + array(), array(), ), // all common diff --git a/tests/security/base.php b/tests/security/base.php index 8cd24ff145..3ab2d1cfec 100644 --- a/tests/security/base.php +++ b/tests/security/base.php @@ -14,7 +14,7 @@ abstract class phpbb_security_test_base extends phpbb_test_case */ protected function setUp() { - global $user, $phpbb_root_path, $request; + global $user, $phpbb_root_path, $phpEx, $request, $symfony_request, $phpbb_filesystem; // Put this into a global function being run by every test to init a proper user session $server['HTTP_HOST'] = 'localhost'; @@ -37,6 +37,22 @@ abstract class phpbb_security_test_base extends phpbb_test_case */ $request = new phpbb_mock_request(array(), array(), array(), $server); + $symfony_request = $this->getMock("\phpbb\symfony_request", array(), array( + $request, + )); + $symfony_request->expects($this->any()) + ->method('getScriptName') + ->will($this->returnValue($server['SCRIPT_NAME'])); + $symfony_request->expects($this->any()) + ->method('getQueryString') + ->will($this->returnValue($server['QUERY_STRING'])); + $symfony_request->expects($this->any()) + ->method('getBasePath') + ->will($this->returnValue($server['REQUEST_URI'])); + $symfony_request->expects($this->any()) + ->method('getPathInfo') + ->will($this->returnValue('/')); + $phpbb_filesystem = new \phpbb\filesystem($symfony_request, $phpbb_root_path, $phpEx); // Set no user and trick a bit to circumvent errors $user = new \phpbb\user(); diff --git a/tests/security/extract_current_page_test.php b/tests/security/extract_current_page_test.php index e42f446b31..1284aab94c 100644 --- a/tests/security/extract_current_page_test.php +++ b/tests/security/extract_current_page_test.php @@ -26,13 +26,23 @@ class phpbb_security_extract_current_page_test extends phpbb_security_test_base */ public function test_query_string_php_self($url, $query_string, $expected) { - global $request; + global $symfony_request, $request; - $request->merge(\phpbb\request\request_interface::SERVER, array( - 'PHP_SELF' => $url, - 'QUERY_STRING' => $query_string, + $symfony_request = $this->getMock("\phpbb\symfony_request", array(), array( + $request, )); - + $symfony_request->expects($this->any()) + ->method('getScriptName') + ->will($this->returnValue($url)); + $symfony_request->expects($this->any()) + ->method('getQueryString') + ->will($this->returnValue($query_string)); + $symfony_request->expects($this->any()) + ->method('getBasePath') + ->will($this->returnValue($server['REQUEST_URI'])); + $symfony_request->expects($this->any()) + ->method('getPathInfo') + ->will($this->returnValue('/')); $result = \phpbb\session::extract_current_page('./'); $label = 'Running extract_current_page on ' . $query_string . ' with PHP_SELF filled.'; @@ -44,12 +54,23 @@ class phpbb_security_extract_current_page_test extends phpbb_security_test_base */ public function test_query_string_request_uri($url, $query_string, $expected) { - global $request; + global $symfony_request, $request; - $request->merge(\phpbb\request\request_interface::SERVER, array( - 'PHP_SELF' => $url, - 'QUERY_STRING' => $query_string, + $symfony_request = $this->getMock("\phpbb\symfony_request", array(), array( + $request, )); + $symfony_request->expects($this->any()) + ->method('getScriptName') + ->will($this->returnValue($url)); + $symfony_request->expects($this->any()) + ->method('getQueryString') + ->will($this->returnValue($query_string)); + $symfony_request->expects($this->any()) + ->method('getBasePath') + ->will($this->returnValue($server['REQUEST_URI'])); + $symfony_request->expects($this->any()) + ->method('getPathInfo') + ->will($this->returnValue('/')); $result = \phpbb\session::extract_current_page('./'); @@ -57,4 +78,3 @@ class phpbb_security_extract_current_page_test extends phpbb_security_test_base $this->assertEquals($expected, $result['query_string'], $label); } } - diff --git a/tests/security/hash_test.php b/tests/security/hash_test.php index e226365ef3..32aa234316 100644 --- a/tests/security/hash_test.php +++ b/tests/security/hash_test.php @@ -7,10 +7,35 @@ * */ -require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_compatibility.php'; class phpbb_security_hash_test extends phpbb_test_case { + public function setUp() + { + global $phpbb_container; + + $config = new \phpbb\config\config(array()); + $phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $driver_helper = new \phpbb\passwords\driver\helper($config); + $passwords_drivers = array( + 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $driver_helper), + 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $driver_helper), + 'passwords.driver.salted_md5' => new \phpbb\passwords\driver\salted_md5($config, $driver_helper), + 'passwords.driver.phpass' => new \phpbb\passwords\driver\phpass($config, $driver_helper), + ); + + $passwords_helper = new \phpbb\passwords\helper; + // Set up passwords manager + $passwords_manager = new \phpbb\passwords\manager($config, $passwords_drivers, $passwords_helper, array_keys($passwords_drivers)); + + $phpbb_container + ->expects($this->any()) + ->method('get') + ->with('passwords.manager') + ->will($this->returnValue($passwords_manager)); + } + public function test_check_hash_with_phpass() { $this->assertTrue(phpbb_check_hash('test', '$H$9isfrtKXWqrz8PvztXlL3.daw4U0zI1')); diff --git a/tests/security/redirect_test.php b/tests/security/redirect_test.php index 8e36780ca4..e5ff3b1541 100644 --- a/tests/security/redirect_test.php +++ b/tests/security/redirect_test.php @@ -13,19 +13,59 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; class phpbb_security_redirect_test extends phpbb_security_test_base { + protected $path_helper; + public function provider() { // array(Input -> redirect(), expected triggered error (else false), expected returned result url (else false)) return array( - array('data://x', false, 'http://localhost/phpBB'), - array('bad://localhost/phpBB/index.php', 'INSECURE_REDIRECT', false), - array('http://www.otherdomain.com/somescript.php', false, 'http://localhost/phpBB'), - array("http://localhost/phpBB/memberlist.php\n\rConnection: close", 'INSECURE_REDIRECT', false), - array('javascript:test', false, 'http://localhost/phpBB/../javascript:test'), - array('http://localhost/phpBB/index.php;url=', 'INSECURE_REDIRECT', false), + array('data://x', false, false, 'http://localhost/phpBB'), + array('bad://localhost/phpBB/index.php', false, 'INSECURE_REDIRECT', false), + array('http://www.otherdomain.com/somescript.php', false, false, 'http://localhost/phpBB'), + array("http://localhost/phpBB/memberlist.php\n\rConnection: close", false, 'INSECURE_REDIRECT', false), + array('javascript:test', false, false, 'http://localhost/phpBB/javascript:test'), + array('http://localhost/phpBB/index.php;url=', false, 'INSECURE_REDIRECT', false), + array('http://localhost/phpBB/app.php/foobar', false, false, 'http://localhost/phpBB/app.php/foobar'), + array('./app.php/foobar', false, false, 'http://localhost/phpBB/app.php/foobar'), + array('app.php/foobar', false, false, 'http://localhost/phpBB/app.php/foobar'), + array('./../app.php/foobar', false, false, 'http://localhost/app.php/foobar'), + array('./../app.php/foobar', true, false, 'http://localhost/app.php/foobar'), + array('./../app.php/foo/bar', false, false, 'http://localhost/app.php/foo/bar'), + array('./../app.php/foo/bar', true, false, 'http://localhost/app.php/foo/bar'), + array('./../foo/bar', false, false, 'http://localhost/foo/bar'), + array('./../foo/bar', true, false, 'http://localhost/foo/bar'), + array('app.php/', false, false, 'http://localhost/phpBB/app.php/'), + array('app.php/a', false, false, 'http://localhost/phpBB/app.php/a'), + array('app.php/a/b', false, false, 'http://localhost/phpBB/app.php/a/b'), + array('./app.php/', false, false, 'http://localhost/phpBB/app.php/'), + array('foobar', false, false, 'http://localhost/phpBB/foobar'), + array('./foobar', false, false, 'http://localhost/phpBB/foobar'), + array('foo/bar', false, false, 'http://localhost/phpBB/foo/bar'), + array('./foo/bar', false, false, 'http://localhost/phpBB/foo/bar'), + array('./../index.php', false, false, 'http://localhost/index.php'), + array('./../index.php', true, false, 'http://localhost/index.php'), + array('../index.php', false, false, 'http://localhost/index.php'), + array('../index.php', true, false, 'http://localhost/index.php'), + array('./index.php', false, false, 'http://localhost/phpBB/index.php'), ); } + protected function get_path_helper() + { + if (!($this->path_helper instanceof \phpbb\path_helper)) + { + $this->path_helper = new \phpbb\path_helper( + new \phpbb\symfony_request( + new phpbb_mock_request() + ), + new \phpbb\filesystem(), + $this->phpbb_root_path, + 'php' + ); + } + return $this->path_helper; + } + protected function setUp() { parent::setUp(); @@ -33,26 +73,40 @@ class phpbb_security_redirect_test extends phpbb_security_test_base $GLOBALS['config'] = array( 'force_server_vars' => '0', ); + + $this->path_helper = $this->get_path_helper(); } /** * @dataProvider provider */ - public function test_redirect($test, $expected_error, $expected_result) + public function test_redirect($test, $disable_cd_check, $expected_error, $expected_result) { - global $user; + global $user, $phpbb_root_path, $phpbb_path_helper; + + $phpbb_path_helper = $this->path_helper; + + $temp_phpbb_root_path = $phpbb_root_path; + $temp_page_dir = $user->page['page_dir']; + // We need to hack phpbb_root_path and the user's page_dir here + // so it matches the actual fileinfo of the testing script. + // Otherwise the paths are returned incorrectly. + $phpbb_root_path = ''; + $user->page['page_dir'] = ''; if ($expected_error !== false) { $this->setExpectedTriggerError(E_USER_ERROR, $expected_error); } - $result = redirect($test, true); + $result = redirect($test, true, $disable_cd_check); // only verify result if we did not expect an error if ($expected_error === false) { $this->assertEquals($expected_result, $result); } + $phpbb_root_path = $temp_phpbb_root_path; + $user->page['page_dir'] = $temp_page_dir; } } diff --git a/tests/session/extract_page_test.php b/tests/session/extract_page_test.php index f4ae8de021..6e137e28b8 100644 --- a/tests/session/extract_page_test.php +++ b/tests/session/extract_page_test.php @@ -24,6 +24,7 @@ class phpbb_session_extract_page_test extends phpbb_session_test_case '/phpBB/index.php', '', '/phpBB/', + '/', array( 'page_name' => 'index.php', 'page_dir' => '', @@ -38,7 +39,8 @@ class phpbb_session_extract_page_test extends phpbb_session_test_case './', '/phpBB/ucp.php', 'mode=login', - '/phpBB/ucp.php?mode=login', + '/phpBB/', + '/', array( 'page_name' => 'ucp.php', 'page_dir' => '', @@ -53,7 +55,8 @@ class phpbb_session_extract_page_test extends phpbb_session_test_case './', '/phpBB/ucp.php', 'mode=register', - '/phpBB/ucp.php?mode=register', + '/phpBB/', + '/', array( 'page_name' => 'ucp.php', 'page_dir' => '', @@ -68,7 +71,8 @@ class phpbb_session_extract_page_test extends phpbb_session_test_case './', '/phpBB/ucp.php', 'mode=register', - '/phpBB/ucp.php?mode=register', + '/phpBB/', + '/', array( 'page_name' => 'ucp.php', 'page_dir' => '', @@ -83,30 +87,76 @@ class phpbb_session_extract_page_test extends phpbb_session_test_case './../', '/phpBB/adm/index.php', 'sid=e7215d958cdd41a6fc13509bebe53e42', - '/phpBB/adm/index.php?sid=e7215d958cdd41a6fc13509bebe53e42', + '/phpBB/adm/', + '/', array( 'page_name' => 'index.php', //'page_dir' => 'adm', // ^-- Ignored because .. returns different directory in live vs testing 'query_string' => '', 'script_path' => '/phpBB/adm/', - 'root_script_path' => '/phpBB/', + //'root_script_path' => '/phpBB/', //'page' => 'adm/index.php', 'forum' => 0, ), ), + array( + './', + '/phpBB/adm/app.php', + 'page=1&test=2', + '/phpBB/', + '/foo/bar', + array( + 'page_name' => 'app.php/foo/bar', + 'page_dir' => '', + 'query_string' => 'page=1&test=2', + 'script_path' => '/phpBB/', + 'root_script_path' => '/phpBB/', + 'page' => 'app.php/foo/bar?page=1&test=2', + 'forum' => 0, + ), + ), + array( + './../phpBB/', + '/test/test.php', + 'page=1&test=2', + '/test/', + '', + array( + 'page_name' => 'test.php', + //'page_dir' => '', + 'query_string' => 'page=1&test=2', + 'script_path' => '/test/', + //'root_script_path' => '../phpBB/', + //'page' => '../test/test.php/foo/bar?page=1&test=2', + 'forum' => 0, + ), + ), ); } /** @dataProvider extract_current_page_data */ - function test_extract_current_page($root_path, $php_self, $query_string, $request_uri, $expected) + function test_extract_current_page($root_path, $getScriptName, $getQueryString, $getBasePath, $getPathInfo, $expected) { - $output = $this->session_facade->extract_current_page( - $root_path, - $php_self, - $query_string, - $request_uri - ); + global $symfony_request; + + $symfony_request = $this->getMock("\phpbb\symfony_request", array(), array( + new phpbb_mock_request(), + )); + $symfony_request->expects($this->any()) + ->method('getScriptName') + ->will($this->returnValue($getScriptName)); + $symfony_request->expects($this->any()) + ->method('getQueryString') + ->will($this->returnValue($getQueryString)); + $symfony_request->expects($this->any()) + ->method('getBasePath') + ->will($this->returnValue($getBasePath)); + $symfony_request->expects($this->any()) + ->method('getPathInfo') + ->will($this->returnValue($getPathInfo)); + + $output = \phpbb\session::extract_current_page($root_path); // This compares the result of the output. // Any keys that are not in the expected array are overwritten by the output (aka not checked). diff --git a/tests/session/fixtures/sessions_banlist.xml b/tests/session/fixtures/sessions_banlist.xml index 9422fc0665..e720e35f0a 100644 --- a/tests/session/fixtures/sessions_banlist.xml +++ b/tests/session/fixtures/sessions_banlist.xml @@ -5,15 +5,11 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>anonymous</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_sessions"> diff --git a/tests/session/fixtures/sessions_empty.xml b/tests/session/fixtures/sessions_empty.xml index 0e6ddccd88..2acba58f45 100644 --- a/tests/session/fixtures/sessions_empty.xml +++ b/tests/session/fixtures/sessions_empty.xml @@ -5,31 +5,23 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>anonymous</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> <value>foo</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>4</value> <value>bar</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_sessions"> diff --git a/tests/session/fixtures/sessions_full.xml b/tests/session/fixtures/sessions_full.xml index 6bbaf1c9d5..4fb6b9dfd4 100644 --- a/tests/session/fixtures/sessions_full.xml +++ b/tests/session/fixtures/sessions_full.xml @@ -5,31 +5,23 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value>anonymous</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> <value>foo</value> <value></value> <value></value> - <value></value> - <value></value> </row> <row> <value>4</value> <value>bar</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_sessions"> diff --git a/tests/session/fixtures/sessions_garbage.xml b/tests/session/fixtures/sessions_garbage.xml index 23c44a975b..5eace839d0 100644 --- a/tests/session/fixtures/sessions_garbage.xml +++ b/tests/session/fixtures/sessions_garbage.xml @@ -5,15 +5,11 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>4</value> <value>bar</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> <table name="phpbb_sessions"> diff --git a/tests/session/fixtures/sessions_key.xml b/tests/session/fixtures/sessions_key.xml index 246d284557..4f349cd282 100644 --- a/tests/session/fixtures/sessions_key.xml +++ b/tests/session/fixtures/sessions_key.xml @@ -30,15 +30,11 @@ <column>username_clean</column> <column>user_permissions</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>4</value> <value>bar</value> <value></value> <value></value> - <value></value> - <value></value> </row> </table> </dataset> diff --git a/tests/session/testable_facade.php b/tests/session/testable_facade.php index f289c48f69..2600a46cc4 100644 --- a/tests/session/testable_facade.php +++ b/tests/session/testable_facade.php @@ -33,21 +33,6 @@ class phpbb_session_testable_facade $this->session_factory = $session_factory; } - function extract_current_page( - $root_path, - $php_self, - $query_string, - $request_uri - ) - { - $this->session_factory->get_session($this->db); - global $request; - $request->overwrite('PHP_SELF', $php_self, \phpbb\request\request_interface::SERVER); - $request->overwrite('QUERY_STRING', $query_string, \phpbb\request\request_interface::SERVER); - $request->overwrite('REQUEST_URI', $request_uri, \phpbb\request\request_interface::SERVER); - return \phpbb\session::extract_current_page($root_path); - } - function extract_current_hostname( $host, $server_name_config, @@ -139,4 +124,3 @@ class phpbb_session_testable_facade return $session->validate_referer($check_script_path); } } - diff --git a/tests/session/testable_factory.php b/tests/session/testable_factory.php index a58e208efc..c968012edf 100644 --- a/tests/session/testable_factory.php +++ b/tests/session/testable_factory.php @@ -63,10 +63,10 @@ class phpbb_session_testable_factory /** * Retrieve the configured session class instance * - * @param \phpbb\db\driver\driver $dbal The database connection to use for session data + * @param \phpbb\db\driver\driver_interface $dbal The database connection to use for session data * @return phpbb_mock_session_testable A session instance */ - public function get_session(\phpbb\db\driver\driver $dbal) + public function get_session(\phpbb\db\driver\driver_interface $dbal) { // set up all the global variables used by session global $SID, $_SID, $db, $config, $cache, $request, $phpbb_container; diff --git a/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/event/test_event_subloop.html b/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/event/test_event_subloop.html new file mode 100644 index 0000000000..4fdba859f3 --- /dev/null +++ b/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/event/test_event_subloop.html @@ -0,0 +1,2 @@ +[{event_loop.S_ROW_COUNT}<!-- BEGIN subloop -->[subloop:{event_loop.subloop.S_ROW_COUNT}] +<!-- END subloop -->] diff --git a/tests/template/datasets/ext_trivial/styles/silver/template/event_subloop.html b/tests/template/datasets/ext_trivial/styles/silver/template/event_subloop.html new file mode 100644 index 0000000000..233b32a4c7 --- /dev/null +++ b/tests/template/datasets/ext_trivial/styles/silver/template/event_subloop.html @@ -0,0 +1,3 @@ +<!-- BEGIN event_loop --> +event_loop<!-- EVENT test_event_subloop --> +<!-- END event_loop --> diff --git a/tests/template/template_events_test.php b/tests/template/template_events_test.php index 41e00e86a7..d09f22944f 100644 --- a/tests/template/template_events_test.php +++ b/tests/template/template_events_test.php @@ -90,14 +90,33 @@ Zeta test event in all', array(), 'event_loop0|event_loop1|event_loop2', ), + array( + 'EVENT with subloop in loop', + 'ext_trivial', + array('silver'), + 'event_subloop.html', + array(), + array( + 'event_loop' => array(array()), + 'event_loop.subloop' => array(array()), + ), + array(), + 'event_loop[0[subloop:0]]', + 'Event files are missing opened parent loops: PHPBB3-12382', + ), ); } /** * @dataProvider template_data */ - public function test_event($desc, $dataset, $style_names, $file, array $vars, array $block_vars, array $destroy, $expected) + public function test_event($desc, $dataset, $style_names, $file, array $vars, array $block_vars, array $destroy, $expected, $incomplete_message = '') { + if ($incomplete_message) + { + $this->markTestIncomplete($incomplete_message); + } + // Reset the engine state $this->setup_engine_for_events($dataset, $style_names); diff --git a/tests/template/template_includecss_test.php b/tests/template/template_includecss_test.php index 7424af0c93..9ed8bd0947 100644 --- a/tests/template/template_includecss_test.php +++ b/tests/template/template_includecss_test.php @@ -18,8 +18,8 @@ class phpbb_template_template_includecss_test extends phpbb_template_template_te // Prepare correct result $scripts = array( - '<link href="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/child_only.css?assets_version=1" rel="stylesheet" type="text/css" media="screen, projection" />', - '<link href="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/parent_templates/parent_only.css?assets_version=1" rel="stylesheet" type="text/css" media="screen, projection" />', + '<link href="tests/template/templates/child_only.css?assets_version=1" rel="stylesheet" type="text/css" media="screen, projection" />', + '<link href="tests/template/parent_templates/parent_only.css?assets_version=1" rel="stylesheet" type="text/css" media="screen, projection" />', ); // Run test diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index ab0f4b9ca1..b20d068a64 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -24,51 +24,51 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes */ array( array('TEST' => 1), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/parent_and_child.js?assets_version=1"></script>', + '<script type="text/javascript" src="tests/template/templates/parent_and_child.js?assets_version=1"></script>', ), array( array('TEST' => 2), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/parent_and_child.js?assets_version=0"></script>', + '<script type="text/javascript" src="tests/template/templates/parent_and_child.js?assets_version=0"></script>', ), array( array('TEST' => 3), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/parent_and_child.js?test=1&assets_version=0"></script>', + '<script type="text/javascript" src="tests/template/templates/parent_and_child.js?test=1&assets_version=0"></script>', ), array( array('TEST' => 4), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/parent_and_child.js?test=1&assets_version=0"></script>', + '<script type="text/javascript" src="tests/template/templates/parent_and_child.js?test=1&assets_version=0"></script>', ), array( array('TEST' => 6), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/parent_templates/parent_only.js?assets_version=1"></script>', + '<script type="text/javascript" src="tests/template/parent_templates/parent_only.js?assets_version=1"></script>', ), array( array('TEST' => 7), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/child_only.js?assets_version=1"></script>', + '<script type="text/javascript" src="tests/template/templates/child_only.js?assets_version=1"></script>', ), array( array('TEST' => 8), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/subdir/parent_only.js?assets_version=1"></script>', + '<script type="text/javascript" src="tests/template/templates/subdir/parent_only.js?assets_version=1"></script>', ), array( array('TEST' => 9), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/subdir/subsubdir/parent_only.js?assets_version=1"></script>', + '<script type="text/javascript" src="tests/template/templates/subdir/subsubdir/parent_only.js?assets_version=1"></script>', ), array( array('TEST' => 10), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/subdir/parent_only.js?assets_version=1"></script>', + '<script type="text/javascript" src="tests/template/templates/subdir/parent_only.js?assets_version=1"></script>', ), array( array('TEST' => 11), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/child_only.js?test1=1&test2=2&assets_version=1#test3"></script>', + '<script type="text/javascript" src="tests/template/templates/child_only.js?test1=1&test2=2&assets_version=1#test3"></script>', ), array( array('TEST' => 12), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/parent_templates/parent_only.js?test1=1&test2=2&assets_version=1#test3"></script>', + '<script type="text/javascript" src="tests/template/parent_templates/parent_only.js?test1=1&test2=2&assets_version=1#test3"></script>', ), array( array('TEST' => 14), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/parent_templates/parent_only.js?test1="&assets_version=1#test3"></script>', + '<script type="text/javascript" src="tests/template/parent_templates/parent_only.js?test1="&assets_version=1#test3"></script>', ), array( array('TEST' => 15), @@ -84,7 +84,7 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes ), array( array('TEST' => 18), - '<script type="text/javascript" src="' . $this->phpbb_path_helper->get_web_root_path() . 'tests/template/templates/parent_and_child.js?test=1&test2=0&assets_version=1"></script>', + '<script type="text/javascript" src="tests/template/templates/parent_and_child.js?test=1&test2=0&assets_version=1"></script>', ), ); } diff --git a/tests/template/template_test.php b/tests/template/template_test.php index 39eb08ab79..49804c26c5 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -91,6 +91,13 @@ class phpbb_template_template_test extends phpbb_template_template_test_case '03!false', ), array( + 'if.html', + array('VALUE_TEST' => 'value'), + array(), + array(), + '03!falsevalue', + ), + array( 'loop.html', array(), array(), @@ -158,7 +165,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), array('test_loop' => array(array(), array(), array(), array(), array(), array(), array()), 'test' => array(array()), 'test.deep' => array(array()), 'test.deep.defines' => array(array())), array(), - "xyz\nabc\n\$VALUE == 'abc'\n(\$VALUE == 'abc')\n((\$VALUE == 'abc'))\n!\$DOESNT_EXIST\n(!\$DOESNT_EXIST)\nabc\nbar\nbar\nabc\ntest!@#$%^&*()_-=+{}[]:;\",<.>/?[]|foobar|", + "xyz\nabc\n\$VALUE == 'abc'\n(\$VALUE == 'abc')\n((\$VALUE == 'abc'))\n!\$DOESNT_EXIST\n(!\$DOESNT_EXIST)\nabc\nbar\nbar\nabc\ntest!@#$%^&*()_-=+{}[]:;\",<.>/?[]|foobar|false", ), array( 'define_advanced.html', @@ -306,6 +313,25 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), "nonexistent = 0\n! nonexistent\n\nempty = 0\n! empty\nloop\n\nin loop", ), + array( + 'loop_include.html', + array(), + array('test_loop' => array(array('foo' => 'bar'), array('foo' => 'bar1'))), + array(), + "barbarbar1bar1", + ), + array( + 'loop_nested_include.html', + array(), + array( + 'test_loop' => array(array('foo' => 'bar'), array('foo' => 'bar1')), + 'test_loop.inner' => array(array('myinner' => 'works')), + ), + array(), + "[bar|[bar|]][bar1|[bar1|[bar1|works]]]", + array(), + 'Included files are missing opened parent loops: PHPBB3-12382', + ), /* Does not pass with the current implementation. array( 'loop_reuse.html', @@ -349,8 +375,13 @@ class phpbb_template_template_test extends phpbb_template_template_test_case /** * @dataProvider template_data */ - public function test_template($file, array $vars, array $block_vars, array $destroy, $expected, $lang_vars = array()) + public function test_template($file, array $vars, array $block_vars, array $destroy, $expected, $lang_vars = array(), $incomplete_message = '') { + if ($incomplete_message) + { + $this->markTestIncomplete($incomplete_message); + } + $this->run_template($file, $vars, $block_vars, $destroy, $expected, $lang_vars); } @@ -561,4 +592,46 @@ EOT $expect = 'outer - 0[outer|4]outer - 1[outer|4]middle - 0[middle|1]outer - 2 - test[outer|4]middle - 0[middle|2]middle - 1[middle|2]outer - 3[outer|4]middle - 0[middle|3]middle - 1[middle|3]middle - 2[middle|3]'; $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring S_NUM_ROWS is correct after modification'); } + + public function assign_block_vars_array_data() + { + return array( + array( + array( + 'outer' => array( + array('VARIABLE' => 'Test assigning block vars array loop 0:'), + array('VARIABLE' => 'Test assigning block vars array loop 1:'), + ), + 'outer.middle' => array( + array('VARIABLE' => '1st iteration',), + array('VARIABLE' => '2nd iteration',), + array('VARIABLE' => '3rd iteration',), + ), + ) + ) + ); + } + + /** + * @dataProvider assign_block_vars_array_data + */ + public function test_assign_block_vars_array($block_data) + { + $this->template->set_filenames(array('test' => 'loop_nested.html')); + + foreach ($block_data as $blockname => $block_vars_array) + { + $this->template->assign_block_vars_array($blockname, $block_vars_array); + } + + $this->assertEquals("outer - 0 - Test assigning block vars array loop 0:outer - 1 - Test assigning block vars array loop 1:middle - 0 - 1st iterationmiddle - 1 - 2nd iterationmiddle - 2 - 3rd iteration", $this->display('test'), 'Ensuring assigning block vars array to template is working correctly'); + } + + /** + * @expectedException Twig_Error_Syntax + */ + public function test_define_error() + { + $this->run_template('define_error.html', array(), array(), array(), ''); + } } diff --git a/tests/template/templates/define.html b/tests/template/templates/define.html index e7ce7f7def..276d2ebb99 100644 --- a/tests/template/templates/define.html +++ b/tests/template/templates/define.html @@ -29,3 +29,9 @@ $VALUE == 'abc' <!-- DEFINE $VALUE = '' --> [{$VALUE}] <!-- DEFINE $TEST -->foobar<!-- ENDDEFINE -->|{$TEST}| +<!-- DEFINE $VAR = false --> +<!-- IF $VAR --> +true +<!-- ELSE --> +false +<!-- ENDIF --> diff --git a/tests/template/templates/define_error.html b/tests/template/templates/define_error.html new file mode 100644 index 0000000000..72ab1ba033 --- /dev/null +++ b/tests/template/templates/define_error.html @@ -0,0 +1,2 @@ +<!-- DEFINE $VAR = foo --> +{$VAR} diff --git a/tests/template/templates/if.html b/tests/template/templates/if.html index f6ab6e575a..71312f994c 100644 --- a/tests/template/templates/if.html +++ b/tests/template/templates/if.html @@ -19,3 +19,7 @@ false <!-- IF S_TEST !== false --> !false <!-- ENDIF --> + +<!-- IF VALUE_TEST is defined --> +{VALUE_TEST} +<!-- ENDIF --> diff --git a/tests/template/templates/loop_include.html b/tests/template/templates/loop_include.html new file mode 100644 index 0000000000..7bbdfc4248 --- /dev/null +++ b/tests/template/templates/loop_include.html @@ -0,0 +1,4 @@ +<!-- BEGIN test_loop --> +{test_loop.foo} + <!-- INCLUDE loop_include1.html --> +<!-- END test_loop --> diff --git a/tests/template/templates/loop_include1.html b/tests/template/templates/loop_include1.html new file mode 100644 index 0000000000..851f6e6e75 --- /dev/null +++ b/tests/template/templates/loop_include1.html @@ -0,0 +1 @@ +{test_loop.foo} diff --git a/tests/template/templates/loop_nested_include.html b/tests/template/templates/loop_nested_include.html new file mode 100644 index 0000000000..eaad46cc5b --- /dev/null +++ b/tests/template/templates/loop_nested_include.html @@ -0,0 +1,4 @@ +<!-- BEGIN test_loop --> +[{test_loop.foo} + |<!-- INCLUDE loop_nested_include1.html -->] +<!-- END test_loop --> diff --git a/tests/template/templates/loop_nested_include1.html b/tests/template/templates/loop_nested_include1.html new file mode 100644 index 0000000000..0f1a180b4d --- /dev/null +++ b/tests/template/templates/loop_nested_include1.html @@ -0,0 +1,5 @@ +[{test_loop.foo}| +<!-- BEGIN inner --> +[{test_loop.foo}| +{test_loop.inner.myinner}] +<!-- END inner -->] diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index 4c2e9ff600..aacdb1bef4 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -138,7 +138,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test if (!self::$already_connected) { - $manager->load_schema(); + $manager->load_schema($this->new_dbal()); self::$already_connected = true; } diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index af9bd22662..887dad5b50 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -12,8 +12,11 @@ require_once dirname(__FILE__) . '/phpbb_database_connection_odbc_pdo_wrapper.ph class phpbb_database_test_connection_manager { + /** @var array */ private $config; + /** @var array */ private $dbms; + /** @var \PDO */ private $pdo; /** @@ -169,12 +172,12 @@ class phpbb_database_test_connection_manager /** * Load the phpBB database schema into the database */ - public function load_schema() + public function load_schema($db) { $this->ensure_connected(__METHOD__); $directory = dirname(__FILE__) . '/../../phpBB/install/schemas/'; - $this->load_schema_from_file($directory); + $this->load_schema_from_file($directory, $db); } /** @@ -321,7 +324,7 @@ class phpbb_database_test_connection_manager * Compile the correct schema filename (as per create_schema_files) and * load it into the database. */ - protected function load_schema_from_file($directory) + protected function load_schema_from_file($directory, \phpbb\db\driver\driver_interface $db) { $schema = $this->dbms['SCHEMA']; @@ -351,6 +354,35 @@ class phpbb_database_test_connection_manager { $this->pdo->exec($query); } + + // Ok we have the db info go ahead and work on building the table + $db_table_schema = file_get_contents($directory . 'schema.json'); + $db_table_schema = json_decode($db_table_schema, true); + + $db_tools = new \phpbb\db\tools($db, true); + foreach ($db_table_schema as $table_name => $table_data) + { + $queries = $db_tools->sql_create_table( + $table_name, + $table_data + ); + + foreach ($queries as $query) + { + if ($query === 'begin') + { + $this->pdo->beginTransaction(); + } + else if ($query === 'commit') + { + $this->pdo->commit(); + } + else + { + $this->pdo->exec($query); + } + } + } } /** diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index a0d186e0f2..3759097319 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -150,7 +150,7 @@ class phpbb_functional_test_case extends phpbb_test_case { global $phpbb_root_path, $phpEx; // so we don't reopen an open connection - if (!($this->db instanceof \phpbb\db\driver\driver)) + if (!($this->db instanceof \phpbb\db\driver\driver_interface)) { $dbms = self::$config['dbms']; $this->db = new $dbms(); @@ -192,9 +192,10 @@ class phpbb_functional_test_case extends phpbb_test_case $db_tools, self::$config['table_prefix'] . 'migrations', $phpbb_root_path, - $php_ext, + $phpEx, self::$config['table_prefix'], - array() + array(), + new \phpbb\db\migration\helper() ); $container = new phpbb_mock_container_builder(); $container->set('migrator', $migrator); @@ -206,7 +207,7 @@ class phpbb_functional_test_case extends phpbb_test_case new phpbb\filesystem(), self::$config['table_prefix'] . 'ext', dirname(__FILE__) . '/', - $php_ext, + $phpEx, $this->get_cache_driver() ); @@ -299,7 +300,7 @@ class phpbb_functional_test_case extends phpbb_test_case // because that step will create a config.php file if phpBB has the // permission to do so. We have to create the config file on our own // in order to get the DEBUG constants defined. - $config_php_data = phpbb_create_config_file_data(self::$config, self::$config['dbms'], true, true); + $config_php_data = phpbb_create_config_file_data(self::$config, self::$config['dbms'], true, false, true); $config_created = file_put_contents($config_file, $config_php_data) !== false; if (!$config_created) { @@ -421,7 +422,7 @@ class phpbb_functional_test_case extends phpbb_test_case } else { - $db->sql_multi_insert(STYLES_TABLE, array( + $db->sql_multi_insert(STYLES_TABLE, array(array( 'style_id' => $style_id, 'style_name' => $style_path, 'style_copyright' => '', @@ -430,7 +431,7 @@ class phpbb_functional_test_case extends phpbb_test_case 'bbcode_bitfield' => 'kNg=', 'style_parent_id' => $parent_style_id, 'style_parent_tree' => $parent_style_path, - )); + ))); } } @@ -472,6 +473,16 @@ class phpbb_functional_test_case extends phpbb_test_case global $config; $config = new \phpbb\config\config(array()); + + /* + * Add required config entries to the config array to prevent + * set_config() sending an INSERT query for already existing entries, + * resulting in a SQL error. + * This is because set_config() first sends an UPDATE query, then checks + * sql_affectedrows() which can be 0 (e.g. on MySQL) when the new + * data is already there. + */ + $config['newest_user_colour'] = ''; $config['rand_seed'] = ''; $config['rand_seed_last_update'] = time() + 600; @@ -503,6 +514,7 @@ class phpbb_functional_test_case extends phpbb_test_case set_config(null, null, null, $config); set_config_count(null, null, null, $config); $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $passwords_manager = $this->get_passwords_manager(); $user_row = array( 'username' => $username, @@ -510,9 +522,9 @@ class phpbb_functional_test_case extends phpbb_test_case 'user_email' => 'nobody@example.com', 'user_type' => 0, 'user_lang' => 'en', - 'user_timezone' => 0, - 'user_dateformat' => '', - 'user_password' => phpbb_hash($username . $username), + 'user_timezone' => 'UTC', + 'user_dateformat' => 'r', + 'user_password' => $passwords_manager->hash($username . $username), ); return user_add($user_row); } @@ -714,15 +726,27 @@ class phpbb_functional_test_case extends phpbb_test_case /** * assertContains for language strings * - * @param string $needle Search string - * @param string $haystack Search this - * @param string $message Optional failure message + * @param string $needle Search string + * @param string $haystack Search this + * @param string $message Optional failure message */ public function assertContainsLang($needle, $haystack, $message = null) { $this->assertContains(html_entity_decode($this->lang($needle), ENT_QUOTES), $haystack, $message); } + /** + * assertNotContains for language strings + * + * @param string $needle Search string + * @param string $haystack Search this + * @param string $message Optional failure message + */ + public function assertNotContainsLang($needle, $haystack, $message = null) + { + $this->assertNotContains(html_entity_decode($this->lang($needle), ENT_QUOTES), $haystack, $message); + } + /* * Perform some basic assertions for the page * @@ -868,9 +892,10 @@ class phpbb_functional_test_case extends phpbb_test_case * @param string $subject * @param string $message * @param array $additional_form_data Any additional form data to be sent in the request - * @return array post_id, topic_id + * @param string $expected Lang var of expected message after posting + * @return array|null post_id, topic_id if message is empty */ - public function create_topic($forum_id, $subject, $message, $additional_form_data = array()) + public function create_topic($forum_id, $subject, $message, $additional_form_data = array(), $expected = '') { $posting_url = "posting.php?mode=post&f={$forum_id}&sid={$this->sid}"; @@ -880,7 +905,7 @@ class phpbb_functional_test_case extends phpbb_test_case 'post' => true, ), $additional_form_data); - return self::submit_post($posting_url, 'POST_TOPIC', $form_data); + return self::submit_post($posting_url, 'POST_TOPIC', $form_data, $expected); } /** @@ -893,9 +918,10 @@ class phpbb_functional_test_case extends phpbb_test_case * @param string $subject * @param string $message * @param array $additional_form_data Any additional form data to be sent in the request - * @return array post_id, topic_id + * @param string $expected Lang var of expected message after posting + * @return array|null post_id, topic_id if message is empty */ - public function create_post($forum_id, $topic_id, $subject, $message, $additional_form_data = array()) + public function create_post($forum_id, $topic_id, $subject, $message, $additional_form_data = array(), $expected = '') { $posting_url = "posting.php?mode=reply&f={$forum_id}&t={$topic_id}&sid={$this->sid}"; @@ -905,7 +931,7 @@ class phpbb_functional_test_case extends phpbb_test_case 'post' => true, ), $additional_form_data); - return self::submit_post($posting_url, 'POST_REPLY', $form_data); + return self::submit_post($posting_url, 'POST_REPLY', $form_data, $expected); } /** @@ -914,15 +940,33 @@ class phpbb_functional_test_case extends phpbb_test_case * @param string $posting_url * @param string $posting_contains * @param array $form_data - * @return array post_id, topic_id + * @param string $expected Lang var of expected message after posting + * @return array|null post_id, topic_id if message is empty */ - protected function submit_post($posting_url, $posting_contains, $form_data) + protected function submit_post($posting_url, $posting_contains, $form_data, $expected = '') { $this->add_lang('posting'); $crawler = self::request('GET', $posting_url); $this->assertContains($this->lang($posting_contains), $crawler->filter('html')->text()); + if (!empty($form_data['upload_files'])) + { + for ($i = 0; $i < $form_data['upload_files']; $i++) + { + $file = array( + 'tmp_name' => __DIR__ . '/../functional/fixtures/files/valid.jpg', + 'name' => 'valid.jpg', + 'type' => 'image/jpeg', + 'size' => filesize(__DIR__ . '/../functional/fixtures/files/valid.jpg'), + 'error' => UPLOAD_ERR_OK, + ); + + $crawler = self::$client->request('POST', $posting_url, array('add_file' => $this->lang('ADD_FILE')), array('fileupload' => $file)); + } + unset($form_data['upload_files']); + } + $hidden_fields = array( $crawler->filter('[type="hidden"]')->each(function ($node, $i) { return array('name' => $node->attr('name'), 'value' => $node->attr('value')); @@ -945,8 +989,13 @@ class phpbb_functional_test_case extends phpbb_test_case // contained in one of the actual form fields that the browser sees (i.e. it ignores "hidden" inputs) // Instead, I send it as a request with the submit button "post" set to true. $crawler = self::request('POST', $posting_url, $form_data); - $this->assertContains($this->lang('POST_STORED'), $crawler->filter('html')->text()); - $url = $crawler->selectLink($this->lang('VIEW_MESSAGE', '', ''))->link()->getUri(); + + if ($expected !== '') + { + $this->assertContainsLang($expected, $crawler->filter('html')->text()); + return null; + } + $url = $crawler->selectLink($form_data['subject'])->link()->getUri(); return array( 'topic_id' => $this->get_parameter_from_link($url, 't'), @@ -955,6 +1004,52 @@ class phpbb_functional_test_case extends phpbb_test_case } /** + * Deletes a topic + * + * Be sure to login before creating + * + * @param int $topic_id + * @return null + */ + public function delete_topic($topic_id) + { + $crawler = self::request('GET', "viewtopic.php?t={$topic_id}&sid={$this->sid}"); + + $this->add_lang('posting'); + $form = $crawler->selectButton('Go')->eq(1)->form(); + $form['action']->select('delete_topic'); + $crawler = self::submit($form); + $this->assertContainsLang('DELETE_PERMANENTLY', $crawler->text()); + + $this->add_lang('mcp'); + $form = $crawler->selectButton('Yes')->form(); + $form['delete_permanent'] = 1; + $crawler = self::submit($form); + $this->assertContainsLang('TOPIC_DELETED_SUCCESS', $crawler->text()); + } + + /** + * Deletes a post + * + * Be sure to login before creating + * + * @param int $forum_id + * @param int $topic_id + * @return null + */ + public function delete_post($forum_id, $post_id) + { + $this->add_lang('posting'); + $crawler = self::request('GET', "posting.php?mode=delete&f={$forum_id}&p={$post_id}&sid={$this->sid}"); + $this->assertContainsLang('DELETE_PERMANENTLY', $crawler->text()); + + $form = $crawler->selectButton('Yes')->form(); + $form['delete_permanent'] = 1; + $crawler = self::submit($form); + $this->assertContainsLang('POST_DELETED', $crawler->text()); + } + + /** * Returns the requested parameter from a URL * * @param string $url @@ -989,4 +1084,29 @@ class phpbb_functional_test_case extends phpbb_test_case } return null; } + + /** + * Return a passwords manager instance + * + * @return phpbb\passwords\manager + */ + public function get_passwords_manager() + { + // Prepare dependencies for manager and driver + $config = new \phpbb\config\config(array()); + $driver_helper = new \phpbb\passwords\driver\helper($config); + + $passwords_drivers = array( + 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $driver_helper), + 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $driver_helper), + 'passwords.driver.salted_md5' => new \phpbb\passwords\driver\salted_md5($config, $driver_helper), + 'passwords.driver.phpass' => new \phpbb\passwords\driver\phpass($config, $driver_helper), + ); + + $passwords_helper = new \phpbb\passwords\helper; + // Set up passwords manager + $manager = new \phpbb\passwords\manager($config, $passwords_drivers, $passwords_helper, array_keys($passwords_drivers)); + + return $manager; + } } diff --git a/tests/test_framework/phpbb_session_test_case.php b/tests/test_framework/phpbb_session_test_case.php index e6a2b03bba..0a2f767845 100644 --- a/tests/test_framework/phpbb_session_test_case.php +++ b/tests/test_framework/phpbb_session_test_case.php @@ -19,6 +19,19 @@ abstract class phpbb_session_test_case extends phpbb_database_test_case function setUp() { parent::setUp(); + + global $symfony_request, $phpbb_filesystem, $phpbb_path_helper, $request, $phpbb_root_path, $phpEx; + $symfony_request = new \phpbb\symfony_request( + new phpbb_mock_request() + ); + $phpbb_filesystem = new \phpbb\filesystem(); + $phpbb_path_helper = new \phpbb\path_helper( + $symfony_request, + $phpbb_filesystem, + $phpbb_root_path, + $phpEx + ); + $this->session_factory = new phpbb_session_testable_factory; $this->db = $this->new_dbal(); $this->session_facade = diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index 351a3a9594..2f225fe7af 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -158,6 +158,11 @@ class phpbb_test_case_helpers { $config['redis_port'] = $phpbb_redis_port; } + + if (isset($fulltext_sphinx_id)) + { + $config['fulltext_sphinx_id'] = $fulltext_sphinx_id; + } } if (isset($_SERVER['PHPBB_TEST_DBMS'])) diff --git a/tests/text_processing/generate_text_for_display_test.php b/tests/text_processing/generate_text_for_display_test.php index a157fe7d9a..15905535ac 100644 --- a/tests/text_processing/generate_text_for_display_test.php +++ b/tests/text_processing/generate_text_for_display_test.php @@ -16,7 +16,7 @@ class phpbb_text_processing_generate_text_for_display_test extends phpbb_test_ca { public function setUp() { - global $cache, $user; + global $cache, $user, $phpbb_dispatcher; parent::setUp(); @@ -24,6 +24,8 @@ class phpbb_text_processing_generate_text_for_display_test extends phpbb_test_ca $user = new phpbb_mock_user; $user->optionset('viewcensors', false); + + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); } public function test_empty_string() diff --git a/tests/tree/nestedset_forum_get_data_test.php b/tests/tree/nestedset_forum_get_data_test.php index ca1863e55e..a0d0778e82 100644 --- a/tests/tree/nestedset_forum_get_data_test.php +++ b/tests/tree/nestedset_forum_get_data_test.php @@ -116,4 +116,20 @@ class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_ne $forum_data['forum_parents'] = $forum_parents; $this->assertEquals($expected, array_keys($this->set->get_path_basic_data($forum_data))); } + + public function get_all_tree_data_data() + { + return array( + array(true, array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)), + array(false, array(11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)), + ); + } + + /** + * @dataProvider get_all_tree_data_data + */ + public function test_get_all_tree_data($order_asc, $expected) + { + $this->assertEquals($expected, array_keys($this->set->get_all_tree_data($order_asc))); + } } diff --git a/tests/upload/filespec_test.php b/tests/upload/filespec_test.php index 87cd00197f..2d46fd4058 100644 --- a/tests/upload/filespec_test.php +++ b/tests/upload/filespec_test.php @@ -143,6 +143,8 @@ class phpbb_filespec_test extends phpbb_test_case $disallowed_content = explode('|', $this->config['mime_triggers']); $filespec = $this->get_filespec(array('tmp_name' => $this->path . $filename)); $this->assertEquals($expected, $filespec->check_content($disallowed_content)); + // All files should pass if $disallowed_content is empty + $this->assertEquals(true, $filespec->check_content(array())); } public function clean_filename_variables() @@ -271,4 +273,18 @@ class phpbb_filespec_test extends phpbb_test_case $phpEx = ''; } + + /** + * @dataProvider clean_filename_variables + */ + public function test_uploadname($filename) + { + $type_cast_helper = new \phpbb\request\type_cast_helper(); + + $upload_name = ''; + $type_cast_helper->set_var($upload_name, $filename, 'string', true, true); + $filespec = $this->get_filespec(array('name'=> $upload_name)); + + $this->assertSame(trim(utf8_basename(htmlspecialchars($filename))), $filespec->uploadname); + } } diff --git a/tests/user/fixtures/user_loader.xml b/tests/user/fixtures/user_loader.xml index 1fed8b5838..f676f468a6 100644 --- a/tests/user/fixtures/user_loader.xml +++ b/tests/user/fixtures/user_loader.xml @@ -6,16 +6,12 @@ <column>username</column> <column>username_clean</column> <column>user_sig</column> - <column>user_occ</column> - <column>user_interests</column> <row> <value>1</value> <value></value> <value>Guest</value> <value>guest</value> <value></value> - <value></value> - <value></value> </row> <row> <value>2</value> @@ -23,8 +19,6 @@ <value>Admin</value> <value>admin</value> <value></value> - <value></value> - <value></value> </row> <row> <value>3</value> @@ -32,8 +26,6 @@ <value>Test</value> <value>test</value> <value></value> - <value></value> - <value></value> </row> </table> </dataset> diff --git a/tests/user/lang_test.php b/tests/user/lang_test.php index c7c858c59d..9cb9e320b3 100644 --- a/tests/user/lang_test.php +++ b/tests/user/lang_test.php @@ -7,6 +7,8 @@ * */ +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + class phpbb_user_lang_test extends phpbb_test_case { public function test_user_lang_sprintf() diff --git a/tests/version/version_fetch_test.php b/tests/version/version_fetch_test.php new file mode 100644 index 0000000000..7b3ba5e717 --- /dev/null +++ b/tests/version/version_fetch_test.php @@ -0,0 +1,58 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/* +* @group slow +*/ +class phpbb_version_helper_fetch_test extends phpbb_test_case +{ + public function setUp() + { + parent::setUp(); + + global $phpbb_root_path, $phpEx; + + include_once($phpbb_root_path . 'includes/functions.' . $phpEx); + + $this->cache = $this->getMockBuilder('\phpbb\cache\service') + ->disableOriginalConstructor() + ->getMock(); + + $this->version_helper = new \phpbb\version_helper( + $this->cache, + new \phpbb\config\config(array( + 'version' => '3.1.0', + )), + new \phpbb\user() + ); + } + + public function test_version_phpbb_com() + { + global $phpbb_root_path, $phpEx; + include_once($phpbb_root_path . 'includes/functions.' . $phpEx); + + if (!phpbb_checkdnsrr('version.phpbb.com', 'A')) + { + $this->markTestSkipped(sprintf( + 'Could not find a DNS record for hostname %s. ' . + 'Assuming network is down.', + 'version.phpbb.com' + )); + } + + $this->version_helper->get_versions(); + + // get_versions checks to make sure we got a valid versions file or + // throws an exception if we did not. We don't need to test anything + // here, but adding an assertion so we do not get a warning about no + // assertions in this test + $this->assertSame(true, true); + } +} diff --git a/tests/version/version_test.php b/tests/version/version_test.php new file mode 100644 index 0000000000..2e2398bd45 --- /dev/null +++ b/tests/version/version_test.php @@ -0,0 +1,318 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_version_helper_test extends phpbb_test_case +{ + public function setUp() + { + parent::setUp(); + + global $phpbb_root_path, $phpEx; + + include_once($phpbb_root_path . 'includes/functions.' . $phpEx); + + $this->cache = $this->getMockBuilder('\phpbb\cache\service') + ->disableOriginalConstructor() + ->getMock(); + + $this->version_helper = new \phpbb\version_helper( + $this->cache, + new \phpbb\config\config(array( + 'version' => '3.1.0', + )), + new \phpbb\user() + ); + } + + public function is_stable_data() + { + return array( + array( + '3.0.0-a1', + false, + ), + array( + '3.0.0-b1', + false, + ), + array( + '3.0.0-rc1', + false, + ), + array( + '3.0.0-RC1', + false, + ), + array( + '3.0.0', + true, + ), + array( + '3.0.0-pl1', + true, + ), + array( + '3.0.0.1-pl1', + true, + ), + array( + '3.1-dev', + false, + ), + array( + 'foobar', + false, + ), + ); + } + + /** + * @dataProvider is_stable_data + */ + public function test_is_stable($version, $expected) + { + $this->assertSame($expected, $this->version_helper->is_stable($version)); + } + + public function get_suggested_updates_data() + { + return array( + array( + '1.0.0', + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.1', + ), + ), + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.1', + ), + ), + ), + array( + '1.0.1', + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.1', + ), + ), + array( + '1.1' => array( + 'current' => '1.1.1', + ), + ), + ), + array( + '1.0.1-a1', + array( + '1.0' => array( + 'current' => '1.0.1-a2', + ), + '1.1' => array( + 'current' => '1.1.0', + ), + ), + array( + '1.0' => array( + 'current' => '1.0.1-a2', + ), + '1.1' => array( + 'current' => '1.1.0', + ), + ), + ), + array( + '1.1.0', + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.1', + ), + ), + array( + '1.1' => array( + 'current' => '1.1.1', + ), + ), + ), + array( + '1.1.1', + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.1', + ), + ), + array(), + ), + array( + '1.1.0-a1', + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.0-a2', + ), + ), + array( + '1.1' => array( + 'current' => '1.1.0-a2', + ), + ), + ), + ); + } + + /** + * @dataProvider get_suggested_updates_data + */ + public function test_get_suggested_updates($current_version, $versions, $expected) + { + $version_helper = $this + ->getMockBuilder('\phpbb\version_helper') + ->setMethods(array( + 'get_versions_matching_stability', + )) + ->setConstructorArgs(array( + $this->cache, + new \phpbb\config\config(array( + 'version' => $current_version, + )), + new \phpbb\user(), + )) + ->getMock() + ; + + $version_helper->expects($this->any()) + ->method('get_versions_matching_stability') + ->will($this->returnValue($versions)); + + $this->assertSame($expected, $version_helper->get_suggested_updates()); + } + + public function get_latest_on_current_branch_data() + { + return array( + array( + '1.0.0', + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.1', + ), + ), + '1.0.1', + ), + array( + '1.0.1', + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.1', + ), + ), + '1.0.1', + ), + array( + '1.0.1-a1', + array( + '1.0' => array( + 'current' => '1.0.1-a2', + ), + '1.1' => array( + 'current' => '1.1.0', + ), + ), + '1.0.1-a2', + ), + array( + '1.1.0', + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.1', + ), + ), + '1.1.1', + ), + array( + '1.1.1', + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.1', + ), + ), + '1.1.1', + ), + array( + '1.1.0-a1', + array( + '1.0' => array( + 'current' => '1.0.1', + ), + '1.1' => array( + 'current' => '1.1.0-a2', + ), + ), + '1.1.0-a2', + ), + ); + } + + /** + * @dataProvider get_latest_on_current_branch_data + */ + public function test_get_latest_on_current_branch($current_version, $versions, $expected) + { + $version_helper = $this + ->getMockBuilder('\phpbb\version_helper') + ->setMethods(array( + 'get_versions_matching_stability', + )) + ->setConstructorArgs(array( + $this->cache, + new \phpbb\config\config(array( + 'version' => $current_version, + )), + new \phpbb\user(), + )) + ->getMock() + ; + + $version_helper->expects($this->any()) + ->method('get_versions_matching_stability') + ->will($this->returnValue($versions)); + + $this->assertSame($expected, $version_helper->get_latest_on_current_branch()); + } +} diff --git a/tests/wrapper/gmgetdate_test.php b/tests/wrapper/gmgetdate_test.php index a838cfdba9..2f6c74b434 100644 --- a/tests/wrapper/gmgetdate_test.php +++ b/tests/wrapper/gmgetdate_test.php @@ -11,26 +11,28 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; class phpbb_wrapper_gmgetdate_test extends phpbb_test_case { - public function test_gmgetdate() + public static function phpbb_gmgetdate_data() { - $this->run_gmgetdate_assertion(); - $this->run_test_with_timezone('UTC'); - $this->run_test_with_timezone('Europe/Berlin'); - $this->run_test_with_timezone('America/Los_Angeles'); - $this->run_test_with_timezone('Antarctica/South_Pole'); + return array( + array(''), + array('UTC'), + array('Europe/Berlin'), + array('America/Los_Angeles'), + array('Antarctica/South_Pole'), + ); } - protected function run_test_with_timezone($timezone_identifier) + /** + * @dataProvider phpbb_gmgetdate_data + */ + public function test_phpbb_gmgetdate($timezone_identifier) { - $current_timezone = date_default_timezone_get(); - - date_default_timezone_set($timezone_identifier); - $this->run_gmgetdate_assertion(); - date_default_timezone_set($current_timezone); - } + if ($timezone_identifier) + { + $current_timezone = date_default_timezone_get(); + date_default_timezone_set($timezone_identifier); + } - protected function run_gmgetdate_assertion() - { $expected = time(); $date_array = phpbb_gmgetdate($expected); @@ -45,5 +47,10 @@ class phpbb_wrapper_gmgetdate_test extends phpbb_test_case ); $this->assertEquals($expected, $actual); + + if (isset($current_timezone)) + { + date_default_timezone_set($current_timezone); + } } } diff --git a/travis/install-php-extensions.sh b/travis/install-php-extensions.sh deleted file mode 100755 index 55955c2905..0000000000 --- a/travis/install-php-extensions.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# -# @copyright (c) 2013 phpBB Group -# @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -# -set -e - -function add_ext_to_php_ini -{ - echo "extension=$1.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"` -} - -# redis -git clone git://github.com/nicolasff/phpredis.git -cd phpredis -phpize -./configure -make -make install -cd .. -add_ext_to_php_ini 'redis' diff --git a/travis/phpunit-mariadb-travis.xml b/travis/phpunit-mariadb-travis.xml new file mode 100644 index 0000000000..1eaee5b7d8 --- /dev/null +++ b/travis/phpunit-mariadb-travis.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<phpunit backupGlobals="true" + backupStaticAttributes="true" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + syntaxCheck="true" + strict="true" + verbose="true" + bootstrap="../tests/bootstrap.php"> + <testsuites> + <testsuite name="phpBB Test Suite"> + <directory suffix="_test.php">../tests/</directory> + <exclude>tests/functional</exclude> + <exclude>tests/lint_test.php</exclude> + </testsuite> + <testsuite name="phpBB Functional Tests"> + <directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/functional</directory> + </testsuite> + </testsuites> + + <groups> + <exclude> + <group>slow</group> + </exclude> + </groups> + + <php> + <server name="PHPBB_TEST_DBMS" value="mysqli" /> + <server name="PHPBB_TEST_DBHOST" value="0.0.0.0" /> + <server name="PHPBB_TEST_DBPORT" value="3306" /> + <server name="PHPBB_TEST_DBNAME" value="phpbb_tests" /> + <server name="PHPBB_TEST_DBUSER" value="root" /> + <server name="PHPBB_TEST_DBPASSWD" value="" /> + <server name="PHPBB_TEST_TABLE_PREFIX" value="phpbb_"/> + <server name="PHPBB_FUNCTIONAL_URL" value="http://localhost/" /> + </php> +</phpunit> diff --git a/travis/setup-mariadb.sh b/travis/setup-mariadb.sh new file mode 100755 index 0000000000..aceb6af7ee --- /dev/null +++ b/travis/setup-mariadb.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# +# @copyright (c) 2013 phpBB Group +# @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +# +set -e +set -x + +# MariaDB Series +VERSION='5.5' + +# Operating system codename, e.g. "precise" +OS_CODENAME=$(lsb_release --codename --short) + +# Manually purge MySQL to remove conflicting files (e.g. /etc/mysql/my.cnf) +sudo apt-get purge -y mysql-common + +if ! which add-apt-repository > /dev/null +then + sudo apt-get update + sudo apt-get install -y python-software-properties +fi + +MIRROR_DOMAIN='ftp.osuosl.org' +sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db +sudo add-apt-repository "deb http://$MIRROR_DOMAIN/pub/mariadb/repo/$VERSION/ubuntu $OS_CODENAME main" +sudo apt-get update + +# Pin repository in order to avoid conflicts with MySQL from distribution +# repository. See https://mariadb.com/kb/en/installing-mariadb-deb-files +# section "Version Mismatch Between MariaDB and Ubuntu/Debian Repositories" +echo " +Package: * +Pin: origin $MIRROR_DOMAIN +Pin-Priority: 1000 +" | sudo tee /etc/apt/preferences.d/mariadb + +sudo debconf-set-selections <<< "mariadb-server-$VERSION mysql-server/root_password password rootpasswd" +sudo debconf-set-selections <<< "mariadb-server-$VERSION mysql-server/root_password_again password rootpasswd" +sudo apt-get install -y mariadb-server + +# Set root password to empty string. +echo " +USE mysql; +UPDATE user SET Password = PASSWORD('') where User = 'root'; +FLUSH PRIVILEGES; +" | mysql -u root -prootpasswd + +mysql --version diff --git a/travis/setup-php-extensions.sh b/travis/setup-php-extensions.sh new file mode 100755 index 0000000000..826ee7409a --- /dev/null +++ b/travis/setup-php-extensions.sh @@ -0,0 +1,57 @@ +#!/bin/bash +# +# @copyright (c) 2013 phpBB Group +# @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +# +set -e +set -x + +function find_php_ini +{ + echo $(php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||") +} + +# $1 - PHP extension name +# $2 - PHP ini file path +function register_php_extension +{ + echo "extension=$1.so" >> "$2" +} + +# $1 - PHP extension name +# $2 - PHP ini file path +function install_php_extension +{ + echo "Installing $1 PHP extension" + + # See http://www.php.net/manual/en/install.pecl.phpize.php + cd "$1" + phpize + ./configure + make + make install + cd .. + + register_php_extension "$1" "$2" +} + +php_ini_file=$(find_php_ini) + +# disable broken opcache on PHP 5.5.7 and 5.5.8 +if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.5.9', '<');"` == "1" ] +then + sed -i '/opcache.so/d' "$php_ini_file" +fi + +# apc +if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.5.0-dev', '<');"` == "1" ] +then + echo 'Enabling APC PHP extension' + register_php_extension 'apc' "$php_ini_file" + echo 'apc.enable_cli=1' >> "$php_ini_file" +fi + +# redis +# Disabled redis for now as it causes travis to fail +# git clone git://github.com/nicolasff/phpredis.git redis +# install_php_extension 'redis' "$php_ini_file" diff --git a/travis/setup-webserver.sh b/travis/setup-webserver.sh index 95fc4ec1f8..6188d2c232 100755 --- a/travis/setup-webserver.sh +++ b/travis/setup-webserver.sh @@ -1,54 +1,79 @@ #!/bin/bash # -# @copyright (c) 2013 phpBB Group +# @copyright (c) 2014 phpBB Group # @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 # set -e +set -x -sudo apt-get update -qq -sudo apt-get install -qq nginx realpath +if [ "$TRAVIS_PHP_VERSION" = 'hhvm' ] +then + # Add PPA providing dependencies for recent HHVM on Ubuntu 12.04. + sudo add-apt-repository -y ppa:mapnik/boost +fi + +sudo apt-get update +sudo apt-get install -y nginx realpath sudo service nginx stop DIR=$(dirname "$0") +USER=$(whoami) PHPBB_ROOT_PATH=$(realpath "$DIR/../phpBB") - NGINX_CONF="/etc/nginx/sites-enabled/default" +APP_SOCK=$(realpath "$DIR")/php-app.sock -PHP_FPM_BIN="$HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/sbin/php-fpm" -PHP_FPM_CONF="$DIR/php-fpm.conf" -PHP_FPM_SOCK=$(realpath "$DIR")/php-fpm.sock +if [ "$TRAVIS_PHP_VERSION" = 'hhvm' ] +then + # Upgrade to a recent stable version of HHVM + sudo apt-get -o Dpkg::Options::="--force-confnew" install -y hhvm-nightly -USER=$(whoami) + # MySQLi is broken in HHVM 3.0.0~precise and still does not work for us in + # 2014.03.28~saucy, i.e. needs more work. Use MySQL extension for now. + sed -i "s/mysqli/mysql/" "$DIR/phpunit-mysql-travis.xml" -# php-fpm configuration -echo " -[global] + HHVM_LOG=$(realpath "$DIR")/hhvm.log -[travis] -user = $USER -group = $USER -listen = $PHP_FPM_SOCK -pm = static -pm.max_children = 2 + sudo hhvm \ + --mode daemon \ + --user "$USER" \ + -vServer.Type=fastcgi \ + -vServer.FileSocket="$APP_SOCK" \ + -vLog.File="$HHVM_LOG" +else + # php-fpm + PHP_FPM_BIN="$HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/sbin/php-fpm" + PHP_FPM_CONF="$DIR/php-fpm.conf" -php_admin_value[memory_limit] = 128M -" > $PHP_FPM_CONF + echo " + [global] -# nginx configuration + [travis] + user = $USER + group = $USER + listen = $APP_SOCK + pm = static + pm.max_children = 2 + + php_admin_value[memory_limit] = 128M + " > $PHP_FPM_CONF + + sudo $PHP_FPM_BIN \ + --fpm-config "$DIR/php-fpm.conf" +fi + +# nginx echo " -server { - listen 80; - root $PHPBB_ROOT_PATH/; - index index.php index.html; - - location ~ \.php { - fastcgi_pass unix:$PHP_FPM_SOCK; - include fastcgi_params; + server { + listen 80; + root $PHPBB_ROOT_PATH/; + index index.php index.html; + + location ~ \.php { + fastcgi_pass unix:$APP_SOCK; + include fastcgi_params; + } } -} " | sudo tee $NGINX_CONF > /dev/null -# Start daemons -sudo $PHP_FPM_BIN --fpm-config "$DIR/php-fpm.conf" sudo service nginx start |
