diff --git a/.gitignore b/.gitignore index 7d789c59a11..4093aeb56d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,18 @@ *~ /phpunit.xml +/phpBB/cache/*.html /phpBB/cache/*.php /phpBB/cache/queue.php.lock +/phpBB/composer.phar /phpBB/config.php +/phpBB/config_dev.php +/phpBB/config_test.php +/phpBB/ext/* /phpBB/files/* /phpBB/images/avatars/gallery/* /phpBB/images/avatars/upload/* /phpBB/store/* +/phpBB/vendor /tests/phpbb_unit_tests.sqlite2 /tests/test_config.php /tests/tmp/* diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000000..6a1ecedac43 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,27 @@ +language: php +php: + - 5.2 + - 5.3.3 + - 5.3 + - 5.4 + +env: + - DB=mysql + - DB=postgres + +before_script: + - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi" + - sh -c "if [ '$DB' = 'pgsql' ]; 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" + - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then pear install --force phpunit/DbUnit; else pyrus install --force phpunit/DbUnit; fi" + - phpenv rehash + +script: + - phpunit --configuration travis/phpunit-$DB-travis.xml + +notifications: + email: + recipients: + - dev-team@phpbb.com + on_success: change + on_failure: change diff --git a/README.md b/README.md index 6b94f898a3e..51e65176c6f 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,12 @@ Find support and lots more on [phpBB.com](http://www.phpbb.com)! Discuss the dev 3. [Read our Git Contribution Guidelines](http://wiki.phpbb.com/Git); if you're new to git, also read [the introduction guide](http://wiki.phpbb.com/display/DEV/Working+with+Git) 4. Send us a pull request +## 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 - [![Build Status](https://secure.travis-ci.org/phpbb/phpbb3.png?branch=develop)](http://travis-ci.org/phpbb/phpbb3) +develop-olympus - [![Build Status](https://secure.travis-ci.org/phpbb/phpbb3.png?branch=develop-olympus)](http://travis-ci.org/phpbb/phpbb3) + ## LICENSE [GNU General Public License v2](http://opensource.org/licenses/gpl-2.0.php) diff --git a/build/build.xml b/build/build.xml index 3d8d3de6406..0dea17784cc 100644 --- a/build/build.xml +++ b/build/build.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/build/build_changelog.php b/build/build_changelog.php index 4eb5ebd83b1..1e80959adf6 100755 --- a/build/build_changelog.php +++ b/build/build_changelog.php @@ -4,7 +4,7 @@ * * @package build * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU General Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/build/build_diff.php b/build/build_diff.php index 6a6070228f8..0824b53caae 100755 --- a/build/build_diff.php +++ b/build/build_diff.php @@ -3,9 +3,8 @@ /** * * @package build -* @version $Id$ * @copyright (c) 2010 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 * */ @@ -388,7 +387,7 @@ function build_header($mode, $filenames, $header) $html .= "## {$filename['phpbb_filename']}\n"; } } - $html .= "## License: http://opensource.org/licenses/gpl-license.php GNU General Public License v2 \n"; + $html .= "## License: http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 \n"; $html .= "############################################################## \n"; $html .= "\n"; diff --git a/build/build_helper.php b/build/build_helper.php index 2d9b86b3c3c..d6169b913b7 100644 --- a/build/build_helper.php +++ b/build/build_helper.php @@ -2,9 +2,8 @@ /** * * @package build -* @version $Id$ * @copyright (c) 2010 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/build/diff_class.php b/build/diff_class.php index 4625ffde242..2d8555400dd 100644 --- a/build/diff_class.php +++ b/build/diff_class.php @@ -2,10 +2,9 @@ /** * * @package build -* @version $Id$ * @copyright (c) 2000 Geoffrey T. Dairiki * @copyright (c) 2010 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/build/package.php b/build/package.php index 4ce644e8ca1..48f42b3572b 100755 --- a/build/package.php +++ b/build/package.php @@ -3,9 +3,8 @@ /** * * @package build -* @version $Id$ * @copyright (c) 2010 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/git-tools/hooks/commit-msg b/git-tools/hooks/commit-msg index 4f6ae71d4bd..b156d276dfe 100755 --- a/git-tools/hooks/commit-msg +++ b/git-tools/hooks/commit-msg @@ -11,14 +11,30 @@ # # ln -s ../../git-tools/hooks/commit-msg \\ # .git/hooks/commit-msg +# +# You can configure whether invalid commit messages abort commits: +# +# git config phpbb.hooks.commit-msg.fatal true (abort) +# git config phpbb.hooks.commit-msg.fatal false (warn only, do not abort) +# +# The default is to warn only. +# +# Warning/error messages use color by default if the output is a terminal +# ("output" here is normally standard error when you run git commit). +# To force or disable the use of color: +# +# git config phpbb.hooks.commit-msg.color true (force color output) +# git config phpbb.hooks.commit-msg.color false (disable color output) config_ns="phpbb.hooks.commit-msg"; -if [ "$(git config --bool $config_ns.fatal)" = "false" ] +if [ "$(git config --bool $config_ns.fatal)" = "true" ] then - fatal=0; -else fatal=1; + severity=Error; +else + fatal=0; + severity=Warning; fi debug_level=$(git config --int $config_ns.debug || echo 0); @@ -47,14 +63,68 @@ debug() quit() { - if [ $1 -gt 0 ] && [ $1 -ne $ERR_UNKNOWN ] && [ $fatal -eq 0 ] + if [ $1 -eq 0 ] || [ $1 -eq $ERR_UNKNOWN ] + then + # success + exit 0; + elif [ $fatal -eq 0 ] then + # problems found but fatal is false + complain 'Please run `git commit --amend` and fix the problems mentioned.' 1>&2 exit 0; else + complain "Aborting commit." 1>&2 exit $1; fi } +use_color() +{ + if [ -z "$use_color_cached" ] + then + case $(git config --bool $config_ns.color) + in + false) + use_color_cached=1 + ;; + true) + use_color_cached=0 + ;; + *) + # tty detection in shell: + # http://hwi.ath.cx/jsh/list/shext/isatty.sh.html + tty 0>/dev/stdout >/dev/null 2>&1 + use_color_cached=$? + ;; + esac + fi + # return value is the flag inverted - + # if return value is 0, this means use color + return $use_color_cached +} + +complain() +{ + if use_color + then + # Careful: our argument may include arguments to echo like -n + # ANSI color codes: + # http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html + printf "\033[31m\033[1m" + if [ "$1" = "-n" ] + then + echo "$@" + printf "\033[0m" + else + # This will print one trailing space. + # Not sure how to avoid this at the moment. + echo "$@" $(printf "\033[0m") + fi + else + echo "$@" + fi +} + # Check for empty commit message if ! grep -qv '^#' "$1" then @@ -70,9 +140,9 @@ msg=$(grep -v '^#' "$1" |grep -nE '.{81,}') if [ $? -eq 0 ] then - echo "The following lines are greater than 80 characters long:" >&2; - echo >&2 - echo "$msg" >&2; + complain "The following lines are greater than 80 characters long:" >&2; + complain >&2 + complain "$msg" >&2; quit $ERR_LENGTH; fi @@ -126,9 +196,9 @@ do # Don't be too strict. # Commits may be temporary, intended to be squashed later. # Just issue a warning here. - echo "Warning: heading should be a sentence beginning with a capital letter." 1>&2 - echo "You entered:" 1>&2 - echo "$line" 1>&2 + complain "$severity: heading should be a sentence beginning with a capital letter." 1>&2 + complain "You entered:" 1>&2 + complain "$line" 1>&2 fi # restore exit code (exit $result) @@ -160,7 +230,7 @@ do echo "$line" | grep -Eq "^#"; ;; *) - echo "Unrecognised token $expect" >&2; + complain "Unrecognised token $expect" >&2; quit $err; ;; esac @@ -231,7 +301,7 @@ do expecting="eof"; ;; *) - echo "Unrecognised token $expect" >&2; + complain "Unrecognised token $expect" >&2; quit 254; ;; esac @@ -245,11 +315,11 @@ do else # None of the expected line formats matched # Guess we'll call it a day here then - echo "Syntax error on line $i:" >&2; - echo ">> $line" >&2; - echo -n "Expecting: " >&2; - echo "$expecting" | sed 's/ /, /g' >&2; - exit $err; + complain "Syntax error on line $i:" >&2; + complain ">> $line" >&2; + complain -n "Expecting: " >&2; + complain "$expecting" | sed 's/ /, /g' >&2; + quit $err; fi i=$(( $i + 1 )); @@ -258,7 +328,7 @@ done # If EOF is expected exit cleanly echo "$expecting" | grep -q "eof" || ( # Unexpected EOF, error - echo "Unexpected EOF encountered" >&2; + complain "Unexpected EOF encountered" >&2; quit $ERR_EOF; ) && ( # Do post scan checks @@ -269,8 +339,8 @@ echo "$expecting" | grep -q "eof" || ( if [ ! -z "$dupes" ] then - echo "The following tickets are repeated:" >&2; - echo "$dupes" | sed 's/ /\n/g;s/^/* /g' >&2; + complain "The following tickets are repeated:" >&2; + complain "$dupes" | sed 's/ /\n/g;s/^/* /g' >&2; quit $ERR_FOOTER; fi fi @@ -278,8 +348,8 @@ echo "$expecting" | grep -q "eof" || ( if [ $ticket -gt 0 ] then echo "$tickets" | grep -Eq "\bPHPBB3-$ticket\b" || ( - echo "Ticket ID [$ticket] of branch missing from list of tickets:" >&2; - echo "$tickets" | sed 's/ /\n/g;s/^/* /g' >&2; + complain "Ticket ID [$ticket] of branch missing from list of tickets:" >&2; + complain "$tickets" | sed 's/ /\n/g;s/^/* /g' >&2; quit $ERR_FOOTER; ) || exit $?; fi diff --git a/git-tools/hooks/pre-commit b/git-tools/hooks/pre-commit index 4d033597736..03babe47cd0 100755 --- a/git-tools/hooks/pre-commit +++ b/git-tools/hooks/pre-commit @@ -12,8 +12,17 @@ # ln -s ../../git-tools/hooks/pre-commit \\ # .git/hooks/pre-commit -# NOTE: this is run through /usr/bin/env -PHP_BIN=php +if [ -z "$PHP_BIN" ] +then + PHP_BIN=php +fi + +if [ "$(echo -e test)" = test ] +then + echo_e="echo -e" +else + echo_e="echo" +fi # necessary check for initial commit if git rev-parse --verify HEAD >/dev/null 2>&1 @@ -27,7 +36,7 @@ fi error=0 errors="" -if ! which $PHP_BIN >/dev/null 2>&1 +if ! which "$PHP_BIN" >/dev/null 2>&1 then echo "PHP Syntax check failed:" echo "PHP binary does not exist or is not in path: $PHP_BIN" @@ -64,7 +73,13 @@ do # check the staged file content for syntax errors # using php -l (lint) - result=$(git cat-file -p $sha | /usr/bin/env $PHP_BIN -l 2>/dev/null) + # note: if display_errors=stderr in php.ini, + # parse errors are printed on stderr; otherwise + # they are printed on stdout. + # we filter everything other than parse errors + # with a grep below, therefore it should be safe + # to combine stdout and stderr in all circumstances + result=$(git cat-file -p $sha | "$PHP_BIN" -l 2>&1) if [ $? -ne 0 ] then error=1 @@ -76,7 +91,45 @@ unset IFS if [ $error -eq 1 ] then - echo -e "PHP Syntax check failed:"; - echo -e "$errors" | grep "^Parse error:" + echo "PHP Syntax check failed:" + # php "display errors" (display_errors php.ini value) + # and "log errors" (log_errors php.ini value). + # these are independent settings - see main/main.c in php source. + # the "log errors" setting produces output which + # starts with "PHP Parse error:"; the "display errors" + # setting produces output starting with "Parse error:". + # if both are turned on php dumps the parse error twice. + # therefore here we try to grep for one version and + # if that yields no results grep for the other version. + # + # other fun php facts: + # + # 1. in cli, display_errors and log_errors have different + # destinations by default. display_errors prints to + # standard output and log_errors prints to standard error. + # whether these destinations make sense is left + # as an exercise for the reader. + # 2. as mentioned above, with all output turned on + # php will print parse errors twice, one time on stdout + # and one time on stderr. + # 3. it is possible to set both display_errors and log_errors + # to off. if this is done php will print the text + # "Errors parsing " but will not say what + # the errors are. useful behavior, this. + # 4. on my system display_errors defaults to on and + # log_errors defaults to off, therefore providing + # by default one copy of messages. your mileage may vary. + # 5. by setting display_errors=stderr and log_errors=on, + # both sets of messages will be printed on stderr. + # 6. php-cgi binary, given display_errors=stderr and + # log_errors=on, still prints both sets of messages + # on stderr, but formats one set as an html fragment. + # 7. your entry here? ;) + $echo_e "$errors" | grep "^Parse error:" + if [ $? -ne 0 ] + then + # match failed + $echo_e "$errors" | grep "^PHP Parse error:" + fi exit 1 fi diff --git a/git-tools/merge.php b/git-tools/merge.php index cbd84b896fc..034bd2032c1 100755 --- a/git-tools/merge.php +++ b/git-tools/merge.php @@ -4,7 +4,7 @@ * * @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 * */ diff --git a/git-tools/setup_github_network.php b/git-tools/setup_github_network.php index e4e212eef68..5f2e1609a70 100755 --- a/git-tools/setup_github_network.php +++ b/git-tools/setup_github_network.php @@ -4,7 +4,7 @@ * * @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 * */ diff --git a/phpBB/adm/images/phpbb_logo.gif b/phpBB/adm/images/phpbb_logo.gif deleted file mode 100644 index 239993182be..00000000000 Binary files a/phpBB/adm/images/phpbb_logo.gif and /dev/null differ diff --git a/phpBB/adm/images/phpbb_logo.png b/phpBB/adm/images/phpbb_logo.png new file mode 100644 index 00000000000..c3f9248ed79 Binary files /dev/null and b/phpBB/adm/images/phpbb_logo.png differ diff --git a/phpBB/adm/index.php b/phpBB/adm/index.php index bf4dc37044d..3c984f8290a 100644 --- a/phpBB/adm/index.php +++ b/phpBB/adm/index.php @@ -199,6 +199,7 @@ function adm_page_footer($copyright_html = true) 'DEBUG_OUTPUT' => (defined('DEBUG')) ? $debug_output : '', 'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '', 'S_COPYRIGHT_HTML' => $copyright_html, + 'CREDIT_LINE' => $user->lang('POWERED_BY', 'phpBB® Forum Software © phpBB Group'), 'VERSION' => $config['version']) ); diff --git a/phpBB/adm/style/acp_profile.html b/phpBB/adm/style/acp_profile.html index 85d37568c29..1c9c038f8f1 100644 --- a/phpBB/adm/style/acp_profile.html +++ b/phpBB/adm/style/acp_profile.html @@ -63,6 +63,10 @@

{L_WARNING}


{L_REQUIRED_FIELD_EXPLAIN}
checked="checked" />
+
+

{L_SHOW_NOVALUE_FIELD_EXPLAIN}
+
checked="checked" />
+

{L_HIDE_PROFILE_FIELD_EXPLAIN}
checked="checked" />
diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html index 098cc723d9a..6aa1c0ccc94 100644 --- a/phpBB/adm/style/acp_styles.html +++ b/phpBB/adm/style/acp_styles.html @@ -402,6 +402,12 @@

{L_TITLE}

{L_INSTALLED} + + + + {L_INACTIVE_STYLES} + + {installed.NAME} * diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index 9237e45daf8..e2dcdb63073 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -135,19 +135,24 @@ -
-
- {L_DELETE_USER} -
-

{L_DELETE_USER_EXPLAIN}
-
-
-

- - - {S_FORM_TOKEN} -

-
-
+
+
+ {L_DELETE_USER} +
+

{L_DELETE_USER_EXPLAIN}
+
+ +
+ + {L_USER_NO_POSTS_TO_DELETE} + +
+

+ + + {S_FORM_TOKEN} +

+
+
diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css index 666f4921ba5..b9996fd1d17 100644 --- a/phpBB/adm/style/admin.css +++ b/phpBB/adm/style/admin.css @@ -142,15 +142,15 @@ li { #page-header { clear: both; text-align: right; - background: url("../images/phpbb_logo.gif") top left no-repeat; - height: 49px; + background: url("../images/phpbb_logo.png") top left no-repeat; + height: 54px; font-size: 0.85em; margin-bottom: 10px; } .rtl #page-header { text-align: left; - background: url("../images/phpbb_logo.gif") top right no-repeat; + background: url("../images/phpbb_logo.png") top right no-repeat; } #page-header h1 { diff --git a/phpBB/adm/style/install_update.html b/phpBB/adm/style/install_update.html index 22d21d8314e..818889c89b6 100644 --- a/phpBB/adm/style/install_update.html +++ b/phpBB/adm/style/install_update.html @@ -43,6 +43,11 @@

{L_NOTICE}

{WARNING_MSG}

+ +
+

{L_NOTICE}

+

{L_BACKUP_NOTICE}

+
diff --git a/phpBB/adm/style/install_update_diff.html b/phpBB/adm/style/install_update_diff.html index b65a0143124..922b4aca312 100644 --- a/phpBB/adm/style/install_update_diff.html +++ b/phpBB/adm/style/install_update_diff.html @@ -15,12 +15,12 @@ // - Powered by phpBB® Forum Software © phpBB Group + {CREDIT_LINE}
{TRANSLATION_INFO} diff --git a/phpBB/adm/style/simple_footer.html b/phpBB/adm/style/simple_footer.html index ac9c26a6905..6395eace6ce 100644 --- a/phpBB/adm/style/simple_footer.html +++ b/phpBB/adm/style/simple_footer.html @@ -5,7 +5,7 @@ @@ -139,15 +139,15 @@

Install

  • MySQL 3.23 or above (MySQLi supported)
  • PostgreSQL 7.3+
  • -
  • SQLite 2.8.2+
  • +
  • SQLite 2.8.2+ (SQLite 3 is not supported)
  • Firebird 2.1+
  • -
  • MS SQL Server 2000 or above (directly or via ODBC)
  • +
  • MS SQL Server 2000 or above (directly or via ODBC or the native adapter)
  • Oracle
-
  • PHP 4.3.3+ (>=4.3.3, >4.4.x, >5.x.x, >6.0-dev (compatible)) with support for the database you intend to use.
  • +
  • PHP 4.3.3+ (>=4.3.3, >=4.4.x, >=5.x.x, >=5.4.x) with support for the database you intend to use.
  • getimagesize() function need to be enabled.
  • -
  • These optional presence of the following modules within PHP will provide access to additional features, but they are not required. +
  • Presence of the following modules within PHP will provide access to additional features, but they are not required:
    • zlib Compression support
    • Remote FTP support
    • @@ -182,7 +182,7 @@

      Install

      All .php, .inc, .sql, .cfg, .html and .txt files should be uploaded in ASCII mode, while all graphics should be uploaded in BINARY mode. If you are unfamiliar with what this means please refer to your FTP client documentation. In most cases this is all handled transparantly by your ftp client but if you encounter problems later you should be sure the files where uploaded correctly as described here.

      -

      phpBB3 comes supplied with english as its standard language. However a number of separate packs for different languages are available. If you are not a native english speaker you may wish to install one or more of these packages before continuing. The installation process below will allow you to select a default language from those available (you can of course change this default at a later stage). For more details of language packs, where to obtain them and how to install them please see the README.

      +

      phpBB3 comes supplied with British English as its standard language. However a number of separate packs for different languages are available. If you are not a native English speaker you may wish to install one or more of these packages before continuing. The installation process below will allow you to select a default language from those available (you can of course change this default at a later stage). For more details of language packs, where to obtain them and how to install them please see the README.

      Once all the files have been uploaded to your site you should point your browser at this location with the addition of install/. For example if your domain name is www.mydomain.tld and you placed phpBB3 in a directory /phpBB3 off your web root you would enter http://www.mydomain.tld/phpBB3/install/ or (alternatively) http://www.mydomain.tld/phpBB3/install/index.php into your browser. When you have done this you should see the phpBB3 Installation screen appear.

      @@ -274,7 +274,7 @@

      Advanced settings

      This package is meant for those wanting to only replace changed files from a previous version to the latest version. This package normally contains the changed files from up to five previous versions.

      -

      This package contains a number of archives, each contains the files changed from a given release to the latest version. You should select the appropriate archive for your current version, e.g. if you currently have 3.0.9 you should select the phpBB-3.0.9_to_3.0.10.zip/tar.gz file.

      +

      This package contains a number of archives, each contains the files changed from a given release to the latest version. You should select the appropriate archive for your current version, e.g. if you currently have 3.0.10 you should select the phpBB-3.0.10_to_3.0.11.zip/tar.gz file.

      The directory structure has been preserved enabling you (if you wish) to simply upload the contents of the archive to the appropriate location on your server, i.e. simply overwrite the existing files with the new versions. Do not forget that if you have installed any MODs these files will overwrite the originals possibly destroying them in the process. You will need to re-add MODs to any affected file before uploading.

      @@ -286,7 +286,7 @@

      Advanced settings

      The patch file is one solution for those with many Modifications (MODs) or other changes who do not want to re-add them back to all the changed files if they use the method explained above. To use this you will need command line access to a standard UNIX type patch application. If you do not have access to such an application but still want to use this update approach, we strongly recommend the Automatic update package explained below. It is also the recommended update method.

      -

      A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is 3.0.9 you need the phpBB-3.0.9_to_3.0.10.patch file. Place the correct patch in the parent directory containing the phpBB3 core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: patch -cl -d [PHPBB DIRECTORY] -p1 < [PATCH NAME] (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB3, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.

      +

      A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is 3.0.10 you need the phpBB-3.0.10_to_3.0.11.patch file. Place the correct patch in the parent directory containing the phpBB3 core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: patch -cl -d [PHPBB DIRECTORY] -p1 < [PATCH NAME] (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB3, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.

      If you do get failures you should look at using the Changed files only package to replace the files which failed to patch, please note that you will need to manually re-add any Modifications (MODs) to these particular files. Alternatively if you know how you can examine the .rej files to determine what failed where and make manual adjustments to the relevant source.

      @@ -431,7 +431,7 @@

      Advanced settings

      -

      This application is opensource software released under the GPL. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) phpBB Group, All Rights Reserved.

      +

      This application is opensource software released under the GNU General Public License v2. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) phpBB Group, All Rights Reserved.

      diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index 7ceb698ac44..86340ac882b 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -54,7 +54,7 @@

      Readme

    • Installing phpBB3
    • Running phpBB3
        -
      1. Internationalisation (i18n)
      2. +
      3. Languages (Internationalisation - i18n)
      4. Styles
      5. Modifications
      @@ -62,8 +62,9 @@

      Readme

    • Getting help with phpBB3
      1. Documentation
      2. +
      3. Knowledge Base
      4. Community Forums
      5. -
      6. Internet Relay Chat
      7. +
      8. Internet Relay Chat (IRC)
    • Status of this version
    • @@ -106,6 +107,7 @@

      Readme

      • Updates from phpBB3 RC1 to the latest version
      • +
      • Note: if using the Automatic Update Package, updates are supported from phpBB 3.0.2 onward. To update a pre-3.0.2 installation, first update to 3.0.2 and then update to the current version.
      • Conversions from phpBB 2.0.x to the latest version
      • New installations of phpBB3 - always only the latest released version
      @@ -126,41 +128,41 @@

      Readme

      -

      Once installed phpBB is easily managed by both admin and moderator control panels. If you need help or advice with phpBB please see Section 3 below.

      +

      Once installed, phpBB is easily managed via the Administration and Moderator Control Panels. If you need help or advice with phpBB, please see Section 3 below.

      -

      2.i. Internationalisation (i18n)

      +

      2.i. Languages (Internationalisation - i18n)

      -

      A number of language packs and style localisations are available. You can find them on our official download page:

      +

      A number of language packs with included style localisations are available. You can find them listed in the Language Packs pages of our downloads section or from the Language Packs section of the Customisation Database.

      -

      http://www.phpbb.com/downloads/

      +

      For more information about language packs, please see: http://www.phpbb.com/languages/

      This is the official location for all supported language sets. If you download a package from a 3rd party site you do so with the understanding that we cannot offer support. So please, do not ask for help in these cases!

      -

      Installation of these packages is straightforward, simply download the required language pack and unarchive it into the languages/ folder. Please ensure you retain the directory structure when doing this! Once uploaded go to the Admin->System->Language Packs and install the now appeared new language pack. To install the style imageset you should download the imageset for your language and unarchive the file/s into the relevant imageset directory (styles/prosilver/imageset or styles/subsilver2/imageset), again you must retain the directory structure. Once installed the imageset will become immediately available.

      +

      Installation of these packages is straightforward: simply download the required language pack, uncompress (unzip) it and via FTP transfer the included language and styles folders to the root of your board installation. The language can then be installed via the Administration Control Panel of your board: System tab -> General Tasks -> Language packs. A more detailed description of the process is in the Knowledge Base article, How to Install a Language Pack.

      -

      If your language is not available please visit our forums where you will find a topic listing translations currently available or in preparation. This topic also gives you information should you wish to volunteer to translate a language not currently listed.

      +

      If your language is not available, please visit our [3.0.x] Translations forum where you will find topics on translations in progress. Should you wish to volunteer to translate a language not currently available or assist in maintaining an existing language pack, you can Apply to become a translator.

      2.ii. Styles

      -

      Although phpBB Group are rather proud of the included styles we realise that it may not be to everyones tastes. Therefore phpBB3 allows styles to be switched with relative ease. Firstly you need to locate and download a style you like. We maintain such a site at

      +

      Although the phpBB Group is rather proud of the included styles, we realise that they may not be to everyone's taste. Therefore, phpBB3 allows styles to be switched with relative ease. First, you need to locate and download a style you like. You can find them listed in the Styles section of our Customisation Database.

      -

      http://www.phpbb.com/styles/

      +

      For more information about styles, please see: http://www.phpbb.com/styles/

      -

      Please note that 3rd party styles downloaded for versions of phpBB2 will not work in phpBB3.

      +

      Please note that 3rd party styles downloaded for versions of phpBB2 will not work in phpBB3. It is also important to ensure that the style is updated to match the current version of the phpBB software you are using.

      -

      Once you have downloaded a style the usual next step is to unarchive (or upload the unarchived contents of) the package into your styles/ directory. You then need to visit Administration -> Styles, you should see the new style available, click install and it will become available for all your users.

      +

      Once you have downloaded a style, the usual next step is to unarchive (or upload the unarchived contents of) the package into your styles/ directory. You then need to visit Administration Control Panel -> Styles tab where you should see the new style available. Click "Install" to install the style.

      -

      Please note that if you create your own style or modify existing ones, please remember to enable the "Recompile stale style components" setting within the Admin->General->Load Settings screen. This setting allows the cache to detect changes made to the style and automatically refresh it. If this setting is disabled, you will not see your changes taking effect.

      +

      Please note that to improve efficiency, the software caches certain data. For this reason, if you create your own style or modify existing ones, please remember to "Refresh" the appropriate style components Administration Control Panel -> Styles tab -> Style Components screen. You may also need to reload the page you have changed in your web browser to overcome browser caching. If the changed components are not refreshed you will not see your changes taking effect.

      2.iii. Modifications

      -

      Although not officially supported by phpBB Group, phpBB has a thriving modification scene. These third party modifications to the standard phpBB extend its capabilities still further and can be found at:

      +

      Although not officially supported by the phpBB Group, phpBB has a thriving modification scene. These third party modifications to the standard phpBB software, known as MODs, extend its capabilities still further. You can browse through many of the MODs in the Modifications section of our Customisation Database.

      -

      http://www.phpbb.com/mods/

      +

      For more information about MODs, please see: http://www.phpbb.com/mods/

      -

      Please remember that any bugs or other issues that occur after you have added any modification should NOT be reported to the bug tracker (see below). First remove the modification and see if the problem is resolved.

      +

      Please remember that any bugs or other issues that occur after you have added any modification should NOT be reported to the bug tracker (see below). First remove the MOD and see if the problem is resolved. Any support for a MOD should only be sought in the "Discussion/Support" forum for that MOD.

      -

      Also remember that any modifications which modify the database in any way may render upgrading your forum to future versions more difficult unless we state otherwise. With all this said many users have and continue to utilise many of the mods already available with great success.

      +

      Also remember that any modifications, particularly those which modify the database in any way, may render upgrading your forum to future versions more difficult. With all this said, many users have and continue to utilise many of the MODs already available with great success.

      @@ -188,17 +190,25 @@

      Readme

      This covers everything from installation through setting permissions and managing users.

      -

      3.ii. Community Forums

      +

      3.ii. Knowledge Base

      -

      phpBB Group maintains a thriving community where a number of people have generously decided to donate their time to help support users. This site can be found at:

      +

      The Knowledge Base consists of a number of detailed articles on some common issues phpBB users may encounter while using the product. The Knowledge Base can be found at:

      -

      http://www.phpbb.com/

      +

      http://www.phpbb.com/kb/

      + +

      3.iii. Community Forums

      + +

      The phpBB Group maintains a thriving community where a number of people have generously decided to donate their time to help support users. This site can be found at:

      + +

      http://www.phpbb.com/community/

      If you do seek help via our forums please be sure to do a Search before posting. This may well save both you and us time and allow the developer, moderator and support groups to spend more time responding to people with unknown issues and problems. Please also remember that phpBB is an entirely volunteer effort, no one receives any compensation for the time they give, this includes moderators as well as developers. So please be respectful and mindful when awaiting responses.

      -

      3.iii Internet Relay Chat

      +

      3.iv Internet Relay Chat

      -

      Another place you may find help is our IRC channel. This operates on the Freenode IRC network, irc.freenode.net and the channel is #phpbb and can be accessed by any good IRC client such as mIRC, XChat, etc. Again, please do not abuse this service and be respectful of other users.

      +

      Another place you may find help is our IRC channel. This operates on the Freenode IRC network, irc.freenode.net and the channel is #phpbb and can be accessed by any decent IRC client such as mIRC, XChat, etc. Again, please do not abuse this service and be respectful of other users.

      + +

      There are other IRC channels available, please see http://www.phpbb.com/support/irc/ for the complete list.

      @@ -216,13 +226,13 @@

      Readme

      -

      This is the third stable release of phpBB. The 3.0.x line is essentially feature frozen, with only point releases seeing fixes for bugs and security issues, though feature alterations and minor feature additions may be done if deemed absolutely required. Our next major release will be phpBB 3.2 and the planning phase has begun (the unstable development version is 3.1). Please do not post questions asking when 3.2 will be available, no release date has been set.

      +

      This is the third stable release of phpBB. The 3.0.x line is essentially feature frozen, with only point releases seeing fixes for bugs and security issues, though feature alterations and minor feature additions may be done if deemed absolutely required. Our next major release will be phpBB 3.1. Please do not post questions asking when 3.1 will be available, no release date has been set.

      -

      For those interested in the development of phpBB should keep an eye on the community forums to see how things are progressing:

      +

      Those interested in the development of phpBB should keep an eye on the development forums to see how things are progressing:

      http://area51.phpbb.com/phpBB/

      -

      Please note that this forum should NOT be used to obtain support for or ask questions about phpBB 2.0.x or phpBB 3.0.x, the main community forums are the place for this. Any such posts will be locked and go unanswered.

      +

      Please note that the development forums should NOT be used to seek support for or ask questions about phpBB 2.0.x or phpBB 3.0.x, the main community forums are the place for this. Any such posts will be locked and go unanswered.

      @@ -240,20 +250,20 @@

      Readme

      -

      The phpBB Group uses a bug tracking system to store, list and manage all reported bugs, it can be found at the location listed below. Please DO NOT post bug reports to our forums, they will be locked. In addition please DO NOT use the bug tracker for support requests. Posting such a request will only see you directed to the support forums (while taking time away from working on real bugs).

      +

      The phpBB Group uses a bug tracking system to store, list and manage all reported bugs, it can be found at the location listed below. Please DO NOT post bug reports to our forums. In addition please DO NOT use the bug tracker for support requests. Posting such a request will only see you directed to the support forums (while taking time away from working on real bugs).

      -

      http://tracker.phpbb.com/

      +

      http://tracker.phpbb.com/browse/PHPBB3

      While we very much appreciate receiving bug reports (the more reports the more stable phpBB will be) we ask you carry out a few steps before adding new entries:

        -
      • Firstly determine if your bug is reproduceable, how to determine this depends on the bug in question. Only if the bug is reproduceable it is likely to be a problem with phpBB3 (or in some way connected). If something cannot be reproduced it may turn out to have been your hosting provider working on something, a user doing something silly, etc. Bug reports for non-reproduceable events can slow down our attempts to fix real, reproduceable issues

      • -
      • Next please read or search through the existing bug reports to see if your bug (or one very similar to it) is already listed. If it is please add to that existing bug rather than creating a new duplicate entry (all this does is slow us down).

      • -
      • Check the forums (use search!) to see if people have discussed anything that sounds similar to what you are seeing. However, as noted above please DO NOT post your particular bug to the forum unless it's non-reproduceable or you are sure it's related to something you have done rather phpBB3

      • +
      • First, determine if your bug is reproduceable; how to determine this depends on the bug in question. Only if the bug is reproduceable is it likely to be a problem with phpBB3 (or in some way connected). If something cannot be reproduced it may turn out to have been your hosting provider working on something, a user doing something silly, etc. Bug reports for non-reproduceable events can slow down our attempts to fix real, reproduceable issues

      • +
      • Next, please read or search through the existing bug reports to see if your bug (or one very similar to it) is already listed. If it is please add to that existing bug rather than creating a new duplicate entry (all this does is slow us down).

      • +
      • Check the forums (use search!) to see if people have discussed anything that sounds similar to what you are seeing. However, as noted above please DO NOT post your particular bug to the forum unless it's non-reproduceable or you are sure it’s related to something you have done rather than phpBB3

      • If no existing bug exists then please feel free to add it
      -

      If you do post a new bug (i.e. one that isn't already listed in the bug tracker) firstly make sure you have logged in (your username and password are the same as for the community forums) then please include the following details:

      +

      If you do post a new bug (i.e. one that isn't already listed in the bug tracker) first make sure that you have logged in (your username and password are the same as for the community forums) then please include the following details:

      • Your server type/version, e.g. Apache 1.3.28, IIS 4, Sambar, etc.
      • @@ -261,10 +271,12 @@

        Readme

      • DB type/version, e.g. MySQL 4.0.1, PostgreSQL 7.3.2, MSSQL Server 2000 SP1, etc.
      -

      The relevant database type/version is listed within the administration control panel

      +

      The relevant database type/version is listed within the administration control panel.

      Please also be as detailed as you can in your report, if possible list the steps required to duplicate the problem. If you have a patch that fixes the issue, please attach it to the ticket or submit a pull request on GitHub.

      +

      If you create a patch, it is very much appreciated (but not required) if you follow the phpBB coding guidelines. Please note that the coding guidelines are somewhat different between different versions of phpBB. For phpBB 3.0.x the coding guidelines may be found here: http://area51.phpbb.com/docs/30x/coding-guidelines.html

      +

      Once a bug has been submitted you will be emailed any follow up comments added to it. Please if you are requested to supply additional information, do so! It is frustrating for us to receive bug reports, ask for additional information but get nothing. In these cases we have a policy of closing the bug, which may leave a very real problem in place. Obviously we would rather not have this situation arise.

      5.i. Security related bugs

      @@ -289,7 +301,7 @@

      Readme

      -

      This list is not complete but does represent those bugs which may effect users on a wider scale. Other bugs listed in the tracker have typically been shown to be limited to certain setups or methods of installation, updating and/or conversions.

      +

      This list is not complete but does represent those bugs which may affect users on a wider scale. Other bugs listed in the tracker have typically been shown to be limited to certain setups or methods of installation, updating and/or conversions.

      • Conversions may fail to complete on large boards under some hosts
      • @@ -317,7 +329,7 @@

        Readme

        Please remember that running any application on a developmental version of PHP can lead to strange/unexpected results which may appear to be bugs in the application (which may not be true). Therefore we recommend you upgrade to the newest stable version of PHP before running phpBB3. If you are running a developmental version of PHP please check any bugs you find on a system running a stable release before submitting.

        -

        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 7.x, Oracle 8, SQLite and Firebird. Versions of PHP used range from 4.3.3 to 6.0.0-dev without problem.

        +

        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 7.x, Oracle 8, SQLite 2 and Firebird. Versions of PHP used range from 4.3.3 to 5.4.x without problem.

        7.i. Notice on PHP security issues

        @@ -339,7 +351,7 @@

        Readme

        -

        This application is opensource software released under the GPL. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) phpBB Group, All Rights Reserved.

        +

        This application is opensource software released under the GNU General Public License v2. Please see source code and the docs directory for more details. This package and its contents are Copyright © phpBB Group, All Rights Reserved.

        diff --git a/phpBB/docs/auth_api.html b/phpBB/docs/auth_api.html index 88618fa6405..29469c21acb 100644 --- a/phpBB/docs/auth_api.html +++ b/phpBB/docs/auth_api.html @@ -275,7 +275,7 @@

        Initialisation

        -

        This application is opensource software released under the GPL. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) phpBB Group, All Rights Reserved.

        +

        This application is opensource software released under the GNU General Public License v2. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) phpBB Group, All Rights Reserved.

        diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index 7d51b26dca1..cd113a72262 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -129,9 +129,8 @@

        Standard header for new files:

        /** * * @package {PACKAGENAME} -* @version $Id: $ * @copyright (c) 2007 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 * */
      @@ -2322,7 +2321,7 @@

      Spelling, punctuation, grammar, et cetera:

      -

      This application is opensource software released under the GPL. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) phpBB Group, All Rights Reserved.

      +

      This application is opensource software released under the GNU General Public License v2. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) phpBB Group, All Rights Reserved.

      diff --git a/phpBB/docs/hook_system.html b/phpBB/docs/hook_system.html index a5fad0d530f..1b8131efafb 100644 --- a/phpBB/docs/hook_system.html +++ b/phpBB/docs/hook_system.html @@ -867,7 +867,7 @@

      Case 2 - Not Returning any result

      -

      This application is opensource software released under the GPL. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) phpBB Group, All Rights Reserved.

      +

      This application is opensource software released under the GNU General Public License v2. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) phpBB Group, All Rights Reserved.

      diff --git a/phpBB/download/file.php b/phpBB/download/file.php index c17f0cf0182..bf277c69fab 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -424,7 +424,7 @@ function send_file_to_browser($attachment, $upload_dir, $category) if (!@file_exists($filename)) { send_status_line(404, 'Not Found'); - trigger_error($user->lang['ERROR_NO_ATTACHMENT'] . '

      ' . sprintf($user->lang['FILE_NOT_FOUND_404'], $filename)); + trigger_error('ERROR_NO_ATTACHMENT'); } // Correct the mime type - we force application/octetstream for all files, except images diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 3ed5f403681..f437dca8f99 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -234,7 +234,7 @@ function main($id, $mode) 'max_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:8:180', 'type' => false, 'method' => false, 'explain' => false,), 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,), - 'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_acc_activation', 'explain' => true), + 'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'select', 'method' => 'select_acc_activation', 'explain' => true), 'new_member_post_limit' => array('lang' => 'NEW_MEMBER_POST_LIMIT', 'validate' => 'int:0:255', 'type' => 'text:4:4', 'explain' => true, 'append' => ' ' . $user->lang['POSTS']), 'new_member_group_default'=> array('lang' => 'NEW_MEMBER_GROUP_DEFAULT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'min_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:1', 'type' => 'custom:5:180', 'method' => 'username_length', 'explain' => true), @@ -383,6 +383,8 @@ function main($id, $mode) 'referer_validation' => array('lang' => 'REFERER_VALID', 'validate' => 'int:0:3','type' => 'custom', 'method' => 'select_ref_check', 'explain' => true), 'check_dnsbl' => array('lang' => 'CHECK_DNSBL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'email_check_mx' => array('lang' => 'EMAIL_CHECK_MX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,), + 'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true), 'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true), 'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0', 'type' => 'text:3:3', 'explain' => true), @@ -768,24 +770,28 @@ function select_ref_check($value, $key = '') /** * Select account activation method */ - function select_acc_activation($value, $key = '') + function select_acc_activation($selected_value, $value) { global $user, $config; - $radio_ary = array( - USER_ACTIVATION_DISABLE => 'ACC_DISABLE', - USER_ACTIVATION_NONE => 'ACC_NONE', + $act_ary = array( + 'ACC_DISABLE' => USER_ACTIVATION_DISABLE, + 'ACC_NONE' => USER_ACTIVATION_NONE, ); - if ($config['email_enable']) { - $radio_ary[USER_ACTIVATION_SELF] = 'ACC_USER'; - $radio_ary[USER_ACTIVATION_ADMIN] = 'ACC_ADMIN'; - } + $act_ary['ACC_USER'] = USER_ACTIVATION_SELF; + $act_ary['ACC_ADMIN'] = USER_ACTIVATION_ADMIN; + } + $act_options = ''; - $radio_text = h_radio('config[require_activation]', $radio_ary, $value, 'require_activation', $key, '
      '); + foreach ($act_ary as $key => $value) + { + $selected = ($selected_value == $value) ? ' selected="selected"' : ''; + $act_options .= ''; + } - return $radio_text; + return $act_options; } /** diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php index 1893eed14f6..469a367bbab 100644 --- a/phpBB/includes/acp/acp_captcha.php +++ b/phpBB/includes/acp/acp_captcha.php @@ -96,7 +96,7 @@ function main($id, $mode) } else if ($submit) { - trigger_error($user->lang['FORM_INVALID'] . adm_back_link(), E_USER_WARNING); + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } else { diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php index 62bcd43a474..758cd104342 100644 --- a/phpBB/includes/acp/acp_database.php +++ b/phpBB/includes/acp/acp_database.php @@ -21,6 +21,7 @@ */ class acp_database { + var $db_tools; var $u_action; function main($id, $mode) @@ -28,6 +29,12 @@ function main($id, $mode) global $cache, $db, $user, $auth, $template, $table_prefix; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; + if (!class_exists('phpbb_db_tools')) + { + require($phpbb_root_path . 'includes/db/db_tools.' . $phpEx); + } + $this->db_tools = new phpbb_db_tools($db); + $user->add_lang('acp/database'); $this->tpl_name = 'acp_database'; @@ -50,7 +57,7 @@ function main($id, $mode) { case 'download': $type = request_var('type', ''); - $table = request_var('table', array('')); + $table = array_intersect($this->db_tools->sql_list_tables(), request_var('table', array(''))); $format = request_var('method', ''); $where = request_var('where', ''); @@ -173,8 +180,7 @@ function main($id, $mode) break; default: - include($phpbb_root_path . 'includes/functions_install.' . $phpEx); - $tables = get_tables($db); + $tables = $this->db_tools->sql_list_tables(); asort($tables); foreach ($tables as $table_name) { diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index c8df21f5a90..cffe296651a 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -201,7 +201,7 @@ function main($id, $mode) // No maximum post id? :o if (!$max_post_id) { - $sql = 'SELECT MAX(post_id) + $sql = 'SELECT MAX(post_id) as max_post_id FROM ' . POSTS_TABLE; $result = $db->sql_query($sql); $max_post_id = (int) $db->sql_fetchfield('max_post_id'); @@ -398,11 +398,11 @@ function main($id, $mode) // Version check $user->add_lang('install'); - if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.2.0', '<')) + if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.3.2', '<')) { $template->assign_vars(array( 'S_PHP_VERSION_OLD' => true, - 'L_PHP_VERSION_OLD' => sprintf($user->lang['PHP_VERSION_OLD'], '', ''), + 'L_PHP_VERSION_OLD' => sprintf($user->lang['PHP_VERSION_OLD'], '', ''), )); } diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index 2e43b0545af..19223847f06 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -365,6 +365,7 @@ function main($id, $mode) $field_row = array_merge($default_values[$field_type], array( 'field_ident' => str_replace(' ', '_', utf8_clean_string(request_var('field_ident', '', true))), 'field_required' => 0, + 'field_show_novalue'=> 0, 'field_hide' => 0, 'field_show_profile'=> 0, 'field_no_view' => 0, @@ -380,7 +381,7 @@ function main($id, $mode) // $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_vt', 'field_required', '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_vt', 'field_required', 'field_show_novalue', 'field_hide', 'field_show_profile', 'field_no_view'), 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') ); @@ -405,6 +406,7 @@ function main($id, $mode) // Visibility Options... $visibility_ary = array( 'field_required', + 'field_show_novalue', 'field_show_on_reg', 'field_show_on_vt', 'field_show_profile', @@ -504,11 +506,34 @@ function main($id, $mode) } } } - /* else if ($field_type == FIELD_BOOL && $key == 'field_default_value') + else if ($field_type == FIELD_BOOL && $key == 'field_default_value') { - // Get the number of options if this key is 'field_maxlen' - $var = request_var('field_default_value', 0); - }*/ + // '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 @@ -676,6 +701,10 @@ function main($id, $mode) { $_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 { if (!isset($_REQUEST[$key])) @@ -730,6 +759,7 @@ function main($id, $mode) $template->assign_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_VT' => ($cp->vars['field_show_on_vt']) ? true : false, 'S_FIELD_HIDE' => ($cp->vars['field_hide']) ? true : false, @@ -1046,6 +1076,7 @@ function save_profile_field(&$cp, $field_type, $action = 'create') 'field_default_value' => $cp->vars['field_default_value'], 'field_validation' => $cp->vars['field_validation'], 'field_required' => $cp->vars['field_required'], + 'field_show_novalue' => $cp->vars['field_show_novalue'], 'field_show_on_reg' => $cp->vars['field_show_on_reg'], 'field_show_on_vt' => $cp->vars['field_show_on_vt'], 'field_hide' => $cp->vars['field_hide'], diff --git a/phpBB/includes/acp/acp_ranks.php b/phpBB/includes/acp/acp_ranks.php index dfd75114273..ea057cd84c2 100644 --- a/phpBB/includes/acp/acp_ranks.php +++ b/phpBB/includes/acp/acp_ranks.php @@ -52,7 +52,7 @@ function main($id, $mode) } $rank_title = utf8_normalize_nfc(request_var('title', '', true)); $special_rank = request_var('special_rank', 0); - $min_posts = ($special_rank) ? 0 : request_var('min_posts', 0); + $min_posts = ($special_rank) ? 0 : max(0, request_var('min_posts', 0)); $rank_image = request_var('rank_image', ''); // The rank image has to be a jpg, gif or png diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 53002656863..47cd02bca7e 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -99,11 +99,11 @@ function main($id, $mode) $this->template_cfg .= ' # Some configuration options -# -# You can use this function to inherit templates from another template. -# The template of the given name has to be installed. -# Templates cannot inherit from inheriting templates. -#'; +# Template inheritance +# See http://blog.phpbb.com/2008/07/31/templating-just-got-easier/ +# Set value to empty or this template name to ignore template inheritance. +inherit_from = {INHERIT_FROM} +'; $this->imageset_keys = array( 'logos' => array( @@ -540,12 +540,14 @@ function frontend($mode, $options, $actions) global $user, $template, $db, $config, $phpbb_root_path, $phpEx; $sql_from = ''; + $sql_sort = 'LOWER(' . $mode . '_name)'; $style_count = array(); switch ($mode) { case 'style': $sql_from = STYLES_TABLE; + $sql_sort = 'style_active DESC, ' . $sql_sort; $sql = 'SELECT user_style, COUNT(user_style) AS style_count FROM ' . USERS_TABLE . ' @@ -571,6 +573,9 @@ function frontend($mode, $options, $actions) case 'imageset': $sql_from = STYLES_IMAGESET_TABLE; break; + + default: + trigger_error($user->lang['NO_MODE'] . adm_back_link($this->u_action), E_USER_WARNING); } $l_prefix = strtoupper($mode); @@ -594,7 +599,8 @@ function frontend($mode, $options, $actions) ); $sql = "SELECT * - FROM $sql_from"; + FROM $sql_from + ORDER BY $sql_sort ASC"; $result = $db->sql_query($sql); $installed = array(); @@ -630,6 +636,8 @@ function frontend($mode, $options, $actions) 'NAME' => $row[$mode . '_name'], 'STYLE_COUNT' => ($mode == 'style' && isset($style_count[$row['style_id']])) ? $style_count[$row['style_id']] : 0, + + 'S_INACTIVE' => ($mode == 'style' && !$row['style_active']) ? true : false, ) ); } @@ -659,7 +667,9 @@ function frontend($mode, $options, $actions) if ($name && !in_array($name, $installed)) { - $new_ary[] = array( + // The array key is used for sorting later on. + // $file is appended because $name doesn't have to be unique. + $new_ary[$name . $file] = array( 'path' => $file, 'name' => $name, 'copyright' => $items['copyright'], @@ -675,6 +685,8 @@ function frontend($mode, $options, $actions) if (sizeof($new_ary)) { + ksort($new_ary); + foreach ($new_ary as $cfg) { $template->assign_block_vars('uninstalled', array( @@ -2039,9 +2051,7 @@ function export($mode, $style_id) // Export template core code if ($mode == 'template' || $inc_template) { - $template_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}'), array($mode, $style_row['template_name'], $style_row['template_copyright'], $config['version']), $this->template_cfg); - - $use_template_name = ''; + $use_template_name = $style_row['template_name']; // Add the inherit from variable, depending on it's use... if ($style_row['template_inherits_id']) @@ -2055,7 +2065,8 @@ function export($mode, $style_id) $db->sql_freeresult($result); } - $template_cfg .= ($use_template_name) ? "\ninherit_from = $use_template_name" : "\n#inherit_from = "; + $template_cfg = str_replace(array('{MODE}', '{NAME}', '{COPYRIGHT}', '{VERSION}', '{INHERIT_FROM}'), array($mode, $style_row['template_name'], $style_row['template_copyright'], $config['version'], $use_template_name), $this->template_cfg); + $template_cfg .= "\n\nbbcode_bitfield = {$style_row['bbcode_bitfield']}"; $data[] = array( diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 4f58434a436..70e08f79f20 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1009,6 +1009,13 @@ function main($id, $mode) $user_row['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue'); $db->sql_freeresult($result); + $sql = 'SELECT post_id + FROM ' . POSTS_TABLE . ' + WHERE poster_id = '. $user_id; + $result = $db->sql_query_limit($sql, 1); + $user_row['user_has_posts'] = (bool) $db->sql_fetchfield('post_id'); + $db->sql_freeresult($result); + $template->assign_vars(array( 'L_NAME_CHARS_EXPLAIN' => sprintf($user->lang[$config['allow_name_chars'] . '_EXPLAIN'], $config['min_name_chars'], $config['max_name_chars']), 'L_CHANGE_PASSWORD_EXPLAIN' => sprintf($user->lang[$config['pass_complex'] . '_EXPLAIN'], $config['min_pass_chars'], $config['max_pass_chars']), @@ -1036,6 +1043,7 @@ function main($id, $mode) 'USER_EMAIL' => $user_row['user_email'], 'USER_WARNINGS' => $user_row['user_warnings'], 'USER_POSTS' => $user_row['user_posts'], + 'USER_HAS_POSTS' => $user_row['user_has_posts'], 'USER_INACTIVE_REASON' => $inactive_reason, )); @@ -2339,47 +2347,62 @@ function main($id, $mode) } /** - * Optionset replacement for this module based on $user->optionset + * Set option bit field for user options in a user row array. + * + * Optionset replacement for this module based on $user->optionset. + * + * @param array $user_row Row from the users table. + * @param int $key Option key, as defined in $user->keyoptions property. + * @param bool $value True to set the option, false to clear the option. + * @param int $data Current bit field value, or false to use $user_row['user_options'] + * @return int|bool If $data is false, the bit field is modified and + * written back to $user_row['user_options'], and + * return value is true if the bit field changed and + * false otherwise. If $data is not false, the new + * bitfield value is returned. */ function optionset(&$user_row, $key, $value, $data = false) { global $user; - $var = ($data) ? $data : $user_row['user_options']; + $var = ($data !== false) ? $data : $user_row['user_options']; - if ($value && !($var & 1 << $user->keyoptions[$key])) - { - $var += 1 << $user->keyoptions[$key]; - } - else if (!$value && ($var & 1 << $user->keyoptions[$key])) - { - $var -= 1 << $user->keyoptions[$key]; - } - else - { - return ($data) ? $var : false; - } + $new_var = phpbb_optionset($user->keyoptions[$key], $value, $var); - if (!$data) + if ($data === false) { - $user_row['user_options'] = $var; - return true; + if ($new_var != $var) + { + $user_row['user_options'] = $new_var; + return true; + } + else + { + return false; + } } else { - return $var; + return $new_var; } } /** - * Optionget replacement for this module based on $user->optionget + * Get option bit field from user options in a user row array. + * + * Optionget replacement for this module based on $user->optionget. + * + * @param array $user_row Row from the users table. + * @param int $key option key, as defined in $user->keyoptions property. + * @param int $data bit field value to use, or false to use $user_row['user_options'] + * @return bool true if the option is set in the bit field, false otherwise */ function optionget(&$user_row, $key, $data = false) { global $user; - $var = ($data) ? $data : $user_row['user_options']; - return ($var & 1 << $user->keyoptions[$key]) ? true : false; + $var = ($data !== false) ? $data : $user_row['user_options']; + return phpbb_optionget($user->keyoptions[$key], $var); } } diff --git a/phpBB/includes/auth/auth_db.php b/phpBB/includes/auth/auth_db.php index c20196d019d..1c6cdf78325 100644 --- a/phpBB/includes/auth/auth_db.php +++ b/phpBB/includes/auth/auth_db.php @@ -163,7 +163,7 @@ function login_db($username, $password, $ip = '', $browser = '', $forwarded_for $password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format; $password_new_format = ''; - set_var($password_new_format, stripslashes($password_old_format), 'string'); + set_var($password_new_format, stripslashes($password_old_format), 'string', true); if ($password == $password_new_format) { diff --git a/phpBB/includes/auth/auth_ldap.php b/phpBB/includes/auth/auth_ldap.php index 5dfa74ddab0..eebf147d48e 100644 --- a/phpBB/includes/auth/auth_ldap.php +++ b/phpBB/includes/auth/auth_ldap.php @@ -156,7 +156,11 @@ function login_ldap(&$username, &$password) { if (!@ldap_bind($ldap, htmlspecialchars_decode($config['ldap_user']), htmlspecialchars_decode($config['ldap_password']))) { - return $user->lang['LDAP_NO_SERVER_CONNECTION']; + return array( + 'status' => LOGIN_ERROR_EXTERNAL_AUTH, + 'error_msg' => 'LDAP_NO_SERVER_CONNECTION', + 'user_row' => array('user_id' => ANONYMOUS), + ); } } diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index b70cf5bc591..54e5e2632d4 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -25,7 +25,7 @@ */ // phpBB Version -define('PHPBB_VERSION', '3.0.10'); +define('PHPBB_VERSION', '3.0.11'); // QA-related // define('PHPBB_QA', 1); diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index 2cba11133a2..c6dd23e6bd3 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -2115,7 +2115,7 @@ function sql_create_unique_index($table_name, $index_name, $column) case 'mysql_40': case 'mysql_41': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX (' . implode(', ', $column) . ')'; + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; break; case 'mssql': diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index b4c1a72e1c8..9cc337955bf 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -194,6 +194,49 @@ function sql_fetchrowset($query_id = false) return false; } + /** + * Seek to given row number + * rownum is zero-based + */ + function sql_rowseek($rownum, &$query_id) + { + global $cache; + + if ($query_id === false) + { + $query_id = $this->query_result; + } + + if (isset($cache->sql_rowset[$query_id])) + { + return $cache->sql_rowseek($rownum, $query_id); + } + + if ($query_id === false) + { + return false; + } + + $this->sql_freeresult($query_id); + $query_id = $this->sql_query($this->last_query_text); + + if ($query_id === false) + { + return false; + } + + // We do not fetch the row for rownum == 0 because then the next resultset would be the second row + for ($i = 0; $i < $rownum; $i++) + { + if (!$this->sql_fetchrow($query_id)) + { + return false; + } + } + + return true; + } + /** * Fetch field * if rownum is false, the current row is used, else it is pointing to the row (zero-based) @@ -457,6 +500,18 @@ function sql_bit_or($column_name, $bit, $compare = '') return $column_name . ' | ' . (1 << $bit) . (($compare) ? ' ' . $compare : ''); } + /** + * 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)" + */ + function sql_lower_text($column_name) + { + return "LOWER($column_name)"; + } + /** * Run more than one insert statement. * @@ -662,12 +717,7 @@ function sql_error($sql = '') // The DEBUG_EXTRA constant is for development only! if ((isset($auth) && $auth->acl_get('a_')) || defined('IN_INSTALL') || defined('DEBUG_EXTRA')) { - // Print out a nice backtrace... - $backtrace = get_backtrace(); - $message .= ($sql) ? '

      SQL

      ' . htmlspecialchars($sql) : ''; - $message .= ($backtrace) ? '

      BACKTRACE
      ' . $backtrace : ''; - $message .= '
      '; } else { @@ -905,6 +955,41 @@ function sql_report($mode, $query = '') return true; } + + /** + * 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 + */ + function get_estimated_row_count($table_name) + { + return $this->get_row_count($table_name); + } + + /** + * 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 + */ + function get_row_count($table_name) + { + $sql = 'SELECT COUNT(*) AS rows_total + FROM ' . $this->sql_escape($table_name); + $result = $this->sql_query($sql); + $rows_total = $this->sql_fetchfield('rows_total'); + $this->sql_freeresult($result); + + return $rows_total; + } } /** diff --git a/phpBB/includes/db/firebird.php b/phpBB/includes/db/firebird.php index 7e3f15ed1d0..7072c58ac0d 100644 --- a/phpBB/includes/db/firebird.php +++ b/phpBB/includes/db/firebird.php @@ -359,49 +359,6 @@ function sql_fetchrow($query_id = false) return (sizeof($row)) ? $row : false; } - /** - * Seek to given row number - * rownum is zero-based - */ - function sql_rowseek($rownum, &$query_id) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if (isset($cache->sql_rowset[$query_id])) - { - return $cache->sql_rowseek($rownum, $query_id); - } - - if ($query_id === false) - { - return; - } - - $this->sql_freeresult($query_id); - $query_id = $this->sql_query($this->last_query_text); - - if ($query_id === false) - { - return false; - } - - // We do not fetch the row for rownum == 0 because then the next resultset would be the second row - for ($i = 0; $i < $rownum; $i++) - { - if (!$this->sql_fetchrow($query_id)) - { - return false; - } - } - - return true; - } - /** * Get last inserted id after insert statement */ diff --git a/phpBB/includes/db/mssql.php b/phpBB/includes/db/mssql.php index 6899a739024..b7178593dc9 100644 --- a/phpBB/includes/db/mssql.php +++ b/phpBB/includes/db/mssql.php @@ -332,6 +332,14 @@ function sql_escape($msg) return str_replace(array("'", "\0"), array("''", ''), $msg); } + /** + * {@inheritDoc} + */ + function sql_lower_text($column_name) + { + return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; + } + /** * Build LIKE expression * @access private diff --git a/phpBB/includes/db/mssql_odbc.php b/phpBB/includes/db/mssql_odbc.php index 75a080b1b77..2ecc42cadf5 100644 --- a/phpBB/includes/db/mssql_odbc.php +++ b/phpBB/includes/db/mssql_odbc.php @@ -255,49 +255,6 @@ function sql_fetchrow($query_id = false, $debug = false) return ($query_id !== false) ? @odbc_fetch_array($query_id) : false; } - /** - * Seek to given row number - * rownum is zero-based - */ - function sql_rowseek($rownum, &$query_id) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if (isset($cache->sql_rowset[$query_id])) - { - return $cache->sql_rowseek($rownum, $query_id); - } - - if ($query_id === false) - { - return false; - } - - $this->sql_freeresult($query_id); - $query_id = $this->sql_query($this->last_query_text); - - if ($query_id === false) - { - return false; - } - - // We do not fetch the row for rownum == 0 because then the next resultset would be the second row - for ($i = 0; $i < $rownum; $i++) - { - if (!$this->sql_fetchrow($query_id)) - { - return false; - } - } - - return true; - } - /** * Get last inserted id after insert statement */ @@ -353,6 +310,14 @@ function sql_escape($msg) return str_replace(array("'", "\0"), array("''", ''), $msg); } + /** + * {@inheritDoc} + */ + function sql_lower_text($column_name) + { + return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; + } + /** * Build LIKE expression * @access private diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index 7fbc374e77d..c91cc188b0c 100644 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -439,24 +439,6 @@ function sql_fetchrow($query_id = false) return $row; } - /** - * Seek to given row number - * rownum is zero-based - */ - function sql_rowseek($rownum, &$query_id) - { - global $cache; - - if (isset($cache->sql_rowset[$query_id])) - { - return $cache->sql_rowseek($rownum, $query_id); - } - - $seek = new result_mssqlnative($query_id); - $row = $seek->seek($rownum); - return ($row = $seek->fetch()) ? $row : false; - } - /** * Get last inserted id after insert statement */ @@ -510,6 +492,14 @@ function sql_escape($msg) return str_replace(array("'", "\0"), array("''", ''), $msg); } + /** + * {@inheritDoc} + */ + function sql_lower_text($column_name) + { + return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; + } + /** * Build LIKE expression * @access private diff --git a/phpBB/includes/db/mysql.php b/phpBB/includes/db/mysql.php index 1e24c795775..1ccb785150a 100644 --- a/phpBB/includes/db/mysql.php +++ b/phpBB/includes/db/mysql.php @@ -318,6 +318,76 @@ function sql_escape($msg) return @mysql_real_escape_string($msg, $this->db_connect_id); } + /** + * 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 + */ + function get_estimated_row_count($table_name) + { + $table_status = $this->get_table_status($table_name); + + if (isset($table_status['Engine'])) + { + if ($table_status['Engine'] === 'MyISAM') + { + return $table_status['Rows']; + } + else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000) + { + return '~' . $table_status['Rows']; + } + } + + return parent::get_row_count($table_name); + } + + /** + * 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 + */ + function get_row_count($table_name) + { + $table_status = $this->get_table_status($table_name); + + if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM') + { + return $table_status['Rows']; + } + + return parent::get_row_count($table_name); + } + + /** + * Gets some information about the specified table. + * + * @param string $table_name Table name + * + * @return array + * + * @access protected + */ + function get_table_status($table_name) + { + $sql = "SHOW TABLE STATUS + LIKE '" . $this->sql_escape($table_name) . "'"; + $result = $this->sql_query($sql); + $table_status = $this->sql_fetchrow($result); + $this->sql_freeresult($result); + + return $table_status; + } + /** * Build LIKE expression * @access private diff --git a/phpBB/includes/db/mysqli.php b/phpBB/includes/db/mysqli.php index 456ce906d0a..a311b8cda6e 100644 --- a/phpBB/includes/db/mysqli.php +++ b/phpBB/includes/db/mysqli.php @@ -315,6 +315,76 @@ function sql_escape($msg) return @mysqli_real_escape_string($this->db_connect_id, $msg); } + /** + * 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 + */ + function get_estimated_row_count($table_name) + { + $table_status = $this->get_table_status($table_name); + + if (isset($table_status['Engine'])) + { + if ($table_status['Engine'] === 'MyISAM') + { + return $table_status['Rows']; + } + else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000) + { + return '~' . $table_status['Rows']; + } + } + + return parent::get_row_count($table_name); + } + + /** + * 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 + */ + function get_row_count($table_name) + { + $table_status = $this->get_table_status($table_name); + + if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM') + { + return $table_status['Rows']; + } + + return parent::get_row_count($table_name); + } + + /** + * Gets some information about the specified table. + * + * @param string $table_name Table name + * + * @return array + * + * @access protected + */ + function get_table_status($table_name) + { + $sql = "SHOW TABLE STATUS + LIKE '" . $this->sql_escape($table_name) . "'"; + $result = $this->sql_query($sql); + $table_status = $this->sql_fetchrow($result); + $this->sql_freeresult($result); + + return $table_status; + } + /** * Build LIKE expression * @access private diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 01b3ca92a99..59148315398 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1918,14 +1918,17 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti } else { - $sql = 'SELECT t.forum_id FROM ' . TOPICS_TABLE . ' t - LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt ON (tt.topic_id = t.topic_id AND tt.user_id = ' . $user->data['user_id'] . ') + $sql = 'SELECT t.forum_id + FROM ' . TOPICS_TABLE . ' t + LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt + ON (tt.topic_id = t.topic_id + AND tt.user_id = ' . $user->data['user_id'] . ') WHERE t.forum_id = ' . $forum_id . ' AND t.topic_last_post_time > ' . $mark_time_forum . ' AND t.topic_moved_id = 0 ' . $sql_update_unapproved . ' - AND (tt.topic_id IS NULL OR tt.mark_time < t.topic_last_post_time) - GROUP BY t.forum_id'; + AND (tt.topic_id IS NULL + OR tt.mark_time < t.topic_last_post_time)'; $result = $db->sql_query_limit($sql, 1); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); @@ -3322,6 +3325,11 @@ function parse_cfg_file($filename, $lines = false) $parsed_items[$key] = $value; } + + if (isset($parsed_items['inherit_from']) && isset($parsed_items['name']) && $parsed_items['inherit_from'] == $parsed_items['name']) + { + unset($parsed_items['inherit_from']); + } return $parsed_items; } @@ -3448,7 +3456,7 @@ function get_preg_expression($mode) case 'email': // Regex written by James Watts and Francisco Jose Martin Moreno // http://fightingforalostcause.net/misc/2006/compare-email-regex.php - return '([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)'; + return '([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)'; break; case 'bbcode_htm': @@ -3853,11 +3861,23 @@ function msg_handler($errno, $msg_text, $errfile, $errline) } } + $log_text = $msg_text; + $backtrace = get_backtrace(); + if ($backtrace) + { + $log_text .= '

      BACKTRACE
      ' . $backtrace; + } + + if (defined('IN_INSTALL') || defined('DEBUG_EXTRA') || isset($auth) && $auth->acl_get('a_')) + { + $msg_text = $log_text; + } + if ((defined('DEBUG') || defined('IN_CRON') || defined('IMAGE_OUTPUT')) && isset($db)) { // let's avoid loops $db->sql_return_on_error(true); - add_log('critical', 'LOG_GENERAL_ERROR', $msg_title, $msg_text); + add_log('critical', 'LOG_GENERAL_ERROR', $msg_title, $log_text); $db->sql_return_on_error(false); } @@ -4536,7 +4556,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 foreach ($_EXTRA_URL as $url_param) { $url_param = explode('=', $url_param, 2); - $s_hidden_fields[$url_param[0]] = $url_param[1]; + $s_search_hidden_fields[$url_param[0]] = $url_param[1]; } } @@ -4631,11 +4651,11 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'S_SEARCH_HIDDEN_FIELDS' => build_hidden_fields($s_search_hidden_fields), - 'T_THEME_PATH' => "{$web_path}styles/" . $user->theme['theme_path'] . '/theme', - 'T_TEMPLATE_PATH' => "{$web_path}styles/" . $user->theme['template_path'] . '/template', - 'T_SUPER_TEMPLATE_PATH' => (isset($user->theme['template_inherit_path']) && $user->theme['template_inherit_path']) ? "{$web_path}styles/" . $user->theme['template_inherit_path'] . '/template' : "{$web_path}styles/" . $user->theme['template_path'] . '/template', - 'T_IMAGESET_PATH' => "{$web_path}styles/" . $user->theme['imageset_path'] . '/imageset', - 'T_IMAGESET_LANG_PATH' => "{$web_path}styles/" . $user->theme['imageset_path'] . '/imageset/' . $user->lang_name, + 'T_THEME_PATH' => "{$web_path}styles/" . rawurlencode($user->theme['theme_path']) . '/theme', + 'T_TEMPLATE_PATH' => "{$web_path}styles/" . rawurlencode($user->theme['template_path']) . '/template', + 'T_SUPER_TEMPLATE_PATH' => (isset($user->theme['template_inherit_path']) && $user->theme['template_inherit_path']) ? "{$web_path}styles/" . rawurlencode($user->theme['template_inherit_path']) . '/template' : "{$web_path}styles/" . rawurlencode($user->theme['template_path']) . '/template', + 'T_IMAGESET_PATH' => "{$web_path}styles/" . rawurlencode($user->theme['imageset_path']) . '/imageset', + 'T_IMAGESET_LANG_PATH' => "{$web_path}styles/" . rawurlencode($user->theme['imageset_path']) . '/imageset/' . $user->lang_name, 'T_IMAGES_PATH' => "{$web_path}images/", 'T_SMILIES_PATH' => "{$web_path}{$config['smilies_path']}/", 'T_AVATAR_PATH' => "{$web_path}{$config['avatar_path']}/", @@ -4643,13 +4663,13 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'T_ICONS_PATH' => "{$web_path}{$config['icons_path']}/", 'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/", 'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/", - 'T_STYLESHEET_LINK' => (!$user->theme['theme_storedb']) ? "{$web_path}styles/" . $user->theme['theme_path'] . '/theme/stylesheet.css' : append_sid("{$phpbb_root_path}style.$phpEx", 'id=' . $user->theme['style_id'] . '&lang=' . $user->lang_name), + 'T_STYLESHEET_LINK' => (!$user->theme['theme_storedb']) ? "{$web_path}styles/" . rawurlencode($user->theme['theme_path']) . '/theme/stylesheet.css' : append_sid("{$phpbb_root_path}style.$phpEx", 'id=' . $user->theme['style_id'] . '&lang=' . $user->lang_name), 'T_STYLESHEET_NAME' => $user->theme['theme_name'], - 'T_THEME_NAME' => $user->theme['theme_path'], - 'T_TEMPLATE_NAME' => $user->theme['template_path'], - 'T_SUPER_TEMPLATE_NAME' => (isset($user->theme['template_inherit_path']) && $user->theme['template_inherit_path']) ? $user->theme['template_inherit_path'] : $user->theme['template_path'], - 'T_IMAGESET_NAME' => $user->theme['imageset_path'], + 'T_THEME_NAME' => rawurlencode($user->theme['theme_path']), + 'T_TEMPLATE_NAME' => rawurlencode($user->theme['template_path']), + 'T_SUPER_TEMPLATE_NAME' => rawurlencode((isset($user->theme['template_inherit_path']) && $user->theme['template_inherit_path']) ? $user->theme['template_inherit_path'] : $user->theme['template_path']), + 'T_IMAGESET_NAME' => rawurlencode($user->theme['imageset_path']), 'T_IMAGESET_LANG_NAME' => $user->data['user_lang'], 'T_IMAGES' => 'images', 'T_SMILIES' => $config['smilies_path'], @@ -4721,6 +4741,7 @@ function page_footer($run_cron = true) $template->assign_vars(array( 'DEBUG_OUTPUT' => (defined('DEBUG')) ? $debug_output : '', 'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '', + 'CREDIT_LINE' => $user->lang('POWERED_BY', 'phpBB® Forum Software © phpBB Group'), 'U_ACP' => ($auth->acl_get('a_') && !empty($user->data['is_registered'])) ? append_sid("{$phpbb_root_path}adm/index.$phpEx", false, true, $user->session_id) : '') ); diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 526bc16ff08..7352b3d1f3b 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2296,35 +2296,15 @@ function auto_prune($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_fr /** * remove_comments will strip the sql comment lines out of an uploaded sql file * specifically for mssql and postgres type files in the install.... +* +* @deprecated Use phpbb_remove_comments() instead. */ function remove_comments(&$output) { - $lines = explode("\n", $output); - $output = ''; - - // try to keep mem. use down - $linecount = sizeof($lines); - - $in_comment = false; - for ($i = 0; $i < $linecount; $i++) - { - if (trim($lines[$i]) == '/*') - { - $in_comment = true; - } - - if (!$in_comment) - { - $output .= $lines[$i] . "\n"; - } - - if (trim($lines[$i]) == '*/') - { - $in_comment = false; - } - } + // Remove /* */ comments (http://ostermiller.org/findcomment.html) + $output = preg_replace('#/\*(.|[\r\n])*?\*/#', "\n", $output); - unset($lines); + // Return by reference and value. return $output; } @@ -2592,7 +2572,8 @@ function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id { $sql_keywords .= $db->sql_in_set('l.log_operation', $operations) . ' OR '; } - $sql_keywords .= 'LOWER(l.log_data) ' . implode(' OR LOWER(l.log_data) ', $keywords) . ')'; + $sql_lower = $db->sql_lower_text('l.log_data'); + $sql_keywords .= "$sql_lower " . implode(" OR $sql_lower ", $keywords) . ')'; } if ($log_count !== false) diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php index 4a359dcade8..3b26f417e90 100644 --- a/phpBB/includes/functions_convert.php +++ b/phpBB/includes/functions_convert.php @@ -424,7 +424,8 @@ function import_avatar_gallery($gallery_name = '', $subdirs_as_galleries = false $relative_path = empty($convert->convertor['source_path_absolute']); - if (empty($convert->convertor['avatar_gallery_path'])) + // check for trailing slash + if (rtrim($convert->convertor['avatar_gallery_path'], '/') === '') { $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_GALLERY_PATH'], 'import_avatar_gallery()'), __LINE__, __FILE__); } @@ -588,7 +589,8 @@ function import_attachment($source, $use_target = false) global $convert, $phpbb_root_path, $config, $user; - if (empty($convert->convertor['upload_path'])) + // check for trailing slash + if (rtrim($convert->convertor['upload_path'], '/') === '') { $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_UPLOAD_DIR'], 'import_attachment()'), __LINE__, __FILE__); } @@ -647,7 +649,8 @@ function import_smiley($source, $use_target = false) global $convert, $phpbb_root_path, $config, $user; - if (!isset($convert->convertor['smilies_path'])) + // check for trailing slash + if (rtrim($convert->convertor['smilies_path'], '/') === '') { $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_SMILIES_PATH'], 'import_smiley()'), __LINE__, __FILE__); } @@ -667,7 +670,8 @@ function import_avatar($source, $use_target = false, $user_id = false) global $convert, $phpbb_root_path, $config, $user; - if (!isset($convert->convertor['avatar_path'])) + // check for trailing slash + if (rtrim($convert->convertor['avatar_path'], '/') === '') { $convert->p_master->error(sprintf($user->lang['CONV_ERROR_NO_AVATAR_PATH'], 'import_avatar()'), __LINE__, __FILE__); } diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index 2c640e09996..89dfb7cd2f8 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -473,11 +473,40 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix, } /** -* remove_remarks will strip the sql comment lines out of an uploaded sql file +* Removes comments from schema files +* +* @deprecated Use phpbb_remove_comments() instead. */ function remove_remarks(&$sql) { + // Remove # style comments $sql = preg_replace('/\n{2,}/', "\n", preg_replace('/^#.*$/m', "\n", $sql)); + + // Return by reference +} + +/** +* Removes "/* style" as well as "# style" comments from $input. +* +* @param string $input Input string +* +* @return string Input string with comments removed +*/ +function phpbb_remove_comments($input) +{ + if (!function_exists('remove_comments')) + { + global $phpbb_root_path, $phpEx; + require($phpbb_root_path . 'includes/functions_admin.' . $phpEx); + } + + // Remove /* */ comments + remove_comments($input); + + // Remove # style comments + remove_remarks($input); + + return $input; } /** @@ -515,4 +544,54 @@ function adjust_language_keys_callback($matches) } } +/** +* Creates the output to be stored in a phpBB config.php file +* +* @param array $data Array containing the database connection information +* @param string $dbms The name of the DBAL class to use +* @param array $load_extensions Array of additional extensions that should be loaded +* @param bool $debug If the debug constants should be enabled by default or not +* +* @return string The output to write to the file +*/ +function phpbb_create_config_file_data($data, $dbms, $load_extensions, $debug = false) +{ + $load_extensions = implode(',', $load_extensions); + + $config_data = " $dbms, + 'dbhost' => $data['dbhost'], + 'dbport' => $data['dbport'], + 'dbname' => $data['dbname'], + 'dbuser' => $data['dbuser'], + 'dbpasswd' => htmlspecialchars_decode($data['dbpasswd']), + 'table_prefix' => $data['table_prefix'], + 'acm_type' => 'file', + 'load_extensions' => $load_extensions, + ); + + foreach ($config_data_array as $key => $value) + { + $config_data .= "\${$key} = '" . str_replace("'", "\\'", str_replace('\\', '\\\\', $value)) . "';\n"; + } + + $config_data .= "\n@define('PHPBB_INSTALLED', true);\n"; + + if ($debug) + { + $config_data .= "@define('DEBUG', true);\n"; + $config_data .= "@define('DEBUG_EXTRA', true);\n"; + } + else + { + $config_data .= "// @define('DEBUG', true);\n"; + $config_data .= "// @define('DEBUG_EXTRA', true);\n"; + } + + return $config_data; +} + ?> \ No newline at end of file diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 91b361183cb..65496933337 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -568,7 +568,7 @@ function msg_jabber() if (!$use_queue) { include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx); - $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], $config['jab_password'], $config['jab_use_ssl']); + $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl']); if (!$this->jabber->connect()) { @@ -769,7 +769,7 @@ function process() } include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx); - $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], $config['jab_password'], $config['jab_use_ssl']); + $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl']); if (!$this->jabber->connect()) { @@ -1022,7 +1022,7 @@ function smtpmail($addresses, $subject, $message, &$err_msg, $headers = false) } // Let me in. This function handles the complete authentication process - if ($err_msg = $smtp->log_into_server($config['smtp_host'], $config['smtp_username'], $config['smtp_password'], $config['smtp_auth_method'])) + if ($err_msg = $smtp->log_into_server($config['smtp_host'], $config['smtp_username'], htmlspecialchars_decode($config['smtp_password']), $config['smtp_auth_method'])) { $smtp->close_session($err_msg); return false; diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 77d92e26e23..68b6199cf56 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -497,7 +497,14 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage { if ($free_space <= $file->get('filesize')) { - $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED']; + if ($auth->acl_get('a_')) + { + $filedata['error'][] = $user->lang['ATTACH_DISK_FULL']; + } + else + { + $filedata['error'][] = $user->lang['ATTACH_QUOTA_REACHED']; + } $filedata['post_attach'] = false; $file->remove(); @@ -1180,36 +1187,32 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id $topic_title = ($topic_notification) ? $topic_title : $subject; $topic_title = censor_text($topic_title); - // Get banned User ID's - $sql = 'SELECT ban_userid - FROM ' . BANLIST_TABLE . ' - WHERE ban_userid <> 0 - AND ban_exclude <> 1'; - $result = $db->sql_query($sql); - - $sql_ignore_users = ANONYMOUS . ', ' . $user->data['user_id']; - while ($row = $db->sql_fetchrow($result)) + // Exclude guests, current user and banned users from notifications + if (!function_exists('phpbb_get_banned_user_ids')) { - $sql_ignore_users .= ', ' . (int) $row['ban_userid']; + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); } - $db->sql_freeresult($result); + $sql_ignore_users = phpbb_get_banned_user_ids(); + $sql_ignore_users[ANONYMOUS] = ANONYMOUS; + $sql_ignore_users[$user->data['user_id']] = $user->data['user_id']; $notify_rows = array(); // -- get forum_userids || topic_userids $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber FROM ' . (($topic_notification) ? TOPICS_WATCH_TABLE : FORUMS_WATCH_TABLE) . ' w, ' . USERS_TABLE . ' u - WHERE w.' . (($topic_notification) ? 'topic_id' : 'forum_id') . ' = ' . (($topic_notification) ? $topic_id : $forum_id) . " - AND w.user_id NOT IN ($sql_ignore_users) - AND w.notify_status = " . NOTIFY_YES . ' + WHERE w.' . (($topic_notification) ? 'topic_id' : 'forum_id') . ' = ' . (($topic_notification) ? $topic_id : $forum_id) . ' + AND ' . $db->sql_in_set('w.user_id', $sql_ignore_users, true) . ' + AND w.notify_status = ' . NOTIFY_YES . ' AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ') AND u.user_id = w.user_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { - $notify_rows[$row['user_id']] = array( - 'user_id' => $row['user_id'], + $notify_user_id = (int) $row['user_id']; + $notify_rows[$notify_user_id] = array( + 'user_id' => $notify_user_id, 'username' => $row['username'], 'user_email' => $row['user_email'], 'user_jabber' => $row['user_jabber'], @@ -1219,30 +1222,29 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id 'method' => $row['user_notify_type'], 'allowed' => false ); + + // Add users who have been already notified to ignore list + $sql_ignore_users[$notify_user_id] = $notify_user_id; } $db->sql_freeresult($result); // forum notification is sent to those not already receiving topic notifications if ($topic_notification) { - if (sizeof($notify_rows)) - { - $sql_ignore_users .= ', ' . implode(', ', array_keys($notify_rows)); - } - $sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber FROM ' . FORUMS_WATCH_TABLE . ' fw, ' . USERS_TABLE . " u WHERE fw.forum_id = $forum_id - AND fw.user_id NOT IN ($sql_ignore_users) - AND fw.notify_status = " . NOTIFY_YES . ' + AND " . $db->sql_in_set('fw.user_id', $sql_ignore_users, true) . ' + AND fw.notify_status = ' . NOTIFY_YES . ' AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ') AND u.user_id = fw.user_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { - $notify_rows[$row['user_id']] = array( - 'user_id' => $row['user_id'], + $notify_user_id = (int) $row['user_id']; + $notify_rows[$notify_user_id] = array( + 'user_id' => $notify_user_id, 'username' => $row['username'], 'user_email' => $row['user_email'], 'user_jabber' => $row['user_jabber'], @@ -1273,7 +1275,6 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id } } - // Now, we have to do a little step before really sending, we need to distinguish our users a little bit. ;) $msg_users = $delete_ids = $update_notification = array(); foreach ($notify_rows as $user_id => $row) @@ -1286,6 +1287,20 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id { $msg_users[] = $row; $update_notification[$row['notify_type']][] = $row['user_id']; + + /* + * We also update the forums watch table for this user when we are + * sending out a topic notification to prevent sending out another + * notification in case this user is also subscribed to the forum + * this topic was posted in. + * Since an UPDATE query is used, this has no effect on users only + * subscribed to the topic (i.e. no row is created) and should not + * be a performance issue. + */ + if ($row['notify_type'] === 'topic') + { + $update_notification['forum'][] = $row['user_id']; + } } } unset($notify_rows); diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index c40ceb088f9..b08d6e7f5c0 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1083,6 +1083,205 @@ function delete_pm($user_id, $msg_ids, $folder_id) return true; } +/** +* Delete all PM(s) for a given user and delete the ones without references +* +* @param int $user_id ID of the user whose private messages we want to delete +* +* @return boolean False if there were no pms found, true otherwise. +*/ +function phpbb_delete_user_pms($user_id) +{ + global $db, $user, $phpbb_root_path, $phpEx; + + $user_id = (int) $user_id; + + if (!$user_id) + { + return false; + } + + // Get PM Information for later deleting + // The two queries where split, so we can use our indexes + $undelivered_msg = $delete_ids = array(); + + // Part 1: get PMs the user received + $sql = 'SELECT msg_id + FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE user_id = ' . $user_id; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $msg_id = (int) $row['msg_id']; + $delete_ids[$msg_id] = $msg_id; + } + $db->sql_freeresult($result); + + // Part 2: get PMs the user sent, but have yet to be received + // We cannot simply delete them. First we have to check, + // whether another user already received and read the message. + $sql = 'SELECT msg_id + FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE author_id = ' . $user_id . ' + AND folder_id = ' . PRIVMSGS_NO_BOX; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $msg_id = (int) $row['msg_id']; + $undelivered_msg[$msg_id] = $msg_id; + } + $db->sql_freeresult($result); + + if (empty($delete_ids) && empty($undelivered_msg)) + { + return false; + } + + $db->sql_transaction('begin'); + + if (!empty($undelivered_msg)) + { + // A pm is delivered, if for any recipient the message was moved + // from their NO_BOX to another folder. We do not delete such + // messages, but only delete them for users, who have not yet + // received them. + $sql = 'SELECT msg_id + FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE author_id = ' . $user_id . ' + AND folder_id <> ' . PRIVMSGS_NO_BOX . ' + AND folder_id <> ' . PRIVMSGS_OUTBOX . ' + AND folder_id <> ' . PRIVMSGS_SENTBOX; + $result = $db->sql_query($sql); + + $delivered_msg = array(); + while ($row = $db->sql_fetchrow($result)) + { + $msg_id = (int) $row['msg_id']; + $delivered_msg[$msg_id] = $msg_id; + unset($undelivered_msg[$msg_id]); + } + $db->sql_freeresult($result); + + $undelivered_user = array(); + + // Count the messages we delete, so we can correct the user pm data + $sql = 'SELECT user_id, COUNT(msg_id) as num_undelivered_privmsgs + FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE author_id = ' . $user_id . ' + AND folder_id = ' . PRIVMSGS_NO_BOX . ' + AND ' . $db->sql_in_set('msg_id', array_merge($undelivered_msg, $delivered_msg)) . ' + GROUP BY user_id'; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $num_pms = (int) $row['num_undelivered_privmsgs']; + $undelivered_user[$num_pms][] = (int) $row['user_id']; + + if (sizeof($undelivered_user[$num_pms]) > 50) + { + // If there are too many users affected the query might get + // too long, so we update the value for the first bunch here. + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_new_privmsg = user_new_privmsg - ' . $num_pms . ', + user_unread_privmsg = user_unread_privmsg - ' . $num_pms . ' + WHERE ' . $db->sql_in_set('user_id', $undelivered_user[$num_pms]); + $db->sql_query($sql); + unset($undelivered_user[$num_pms]); + } + } + $db->sql_freeresult($result); + + foreach ($undelivered_user as $num_pms => $undelivered_user_set) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_new_privmsg = user_new_privmsg - ' . $num_pms . ', + user_unread_privmsg = user_unread_privmsg - ' . $num_pms . ' + WHERE ' . $db->sql_in_set('user_id', $undelivered_user_set); + $db->sql_query($sql); + } + + if (!empty($delivered_msg)) + { + $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE folder_id = ' . PRIVMSGS_NO_BOX . ' + AND ' . $db->sql_in_set('msg_id', $delivered_msg); + $db->sql_query($sql); + } + + if (!empty($undelivered_msg)) + { + $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg); + $db->sql_query($sql); + + $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' + WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg); + $db->sql_query($sql); + } + } + + // Reset the user's pm count to 0 + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_new_privmsg = 0, + user_unread_privmsg = 0 + WHERE user_id = ' . $user_id; + $db->sql_query($sql); + + // Delete private message data of the user + $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE user_id = ' . (int) $user_id; + $db->sql_query($sql); + + if (!empty($delete_ids)) + { + // Now we have to check which messages we can delete completely + $sql = 'SELECT msg_id + FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE ' . $db->sql_in_set('msg_id', $delete_ids); + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + unset($delete_ids[$row['msg_id']]); + } + $db->sql_freeresult($result); + + if (!empty($delete_ids)) + { + // Check if there are any attachments we need to remove + if (!function_exists('delete_attachments')) + { + include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); + } + + delete_attachments('message', $delete_ids, false); + + $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' + WHERE ' . $db->sql_in_set('msg_id', $delete_ids); + $db->sql_query($sql); + } + } + + // Set the remaining author id to anonymous + // This way users are still able to read messages from users being removed + $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' + SET author_id = ' . ANONYMOUS . ' + WHERE author_id = ' . $user_id; + $db->sql_query($sql); + + $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' + SET author_id = ' . ANONYMOUS . ' + WHERE author_id = ' . $user_id; + $db->sql_query($sql); + + $db->sql_transaction('commit'); + + return true; +} + /** * Rebuild message header */ @@ -1362,12 +1561,6 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) while ($row = $db->sql_fetchrow($result)) { - // Additionally, do not include the sender if he is in the group he wants to send to. ;) - if ($row['user_id'] === $user->data['user_id']) - { - continue; - } - $field = ($data['address_list']['g'][$row['group_id']] == 'to') ? 'to' : 'bcc'; $recipients[$row['user_id']] = $field; } @@ -1622,6 +1815,7 @@ function pm_notification($mode, $author, $recipients, $subject, $message, $msg_i $subject = censor_text($subject); + // Exclude guests, current user and banned users from notifications unset($recipients[ANONYMOUS], $recipients[$user->data['user_id']]); if (!sizeof($recipients)) @@ -1629,18 +1823,12 @@ function pm_notification($mode, $author, $recipients, $subject, $message, $msg_i return; } - // Get banned User ID's - $sql = 'SELECT ban_userid - FROM ' . BANLIST_TABLE . ' - WHERE ' . $db->sql_in_set('ban_userid', array_map('intval', array_keys($recipients))) . ' - AND ban_exclude = 0'; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) + if (!function_exists('phpbb_get_banned_user_ids')) { - unset($recipients[$row['ban_userid']]); + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); } - $db->sql_freeresult($result); + $banned_users = phpbb_get_banned_user_ids(array_keys($recipients)); + $recipients = array_diff(array_keys($recipients), $banned_users); if (!sizeof($recipients)) { @@ -1649,7 +1837,7 @@ function pm_notification($mode, $author, $recipients, $subject, $message, $msg_i $sql = 'SELECT user_id, username, user_email, user_lang, user_notify_pm, user_notify_type, user_jabber FROM ' . USERS_TABLE . ' - WHERE ' . $db->sql_in_set('user_id', array_map('intval', array_keys($recipients))); + WHERE ' . $db->sql_in_set('user_id', $recipients); $result = $db->sql_query($sql); $msg_list_ary = array(); diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php index 1eae2a9ad6b..8573533c2c8 100644 --- a/phpBB/includes/functions_profile_fields.php +++ b/phpBB/includes/functions_profile_fields.php @@ -122,7 +122,7 @@ function validate_profile_field($field_type, &$field_value, $field_data) case FIELD_BOOL: $field_value = (bool) $field_value; - + if (!$field_value && $field_data['field_required']) { return 'FIELD_REQUIRED'; @@ -134,7 +134,7 @@ function validate_profile_field($field_type, &$field_value, $field_data) { return false; } - + $field_value = (int) $field_value; if ($field_value < $field_data['field_minlen']) @@ -456,6 +456,8 @@ function generate_profile_fields_template($mode, $user_id = 0, $profile_row = fa $user_fields = array(); + $user_ids = $user_id; + // Go through the fields in correct order foreach (array_keys($this->profile_cache) as $used_ident) { @@ -464,6 +466,15 @@ function generate_profile_fields_template($mode, $user_id = 0, $profile_row = fa $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; @@ -521,7 +532,7 @@ function get_profile_value($ident_ary) switch ($this->profile_types[$field_type]) { case 'int': - if ($value === '') + if ($value === '' && !$ident_ary['data']['field_show_novalue']) { return NULL; } @@ -530,7 +541,7 @@ function get_profile_value($ident_ary) case 'string': case 'text': - if (!$value) + if (!$value && !$ident_ary['data']['field_show_novalue']) { return NULL; } @@ -548,7 +559,7 @@ function get_profile_value($ident_ary) $month = (isset($date[1])) ? (int) $date[1] : 0; $year = (isset($date[2])) ? (int) $date[2] : 0; - if (!$day && !$month && !$year) + if (!$day && !$month && !$year && !$ident_ary['data']['field_show_novalue']) { return NULL; } @@ -571,7 +582,7 @@ function get_profile_value($ident_ary) $this->get_option_lang($field_id, $lang_id, FIELD_DROPDOWN, false); } - if ($value == $ident_ary['data']['field_novalue']) + if ($value == $ident_ary['data']['field_novalue'] && !$ident_ary['data']['field_show_novalue']) { return NULL; } @@ -581,7 +592,14 @@ function get_profile_value($ident_ary) // User not having a value assigned if (!isset($this->options_lang[$field_id][$lang_id][$value])) { - return NULL; + 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]; @@ -595,6 +613,11 @@ function get_profile_value($ident_ary) $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; @@ -625,10 +648,10 @@ function get_var($field_validation, &$profile_row, $default_value, $preview) $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 - only testing for isset + // 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']])) ? true : ((!isset($user->profile_fields[$user_ident]) || $preview) ? $default_value : $user->profile_fields[$user_ident]); + $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) { diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index d5bbd80242f..73ac1df2d2a 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -751,6 +751,31 @@ function remote_upload($upload_url) $filename = $url['path']; $filesize = 0; + $remote_max_filesize = $this->max_filesize; + if (!$remote_max_filesize) + { + $max_filesize = @ini_get('upload_max_filesize'); + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $remote_max_filesize = (int) $max_filesize; + + switch ($unit) + { + case 'g': + $remote_max_filesize *= 1024; + // no break + case 'm': + $remote_max_filesize *= 1024; + // no break + case 'k': + $remote_max_filesize *= 1024; + // no break + } + } + } + $errno = 0; $errstr = ''; @@ -779,9 +804,9 @@ function remote_upload($upload_url) $block = @fread($fsock, 1024); $filesize += strlen($block); - if ($this->max_filesize && $filesize > $this->max_filesize) + if ($remote_max_filesize && $filesize > $remote_max_filesize) { - $max_filesize = get_formatted_filesize($this->max_filesize, false); + $max_filesize = get_formatted_filesize($remote_max_filesize, false); $file = new fileerror(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); return $file; @@ -807,9 +832,9 @@ function remote_upload($upload_url) { $length = (int) str_replace('content-length: ', '', strtolower($line)); - if ($length && $length > $this->max_filesize) + if ($remote_max_filesize && $length && $length > $remote_max_filesize) { - $max_filesize = get_formatted_filesize($this->max_filesize, false); + $max_filesize = get_formatted_filesize($remote_max_filesize, false); $file = new fileerror(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); return $file; diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 6b5cca8abb0..5a6a0b4a05c 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -528,62 +528,12 @@ function user_delete($mode, $user_id, $post_username = false) WHERE session_user_id = ' . $user_id; $db->sql_query($sql); - // Remove any undelivered mails... - $sql = 'SELECT msg_id, user_id - FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE author_id = ' . $user_id . ' - AND folder_id = ' . PRIVMSGS_NO_BOX; - $result = $db->sql_query($sql); - - $undelivered_msg = $undelivered_user = array(); - while ($row = $db->sql_fetchrow($result)) - { - $undelivered_msg[] = $row['msg_id']; - $undelivered_user[$row['user_id']][] = true; - } - $db->sql_freeresult($result); - - if (sizeof($undelivered_msg)) - { - $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' - WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg); - $db->sql_query($sql); - } - - $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE author_id = ' . $user_id . ' - AND folder_id = ' . PRIVMSGS_NO_BOX; - $db->sql_query($sql); - - // Delete all to-information - $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE user_id = ' . $user_id; - $db->sql_query($sql); - - // Set the remaining author id to anonymous - this way users are still able to read messages from users being removed - $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' - SET author_id = ' . ANONYMOUS . ' - WHERE author_id = ' . $user_id; - $db->sql_query($sql); - - $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' - SET author_id = ' . ANONYMOUS . ' - WHERE author_id = ' . $user_id; - $db->sql_query($sql); - - foreach ($undelivered_user as $_user_id => $ary) + // Clean the private messages tables from the user + if (!function_exists('phpbb_delete_user_pms')) { - if ($_user_id == $user_id) - { - continue; - } - - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_new_privmsg = user_new_privmsg - ' . sizeof($ary) . ', - user_unread_privmsg = user_unread_privmsg - ' . sizeof($ary) . ' - WHERE user_id = ' . $_user_id; - $db->sql_query($sql); + include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx); } + phpbb_delete_user_pms($user_id); $db->sql_transaction('commit'); @@ -1948,6 +1898,27 @@ function validate_jabber($jid) return false; } +/** +* Verifies whether a style ID corresponds to an active style. +* +* @param int $style_id The style_id of a style which should be checked if activated or not. +* @return boolean +*/ +function phpbb_style_is_active($style_id) +{ + global $db; + + $sql = 'SELECT style_active + FROM ' . STYLES_TABLE . ' + WHERE style_id = '. (int) $style_id; + $result = $db->sql_query($sql); + + $style_is_active = (bool) $db->sql_fetchfield('style_active'); + $db->sql_freeresult($result); + + return $style_is_active; +} + /** * Remove avatar */ @@ -3587,4 +3558,37 @@ function remove_newly_registered($user_id, $user_data = false) return $user_data['group_id']; } +/** +* Gets user ids of currently banned registered users. +* +* @param array $user_ids Array of users' ids to check for banning, +* leave empty to get complete list of banned ids +* @return array Array of banned users' ids if any, empty array otherwise +*/ +function phpbb_get_banned_user_ids($user_ids = array()) +{ + global $db; + + $sql_user_ids = (!empty($user_ids)) ? $db->sql_in_set('ban_userid', $user_ids) : 'ban_userid <> 0'; + + // Get banned User ID's + // Ignore stale bans which were not wiped yet + $banned_ids_list = array(); + $sql = 'SELECT ban_userid + FROM ' . BANLIST_TABLE . " + WHERE $sql_user_ids + AND ban_exclude <> 1 + AND (ban_end > " . time() . ' + OR ban_end = 0)'; + $result = $db->sql_query($sql); + while ($row = $db->sql_fetchrow($result)) + { + $user_id = (int) $row['ban_userid']; + $banned_ids_list[$user_id] = $user_id; + } + $db->sql_freeresult($result); + + return $banned_ids_list; +} + ?> \ No newline at end of file diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index d7cc1e795a4..7d4edaf3629 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -50,6 +50,16 @@ function mcp_topic_view($id, $mode, $action) $submitted_id_list = request_var('post_ids', array(0)); $checked_ids = $post_id_list = request_var('post_id_list', array(0)); + // Resync Topic? + if ($action == 'resync') + { + if (!function_exists('mcp_resync_topics')) + { + include($phpbb_root_path . 'includes/mcp/mcp_forum.' . $phpEx); + } + mcp_resync_topics(array($topic_id)); + } + // Split Topic? if ($action == 'split_all' || $action == 'split_beyond') { @@ -320,6 +330,7 @@ function mcp_topic_view($id, $mode, $action) 'S_CAN_APPROVE' => ($has_unapproved_posts && $auth->acl_get('m_approve', $topic_info['forum_id'])) ? true : false, 'S_CAN_LOCK' => ($auth->acl_get('m_lock', $topic_info['forum_id'])) ? true : false, 'S_CAN_REPORT' => ($auth->acl_get('m_report', $topic_info['forum_id'])) ? true : false, + 'S_CAN_SYNC' => $auth->acl_get('m_', $topic_info['forum_id']), 'S_REPORT_VIEW' => ($action == 'reports') ? true : false, 'S_MERGE_VIEW' => ($action == 'merge') ? true : false, 'S_SPLIT_VIEW' => ($action == 'split') ? true : false, diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php index 63e5b191559..1016204ff83 100644 --- a/phpBB/includes/mcp/mcp_warn.php +++ b/phpBB/includes/mcp/mcp_warn.php @@ -308,7 +308,7 @@ function mcp_warn_post_view($action) include($phpbb_root_path . 'includes/functions_display.' . $phpEx); } - $rank_title = $rank_img = ''; + get_user_rank($user_row['user_rank'], $user_row['user_posts'], $rank_title, $rank_img, $rank_img_src); $avatar_img = get_user_avatar($user_row['user_avatar'], $user_row['user_avatar_type'], $user_row['user_avatar_width'], $user_row['user_avatar_height']); $template->assign_vars(array( @@ -413,7 +413,7 @@ function mcp_warn_user_view($action) include($phpbb_root_path . 'includes/functions_display.' . $phpEx); } - $rank_title = $rank_img = ''; + get_user_rank($user_row['user_rank'], $user_row['user_posts'], $rank_title, $rank_img, $rank_img_src); $avatar_img = get_user_avatar($user_row['user_avatar'], $user_row['user_avatar_type'], $user_row['user_avatar_width'], $user_row['user_avatar_height']); // OK, they didn't submit a warning so lets build the page for them to do so diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index 29cdd8ee9a6..779ec1d2167 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -707,7 +707,7 @@ function index($mode, $post_id, &$message, &$subject, $poster_id, $forum_id) */ function index_remove($post_ids, $author_ids, $forum_ids) { - $this->destroy_cache(array(), $author_ids); + $this->destroy_cache(array(), array_unique($author_ids)); } /** @@ -896,11 +896,7 @@ function get_stats() } $db->sql_freeresult($result); - $sql = 'SELECT COUNT(post_id) as total_posts - FROM ' . POSTS_TABLE; - $result = $db->sql_query($sql); - $this->stats['total_posts'] = (int) $db->sql_fetchfield('total_posts'); - $db->sql_freeresult($result); + $this->stats['total_posts'] = empty($this->stats) ? 0 : $db->get_estimated_row_count(POSTS_TABLE); } /** diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index 727e3aaffb0..dc961f3c8a4 100644 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -1334,7 +1334,7 @@ function index_remove($post_ids, $author_ids, $forum_ids) $db->sql_query($sql); } - $this->destroy_cache(array_unique($word_texts), $author_ids); + $this->destroy_cache(array_unique($word_texts), array_unique($author_ids)); } /** @@ -1461,17 +1461,8 @@ function get_stats() { global $db; - $sql = 'SELECT COUNT(*) as total_words - FROM ' . SEARCH_WORDLIST_TABLE; - $result = $db->sql_query($sql); - $this->stats['total_words'] = (int) $db->sql_fetchfield('total_words'); - $db->sql_freeresult($result); - - $sql = 'SELECT COUNT(*) as total_matches - FROM ' . SEARCH_WORDMATCH_TABLE; - $result = $db->sql_query($sql); - $this->stats['total_matches'] = (int) $db->sql_fetchfield('total_matches'); - $db->sql_freeresult($result); + $this->stats['total_words'] = $db->get_estimated_row_count(SEARCH_WORDLIST_TABLE); + $this->stats['total_matches'] = $db->get_estimated_row_count(SEARCH_WORDMATCH_TABLE); } /** diff --git a/phpBB/includes/search/search.php b/phpBB/includes/search/search.php index 2f20d11495b..df7c8a0892e 100644 --- a/phpBB/includes/search/search.php +++ b/phpBB/includes/search/search.php @@ -295,7 +295,7 @@ function destroy_cache($words, $authors = false) $sql_where = ''; foreach ($authors as $author) { - $sql_where .= (($sql_where) ? ' OR ' : '') . 'search_authors LIKE \'% ' . (int) $author . ' %\''; + $sql_where .= (($sql_where) ? ' OR ' : '') . 'search_authors ' . $db->sql_like_expression($db->any_char . ' ' . (int) $author . ' ' . $db->any_char); } $sql = 'SELECT search_key diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index caadcbafaa4..496c12a0d1b 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -322,8 +322,15 @@ function session_begin($update_session_page = true) } } - // Is session_id is set or session_id is set and matches the url param if required - if (!empty($this->session_id) && (!defined('NEED_SID') || (isset($_GET['sid']) && $this->session_id === $_GET['sid']))) + // if no session id is set, redirect to index.php + if (defined('NEED_SID') && (!isset($_GET['sid']) || $this->session_id !== $_GET['sid'])) + { + send_status_line(401, 'Not authorized'); + redirect(append_sid("{$phpbb_root_path}index.$phpEx")); + } + + // if session id is set + if (!empty($this->session_id)) { $sql = 'SELECT u.*, s.* FROM ' . SESSIONS_TABLE . ' s, ' . USERS_TABLE . " u @@ -1507,7 +1514,6 @@ class user extends session // 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 $keyvalues = array(); /** * Constructor to set the lang path @@ -2337,47 +2343,51 @@ function img($img, $alt = '', $width = false, $suffix = '', $type = 'full_tag') } /** - * Get option bit field from user options + * Get option bit field from user options. + * + * @param int $key option key, as defined in $keyoptions property. + * @param int $data bit field value to use, or false to use $this->data['user_options'] + * @return bool true if the option is set in the bit field, false otherwise */ function optionget($key, $data = false) { - if (!isset($this->keyvalues[$key])) - { - $var = ($data) ? $data : $this->data['user_options']; - $this->keyvalues[$key] = ($var & 1 << $this->keyoptions[$key]) ? true : false; - } - - return $this->keyvalues[$key]; + $var = ($data !== false) ? $data : $this->data['user_options']; + return phpbb_optionget($this->keyoptions[$key], $var); } /** - * Set option bit field for user options + * Set option bit field for user options. + * + * @param int $key Option key, as defined in $keyoptions property. + * @param bool $value True to set the option, false to clear the option. + * @param int $data Current bit field value, or false to use $this->data['user_options'] + * @return int|bool If $data is false, the bit field is modified and + * written back to $this->data['user_options'], and + * return value is true if the bit field changed and + * false otherwise. If $data is not false, the new + * bitfield value is returned. */ function optionset($key, $value, $data = false) { - $var = ($data) ? $data : $this->data['user_options']; + $var = ($data !== false) ? $data : $this->data['user_options']; - if ($value && !($var & 1 << $this->keyoptions[$key])) - { - $var += 1 << $this->keyoptions[$key]; - } - else if (!$value && ($var & 1 << $this->keyoptions[$key])) - { - $var -= 1 << $this->keyoptions[$key]; - } - else - { - return ($data) ? $var : false; - } + $new_var = phpbb_optionset($this->keyoptions[$key], $value, $var); - if (!$data) + if ($data === false) { - $this->data['user_options'] = $var; - return true; + if ($new_var != $var) + { + $this->data['user_options'] = $new_var; + return true; + } + else + { + return false; + } } else { - return $var; + return $new_var; } } diff --git a/phpBB/includes/startup.php b/phpBB/includes/startup.php index bbe2f127f16..cf216a65db0 100644 --- a/phpBB/includes/startup.php +++ b/phpBB/includes/startup.php @@ -19,7 +19,23 @@ { define('E_DEPRECATED', 8192); } -error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED); +$level = E_ALL & ~E_NOTICE & ~E_DEPRECATED; +if (version_compare(PHP_VERSION, '5.4.0-dev', '>=')) +{ + // PHP 5.4 adds E_STRICT to E_ALL. + // Our utf8 normalizer triggers E_STRICT output on PHP 5.4. + // Unfortunately it cannot be made E_STRICT-clean while + // continuing to work on PHP 4. + // Therefore, in phpBB 3.0.x we disable E_STRICT on PHP 5.4+, + // while phpBB 3.1 will fix utf8 normalizer. + // E_STRICT is defined starting with PHP 5 + if (!defined('E_STRICT')) + { + define('E_STRICT', 2048); + } + $level &= ~E_STRICT; +} +error_reporting($level); /* * Remove variables created by register_globals from the global scope diff --git a/phpBB/includes/ucp/ucp_pm_options.php b/phpBB/includes/ucp/ucp_pm_options.php index 58c2d087c8b..efa390ed879 100644 --- a/phpBB/includes/ucp/ucp_pm_options.php +++ b/phpBB/includes/ucp/ucp_pm_options.php @@ -328,10 +328,23 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit trigger_error('RULE_ALREADY_DEFINED'); } + // Prevent users from flooding the rules table + $sql = 'SELECT COUNT(rule_id) AS num_rules + FROM ' . PRIVMSGS_RULES_TABLE . ' + WHERE user_id = ' . (int) $user->data['user_id']; + $result = $db->sql_query($sql); + $num_rules = (int) $db->sql_fetchfield('num_rules'); + $db->sql_freeresult($result); + + if ($num_rules >= 5000) + { + trigger_error('RULE_LIMIT_REACHED'); + } + $sql = 'INSERT INTO ' . PRIVMSGS_RULES_TABLE . ' ' . $db->sql_build_array('INSERT', $rule_ary); $db->sql_query($sql); - // Update users message rules + // Set the user_message_rules bit $sql = 'UPDATE ' . USERS_TABLE . ' SET user_message_rules = 1 WHERE user_id = ' . $user->data['user_id']; @@ -378,7 +391,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - // Update users message rules + // Unset the user_message_rules bit if (!$row) { $sql = 'UPDATE ' . USERS_TABLE . ' diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index 13167b2b3da..17d7d23f02e 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -61,7 +61,14 @@ function main($id, $mode) if ($submit) { - $data['style'] = ($config['override_user_style']) ? $config['default_style'] : $data['style']; + if ($config['override_user_style']) + { + $data['style'] = (int) $config['default_style']; + } + else if (!phpbb_style_is_active($data['style'])) + { + $data['style'] = (int) $user->data['user_style']; + } $error = validate_data($data, array( 'dateformat' => array('string', false, 1, 30), diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 4e8729db561..6ad3a55589e 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -165,24 +165,8 @@ function main($id, $mode) $captcha->init(CONFIRM_REG); } - // Try to manually determine the timezone and adjust the dst if the server date/time complies with the default setting +/- 1 - $timezone = date('Z') / 3600; - $is_dst = date('I'); - - if ($config['board_timezone'] == $timezone || $config['board_timezone'] == ($timezone - 1)) - { - $timezone = ($is_dst) ? $timezone - 1 : $timezone; - - if (!isset($user->lang['tz_zones'][(string) $timezone])) - { - $timezone = $config['board_timezone']; - } - } - else - { - $is_dst = $config['board_dst']; - $timezone = $config['board_timezone']; - } + $is_dst = $config['board_dst']; + $timezone = $config['board_timezone']; $data = array( 'username' => utf8_normalize_nfc(request_var('username', '', true)), diff --git a/phpBB/index.php b/phpBB/index.php index 0105a0a1bdf..46694a6ec26 100644 --- a/phpBB/index.php +++ b/phpBB/index.php @@ -89,7 +89,7 @@ $leap_year_birthdays = ''; if ($now['mday'] == 28 && $now['mon'] == 2 && !$user->format_date(time(), 'L')) { - $leap_year_birthdays = " OR user_birthday LIKE '" . $db->sql_escape(sprintf('%2d-%2d-', 29, 2)) . "%'"; + $leap_year_birthdays = " OR u.user_birthday LIKE '" . $db->sql_escape(sprintf('%2d-%2d-', 29, 2)) . "%'"; } $sql = 'SELECT u.user_id, u.username, u.user_colour, u.user_birthday diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index 81cc2f68f30..7d6fed61644 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -32,7 +32,7 @@ $convertor_data = array( 'forum_name' => 'phpBB 2.0.x', 'version' => '1.0.3', - 'phpbb_version' => '3.0.10', + 'phpbb_version' => '3.0.11', 'author' => 'phpBB Group', 'dbms' => $dbms, 'dbhost' => $dbhost, diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 5694c6e29f7..b7aaefb1d06 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -8,7 +8,7 @@ * */ -define('UPDATES_TO_VERSION', '3.0.10'); +define('UPDATES_TO_VERSION', '3.0.11'); // Enter any version to update from to test updates. The version within the db will not be updated. define('DEBUG_FROM_VERSION', false); @@ -951,7 +951,7 @@ function database_update_info() // this column was removed from the database updater // after 3.0.9-RC3 was released. It might still exist // in 3.0.9-RCX installations and has to be dropped in - // 3.0.11 after the db_tools class is capable of properly + // 3.0.12 after the db_tools class is capable of properly // removing a primary key. // 'attempt_id' => array('UINT', NULL, 'auto_increment'), 'attempt_ip' => array('VCHAR:40', ''), @@ -993,8 +993,20 @@ function database_update_info() '3.0.10-RC2' => array(), // No changes from 3.0.10-RC3 to 3.0.10 '3.0.10-RC3' => array(), + // No changes from 3.0.10 to 3.0.11-RC1 + '3.0.10' => array(), + // Changes from 3.0.11-RC1 to 3.0.11-RC2 + '3.0.11-RC1' => array( + 'add_columns' => array( + PROFILE_FIELDS_TABLE => array( + 'field_show_novalue' => array('BOOL', 0), + ), + ), + ), + // No changes from 3.0.11-RC2 to 3.0.11 + '3.0.11-RC2' => array(), - /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.11-RC1 */ + /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.12-RC1 */ ); } @@ -2024,6 +2036,78 @@ function change_database_data(&$no_updates, $version) // No changes from 3.0.10-RC3 to 3.0.10 case '3.0.10-RC3': break; + + // Changes from 3.0.10 to 3.0.11-RC1 + case '3.0.10': + // Updates users having current style a deactivated one + $sql = 'SELECT style_id + FROM ' . STYLES_TABLE . ' + WHERE style_active = 0'; + $result = $db->sql_query($sql); + + $deactivated_style_ids = array(); + while ($style_id = $db->sql_fetchfield('style_id', false, $result)) + { + $deactivated_style_ids[] = (int) $style_id; + } + $db->sql_freeresult($result); + + if (!empty($deactivated_style_ids)) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_style = ' . (int) $config['default_style'] .' + WHERE ' . $db->sql_in_set('user_style', $deactivated_style_ids); + _sql($sql, $errored, $error_ary); + } + + // Delete orphan private messages + $batch_size = 500; + + $sql_array = array( + 'SELECT' => 'p.msg_id', + 'FROM' => array( + PRIVMSGS_TABLE => 'p', + ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(PRIVMSGS_TO_TABLE => 't'), + 'ON' => 'p.msg_id = t.msg_id', + ), + ), + 'WHERE' => 't.user_id IS NULL', + ); + $sql = $db->sql_build_query('SELECT', $sql_array); + + do + { + $result = $db->sql_query_limit($sql, $batch_size); + + $delete_pms = array(); + while ($row = $db->sql_fetchrow($result)) + { + $delete_pms[] = (int) $row['msg_id']; + } + $db->sql_freeresult($result); + + if (!empty($delete_pms)) + { + $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' + WHERE ' . $db->sql_in_set('msg_id', $delete_pms); + _sql($sql, $errored, $error_ary); + } + } + while (sizeof($delete_pms) == $batch_size); + + $no_updates = false; + break; + + // No changes from 3.0.11-RC1 to 3.0.11-RC2 + case '3.0.11-RC1': + break; + + // No changes from 3.0.11-RC2 to 3.0.11 + case '3.0.11-RC2': + break; } } diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index 8b073df44c3..f1003b07d7d 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -53,11 +53,13 @@ function install_install(&$p_master) function main($mode, $sub) { - global $lang, $template, $language, $phpbb_root_path; + global $lang, $template, $language, $phpbb_root_path, $cache; switch ($sub) { case 'intro': + $cache->purge(); + $this->page_title = $lang['SUB_INTRO']; $template->assign_vars(array( @@ -105,6 +107,7 @@ function main($mode, $sub) $this->add_language($mode, $sub); $this->add_bots($mode, $sub); $this->email_admin($mode, $sub); + $this->disable_avatars_if_unwritable(); // Remove the lock file @unlink($phpbb_root_path . 'cache/install_lock'); @@ -166,25 +169,28 @@ function check_server_requirements($mode, $sub) 'S_LEGEND' => false, )); - // Check for register_globals being enabled - if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on') - { - $result = '' . $lang['NO'] . ''; - } - else + // Don't check for register_globals on 5.4+ + if (version_compare($php_version, '5.4.0-dev') < 0) { - $result = '' . $lang['YES'] . ''; - } - - $template->assign_block_vars('checks', array( - 'TITLE' => $lang['PHP_REGISTER_GLOBALS'], - 'TITLE_EXPLAIN' => $lang['PHP_REGISTER_GLOBALS_EXPLAIN'], - 'RESULT' => $result, + // Check for register_globals being enabled + if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on') + { + $result = '' . $lang['NO'] . ''; + } + else + { + $result = '' . $lang['YES'] . ''; + } - 'S_EXPLAIN' => true, - 'S_LEGEND' => false, - )); + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['PHP_REGISTER_GLOBALS'], + 'TITLE_EXPLAIN' => $lang['PHP_REGISTER_GLOBALS_EXPLAIN'], + 'RESULT' => $result, + 'S_EXPLAIN' => true, + 'S_LEGEND' => false, + )); + } // Check for url_fopen if (@ini_get('allow_url_fopen') == '1' || strtolower(@ini_get('allow_url_fopen')) == 'on') @@ -881,34 +887,8 @@ function create_config_file($mode, $sub) @chmod($phpbb_root_path . 'cache/install_lock', 0777); - $load_extensions = implode(',', $load_extensions); - // Time to convert the data provided into a config file - $config_data = " $available_dbms[$data['dbms']]['DRIVER'], - 'dbhost' => $data['dbhost'], - 'dbport' => $data['dbport'], - 'dbname' => $data['dbname'], - 'dbuser' => $data['dbuser'], - 'dbpasswd' => htmlspecialchars_decode($data['dbpasswd']), - 'table_prefix' => $data['table_prefix'], - 'acm_type' => 'file', - 'load_extensions' => $load_extensions, - ); - - foreach ($config_data_array as $key => $value) - { - $config_data .= "\${$key} = '" . str_replace("'", "\\'", str_replace('\\', '\\\\', $value)) . "';\n"; - } - unset($config_data_array); - - $config_data .= "\n@define('PHPBB_INSTALLED', true);\n"; - $config_data .= "// @define('DEBUG', true);\n"; - $config_data .= "// @define('DEBUG_EXTRA', true);\n"; - $config_data .= '?' . '>'; // Done this to prevent highlighting editors getting confused! + $config_data = phpbb_create_config_file_data($data, $available_dbms[$data['dbms']]['DRIVER'], $load_extensions); // Attempt to write out the config file directly. If it works, this is the easiest way to do it ... if ((file_exists($phpbb_root_path . 'config.' . $phpEx) && phpbb_is_writable($phpbb_root_path . 'config.' . $phpEx)) || phpbb_is_writable($phpbb_root_path)) @@ -1178,14 +1158,13 @@ function load_schema($mode, $sub) $dbms_schema = 'schemas/' . $available_dbms[$data['dbms']]['SCHEMA'] . '_schema.sql'; // How should we treat this schema? - $remove_remarks = $available_dbms[$data['dbms']]['COMMENTS']; $delimiter = $available_dbms[$data['dbms']]['DELIM']; $sql_query = @file_get_contents($dbms_schema); $sql_query = preg_replace('#phpbb_#i', $data['table_prefix'], $sql_query); - $remove_remarks($sql_query); + $sql_query = phpbb_remove_comments($sql_query); $sql_query = split_sql_file($sql_query, $delimiter); @@ -1223,8 +1202,7 @@ function load_schema($mode, $sub) // Change language strings... $sql_query = preg_replace_callback('#\{L_([A-Z0-9\-_]*)\}#s', 'adjust_language_keys_callback', $sql_query); - // Since there is only one schema file we know the comment style and are able to remove it directly with remove_remarks - remove_remarks($sql_query); + $sql_query = phpbb_remove_comments($sql_query); $sql_query = split_sql_file($sql_query, ';'); foreach ($sql_query as $sql) @@ -1966,6 +1944,21 @@ function email_admin($mode, $sub) )); } + /** + * Check if the avatar directory is writable and disable avatars + * if it isn't writable. + */ + function disable_avatars_if_unwritable() + { + global $phpbb_root_path; + + if (!phpbb_is_writable($phpbb_root_path . 'images/avatars/upload/')) + { + set_config('allow_avatar', 0); + set_config('allow_avatar_upload', 0); + } + } + /** * Generate a list of available mail server authentication methods */ diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 73052f0a225..eae692f5290 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -807,6 +807,7 @@ CREATE TABLE phpbb_profile_fields ( 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_vt INTEGER DEFAULT 0 NOT NULL, field_show_profile INTEGER DEFAULT 0 NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 8ed3ba7e12e..0b2f8368dee 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -974,6 +974,7 @@ CREATE TABLE [phpbb_profile_fields] ( [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_vt] [int] DEFAULT (0) NOT NULL , [field_show_profile] [int] DEFAULT (0) NOT NULL , diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 42b7291d9d5..969cbe0472e 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -571,6 +571,7 @@ CREATE TABLE phpbb_profile_fields ( 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_vt tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, field_show_profile tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index 7a6d0ae1887..15d34894d8e 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -571,6 +571,7 @@ CREATE TABLE phpbb_profile_fields ( 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_vt tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, field_show_profile tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 6e7ec31efc7..af7b2b60ec9 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -1085,6 +1085,7 @@ CREATE TABLE phpbb_profile_fields ( 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_vt number(1) DEFAULT '0' NOT NULL, field_show_profile number(1) DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index 38f167bc7bb..0a05a7cd754 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -761,6 +761,7 @@ CREATE TABLE phpbb_profile_fields ( 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_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), diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index d7433d52fd2..d2d8d95b345 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -8,10 +8,10 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('active_sessions', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_attachments', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_autologin', '1'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_local', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_remote', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_upload', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_upload', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_remote_upload', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_bbcode', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_birthdays', '1'); @@ -99,7 +99,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_package_size INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_confirm', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_pm_icons', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_post_confirm', '1'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_enable', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_enable', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_http_auth', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_limit_post', '15'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_limit_topic', '10'); @@ -246,7 +246,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('topics_per_page', 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 ('version', '3.0.10'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.0.11'); 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'); diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index c0574244ca4..be7faa46881 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -554,6 +554,7 @@ CREATE TABLE phpbb_profile_fields ( 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_vt INTEGER UNSIGNED NOT NULL DEFAULT '0', field_show_profile INTEGER UNSIGNED NOT NULL DEFAULT '0', diff --git a/phpBB/language/en/acp/attachments.php b/phpBB/language/en/acp/attachments.php index 1821b8c867b..6aeb3c2188d 100644 --- a/phpBB/language/en/acp/attachments.php +++ b/phpBB/language/en/acp/attachments.php @@ -57,7 +57,7 @@ 'ATTACH_EXT_GROUPS_URL' => 'Extension groups', 'ATTACH_ID' => 'ID', 'ATTACH_MAX_FILESIZE' => 'Maximum file size', - 'ATTACH_MAX_FILESIZE_EXPLAIN' => 'Maximum size of each file, with 0 being unlimited.', + 'ATTACH_MAX_FILESIZE_EXPLAIN' => 'Maximum size of each file. If this value is 0, the uploadable filesize is only limited by your PHP configuration.', 'ATTACH_MAX_PM_FILESIZE' => 'Maximum file size messaging', 'ATTACH_MAX_PM_FILESIZE_EXPLAIN' => 'Maximum size of each file, with 0 being unlimited, attached to a private message.', 'ATTACH_ORPHAN_URL' => 'Orphan attachments', diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 6e6d4302cd7..f24376f8aa3 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -108,7 +108,7 @@ 'MAX_AVATAR_SIZE' => 'Maximum avatar dimensions', 'MAX_AVATAR_SIZE_EXPLAIN' => 'Width x Height in pixels.', 'MAX_FILESIZE' => 'Maximum avatar file size', - 'MAX_FILESIZE_EXPLAIN' => 'For uploaded avatar files.', + 'MAX_FILESIZE_EXPLAIN' => 'For uploaded avatar files. If this value is 0, the uploaded filesize is only limited by your PHP configuration.', 'MIN_AVATAR_SIZE' => 'Minimum avatar dimensions', 'MIN_AVATAR_SIZE_EXPLAIN' => 'Width x Height in pixels.', )); diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index ef8d6f1cb3e..e64ba3c371d 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -96,10 +96,10 @@ 'ACP_GLOBAL_MODERATORS' => 'Global moderators', 'ACP_GLOBAL_PERMISSIONS' => 'Global permissions', 'ACP_GROUPS' => 'Groups', - 'ACP_GROUPS_FORUM_PERMISSIONS' => 'Groups’ forum permissions', + 'ACP_GROUPS_FORUM_PERMISSIONS' => 'Group forum permissions', 'ACP_GROUPS_MANAGE' => 'Manage groups', 'ACP_GROUPS_MANAGEMENT' => 'Group management', - 'ACP_GROUPS_PERMISSIONS' => 'Groups’ permissions', + 'ACP_GROUPS_PERMISSIONS' => 'Group permissions', 'ACP_ICONS' => 'Topic icons', 'ACP_ICONS_SMILIES' => 'Topic icons/smilies', @@ -172,9 +172,9 @@ 'ACP_THEMES' => 'Themes', 'ACP_UPDATE' => 'Updating', - 'ACP_USERS_FORUM_PERMISSIONS' => 'Users’ forum permissions', + 'ACP_USERS_FORUM_PERMISSIONS' => 'User forum permissions', 'ACP_USERS_LOGS' => 'User logs', - 'ACP_USERS_PERMISSIONS' => 'Users’ permissions', + 'ACP_USERS_PERMISSIONS' => 'User permissions', 'ACP_USER_ATTACH' => 'Attachments', 'ACP_USER_AVATAR' => 'Avatar', 'ACP_USER_FEEDBACK' => 'Feedback', @@ -405,7 +405,7 @@ 'INACTIVE_REASON_UNKNOWN' => 'Unknown', 'INACTIVE_USERS' => 'Inactive users', 'INACTIVE_USERS_EXPLAIN' => 'This is a list of users who have registered but whose accounts are inactive. You can activate, delete or remind (by sending an e-mail) these users if you wish.', - 'INACTIVE_USERS_EXPLAIN_INDEX' => 'This is a list of the last 10 registered users who have inactive accounts. A full list is available from the appropriate menu item or by following the link below from where you can activate, delete or remind (by sending an e-mail) these users if you wish.', + 'INACTIVE_USERS_EXPLAIN_INDEX' => 'This is a list of the last 10 registered users who have inactive accounts. Accounts are inactive either because account activation was enabled in user registration settings and these users’ accounts have not yet been activated, or because these accounts have been deactivated. A full list is available by following the link below from where you can activate, delete or remind (by sending an e-mail) these users if you wish.', 'NO_INACTIVE_USERS' => 'No inactive users', diff --git a/phpBB/language/en/acp/permissions.php b/phpBB/language/en/acp/permissions.php index cf248cffdba..c0396cc2479 100644 --- a/phpBB/language/en/acp/permissions.php +++ b/phpBB/language/en/acp/permissions.php @@ -40,10 +40,10 @@

      Permissions are highly granular and grouped into four major sections, which are:

      Global Permissions

      -

      These are used to control access on a global level and apply to the entire bulletin board. They are further divided into Users’ Permissions, Groups’ Permissions, Administrators and Global Moderators.

      +

      These are used to control access on a global level and apply to the entire bulletin board. They are further divided into User Permissions, Group Permissions, Administrators and Global Moderators.

      Forum Based Permissions

      -

      These are used to control access on a per forum basis. They are further divided into Forum Permissions, Forum Moderators, Users’ Forum Permissions and Groups’ Forum Permissions.

      +

      These are used to control access on a per forum basis. They are further divided into Forum Permissions, Forum Moderators, User Forum Permissions and Group Forum Permissions.

      Permission Roles

      These are used to create different sets of permissions for the different permission types later being able to be assigned on a role-based basis. The default roles should cover the administration of bulletin boards large and small, though within each of the four divisions, you can add/edit/delete roles as you see fit.

      @@ -83,13 +83,13 @@ 'ACP_FORUM_PERMISSIONS_COPY_EXPLAIN' => 'Here you can copy forum permissions from one forum to one or more other forums.', 'ACP_GLOBAL_MODERATORS_EXPLAIN' => 'Here you can assign global moderator permissions to users or groups. These moderators are like ordinary moderators except they have access to every forum on your board.', 'ACP_GROUPS_FORUM_PERMISSIONS_EXPLAIN' => 'Here you can assign forum permissions to groups.', - 'ACP_GROUPS_PERMISSIONS_EXPLAIN' => 'Here you can assign global permissions to groups - user permissions, global moderator permissions and administrator permissions. User permissions include capabilities such as the use of avatars, sending private messages, et cetera; global moderator permissions such as approving posts, manage topics, manage bans, et cetera and lastly administrator permissions such as altering permissions, define custom BBCodes, manage forums, et cetera. Individual users permissions should only be changed in rare occasions, the preferred method is putting users in groups and assigning the group’s permissions.', + 'ACP_GROUPS_PERMISSIONS_EXPLAIN' => 'Here you can assign global permissions to groups - user permissions, global moderator permissions and administrator permissions. User permissions include capabilities such as the use of avatars, sending private messages, et cetera; global moderator permissions such as approving posts, manage topics, manage bans, et cetera and lastly administrator permissions such as altering permissions, define custom BBCodes, manage forums, et cetera. Individual user permissions should only be changed in rare occasions, the preferred method is putting users in groups and assigning the group permissions.', 'ACP_ADMIN_ROLES_EXPLAIN' => 'Here you are able to manage the roles for administrative permissions. Roles are effective permissions, if you change a role the items having this role assigned will change its permissions too.', 'ACP_FORUM_ROLES_EXPLAIN' => 'Here you are able to manage the roles for forum permissions. Roles are effective permissions, if you change a role the items having this role assigned will change its permissions too.', 'ACP_MOD_ROLES_EXPLAIN' => 'Here you are able to manage the roles for moderative permissions. Roles are effective permissions, if you change a role the items having this role assigned will change its permissions too.', 'ACP_USER_ROLES_EXPLAIN' => 'Here you are able to manage the roles for user permissions. Roles are effective permissions, if you change a role the items having this role assigned will change its permissions too.', 'ACP_USERS_FORUM_PERMISSIONS_EXPLAIN' => 'Here you can assign forum permissions to users.', - 'ACP_USERS_PERMISSIONS_EXPLAIN' => 'Here you can assign global permissions to users - user permissions, global moderator permissions and administrator permissions. User permissions include capabilities such as the use of avatars, sending private messages, et cetera; global moderator permissions such as approving posts, manage topics, manage bans, et cetera and lastly administrator permissions such as altering permissions, define custom BBCodes, manage forums, et cetera. To alter these settings for large numbers of users the Group permissions system is the preferred method. User’s permissions should only be changed in rare occasions, the preferred method is putting users in groups and assigning the group’s permissions.', + 'ACP_USERS_PERMISSIONS_EXPLAIN' => 'Here you can assign global permissions to users - user permissions, global moderator permissions and administrator permissions. User permissions include capabilities such as the use of avatars, sending private messages, et cetera; global moderator permissions such as approving posts, manage topics, manage bans, et cetera and lastly administrator permissions such as altering permissions, define custom BBCodes, manage forums, et cetera. To alter these settings for large numbers of users the Group permissions system is the preferred method. User permissions should only be changed in rare occasions, the preferred method is putting users in groups and assigning the group permissions.', 'ACP_VIEW_ADMIN_PERMISSIONS_EXPLAIN' => 'Here you can view the effective administrative permissions assigned to the selected users/groups.', 'ACP_VIEW_GLOBAL_MOD_PERMISSIONS_EXPLAIN' => 'Here you can view the global moderative permissions assigned to the selected users/groups.', 'ACP_VIEW_FORUM_PERMISSIONS_EXPLAIN' => 'Here you can view the forum permissions assigned to the selected users/groups and forums.', @@ -171,7 +171,7 @@ 'ROLE_FORUM_POLLS' => 'Standard Access + Polls', 'ROLE_FORUM_READONLY' => 'Read Only Access', 'ROLE_FORUM_STANDARD' => 'Standard Access', - 'ROLE_FORUM_NEW_MEMBER' => 'Newly registered User', + 'ROLE_FORUM_NEW_MEMBER' => 'Newly Registered User Access', 'ROLE_MOD_FULL' => 'Full Moderator', 'ROLE_MOD_QUEUE' => 'Queue Moderator', 'ROLE_MOD_SIMPLE' => 'Simple Moderator', @@ -181,7 +181,7 @@ 'ROLE_USER_NOAVATAR' => 'No Avatar', 'ROLE_USER_NOPM' => 'No Private Messages', 'ROLE_USER_STANDARD' => 'Standard Features', - 'ROLE_USER_NEW_MEMBER' => 'Newly registered User', + 'ROLE_USER_NEW_MEMBER' => 'Newly Registered User Features', 'ROLE_DESCRIPTION_ADMIN_FORUM' => 'Can access the forum management and forum permission settings.', @@ -225,8 +225,8 @@ 'SELECT_TYPE' => 'Select type', 'SET_PERMISSIONS' => 'Set permissions', 'SET_ROLE_PERMISSIONS' => 'Set role permissions', - 'SET_USERS_PERMISSIONS' => 'Set users permissions', - 'SET_USERS_FORUM_PERMISSIONS' => 'Set users forum permissions', + 'SET_USERS_PERMISSIONS' => 'Set user permissions', + 'SET_USERS_FORUM_PERMISSIONS' => 'Set user forum permissions', 'TRACE_DEFAULT' => 'By default every permission is NO (unset). So the permission can be overwritten by other settings.', 'TRACE_FOR' => 'Trace for', @@ -273,7 +273,7 @@ 'TRACE_WHO' => 'Who', 'TRACE_TOTAL' => 'Total', - 'USERS_NOT_ASSIGNED' => 'No user assigned to this role', + 'USERS_NOT_ASSIGNED' => 'No users are assigned to this role', 'USER_IS_MEMBER_OF_DEFAULT' => 'is a member of the following pre-defined groups', 'USER_IS_MEMBER_OF_CUSTOM' => 'is a member of the following user defined groups', diff --git a/phpBB/language/en/acp/profile.php b/phpBB/language/en/acp/profile.php index a25dcd174b7..e193d9303c2 100644 --- a/phpBB/language/en/acp/profile.php +++ b/phpBB/language/en/acp/profile.php @@ -131,6 +131,8 @@ 'SAVE' => 'Save', 'SECOND_OPTION' => 'Second option', + 'SHOW_NOVALUE_FIELD' => 'Show field if no value was selected', + 'SHOW_NOVALUE_FIELD_EXPLAIN' => 'Determines if the profile field should be displayed if no value was selected for optional fields or if no value has been selected yet for required fields.', 'STEP_1_EXPLAIN_CREATE' => 'Here you can enter the first basic parameters of your new profile field. This information is needed for the second step where you’ll be able to set remaining options and tweak your profile field further.', 'STEP_1_EXPLAIN_EDIT' => 'Here you can change the basic parameters of your profile field. The relevant options are re-calculated within the second step.', 'STEP_1_TITLE_CREATE' => 'Add profile field', diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php index 3c8c4a328f8..3194a2ebd6b 100644 --- a/phpBB/language/en/acp/styles.php +++ b/phpBB/language/en/acp/styles.php @@ -267,6 +267,7 @@ 'IMG_USER_ICON9' => 'User defined image 9', 'IMG_USER_ICON10' => 'User defined image 10', + 'INACTIVE_STYLES' => 'Inactive styles', 'INCLUDE_DIMENSIONS' => 'Include dimensions', 'INCLUDE_IMAGESET' => 'Include imageset', 'INCLUDE_TEMPLATE' => 'Include template', diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php index eda9659795e..3b82a7022d5 100644 --- a/phpBB/language/en/acp/users.php +++ b/phpBB/language/en/acp/users.php @@ -59,7 +59,7 @@ 'DELETE_POSTS' => 'Delete posts', 'DELETE_USER' => 'Delete user', - 'DELETE_USER_EXPLAIN' => 'Please note that deleting a user is final, they cannot be recovered.', + 'DELETE_USER_EXPLAIN' => 'Please note that deleting a user is final, they cannot be recovered. Unread private messages sent by this user will be deleted and will not be available to their recipients.', 'FORCE_REACTIVATION_SUCCESS' => 'Successfully forced reactivation.', 'FOUNDER' => 'Founder', @@ -124,6 +124,7 @@ 'USER_GROUP_SPECIAL' => 'Pre-defined groups user is a member of', 'USER_LIFTED_NR' => 'Successfully removed the user’s newly registered status.', 'USER_NO_ATTACHMENTS' => 'There are no attached files to display.', + 'USER_NO_POSTS_TO_DELETE' => 'The user has no posts to retain or delete.', 'USER_OUTBOX_EMPTIED' => 'Successfully emptied user’s private message outbox.', 'USER_OUTBOX_EMPTY' => 'The user’s private message outbox was already empty.', 'USER_OVERVIEW_UPDATED' => 'User details updated.', diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 005640b7ddc..0184dd083b2 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -191,7 +191,7 @@ 'FORM_INVALID' => 'The submitted form was invalid. Try submitting again.', 'FORUM' => 'Forum', 'FORUMS' => 'Forums', - 'FORUMS_MARKED' => 'The selected forums have been marked read.', + 'FORUMS_MARKED' => 'Forums have been marked read.', 'FORUM_CAT' => 'Forum category', 'FORUM_INDEX' => 'Board index', 'FORUM_LINK' => 'Forum link', @@ -450,6 +450,7 @@ 'POST_TIME' => 'Post time', 'POST_TOPIC' => 'Post a new topic', 'POST_UNAPPROVED' => 'This post is waiting for approval', + 'POWERED_BY' => 'Powered by %s', 'PREVIEW' => 'Preview', 'PREVIOUS' => 'Previous', // Used in pagination 'PREVIOUS_STEP' => 'Previous', @@ -459,6 +460,7 @@ 'PRIVATE_MESSAGING' => 'Private messaging', 'PROFILE' => 'User Control Panel', + 'RANK' => 'Rank', 'READING_FORUM' => 'Viewing topics in %s', 'READING_GLOBAL_ANNOUNCE' => 'Reading global announcement', 'READING_LINK' => 'Following forum link %s', diff --git a/phpBB/language/en/help_faq.php b/phpBB/language/en/help_faq.php index b915a3da193..c500917d581 100644 --- a/phpBB/language/en/help_faq.php +++ b/phpBB/language/en/help_faq.php @@ -333,7 +333,7 @@ ), array( 0 => 'Why isn’t X feature available?', - 1 => 'This software was written by and licensed through phpBB Group. If you believe a feature needs to be added, please visit the phpbb.com website and see what phpBB Group have to say. Please do not post feature requests to the board at phpbb.com, the group uses SourceForge to handle tasking of new features. Please read through the forums and see what, if any, our position may already be for a feature and then follow the procedure given there.' + 1 => 'This software was written by and licensed through phpBB Group. If you believe a feature needs to be added, or you want to report a bug, please visit the phpBB Area51 website, where you will find resources to do so.' ), array( 0 => 'Who do I contact about abusive and/or legal matters related to this board?', diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php index f69ca406135..bbf407f1dc3 100644 --- a/phpBB/language/en/install.php +++ b/phpBB/language/en/install.php @@ -52,6 +52,7 @@ 'BLANK_PREFIX_FOUND' => 'A scan of your tables has shown a valid installation using no table prefix.', 'BOARD_NOT_INSTALLED' => 'No installation found', 'BOARD_NOT_INSTALLED_EXPLAIN' => 'The phpBB Unified Convertor Framework requires a default installation of phpBB3 to function, please proceed by first installing phpBB3.', + 'BACKUP_NOTICE' => 'Please backup your board before updating in case any problems arise during the update process.', 'CATEGORY' => 'Category', 'CACHE_STORE' => 'Cache type', diff --git a/phpBB/language/en/memberlist.php b/phpBB/language/en/memberlist.php index e71f9d6565f..7dc5e6b74a0 100644 --- a/phpBB/language/en/memberlist.php +++ b/phpBB/language/en/memberlist.php @@ -110,7 +110,6 @@ 'POST_IP' => 'Posted from IP/domain', - 'RANK' => 'Rank', 'REAL_NAME' => 'Recipient name', 'RECIPIENT' => 'Recipient', 'REMOVE_FOE' => 'Remove foe', diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php index f8d265dddd7..24f3204c577 100644 --- a/phpBB/language/en/posting.php +++ b/phpBB/language/en/posting.php @@ -42,6 +42,7 @@ 'ADD_POLL' => 'Poll creation', 'ADD_POLL_EXPLAIN' => 'If you do not want to add a poll to your topic leave the fields blank.', 'ALREADY_DELETED' => 'Sorry but this message is already deleted.', + 'ATTACH_DISK_FULL' => 'There is not enough free disk space to post this attachment.', 'ATTACH_QUOTA_REACHED' => 'Sorry, the board attachment quota has been reached.', 'ATTACH_SIG' => 'Attach a signature (signatures can be altered via the UCP)', diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 3ebc863447d..94d9a5171e8 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -137,7 +137,8 @@ 'CREATE_FOLDER' => 'Add folder
', 'CURRENT_IMAGE' => 'Current image', 'CURRENT_PASSWORD' => 'Current password', - 'CURRENT_PASSWORD_EXPLAIN' => 'You must confirm your current password if you wish to change it, alter your e-mail address or username.', + 'CURRENT_PASSWORD_EXPLAIN' => 'You must enter your current password if you wish to alter your email address or username.', + 'CURRENT_CHANGE_PASSWORD_EXPLAIN' => 'To change your password, your email address, or your username, you must enter your current password.', 'CUR_PASSWORD_EMPTY' => 'You did not enter your current password.', 'CUR_PASSWORD_ERROR' => 'The current password you entered is incorrect.', 'CUSTOM_DATEFORMAT' => 'Custom
', @@ -387,6 +388,7 @@ 'RULE_ADDED' => 'Rule successfully added.', 'RULE_ALREADY_DEFINED' => 'This rule was defined previously.', 'RULE_DELETED' => 'Rule successfully removed.', + 'RULE_LIMIT_REACHED' => 'You cannot add more PM rules. You have reached the maximum number of rules.', 'RULE_NOT_DEFINED' => 'Rule not correctly specified.', 'RULE_REMOVED_MESSAGE' => 'One private message had been removed due to private message filters.', 'RULE_REMOVED_MESSAGES' => '%d private messages were removed due to private message filters.', diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index b3c0bae16af..7e510a33681 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -62,11 +62,6 @@ $sort_key = request_var('sk', $default_key); $sort_dir = request_var('sd', 'a'); - -// Grab rank information for later -$ranks = $cache->obtain_ranks(); - - // What do you want to do today? ... oops, I think that line is taken ... switch ($mode) { @@ -1221,21 +1216,16 @@ // Misusing the avatar function for displaying group avatars... $avatar_img = get_user_avatar($group_row['group_avatar'], $group_row['group_avatar_type'], $group_row['group_avatar_width'], $group_row['group_avatar_height'], 'GROUP_AVATAR'); + // ... same for group rank $rank_title = $rank_img = $rank_img_src = ''; if ($group_row['group_rank']) { - if (isset($ranks['special'][$group_row['group_rank']])) + get_user_rank($group_row['group_rank'], false, $rank_title, $rank_img, $rank_img_src); + + if ($rank_img) { - $rank_title = $ranks['special'][$group_row['group_rank']]['rank_title']; + $rank_img .= '
      '; } - $rank_img = (!empty($ranks['special'][$group_row['group_rank']]['rank_image'])) ? '' . $ranks['special'][$group_row['group_rank']]['rank_title'] . '
      ' : ''; - $rank_img_src = (!empty($ranks['special'][$group_row['group_rank']]['rank_image'])) ? $config['ranks_path'] . '/' . $ranks['special'][$group_row['group_rank']]['rank_image'] : ''; - } - else - { - $rank_title = ''; - $rank_img = ''; - $rank_img_src = ''; } $template->assign_vars(array( @@ -1346,6 +1336,7 @@ if ($mode) { $params[] = "mode=$mode"; + $u_first_char_params[] = "mode=$mode"; } $sort_params[] = "mode=$mode"; diff --git a/phpBB/search.php b/phpBB/search.php index 2aa61401cf5..8cb2020630e 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -469,33 +469,60 @@ $per_page = ($show_results == 'posts') ? $config['posts_per_page'] : $config['topics_per_page']; $total_match_count = 0; + // Set limit for the $total_match_count to reduce server load + $total_matches_limit = 1000; + $found_more_search_matches = false; + if ($search_id) { if ($sql) { - // only return up to 1000 ids (the last one will be removed later) - $result = $db->sql_query_limit($sql, 1001 - $start, $start); + // Only return up to $total_matches_limit+1 ids (the last one will be removed later) + $result = $db->sql_query_limit($sql, $total_matches_limit + 1); while ($row = $db->sql_fetchrow($result)) { $id_ary[] = (int) $row[$field]; } $db->sql_freeresult($result); - - $total_match_count = sizeof($id_ary) + $start; - $id_ary = array_slice($id_ary, 0, $per_page); } else if ($search_id == 'unreadposts') { - $id_ary = array_keys(get_unread_topics($user->data['user_id'], $sql_where, $sql_sort, 1001 - $start, $start)); - - $total_match_count = sizeof($id_ary) + $start; - $id_ary = array_slice($id_ary, 0, $per_page); + // Only return up to $total_matches_limit+1 ids (the last one will be removed later) + $id_ary = array_keys(get_unread_topics($user->data['user_id'], $sql_where, $sql_sort, $total_matches_limit + 1)); } else { $search_id = ''; } + + $total_match_count = sizeof($id_ary); + if ($total_match_count) + { + // Limit the number to $total_matches_limit for pre-made searches + if ($total_match_count > $total_matches_limit) + { + $found_more_search_matches = true; + $total_match_count = $total_matches_limit; + } + + // 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; + } + + $id_ary = array_slice($id_ary, $start, $per_page); + } + else + { + // Set $start to 0 if no matches were found + $start = 0; + } } // make sure that some arrays are always in the same order @@ -543,10 +570,8 @@ $icons = $cache->obtain_icons(); // Output header - if ($search_id && ($total_match_count > 1000)) + if ($found_more_search_matches) { - // limit the number to 1000 for pre-made searches - $total_match_count--; $l_search_matches = sprintf($user->lang['FOUND_MORE_SEARCH_MATCHES'], $total_match_count); } else diff --git a/phpBB/style.php b/phpBB/style.php index 916aa8ce5c8..f1b41c6a856 100644 --- a/phpBB/style.php +++ b/phpBB/style.php @@ -216,10 +216,10 @@ // Parse Theme Data $replace = array( - '{T_THEME_PATH}' => "{$phpbb_root_path}styles/" . $theme['theme_path'] . '/theme', - '{T_TEMPLATE_PATH}' => "{$phpbb_root_path}styles/" . $theme['template_path'] . '/template', - '{T_IMAGESET_PATH}' => "{$phpbb_root_path}styles/" . $theme['imageset_path'] . '/imageset', - '{T_IMAGESET_LANG_PATH}' => "{$phpbb_root_path}styles/" . $theme['imageset_path'] . '/imageset/' . $user_image_lang, + '{T_THEME_PATH}' => "{$phpbb_root_path}styles/" . rawurlencode($theme['theme_path']) . '/theme', + '{T_TEMPLATE_PATH}' => "{$phpbb_root_path}styles/" . rawurlencode($theme['template_path']) . '/template', + '{T_IMAGESET_PATH}' => "{$phpbb_root_path}styles/" . rawurlencode($theme['imageset_path']) . '/imageset', + '{T_IMAGESET_LANG_PATH}' => "{$phpbb_root_path}styles/" . rawurlencode($theme['imageset_path']) . '/imageset/' . $user_image_lang, '{T_STYLESHEET_NAME}' => $theme['theme_name'], '{S_USER_LANG}' => $user['user_lang'] ); @@ -248,7 +248,7 @@ $img_data = &$img_array[$img]; $imgsrc = ($img_data['image_lang'] ? $img_data['image_lang'] . '/' : '') . $img_data['image_filename']; $imgs[$img] = array( - 'src' => $phpbb_root_path . 'styles/' . $theme['imageset_path'] . '/imageset/' . $imgsrc, + 'src' => $phpbb_root_path . 'styles/' . rawurlencode($theme['imageset_path']) . '/imageset/' . $imgsrc, 'width' => $img_data['image_width'], 'height' => $img_data['image_height'], ); diff --git a/phpBB/styles/prosilver/imageset/imageset.cfg b/phpBB/styles/prosilver/imageset/imageset.cfg index 5a703d9e479..d7ba7690f69 100644 --- a/phpBB/styles/prosilver/imageset/imageset.cfg +++ b/phpBB/styles/prosilver/imageset/imageset.cfg @@ -19,7 +19,7 @@ # General Information about this style name = prosilver copyright = © phpBB Group, 2007 -version = 3.0.10 +version = 3.0.11 # Images img_site_logo = site_logo.gif*52*139 diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg index 95d8d287e4f..97e8aced012 100644 --- a/phpBB/styles/prosilver/style.cfg +++ b/phpBB/styles/prosilver/style.cfg @@ -19,4 +19,4 @@ # General Information about this style name = prosilver copyright = © phpBB Group, 2007 -version = 3.0.10 \ No newline at end of file +version = 3.0.11 \ No newline at end of file diff --git a/phpBB/styles/prosilver/template/editor.js b/phpBB/styles/prosilver/template/editor.js index cfdb54f54b9..c16b0ef7036 100644 --- a/phpBB/styles/prosilver/template/editor.js +++ b/phpBB/styles/prosilver/template/editor.js @@ -219,7 +219,7 @@ function addquote(post_id, username, l_wrote) // 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) + if (window.getSelection && !is_ie && !window.opera) { theSelection = window.getSelection().toString(); } @@ -456,4 +456,4 @@ function getCaretPosition(txtarea) } return caretPos; -} \ No newline at end of file +} diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index a4d2a0f600e..13b661ef0ab 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -1,5 +1,6 @@ +

      {L_TOPIC}: {TOPIC_TITLE}