aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore8
-rw-r--r--.travis.yml1
-rw-r--r--build/build.xml15
-rwxr-xr-xbuild/build_changelog.php2
-rw-r--r--build/sami-all.conf.php30
-rw-r--r--build/sami-checkout.conf.php (renamed from build/sami.conf.php)15
-rw-r--r--phpBB/adm/style/acp_email.html2
-rw-r--r--phpBB/adm/style/acp_forums.html7
-rw-r--r--phpBB/assets/javascript/core.js3
-rw-r--r--phpBB/assets/javascript/plupload.js8
-rw-r--r--phpBB/composer.lock191
-rw-r--r--phpBB/config/console.yml1
-rw-r--r--phpBB/config/password.yml1
-rw-r--r--phpBB/config/services.yml7
-rw-r--r--phpBB/docs/CHANGELOG.html238
-rw-r--r--phpBB/docs/CREDITS.txt2
-rw-r--r--phpBB/docs/INSTALL.html6
-rw-r--r--phpBB/docs/events.md98
-rw-r--r--phpBB/includes/acp/acp_board.php29
-rw-r--r--phpBB/includes/acp/acp_email.php28
-rw-r--r--phpBB/includes/acp/acp_extensions.php2
-rw-r--r--phpBB/includes/acp/acp_styles.php46
-rw-r--r--phpBB/includes/constants.php2
-rw-r--r--phpBB/includes/functions.php4
-rw-r--r--phpBB/includes/functions_admin.php67
-rw-r--r--phpBB/includes/functions_compatibility.php7
-rw-r--r--phpBB/includes/functions_content.php10
-rw-r--r--phpBB/includes/functions_display.php8
-rw-r--r--phpBB/includes/functions_privmsgs.php18
-rw-r--r--phpBB/includes/functions_user.php28
-rw-r--r--phpBB/includes/mcp/mcp_forum.php16
-rw-r--r--phpBB/includes/mcp/mcp_logs.php2
-rw-r--r--phpBB/includes/mcp/mcp_main.php14
-rw-r--r--phpBB/includes/mcp/mcp_warn.php2
-rw-r--r--phpBB/includes/message_parser.php57
-rw-r--r--phpBB/includes/startup.php28
-rw-r--r--phpBB/includes/ucp/ucp_auth_link.php5
-rw-r--r--phpBB/includes/ucp/ucp_login_link.php8
-rw-r--r--phpBB/includes/ucp/ucp_pm.php24
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewmessage.php3
-rw-r--r--phpBB/includes/ucp/ucp_profile.php9
-rw-r--r--phpBB/includes/ucp/ucp_register.php7
-rw-r--r--phpBB/index.php2
-rw-r--r--phpBB/install/convertors/convert_phpbb20.php2
-rw-r--r--phpBB/install/database_update.php26
-rw-r--r--phpBB/install/schemas/schema_data.sql2
-rw-r--r--phpBB/language/en/acp/board.php5
-rw-r--r--phpBB/language/en/acp/styles.php1
-rw-r--r--phpBB/language/en/help_faq.php76
-rw-r--r--phpBB/language/en/install.php2
-rw-r--r--phpBB/language/en/mcp.php2
-rw-r--r--phpBB/language/en/memberlist.php2
-rw-r--r--phpBB/language/en/migrator.php4
-rw-r--r--phpBB/language/en/ucp.php2
-rw-r--r--phpBB/memberlist.php8
-rw-r--r--phpBB/phpbb/auth/auth.php6
-rw-r--r--phpBB/phpbb/auth/provider/apache.php4
-rw-r--r--phpBB/phpbb/auth/provider/db.php8
-rw-r--r--phpBB/phpbb/auth/provider_collection.php8
-rw-r--r--phpBB/phpbb/avatar/driver/local.php4
-rw-r--r--phpBB/phpbb/avatar/driver/remote.php18
-rw-r--r--phpBB/phpbb/avatar/manager.php40
-rw-r--r--phpBB/phpbb/captcha/plugins/recaptcha.php6
-rw-r--r--phpBB/phpbb/console/command/db/console_migrator_output_handler.php69
-rw-r--r--phpBB/phpbb/console/command/db/migrate.php40
-rw-r--r--phpBB/phpbb/controller/helper.php11
-rw-r--r--phpBB/phpbb/cron/manager.php1
-rw-r--r--phpBB/phpbb/cron/task/core/queue.php2
-rw-r--r--phpBB/phpbb/db/html_migrator_output_handler.php48
-rw-r--r--phpBB/phpbb/db/log_wrapper_migrator_output_handler.php95
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php57
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php5
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php65
-rw-r--r--phpBB/phpbb/db/migration/data/v310/bot_update.php150
-rw-r--r--phpBB/phpbb/db/migration/data/v310/captcha_plugins.php8
-rw-r--r--phpBB/phpbb/db/migration/data/v310/contact_admin_form.php5
-rw-r--r--phpBB/phpbb/db/migration/data/v310/gold.php32
-rw-r--r--phpBB/phpbb/db/migration/data/v310/rc6.php31
-rw-r--r--phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php3
-rw-r--r--phpBB/phpbb/db/migration/data/v31x/m_softdelete_global.php31
-rw-r--r--phpBB/phpbb/db/migration/data/v31x/style_update.php136
-rw-r--r--phpBB/phpbb/db/migration/data/v31x/v311.php32
-rw-r--r--phpBB/phpbb/db/migration/data/v31x/v312.php31
-rw-r--r--phpBB/phpbb/db/migration/data/v31x/v312rc1.php32
-rw-r--r--phpBB/phpbb/db/migrator.php61
-rw-r--r--phpBB/phpbb/db/migrator_output_handler_interface.php31
-rw-r--r--phpBB/phpbb/db/null_migrator_output_handler.php (renamed from travis/sami.conf.php)15
-rw-r--r--phpBB/phpbb/db/tools.php4
-rw-r--r--phpBB/phpbb/di/extension/config.php28
-rw-r--r--phpBB/phpbb/extension/metadata_manager.php34
-rw-r--r--phpBB/phpbb/file_downloader.php120
-rw-r--r--phpBB/phpbb/message/admin_form.php1
-rw-r--r--phpBB/phpbb/message/form.php2
-rw-r--r--phpBB/phpbb/message/topic_form.php2
-rw-r--r--phpBB/phpbb/notification/manager.php46
-rw-r--r--phpBB/phpbb/notification/type/admin_activate_user.php2
-rw-r--r--phpBB/phpbb/passwords/driver/bcrypt.php2
-rw-r--r--phpBB/phpbb/passwords/driver/bcrypt_wcf2.php2
-rw-r--r--phpBB/phpbb/passwords/driver/helper.php20
-rw-r--r--phpBB/phpbb/passwords/driver/md5_mybb.php2
-rw-r--r--phpBB/phpbb/passwords/driver/md5_phpbb2.php9
-rw-r--r--phpBB/phpbb/passwords/driver/md5_vb.php2
-rw-r--r--phpBB/phpbb/passwords/driver/salted_md5.php2
-rw-r--r--phpBB/phpbb/passwords/driver/sha1.php2
-rw-r--r--phpBB/phpbb/passwords/driver/sha1_smf.php2
-rw-r--r--phpBB/phpbb/passwords/driver/sha1_wcf1.php2
-rw-r--r--phpBB/phpbb/passwords/driver/sha_xf1.php4
-rw-r--r--phpBB/phpbb/path_helper.php14
-rw-r--r--phpBB/phpbb/profilefields/type/type_base.php14
-rw-r--r--phpBB/phpbb/profilefields/type/type_bool.php2
-rw-r--r--phpBB/phpbb/request/request.php23
-rw-r--r--phpBB/phpbb/request/request_interface.php10
-rw-r--r--phpBB/phpbb/session.php84
-rw-r--r--phpBB/phpbb/symfony_request.php13
-rw-r--r--phpBB/phpbb/template/twig/twig.php32
-rw-r--r--phpBB/phpbb/version_helper.php42
-rw-r--r--phpBB/posting.php45
-rw-r--r--phpBB/search.php2
-rw-r--r--phpBB/styles/prosilver/style.cfg4
-rw-r--r--phpBB/styles/prosilver/template/confirm_delete_body.html4
-rw-r--r--phpBB/styles/prosilver/template/forumlist_body.html2
-rw-r--r--phpBB/styles/prosilver/template/index_body.html2
-rw-r--r--phpBB/styles/prosilver/template/memberlist_email.html4
-rw-r--r--phpBB/styles/prosilver/template/memberlist_search.html3
-rw-r--r--phpBB/styles/prosilver/template/posting_buttons.html3
-rw-r--r--phpBB/styles/prosilver/template/ucp_pm_message_header.html1
-rw-r--r--phpBB/styles/prosilver/template/ucp_pm_viewmessage.html2
-rw-r--r--phpBB/styles/prosilver/theme/common.css2
-rw-r--r--phpBB/styles/prosilver/theme/content.css2
-rw-r--r--phpBB/styles/prosilver/theme/cp.css8
-rw-r--r--phpBB/styles/subsilver2/style.cfg4
-rw-r--r--phpBB/styles/subsilver2/template/confirm_delete_body.html2
-rw-r--r--phpBB/styles/subsilver2/template/index_body.html2
-rw-r--r--phpBB/styles/subsilver2/template/memberlist_email.html6
-rw-r--r--phpBB/styles/subsilver2/template/memberlist_search.html3
-rw-r--r--phpBB/styles/subsilver2/template/posting_buttons.html19
-rw-r--r--phpBB/viewforum.php8
-rw-r--r--phpBB/viewtopic.php5
-rw-r--r--phpunit.xml.dist11
-rw-r--r--tests/auth/provider_db_test.php9
-rw-r--r--tests/avatar/fixtures/users.xml28
-rw-r--r--tests/avatar/manager_test.php56
-rw-r--r--tests/bootstrap.php6
-rw-r--r--tests/composer.json5
-rw-r--r--tests/composer.lock66
-rw-r--r--tests/console/cron/run_test.php1
-rw-r--r--tests/controller/common_helper_route.php32
-rw-r--r--tests/controller/controller_test.php2
-rw-r--r--tests/datetime/from_format_test.php28
-rw-r--r--tests/extension/metadata_manager_test.php1
-rw-r--r--tests/functional/acp_groups_test.php4
-rw-r--r--tests/functional/acp_registration_test.php55
-rw-r--r--tests/functional/auth_test.php19
-rw-r--r--tests/functional/avatar_acp_groups_test.php4
-rw-r--r--tests/functional/avatar_acp_users_test.php4
-rw-r--r--tests/functional/avatar_ucp_groups_test.php4
-rw-r--r--tests/functional/avatar_ucp_users_test.php4
-rw-r--r--tests/functional/common_avatar_test_case.php (renamed from tests/functional/common_avatar_test.php)2
-rw-r--r--tests/functional/common_groups_test_case.php (renamed from tests/functional/common_groups_test.php)2
-rw-r--r--tests/functional/feed_test.php37
-rw-r--r--tests/functional/memberlist_test.php28
-rw-r--r--tests/functional/prune_shadow_topic_test.php4
-rw-r--r--tests/functional/registration_test.php15
-rw-r--r--tests/functional/ucp_groups_test.php4
-rw-r--r--tests/functional/viewforum_paging_test.php256
-rw-r--r--tests/functions/build_url_test.php5
-rw-r--r--tests/functions/make_clickable_test.php100
-rw-r--r--tests/functions/validate_username_test.php1
-rw-r--r--tests/functions_acp/insert_config_array_test.php (renamed from tests/functions/insert_config_array_test.php)2
-rw-r--r--tests/mock/controller_helper.php3
-rw-r--r--tests/mock/file_downloader.php27
-rw-r--r--tests/mock/metadata_manager.php2
-rw-r--r--tests/mock/request.php21
-rw-r--r--tests/notification/group_request_test.php1
-rw-r--r--tests/pagination/pagination_test.php2
-rw-r--r--tests/passwords/drivers_test.php2
-rw-r--r--tests/passwords/manager_test.php20
-rw-r--r--tests/path_helper/path_helper_test.php15
-rw-r--r--tests/security/base.php50
-rw-r--r--tests/security/extract_current_page_test.php49
-rw-r--r--tests/security/redirect_test.php4
-rw-r--r--tests/session/extract_page_test.php47
-rw-r--r--tests/template/ext/include/css/styles/all/theme/child_only.css0
-rw-r--r--tests/template/ext/include/css/styles/all/theme/test.css0
-rw-r--r--tests/template/template_includecss_test.php86
-rw-r--r--tests/template/templates/includecss.html11
-rw-r--r--tests/test_framework/phpbb_functional_test_case.php17
-rw-r--r--tests/test_framework/phpbb_session_test_case.php1
-rw-r--r--tests/test_framework/phpbb_test_case.php2
-rw-r--r--tests/test_framework/phpbb_ui_test_case.php204
-rw-r--r--tests/tree/nestedset_forum_base.php2
-rw-r--r--tests/ui/quick_links_test.php27
-rw-r--r--tests/version/version_fetch_test.php1
-rw-r--r--tests/version/version_helper_remote_test.php173
-rw-r--r--tests/version/version_test.php3
-rwxr-xr-xtravis/check-sami-parse-errors.sh2
-rwxr-xr-xtravis/install-phpbb-test-dependencies.sh16
-rw-r--r--travis/phpunit-mariadb-travis.xml4
-rw-r--r--travis/phpunit-mysql-travis.xml4
-rw-r--r--travis/phpunit-mysqli-travis.xml4
-rw-r--r--travis/phpunit-postgres-travis.xml4
-rw-r--r--travis/phpunit-sqlite3-travis.xml4
-rwxr-xr-xtravis/setup-phpbb.sh1
203 files changed, 3616 insertions, 921 deletions
diff --git a/.gitignore b/.gitignore
index f9c04980ba..8a119e8d6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,8 @@
*~
/phpunit.xml
-/phpBB/cache/twig/*
-/phpBB/cache/*.html
-/phpBB/cache/*.php
-/phpBB/cache/*.lock
+/phpBB/cache/*
+!/phpBB/.htaccess
+!/phpBB/index.html
/phpBB/composer.phar
/phpBB/config*.php
/phpBB/ext/*
@@ -22,3 +21,4 @@
/tests/phpbb_unit_tests.sqlite*
/tests/test_config*.php
/tests/tmp/*
+/tests/vendor
diff --git a/.travis.yml b/.travis.yml
index cbba07b16d..2e0b68c3de 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -34,6 +34,7 @@ install:
before_script:
- travis/setup-database.sh $DB $TRAVIS_PHP_VERSION
+ - phantomjs --webdriver=8910 > /dev/null &
script:
- travis/phing-sniff.sh $DB $TRAVIS_PHP_VERSION
diff --git a/build/build.xml b/build/build.xml
index de0f916a1f..dd7bb3d014 100644
--- a/build/build.xml
+++ b/build/build.xml
@@ -2,9 +2,9 @@
<project name="phpBB" description="The phpBB forum software" default="all" basedir="../">
<!-- a few settings for the build -->
- <property name="newversion" value="3.1.0-RC6-dev" />
- <property name="prevversion" value="3.1.0-RC5" />
- <property name="olderversions" value="3.0.12, 3.1.0-a1, 3.1.0-a2, 3.1.0-a3, 3.1.0-b1, 3.1.0-b2, 3.1.0-b3, 3.1.0-b4, 3.1.0-RC1, 3.1.0-RC2, 3.1.0-RC3, 3.1.0-RC4" />
+ <property name="newversion" value="3.1.3-RC1-dev" />
+ <property name="prevversion" value="3.1.2" />
+ <property name="olderversions" value="3.0.12, 3.1.0-a1, 3.1.0-a2, 3.1.0-a3, 3.1.0-b1, 3.1.0-b2, 3.1.0-b3, 3.1.0-b4, 3.1.0-RC1, 3.1.0-RC2, 3.1.0-RC3, 3.1.0-RC4, 3.1.0-RC5, 3.1.0-RC6, 3.1.0, 3.1.1, 3.1.2-RC1" />
<!-- no configuration should be needed beyond this point -->
<property name="oldversions" value="${olderversions}, ${prevversion}" />
@@ -117,9 +117,16 @@
</if>
</target>
+ <!-- Builds docs for current branch into build/api/output/master -->
<target name="docs">
<exec dir="."
- command="phpBB/vendor/bin/sami.php update build/sami.conf.php"
+ command="phpBB/vendor/bin/sami.php update build/sami-checkout.conf.php"
+ passthru="true" />
+ </target>
+ <!-- Builds docs for multiple branches/tags into build/api/output/$branch -->
+ <target name="docs-all">
+ <exec dir="."
+ command="phpBB/vendor/bin/sami.php update build/sami-all.conf.php"
passthru="true" />
</target>
diff --git a/build/build_changelog.php b/build/build_changelog.php
index be0fb625ea..2d38480f9f 100755
--- a/build/build_changelog.php
+++ b/build/build_changelog.php
@@ -20,7 +20,7 @@ if ($_SERVER['argc'] != 2)
$fixVersion = $_SERVER['argv'][1];
-$query = 'project = PHPBB3
+$query = 'project IN (PHPBB3, SECURITY)
AND resolution = Fixed
AND fixVersion = "' . $fixVersion . '"
AND status IN ("Unverified Fix", Closed)';
diff --git a/build/sami-all.conf.php b/build/sami-all.conf.php
new file mode 100644
index 0000000000..68350fee8f
--- /dev/null
+++ b/build/sami-all.conf.php
@@ -0,0 +1,30 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+require __DIR__ . '/sami-checkout.conf.php';
+
+$config['versions'] = Sami\Version\GitVersionCollection::create(__DIR__ . '/../')
+ /*
+ This would be nice, but currently causes various problems that need
+ debugging.
+ ->addFromTags('release-3.0.*')
+ ->add('develop-olympus', '3.0-next (olympus)')
+ ->addFromTags('release-3.1.*')
+ ->add('develop-ascraeus', '3.1-next (ascraeus)')
+ ->add('develop')
+ */
+ ->add('develop-olympus')
+ ->add('develop-ascraeus')
+;
+
+return new Sami\Sami($iterator, $config);
diff --git a/build/sami.conf.php b/build/sami-checkout.conf.php
index 78d532631c..abbf1d257e 100644
--- a/build/sami.conf.php
+++ b/build/sami-checkout.conf.php
@@ -31,23 +31,8 @@ $iterator = Symfony\Component\Finder\Finder::create()
->notPath('data')
;
-$versions = Sami\Version\GitVersionCollection::create(__DIR__ . '/../')
- /*
- This would be nice, but currently causes various problems that need
- debugging.
- ->addFromTags('release-3.0.*')
- ->add('develop-olympus', '3.0-next (olympus)')
- ->addFromTags('release-3.1.*')
- ->add('develop-ascraeus', '3.1-next (ascraeus)')
- ->add('develop')
- */
- ->add('develop-olympus')
- ->add('develop-ascraeus')
-;
-
$config = array(
'theme' => 'enhanced',
- 'versions' => $versions,
'title' => 'phpBB API Documentation',
'build_dir' => __DIR__.'/api/output/%version%',
'cache_dir' => __DIR__.'/api/cache/%version%',
diff --git a/phpBB/adm/style/acp_email.html b/phpBB/adm/style/acp_email.html
index 950ecb40b0..63acd7fcc1 100644
--- a/phpBB/adm/style/acp_email.html
+++ b/phpBB/adm/style/acp_email.html
@@ -47,6 +47,8 @@
<dd><input id="send" type="checkbox" class="radio" name="send_immediately" checked="checked" /></dd>
</dl>
+<!-- EVENT acp_email_options_after -->
+
<p class="submit-buttons">
<input class="button1" type="submit" id="submit" name="submit" value="{L_SEND_EMAIL}" />&nbsp;
<input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" />
diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html
index af79791ff8..756092a1f0 100644
--- a/phpBB/adm/style/acp_forums.html
+++ b/phpBB/adm/style/acp_forums.html
@@ -111,6 +111,7 @@
<fieldset>
<legend>{L_FORUM_SETTINGS}</legend>
+ <!-- EVENT acp_forums_main_settings_prepend -->
<dl>
<dt><label for="forum_type">{L_FORUM_TYPE}{L_COLON}</label></dt>
<dd><select id="forum_type" name="forum_type" onchange="display_options(this.options[this.selectedIndex].value);">{S_FORUM_TYPE_OPTIONS}</select></dd>
@@ -182,6 +183,7 @@
<dt><label for="forum_style">{L_FORUM_STYLE}{L_COLON}</label></dt>
<dd><select id="forum_style" name="forum_style"><option value="0">{L_DEFAULT_STYLE}</option>{S_STYLES_OPTIONS}</select></dd>
</dl>
+ <!-- EVENT acp_forums_main_settings_append -->
</fieldset>
<div id="forum_cat_options">
@@ -198,6 +200,7 @@
<div id="forum_post_options">
<fieldset>
<legend>{L_GENERAL_FORUM_SETTINGS}</legend>
+ <!-- EVENT acp_forums_normal_settings_prepend -->
<dl>
<dt><label for="forum_status">{L_FORUM_STATUS}{L_COLON}</label></dt>
<dd><select id="forum_status" name="forum_status">{S_STATUS_OPTIONS}</select></dd>
@@ -246,6 +249,7 @@
<fieldset>
<legend>{L_FORUM_PRUNE_SETTINGS}</legend>
+ <!-- EVENT acp_forums_prune_settings_prepend -->
<dl>
<dt><label for="enable_prune">{L_FORUM_AUTO_PRUNE}{L_COLON}</label><br /><span>{L_FORUM_AUTO_PRUNE_EXPLAIN}</span></dt>
<dd><label><input type="radio" class="radio" name="enable_prune" value="1"<!-- IF S_PRUNE_ENABLE --> id="enable_prune" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
@@ -291,6 +295,7 @@
<dt><label for="prune_shadow_days">{L_AUTO_PRUNE_SHADOW_DAYS}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_SHADOW_DAYS_EXPLAIN}</span></dt>
<dd><input type="number" id="prune_shadow_days" name="prune_shadow_days" value="{PRUNE_SHADOW_DAYS}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd>
</dl>
+ <!-- EVENT acp_forums_prune_settings_append -->
</fieldset>
</div>
@@ -317,6 +322,7 @@
<div id="forum_rules_options">
<fieldset>
<legend>{L_FORUM_RULES}</legend>
+ <!-- EVENT acp_forums_rules_settings_prepend -->
<dl>
<dt><label for="forum_rules_link">{L_FORUM_RULES_LINK}{L_COLON}</label><br /><span>{L_FORUM_RULES_LINK_EXPLAIN}</span></dt>
<dd><input class="text medium" type="text" id="forum_rules_link" name="forum_rules_link" value="{FORUM_RULES_LINK}" maxlength="255" /></dd>
@@ -334,6 +340,7 @@
<label><input type="checkbox" class="radio" name="rules_parse_smilies"<!-- IF S_SMILIES_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_SMILIES}</label>
<label><input type="checkbox" class="radio" name="rules_parse_urls"<!-- IF S_URLS_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_PARSE_URLS}</label></dd>
</dl>
+ <!-- EVENT acp_forums_rules_settings_append -->
</fieldset>
</div>
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index 6ddbba7515..6481a2e113 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -386,7 +386,8 @@ phpbb.ajaxify = function(options) {
type: method,
data: data,
success: returnHandler,
- error: errorHandler
+ error: errorHandler,
+ cache: false
});
request.always(function() {
$loadingIndicator.fadeOut(phpbb.alertTime);
diff --git a/phpBB/assets/javascript/plupload.js b/phpBB/assets/javascript/plupload.js
index 5445e83e15..a58c71e64d 100644
--- a/phpBB/assets/javascript/plupload.js
+++ b/phpBB/assets/javascript/plupload.js
@@ -34,6 +34,14 @@ phpbb.plupload.initialize = function() {
if (uploader.features.dragdrop) {
$('#drag-n-drop-message').show();
}
+
+ // Ensure "Add files" button position is correctly calculated.
+ if ($('#attach-panel-multi').is(':visible')) {
+ uploader.refresh();
+ }
+ $('[data-subpanel="attach-panel"]').one('click', function() {
+ uploader.refresh();
+ });
});
};
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index b686bfef5c..07ae59f863 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -108,17 +108,17 @@
},
{
"name": "symfony/config",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/Config",
"source": {
"type": "git",
"url": "https://github.com/symfony/Config.git",
- "reference": "b34d2b32a92938476f0689486e7a11ea1aeb079e"
+ "reference": "f9fac999dbc2c6aabd749c034d938b5f9aa5fb7d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Config/zipball/b34d2b32a92938476f0689486e7a11ea1aeb079e",
- "reference": "b34d2b32a92938476f0689486e7a11ea1aeb079e",
+ "url": "https://api.github.com/repos/symfony/Config/zipball/f9fac999dbc2c6aabd749c034d938b5f9aa5fb7d",
+ "reference": "f9fac999dbc2c6aabd749c034d938b5f9aa5fb7d",
"shasum": ""
},
"require": {
@@ -152,21 +152,21 @@
],
"description": "Symfony Config Component",
"homepage": "http://symfony.com",
- "time": "2014-08-02 07:53:48"
+ "time": "2014-09-23 05:15:05"
},
{
"name": "symfony/console",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
- "reference": "a2723f99716c2fa6411e2eb5842edbe680e4b462"
+ "reference": "aa12ac573c583a74c2cb26ad9be478e119f04ad1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Console/zipball/a2723f99716c2fa6411e2eb5842edbe680e4b462",
- "reference": "a2723f99716c2fa6411e2eb5842edbe680e4b462",
+ "url": "https://api.github.com/repos/symfony/Console/zipball/aa12ac573c583a74c2cb26ad9be478e119f04ad1",
+ "reference": "aa12ac573c583a74c2cb26ad9be478e119f04ad1",
"shasum": ""
},
"require": {
@@ -205,21 +205,21 @@
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com",
- "time": "2014-08-07 15:55:24"
+ "time": "2014-10-05 13:45:10"
},
{
"name": "symfony/debug",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/Debug",
"source": {
"type": "git",
"url": "https://github.com/symfony/Debug.git",
- "reference": "91e3a1480c67601d2406cd938735abe0243e1c95"
+ "reference": "883f847ad179e92549a8cea372b08e5ef47ffe40"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Debug/zipball/91e3a1480c67601d2406cd938735abe0243e1c95",
- "reference": "91e3a1480c67601d2406cd938735abe0243e1c95",
+ "url": "https://api.github.com/repos/symfony/Debug/zipball/883f847ad179e92549a8cea372b08e5ef47ffe40",
+ "reference": "883f847ad179e92549a8cea372b08e5ef47ffe40",
"shasum": ""
},
"require": {
@@ -261,21 +261,21 @@
],
"description": "Symfony Debug Component",
"homepage": "http://symfony.com",
- "time": "2014-07-07 10:13:42"
+ "time": "2014-10-09 16:42:17"
},
{
"name": "symfony/dependency-injection",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/DependencyInjection",
"source": {
"type": "git",
"url": "https://github.com/symfony/DependencyInjection.git",
- "reference": "5ee5795515be251c56057d79154e561ee1efecd2"
+ "reference": "e2324e1c8c39faa5f27e6170b278d7f631574141"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/5ee5795515be251c56057d79154e561ee1efecd2",
- "reference": "5ee5795515be251c56057d79154e561ee1efecd2",
+ "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/e2324e1c8c39faa5f27e6170b278d7f631574141",
+ "reference": "e2324e1c8c39faa5f27e6170b278d7f631574141",
"shasum": ""
},
"require": {
@@ -317,21 +317,21 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "http://symfony.com",
- "time": "2014-08-27 08:32:18"
+ "time": "2014-10-01 05:38:33"
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/EventDispatcher",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
- "reference": "2c64e46d7e22bcafcab4413ff62bc389abf87ea5"
+ "reference": "3e0b837811fadd73c833c7c06a92201d953df59d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/2c64e46d7e22bcafcab4413ff62bc389abf87ea5",
- "reference": "2c64e46d7e22bcafcab4413ff62bc389abf87ea5",
+ "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/3e0b837811fadd73c833c7c06a92201d953df59d",
+ "reference": "3e0b837811fadd73c833c7c06a92201d953df59d",
"shasum": ""
},
"require": {
@@ -371,21 +371,21 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com",
- "time": "2014-07-25 15:00:14"
+ "time": "2014-10-01 05:39:06"
},
{
"name": "symfony/filesystem",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/Filesystem",
"source": {
"type": "git",
"url": "https://github.com/symfony/Filesystem.git",
- "reference": "007359d2822d5eba4f04f6507bc9b46877c622b4"
+ "reference": "1c3a5fab445d1d4a5d57f8fbf1379696c9785942"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Filesystem/zipball/007359d2822d5eba4f04f6507bc9b46877c622b4",
- "reference": "007359d2822d5eba4f04f6507bc9b46877c622b4",
+ "url": "https://api.github.com/repos/symfony/Filesystem/zipball/1c3a5fab445d1d4a5d57f8fbf1379696c9785942",
+ "reference": "1c3a5fab445d1d4a5d57f8fbf1379696c9785942",
"shasum": ""
},
"require": {
@@ -418,21 +418,21 @@
],
"description": "Symfony Filesystem Component",
"homepage": "http://symfony.com",
- "time": "2014-08-31 03:30:23"
+ "time": "2014-09-22 08:32:35"
},
{
"name": "symfony/http-foundation",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/HttpFoundation",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpFoundation.git",
- "reference": "d0125fed988da9e189864c2e6de967b3ee7f1d98"
+ "reference": "30c90f08f948dd43e7310beae7a85c02ad2b655d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/d0125fed988da9e189864c2e6de967b3ee7f1d98",
- "reference": "d0125fed988da9e189864c2e6de967b3ee7f1d98",
+ "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/30c90f08f948dd43e7310beae7a85c02ad2b655d",
+ "reference": "30c90f08f948dd43e7310beae7a85c02ad2b655d",
"shasum": ""
},
"require": {
@@ -468,21 +468,21 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "http://symfony.com",
- "time": "2014-09-03 07:39:11"
+ "time": "2014-10-23 13:11:04"
},
{
"name": "symfony/http-kernel",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/HttpKernel",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpKernel.git",
- "reference": "a24817f69012b23ce7c554af6b4c7b53235c7c55"
+ "reference": "0154ff659004d4148e8da0f2bdb672efe55e6ee5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/a24817f69012b23ce7c554af6b4c7b53235c7c55",
- "reference": "a24817f69012b23ce7c554af6b4c7b53235c7c55",
+ "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/0154ff659004d4148e8da0f2bdb672efe55e6ee5",
+ "reference": "0154ff659004d4148e8da0f2bdb672efe55e6ee5",
"shasum": ""
},
"require": {
@@ -539,21 +539,21 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "http://symfony.com",
- "time": "2014-09-03 09:45:27"
+ "time": "2014-10-24 05:54:08"
},
{
"name": "symfony/routing",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/Routing",
"source": {
"type": "git",
"url": "https://github.com/symfony/Routing.git",
- "reference": "aa2beef5d5f1d84250b5ca73a4056c0504e5969e"
+ "reference": "f7f8ebf9c99e5ebfdb908c3558a818c2883eab1f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Routing/zipball/aa2beef5d5f1d84250b5ca73a4056c0504e5969e",
- "reference": "aa2beef5d5f1d84250b5ca73a4056c0504e5969e",
+ "url": "https://api.github.com/repos/symfony/Routing/zipball/f7f8ebf9c99e5ebfdb908c3558a818c2883eab1f",
+ "reference": "f7f8ebf9c99e5ebfdb908c3558a818c2883eab1f",
"shasum": ""
},
"require": {
@@ -563,6 +563,7 @@
"doctrine/common": "~2.2",
"psr/log": "~1.0",
"symfony/config": "~2.2",
+ "symfony/http-foundation": "~2.3",
"symfony/yaml": "~2.0"
},
"suggest": {
@@ -597,21 +598,21 @@
],
"description": "Symfony Routing Component",
"homepage": "http://symfony.com",
- "time": "2014-08-15 09:05:55"
+ "time": "2014-10-13 12:38:27"
},
{
"name": "symfony/yaml",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
- "reference": "71ceeca3d8164f0c5313127b24ad056071ccf2c6"
+ "reference": "34687c6236f1dfcebc874fbebd8da74d90f9f64f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Yaml/zipball/71ceeca3d8164f0c5313127b24ad056071ccf2c6",
- "reference": "71ceeca3d8164f0c5313127b24ad056071ccf2c6",
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/34687c6236f1dfcebc874fbebd8da74d90f9f64f",
+ "reference": "34687c6236f1dfcebc874fbebd8da74d90f9f64f",
"shasum": ""
},
"require": {
@@ -644,7 +645,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
- "time": "2014-08-28 01:42:35"
+ "time": "2014-10-01 05:38:33"
},
{
"name": "twig/twig",
@@ -702,21 +703,21 @@
"packages-dev": [
{
"name": "fabpot/goutte",
- "version": "v1.0.3",
+ "version": "v1.0.7",
"source": {
"type": "git",
- "url": "https://github.com/fabpot/Goutte.git",
- "reference": "75c9f23c4122caf4ea3e87a42a00b471366e707f"
+ "url": "https://github.com/FriendsOfPHP/Goutte.git",
+ "reference": "794b196e76bdd37b5155cdecbad311f0a3b07625"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fabpot/Goutte/zipball/75c9f23c4122caf4ea3e87a42a00b471366e707f",
- "reference": "75c9f23c4122caf4ea3e87a42a00b471366e707f",
+ "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/794b196e76bdd37b5155cdecbad311f0a3b07625",
+ "reference": "794b196e76bdd37b5155cdecbad311f0a3b07625",
"shasum": ""
},
"require": {
"ext-curl": "*",
- "guzzle/http": ">=3.0.5,<3.8-dev",
+ "guzzle/http": "~3.1",
"php": ">=5.3.0",
"symfony/browser-kit": "~2.1",
"symfony/css-selector": "~2.1",
@@ -725,8 +726,8 @@
"symfony/process": "~2.1"
},
"require-dev": {
- "guzzle/plugin-history": ">=3.0.5,<3.8-dev",
- "guzzle/plugin-mock": ">=3.0.5,<3.8-dev"
+ "guzzle/plugin-history": "~3.1",
+ "guzzle/plugin-mock": "~3.1"
},
"type": "application",
"extra": {
@@ -746,9 +747,7 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com",
- "homepage": "http://fabien.potencier.org",
- "role": "Lead Developer"
+ "email": "fabien@symfony.com"
}
],
"description": "A simple PHP Web Scraper",
@@ -756,7 +755,7 @@
"keywords": [
"scraper"
],
- "time": "2013-08-16 06:03:22"
+ "time": "2014-10-09 15:52:51"
},
{
"name": "guzzle/common",
@@ -1591,16 +1590,16 @@
},
{
"name": "sami/sami",
- "version": "v1.3",
+ "version": "v1.4",
"source": {
"type": "git",
- "url": "https://github.com/fabpot/Sami.git",
- "reference": "76f2ed80b3420f7e2f6dcd5b7218b5a5781f4110"
+ "url": "https://github.com/FriendsOfPHP/Sami.git",
+ "reference": "70f29c781f7bef30181c814b9471b2ceac694454"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fabpot/Sami/zipball/76f2ed80b3420f7e2f6dcd5b7218b5a5781f4110",
- "reference": "76f2ed80b3420f7e2f6dcd5b7218b5a5781f4110",
+ "url": "https://api.github.com/repos/FriendsOfPHP/Sami/zipball/70f29c781f7bef30181c814b9471b2ceac694454",
+ "reference": "70f29c781f7bef30181c814b9471b2ceac694454",
"shasum": ""
},
"require": {
@@ -1621,7 +1620,7 @@
"type": "application",
"extra": {
"branch-alias": {
- "dev-master": "1.3-dev"
+ "dev-master": "1.4-dev"
}
},
"autoload": {
@@ -1636,9 +1635,7 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com",
- "homepage": "http://fabien.potencier.org",
- "role": "Lead Developer"
+ "email": "fabien@symfony.com"
}
],
"description": "Sami, an API documentation generator",
@@ -1646,7 +1643,7 @@
"keywords": [
"phpdoc"
],
- "time": "2013-11-30 17:16:25"
+ "time": "2014-06-25 11:24:03"
},
{
"name": "sebastian/comparator",
@@ -1987,17 +1984,17 @@
},
{
"name": "symfony/browser-kit",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/BrowserKit",
"source": {
"type": "git",
"url": "https://github.com/symfony/BrowserKit.git",
- "reference": "262d698efaa788ce24ff9c987378789bf3f81ce9"
+ "reference": "6a403eedacb56d32dc2cc657cfeac09d640ae6bc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/262d698efaa788ce24ff9c987378789bf3f81ce9",
- "reference": "262d698efaa788ce24ff9c987378789bf3f81ce9",
+ "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/6a403eedacb56d32dc2cc657cfeac09d640ae6bc",
+ "reference": "6a403eedacb56d32dc2cc657cfeac09d640ae6bc",
"shasum": ""
},
"require": {
@@ -2038,21 +2035,21 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "http://symfony.com",
- "time": "2014-08-05 07:20:55"
+ "time": "2014-09-22 08:32:35"
},
{
"name": "symfony/css-selector",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/CssSelector",
"source": {
"type": "git",
"url": "https://github.com/symfony/CssSelector.git",
- "reference": "8953d325d3341c246abadb79be172de95ef80664"
+ "reference": "d9943386b648d21746bed25cc24f61fab1387943"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/CssSelector/zipball/8953d325d3341c246abadb79be172de95ef80664",
- "reference": "8953d325d3341c246abadb79be172de95ef80664",
+ "url": "https://api.github.com/repos/symfony/CssSelector/zipball/d9943386b648d21746bed25cc24f61fab1387943",
+ "reference": "d9943386b648d21746bed25cc24f61fab1387943",
"shasum": ""
},
"require": {
@@ -2089,21 +2086,21 @@
],
"description": "Symfony CssSelector Component",
"homepage": "http://symfony.com",
- "time": "2014-08-27 08:24:06"
+ "time": "2014-10-09 12:30:02"
},
{
"name": "symfony/dom-crawler",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/DomCrawler",
"source": {
"type": "git",
"url": "https://github.com/symfony/DomCrawler.git",
- "reference": "bad8d98561f071639fa67b20680bffcc256ce252"
+ "reference": "64b90870ee3a4e88c9a7a12861683864de029d31"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/bad8d98561f071639fa67b20680bffcc256ce252",
- "reference": "bad8d98561f071639fa67b20680bffcc256ce252",
+ "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/64b90870ee3a4e88c9a7a12861683864de029d31",
+ "reference": "64b90870ee3a4e88c9a7a12861683864de029d31",
"shasum": ""
},
"require": {
@@ -2142,21 +2139,21 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "http://symfony.com",
- "time": "2014-08-21 00:21:59"
+ "time": "2014-10-01 05:38:33"
},
{
"name": "symfony/finder",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/Finder",
"source": {
"type": "git",
"url": "https://github.com/symfony/Finder.git",
- "reference": "f7a5a5a3b1fc0ec9a1a5b4429223a8726e0f4b55"
+ "reference": "fc25dab213d14468c39f12d47e5b79a72b898d4d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Finder/zipball/f7a5a5a3b1fc0ec9a1a5b4429223a8726e0f4b55",
- "reference": "f7a5a5a3b1fc0ec9a1a5b4429223a8726e0f4b55",
+ "url": "https://api.github.com/repos/symfony/Finder/zipball/fc25dab213d14468c39f12d47e5b79a72b898d4d",
+ "reference": "fc25dab213d14468c39f12d47e5b79a72b898d4d",
"shasum": ""
},
"require": {
@@ -2189,21 +2186,21 @@
],
"description": "Symfony Finder Component",
"homepage": "http://symfony.com",
- "time": "2014-08-31 04:03:32"
+ "time": "2014-10-01 05:39:06"
},
{
"name": "symfony/process",
- "version": "v2.3.19",
+ "version": "v2.3.21",
"target-dir": "Symfony/Component/Process",
"source": {
"type": "git",
"url": "https://github.com/symfony/Process.git",
- "reference": "b8fc0e4b6750e4c458a38d038e6b4d538d4fe2bb"
+ "reference": "0434822691030547f2439d30ff68758c5576a0ce"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Process/zipball/b8fc0e4b6750e4c458a38d038e6b4d538d4fe2bb",
- "reference": "b8fc0e4b6750e4c458a38d038e6b4d538d4fe2bb",
+ "url": "https://api.github.com/repos/symfony/Process/zipball/0434822691030547f2439d30ff68758c5576a0ce",
+ "reference": "0434822691030547f2439d30ff68758c5576a0ce",
"shasum": ""
},
"require": {
@@ -2236,7 +2233,7 @@
],
"description": "Symfony Process Component",
"homepage": "http://symfony.com",
- "time": "2014-08-28 09:02:24"
+ "time": "2014-10-01 05:38:33"
}
],
"aliases": [
diff --git a/phpBB/config/console.yml b/phpBB/config/console.yml
index 540908164a..1e18a7dd37 100644
--- a/phpBB/config/console.yml
+++ b/phpBB/config/console.yml
@@ -84,6 +84,7 @@ services:
- @config
- @cache
- @log
+ - %core.root_path%
tags:
- { name: console.command }
diff --git a/phpBB/config/password.yml b/phpBB/config/password.yml
index 09e935016e..cb45ec3d42 100644
--- a/phpBB/config/password.yml
+++ b/phpBB/config/password.yml
@@ -101,6 +101,7 @@ services:
arguments:
- @request
- @passwords.driver.salted_md5
+ - @passwords.driver_helper
- %core.root_path%
- %core.php_ext%
tags:
diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml
index 5003697564..8667cbbf84 100644
--- a/phpBB/config/services.yml
+++ b/phpBB/config/services.yml
@@ -75,6 +75,7 @@ services:
- @controller.provider
- @ext.manager
- @symfony_request
+ - @request
- @filesystem
- %core.root_path%
- %core.php_ext%
@@ -108,6 +109,9 @@ services:
filesystem:
class: phpbb\filesystem
+ file_downloader:
+ class: phpbb\file_downloader
+
http_kernel:
class: Symfony\Component\HttpKernel\HttpKernel
arguments:
@@ -155,6 +159,8 @@ services:
- null
- %core.disable_super_globals%
+ # WARNING: The Symfony request does not escape the input and should be used very carefully
+ # prefer the phpbb request (service @request) as possible
symfony_request:
class: phpbb\symfony_request
arguments:
@@ -178,4 +184,5 @@ services:
arguments:
- @cache
- @config
+ - @file_downloader
- @user
diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html
index 3f6bd0ee51..5cf98e20fc 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -46,6 +46,10 @@
<ol>
<li><a href="#changelog">Changelog</a>
<ol style="list-style-type: lower-roman;">
+ <li><a href="#v311">Changes since 3.1.1</a></li>
+ <li><a href="#v310">Changes since 3.1.0</a></li>
+ <li><a href="#v310RC6">Changes since 3.1.0-RC6</a></li>
+ <li><a href="#v310RC5">Changes since 3.1.0-RC5</a></li>
<li><a href="#v310RC4">Changes since 3.1.0-RC4</a></li>
<li><a href="#v310RC3">Changes since 3.1.0-RC3</a></li>
<li><a href="#v310RC2">Changes since 3.1.0-RC2</a></li>
@@ -98,7 +102,175 @@
<div class="content">
- <a name="v310RC4"></a><h3>1.i. Changes since 3.1.0-RC4</h3>
+ <a name="v311"></a><h3>1.i. Changes since 3.1.1</h3>
+
+ <h4>Security</h4>
+ <ul>
+ <li>[SECURITY-171] - Version helper does not properly escape version info</li>
+ <li>[SECURITY-169] - AJAX request with unexpected referrer causes infinite loop</li>
+ </ul>
+
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10442">PHPBB3-10442</a>] - XHTML is invalid when a forum link without redirect counter is present</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10744">PHPBB3-10744</a>] - Prevent user from installing styles with reserved directory names</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11863">PHPBB3-11863</a>] - User registration settings show incorrectly as disabled when board-wide emails are disabled</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12703">PHPBB3-12703</a>] - Notification System sends exact same SQL query multiple times</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13083">PHPBB3-13083</a>] - Language correction in NO_ENTRIES in acp_logs</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13100">PHPBB3-13100</a>] - Don't display &quot;delete reason&quot; dialog for shadow-topics</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13193">PHPBB3-13193</a>] - Post counts in Private Messages should link to the user's posts</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13197">PHPBB3-13197</a>] - Group Avatar not deleted from users</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13204">PHPBB3-13204</a>] - Login flood control error supresses incorrect credential error</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13209">PHPBB3-13209</a>] - Boolean (Yes/No) custom profile field doesn't show given name</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13216">PHPBB3-13216</a>] - Datetime tests fail randomly</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13228">PHPBB3-13228</a>] - &quot;Code: Select all&quot; font-size too big in Private Messages</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13239">PHPBB3-13239</a>] - Can´t upload Attachments on iOS</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13241">PHPBB3-13241</a>] - Topics are being duplicated in multipage forums</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13242">PHPBB3-13242</a>] - Validation error in Contact a Board Administrator</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13243">PHPBB3-13243</a>] - Debug error when clicking Re-check all versions on ACP manage extensions page</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13251">PHPBB3-13251</a>] - Database password containing special characters no longer accepted after upgrade to 3.1.0</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13253">PHPBB3-13253</a>] - MCP queue link in active topics search is missing</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13265">PHPBB3-13265</a>] - &quot;Edit profile&quot; link on view-own-profile page should only show if user has permission to edit</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13270">PHPBB3-13270</a>] - Upgrading from 3.0.12 to 3.1.1 does not display moderator soft delete permissions</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13277">PHPBB3-13277</a>] - Move Up &amp; Down does not take work in Internet Explorer</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13280">PHPBB3-13280</a>] - $user-&gt;page['page'] - is invalid resulting in confirm_box() not working correctly</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13284">PHPBB3-13284</a>] - Message body not included in email topic message </li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13298">PHPBB3-13298</a>] - Use mysql_free_result to free result sets which were requested using mysql_query()</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13300">PHPBB3-13300</a>] - Jabber field still shown in profile when feature is disabled</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13301">PHPBB3-13301</a>] - Apache Authentication is probably broken</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13303">PHPBB3-13303</a>] - Migrator caught in loop calculating dependencies</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13315">PHPBB3-13315</a>] - Upgrade from 3.0.12 to 3.1.1 resets CAPTCHA selection</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13316">PHPBB3-13316</a>] - reCAPTCHA does not work on secured connection</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13318">PHPBB3-13318</a>] - login_username doesn't have multibyte parameter set to true</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13323">PHPBB3-13323</a>] - posting.php can pass invalid auth option to acl_get()</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13332">PHPBB3-13332</a>] - Insufficient information passed to password drivers for converted boards</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13337">PHPBB3-13337</a>] - Mark subforums read triggers error if subforums contain no topics</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13338">PHPBB3-13338</a>] - Some tests fail when run on their own</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13342">PHPBB3-13342</a>] - 310/captcha_plugins migration changes recaptcha to nogd</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13349">PHPBB3-13349</a>] - Incorrect entities used for breadcrumb separator in CSS</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13354">PHPBB3-13354</a>] - Unknown column 'topic_logs' in 'where clause' when deleting topic log in MCP</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13376">PHPBB3-13376</a>] - deregister_globals() does not work correctly when $_COOKIE['GLOBALS'] is specified</li>
+ </ul>
+
+ <h4>Improvement</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12681">PHPBB3-12681</a>] - Cache the compiled routes and dump the url_generator</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12885">PHPBB3-12885</a>] - Wrong index page title when using Board Index text</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13023">PHPBB3-13023</a>] - [event] - Add Event posting_editor_buttons_custom_tags_before</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13133">PHPBB3-13133</a>] - Allow @vendor_extname in INCLUDECSS</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13182">PHPBB3-13182</a>] - [event] - Add posting.php core event to allow modifying the message before parsing</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13220">PHPBB3-13220</a>] - [event] - Add template events to memberlist_search.html</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13290">PHPBB3-13290</a>] - [event] - Add template event index_body_forumlist_body_after</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13294">PHPBB3-13294</a>] - [event] - Add message_parser.php core event for additional message handling before parsing</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13297">PHPBB3-13297</a>] - Add unicode modifier to url/email regular expression patterns</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13309">PHPBB3-13309</a>] - [event] - Add ACP template event acp_email_options_after</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13310">PHPBB3-13310</a>] - [event] - Add core event core.acp_email_modify_sql</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13326">PHPBB3-13326</a>] - Add viewtopic_url variable to a viewtopic event</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13328">PHPBB3-13328</a>] - [event] - Add event core.mcp_view_forum_modify_sql</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13347">PHPBB3-13347</a>] - [event] - Add new template events to acp_forums.html</li>
+ </ul>
+
+ <h4>New Feature</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12962">PHPBB3-12962</a>] - Use phantomjs and webdriver for UI testing</li>
+ </ul>
+
+ <h4>Task</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13324">PHPBB3-13324</a>] - Composer no longer downloads sami/sami and fabpot/goutte</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13325">PHPBB3-13325</a>] - Make installing dependencies for tests more user friendly or optional</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13331">PHPBB3-13331</a>] - Sami run as part of phing MUST NOT switch branches</li>
+ </ul>
+
+
+ <a name="v310"></a><h3>1.ii. Changes since 3.1.0</h3>
+
+ <h4>Security</h4>
+ <ul>
+ <li>[SECURITY-164] - Cross Site Scripting via PATH_INFO in page_name variable</li>
+ </ul>
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13248">PHPBB3-13248</a>] - Login functions need to use provider collection for retrieving provider</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13267">PHPBB3-13267</a>] - Automatic Update instructions indicate that only the install folder is necessary</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13268">PHPBB3-13268</a>] - MSSQL's get_existing_indexes() function improperly appends ternary result</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13271">PHPBB3-13271</a>] - Anonymous users can CC themselves on emails sent to admin via contact form</li>
+ </ul>
+ <h4>Task</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13262">PHPBB3-13262</a>] - Add note to docs about htaccess file when upgrading 3.0 to 3.1</li>
+ </ul>
+
+ <a name="v310RC6"></a><h3>1.iii. Changes since 3.1.0-RC6</h3>
+
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13126">PHPBB3-13126</a>] - More detailed output for migrations needed</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13208">PHPBB3-13208</a>] - Security issues are not pulled into the changelog</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13210">PHPBB3-13210</a>] - Queue Cron Job checks for wrong config variable queue_interval_config</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13211">PHPBB3-13211</a>] - Add possibility to save migrations output to log</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13221">PHPBB3-13221</a>] - Can't upgrade to 3.1 from 3.0.11 and older</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13223">PHPBB3-13223</a>] - Using get_username_string() for email template variables causes HTML markup in emails</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13225">PHPBB3-13225</a>] - phpbb_hash() undefined in phpbb\db\migration\data\v30x\release_3_0_5_rc1.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13226">PHPBB3-13226</a>] - Stray $rank_img in memberlist.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13227">PHPBB3-13227</a>] - Remote avatars do not work with cURL wrapper</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13229">PHPBB3-13229</a>] - Memberlist is getting overloaded with redundant SQL queries</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13230">PHPBB3-13230</a>] - Deprecated phpbb_clean_path() does not work anymore</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13231">PHPBB3-13231</a>] - The migration contact_admin_form must depends on config_db_text</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13232">PHPBB3-13232</a>] - Email queue does not get run</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13234">PHPBB3-13234</a>] - Remember me cookie gets unset by admin reauthentication</li>
+ </ul>
+ <h4>Improvement</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13207">PHPBB3-13207</a>] - Default subscription notification setting for new users does not include email</li>
+ </ul>
+ <h4>Task</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13215">PHPBB3-13215</a>] - Update Symfony Components to 2.3.21</li>
+ </ul>
+
+ <a name="v310RC5"></a><h3>1.iv. Changes since 3.1.0-RC5</h3>
+
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12530">PHPBB3-12530</a>] - Visual confirmation is breaking layout in prosilver's mobile mode</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12568">PHPBB3-12568</a>] - docs/README.html references MODs instead of extensions</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13124">PHPBB3-13124</a>] - PHP event extractor too strict on doc blocks</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13138">PHPBB3-13138</a>] - Banned users cause infinite recursion</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13140">PHPBB3-13140</a>] - Header links don't re-appear on window size increase</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13161">PHPBB3-13161</a>] - PHP Warnings issued from phpbb database test case</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13163">PHPBB3-13163</a>] - Header Navbar Responsiveness Broken</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13164">PHPBB3-13164</a>] - Data sent to core.submit_post_end event does not include fresh post_visibility</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13168">PHPBB3-13168</a>] - Warning displayed in PHP 5.6 for mbstring.http_input</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13169">PHPBB3-13169</a>] - Responsive forms not displaying correctly in RTL</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13171">PHPBB3-13171</a>] - Can not delete posts and soft delete topics in MCP topic view</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13174">PHPBB3-13174</a>] - Minor HTML error in ucp_pm_viewmessage.html (needs closing &lt;/div&gt;)</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13177">PHPBB3-13177</a>] - Post count-based ranks do not display in viewtopic</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13181">PHPBB3-13181</a>] - Sphinx config template should use place holders for database credentials</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13186">PHPBB3-13186</a>] - Do not link post count to author search if search disabled</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13187">PHPBB3-13187</a>] - INSTALL.html is not valid HTML</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13188">PHPBB3-13188</a>] - Sphinx index() function triggers slow queries that time out replies</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13190">PHPBB3-13190</a>] - phpbb_session_login_keys_test::test_reset_keys fails on develop-ascraeus</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13194">PHPBB3-13194</a>] - BBCode isn't parsed when issuing a warning for a post</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13203">PHPBB3-13203</a>] - Use constant time comparison method for comparing password hashes</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13217">PHPBB3-13217</a>] - Remember me cookie leak</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13218">PHPBB3-13218</a>] - Missing token check in acp_styles</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13221">PHPBB3-13221</a>] - Can't upgrade to 3.1 from 3.0.11 and older</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13223">PHPBB3-13223</a>] - Using get_username_string() for email template variables causes HTML markup in emails</li>
+ </ul>
+ <h4>Improvement</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12796">PHPBB3-12796</a>] - View own Profile should have an edit button</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12799">PHPBB3-12799</a>] - Place the events for f_brunoais_read_other</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13041">PHPBB3-13041</a>] - help_faq.php language file needs to be revised</li>
+ </ul>
+ <h4>New Feature</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13205">PHPBB3-13205</a>] - Add mark all PMs read button</li>
+ </ul>
+
+
+ <a name="v310RC4"></a><h3>1.v. Changes since 3.1.0-RC4</h3>
<h4>Bug</h4>
<ul>
@@ -165,7 +337,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13123">PHPBB3-13123</a>] - Add events to allow post blocking and post pre/past processing</li>
</ul>
- <a name="v310RC3"></a><h3>1.ii. Changes since 3.1.0-RC3</h3>
+ <a name="v310RC3"></a><h3>1.vi. Changes since 3.1.0-RC3</h3>
<h4>Bug</h4>
<ul>
@@ -255,7 +427,7 @@
</ul>
- <a name="v310RC2"></a><h3>1.iii. Changes since 3.1.0-RC2</h3>
+ <a name="v310RC2"></a><h3>1.vii. Changes since 3.1.0-RC2</h3>
<h4>Bug</h4>
<ul>
@@ -379,7 +551,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12948">PHPBB3-12948</a>] - Remove Travis CI &quot;broken opcache on PHP 5.5.7 and 5.5.8&quot; workaround.</li>
</ul>
- <a name="v310RC1"></a><h3>1.iv. Changes since 3.1.0-RC1</h3>
+ <a name="v310RC1"></a><h3>1.viii. Changes since 3.1.0-RC1</h3>
<h4>Bug</h4>
<ul>
@@ -450,7 +622,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12829">PHPBB3-12829</a>] - Remove check for pgsql 8.3/8.2</li>
</ul>
- <a name="v310b4"></a><h3>1.v. Changes since 3.1.0-b4</h3>
+ <a name="v310b4"></a><h3>1.ix. Changes since 3.1.0-b4</h3>
<h4>Bug</h4>
<ul>
@@ -570,7 +742,7 @@
</ul>
- <a name="v310b3"></a><h3>1.vi. Changes since 3.1.0-b3</h3>
+ <a name="v310b3"></a><h3>1.x. Changes since 3.1.0-b3</h3>
<h4>Bug</h4>
<ul>
@@ -677,7 +849,7 @@
</ul>
- <a name="v310b2"></a><h3>1.vii. Changes since 3.1.0-b2</h3>
+ <a name="v310b2"></a><h3>1.xi. Changes since 3.1.0-b2</h3>
<h4>Bug</h4>
<ul>
@@ -842,7 +1014,7 @@
</ul>
- <a name="v310b1"></a><h3>1.viii. Changes since 3.1.0-b1</h3>
+ <a name="v310b1"></a><h3>1.xii. Changes since 3.1.0-b1</h3>
<h4>Bug</h4>
<ul>
@@ -910,7 +1082,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12302">PHPBB3-12302</a>] - Upgrade composer.phar to 1.0.0-alpha8</li>
</ul>
- <a name="v310a3"></a><h3>1.ix. Changes since 3.1.0-a3</h3>
+ <a name="v310a3"></a><h3>1.xiii. Changes since 3.1.0-a3</h3>
<h4>Bug</h4>
<ul>
@@ -1057,7 +1229,7 @@
</ul>
- <a name="v310a2"></a><h3>1.x. Changes since 3.1.0-a2</h3>
+ <a name="v310a2"></a><h3>1.xiv. Changes since 3.1.0-a2</h3>
<h4>Bug</h4>
<ul>
@@ -1165,7 +1337,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12147">PHPBB3-12147</a>] - Remove Travis CI notification configuration</li>
</ul>
- <a name="v310a1"></a><h3>1.xi. Changes since 3.1.0-a1</h3>
+ <a name="v310a1"></a><h3>1.xv. Changes since 3.1.0-a1</h3>
<h4>Bug</h4>
<ul>
@@ -1241,7 +1413,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11998">PHPBB3-11998</a>] - Add console / command line client environment </li>
</ul>
- <a name="v30x"></a><h3>1.xii. Changes since 3.0.x</h3>
+ <a name="v30x"></a><h3>1.xvi. Changes since 3.0.x</h3>
<h4>Bug</h4>
<ul>
@@ -1922,7 +2094,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11913">PHPBB3-11913</a>] - Apply reorganisation of download.phpbb.com to build_announcement.php</li>
</ul>
- <a name="v3011"></a><h3>1.xiii. Changes since 3.0.11</h3>
+ <a name="v3011"></a><h3>1.xvii. Changes since 3.0.11</h3>
<h4>Bug</h4>
<ul>
@@ -2077,7 +2249,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11753">PHPBB3-11753</a>] - Upgrade mysql_upgrader.php schema data.</li>
</ul>
- <a name="v3010"></a><h3>1.xiv. Changes since 3.0.10</h3>
+ <a name="v3010"></a><h3>1.xviii. Changes since 3.0.10</h3>
<h4>Bug</h4>
<ul>
@@ -2202,7 +2374,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10909">PHPBB3-10909</a>] - Update Travis Test Configuration: Travis no longer supports PHP 5.3.2</li>
</ul>
- <a name="v309"></a><h3>1.xv. Changes since 3.0.9</h3>
+ <a name="v309"></a><h3>1.xix. Changes since 3.0.9</h3>
<h4>Bug</h4>
<ul>
@@ -2338,7 +2510,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10480">PHPBB3-10480</a>] - Automate changelog building</li>
</ul>
- <a name="v308"></a><h3>1.xvi. Changes since 3.0.8</h3>
+ <a name="v308"></a><h3>1.xx. Changes since 3.0.8</h3>
<h4> Bug
</h4>
@@ -2706,7 +2878,7 @@
</ul>
- <a name="v307-PL1"></a><h3>1.xvii. Changes since 3.0.7-PL1</h3>
+ <a name="v307-PL1"></a><h3>1.xxi. Changes since 3.0.7-PL1</h3>
<h4> Security
</h4>
<ul>
@@ -3164,13 +3336,13 @@
</ul>
- <a name="v307"></a><h3>1.xviii. Changes since 3.0.7</h3>
+ <a name="v307"></a><h3>1.xxii. Changes since 3.0.7</h3>
<ul>
<li>[Sec] Do not expose forum content of forums with ACL entries but no actual permission in ATOM Feeds. (Bug #58595)</li>
</ul>
- <a name="v306"></a><h3>1.xix. Changes since 3.0.6</h3>
+ <a name="v306"></a><h3>1.xxiii. Changes since 3.0.6</h3>
<ul>
<li>[Fix] Allow ban reason and length to be selected and copied in ACP and subsilver2 MCP. (Bug #51095)</li>
@@ -3274,7 +3446,7 @@
</ul>
- <a name="v305"></a><h3>1.xx. Changes since 3.0.5</h3>
+ <a name="v305"></a><h3>1.xxiv. Changes since 3.0.5</h3>
<ul>
<li>[Fix] Allow whitespaces in avatar gallery names. (Bug #44955)</li>
@@ -3496,7 +3668,7 @@
<li>[Feature] Send anonymous statistical information to phpBB on installation and update (optional).</li>
</ul>
- <a name="v304"></a><h3>1.xxi. Changes since 3.0.4</h3>
+ <a name="v304"></a><h3>1.xxv. Changes since 3.0.4</h3>
<ul>
<li>[Fix] Delete user entry from ban list table upon user deletion (Bug #40015 - Patch by TerraFrost)</li>
@@ -3585,7 +3757,7 @@
<li>[Sec] Only use forum id supplied for posting if global announcement detected. (Reported by nickvergessen)</li>
</ul>
- <a name="v303"></a><h3>1.xxii. Changes since 3.0.3</h3>
+ <a name="v303"></a><h3>1.xxvi. Changes since 3.0.3</h3>
<ul>
<li>[Fix] Allow mixed-case template directories to be inherited (Bug #36725)</li>
@@ -3617,7 +3789,7 @@
<li>[Sec] Ask for forum password if post within passworded forum quoted in private message. (Reported by nickvergessen)</li>
</ul>
- <a name="v302"></a><h3>1.xxiii. Changes since 3.0.2</h3>
+ <a name="v302"></a><h3>1.xxvii. Changes since 3.0.2</h3>
<ul>
<li>[Fix] Correctly set topic starter if first post in topic removed (Bug #30575 - Patch by blueray2048)</li>
@@ -3716,7 +3888,7 @@
<li>[Sec Precaution] Stricter validation of the HTTP_HOST header (Thanks to Techie-Micheal et al for pointing out possible issues in derived code)</li>
</ul>
- <a name="v301"></a><h3>1.xxiv. Changes since 3.0.1</h3>
+ <a name="v301"></a><h3>1.xxviii. Changes since 3.0.1</h3>
<ul>
<li>[Fix] Ability to set permissions on non-mysql dbms (Bug #24955)</li>
@@ -3764,7 +3936,7 @@
<li>[Sec] Only allow urls gone through redirect() being used within login_box(). (thanks nookieman)</li>
</ul>
- <a name="v300"></a><h3>1.xxv. Changes since 3.0.0</h3>
+ <a name="v300"></a><h3>1.xxix. Changes since 3.0.0</h3>
<ul>
<li>[Change] Validate birthdays (Bug #15004)</li>
@@ -3835,7 +4007,7 @@
<li>[Fix] Find and display colliding usernames correctly when converting from one database to another (Bug #23925)</li>
</ul>
- <a name="v30rc8"></a><h3>1.xxvi. Changes since 3.0.RC8</h3>
+ <a name="v30rc8"></a><h3>1.xxx. Changes since 3.0.RC8</h3>
<ul>
<li>[Fix] Cleaned usernames contain only single spaces, so &quot;a_name&quot; and &quot;a__name&quot; are treated as the same name (Bug #15634)</li>
@@ -3844,7 +4016,7 @@
<li>[Fix] Call garbage_collection() within database updater to correctly close connections (affects Oracle for example)</li>
</ul>
- <a name="v30rc7"></a><h3>1.xxvii. Changes since 3.0.RC7</h3>
+ <a name="v30rc7"></a><h3>1.xxxi. Changes since 3.0.RC7</h3>
<ul>
<li>[Fix] Fixed MSSQL related bug in the update system</li>
@@ -3879,7 +4051,7 @@
<li>[Fix] No duplication of active topics (Bug #15474)</li>
</ul>
- <a name="v30rc6"></a><h3>1.xxviii. Changes since 3.0.RC6</h3>
+ <a name="v30rc6"></a><h3>1.xxxii. Changes since 3.0.RC6</h3>
<ul>
<li>[Fix] Submitting language changes using acp_language (Bug #14736)</li>
@@ -3889,7 +4061,7 @@
<li>[Fix] Able to request new password (Bug #14743)</li>
</ul>
- <a name="v30rc5"></a><h3>1.xxix. Changes since 3.0.RC5</h3>
+ <a name="v30rc5"></a><h3>1.xxxiii. Changes since 3.0.RC5</h3>
<ul>
<li>[Feature] Removing constant PHPBB_EMBEDDED in favor of using an exit_handler(); the constant was meant to achive this more or less.</li>
@@ -3952,7 +4124,7 @@
<li>[Sec] New password hashing mechanism for storing passwords (#i42)</li>
</ul>
- <a name="v30rc4"></a><h3>1.xxx. Changes since 3.0.RC4</h3>
+ <a name="v30rc4"></a><h3>1.xxxiv. Changes since 3.0.RC4</h3>
<ul>
<li>[Fix] MySQL, PostgreSQL and SQLite related database fixes (Bug #13862)</li>
@@ -4003,7 +4175,7 @@
<li>[Fix] odbc_autocommit causing existing result sets to be dropped (Bug #14182)</li>
</ul>
- <a name="v30rc3"></a><h3>1.xxxi. Changes since 3.0.RC3</h3>
+ <a name="v30rc3"></a><h3>1.xxxv. Changes since 3.0.RC3</h3>
<ul>
<li>[Fix] Fixing some subsilver2 and prosilver style issues</li>
@@ -4112,7 +4284,7 @@
</ul>
- <a name="v30rc2"></a><h3>1.xxxii. Changes since 3.0.RC2</h3>
+ <a name="v30rc2"></a><h3>1.xxxvi. Changes since 3.0.RC2</h3>
<ul>
<li>[Fix] Re-allow searching within the memberlist</li>
@@ -4158,7 +4330,7 @@
</ul>
- <a name="v30rc1"></a><h3>1.xxxiii. Changes since 3.0.RC1</h3>
+ <a name="v30rc1"></a><h3>1.xxxvii. Changes since 3.0.RC1</h3>
<ul>
<li>[Fix] (X)HTML issues within the templates (Bug #11255, #11255)</li>
diff --git a/phpBB/docs/CREDITS.txt b/phpBB/docs/CREDITS.txt
index c0b1d4dbe2..5c17787495 100644
--- a/phpBB/docs/CREDITS.txt
+++ b/phpBB/docs/CREDITS.txt
@@ -24,7 +24,6 @@ phpBB Lead Developer: naderman (Nils Adermann)
phpBB Developers: bantu (Andreas Fischer)
dhruv.goel92 (Dhruv Goel)
- EXreaction (Nathan Guse)
marc1706 (Marc Alexander)
nickvergessen (Joas Schilling)
nicofuma (Tristan Darricau)
@@ -53,6 +52,7 @@ phpBB Developers: A_Jelly_Doughnut (Josh Woody) [01/2010 - 11/2010]
ckwalsh (Cullen Walsh) [01/2010 - 07/2011]
DavidMJ (David M.) [12/2005 - 08/2009]
dhn (Dominik Dröscher) [05/2007 - 01/2011]
+ EXreaction (Nathan Guse) [07/2012 - 05/2014]
GrahamJE (Graham Eames) [09/2005 - 11/2006]
igorw (Igor Wiedler) [08/2010 - 02/2013]
imkingdavid (David King) [11/2012 - 06/2014]
diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html
index 4bde6c01ea..80e09f1bf9 100644
--- a/phpBB/docs/INSTALL.html
+++ b/phpBB/docs/INSTALL.html
@@ -303,7 +303,7 @@
<ul>
<li>Go to the <a href="https://www.phpbb.com/downloads/">downloads page</a> and download the latest update package listed there, matching your current version.</li>
- <li>Upload the uncompressed archive contents to your phpBB installation - only the install folder is required. Upload the whole install folder, retaining the file structure.</li>
+ <li>Upload the uncompressed archive contents to your phpBB installation - only the <code>install/</code> and <code>vendor/</code> folders are required. Upload these folders in their entirety, retaining the file structure.</li>
<li>After the install folder is present, phpBB will go offline automatically.</li>
<li>Point your browser to the install directory, for example <code>http://www.example.com/phpBB3/install/</code></li>
<li>Choose the "Update" Tab and follow the instructions</li>
@@ -347,7 +347,7 @@
<li>The <code>store/</code> directory</li>
</ul></li>
- <li>Upload the contents of the 3.1.x Full Package into your forum's directory.</li>
+ <li>Upload the contents of the 3.1.x Full Package into your forum's directory. Make sure the root level .htaccess file is included in the upload.</li>
<li>Browse to install/database_update.php</li>
<li>Delete the <code>install/</code> directory</li>
</ol>
@@ -462,7 +462,7 @@
<hr />
<a name="anti_spam"></a><h2>8. Anti-Spam Measures</h2>
-
+
<div class="paragraph">
<div class="inner"><span class="corners-top"><span></span></span>
diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md
index c51bc72160..7863814daa 100644
--- a/phpBB/docs/events.md
+++ b/phpBB/docs/events.md
@@ -16,11 +16,59 @@ acp_bbcodes_edit_fieldsets_after
* Since: 3.1.0-a3
* Purpose: Add settings to BBCode add/edit form
+acp_email_options_after
+===
+* Location: adm/style/acp_email.html
+* Since: 3.1.2-RC1
+* Purpose: Add settings to mass email form
+
+acp_forums_main_settings_append
+===
+* Location: adm/style/acp_forums.html
+* Since: 3.1.2-RC1
+* Purpose: Add settings to forums at end of main settings section
+
+acp_forums_main_settings_prepend
+===
+* Location: adm/style/acp_forums.html
+* Since: 3.1.2-RC1
+* Purpose: Add settings to forums before main settings section
+
acp_forums_normal_settings_append
===
* Location: adm/style/acp_forums.html
* Since: 3.1.0-a1
-* Purpose: Add settings to forums
+* Purpose: Add settings to forums at end of normal settings section
+
+acp_forums_normal_settings_prepend
+===
+* Location: adm/style/acp_forums.html
+* Since: 3.1.2-RC1
+* Purpose: Add settings to forums before normal settings section
+
+acp_forums_prune_settings_append
+===
+* Location: adm/style/acp_forums.html
+* Since: 3.1.2-RC1
+* Purpose: Add settings to forums at end of prune settings section
+
+acp_forums_prune_settings_prepend
+===
+* Location: adm/style/acp_forums.html
+* Since: 3.1.2-RC1
+* Purpose: Add settings to forums before prune settings section
+
+acp_forums_rules_settings_append
+===
+* Location: adm/style/acp_forums.html
+* Since: 3.1.2-RC1
+* Purpose: Add settings to forums at end of rules settings section
+
+acp_forums_rules_settings_prepend
+===
+* Location: adm/style/acp_forums.html
+* Since: 3.1.2-RC1
+* Purpose: Add settings to forums before rules settings section
acp_group_options_before
===
@@ -111,7 +159,7 @@ acp_ranks_list_column_before
* Locations:
+ adm/style/acp_ranks.html
* Since: 3.1.0-RC3
-* Purpose: Add content after the last column (but before the action column)
+* Purpose: Add content after the last column (but before the action column)
in the ranks list in the ACP
acp_ranks_list_header_after
@@ -126,7 +174,7 @@ acp_ranks_list_header_before
* Locations:
+ adm/style/acp_ranks.html
* Since: 3.1.0-RC3
-* Purpose: Add content after the last header-column (but before the action column)
+* Purpose: Add content after the last header-column (but before the action column)
in the ranks list in the ACP
acp_simple_footer_after
@@ -336,6 +384,14 @@ index_body_block_stats_prepend
* Since: 3.1.0-b3
* Purpose: Prepend content to the statistics list on the Board index
+index_body_forumlist_body_after
+===
+* Locations:
+ + styles/prosilver/template/index_body.html
+ + styles/subsilver2/template/index_body.html
+* Since: 3.1.1
+* Purpose: Add content after the forum list body on the index page
+
index_body_markforums_after
===
* Locations:
@@ -418,6 +474,30 @@ memberlist_body_username_prepend
* Purpose: Add information before every username in the memberlist. Works in
all display modes (leader, group and normal memberlist).
+memberlist_search_fields_after
+===
+* Locations:
+ + styles/prosilver/template/memberlist_search.html
+ + styles/subsilver2/template/memberlist_search.html
+* Since: 3.1.2-RC1
+* Purpose: Add information after the search fields column.
+
+memberlist_search_fields_before
+===
+* Locations:
+ + styles/prosilver/template/memberlist_search.html
+ + styles/subsilver2/template/memberlist_search.html
+* Since: 3.1.2-RC1
+* Purpose: Add information before the search fields column.
+
+memberlist_search_sorting_options_before
+===
+* Locations:
+ + styles/prosilver/template/memberlist_search.html
+ + styles/subsilver2/template/memberlist_search.html
+* Since: 3.1.2-RC1
+* Purpose: Add information before the search sorting options field.
+
memberlist_view_contact_after
===
* Locations:
@@ -756,6 +836,14 @@ posting_editor_buttons_before
* Since: 3.1.0-a3
* Purpose: Add content before the BBCode posting buttons
+posting_editor_buttons_custom_tags_before
+===
+* Locations:
+ + styles/prosilver/template/posting_buttons.html
+ + styles/subsilver2/template/posting_buttons.html
+* Since: 3.1.2-RC1
+* Purpose: Add content inside the BBCode posting buttons and before the customs BBCode
+
posting_editor_message_after
===
* Locations:
@@ -1011,7 +1099,7 @@ ucp_pm_viewmessage_post_buttons_after
+ styles/prosilver/template/ucp_pm_viewmessage.html
+ styles/subsilver2/template/ucp_pm_viewmessage.html
* Since: 3.1.0-RC3
-* Purpose: Add post button to private messages (next to edit, quote etc), at
+* Purpose: Add post button to private messages (next to edit, quote etc), at
the end of the list.
ucp_pm_viewmessage_post_buttons_before
@@ -1020,7 +1108,7 @@ ucp_pm_viewmessage_post_buttons_before
+ styles/prosilver/template/ucp_pm_viewmessage.html
+ styles/subsilver2/template/ucp_pm_viewmessage.html
* Since: 3.1.0-RC3
-* Purpose: Add post button to private messages (next to edit, quote etc), at
+* Purpose: Add post button to private messages (next to edit, quote etc), at
the start of the list.
ucp_pm_viewmessage_print_head_append
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index f4f7512f0c..63e2647f02 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -615,7 +615,15 @@ class acp_board
{
add_log('admin', 'LOG_CONFIG_' . strtoupper($mode));
- trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
+ $message = $user->lang('CONFIG_UPDATED');
+ $message_type = E_USER_NOTICE;
+ if (!$config['email_enable'] && in_array($mode, array('email', 'registration')) &&
+ in_array($config['require_activation'], array(USER_ACTIVATION_SELF, USER_ACTIVATION_ADMIN)))
+ {
+ $message .= '<br /><br />' . $user->lang('ACC_ACTIVATION_WARNING');
+ $message_type = E_USER_WARNING;
+ }
+ trigger_error($message . adm_back_link($this->u_action), $message_type);
}
$this->tpl_name = 'acp_board';
@@ -792,20 +800,19 @@ class acp_board
global $user, $config;
$act_ary = array(
- 'ACC_DISABLE' => USER_ACTIVATION_DISABLE,
- 'ACC_NONE' => USER_ACTIVATION_NONE,
+ 'ACC_DISABLE' => array(true, USER_ACTIVATION_DISABLE),
+ 'ACC_NONE' => array(true, USER_ACTIVATION_NONE),
+ 'ACC_USER' => array($config['email_enable'], USER_ACTIVATION_SELF),
+ 'ACC_ADMIN' => array($config['email_enable'], USER_ACTIVATION_ADMIN),
);
- if ($config['email_enable'])
- {
- $act_ary['ACC_USER'] = USER_ACTIVATION_SELF;
- $act_ary['ACC_ADMIN'] = USER_ACTIVATION_ADMIN;
- }
- $act_options = '';
- foreach ($act_ary as $key => $value)
+ $act_options = '';
+ foreach ($act_ary as $key => $data)
{
+ list($available, $value) = $data;
$selected = ($selected_value == $value) ? ' selected="selected"' : '';
- $act_options .= '<option value="' . $value . '"' . $selected . '>' . $user->lang[$key] . '</option>';
+ $class = (!$available) ? ' class="disabled-option"' : '';
+ $act_options .= '<option value="' . $value . '"' . $selected . $class . '>' . $user->lang($key) . '</option>';
}
return $act_options;
diff --git a/phpBB/includes/acp/acp_email.php b/phpBB/includes/acp/acp_email.php
index fe55b36e67..4fefd6bec3 100644
--- a/phpBB/includes/acp/acp_email.php
+++ b/phpBB/includes/acp/acp_email.php
@@ -26,7 +26,7 @@ class acp_email
function main($id, $mode)
{
global $config, $db, $user, $auth, $template, $cache;
- global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix;
+ global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix, $phpbb_dispatcher;
$user->add_lang('acp/email');
$this->tpl_name = 'acp_email';
@@ -72,11 +72,15 @@ class acp_email
if ($usernames)
{
// If giving usernames the admin is able to email inactive users too...
- $sql = 'SELECT username, user_email, user_jabber, user_notify_type, user_lang
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('username_clean', array_map('utf8_clean_string', explode("\n", $usernames))) . '
- AND user_allow_massemail = 1
- ORDER BY user_lang, user_notify_type'; // , SUBSTRING(user_email FROM INSTR(user_email, '@'))
+ $sql_ary = array(
+ 'SELECT' => 'username, user_email, user_jabber, user_notify_type, user_lang',
+ 'FROM' => array(
+ USERS_TABLE => '',
+ ),
+ 'WHERE' => $db->sql_in_set('username_clean', array_map('utf8_clean_string', explode("\n", $usernames))) . '
+ AND user_allow_massemail = 1',
+ 'ORDER_BY' => 'user_lang, user_notify_type',
+ );
}
else
{
@@ -123,8 +127,18 @@ class acp_email
),
);
}
- $sql = $db->sql_build_query('SELECT', $sql_ary);
}
+ /**
+ * Modify sql query to change the list of users the email is sent to
+ *
+ * @event core.acp_email_modify_sql
+ * @var array sql_ary Array which is used to build the sql query
+ * @since 3.1.2-RC1
+ */
+ $vars = array('sql_ary');
+ extract($phpbb_dispatcher->trigger_event('core.acp_email_modify_sql', compact($vars)));
+
+ $sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php
index 9bdd8eb458..89fdc8b863 100644
--- a/phpBB/includes/acp/acp_extensions.php
+++ b/phpBB/includes/acp/acp_extensions.php
@@ -537,7 +537,7 @@ class acp_extensions
$version_check = $meta['extra']['version-check'];
- $version_helper = new \phpbb\version_helper($this->cache, $this->config, $this->user);
+ $version_helper = new \phpbb\version_helper($this->cache, $this->config, new \phpbb\file_downloader(), $this->user);
$version_helper->set_current_version($meta['version']);
$version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename']);
$version_helper->force_stability($this->config['extension_force_unstable'] ? 'unstable' : null);
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php
index 42c67a88b5..6bd27a8bca 100644
--- a/phpBB/includes/acp/acp_styles.php
+++ b/phpBB/includes/acp/acp_styles.php
@@ -29,14 +29,31 @@ class acp_styles
protected $styles_path;
protected $styles_path_absolute = 'styles';
protected $default_style = 0;
+ protected $styles_list_cols = 0;
+ protected $reserved_style_names = array('adm', 'admin', 'all');
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
+
+ /** @var \phpbb\user */
protected $user;
+
+ /** @var \phpbb\template\template */
protected $template;
+
+ /** @var \phpbb\request\request_interface */
protected $request;
+
+ /** @var \phpbb\cache\driver\driver_interface */
protected $cache;
+
+ /** @var \phpbb\auth\auth */
protected $auth;
+
+ /** @var string */
protected $phpbb_root_path;
+
+ /** @var string */
protected $php_ext;
public function main($id, $mode)
@@ -70,11 +87,6 @@ class acp_styles
$action = $this->request->variable('action', '');
$post_actions = array('install', 'activate', 'deactivate', 'uninstall');
- if ($action && in_array($action, $post_actions) && !check_link_hash($request->variable('hash', ''), $action))
- {
- trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
- }
-
foreach ($post_actions as $key)
{
if ($this->request->is_set_post($key))
@@ -83,6 +95,18 @@ class acp_styles
}
}
+ // The uninstall action uses confirm_box() to verify the validity of the request,
+ // so there is no need to check for a valid token here.
+ if (in_array($action, $post_actions) && $action != 'uninstall')
+ {
+ $is_valid_request = check_link_hash($request->variable('hash', ''), $action) || check_form_key('styles_management');
+
+ if (!$is_valid_request)
+ {
+ trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+ }
+
if ($action != '')
{
$this->s_hidden_fields['action'] = $action;
@@ -122,6 +146,8 @@ class acp_styles
*/
protected function frontend()
{
+ add_form_key('styles_management');
+
// Check mode
switch ($this->mode)
{
@@ -155,6 +181,12 @@ class acp_styles
$last_installed = false;
foreach ($dirs as $dir)
{
+ if (in_array($dir, $this->reserved_style_names))
+ {
+ $messages[] = $this->user->lang('STYLE_NAME_RESERVED', htmlspecialchars($dir));
+ continue;
+ }
+
$found = false;
foreach ($styles as &$style)
{
@@ -800,7 +832,7 @@ class acp_styles
* Update styles tree
*
* @param array $styles Styles list, passed as reference
- * @param array $style Current style, false if root
+ * @param array|false $style Current style, false if root
* @return bool True if something was updated, false if not
*/
protected function update_styles_tree(&$styles, $style = false)
@@ -1082,7 +1114,7 @@ class acp_styles
/**
* Install style
*
- * @param $style style data
+ * @param array $style style data
* @return int Style id
*/
protected function install_style($style)
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index 6693b822fe..0ac9208aa4 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))
*/
// phpBB Version
-define('PHPBB_VERSION', '3.1.0-RC6-dev');
+define('PHPBB_VERSION', '3.1.3-RC1-dev');
// QA-related
// define('PHPBB_QA', 1);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 7700dcfd27..1a3560dbb1 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -5254,7 +5254,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler =
// Call cron-type script
$call_cron = false;
- if (!defined('IN_CRON') && !$config['use_system_cron'] && $run_cron && !$config['board_disable'] && !$user->data['is_bot'] && !$cache->get('cron.lock_check'))
+ if (!defined('IN_CRON') && !$config['use_system_cron'] && $run_cron && !$config['board_disable'] && !$user->data['is_bot'] && !$cache->get('_cron.lock_check'))
{
$call_cron = true;
$time_now = (!empty($user->time_now) && is_int($user->time_now)) ? $user->time_now : time();
@@ -5286,7 +5286,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler =
}
else
{
- $cache->put('cron.lock_check', true, 300);
+ $cache->put('_cron.lock_check', true, 60);
}
}
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index e3e8657afb..0b9ea23fe7 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -2512,6 +2512,7 @@ function phpbb_cache_moderators($db, $cache, $auth)
{
$usernames_ary[$row['user_id']] = $row['username'];
}
+ $db->sql_freeresult($result);
foreach ($hold_ary as $user_id => $forum_id_ary)
{
@@ -2806,6 +2807,7 @@ function view_inactive_users(&$users, &$user_count, $limit = 0, $offset = 0, $li
$users[] = $row;
}
+ $db->sql_freeresult($result);
return $offset;
}
@@ -2980,68 +2982,21 @@ function get_database_size()
/**
* Retrieve contents from remotely stored file
+*
+* @deprecated 3.1.2 Use file_downloader instead
*/
function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port = 80, $timeout = 6)
{
- global $user;
+ global $phpbb_container;
- if ($fsock = @fsockopen($host, $port, $errno, $errstr, $timeout))
- {
- @fputs($fsock, "GET $directory/$filename HTTP/1.0\r\n");
- @fputs($fsock, "HOST: $host\r\n");
- @fputs($fsock, "Connection: close\r\n\r\n");
+ // Get file downloader and assign $errstr and $errno
+ $file_downloader = $phpbb_container->get('file_downloader');
- $timer_stop = time() + $timeout;
- stream_set_timeout($fsock, $timeout);
-
- $file_info = '';
- $get_info = false;
-
- while (!@feof($fsock))
- {
- if ($get_info)
- {
- $file_info .= @fread($fsock, 1024);
- }
- else
- {
- $line = @fgets($fsock, 1024);
- if ($line == "\r\n")
- {
- $get_info = true;
- }
- else if (stripos($line, '404 not found') !== false)
- {
- $errstr = $user->lang('FILE_NOT_FOUND', $filename);
- return false;
- }
- }
-
- $stream_meta_data = stream_get_meta_data($fsock);
-
- if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop)
- {
- $errstr = $user->lang['FSOCK_TIMEOUT'];
- return false;
- }
- }
- @fclose($fsock);
- }
- else
- {
- if ($errstr)
- {
- $errstr = utf8_convert_message($errstr);
- return false;
- }
- else
- {
- $errstr = $user->lang['FSOCK_DISABLED'];
- return false;
- }
- }
+ $file_data = $file_downloader->get($host, $directory, $filename, $port, $timeout);
+ $errstr = $file_downloader->get_error_string();
+ $errno = $file_downloader->get_error_number();
- return $file_info;
+ return $file_data;
}
/*
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
index fbb1f0e03d..43952ae57a 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -101,18 +101,21 @@ function phpbb_clean_path($path)
}
else if (!$phpbb_path_helper)
{
+ global $phpbb_root_path, $phpEx;
+
// The container is not yet loaded, use a new instance
if (!class_exists('\phpbb\path_helper'))
{
- global $phpbb_root_path, $phpEx;
require($phpbb_root_path . 'phpbb/path_helper.' . $phpEx);
}
+ $request = new phpbb\request\request();
$phpbb_path_helper = new phpbb\path_helper(
new phpbb\symfony_request(
- new phpbb\request\request()
+ $request
),
new phpbb\filesystem(),
+ $request,
$phpbb_root_path,
$phpEx
);
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index 25ca50e8f1..87cf34bd9d 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -712,7 +712,7 @@ function make_clickable_callback($type, $whitespace, $url, $relative_url, $class
break;
}
- $short_url = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url;
+ $short_url = (utf8_strlen($url) > 55) ? utf8_substr($url, 0, 39) . ' ... ' . utf8_substr($url, -10) : $url;
switch ($type)
{
@@ -788,28 +788,28 @@ function make_clickable($text, $server_url = false, $class = 'postlink')
// relative urls for this board
$magic_url_match_args[$server_url][] = array(
- '#(^|[\n\t (>.])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url_inline') . ')#i',
+ '#(^|[\n\t (>.])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url_inline') . ')#iu',
MAGIC_URL_LOCAL,
$local_class,
);
// matches a xxxx://aaaaa.bbb.cccc. ...
$magic_url_match_args[$server_url][] = array(
- '#(^|[\n\t (>.])(' . get_preg_expression('url_inline') . ')#i',
+ '#(^|[\n\t (>.])(' . get_preg_expression('url_inline') . ')#iu',
MAGIC_URL_FULL,
$class,
);
// matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
$magic_url_match_args[$server_url][] = array(
- '#(^|[\n\t (>])(' . get_preg_expression('www_url_inline') . ')#i',
+ '#(^|[\n\t (>])(' . get_preg_expression('www_url_inline') . ')#iu',
MAGIC_URL_WWW,
$class,
);
// matches an email@domain type address at the start of a line, or after a space or after what might be a BBCode.
$magic_url_match_args[$server_url][] = array(
- '/(^|[\n\t (>])(' . get_preg_expression('email') . ')/i',
+ '/(^|[\n\t (>])(' . get_preg_expression('email') . ')/iu',
MAGIC_URL_EMAIL,
'',
);
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index 745eb20c77..31cf43e599 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -1491,7 +1491,7 @@ function phpbb_get_user_rank($user_data, $user_posts)
/**
* Prepare profile data
*/
-function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabled = false)
+function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabled = false, $check_can_receive_pm = true)
{
global $config, $auth, $user, $phpEx, $phpbb_root_path, $phpbb_dispatcher;
@@ -1559,7 +1559,7 @@ function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabl
}
// Can this user receive a Private Message?
- $can_receive_pm = (
+ $can_receive_pm = $check_can_receive_pm && (
// They must be a "normal" user
$data['user_type'] != USER_IGNORE &&
@@ -1608,8 +1608,8 @@ function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabl
'U_EMAIL' => $email,
'U_JABBER' => ($data['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&amp;action=jabber&amp;u=' . $user_id) : '',
- 'USER_JABBER' => $data['user_jabber'],
- 'USER_JABBER_IMG' => ($data['user_jabber']) ? $user->img('icon_contact_jabber', $data['user_jabber']) : '',
+ 'USER_JABBER' => ($config['jab_enable']) ? $data['user_jabber'] : '',
+ 'USER_JABBER_IMG' => ($config['jab_enable'] && $data['user_jabber']) ? $user->img('icon_contact_jabber', $data['user_jabber']) : '',
'L_SEND_EMAIL_USER' => $user->lang('SEND_EMAIL_USER', $username),
'L_CONTACT_USER' => $user->lang('CONTACT_USER', $username),
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index ad142b1cca..838c6a0fec 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -914,6 +914,24 @@ function update_unread_status($unread, $msg_id, $user_id, $folder_id)
}
}
+function mark_folder_read($user_id, $folder_id)
+{
+ global $db;
+
+ $sql = 'SELECT msg_id
+ FROM ' . PRIVMSGS_TO_TABLE . '
+ WHERE folder_id = ' . ((int) $folder_id) . '
+ AND user_id = ' . ((int) $user_id) . '
+ AND pm_unread = 1';
+ $result = $db->sql_query($sql);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ update_unread_status(true, $row['msg_id'], $user_id, $folder_id);
+ }
+ $db->sql_freeresult($result);
+}
+
/**
* Handle all actions possible with marked messages
*/
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index e4479f07b0..f79a8998c4 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -161,9 +161,10 @@ function user_update_name($old_name, $new_name)
*
* @param mixed $user_row An array containing the following keys (and the appropriate values): username, group_id (the group to place the user in), user_email and the user_type(usually 0). Additional entries not overridden by defaults will be forwarded.
* @param string $cp_data custom profile fields, see custom_profile::build_insert_sql_array
+* @param array $notifications_data The notifications settings for the new user
* @return the new user's ID.
*/
-function user_add($user_row, $cp_data = false)
+function user_add($user_row, $cp_data = false, $notifications_data = null)
{
global $db, $user, $auth, $config, $phpbb_root_path, $phpEx;
global $phpbb_dispatcher, $phpbb_container;
@@ -347,6 +348,31 @@ function user_add($user_row, $cp_data = false)
set_config('newest_user_colour', $row['group_colour'], true);
}
+ // Use default notifications settings if notifications_data is not set
+ if ($notifications_data === null)
+ {
+ $notifications_data = array(
+ array(
+ 'item_type' => 'notification.type.post',
+ 'method' => 'notification.method.email',
+ ),
+ array(
+ 'item_type' => 'notification.type.topic',
+ 'method' => 'notification.method.email',
+ ),
+ );
+ }
+
+ // Subscribe user to notifications if necessary
+ if (!empty($notifications_data))
+ {
+ $phpbb_notifications = $phpbb_container->get('notification_manager');
+ foreach ($notifications_data as $subscription)
+ {
+ $phpbb_notifications->add_subscription($subscription['item_type'], 0, $subscription['method'], $user_id);
+ }
+ }
+
/**
* Event that returns user id, user detals and user CPF of newly registared user
*
diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php
index 0c6acaa908..c18ca1aa1d 100644
--- a/phpBB/includes/mcp/mcp_forum.php
+++ b/phpBB/includes/mcp/mcp_forum.php
@@ -165,6 +165,22 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.') . "
$limit_time_sql
ORDER BY t.topic_type DESC, $sort_order_sql";
+
+ /**
+ * Modify SQL query before MCP forum view topic list is queried
+ *
+ * @event core.mcp_view_forum_modify_sql
+ * @var string sql SQL query for forum view topic list
+ * @var int forum_id ID of the forum
+ * @var string limit_time_sql SQL query part for limit time
+ * @var string sort_order_sql SQL query part for sort order
+ * @var int topics_per_page Number of topics per page
+ * @var int start Start value
+ * @since 3.1.2-RC1
+ */
+ $vars = array('sql', 'forum_id', 'limit_time_sql', 'sort_order_sql', 'topics_per_page', 'start');
+ extract($phpbb_dispatcher->trigger_event('core.mcp_view_forum_modify_sql', compact($vars)));
+
$result = $db->sql_query_limit($sql, $topics_per_page, $start);
$topic_list = $topic_tracking_info = array();
diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php
index 92dcdb5499..9c76f0df90 100644
--- a/phpBB/includes/mcp/mcp_logs.php
+++ b/phpBB/includes/mcp/mcp_logs.php
@@ -137,7 +137,7 @@ class mcp_logs
if ($mode == 'topic_logs')
{
- $conditions['topic_logs'] = $topic_id;
+ $conditions['topic_id'] = $topic_id;
}
$phpbb_log->delete('mod', $conditions);
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index 19a0ee3051..227ae84bd6 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -813,8 +813,17 @@ function mcp_delete_topic($topic_ids, $is_soft = false, $soft_delete_reason = ''
$user->add_lang('posting');
+ // If there are only shadow topics, we neither need a reason nor softdelete
+ $sql = 'SELECT topic_id
+ FROM ' . TOPICS_TABLE . '
+ WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . '
+ AND topic_moved_id = 0';
+ $result = $db->sql_query_limit($sql, 1);
+ $only_shadow = !$db->sql_fetchfield('topic_id');
+ $db->sql_freeresult($result);
+
$only_softdeleted = false;
- if ($auth->acl_get('m_delete', $forum_id) && $auth->acl_get('m_softdelete', $forum_id))
+ if (!$only_shadow && $auth->acl_get('m_delete', $forum_id) && $auth->acl_get('m_softdelete', $forum_id))
{
// If there are only soft deleted topics, we display a message why the option is not available
$sql = 'SELECT topic_id
@@ -827,6 +836,7 @@ function mcp_delete_topic($topic_ids, $is_soft = false, $soft_delete_reason = ''
}
$template->assign_vars(array(
+ 'S_SHADOW_TOPICS' => $only_shadow,
'S_SOFTDELETED' => $only_softdeleted,
'S_TOPIC_MODE' => true,
'S_ALLOWED_DELETE' => $auth->acl_get('m_delete', $forum_id),
@@ -839,7 +849,7 @@ function mcp_delete_topic($topic_ids, $is_soft = false, $soft_delete_reason = ''
$l_confirm .= '_PERMANENTLY';
$s_hidden_fields['delete_permanent'] = '1';
}
- else if (!$auth->acl_get('m_softdelete', $forum_id))
+ else if ($only_shadow || !$auth->acl_get('m_softdelete', $forum_id))
{
$s_hidden_fields['delete_permanent'] = '1';
}
diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php
index 425c3ac235..d724b8703b 100644
--- a/phpBB/includes/mcp/mcp_warn.php
+++ b/phpBB/includes/mcp/mcp_warn.php
@@ -332,7 +332,7 @@ class mcp_warn
// We want to make the message available here as a reminder
// Parse the message and subject
- $parse_flags = OPTION_FLAG_SMILIES | ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0);
+ $parse_flags = OPTION_FLAG_SMILIES | ($user_row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0);
$message = generate_text_for_display($user_row['post_text'], $user_row['bbcode_uid'], $user_row['bbcode_bitfield'], $parse_flags, true);
// Generate the appropriate user information for the user we are looking at
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php
index 92ace7b585..12ef94c07a 100644
--- a/phpBB/includes/message_parser.php
+++ b/phpBB/includes/message_parser.php
@@ -313,7 +313,7 @@ class bbcode_firstpass extends bbcode
$in = str_replace(' ', '%20', $in);
// Checking urls
- if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) && !preg_match('#^' . get_preg_expression('www_url') . '$#i', $in))
+ if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) && !preg_match('#^' . get_preg_expression('www_url') . '$#iu', $in))
{
return '[img]' . $in . '[/img]';
}
@@ -381,8 +381,8 @@ class bbcode_firstpass extends bbcode
$in = str_replace(' ', '%20', $in);
// Make sure $in is a URL.
- if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) &&
- !preg_match('#^' . get_preg_expression('www_url') . '$#i', $in))
+ if (!preg_match('#^' . get_preg_expression('url') . '$#iu', $in) &&
+ !preg_match('#^' . get_preg_expression('www_url') . '$#iu', $in))
{
return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
}
@@ -973,9 +973,9 @@ class bbcode_firstpass extends bbcode
$url = str_replace(' ', '%20', $url);
// Checking urls
- if (preg_match('#^' . get_preg_expression('url') . '$#i', $url) ||
- preg_match('#^' . get_preg_expression('www_url') . '$#i', $url) ||
- preg_match('#^' . preg_quote(generate_board_url(), '#') . get_preg_expression('relative_url') . '$#i', $url))
+ if (preg_match('#^' . get_preg_expression('url') . '$#iu', $url) ||
+ preg_match('#^' . get_preg_expression('www_url') . '$#iu', $url) ||
+ preg_match('#^' . preg_quote(generate_board_url(), '#') . get_preg_expression('relative_url') . '$#iu', $url))
{
$valid = true;
}
@@ -1103,7 +1103,7 @@ class parse_message extends bbcode_firstpass
*/
function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post')
{
- global $config, $db, $user;
+ global $config, $db, $user, $phpbb_dispatcher;
$this->mode = $mode;
@@ -1158,6 +1158,49 @@ class parse_message extends bbcode_firstpass
}
}
+ /**
+ * This event can be used for additional message checks/cleanup before parsing
+ *
+ * @event core.message_parser_check_message
+ * @var bool allow_bbcode Do we allow BBCodes
+ * @var bool allow_magic_url Do we allow magic urls
+ * @var bool allow_smilies Do we allow smilies
+ * @var bool allow_img_bbcode Do we allow image BBCode
+ * @var bool allow_flash_bbcode Do we allow flash BBCode
+ * @var bool allow_quote_bbcode Do we allow quote BBCode
+ * @var bool allow_url_bbcode Do we allow url BBCode
+ * @var bool update_this_message Do we alter the parsed message
+ * @var string mode Posting mode
+ * @var string message The message text to parse
+ * @var bool return Do we return after the event is triggered if $warn_msg is not empty
+ * @var array warn_msg Array of the warning messages
+ * @since 3.1.2-RC1
+ */
+ $message = $this->message;
+ $warn_msg = $this->warn_msg;
+ $return = false;
+ $vars = array(
+ 'allow_bbcode',
+ 'allow_magic_url',
+ 'allow_smilies',
+ 'allow_img_bbcode',
+ 'allow_flash_bbcode',
+ 'allow_quote_bbcode',
+ 'allow_url_bbcode',
+ 'update_this_message',
+ 'mode',
+ 'message',
+ 'return',
+ 'warn_msg',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.message_parser_check_message', compact($vars)));
+ $this->message = $message;
+ $this->warn_msg = $warn_msg;
+ if ($return && !empty($this->warn_msg))
+ {
+ return (!$update_this_message) ? $return_message : $this->warn_msg;
+ }
+
// Prepare BBcode (just prepares some tags for better parsing)
if ($allow_bbcode && strpos($this->message, '[') !== false)
{
diff --git a/phpBB/includes/startup.php b/phpBB/includes/startup.php
index 50fcd11bee..2885c80541 100644
--- a/phpBB/includes/startup.php
+++ b/phpBB/includes/startup.php
@@ -69,31 +69,13 @@ function deregister_globals()
{
if (isset($not_unset[$varname]))
{
- // Hacking attempt. No point in continuing unless it's a COOKIE (so a cookie called GLOBALS doesn't lock users out completely)
- if ($varname !== 'GLOBALS' || isset($_GET['GLOBALS']) || isset($_POST['GLOBALS']) || isset($_SERVER['GLOBALS']) || isset($_SESSION['GLOBALS']) || isset($_ENV['GLOBALS']) || isset($_FILES['GLOBALS']))
+ // Hacking attempt. No point in continuing.
+ if (isset($_COOKIE[$varname]))
{
- exit;
- }
- else
- {
- $cookie = &$_COOKIE;
- while (isset($cookie['GLOBALS']))
- {
- if (!is_array($cookie['GLOBALS']))
- {
- break;
- }
-
- foreach ($cookie['GLOBALS'] as $registered_var => $value)
- {
- if (!isset($not_unset[$registered_var]))
- {
- unset($GLOBALS[$registered_var]);
- }
- }
- $cookie = &$cookie['GLOBALS'];
- }
+ echo "Clear your cookies. ";
}
+ echo "Malicious variable name detected. Contact the administrator and ask them to disable register_globals.";
+ exit;
}
unset($GLOBALS[$varname]);
diff --git a/phpBB/includes/ucp/ucp_auth_link.php b/phpBB/includes/ucp/ucp_auth_link.php
index a595ce46c3..748f0fdec2 100644
--- a/phpBB/includes/ucp/ucp_auth_link.php
+++ b/phpBB/includes/ucp/ucp_auth_link.php
@@ -34,11 +34,12 @@ class ucp_auth_link
*/
public function main($id, $mode)
{
- global $config, $request, $template, $phpbb_container, $user;
+ global $request, $template, $phpbb_container, $user;
$error = array();
- $auth_provider = $phpbb_container->get('auth.provider.' . $config['auth_method']);
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+ $auth_provider = $provider_collection->get_provider();
// confirm that the auth provider supports this page
$provider_data = $auth_provider->get_auth_link_data();
diff --git a/phpBB/includes/ucp/ucp_login_link.php b/phpBB/includes/ucp/ucp_login_link.php
index 5ca5df00f7..bfe4804286 100644
--- a/phpBB/includes/ucp/ucp_login_link.php
+++ b/phpBB/includes/ucp/ucp_login_link.php
@@ -39,7 +39,7 @@ class ucp_login_link
*/
function main($id, $mode)
{
- global $config, $phpbb_container, $request, $template, $user;
+ global $phpbb_container, $request, $template, $user;
global $phpbb_root_path, $phpEx;
// Initialize necessary variables
@@ -57,8 +57,8 @@ class ucp_login_link
}
// Use the auth_provider requested even if different from configured
- $auth_provider = 'auth.provider.' . $request->variable('auth_provider', $config['auth_method']);
- $auth_provider = $phpbb_container->get($auth_provider);
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+ $auth_provider = $provider_collection->get_provider($request->variable('auth_provider', ''));
// Set the link_method to login_link
$data['link_method'] = 'login_link';
@@ -75,7 +75,7 @@ class ucp_login_link
{
if ($request->is_set_post('login'))
{
- $login_username = $request->variable('login_username', '', false, \phpbb\request\request_interface::POST);
+ $login_username = $request->variable('login_username', '', true, \phpbb\request\request_interface::POST);
$login_password = $request->untrimmed_variable('login_password', '', true, \phpbb\request\request_interface::POST);
$login_result = $auth_provider->login($login_username, $login_password);
diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php
index 7a8c694870..425a56cf6c 100644
--- a/phpBB/includes/ucp/ucp_pm.php
+++ b/phpBB/includes/ucp/ucp_pm.php
@@ -45,7 +45,7 @@ class ucp_pm
function main($id, $mode)
{
- global $user, $template, $phpbb_root_path, $auth, $phpEx, $db, $config;
+ global $user, $template, $phpbb_root_path, $auth, $phpEx, $db, $config, $request;
if (!$user->data['is_registered'])
{
@@ -246,6 +246,27 @@ class ucp_pm
$folder_id = (int) $row['folder_id'];
}
+ if ($request->variable('mark', '') == 'all' && check_link_hash($request->variable('token', ''), 'mark_all_pms_read'))
+ {
+ mark_folder_read($user->data['user_id'], $folder_id);
+
+ meta_refresh(3, $this->u_action);
+ $message = $user->lang['PM_MARK_ALL_READ_SUCCESS'];
+
+ if ($request->is_ajax())
+ {
+ $json_response = new \phpbb\json_response();
+ $json_response->send(array(
+ 'MESSAGE_TITLE' => $user->lang['INFORMATION'],
+ 'MESSAGE_TEXT' => $message,
+ 'success' => true,
+ ));
+ }
+ $message .= '<br /><br />' . $user->lang('RETURN_UCP', '<a href="' . $this->u_action . '">', '</a>');
+
+ trigger_error($message);
+ }
+
$message_row = array();
if ($action == 'view_message' && $msg_id)
{
@@ -332,6 +353,7 @@ class ucp_pm
'U_SENTBOX' => $this->u_action . '&amp;folder=sentbox',
'U_CREATE_FOLDER' => $this->u_action . '&amp;mode=options',
'U_CURRENT_FOLDER' => $this->u_action . '&amp;folder=' . $folder_id,
+ 'U_MARK_ALL' => $this->u_action . '&amp;folder=' . $folder_id . '&amp;mark=all&amp;token=' . generate_link_hash('mark_all_pms_read'),
'S_IN_INBOX' => ($folder_id == PRIVMSGS_INBOX) ? true : false,
'S_IN_OUTBOX' => ($folder_id == PRIVMSGS_OUTBOX) ? true : false,
diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php
index 2f34fd64a5..888c2e6825 100644
--- a/phpBB/includes/ucp/ucp_pm_viewmessage.php
+++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php
@@ -197,7 +197,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
$u_pm = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;u=' . $author_id);
}
- if ($user_info['user_jabber'] && $auth->acl_get('u_sendim'))
+ if ($config['jab_enable'] && $user_info['user_jabber'] && $auth->acl_get('u_sendim'))
{
$u_jabber = append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&amp;action=jabber&amp;u=' . $author_id);
}
@@ -213,6 +213,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
'AUTHOR_AVATAR' => (isset($user_info['avatar'])) ? $user_info['avatar'] : '',
'AUTHOR_JOINED' => $user->format_date($user_info['user_regdate']),
'AUTHOR_POSTS' => (int) $user_info['user_posts'],
+ 'U_AUTHOR_POSTS' => ($config['load_search'] && $auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id=$author_id&amp;sr=posts") : '',
'CONTACT_USER' => $user->lang('CONTACT_USER', get_username_string('username', $author_id, $user_info['username'], $user_info['user_colour'], $user_info['username'])),
'ONLINE_IMG' => (!$config['load_onlinetrack']) ? '' : ((isset($user_info['online']) && $user_info['online']) ? $user->img('icon_user_online', $user->lang['ONLINE']) : $user->img('icon_user_offline', $user->lang['OFFLINE'])),
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index 361dc831aa..a876d0133a 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -655,9 +655,14 @@ class ucp_profile
{
if (!empty($keys))
{
+ foreach ($keys as $key => $id)
+ {
+ $keys[$key] = $db->sql_like_expression($id . $db->get_any_char());
+ }
+ $sql_where = '(key_id ' . implode(' OR key_id ', $keys) . ')';
$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
WHERE user_id = ' . (int) $user->data['user_id'] . '
- AND ' . $db->sql_in_set('key_id', $keys) ;
+ AND ' . $sql_where ;
$db->sql_query($sql);
@@ -681,7 +686,7 @@ class ucp_profile
while ($row = $db->sql_fetchrow($result))
{
$template->assign_block_vars('sessions', array(
- 'KEY' => $row['key_id'],
+ 'KEY' => substr($row['key_id'], 0, 8),
'IP' => $row['last_ip'],
'LOGIN_TIME' => $user->format_date($row['last_login']),
));
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 9a15967bae..14f6a8bc02 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -33,7 +33,8 @@ class ucp_register
global $request, $phpbb_container;
//
- if ($config['require_activation'] == USER_ACTIVATION_DISABLE)
+ if ($config['require_activation'] == USER_ACTIVATION_DISABLE ||
+ (in_array($config['require_activation'], array(USER_ACTIVATION_SELF, USER_ACTIVATION_ADMIN)) && !$config['email_enable']))
{
trigger_error('UCP_REGISTER_DISABLE');
}
@@ -87,8 +88,8 @@ class ucp_register
if (!empty($login_link_data))
{
// Confirm that we have all necessary data
- $auth_provider = 'auth.provider.' . $request->variable('auth_provider', $config['auth_method']);
- $auth_provider = $phpbb_container->get($auth_provider);
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+ $auth_provider = $provider_collection->get_provider($request->variable('auth_provider', ''));
$result = $auth_provider->login_link_has_necessary_data($login_link_data);
if ($result !== null)
diff --git a/phpBB/index.php b/phpBB/index.php
index a36d74e0e9..df6932f6c0 100644
--- a/phpBB/index.php
+++ b/phpBB/index.php
@@ -185,7 +185,7 @@ $template->assign_vars(array(
'U_MCP' => ($auth->acl_get('m_') || $auth->acl_getf_global('m_')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&amp;mode=front', true, $user->session_id) : '')
);
-$page_title = $user->lang['INDEX'];
+$page_title = ($config['board_index_text'] !== '') ? $config['board_index_text'] : $user->lang['INDEX'];
/**
* You can use this event to modify the page title and load data for the index
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php
index cab3fd7f1f..da53d2c143 100644
--- a/phpBB/install/convertors/convert_phpbb20.php
+++ b/phpBB/install/convertors/convert_phpbb20.php
@@ -38,7 +38,7 @@ $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
$convertor_data = array(
'forum_name' => 'phpBB 2.0.x',
'version' => '1.0.3',
- 'phpbb_version' => '3.1.0-RC5',
+ 'phpbb_version' => '3.1.2',
'author' => '<a href="https://www.phpbb.com/">phpBB Limited</a>',
'dbms' => $dbms,
'dbhost' => $dbhost,
diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php
index 8016ff349b..80fd40a944 100644
--- a/phpBB/install/database_update.php
+++ b/phpBB/install/database_update.php
@@ -174,6 +174,8 @@ define('IN_DB_UPDATE', true);
// End startup code
$migrator = $phpbb_container->get('migrator');
+$migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($user, new \phpbb\db\html_migrator_output_handler($user), $phpbb_root_path . 'store/migrations_' . time() . '.log'));
+
$migrator->create_migrations_table();
$phpbb_extension_manager = $phpbb_container->get('ext.manager');
@@ -199,8 +201,6 @@ $safe_time_limit = min(15, ($phpbb_ini->get_int('max_execution_time') / 2));
while (!$migrator->finished())
{
- $migration_start_time = microtime(true);
-
try
{
$migrator->update();
@@ -219,28 +219,6 @@ while (!$migrator->finished())
$migrator->last_run_migration['state']
);
- if (isset($migrator->last_run_migration['effectively_installed']) && $migrator->last_run_migration['effectively_installed'])
- {
- echo $user->lang('MIGRATION_EFFECTIVELY_INSTALLED', $migrator->last_run_migration['name']);
- }
- else
- {
- if ($migrator->last_run_migration['task'] == 'process_data_step' && $state['migration_data_done'])
- {
- echo $user->lang('MIGRATION_DATA_DONE', $migrator->last_run_migration['name'], (microtime(true) - $migration_start_time));
- }
- else if ($migrator->last_run_migration['task'] == 'process_data_step')
- {
- echo $user->lang('MIGRATION_DATA_IN_PROGRESS', $migrator->last_run_migration['name'], (microtime(true) - $migration_start_time));
- }
- else if ($state['migration_schema_done'])
- {
- echo $user->lang('MIGRATION_SCHEMA_DONE', $migrator->last_run_migration['name'], (microtime(true) - $migration_start_time));
- }
- }
-
- echo "<br />\n";
-
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $update_start_time) >= $safe_time_limit)
{
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index adbd5a540e..ea51e5df76 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -273,7 +273,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.1.0-RC6-dev');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.1.3-RC1-dev');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400');
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index ae7565d608..8d6c1c141d 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -221,7 +221,8 @@ $lang = array_merge($lang, array(
'ACP_REGISTER_SETTINGS_EXPLAIN' => 'Here you are able to define registration and profile related settings.',
'ACC_ACTIVATION' => 'Account activation',
- 'ACC_ACTIVATION_EXPLAIN' => 'This determines whether users have immediate access to the board or if confirmation is required. You can also completely disable new registrations. “Board-wide email” must be enabled in order to use user or admin activation.',
+ 'ACC_ACTIVATION_EXPLAIN' => 'This determines whether users have immediate access to the board or if confirmation is required. You can also completely disable new registrations. <em>“Board-wide email” must be enabled in order to use user or admin activation.</em>',
+ 'ACC_ACTIVATION_WARNING' => 'Please note that the currently selected activation method requires emails to be enabled, otherwise registration will be disabled. We recommend to either select a different activation method or reenable emails.',
'NEW_MEMBER_POST_LIMIT' => 'New member post limit',
'NEW_MEMBER_POST_LIMIT_EXPLAIN' => 'New members are within the <em>Newly Registered Users</em> group until they reach this number of posts. You can use this group to keep them from using the PM system or to review their posts. <strong>A value of 0 disables this feature.</strong>',
'NEW_MEMBER_GROUP_DEFAULT' => 'Set Newly Registered Users group to default',
@@ -556,7 +557,7 @@ $lang = array_merge($lang, array(
'EMAIL_SIG' => 'Email signature',
'EMAIL_SIG_EXPLAIN' => 'This text will be attached to all emails the board sends.',
'ENABLE_EMAIL' => 'Enable board-wide emails',
- 'ENABLE_EMAIL_EXPLAIN' => 'If this is set to disabled no emails will be sent by the board at all. <em>Note the user and admin account activation settings require this setting to be enabled. If currently using “user” or “admin” activation in the activation settings, disabling this setting will require no activation of new accounts.</em>',
+ 'ENABLE_EMAIL_EXPLAIN' => 'If this is set to disabled no emails will be sent by the board at all. <em>Note the user and admin account activation settings require this setting to be enabled. If currently using “user” or “admin” activation in the activation settings, disabling this setting will disable registration.</em>',
'SMTP_AUTH_METHOD' => 'Authentication method for SMTP',
'SMTP_AUTH_METHOD_EXPLAIN' => 'Only used if a username/password is set, ask your provider if you are unsure which method to use.',
'SMTP_CRAM_MD5' => 'CRAM-MD5',
diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php
index 506d569d56..e6b05c8282 100644
--- a/phpBB/language/en/acp/styles.php
+++ b/phpBB/language/en/acp/styles.php
@@ -74,6 +74,7 @@ $lang = array_merge($lang, array(
'STYLE_INSTALLED_RETURN_INSTALLED_STYLES' => 'Return to installed styles list',
'STYLE_INSTALLED_RETURN_UNINSTALLED_STYLES' => 'Install more styles',
'STYLE_NAME' => 'Style name',
+ 'STYLE_NAME_RESERVED' => 'Style "%s" can not be installed, because the name is reserved.',
'STYLE_NOT_INSTALLED' => 'Style "%s" was not installed.',
'STYLE_PATH' => 'Style path',
'STYLE_UNINSTALL' => 'Uninstall',
diff --git a/phpBB/language/en/help_faq.php b/phpBB/language/en/help_faq.php
index 904dc92080..69cb70df62 100644
--- a/phpBB/language/en/help_faq.php
+++ b/phpBB/language/en/help_faq.php
@@ -36,44 +36,40 @@ $help = array(
1 => 'Login and Registration Issues'
),
array(
- 0 => 'Why can’t I login?',
- 1 => 'There are several reasons why this could occur. First, ensure your username and password are correct. If they are, contact the board owner to make sure you haven’t been banned. It is also possible the website owner has a configuration error on their end, and they would need to fix it.'
- ),
- array(
- 0 => 'Why do I need to register at all?',
+ 0 => 'Why do I need to register?',
1 => 'You may not have to, it is up to the administrator of the board as to whether you need to register in order to post messages. However; registration will give you access to additional features not available to guest users such as definable avatar images, private messaging, emailing of fellow users, usergroup subscription, etc. It only takes a few moments to register so it is recommended you do so.'
),
array(
- 0 => 'Why do I get logged off automatically?',
- 1 => 'If you do not check the <em>Remember me</em> box when you login, the board will only keep you logged in for a preset time. This prevents misuse of your account by anyone else. To stay logged in, check the box during login. This is not recommended if you access the board from a shared computer, e.g. library, internet cafe, university computer lab, etc. If you do not see this checkbox, it means the board administrator has disabled this feature.'
- ),
- array(
- 0 => 'How do I prevent my username appearing in the online user listings?',
- 1 => 'Within your User Control Panel, under “Board preferences”, you will find the option <em>Hide your online status</em>. Enable this option with <samp>Yes</samp> and you will only appear to the administrators, moderators and yourself. You will be counted as a hidden user.'
+ 0 => 'What is COPPA?',
+ 1 => 'COPPA, or the Children’s Online Privacy Protection Act of 1998, is a law in the United States requiring websites which can potentially collect information from minors under the age of 13 to have written parental consent or some other method of legal guardian acknowledgment, allowing the collection of personally identifiable information from a minor under the age of 13. If you are unsure if this applies to you as someone trying to register or to the website you are trying to register on, contact legal counsel for assistance. Please note that phpBB Limited and the owner’s of this board cannot provide legal advice and is not a point of contact for legal concerns of any kind, except as outlined in question “Who do I contact about abusive and/or legal matters related to this board?”.',
),
array(
- 0 => 'I’ve lost my password!',
- 1 => 'Don’t panic! While your password cannot be retrieved, it can easily be reset. Visit the login page and click <em>I’ve forgotten my password</em>. Follow the instructions and you should be able to log in again shortly.'
+ 0 => 'Why can’t I register?',
+ 1 => 'It is possible a board administrator has disabled registration to prevent new visitors from signing up. A board administrator could have also banned your IP address or disallowed the username you are attempting to register. Contact a board administrator for assistance.',
),
array(
0 => 'I registered but cannot login!',
1 => 'First, check your username and password. If they are correct, then one of two things may have happened. If COPPA support is enabled and you specified being under 13 years old during registration, you will have to follow the instructions you received. Some boards will also require new registrations to be activated, either by yourself or by an administrator before you can logon; this information was present during registration. If you were sent an email, follow the instructions. If you did not receive an email, you may have provided an incorrect email address or the email may have been picked up by a spam filer. If you are sure the email address you provided is correct, try contacting an administrator.'
),
array(
+ 0 => 'Why can’t I login?',
+ 1 => 'There are several reasons why this could occur. First, ensure your username and password are correct. If they are, contact a board administrator to make sure you haven’t been banned. It is also possible the website owner has a configuration error on their end, and they would need to fix it.',
+ ),
+ array(
0 => 'I registered in the past but cannot login any more?!',
1 => 'It is possible an administrator has deactivated or deleted your account for some reason. Also, many boards periodically remove users who have not posted for a long time to reduce the size of the database. If this has happened, try registering again and being more involved in discussions.'
),
array(
- 0 => 'What is COPPA?',
- 1 => 'COPPA, or the Child Online Privacy and Protection Act of 1998, is a law in the United States requiring websites which can potentially collect information from minors under the age of 13 to have written parental consent or some other method of legal guardian acknowledgment, allowing the collection of personally identifiable information from a minor under the age of 13. If you are unsure if this applies to you as someone trying to register or to the website you are trying to register on, contact legal counsel for assistance. Please note that the phpBB Limited cannot provide legal advice and is not a point of contact for legal concerns of any kind, except as outlined below.',
+ 0 => 'I’ve lost my password!',
+ 1 => 'Don’t panic! While your password cannot be retrieved, it can easily be reset. Visit the login page and click <em>I forgot my password</em>. Follow the instructions and you should be able to log in again shortly.<br />However, if you are not able to reset your password, contact a board administrator.',
),
array(
- 0 => 'Why can’t I register?',
- 1 => 'It is possible the website owner has banned your IP address or disallowed the username you are attempting to register. The website owner could have also disabled registration to prevent new visitors from signing up. Contact a board administrator for assistance.',
+ 0 => 'Why do I get logged off automatically?',
+ 1 => 'If you do not check the <em>Remember me</em> box when you login, the board will only keep you logged in for a preset time. This prevents misuse of your account by anyone else. To stay logged in, check the <em>Remember me</em> box during login. This is not recommended if you access the board from a shared computer, e.g. library, internet cafe, university computer lab, etc. If you do not see this checkbox, it means a board administrator has disabled this feature.',
),
array(
0 => 'What does the “Delete all board cookies” do?',
- 1 => '“Delete all board cookies” deletes the cookies created by phpBB which keep you authenticated and logged into the board. It also provides functions such as read tracking if they have been enabled by the board owner. If you are having login or logout problems, deleting board cookies may help.',
+ 1 => '“Delete all board cookies” deletes the cookies created by phpBB which keep you authenticated and logged into the board. Cookies also provide functions such as read tracking if they have been enabled by a board administrator. If you are having login or logout problems, deleting board cookies may help.',
),
array(
0 => '--',
@@ -81,7 +77,11 @@ $help = array(
),
array(
0 => 'How do I change my settings?',
- 1 => 'If you are a registered user, all your settings are stored in the board database. To alter them, visit your User Control Panel; a link can usually be found at the top of board pages. This system will allow you to change all your settings and preferences.'
+ 1 => 'If you are a registered user, all your settings are stored in the board database. To alter them, visit your User Control Panel; a link can usually be found by clicking on your username at the top of board pages. This system will allow you to change all your settings and preferences.',
+ ),
+ array(
+ 0 => 'How do I prevent my username appearing in the online user listings?',
+ 1 => 'Within your User Control Panel, under “Board preferences”, you will find the option <em>Hide your online status</em>. Enable this option and you will only appear to the administrators, moderators and yourself. You will be counted as a hidden user.'
),
array(
0 => 'The times are not correct!',
@@ -93,11 +93,15 @@ $help = array(
),
array(
0 => 'My language is not in the list!',
- 1 => 'Either the administrator has not installed your language or nobody has translated this board into your language. Try asking the board administrator if they can install the language pack you need. If the language pack does not exist, feel free to create a new translation. More information can be found at the phpBB website (see link at the bottom of board pages).'
+ 1 => 'Either the administrator has not installed your language or nobody has translated this board into your language. Try asking a board administrator if they can install the language pack you need. If the language pack does not exist, feel free to create a new translation. More information can be found at the <a href="https://www.phpbb.com/">phpBB</a>&reg; website.',
),
array(
- 0 => 'How do I show an image along with my username?',
- 1 => 'There are two images which may appear along with a username when viewing posts. One of them may be an image associated with your rank, generally in the form of stars, blocks or dots, indicating how many posts you have made or your status on the board. Another, usually a larger image, is known as an avatar and is generally unique or personal to each user. It is up to the board administrator to enable avatars and to choose the way in which avatars can be made available. If you are unable to use avatars, contact a board administrator and ask them for their reasons.'
+ 0 => 'What are the images next to my username?',
+ 1 => 'There are two images which may appear along with a username when viewing posts. One of them may be an image associated with your rank, generally in the form of stars, blocks or dots, indicating how many posts you have made or your status on the board. Another, usually larger, image is known as an avatar and is generally unique or personal to each user.',
+ ),
+ array(
+ 0 => 'How do I display an avatar?',
+ 1 => 'Within your User Control Panel, under “Profile” you can add an avatar by using one of the four following methods: Gravatar, Gallery, Remote or Upload. It is up to the board administrator to enable avatars and to choose the way in which avatars can be made available. If you are unable to use avatars, contact a board administrator.',
),
array(
0 => 'What is my rank and how do I change it?',
@@ -112,8 +116,8 @@ $help = array(
1 => 'Posting Issues'
),
array(
- 0 => 'How do I post a topic in a forum?',
- 1 => 'To post a new topic in a forum, click the relevant button on either the forum or topic screens. You may need to register before you can post a message. A list of your permissions in each forum is available at the bottom of the forum and topic screens. Example: You can post new topics, You can vote in polls, etc.'
+ 0 => 'How do I create a new topic or post a reply?',
+ 1 => 'To post a new topic in a forum, click "New Topic". To post a reply to a topic, click "Post Reply". You may need to register before you can post a message. A list of your permissions in each forum is available at the bottom of the forum and topic screens. Example: You can post new topics, You can post attachments, etc.',
),
array(
0 => 'How do I edit or delete a post?',
@@ -282,7 +286,7 @@ $help = array(
),
array(
0 => 'Why does my search return no results?',
- 1 => 'Your search was probably too vague and included many common terms which are not indexed by phpBB3. Be more specific and use the options available within Advanced search.'
+ 1 => 'Your search was probably too vague and included many common terms which are not indexed by phpBB. Be more specific and use the options available within Advanced search.',
),
array(
0 => 'Why does my search return a blank page!?',
@@ -294,19 +298,23 @@ $help = array(
),
array(
0 => 'How can I find my own posts and topics?',
- 1 => 'Your own posts can be retrieved either by clicking the “Search user’s posts” within the User Control Panel or via your own profile page. To search for your topics, use the Advanced search page and fill in the various options appropriately.'
+ 1 => 'Your own posts can be retrieved either by clicking the “Show your posts” link within the User Control Panel or by clicking the “Search user’s posts” link via your own profile page or by clicking the “Quick links” menu at the top of the board. To search for your topics, use the Advanced search page and fill in the various options appropriately.',
),
array(
0 => '--',
- 1 => 'Topic Subscriptions and Bookmarks'
+ 1 => 'Subscriptions and Bookmarks',
),
array(
0 => 'What is the difference between bookmarking and subscribing?',
- 1 => 'Bookmarking in phpBB3 is much like bookmarking in your web browser. You aren’t alerted when there’s an update, but you can come back to the topic later. Subscribing, however, will notify you when there is an update to the topic or forum on the board via your preferred method or methods.'
+ 1 => 'In phpBB 3.0, bookmarking topics worked much like bookmarking in a web browser. You were not alerted when there was an update. As of phpBB 3.1, bookmarking is more like subscribing to a topic. You can be notified when a bookmarked topic is updated. Subscribing, however, will notify you when there is an update to a topic or forum on the board. Notification options for bookmarks and subscriptions can be configured in the User Control Panel, under “Board preferences”.',
+ ),
+ array(
+ 0 => 'How do I bookmark or subscribe to specific topics?',
+ 1 => 'You can bookmark or subscribe to a specific topic by clicking the appropriate link in the “Topic tools” menu, conveniently located near the top and bottom of a topic discussion.<br />Replying to a topic with the “Notify me when a reply is posted” option checked will also subscribe you to the topic.',
),
array(
- 0 => 'How do I subscribe to specific forums or topics?',
- 1 => 'To subscribe to a specific forum, click the “Subscribe forum” link upon entering the forum. To subscribe to a topic, reply to the topic with the subscribe checkbox checked or click the “Subscribe topic” link within the topic itself.'
+ 0 => 'How do I subscribe to specific forums?',
+ 1 => 'To subscribe to a specific forum, click the “Subscribe forum” link, at the bottom of page, upon entering the forum.',
),
array(
0 => 'How do I remove my subscriptions?',
@@ -326,11 +334,11 @@ $help = array(
),
array(
0 => '--',
- 1 => 'phpBB 3 Issues'
+ 1 => 'phpBB Issues',
),
array(
0 => 'Who wrote this bulletin board?',
- 1 => 'This software (in its unmodified form) is produced, released and is copyright <a href="https://www.phpbb.com/">phpBB Limited</a>. It is made available under the GNU General Public License and may be freely distributed. See the link for more details.'
+ 1 => 'This software (in its unmodified form) is produced, released and is copyright <a href="https://www.phpbb.com/">phpBB Limited</a>. It is made available under the GNU General Public License, version 2 (GPL-2.0) and may be freely distributed. See <a href="https://www.phpbb.com/about/">About phpBB</a> for more details.',
),
array(
0 => 'Why isn’t X feature available?',
@@ -340,4 +348,8 @@ $help = array(
0 => 'Who do I contact about abusive and/or legal matters related to this board?',
1 => 'Any of the administrators listed on the “The team” page should be an appropriate point of contact for your complaints. If this still gets no response then you should contact the owner of the domain (do a <a href="http://www.google.com/search?q=whois">whois lookup</a>) or, if this is running on a free service (e.g. Yahoo!, free.fr, f2s.com, etc.), the management or abuse department of that service. Please note that the phpBB Limited has <strong>absolutely no jurisdiction</strong> and cannot in any way be held liable over how, where or by whom this board is used. Do not contact the phpBB Limited in relation to any legal (cease and desist, liable, defamatory comment, etc.) matter <strong>not directly related</strong> to the phpBB.com website or the discrete software of phpBB itself. If you do email phpBB Limited <strong>about any third party</strong> use of this software then you should expect a terse response or no response at all.'
),
+ array(
+ 0 => 'How do I contact a board administrator?',
+ 1 => 'All users of the board can use the “Contact us” form, if the option was enabled by the board administrator.<br />Members of the board can also use the “The team” link.',
+ ),
);
diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php
index a2b27f0a60..107de9c64f 100644
--- a/phpBB/language/en/install.php
+++ b/phpBB/language/en/install.php
@@ -547,7 +547,7 @@ $lang = array_merge($lang, array(
<ul style="margin-left: 20px; font-size: 1.1em;">
<li>Go to the <a href="https://www.phpbb.com/downloads/" title="https://www.phpbb.com/downloads/">phpBB.com downloads page</a> and download the "Automatic Update Package" archive.<br /><br /></li>
<li>Unpack the archive.<br /><br /></li>
- <li>Upload the complete uncompressed install folder to your phpBB root directory (where your config.php file is).<br /><br /></li>
+ <li>Upload the complete uncompressed "install" and "vendor" folders to your phpBB root directory (where your config.php file is).<br /><br /></li>
</ul>
<p>Once uploaded your board will be offline for normal users due to the install directory you uploaded now present.<br /><br />
diff --git a/phpBB/language/en/mcp.php b/phpBB/language/en/mcp.php
index bc0fd03520..a961068657 100644
--- a/phpBB/language/en/mcp.php
+++ b/phpBB/language/en/mcp.php
@@ -237,7 +237,7 @@ $lang = array_merge($lang, array(
'NOT_MODERATOR' => 'You are not a moderator of this forum.',
'NO_DESTINATION_FORUM' => 'Please select a forum for destination.',
'NO_DESTINATION_FORUM_FOUND' => 'There is no destination forum available.',
- 'NO_ENTRIES' => 'No log entries for this period.',
+ 'NO_ENTRIES' => 'No log entries.',
'NO_FEEDBACK' => 'No feedback exists for this user.',
'NO_FINAL_TOPIC_SELECTED' => 'You have to select a destination topic for merging posts.',
'NO_MATCHES_FOUND' => 'No matches found.',
diff --git a/phpBB/language/en/memberlist.php b/phpBB/language/en/memberlist.php
index b8c626d331..5605f8f4b5 100644
--- a/phpBB/language/en/memberlist.php
+++ b/phpBB/language/en/memberlist.php
@@ -48,7 +48,7 @@ $lang = array_merge($lang, array(
'BEFORE' => 'Before',
- 'CC_EMAIL' => 'Send a copy of this email to yourself.',
+ 'CC_SENDER' => 'Send a copy of this email to yourself.',
'CONTACT_ADMIN' => 'Contact a Board Administrator',
'DEST_LANG' => 'Language',
diff --git a/phpBB/language/en/migrator.php b/phpBB/language/en/migrator.php
index 7199d21d96..f5a56816c2 100644
--- a/phpBB/language/en/migrator.php
+++ b/phpBB/language/en/migrator.php
@@ -41,12 +41,16 @@ $lang = array_merge($lang, array(
'GROUP_NOT_EXIST' => 'The group "%s" unexpectedly does not exist.',
+ 'MIGRATION_APPLY_DEPENDENCIES' => 'Apply dependencies of %s.',
'MIGRATION_DATA_DONE' => 'Installed Data: %1$s; Time: %2$.2f seconds',
'MIGRATION_DATA_IN_PROGRESS' => 'Installing Data: %1$s; Time: %2$.2f seconds',
+ 'MIGRATION_DATA_RUNNING' => 'Installing Data: %s.',
'MIGRATION_EFFECTIVELY_INSTALLED' => 'Migration already effectively installed (skipped): %s',
'MIGRATION_EXCEPTION_ERROR' => 'Something went wrong during the request and an exception was thrown. The changes made before the error occurred were reversed to the best of our abilities, but you should check the board for errors.',
'MIGRATION_NOT_FULFILLABLE' => 'The migration "%1$s" is not fulfillable, missing migration "%2$s".',
+ 'MIGRATION_NOT_VALID' => '%s is not a valid migration.',
'MIGRATION_SCHEMA_DONE' => 'Installed Schema: %1$s; Time: %2$.2f seconds',
+ 'MIGRATION_SCHEMA_RUNNING' => 'Installing Schema: %s.',
'MODULE_ERROR' => 'An error occurred while creating a module: %s',
'MODULE_INFO_FILE_NOT_EXIST' => 'A required module info file is missing: %2$s',
diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php
index ad7063d3f9..07751d1f7f 100644
--- a/phpBB/language/en/ucp.php
+++ b/phpBB/language/en/ucp.php
@@ -417,6 +417,8 @@ $lang = array_merge($lang, array(
'PM_FROM_REMOVED_AUTHOR' => 'This message was sent by a user no longer registered.',
'PM_ICON' => 'PM icon',
'PM_INBOX' => 'Inbox',
+ 'PM_MARK_ALL_READ' => 'Mark all messages read',
+ 'PM_MARK_ALL_READ_SUCCESS' => 'All private messages in this folder have been marked read',
'PM_NO_USERS' => 'The requested users to be added do not exist.',
'PM_OUTBOX' => 'Outbox',
'PM_SENTBOX' => 'Sent messages',
diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php
index e3ac8dad51..5a5be6f761 100644
--- a/phpBB/memberlist.php
+++ b/phpBB/memberlist.php
@@ -681,7 +681,7 @@ switch ($mode)
'U_MCP_QUEUE' => ($auth->acl_getf_global('m_approve')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue', true, $user->session_id) : '',
'U_SWITCH_PERMISSIONS' => ($auth->acl_get('a_switchperm') && $user->data['user_id'] != $user_id) ? append_sid("{$phpbb_root_path}ucp.$phpEx", "mode=switch_perm&amp;u={$user_id}&amp;hash=" . generate_link_hash('switchperm')) : '',
- 'U_EDIT_SELF' => ($user_id == $user->data['user_id']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_profile&amp;mode=profile_info') : '',
+ 'U_EDIT_SELF' => ($user_id == $user->data['user_id'] && $auth->acl_get('u_chgprofileinfo')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_profile&amp;mode=profile_info') : '',
'S_USER_NOTES' => ($user_notes_enabled) ? true : false,
'S_WARN_USER' => ($warn_user_enabled) ? true : false,
@@ -1089,9 +1089,9 @@ switch ($mode)
{
$user_rank_data = phpbb_get_user_rank($group_row, false);
- if ($rank_img)
+ if ($user_rank_data['img'])
{
- $rank_img .= '<br />';
+ $user_rank_data['img'] .= '<br />';
}
}
@@ -1427,7 +1427,7 @@ switch ($mode)
$cp_row = (isset($profile_fields_cache[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields_cache[$user_id], false) : array();
}
- $memberrow = array_merge(phpbb_show_profile($row), array(
+ $memberrow = array_merge(phpbb_show_profile($row, false, false, false), array(
'ROW_NUMBER' => $i + ($start + 1),
'S_CUSTOM_PROFILE' => (isset($cp_row['row']) && sizeof($cp_row['row'])) ? true : false,
diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php
index 38755ccf99..b59f0e60ec 100644
--- a/phpBB/phpbb/auth/auth.php
+++ b/phpBB/phpbb/auth/auth.php
@@ -927,11 +927,11 @@ class auth
*/
function login($username, $password, $autologin = false, $viewonline = 1, $admin = 0)
{
- global $config, $db, $user, $phpbb_root_path, $phpEx, $phpbb_container;
+ global $db, $user, $phpbb_root_path, $phpEx, $phpbb_container;
- $method = trim(basename($config['auth_method']));
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
- $provider = $phpbb_container->get('auth.provider.' . $method);
+ $provider = $provider_collection->get_provider();
if ($provider)
{
$login = $provider->login($username, $password);
diff --git a/phpBB/phpbb/auth/provider/apache.php b/phpBB/phpbb/auth/provider/apache.php
index 9137a77210..aa5bf64335 100644
--- a/phpBB/phpbb/auth/provider/apache.php
+++ b/phpBB/phpbb/auth/provider/apache.php
@@ -137,7 +137,7 @@ class apache extends \phpbb\auth\provider\base
return array(
'status' => LOGIN_SUCCESS_CREATE_PROFILE,
'error_msg' => false,
- 'user_row' => user_row_apache($php_auth_user, $php_auth_pw),
+ 'user_row' => $this->user_row($php_auth_user, $php_auth_pw),
);
}
@@ -185,7 +185,7 @@ class apache extends \phpbb\auth\provider\base
}
// create the user if he does not exist yet
- user_add(user_row_apache($php_auth_user, $php_auth_pw));
+ user_add($this->user_row($php_auth_user, $php_auth_pw));
$sql = 'SELECT *
FROM ' . USERS_TABLE . "
diff --git a/phpBB/phpbb/auth/provider/db.php b/phpBB/phpbb/auth/provider/db.php
index 722eeffa9a..d8c5fb72de 100644
--- a/phpBB/phpbb/auth/provider/db.php
+++ b/phpBB/phpbb/auth/provider/db.php
@@ -87,7 +87,7 @@ class db extends \phpbb\auth\provider\base
$username_clean = utf8_clean_string($username);
- $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type, user_login_attempts
+ $sql = 'SELECT *
FROM ' . USERS_TABLE . "
WHERE username_clean = '" . $this->db->sql_escape($username_clean) . "'";
$result = $this->db->sql_query($sql);
@@ -123,7 +123,7 @@ class db extends \phpbb\auth\provider\base
'username_clean' => $username_clean,
);
$sql = 'INSERT INTO ' . LOGIN_ATTEMPT_TABLE . $this->db->sql_build_array('INSERT', $attempt_data);
- $result = $this->db->sql_query($sql);
+ $this->db->sql_query($sql);
}
else
{
@@ -175,7 +175,7 @@ class db extends \phpbb\auth\provider\base
}
// Check password ...
- if ($this->passwords_manager->check($password, $row['user_password']))
+ if ($this->passwords_manager->check($password, $row['user_password'], $row))
{
// Check for old password hash...
if ($this->passwords_manager->convert_flag || strlen($row['user_password']) == 32)
@@ -232,7 +232,7 @@ class db extends \phpbb\auth\provider\base
// Give status about wrong password...
return array(
'status' => ($show_captcha) ? LOGIN_ERROR_ATTEMPTS : LOGIN_ERROR_PASSWORD,
- 'error_msg' => ($show_captcha) ? 'LOGIN_ERROR_ATTEMPTS' : 'LOGIN_ERROR_PASSWORD',
+ 'error_msg' => 'LOGIN_ERROR_PASSWORD',
'user_row' => $row,
);
}
diff --git a/phpBB/phpbb/auth/provider_collection.php b/phpBB/phpbb/auth/provider_collection.php
index a74a2135dc..8e7e9e2cc1 100644
--- a/phpBB/phpbb/auth/provider_collection.php
+++ b/phpBB/phpbb/auth/provider_collection.php
@@ -38,6 +38,7 @@ class provider_collection extends \phpbb\di\service_collection
/**
* Get an auth provider.
*
+ * @param string $provider_name The name of the auth provider
* @return object Default auth provider selected in config if it
* does exist. Otherwise the standard db auth
* provider.
@@ -46,11 +47,12 @@ class provider_collection extends \phpbb\di\service_collection
* auth provider exist. The db auth provider
* should always exist in a phpBB installation.
*/
- public function get_provider()
+ public function get_provider($provider_name = '')
{
- if ($this->offsetExists('auth.provider.' . basename(trim($this->config['auth_method']))))
+ $provider_name = ($provider_name !== '') ? $provider_name : basename(trim($this->config['auth_method']));
+ if ($this->offsetExists('auth.provider.' . $provider_name))
{
- return $this->offsetGet('auth.provider.' . basename(trim($this->config['auth_method'])));
+ return $this->offsetGet('auth.provider.' . $provider_name);
}
// Revert to db auth provider if selected method does not exist
else if ($this->offsetExists('auth.provider.db'))
diff --git a/phpBB/phpbb/avatar/driver/local.php b/phpBB/phpbb/avatar/driver/local.php
index 07b3ed59de..8888686b2d 100644
--- a/phpBB/phpbb/avatar/driver/local.php
+++ b/phpBB/phpbb/avatar/driver/local.php
@@ -154,7 +154,7 @@ class local extends \phpbb\avatar\driver\driver
*/
protected function get_avatar_list($user)
{
- $avatar_list = ($this->cache == null) ? false : $this->cache->get('avatar_local_list');
+ $avatar_list = ($this->cache == null) ? false : $this->cache->get('_avatar_local_list');
if ($avatar_list === false)
{
@@ -192,7 +192,7 @@ class local extends \phpbb\avatar\driver\driver
if ($this->cache != null)
{
- $this->cache->put('avatar_local_list', $avatar_list, 86400);
+ $this->cache->put('_avatar_local_list', $avatar_list, 86400);
}
}
diff --git a/phpBB/phpbb/avatar/driver/remote.php b/phpBB/phpbb/avatar/driver/remote.php
index 1bd7f6c927..4b0ee3f06f 100644
--- a/phpBB/phpbb/avatar/driver/remote.php
+++ b/phpBB/phpbb/avatar/driver/remote.php
@@ -130,8 +130,24 @@ class remote extends \phpbb\avatar\driver\driver
{
// Timeout after 1 second
stream_set_timeout($file_stream, 1);
+ // read some data to ensure headers are present
+ fread($file_stream, 1024);
$meta = stream_get_meta_data($file_stream);
- foreach ($meta['wrapper_data'] as $header)
+
+ if (isset($meta['wrapper_data']['headers']) && is_array($meta['wrapper_data']['headers']))
+ {
+ $headers = $meta['wrapper_data']['headers'];
+ }
+ else if (isset($meta['wrapper_data']) && is_array($meta['wrapper_data']))
+ {
+ $headers = $meta['wrapper_data'];
+ }
+ else
+ {
+ $headers = array();
+ }
+
+ foreach ($headers as $header)
{
$header = preg_split('/ /', $header, 2);
if (strtr(strtolower(trim($header[0], ':')), '_', '-') === 'content-type')
diff --git a/phpBB/phpbb/avatar/manager.php b/phpBB/phpbb/avatar/manager.php
index 42ae61a9a2..8d83152ed6 100644
--- a/phpBB/phpbb/avatar/manager.php
+++ b/phpBB/phpbb/avatar/manager.php
@@ -326,17 +326,41 @@ class manager
$driver->delete($avatar_data);
}
- $result = self::$default_row;
+ $result = $this->prefix_avatar_columns($prefix, self::$default_row);
- foreach ($result as $key => $value)
+ $sql = 'UPDATE ' . $table . '
+ SET ' . $db->sql_build_array('UPDATE', $result) . '
+ WHERE ' . $prefix . 'id = ' . (int) $avatar_data['id'];
+ $db->sql_query($sql);
+
+ // Make sure we also delete this avatar from the users
+ if ($prefix === 'group_')
{
- $result[$prefix . $key] = $value;
- unset($result[$key]);
+ $result = $this->prefix_avatar_columns('user_', self::$default_row);
+
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET ' . $db->sql_build_array('UPDATE', $result) . "
+ WHERE user_avatar = '" . $db->sql_escape($avatar_data['avatar']) . "'";
+ $db->sql_query($sql);
}
+ }
- $sql = 'UPDATE ' . $table . '
- SET ' . $db->sql_build_array('UPDATE', $result) . '
- WHERE ' . $prefix . 'id = ' . (int) $avatar_data['id'];
- $db->sql_query($sql);
+ /**
+ * Prefix avatar columns
+ *
+ * @param string $prefix Column prefix
+ * @param array $data Column data
+ *
+ * @return array Column data with prefixed column names
+ */
+ public function prefix_avatar_columns($prefix, $data)
+ {
+ foreach ($data as $key => $value)
+ {
+ $data[$prefix . $key] = $value;
+ unset($data[$key]);
+ }
+
+ return $data;
}
}
diff --git a/phpBB/phpbb/captcha/plugins/recaptcha.php b/phpBB/phpbb/captcha/plugins/recaptcha.php
index ea446d7bc3..584f3afec1 100644
--- a/phpBB/phpbb/captcha/plugins/recaptcha.php
+++ b/phpBB/phpbb/captcha/plugins/recaptcha.php
@@ -26,8 +26,10 @@ class recaptcha extends captcha_abstract
var $challenge;
var $response;
- // PHP4 Constructor
- function phpbb_recaptcha()
+ /**
+ * Constructor
+ */
+ public function __construct()
{
global $request;
$this->recaptcha_server = $request->is_secure() ? $this->recaptcha_server_secure : $this->recaptcha_server;
diff --git a/phpBB/phpbb/console/command/db/console_migrator_output_handler.php b/phpBB/phpbb/console/command/db/console_migrator_output_handler.php
new file mode 100644
index 0000000000..b9741a3838
--- /dev/null
+++ b/phpBB/phpbb/console/command/db/console_migrator_output_handler.php
@@ -0,0 +1,69 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\console\command\db;
+
+use phpbb\user;
+use phpbb\db\migrator_output_handler_interface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class console_migrator_output_handler implements migrator_output_handler_interface
+{
+ /**
+ * User object.
+ *
+ * @var user
+ */
+ private $user;
+
+ /**
+ * Console output object.
+ *
+ * @var OutputInterface
+ */
+ private $output;
+
+ /**
+ * Constructor
+ *
+ * @param user $user User object
+ * @param OutputInterface $output Console output object
+ */
+ public function __construct(user $user, OutputInterface $output)
+ {
+ $this->user = $user;
+ $this->output = $output;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($message, $verbosity)
+ {
+ if ($verbosity <= $this->output->getVerbosity())
+ {
+ $translated_message = call_user_func_array(array($this->user, 'lang'), $message);
+
+ if ($verbosity === migrator_output_handler_interface::VERBOSITY_NORMAL)
+ {
+ $translated_message = '<info>' . $translated_message . '</info>';
+ }
+ else if ($verbosity === migrator_output_handler_interface::VERBOSITY_VERBOSE)
+ {
+ $translated_message = '<comment>' . $translated_message . '</comment>';
+ }
+
+ $this->output->writeln($translated_message);
+ }
+ }
+}
diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php
index c760cde5b5..87c2a057d1 100644
--- a/phpBB/phpbb/console/command/db/migrate.php
+++ b/phpBB/phpbb/console/command/db/migrate.php
@@ -32,13 +32,17 @@ class migrate extends \phpbb\console\command\command
/** @var \phpbb\log\log */
protected $log;
- function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log)
+ /** @var string phpBB root path */
+ protected $phpbb_root_path;
+
+ function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, $phpbb_root_path)
{
$this->migrator = $migrator;
$this->extension_manager = $extension_manager;
$this->config = $config;
$this->cache = $cache;
$this->log = $log;
+ $this->phpbb_root_path = $phpbb_root_path;
parent::__construct($user);
$this->user->add_lang(array('common', 'install', 'migrator'));
}
@@ -53,6 +57,8 @@ class migrate extends \phpbb\console\command\command
protected function execute(InputInterface $input, OutputInterface $output)
{
+ $this->migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($this->user, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log'));
+
$this->migrator->create_migrations_table();
$this->cache->purge();
@@ -61,8 +67,6 @@ class migrate extends \phpbb\console\command\command
$orig_version = $this->config['version'];
while (!$this->migrator->finished())
{
- $migration_start_time = microtime(true);
-
try
{
$this->migrator->update();
@@ -73,36 +77,6 @@ class migrate extends \phpbb\console\command\command
$this->finalise_update();
return 1;
}
-
- $migration_stop_time = microtime(true) - $migration_start_time;
-
- $state = array_merge(
- array(
- 'migration_schema_done' => false,
- 'migration_data_done' => false,
- ),
- $this->migrator->last_run_migration['state']
- );
-
- if (!empty($this->migrator->last_run_migration['effectively_installed']))
- {
- $msg = $this->user->lang('MIGRATION_EFFECTIVELY_INSTALLED', $this->migrator->last_run_migration['name']);
- $output->writeln("<comment>$msg</comment>");
- }
- else if ($this->migrator->last_run_migration['task'] == 'process_data_step' && $state['migration_data_done'])
- {
- $msg = $this->user->lang('MIGRATION_DATA_DONE', $this->migrator->last_run_migration['name'], $migration_stop_time);
- $output->writeln("<info>$msg</info>");
- }
- else if ($this->migrator->last_run_migration['task'] == 'process_data_step')
- {
- $output->writeln($this->user->lang('MIGRATION_DATA_IN_PROGRESS', $this->migrator->last_run_migration['name'], $migration_stop_time));
- }
- else if ($state['migration_schema_done'])
- {
- $msg = $this->user->lang('MIGRATION_SCHEMA_DONE', $this->migrator->last_run_migration['name'], $migration_stop_time);
- $output->writeln("<info>$msg</info>");
- }
}
if ($orig_version != $this->config['version'])
diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php
index 187e455d48..52e6947c2c 100644
--- a/phpBB/phpbb/controller/helper.php
+++ b/phpBB/phpbb/controller/helper.php
@@ -44,6 +44,9 @@ class helper
/* @var \phpbb\symfony_request */
protected $symfony_request;
+ /* @var \phpbb\request\request_interface */
+ protected $request;
+
/**
* @var \phpbb\filesystem The filesystem object
*/
@@ -70,16 +73,18 @@ class helper
* @param \phpbb\controller\provider $provider Path provider
* @param \phpbb\extension\manager $manager Extension manager object
* @param \phpbb\symfony_request $symfony_request Symfony Request object
+ * @param \phpbb\request\request_interface $request phpBB request object
* @param \phpbb\filesystem $filesystem The filesystem object
* @param string $phpbb_root_path phpBB root path
* @param string $php_ext PHP file extension
*/
- public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext)
{
$this->template = $template;
$this->user = $user;
$this->config = $config;
$this->symfony_request = $symfony_request;
+ $this->request = $request;
$this->filesystem = $filesystem;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
@@ -153,7 +158,7 @@ class helper
}
}
- $base_url = $this->filesystem->clean_path($base_url);
+ $base_url = $this->request->escape($this->filesystem->clean_path($base_url), true);
$context->setBaseUrl($base_url);
@@ -197,6 +202,6 @@ class helper
*/
public function get_current_url()
{
- return generate_board_url(true) . $this->symfony_request->getRequestUri();
+ return generate_board_url(true) . $this->request->escape($this->symfony_request->getRequestUri(), true);
}
}
diff --git a/phpBB/phpbb/cron/manager.php b/phpBB/phpbb/cron/manager.php
index 5c8ac04b77..079ce8107e 100644
--- a/phpBB/phpbb/cron/manager.php
+++ b/phpBB/phpbb/cron/manager.php
@@ -73,6 +73,7 @@ class manager
*/
public function find_one_ready_task()
{
+ shuffle($this->tasks);
foreach ($this->tasks as $task)
{
if ($task->is_ready())
diff --git a/phpBB/phpbb/cron/task/core/queue.php b/phpBB/phpbb/cron/task/core/queue.php
index 796a96d7f5..a9345a44df 100644
--- a/phpBB/phpbb/cron/task/core/queue.php
+++ b/phpBB/phpbb/cron/task/core/queue.php
@@ -73,6 +73,6 @@ class queue extends \phpbb\cron\task\base
*/
public function should_run()
{
- return $this->config['last_queue_run'] < time() - $this->config['queue_interval_config'];
+ return $this->config['last_queue_run'] < time() - $this->config['queue_interval'];
}
}
diff --git a/phpBB/phpbb/db/html_migrator_output_handler.php b/phpBB/phpbb/db/html_migrator_output_handler.php
new file mode 100644
index 0000000000..e37c667463
--- /dev/null
+++ b/phpBB/phpbb/db/html_migrator_output_handler.php
@@ -0,0 +1,48 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db;
+
+use phpbb\user;
+
+class html_migrator_output_handler implements migrator_output_handler_interface
+{
+ /**
+ * User object.
+ *
+ * @var user
+ */
+ private $user;
+
+ /**
+ * Constructor
+ *
+ * @param user $user User object
+ */
+ public function __construct(user $user)
+ {
+ $this->user = $user;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($message, $verbosity)
+ {
+ if ($verbosity <= migrator_output_handler_interface::VERBOSITY_VERBOSE)
+ {
+ $final_message = call_user_func_array(array($this->user, 'lang'), $message);
+ echo $final_message . "<br />\n";
+ }
+ }
+}
diff --git a/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php b/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php
new file mode 100644
index 0000000000..94c293dc45
--- /dev/null
+++ b/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php
@@ -0,0 +1,95 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db;
+
+use phpbb\user;
+
+class log_wrapper_migrator_output_handler implements migrator_output_handler_interface
+{
+ /**
+ * User object.
+ *
+ * @var user
+ */
+ protected $user;
+
+ /**
+ * A migrator output handler
+ *
+ * @var migrator_output_handler_interface
+ */
+ protected $migrator;
+
+ /**
+ * Log file handle
+ * @var resource
+ */
+ protected $file_handle = false;
+
+ /**
+ * Constructor
+ *
+ * @param user $user User object
+ * @param migrator_output_handler_interface $migrator Migrator output handler
+ * @param string $log_file File to log to
+ */
+ public function __construct(user $user, migrator_output_handler_interface $migrator, $log_file)
+ {
+ $this->user = $user;
+ $this->migrator = $migrator;
+ $this->file_open($log_file);
+ }
+
+ /**
+ * Open file for logging
+ *
+ * @param string $file File to open
+ */
+ protected function file_open($file)
+ {
+ if (phpbb_is_writable(dirname($file)))
+ {
+ $this->file_handle = fopen($file, 'w');
+ }
+ else
+ {
+ throw new \RuntimeException('Unable to write to migrator log file');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($message, $verbosity)
+ {
+ $this->migrator->write($message, $verbosity);
+
+ if ($this->file_handle !== false)
+ {
+ $translated_message = call_user_func_array(array($this->user, 'lang'), $message) . "\n";
+
+ if ($verbosity <= migrator_output_handler_interface::VERBOSITY_NORMAL)
+ {
+ $translated_message = '[INFO] ' . $translated_message;
+ }
+ else
+ {
+ $translated_message = '[DEBUG] ' . $translated_message;
+ }
+
+ fwrite($this->file_handle, $translated_message);
+ fflush($this->file_handle);
+ }
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php
index 8600472cca..f9f6d9f7f7 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php
@@ -31,7 +31,6 @@ class release_3_0_12_rc1 extends \phpbb\db\migration\migration
{
return array(
array('custom', array(array(&$this, 'update_module_auth'))),
- array('custom', array(array(&$this, 'update_bots'))),
array('custom', array(array(&$this, 'disable_bots_from_receiving_pms'))),
array('config.update', array('version', '3.0.12-RC1')),
@@ -70,60 +69,4 @@ class release_3_0_12_rc1 extends \phpbb\db\migration\migration
AND module_mode = \'signature\'';
$this->sql_query($sql);
}
-
- public function update_bots()
- {
- // Update bots
- if (!function_exists('user_delete'))
- {
- include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
- }
-
- $bots_updates = array(
- // Bot Deletions
- 'NG-Search [Bot]' => false,
- 'Nutch/CVS [Bot]' => false,
- 'OmniExplorer [Bot]' => false,
- 'Seekport [Bot]' => false,
- 'Synoo [Bot]' => false,
- 'WiseNut [Bot]' => false,
-
- // Bot Updates
- // Bot name to bot user agent map
- 'Baidu [Spider]' => 'Baiduspider',
- 'Exabot [Bot]' => 'Exabot',
- 'Voyager [Bot]' => 'voyager/',
- 'W3C [Validator]' => 'W3C_Validator',
- );
-
- foreach ($bots_updates as $bot_name => $bot_agent)
- {
- $sql = 'SELECT user_id
- FROM ' . USERS_TABLE . '
- WHERE user_type = ' . USER_IGNORE . "
- AND username_clean = '" . $this->db->sql_escape(utf8_clean_string($bot_name)) . "'";
- $result = $this->db->sql_query($sql);
- $bot_user_id = (int) $this->db->sql_fetchfield('user_id');
- $this->db->sql_freeresult($result);
-
- if ($bot_user_id)
- {
- if ($bot_agent === false)
- {
- $sql = 'DELETE FROM ' . BOTS_TABLE . "
- WHERE user_id = $bot_user_id";
- $this->sql_query($sql);
-
- user_delete('retain', $bot_user_id);
- }
- else
- {
- $sql = 'UPDATE ' . BOTS_TABLE . "
- SET bot_agent = '" . $this->db->sql_escape($bot_agent) . "'
- WHERE user_id = $bot_user_id";
- $this->sql_query($sql);
- }
- }
- }
- }
}
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php
index f593c32181..2cc7786046 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php
@@ -55,6 +55,9 @@ class release_3_0_5_rc1 extends \phpbb\db\migration\migration
public function hash_old_passwords()
{
+ global $phpbb_container;
+
+ $passwords_manager = $phpbb_container->get('passwords.manager');
$sql = 'SELECT user_id, user_password
FROM ' . $this->table_prefix . 'users
WHERE user_pass_convert = 1';
@@ -65,7 +68,7 @@ class release_3_0_5_rc1 extends \phpbb\db\migration\migration
if (strlen($row['user_password']) == 32)
{
$sql_ary = array(
- 'user_password' => phpbb_hash($row['user_password']),
+ 'user_password' => '$CP$' . $passwords_manager->hash($row['user_password'], 'passwords.driver.salted_md5'),
);
$this->sql_query('UPDATE ' . $this->table_prefix . 'users SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id']);
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php
index 4e863fa143..22fd51543b 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php
@@ -30,7 +30,6 @@ class release_3_0_8_rc1 extends \phpbb\db\migration\migration
return array(
array('custom', array(array(&$this, 'update_file_extension_group_names'))),
array('custom', array(array(&$this, 'update_module_auth'))),
- array('custom', array(array(&$this, 'update_bots'))),
array('custom', array(array(&$this, 'delete_orphan_shadow_topics'))),
array('module.add', array(
'acp',
@@ -114,70 +113,6 @@ class release_3_0_8_rc1 extends \phpbb\db\migration\migration
$this->sql_query($sql);
}
- public function update_bots()
- {
- $bot_name = 'Bing [Bot]';
- $bot_name_clean = utf8_clean_string($bot_name);
-
- $sql = 'SELECT user_id
- FROM ' . USERS_TABLE . "
- WHERE username_clean = '" . $this->db->sql_escape($bot_name_clean) . "'";
- $result = $this->db->sql_query($sql);
- $bing_already_added = (bool) $this->db->sql_fetchfield('user_id');
- $this->db->sql_freeresult($result);
-
- if (!$bing_already_added)
- {
- $bot_agent = 'bingbot/';
- $bot_ip = '';
- $sql = 'SELECT group_id, group_colour
- FROM ' . GROUPS_TABLE . "
- WHERE group_name = 'BOTS'";
- $result = $this->db->sql_query($sql);
- $group_row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
-
- if (!$group_row)
- {
- // default fallback, should never get here
- $group_row['group_id'] = 6;
- $group_row['group_colour'] = '9E8DA7';
- }
-
- if (!function_exists('user_add'))
- {
- include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
- }
-
- $user_row = array(
- 'user_type' => USER_IGNORE,
- 'group_id' => $group_row['group_id'],
- 'username' => $bot_name,
- 'user_regdate' => time(),
- 'user_password' => '',
- 'user_colour' => $group_row['group_colour'],
- 'user_email' => '',
- 'user_lang' => $this->config['default_lang'],
- 'user_style' => $this->config['default_style'],
- 'user_timezone' => 0,
- 'user_dateformat' => $this->config['default_dateformat'],
- 'user_allow_massemail' => 0,
- );
-
- $user_id = user_add($user_row);
-
- $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $this->db->sql_build_array('INSERT', array(
- 'bot_active' => 1,
- 'bot_name' => (string) $bot_name,
- 'user_id' => (int) $user_id,
- 'bot_agent' => (string) $bot_agent,
- 'bot_ip' => (string) $bot_ip,
- ));
-
- $this->sql_query($sql);
- }
- }
-
public function delete_orphan_shadow_topics()
{
// Delete shadow topics pointing to not existing topics
diff --git a/phpBB/phpbb/db/migration/data/v310/bot_update.php b/phpBB/phpbb/db/migration/data/v310/bot_update.php
new file mode 100644
index 0000000000..39b16c68f8
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/bot_update.php
@@ -0,0 +1,150 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class bot_update extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\rc6');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array(&$this, 'update_bing_bot'))),
+ array('custom', array(array(&$this, 'update_bots'))),
+ );
+ }
+
+ public function update_bing_bot()
+ {
+ $bot_name = 'Bing [Bot]';
+ $bot_name_clean = utf8_clean_string($bot_name);
+
+ $sql = 'SELECT user_id
+ FROM ' . USERS_TABLE . "
+ WHERE username_clean = '" . $this->db->sql_escape($bot_name_clean) . "'";
+ $result = $this->db->sql_query($sql);
+ $bing_already_added = (bool) $this->db->sql_fetchfield('user_id');
+ $this->db->sql_freeresult($result);
+
+ if (!$bing_already_added)
+ {
+ $bot_agent = 'bingbot/';
+ $bot_ip = '';
+ $sql = 'SELECT group_id, group_colour
+ FROM ' . GROUPS_TABLE . "
+ WHERE group_name = 'BOTS'";
+ $result = $this->db->sql_query($sql);
+ $group_row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if (!$group_row)
+ {
+ // default fallback, should never get here
+ $group_row['group_id'] = 6;
+ $group_row['group_colour'] = '9E8DA7';
+ }
+
+ if (!function_exists('user_add'))
+ {
+ include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
+ }
+
+ $user_row = array(
+ 'user_type' => USER_IGNORE,
+ 'group_id' => $group_row['group_id'],
+ 'username' => $bot_name,
+ 'user_regdate' => time(),
+ 'user_password' => '',
+ 'user_colour' => $group_row['group_colour'],
+ 'user_email' => '',
+ 'user_lang' => $this->config['default_lang'],
+ 'user_style' => $this->config['default_style'],
+ 'user_timezone' => 0,
+ 'user_dateformat' => $this->config['default_dateformat'],
+ 'user_allow_massemail' => 0,
+ );
+
+ $user_id = user_add($user_row);
+
+ $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $this->db->sql_build_array('INSERT', array(
+ 'bot_active' => 1,
+ 'bot_name' => (string) $bot_name,
+ 'user_id' => (int) $user_id,
+ 'bot_agent' => (string) $bot_agent,
+ 'bot_ip' => (string) $bot_ip,
+ ));
+
+ $this->sql_query($sql);
+ }
+ }
+
+ public function update_bots()
+ {
+ // Update bots
+ if (!function_exists('user_delete'))
+ {
+ include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
+ }
+
+ $bots_updates = array(
+ // Bot Deletions
+ 'NG-Search [Bot]' => false,
+ 'Nutch/CVS [Bot]' => false,
+ 'OmniExplorer [Bot]' => false,
+ 'Seekport [Bot]' => false,
+ 'Synoo [Bot]' => false,
+ 'WiseNut [Bot]' => false,
+
+ // Bot Updates
+ // Bot name to bot user agent map
+ 'Baidu [Spider]' => 'Baiduspider',
+ 'Exabot [Bot]' => 'Exabot',
+ 'Voyager [Bot]' => 'voyager/',
+ 'W3C [Validator]' => 'W3C_Validator',
+ );
+
+ foreach ($bots_updates as $bot_name => $bot_agent)
+ {
+ $sql = 'SELECT user_id
+ FROM ' . USERS_TABLE . '
+ WHERE user_type = ' . USER_IGNORE . "
+ AND username_clean = '" . $this->db->sql_escape(utf8_clean_string($bot_name)) . "'";
+ $result = $this->db->sql_query($sql);
+ $bot_user_id = (int) $this->db->sql_fetchfield('user_id');
+ $this->db->sql_freeresult($result);
+
+ if ($bot_user_id)
+ {
+ if ($bot_agent === false)
+ {
+ $sql = 'DELETE FROM ' . BOTS_TABLE . "
+ WHERE user_id = $bot_user_id";
+ $this->sql_query($sql);
+
+ user_delete('retain', $bot_user_id);
+ }
+ else
+ {
+ $sql = 'UPDATE ' . BOTS_TABLE . "
+ SET bot_agent = '" . $this->db->sql_escape($bot_agent) . "'
+ WHERE user_id = $bot_user_id";
+ $this->sql_query($sql);
+ }
+ }
+ }
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/captcha_plugins.php b/phpBB/phpbb/db/migration/data/v310/captcha_plugins.php
index 13071e9891..328c08f1ec 100644
--- a/phpBB/phpbb/db/migration/data/v310/captcha_plugins.php
+++ b/phpBB/phpbb/db/migration/data/v310/captcha_plugins.php
@@ -25,9 +25,13 @@ class captcha_plugins extends \phpbb\db\migration\migration
public function update_data()
{
$captcha_plugin = $this->config['captcha_plugin'];
- if (strpos($this->config['captcha_plugin'], 'phpbb_captcha_') === 0)
+ if (strpos($captcha_plugin, 'phpbb_captcha_') === 0)
{
- $captcha_plugin = substr($this->config['captcha_plugin'], strlen('phpbb_captcha_'));
+ $captcha_plugin = substr($captcha_plugin, strlen('phpbb_captcha_'));
+ }
+ else if (strpos($captcha_plugin, 'phpbb_') === 0)
+ {
+ $captcha_plugin = substr($captcha_plugin, strlen('phpbb_'));
}
return array(
diff --git a/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php b/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php
index c2dd09ddf6..5736369f1a 100644
--- a/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php
+++ b/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php
@@ -20,6 +20,11 @@ class contact_admin_form extends \phpbb\db\migration\migration
return isset($this->config['contact_admin_form_enable']);
}
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\config_db_text');
+ }
+
public function update_data()
{
return array(
diff --git a/phpBB/phpbb/db/migration/data/v310/gold.php b/phpBB/phpbb/db/migration/data/v310/gold.php
new file mode 100644
index 0000000000..e84c7ee951
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/gold.php
@@ -0,0 +1,32 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class gold extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\rc6',
+ '\phpbb\db\migration\data\v310\bot_update',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/rc6.php b/phpBB/phpbb/db/migration/data/v310/rc6.php
new file mode 100644
index 0000000000..b84f2edcc9
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/rc6.php
@@ -0,0 +1,31 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class rc6 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\rc5',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0-RC6')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php b/phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php
index d5f9076196..8211457dc6 100644
--- a/phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php
+++ b/phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php
@@ -29,7 +29,8 @@ class reset_missing_captcha_plugin extends \phpbb\db\migration\migration
{
return array(
array('if', array(
- (!is_file($this->phpbb_root_path . "includes/captcha/plugins/{$this->config['captcha_plugin']}_plugin." . $this->php_ext)),
+ (is_dir($this->phpbb_root_path . 'includes/captcha/plugins/') &&
+ !is_file($this->phpbb_root_path . "includes/captcha/plugins/{$this->config['captcha_plugin']}_plugin." . $this->php_ext)),
array('config.update', array('captcha_plugin', 'phpbb_captcha_nogd')),
)),
);
diff --git a/phpBB/phpbb/db/migration/data/v31x/m_softdelete_global.php b/phpBB/phpbb/db/migration/data/v31x/m_softdelete_global.php
new file mode 100644
index 0000000000..dd7e20e762
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v31x/m_softdelete_global.php
@@ -0,0 +1,31 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v31x;
+
+class m_softdelete_global extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v31x\v311');
+ }
+
+ public function update_data()
+ {
+ return array(
+ // Make m_softdelete global. The add method will take care of updating
+ // it if it already exists.
+ array('permission.add', array('m_softdelete', true)),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v31x/style_update.php b/phpBB/phpbb/db/migration/data/v31x/style_update.php
new file mode 100644
index 0000000000..bb030bbe6d
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v31x/style_update.php
@@ -0,0 +1,136 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v31x;
+
+class style_update extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\gold');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'update_installed_styles'))),
+ );
+ }
+
+ public function update_installed_styles()
+ {
+ // Get all currently available styles
+ $styles = $this->find_style_dirs();
+ $style_paths = $style_ids = array();
+
+ $sql = 'SELECT style_path, style_id
+ FROM ' . $this->table_prefix . 'styles';
+ $result = $this->db->sql_query($sql);
+ while ($styles_row = $this->db->sql_fetchrow())
+ {
+ if (in_array($styles_row['style_path'], $styles))
+ {
+ $style_paths[] = $styles_row['style_path'];
+ $style_ids[] = $styles_row['style_id'];
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ // Install prosilver if no style is available and prosilver can be installed
+ if (empty($style_paths) && in_array('prosilver', $styles))
+ {
+ // Try to parse config file
+ $cfg = parse_cfg_file($this->phpbb_root_path . 'styles/prosilver/style.cfg');
+
+ // Stop running this if prosilver cfg file can't be read
+ if (empty($cfg))
+ {
+ throw new \RuntimeException('No styles available and could not fall back to prosilver.');
+ }
+
+ $style = array(
+ 'style_name' => 'prosilver',
+ 'style_copyright' => '&copy; phpBB Limited',
+ 'style_active' => 1,
+ 'style_path' => 'prosilver',
+ 'bbcode_bitfield' => 'kNg=',
+ 'style_parent_id' => 0,
+ 'style_parent_tree' => '',
+ );
+
+ // Add to database
+ $this->db->sql_transaction('begin');
+
+ $sql = 'INSERT INTO ' . $this->table_prefix . 'styles
+ ' . $this->db->sql_build_array('INSERT', $style);
+ $this->db->sql_query($sql);
+
+ $style_id = $this->db->sql_nextid();
+ $style_ids[] = $style_id;
+
+ $this->db->sql_transaction('commit');
+
+ // Set prosilver to default style
+ $this->config->set('default_style', $style_id);
+ }
+ else if (empty($styles) && empty($available_styles))
+ {
+ throw new \RuntimeException('No valid styles available');
+ }
+
+ // Make sure default style is available
+ if (!in_array($this->config['default_style'], $style_ids))
+ {
+ $this->config->set('default_style', array_pop($style_ids));
+ }
+
+ // Reset users to default style if their user_style is nonexistent
+ $sql = 'UPDATE ' . $this->table_prefix . "users
+ SET user_style = {$this->config['default_style']}
+ WHERE " . $this->db->sql_in_set('user_style', $style_ids, true, true);
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * Find all directories that have styles
+ * Copied from acp_styles
+ *
+ * @return array Directory names
+ */
+ protected function find_style_dirs()
+ {
+ $styles = array();
+ $styles_path = $this->phpbb_root_path . 'styles/';
+
+ $dp = @opendir($styles_path);
+ if ($dp)
+ {
+ while (($file = readdir($dp)) !== false)
+ {
+ $dir = $styles_path . $file;
+ if ($file[0] == '.' || !is_dir($dir))
+ {
+ continue;
+ }
+
+ if (file_exists("{$dir}/style.cfg"))
+ {
+ $styles[] = $file;
+ }
+ }
+ closedir($dp);
+ }
+
+ return $styles;
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v31x/v311.php b/phpBB/phpbb/db/migration/data/v31x/v311.php
new file mode 100644
index 0000000000..00844dd4c0
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v31x/v311.php
@@ -0,0 +1,32 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v31x;
+
+class v311 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\gold',
+ '\phpbb\db\migration\data\v31x\style_update',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.1')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v31x/v312.php b/phpBB/phpbb/db/migration/data/v31x/v312.php
new file mode 100644
index 0000000000..bf49935f4d
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v31x/v312.php
@@ -0,0 +1,31 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v31x;
+
+class v312 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v31x\v312rc1',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.2')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v31x/v312rc1.php b/phpBB/phpbb/db/migration/data/v31x/v312rc1.php
new file mode 100644
index 0000000000..d4b133fc01
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v31x/v312rc1.php
@@ -0,0 +1,32 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v31x;
+
+class v312rc1 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v31x\v311',
+ '\phpbb\db\migration\data\v31x\m_softdelete_global',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.2-RC1')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php
index 44bea3c5d2..d03496eae3 100644
--- a/phpBB/phpbb/db/migrator.php
+++ b/phpBB/phpbb/db/migrator.php
@@ -59,6 +59,13 @@ class migrator
protected $migrations = array();
/**
+ * Array of migrations that have been determined to be fulfillable
+ *
+ * @var array
+ */
+ protected $fulfillable_migrations = array();
+
+ /**
* 'name,' 'class,' and 'state' of the last migration run
*
* 'effectively_installed' set and set to true if the migration was effectively_installed
@@ -68,6 +75,13 @@ class migrator
public $last_run_migration = false;
/**
+ * The output handler. A null handler is configured by default.
+ *
+ * @var migrator_output_handler
+ */
+ public $output_handler;
+
+ /**
* Constructor of the database migrator
*/
public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper)
@@ -84,6 +98,8 @@ class migrator
$this->table_prefix = $table_prefix;
+ $this->output_handler = new null_migrator_output_handler();
+
foreach ($tools as $tool)
{
$this->tools[$tool->get_name()] = $tool;
@@ -95,6 +111,16 @@ class migrator
}
/**
+ * Set the output handler.
+ *
+ * @param migrator_output_handler $handler The output handler
+ */
+ public function set_output_handler(migrator_output_handler_interface $handler)
+ {
+ $this->output_handler = $handler;
+ }
+
+ /**
* Loads all migrations and their application state from the database.
*
* @return null
@@ -161,6 +187,10 @@ class migrator
return;
}
}
+ else
+ {
+ $this->output_handler->write(array('MIGRATION_EFFECTIVELY_INSTALLED', $name), migrator_output_handler_interface::VERBOSITY_DEBUG);
+ }
}
}
@@ -175,6 +205,7 @@ class migrator
{
if (!class_exists($name))
{
+ $this->output_handler->write(array('MIGRATION_NOT_VALID', $name), migrator_output_handler_interface::VERBOSITY_DEBUG);
return false;
}
@@ -191,6 +222,11 @@ class migrator
'migration_end_time' => 0,
);
+ if (!empty($state['migration_depends_on']))
+ {
+ $this->output_handler->write(array('MIGRATION_APPLY_DEPENDENCIES', $name), migrator_output_handler_interface::VERBOSITY_DEBUG);
+ }
+
foreach ($state['migration_depends_on'] as $depend)
{
if ($this->unfulfillable($depend) !== false)
@@ -227,6 +263,8 @@ class migrator
);
$this->last_run_migration['effectively_installed'] = true;
+
+ $this->output_handler->write(array('MIGRATION_EFFECTIVELY_INSTALLED', $name), migrator_output_handler_interface::VERBOSITY_VERBOSE);
}
else
{
@@ -238,23 +276,43 @@ class migrator
if (!$state['migration_schema_done'])
{
+ $this->output_handler->write(array('MIGRATION_SCHEMA_RUNNING', $name), migrator_output_handler_interface::VERBOSITY_VERBOSE);
+
$this->last_run_migration['task'] = 'process_schema_step';
+ $elapsed_time = microtime(true);
$steps = $this->helper->get_schema_steps($migration->update_schema());
$result = $this->process_data_step($steps, $state['migration_data_state']);
+ $elapsed_time = microtime(true) - $elapsed_time;
$state['migration_data_state'] = ($result === true) ? '' : $result;
$state['migration_schema_done'] = ($result === true);
+
+ $this->output_handler->write(array('MIGRATION_SCHEMA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL);
}
else if (!$state['migration_data_done'])
{
try
{
+ $this->output_handler->write(array('MIGRATION_DATA_RUNNING', $name), migrator_output_handler_interface::VERBOSITY_VERBOSE);
+
$this->last_run_migration['task'] = 'process_data_step';
+
+ $elapsed_time = microtime(true);
$result = $this->process_data_step($migration->update_data(), $state['migration_data_state']);
+ $elapsed_time = microtime(true) - $elapsed_time;
$state['migration_data_state'] = ($result === true) ? '' : $result;
$state['migration_data_done'] = ($result === true);
$state['migration_end_time'] = ($result === true) ? time() : 0;
+
+ if ($state['migration_schema_done'])
+ {
+ $this->output_handler->write(array('MIGRATION_DATA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL);
+ }
+ else
+ {
+ $this->output_handler->write(array('MIGRATION_DATA_IN_PROGRESS', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_VERY_VERBOSE);
+ }
}
catch (\phpbb\db\migration\exception $e)
{
@@ -602,7 +660,7 @@ class migrator
*/
public function unfulfillable($name)
{
- if (isset($this->migration_state[$name]))
+ if (isset($this->migration_state[$name]) || isset($this->fulfillable_migrations[$name]))
{
return false;
}
@@ -623,6 +681,7 @@ class migrator
return $unfulfillable;
}
}
+ $this->fulfillable_migrations[$name] = true;
return false;
}
diff --git a/phpBB/phpbb/db/migrator_output_handler_interface.php b/phpBB/phpbb/db/migrator_output_handler_interface.php
new file mode 100644
index 0000000000..a923af99f6
--- /dev/null
+++ b/phpBB/phpbb/db/migrator_output_handler_interface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db;
+
+interface migrator_output_handler_interface
+{
+ const VERBOSITY_QUIET = 0;
+ const VERBOSITY_NORMAL = 1;
+ const VERBOSITY_VERBOSE = 2;
+ const VERBOSITY_VERY_VERBOSE = 3;
+ const VERBOSITY_DEBUG = 4;
+
+ /**
+ * Write output using the configured closure.
+ *
+ * @param string|array $message The message to write or an array containing the language key and all of its parameters.
+ * @param int $verbosity The verbosity of the message.
+ */
+ public function write($message, $verbosity);
+}
diff --git a/travis/sami.conf.php b/phpBB/phpbb/db/null_migrator_output_handler.php
index 8e7cfa42e9..0e8cfbb049 100644
--- a/travis/sami.conf.php
+++ b/phpBB/phpbb/db/null_migrator_output_handler.php
@@ -11,9 +11,14 @@
*
*/
-require __DIR__ . '/../build/' . basename(__FILE__);
+namespace phpbb\db;
-// Removing the versions array key will make Sami use the current branch.
-unset($config['versions']);
-
-return new Sami\Sami($iterator, $config);
+class null_migrator_output_handler implements migrator_output_handler_interface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function write($message, $verbosity)
+ {
+ }
+}
diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php
index 0781d7425e..c8d25f23a2 100644
--- a/phpBB/phpbb/db/tools.php
+++ b/phpBB/phpbb/db/tools.php
@@ -2643,7 +2643,7 @@ class tools
AND cols.id = ix.id
WHERE ix.id = object_id('{$table_name}')
AND cols.name = '{$column_name}'
- AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique) ? '1' : '0';
+ AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique ? '1' : '0');
}
else
{
@@ -2657,7 +2657,7 @@ class tools
AND cols.object_id = ix.object_id
WHERE ix.object_id = object_id('{$table_name}')
AND cols.name = '{$column_name}'
- AND ix.is_unique = " . ($unique) ? '1' : '0';
+ AND ix.is_unique = " . ($unique ? '1' : '0');
}
break;
diff --git a/phpBB/phpbb/di/extension/config.php b/phpBB/phpbb/di/extension/config.php
index 27ebc94bae..7984a783df 100644
--- a/phpBB/phpbb/di/extension/config.php
+++ b/phpBB/phpbb/di/extension/config.php
@@ -39,16 +39,24 @@ class config extends Extension
*/
public function load(array $config, ContainerBuilder $container)
{
- $container->setParameter('core.adm_relative_path', ($this->config_php->get('phpbb_adm_relative_path') ? $this->config_php->get('phpbb_adm_relative_path') : 'adm/'));
- $container->setParameter('core.table_prefix', $this->config_php->get('table_prefix'));
- $container->setParameter('cache.driver.class', $this->convert_30_acm_type($this->config_php->get('acm_type')));
- $container->setParameter('dbal.driver.class', $this->config_php->convert_30_dbms_to_31($this->config_php->get('dbms')));
- $container->setParameter('dbal.dbhost', $this->config_php->get('dbhost'));
- $container->setParameter('dbal.dbuser', $this->config_php->get('dbuser'));
- $container->setParameter('dbal.dbpasswd', $this->config_php->get('dbpasswd'));
- $container->setParameter('dbal.dbname', $this->config_php->get('dbname'));
- $container->setParameter('dbal.dbport', $this->config_php->get('dbport'));
- $container->setParameter('dbal.new_link', defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK);
+ $parameters = array(
+ 'core.adm_relative_path' => $this->config_php->get('phpbb_adm_relative_path') ? $this->config_php->get('phpbb_adm_relative_path') : 'adm/',
+ 'core.table_prefix' => $this->config_php->get('table_prefix'),
+ 'cache.driver.class' => $this->convert_30_acm_type($this->config_php->get('acm_type')),
+ 'dbal.driver.class' => $this->config_php->convert_30_dbms_to_31($this->config_php->get('dbms')),
+ 'dbal.dbhost' => $this->config_php->get('dbhost'),
+ 'dbal.dbuser' => $this->config_php->get('dbuser'),
+ 'dbal.dbpasswd' => $this->config_php->get('dbpasswd'),
+ 'dbal.dbname' => $this->config_php->get('dbname'),
+ 'dbal.dbport' => $this->config_php->get('dbport'),
+ 'dbal.new_link' => defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK,
+ );
+ $parameter_bag = $container->getParameterBag();
+
+ foreach ($parameters as $parameter => $value)
+ {
+ $container->setParameter($parameter, $parameter_bag->escapeValue($value));
+ }
}
/**
diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php
index edca8ee1af..a64d88fe39 100644
--- a/phpBB/phpbb/extension/metadata_manager.php
+++ b/phpBB/phpbb/extension/metadata_manager.php
@@ -177,6 +177,7 @@ class metadata_manager
throw new \phpbb\extension\exception($this->user->lang('FILE_JSON_DECODE_ERR', $this->metadata_file));
}
+ array_walk_recursive($metadata, array($this, 'sanitize_json'));
$this->metadata = $metadata;
return true;
@@ -184,6 +185,17 @@ class metadata_manager
}
/**
+ * Sanitize input from JSON array using htmlspecialchars()
+ *
+ * @param mixed $value Value of array row
+ * @param string $key Key of array row
+ */
+ public function sanitize_json(&$value, $key)
+ {
+ $value = htmlspecialchars($value);
+ }
+
+ /**
* This array handles the cleaning of the array
*
* @return array Contains the cleaned metadata array
@@ -337,30 +349,30 @@ class metadata_manager
public function output_template_data()
{
$this->template->assign_vars(array(
- 'META_NAME' => htmlspecialchars($this->metadata['name']),
- 'META_TYPE' => htmlspecialchars($this->metadata['type']),
- 'META_DESCRIPTION' => (isset($this->metadata['description'])) ? htmlspecialchars($this->metadata['description']) : '',
+ 'META_NAME' => $this->metadata['name'],
+ 'META_TYPE' => $this->metadata['type'],
+ 'META_DESCRIPTION' => (isset($this->metadata['description'])) ? $this->metadata['description'] : '',
'META_HOMEPAGE' => (isset($this->metadata['homepage'])) ? $this->metadata['homepage'] : '',
- 'META_VERSION' => (isset($this->metadata['version'])) ? htmlspecialchars($this->metadata['version']) : '',
- 'META_TIME' => (isset($this->metadata['time'])) ? htmlspecialchars($this->metadata['time']) : '',
- 'META_LICENSE' => htmlspecialchars($this->metadata['license']),
+ 'META_VERSION' => (isset($this->metadata['version'])) ? $this->metadata['version'] : '',
+ 'META_TIME' => (isset($this->metadata['time'])) ? $this->metadata['time'] : '',
+ 'META_LICENSE' => $this->metadata['license'],
- 'META_REQUIRE_PHP' => (isset($this->metadata['require']['php'])) ? htmlspecialchars($this->metadata['require']['php']) : '',
+ 'META_REQUIRE_PHP' => (isset($this->metadata['require']['php'])) ? $this->metadata['require']['php'] : '',
'META_REQUIRE_PHP_FAIL' => !$this->validate_require_php(),
- 'META_REQUIRE_PHPBB' => (isset($this->metadata['extra']['soft-require']['phpbb/phpbb'])) ? htmlspecialchars($this->metadata['extra']['soft-require']['phpbb/phpbb']) : '',
+ 'META_REQUIRE_PHPBB' => (isset($this->metadata['extra']['soft-require']['phpbb/phpbb'])) ? $this->metadata['extra']['soft-require']['phpbb/phpbb'] : '',
'META_REQUIRE_PHPBB_FAIL' => !$this->validate_require_phpbb(),
- 'META_DISPLAY_NAME' => (isset($this->metadata['extra']['display-name'])) ? htmlspecialchars($this->metadata['extra']['display-name']) : '',
+ 'META_DISPLAY_NAME' => (isset($this->metadata['extra']['display-name'])) ? $this->metadata['extra']['display-name'] : '',
));
foreach ($this->metadata['authors'] as $author)
{
$this->template->assign_block_vars('meta_authors', array(
- 'AUTHOR_NAME' => htmlspecialchars($author['name']),
+ 'AUTHOR_NAME' => $author['name'],
'AUTHOR_EMAIL' => (isset($author['email'])) ? $author['email'] : '',
'AUTHOR_HOMEPAGE' => (isset($author['homepage'])) ? $author['homepage'] : '',
- 'AUTHOR_ROLE' => (isset($author['role'])) ? htmlspecialchars($author['role']) : '',
+ 'AUTHOR_ROLE' => (isset($author['role'])) ? $author['role'] : '',
));
}
}
diff --git a/phpBB/phpbb/file_downloader.php b/phpBB/phpbb/file_downloader.php
new file mode 100644
index 0000000000..d717b394d5
--- /dev/null
+++ b/phpBB/phpbb/file_downloader.php
@@ -0,0 +1,120 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb;
+
+class file_downloader
+{
+ /** @var string Error string */
+ protected $error_string = '';
+
+ /** @var int Error number */
+ protected $error_number = 0;
+
+ /**
+ * Retrieve contents from remotely stored file
+ *
+ * @param string $host File host
+ * @param string $directory Directory file is in
+ * @param string $filename Filename of file to retrieve
+ * @param int $port Port to connect to; default: 80
+ * @param int $timeout Connection timeout in seconds; default: 6
+ *
+ * @return mixed File data as string if file can be read and there is no
+ * timeout, false if there were errors or the connection timed out
+ *
+ * @throws \RuntimeException If data can't be retrieved and no error
+ * message is returned
+ */
+ public function get($host, $directory, $filename, $port = 80, $timeout = 6)
+ {
+ // Set default values for error variables
+ $this->error_number = 0;
+ $this->error_string = '';
+
+ if ($socket = @fsockopen($host, $port, $this->error_number, $this->error_string, $timeout))
+ {
+ @fputs($socket, "GET $directory/$filename HTTP/1.0\r\n");
+ @fputs($socket, "HOST: $host\r\n");
+ @fputs($socket, "Connection: close\r\n\r\n");
+
+ $timer_stop = time() + $timeout;
+ stream_set_timeout($socket, $timeout);
+
+ $file_info = '';
+ $get_info = false;
+
+ while (!@feof($socket))
+ {
+ if ($get_info)
+ {
+ $file_info .= @fread($socket, 1024);
+ }
+ else
+ {
+ $line = @fgets($socket, 1024);
+ if ($line == "\r\n")
+ {
+ $get_info = true;
+ }
+ else if (stripos($line, '404 not found') !== false)
+ {
+ throw new \RuntimeException(array('FILE_NOT_FOUND', $filename));
+ }
+ }
+
+ $stream_meta_data = stream_get_meta_data($socket);
+
+ if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop)
+ {
+ throw new \RuntimeException('FSOCK_TIMEOUT');
+ }
+ }
+ @fclose($socket);
+ }
+ else
+ {
+ if ($this->error_string)
+ {
+ $this->error_string = utf8_convert_message($this->error_string);
+ return false;
+ }
+ else
+ {
+ throw new \RuntimeException('FSOCK_DISABLED');
+ }
+ }
+
+ return $file_info;
+ }
+
+ /**
+ * Get error string
+ *
+ * @return string Error string
+ */
+ public function get_error_string()
+ {
+ return $this->error_string;
+ }
+
+ /**
+ * Get error number
+ *
+ * @return int Error number
+ */
+ public function get_error_number()
+ {
+ return $this->error_number;
+ }
+}
diff --git a/phpBB/phpbb/message/admin_form.php b/phpBB/phpbb/message/admin_form.php
index 93db59880c..96b8d3499e 100644
--- a/phpBB/phpbb/message/admin_form.php
+++ b/phpBB/phpbb/message/admin_form.php
@@ -178,6 +178,7 @@ class admin_form extends form
'S_CONTACT_ADMIN' => true,
'S_CONTACT_FORM' => $this->config['contact_admin_form_enable'],
'S_IS_REGISTERED' => $this->user->data['is_registered'],
+ 'S_POST_ACTION' => append_sid($this->phpbb_root_path . 'memberlist.' . $this->phpEx, 'mode=contactadmin'),
'CONTACT_INFO' => $l_admin_info,
'MESSAGE' => $this->body,
diff --git a/phpBB/phpbb/message/form.php b/phpBB/phpbb/message/form.php
index 076b41dc07..21d4de0b4d 100644
--- a/phpBB/phpbb/message/form.php
+++ b/phpBB/phpbb/message/form.php
@@ -146,7 +146,7 @@ abstract class form
WHERE user_id = ' . $this->user->data['user_id'];
$this->db->sql_query($sql);
- if ($this->cc_sender)
+ if ($this->cc_sender && $this->user->data['is_registered'])
{
$this->message->cc_sender();
}
diff --git a/phpBB/phpbb/message/topic_form.php b/phpBB/phpbb/message/topic_form.php
index 1e0f2a1945..174643bb81 100644
--- a/phpBB/phpbb/message/topic_form.php
+++ b/phpBB/phpbb/message/topic_form.php
@@ -117,7 +117,7 @@ class topic_form extends form
'TOPIC_NAME' => htmlspecialchars_decode($this->topic_row['topic_title']),
'U_TOPIC' => generate_board_url() . '/viewtopic.' . $this->phpEx . '?f=' . $this->topic_row['forum_id'] . '&t=' . $this->topic_id,
));
-
+ $this->message->set_body($this->body);
$this->message->add_recipient(
$this->recipient_name,
$this->recipient_address,
diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php
index 81b450ebbd..dd611e1dd1 100644
--- a/phpBB/phpbb/notification/manager.php
+++ b/phpBB/phpbb/notification/manager.php
@@ -24,6 +24,9 @@ class manager
protected $notification_types;
/** @var array */
+ protected $subscription_types;
+
+ /** @var array */
protected $notification_methods;
/** @var ContainerInterface */
@@ -289,7 +292,7 @@ class manager
WHERE notification_time <= " . (int) $time .
(($notification_type_name !== false) ? ' AND ' .
(is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name)) : '') .
- (($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id) : 'item_parent_id = ' . (int) $item_parent_id) : '') .
+ (($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id, false, true) : 'item_parent_id = ' . (int) $item_parent_id) : '') .
(($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '');
$this->db->sql_query($sql);
}
@@ -524,33 +527,36 @@ class manager
*/
public function get_subscription_types()
{
- $subscription_types = array();
-
- foreach ($this->notification_types as $type_name => $data)
+ if ($this->subscription_types === null)
{
- $type = $this->get_item_type_class($type_name);
+ $this->subscription_types = array();
- if ($type instanceof \phpbb\notification\type\type_interface && $type->is_available())
+ foreach ($this->notification_types as $type_name => $data)
{
- $options = array_merge(array(
- 'id' => $type->get_type(),
- 'lang' => 'NOTIFICATION_TYPE_' . strtoupper($type->get_type()),
- 'group' => 'NOTIFICATION_GROUP_MISCELLANEOUS',
- ), (($type::$notification_option !== false) ? $type::$notification_option : array()));
+ $type = $this->get_item_type_class($type_name);
+
+ if ($type instanceof \phpbb\notification\type\type_interface && $type->is_available())
+ {
+ $options = array_merge(array(
+ 'id' => $type->get_type(),
+ 'lang' => 'NOTIFICATION_TYPE_' . strtoupper($type->get_type()),
+ 'group' => 'NOTIFICATION_GROUP_MISCELLANEOUS',
+ ), (($type::$notification_option !== false) ? $type::$notification_option : array()));
- $subscription_types[$options['group']][$options['id']] = $options;
+ $this->subscription_types[$options['group']][$options['id']] = $options;
+ }
}
- }
- // Move Miscellaneous to the very last section
- if (isset($subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']))
- {
- $miscellaneous = $subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'];
- unset($subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']);
- $subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'] = $miscellaneous;
+ // Move Miscellaneous to the very last section
+ if (isset($this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']))
+ {
+ $miscellaneous = $this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'];
+ unset($this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']);
+ $this->subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS'] = $miscellaneous;
+ }
}
- return $subscription_types;
+ return $this->subscription_types;
}
/**
diff --git a/phpBB/phpbb/notification/type/admin_activate_user.php b/phpBB/phpbb/notification/type/admin_activate_user.php
index 038ca3726e..dfc0157558 100644
--- a/phpBB/phpbb/notification/type/admin_activate_user.php
+++ b/phpBB/phpbb/notification/type/admin_activate_user.php
@@ -131,7 +131,7 @@ class admin_activate_user extends \phpbb\notification\type\base
public function get_email_template_variables()
{
$board_url = generate_board_url();
- $username = $this->user_loader->get_username($this->item_id, 'no_profile');
+ $username = $this->user_loader->get_username($this->item_id, 'username');
return array(
'USERNAME' => htmlspecialchars_decode($username),
diff --git a/phpBB/phpbb/passwords/driver/bcrypt.php b/phpBB/phpbb/passwords/driver/bcrypt.php
index 23add37a56..eab1c3d569 100644
--- a/phpBB/phpbb/passwords/driver/bcrypt.php
+++ b/phpBB/phpbb/passwords/driver/bcrypt.php
@@ -68,7 +68,7 @@ class bcrypt extends base
return false;
}
- if ($hash == $this->hash($password, $salt))
+ if ($this->helper->string_compare($hash, $this->hash($password, $salt)))
{
return true;
}
diff --git a/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php b/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php
index 2d6f897a7b..0eee98d7b7 100644
--- a/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php
+++ b/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php
@@ -78,7 +78,7 @@ class bcrypt_wcf2 extends base
return false;
}
// Works for standard WCF 2.x, i.e. WBB4 and similar
- return $hash === $this->bcrypt->hash($this->bcrypt->hash($password, $salt), $salt);
+ return $this->helper->string_compare($hash, $this->bcrypt->hash($this->bcrypt->hash($password, $salt), $salt));
}
}
}
diff --git a/phpBB/phpbb/passwords/driver/helper.php b/phpBB/phpbb/passwords/driver/helper.php
index 2b3ebce53a..caa65080ac 100644
--- a/phpBB/phpbb/passwords/driver/helper.php
+++ b/phpBB/phpbb/passwords/driver/helper.php
@@ -142,4 +142,24 @@ class helper
}
return $random;
}
+
+ /**
+ * Compare two strings byte by byte
+ *
+ * @param string $string_a The first string
+ * @param string $string_b The second string
+ *
+ * @return bool True if strings are the same, false if not
+ */
+ public function string_compare($string_a, $string_b)
+ {
+ $difference = strlen($string_a) != strlen($string_b);
+
+ for ($i = 0; $i < strlen($string_a) && $i < strlen($string_b); $i++)
+ {
+ $difference |= $string_a[$i] != $string_b[$i];
+ }
+
+ return $difference === 0;
+ }
}
diff --git a/phpBB/phpbb/passwords/driver/md5_mybb.php b/phpBB/phpbb/passwords/driver/md5_mybb.php
index 61ea8dafd8..f631ceae78 100644
--- a/phpBB/phpbb/passwords/driver/md5_mybb.php
+++ b/phpBB/phpbb/passwords/driver/md5_mybb.php
@@ -54,7 +54,7 @@ class md5_mybb extends base
else
{
// Works for myBB 1.1.x, 1.2.x, 1.4.x, 1.6.x
- return $hash === md5(md5($user_row['user_passwd_salt']) . md5($password));
+ return $this->helper->string_compare($hash, md5(md5($user_row['user_passwd_salt']) . md5($password)));
}
}
}
diff --git a/phpBB/phpbb/passwords/driver/md5_phpbb2.php b/phpBB/phpbb/passwords/driver/md5_phpbb2.php
index 86a4b62ea5..bd8cc51e5a 100644
--- a/phpBB/phpbb/passwords/driver/md5_phpbb2.php
+++ b/phpBB/phpbb/passwords/driver/md5_phpbb2.php
@@ -23,6 +23,9 @@ class md5_phpbb2 extends base
/** @var \phpbb\passwords\driver\salted_md5 */
protected $salted_md5;
+ /** @var \phpbb\passwords\driver\helper */
+ protected $helper;
+
/** @var string phpBB root path */
protected $phpbb_root_path;
@@ -34,13 +37,15 @@ class md5_phpbb2 extends base
*
* @param \phpbb\request\request $request phpBB request object
* @param \phpbb\passwords\driver\salted_md5 $salted_md5 Salted md5 driver
+ * @param \phpbb\passwords\driver\helper $helper Driver helper
* @param string $phpbb_root_path phpBB root path
* @param string $php_ext PHP file extension
*/
- public function __construct($request, \phpbb\passwords\driver\salted_md5 $salted_md5, $phpbb_root_path, $php_ext)
+ public function __construct($request, salted_md5 $salted_md5, helper $helper, $phpbb_root_path, $php_ext)
{
$this->request = $request;
$this->salted_md5 = $salted_md5;
+ $this->helper = $helper;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
}
@@ -105,7 +110,7 @@ class md5_phpbb2 extends base
include($this->phpbb_root_path . 'includes/utf/data/recode_basic.' . $this->php_ext);
}
- if (md5($password_old_format) === $hash || md5(\utf8_to_cp1252($password_old_format)) === $hash
+ if ($this->helper->string_compare(md5($password_old_format), $hash) || $this->helper->string_compare(md5(\utf8_to_cp1252($password_old_format)), $hash)
|| $this->salted_md5->check(md5($password_old_format), $hash) === true
|| $this->salted_md5->check(md5(\utf8_to_cp1252($password_old_format)), $hash) === true)
{
diff --git a/phpBB/phpbb/passwords/driver/md5_vb.php b/phpBB/phpbb/passwords/driver/md5_vb.php
index c83c32a596..280b7114c7 100644
--- a/phpBB/phpbb/passwords/driver/md5_vb.php
+++ b/phpBB/phpbb/passwords/driver/md5_vb.php
@@ -54,7 +54,7 @@ class md5_vb extends base
else
{
// Works for vB 3.8.x, 4.x.x, 5.0.x
- return $hash === md5(md5($password) . $user_row['user_passwd_salt']);
+ return $this->helper->string_compare($hash, md5(md5($password) . $user_row['user_passwd_salt']));
}
}
}
diff --git a/phpBB/phpbb/passwords/driver/salted_md5.php b/phpBB/phpbb/passwords/driver/salted_md5.php
index 97a2b9154b..81ac010785 100644
--- a/phpBB/phpbb/passwords/driver/salted_md5.php
+++ b/phpBB/phpbb/passwords/driver/salted_md5.php
@@ -107,7 +107,7 @@ class salted_md5 extends base
return md5($password) === $hash;
}
- return $hash === $this->hash($password, $hash);
+ return $this->helper->string_compare($hash, $this->hash($password, $hash));
}
/**
diff --git a/phpBB/phpbb/passwords/driver/sha1.php b/phpBB/phpbb/passwords/driver/sha1.php
index 0852fd32fc..1abead42cd 100644
--- a/phpBB/phpbb/passwords/driver/sha1.php
+++ b/phpBB/phpbb/passwords/driver/sha1.php
@@ -47,6 +47,6 @@ class sha1 extends base
*/
public function check($password, $hash, $user_row = array())
{
- return (strlen($hash) == 40) ? $hash === sha1($password) : false;
+ return (strlen($hash) == 40) ? $this->helper->string_compare($hash, sha1($password)) : false;
}
}
diff --git a/phpBB/phpbb/passwords/driver/sha1_smf.php b/phpBB/phpbb/passwords/driver/sha1_smf.php
index ec64bd6afb..b30d87265e 100644
--- a/phpBB/phpbb/passwords/driver/sha1_smf.php
+++ b/phpBB/phpbb/passwords/driver/sha1_smf.php
@@ -46,6 +46,6 @@ class sha1_smf extends base
*/
public function check($password, $hash, $user_row = array())
{
- return (strlen($hash) == 40) ? $hash === $this->hash($password, $user_row) : false;
+ return (strlen($hash) == 40) ? $this->helper->string_compare($hash, $this->hash($password, $user_row)) : false;
}
}
diff --git a/phpBB/phpbb/passwords/driver/sha1_wcf1.php b/phpBB/phpbb/passwords/driver/sha1_wcf1.php
index 919fa2bb71..68006486c4 100644
--- a/phpBB/phpbb/passwords/driver/sha1_wcf1.php
+++ b/phpBB/phpbb/passwords/driver/sha1_wcf1.php
@@ -54,7 +54,7 @@ class sha1_wcf1 extends base
else
{
// Works for standard WCF 1.x, i.e. WBB3 and similar
- return $hash === sha1($user_row['user_passwd_salt'] . sha1($user_row['user_passwd_salt'] . sha1($password)));
+ return $this->helper->string_compare($hash, sha1($user_row['user_passwd_salt'] . sha1($user_row['user_passwd_salt'] . sha1($password))));
}
}
}
diff --git a/phpBB/phpbb/passwords/driver/sha_xf1.php b/phpBB/phpbb/passwords/driver/sha_xf1.php
index 7a1ea1450a..9d8f01796e 100644
--- a/phpBB/phpbb/passwords/driver/sha_xf1.php
+++ b/phpBB/phpbb/passwords/driver/sha_xf1.php
@@ -54,8 +54,8 @@ class sha_xf1 extends base
else
{
// Works for xenforo 1.0, 1.1
- if ($hash === sha1(sha1($password) . $user_row['user_passwd_salt'])
- || $hash === hash('sha256', hash('sha256', $password) . $user_row['user_passwd_salt']))
+ if ($this->helper->string_compare($hash, sha1(sha1($password) . $user_row['user_passwd_salt']))
+ || $this->helper->string_compare($hash, hash('sha256', hash('sha256', $password) . $user_row['user_passwd_salt'])))
{
return true;
}
diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php
index 936564d8b6..b49d8d13c2 100644
--- a/phpBB/phpbb/path_helper.php
+++ b/phpBB/phpbb/path_helper.php
@@ -154,6 +154,7 @@ class path_helper
return $this->web_root_path;
}
+ // We do not need to escape $path_info, $request_uri and $script_name because we can not find their content in the result.
// Path info (e.g. /foo/bar)
$path_info = $this->filesystem->clean_path($this->symfony_request->getPathInfo());
@@ -203,9 +204,12 @@ class path_helper
*/
if ($this->request->is_ajax() && $this->symfony_request->get('_referer'))
{
+ // We need to escape $absolute_board_url because it can be partially concatenated to the result.
+ $absolute_board_url = $this->request->escape($this->symfony_request->getSchemeAndHttpHost() . $this->symfony_request->getBasePath(), true);
+
$referer_web_root_path = $this->get_web_root_path_from_ajax_referer(
$this->symfony_request->get('_referer'),
- $this->symfony_request->getSchemeAndHttpHost() . $this->symfony_request->getBasePath()
+ $absolute_board_url
);
return $this->web_root_path = $this->phpbb_root_path . $referer_web_root_path;
}
@@ -278,10 +282,16 @@ class path_helper
$referer_dir = dirname($referer_dir);
}
- while (strpos($absolute_board_url, $referer_dir) !== 0)
+ while (($dir_position = strpos($absolute_board_url, $referer_dir)) !== 0)
{
$fixed_root_path .= '../';
$referer_dir = dirname($referer_dir);
+
+ // Just return phpbb_root_path if we reach the top directory
+ if ($referer_dir === '.')
+ {
+ return $this->phpbb_root_path;
+ }
}
$fixed_root_path .= substr($absolute_board_url, strlen($referer_dir) + 1);
diff --git a/phpBB/phpbb/profilefields/type/type_base.php b/phpBB/phpbb/profilefields/type/type_base.php
index 52f5d15511..9b4bada26d 100644
--- a/phpBB/phpbb/profilefields/type/type_base.php
+++ b/phpBB/phpbb/profilefields/type/type_base.php
@@ -158,7 +158,19 @@ abstract class type_base implements type_interface
}
else
{
- return $this->request->variable($key, '', true);
+ $default_value = '';
+ $lang_fields = array(
+ 'l_lang_name',
+ 'l_lang_explain',
+ 'l_lang_default_value',
+ 'l_lang_options',
+ );
+
+ if (in_array($key, $lang_fields))
+ {
+ $default_value = array(0 => '');
+ }
+ return $this->request->variable($key, $default_value, true);
}
}
diff --git a/phpBB/phpbb/profilefields/type/type_bool.php b/phpBB/phpbb/profilefields/type/type_bool.php
index 0582722833..75934e3be7 100644
--- a/phpBB/phpbb/profilefields/type/type_bool.php
+++ b/phpBB/phpbb/profilefields/type/type_bool.php
@@ -352,7 +352,7 @@ class type_bool extends type_base
}
}
- if ($step == 3 && ($field_data[$key] || $action != 'edit') && $key == 'l_lang_options')
+ if ($key == 'l_lang_options' && $this->request->is_set($key))
{
$field_data[$key] = $this->request->variable($key, array(0 => array('')), true);
diff --git a/phpBB/phpbb/request/request.php b/phpBB/phpbb/request/request.php
index ea9854894c..f0f2f7e2a2 100644
--- a/phpBB/phpbb/request/request.php
+++ b/phpBB/phpbb/request/request.php
@@ -416,4 +416,27 @@ class request implements \phpbb\request\request_interface
{
return $this->input[$super_global];
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function escape($var, $multibyte)
+ {
+ if (is_array($var))
+ {
+ $result = array();
+ foreach ($var as $key => $value)
+ {
+ $this->type_cast_helper->set_var($key, $key, gettype($key), $multibyte);
+ $result[$key] = $this->escape($value, $multibyte);
+ }
+ $var = $result;
+ }
+ else
+ {
+ $this->type_cast_helper->set_var($var, $var, 'string', $multibyte);
+ }
+
+ return $var;
+ }
}
diff --git a/phpBB/phpbb/request/request_interface.php b/phpBB/phpbb/request/request_interface.php
index 3236f73990..47b3b3a4ed 100644
--- a/phpBB/phpbb/request/request_interface.php
+++ b/phpBB/phpbb/request/request_interface.php
@@ -142,4 +142,14 @@ interface request_interface
* @return array The original array of the requested super global.
*/
public function get_super_global($super_global = \phpbb\request\request_interface::REQUEST);
+
+ /**
+ * Escape a string variable.
+ *
+ * @param mixed $value The contents to fill with
+ * @param bool $multibyte Indicates whether string values may contain UTF-8 characters.
+ * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks.
+ * @return string|array
+ */
+ public function escape($value, $multibyte);
}
diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php
index 098c69c636..691d0d5bef 100644
--- a/phpBB/phpbb/session.php
+++ b/phpBB/phpbb/session.php
@@ -31,10 +31,11 @@ class session
var $update_session_page = true;
/**
- * Extract current session page
- *
- * @param string $root_path current root path (phpbb_root_path)
- */
+ * Extract current session page
+ *
+ * @param string $root_path current root path (phpbb_root_path)
+ * @return array
+ */
static function extract_current_page($root_path)
{
global $request, $symfony_request, $phpbb_filesystem;
@@ -42,8 +43,8 @@ class session
$page_array = array();
// First of all, get the request uri...
- $script_name = $symfony_request->getScriptName();
- $args = explode('&', $symfony_request->getQueryString());
+ $script_name = $request->escape($symfony_request->getScriptName(), true);
+ $args = $request->escape(explode('&', $symfony_request->getQueryString()), true);
// If we are unable to get the script name we use REQUEST_URI as a failover and note it within the page array for easier support...
if (!$script_name)
@@ -61,8 +62,8 @@ class session
// Since some browser do not encode correctly we need to do this with some "special" characters...
// " -> %22, ' => %27, < -> %3C, > -> %3E
- $find = array('"', "'", '<', '>');
- $replace = array('%22', '%27', '%3C', '%3E');
+ $find = array('"', "'", '<', '>', '&quot;', '&lt;', '&gt;');
+ $replace = array('%22', '%27', '%3C', '%3E', '%22', '%3C', '%3E');
foreach ($args as $key => $argument)
{
@@ -87,7 +88,7 @@ class session
$symfony_request_path = $phpbb_filesystem->clean_path($symfony_request->getPathInfo());
if ($symfony_request_path !== '/')
{
- $page_name .= $symfony_request_path;
+ $page_name .= str_replace('%2F', '/', urlencode($symfony_request_path));
}
// current directory within the phpBB root (for example: adm)
@@ -577,6 +578,43 @@ class session
}
}
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+ $provider = $provider_collection->get_provider();
+ $this->data = $provider->autologin();
+
+ if ($user_id !== false && sizeof($this->data) && $this->data['user_id'] != $user_id)
+ {
+ $this->data = array();
+ }
+
+ if (sizeof($this->data))
+ {
+ $this->cookie_data['k'] = '';
+ $this->cookie_data['u'] = $this->data['user_id'];
+ }
+
+ // If we're presented with an autologin key we'll join against it.
+ // Else if we've been passed a user_id we'll grab data based on that
+ if (isset($this->cookie_data['k']) && $this->cookie_data['k'] && $this->cookie_data['u'] && !sizeof($this->data))
+ {
+ $sql = 'SELECT u.*
+ FROM ' . USERS_TABLE . ' u, ' . SESSIONS_KEYS_TABLE . ' k
+ WHERE u.user_id = ' . (int) $this->cookie_data['u'] . '
+ AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ")
+ AND k.user_id = u.user_id
+ AND k.key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'";
+ $result = $db->sql_query($sql);
+ $user_data = $db->sql_fetchrow($result);
+
+ if ($user_id === false || (isset($user_data['user_id']) && $user_id == $user_data['user_id']))
+ {
+ $this->data = $user_data;
+ $bot = false;
+ }
+
+ $db->sql_freeresult($result);
+ }
+
if ($user_id !== false && !sizeof($this->data))
{
$this->cookie_data['k'] = '';
@@ -591,34 +629,6 @@ class session
$db->sql_freeresult($result);
$bot = false;
}
- else if (!$bot)
- {
- $provider_collection = $phpbb_container->get('auth.provider_collection');
- $provider = $provider_collection->get_provider();
- $this->data = $provider->autologin();
-
- if (sizeof($this->data))
- {
- $this->cookie_data['k'] = '';
- $this->cookie_data['u'] = $this->data['user_id'];
- }
-
- // If we're presented with an autologin key we'll join against it.
- // Else if we've been passed a user_id we'll grab data based on that
- if (isset($this->cookie_data['k']) && $this->cookie_data['k'] && $this->cookie_data['u'] && !sizeof($this->data))
- {
- $sql = 'SELECT u.*
- FROM ' . USERS_TABLE . ' u, ' . SESSIONS_KEYS_TABLE . ' k
- WHERE u.user_id = ' . (int) $this->cookie_data['u'] . '
- AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ")
- AND k.user_id = u.user_id
- AND k.key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'";
- $result = $db->sql_query($sql);
- $this->data = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
- $bot = false;
- }
- }
// Bot user, if they have a SID in the Request URI we need to get rid of it
// otherwise they'll index this page with the SID, duplicate content oh my!
diff --git a/phpBB/phpbb/symfony_request.php b/phpBB/phpbb/symfony_request.php
index bf9ddec493..2931cae3cc 100644
--- a/phpBB/phpbb/symfony_request.php
+++ b/phpBB/phpbb/symfony_request.php
@@ -15,6 +15,10 @@ namespace phpbb;
use Symfony\Component\HttpFoundation\Request;
+/**
+ * WARNING: The Symfony request does not escape the input and should be used very carefully
+ * prefer the phpbb request as possible
+ */
class symfony_request extends Request
{
/**
@@ -24,21 +28,12 @@ class symfony_request extends Request
*/
public function __construct(\phpbb\request\request_interface $phpbb_request)
{
- // This function is meant to sanitize the global input arrays
- $sanitizer = function(&$value, $key) {
- $type_cast_helper = new \phpbb\request\type_cast_helper();
- $type_cast_helper->set_var($value, $value, gettype($value), true);
- };
-
$get_parameters = $phpbb_request->get_super_global(\phpbb\request\request_interface::GET);
$post_parameters = $phpbb_request->get_super_global(\phpbb\request\request_interface::POST);
$server_parameters = $phpbb_request->get_super_global(\phpbb\request\request_interface::SERVER);
$files_parameters = $phpbb_request->get_super_global(\phpbb\request\request_interface::FILES);
$cookie_parameters = $phpbb_request->get_super_global(\phpbb\request\request_interface::COOKIE);
- array_walk_recursive($get_parameters, $sanitizer);
- array_walk_recursive($post_parameters, $sanitizer);
-
parent::__construct($get_parameters, $post_parameters, array(), $cookie_parameters, $files_parameters, $server_parameters);
}
}
diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php
index a3b002f350..5b71bb5e8a 100644
--- a/phpBB/phpbb/template/twig/twig.php
+++ b/phpBB/phpbb/template/twig/twig.php
@@ -189,13 +189,24 @@ class twig extends \phpbb\template\base
{
$path = $this->phpbb_root_path . trim($directory, '/') . "/{$name}/";
$template_path = $path . 'template/';
+ $theme_path = $path . 'theme/';
+ $is_valid_dir = false;
if (is_dir($template_path))
{
+ $is_valid_dir = true;
+ $paths[] = $template_path;
+ }
+ if (is_dir($theme_path))
+ {
+ $is_valid_dir = true;
+ $paths[] = $theme_path;
+ }
+
+ if ($is_valid_dir)
+ {
// Add the base style directory as a safe directory
$this->twig->getLoader()->addSafeDirectory($path);
-
- $paths[] = $template_path;
}
}
}
@@ -253,25 +264,38 @@ class twig extends \phpbb\template\base
{
$ext_style_template_path = $ext_path . $template_dir['ext_path'];
$ext_style_path = dirname($ext_style_template_path);
+ $ext_style_theme_path = $ext_style_path . 'theme/';
}
else
{
$ext_style_path = $ext_path . 'styles/' . $template_dir['name'] . '/';
$ext_style_template_path = $ext_style_path . 'template/';
+ $ext_style_theme_path = $ext_style_path . 'theme/';
}
}
else
{
$ext_style_path = $ext_path . 'styles/' . $template_dir . '/';
$ext_style_template_path = $ext_style_path . 'template/';
+ $ext_style_theme_path = $ext_style_path . 'theme/';
}
+ $ok = false;
if (is_dir($ext_style_template_path))
{
+ $ok = true;
+ $paths[] = $ext_style_template_path;
+ }
+ if (is_dir($ext_style_theme_path))
+ {
+ $ok = true;
+ $paths[] = $ext_style_theme_path;
+ }
+
+ if ($ok)
+ {
// Add the base style directory as a safe directory
$this->twig->getLoader()->addSafeDirectory($ext_style_path);
-
- $paths[] = $ext_style_template_path;
}
}
diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php
index 968a57428f..7387ad296e 100644
--- a/phpBB/phpbb/version_helper.php
+++ b/phpBB/phpbb/version_helper.php
@@ -50,6 +50,9 @@ class version_helper
/** @var \phpbb\config\config */
protected $config;
+ /** @var \phpbb\file_downloader */
+ protected $file_downloader;
+
/** @var \phpbb\user */
protected $user;
@@ -58,12 +61,14 @@ class version_helper
*
* @param \phpbb\cache\service $cache
* @param \phpbb\config\config $config
+ * @param \phpbb\file_downloader $file_downloader
* @param \phpbb\user $user
*/
- public function __construct(\phpbb\cache\service $cache, \phpbb\config\config $config, \phpbb\user $user)
+ public function __construct(\phpbb\cache\service $cache, \phpbb\config\config $config, \phpbb\file_downloader $file_downloader, \phpbb\user $user)
{
$this->cache = $cache;
$this->config = $config;
+ $this->file_downloader = $file_downloader;
$this->user = $user;
if (defined('PHPBB_QA'))
@@ -239,7 +244,7 @@ class version_helper
*/
public function get_versions($force_update = false, $force_cache = false)
{
- $cache_file = 'versioncheck_' . $this->host . $this->path . $this->file;
+ $cache_file = '_versioncheck_' . $this->host . $this->path . $this->file;
$info = $this->cache->get($cache_file);
@@ -249,16 +254,32 @@ class version_helper
}
else if ($info === false || $force_update)
{
- $errstr = $errno = '';
- $info = get_remote_file($this->host, $this->path, $this->file, $errstr, $errno);
+ try {
+ $info = $this->file_downloader->get($this->host, $this->path, $this->file);
+ }
+ catch (\RuntimeException $exception)
+ {
+ throw new \RuntimeException(call_user_func_array(array($this->user, 'lang'), $exception->getMessage()));
+ }
+ $error_string = $this->file_downloader->get_error_string();
- if (!empty($errstr))
+ if (!empty($error_string))
{
- throw new \RuntimeException($errstr);
+ throw new \RuntimeException($error_string);
}
$info = json_decode($info, true);
+ // Sanitize any data we retrieve from a server
+ if (!empty($info))
+ {
+ $json_sanitizer = function (&$value, $key) {
+ $type_cast_helper = new \phpbb\request\type_cast_helper();
+ $type_cast_helper->set_var($value, $value, gettype($value), true);
+ };
+ array_walk_recursive($info, $json_sanitizer);
+ }
+
if (empty($info['stable']) && empty($info['unstable']))
{
$this->user->add_lang('acp/common');
@@ -266,15 +287,6 @@ class version_helper
throw new \RuntimeException($this->user->lang('VERSIONCHECK_FAIL'));
}
- // Replace & with &amp; on announcement links
- foreach ($info as $stability => $branches)
- {
- foreach ($branches as $branch => $branch_data)
- {
- $info[$stability][$branch]['announcement'] = str_replace('&', '&amp;', $branch_data['announcement']);
- }
- }
-
$info['stable'] = (empty($info['stable'])) ? array() : $info['stable'];
$info['unstable'] = (empty($info['unstable'])) ? $info['stable'] : $info['unstable'];
diff --git a/phpBB/posting.php b/phpBB/posting.php
index 764a16d386..dda7455845 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -73,7 +73,6 @@ $current_time = time();
* @var bool preview Whether or not the post is being previewed
* @var bool save Whether or not a draft is being saved
* @var bool load Whether or not a draft is being loaded
-* @var bool delete Whether or not the post is being deleted
* @var bool cancel Whether or not to cancel the form (returns to
* viewtopic or viewforum depending on if the user
* is posting a new topic or editing a post)
@@ -85,6 +84,7 @@ $current_time = time();
* NOTE: Should be actual language strings, NOT
* language keys.
* @since 3.1.0-a1
+* @change 3.1.2-RC1 Removed 'delete' var as it does not exist
*/
$vars = array(
'post_id',
@@ -96,7 +96,6 @@ $vars = array(
'preview',
'save',
'load',
- 'delete',
'cancel',
'refresh',
'mode',
@@ -870,6 +869,43 @@ if ($submit || $preview || $refresh)
// Parse Attachments - before checksum is calculated
$message_parser->parse_attachments('fileupload', $mode, $forum_id, $submit, $preview, $refresh);
+ /**
+ * This event allows you to modify message text before parsing
+ *
+ * @event core.posting_modify_message_text
+ * @var array post_data Array with post data
+ * @var string mode What action to take if the form is submitted
+ * post|reply|quote|edit|delete|bump|smilies|popup
+ * @var int post_id ID of the post
+ * @var int topic_id ID of the topic
+ * @var int forum_id ID of the forum
+ * @var bool submit Whether or not the form has been submitted
+ * @var bool preview Whether or not the post is being previewed
+ * @var bool save Whether or not a draft is being saved
+ * @var bool load Whether or not a draft is being loaded
+ * @var bool cancel Whether or not to cancel the form (returns to
+ * viewtopic or viewforum depending on if the user
+ * is posting a new topic or editing a post)
+ * @var bool refresh Whether or not to retain previously submitted data
+ * @var object message_parser The message parser object
+ * @since 3.1.2-RC1
+ */
+ $vars = array(
+ 'post_data',
+ 'mode',
+ 'post_id',
+ 'topic_id',
+ 'forum_id',
+ 'submit',
+ 'preview',
+ 'save',
+ 'load',
+ 'cancel',
+ 'refresh',
+ 'message_parser',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.posting_modify_message_text', compact($vars)));
+
// Grab md5 'checksum' of new message
$message_md5 = md5($message_parser->message);
@@ -1125,7 +1161,7 @@ if ($submit || $preview || $refresh)
break;
}
- if (!$auth->acl_get($auth_option, $forum_id))
+ if ($auth_option != '' && !$auth->acl_get($auth_option, $forum_id))
{
// There is a special case where a user edits his post whereby the topic type got changed by an admin/mod.
// Another case would be a mod not having sticky permissions for example but edit permissions.
@@ -1727,7 +1763,6 @@ $page_data = array(
* @var bool preview Whether or not the post is being previewed
* @var bool save Whether or not a draft is being saved
* @var bool load Whether or not a draft is being loaded
-* @var bool delete Whether or not the post is being deleted
* @var bool cancel Whether or not to cancel the form (returns to
* viewtopic or viewforum depending on if the user
* is posting a new topic or editing a post)
@@ -1744,6 +1779,7 @@ $page_data = array(
* s_topic_icons, form_enctype, s_action, s_hidden_fields,
* post_id, topic_id, forum_id, submit, preview, save, load,
* delete, cancel, refresh, error, page_data, message_parser
+* @change 3.1.2-RC1 Removed 'delete' var as it does not exist
*/
$vars = array(
'post_data',
@@ -1761,7 +1797,6 @@ $vars = array(
'preview',
'save',
'load',
- 'delete',
'cancel',
'refresh',
'error',
diff --git a/phpBB/search.php b/phpBB/search.php
index 0d269c5606..e80a89b382 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -922,7 +922,7 @@ if ($keywords || $author || $author_id || $search_id || $submit)
$posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $forum_id)) ? true : false;
$topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
$u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . "&amp;t=$result_topic_id", true, $user->session_id) : '';
- $u_mcp_queue = (!$u_mcp_queue && $topic_deleted) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;mode=deleted_topics&amp;t=$result_topic_id", true, $user->session_id) : '';
+ $u_mcp_queue = (!$u_mcp_queue && $topic_deleted) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;mode=deleted_topics&amp;t=$result_topic_id", true, $user->session_id) : $u_mcp_queue;
$row['topic_title'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#is', '<span class="posthilit">$1</span>', $row['topic_title']);
diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg
index 8853bd4382..41e0d68714 100644
--- a/phpBB/styles/prosilver/style.cfg
+++ b/phpBB/styles/prosilver/style.cfg
@@ -21,8 +21,8 @@
# General Information about this style
name = prosilver
copyright = © phpBB Limited, 2007
-style_version = 3.1.0-RC5
-phpbb_version = 3.1.0-RC5
+style_version = 3.1.2
+phpbb_version = 3.1.2
# Defining a different template bitfield
# template_bitfield = lNg=
diff --git a/phpBB/styles/prosilver/template/confirm_delete_body.html b/phpBB/styles/prosilver/template/confirm_delete_body.html
index f164b5f357..f0a7ab2bdb 100644
--- a/phpBB/styles/prosilver/template/confirm_delete_body.html
+++ b/phpBB/styles/prosilver/template/confirm_delete_body.html
@@ -2,6 +2,7 @@
<form action="{S_CONFIRM_ACTION}" method="post">
<p>{MESSAGE_TEXT}</p>
+ <!-- IF not S_SHADOW_TOPICS -->
<!-- IF not S_SOFTDELETED and S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE -->
<label>
<strong>{L_DELETE_PERMANENTLY}{L_COLON}</strong>
@@ -14,6 +15,7 @@
<strong>{L_DELETE_REASON}{L_COLON}</strong><br /><span>{L_DELETE_REASON_EXPLAIN}</span><br />
<input type="text" name="delete_reason" value="" class="inputbox autowidth" maxlength="120" size="45" />
</label>
+ <!-- ENDIF -->
<fieldset class="submit-buttons">
<input type="button" name="confirm" value="{L_YES}" class="button1" />&nbsp;
@@ -33,6 +35,7 @@
<p>{MESSAGE_TEXT}</p>
+ <!-- IF not S_SHADOW_TOPICS -->
<fieldset class="fields1">
<!-- IF not S_SOFTDELETED and S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE -->
<dl>
@@ -51,6 +54,7 @@
<dd><input type="text" name="delete_reason" id="delete_reason" value="" class="inputbox autowidth" maxlength="120" size="45" /></dd>
</dl>
</fieldset>
+ <!-- ENDIF -->
<fieldset class="submit-buttons">
{S_HIDDEN_FIELDS}
diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html
index c90f5b0639..3e7a2cd102 100644
--- a/phpBB/styles/prosilver/template/forumlist_body.html
+++ b/phpBB/styles/prosilver/template/forumlist_body.html
@@ -80,6 +80,8 @@
{L_POST_BY_AUTHOR} {forumrow.LAST_POSTER_FULL}
<!-- IF not S_IS_BOT --><a href="{forumrow.U_LAST_POST}">{LAST_POST_IMG}</a> <!-- ENDIF --><br />{forumrow.LAST_POST_TIME}<!-- ELSE -->{L_NO_POSTS}<br />&nbsp;<!-- ENDIF --></span>
</dd>
+ <!-- ELSE -->
+ <dd>&nbsp;</dd>
<!-- ENDIF -->
</dl>
<!-- EVENT forumlist_body_forum_row_append -->
diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html
index 1e1eb22c6f..f620b6e966 100644
--- a/phpBB/styles/prosilver/template/index_body.html
+++ b/phpBB/styles/prosilver/template/index_body.html
@@ -13,6 +13,8 @@
<!-- INCLUDE forumlist_body.html -->
+<!-- EVENT index_body_forumlist_body_after -->
+
<!-- IF not S_USER_LOGGED_IN and not S_IS_BOT -->
<form method="post" action="{S_LOGIN_ACTION}" class="headerspace">
<h3><a href="{U_LOGIN_LOGOUT}">{L_LOGIN_LOGOUT}</a><!-- IF S_REGISTER_ENABLED -->&nbsp; &bull; &nbsp;<a href="{U_REGISTER}">{L_REGISTER}</a><!-- ENDIF --></h3>
diff --git a/phpBB/styles/prosilver/template/memberlist_email.html b/phpBB/styles/prosilver/template/memberlist_email.html
index 865f0b883c..1bfd83e3a1 100644
--- a/phpBB/styles/prosilver/template/memberlist_email.html
+++ b/phpBB/styles/prosilver/template/memberlist_email.html
@@ -77,10 +77,12 @@
<span>{L_EMAIL_BODY_EXPLAIN}</span></dt>
<dd><textarea class="inputbox" name="message" id="message" rows="15" cols="76" tabindex="4">{MESSAGE}</textarea></dd>
</dl>
+ <!-- IF S_REGISTERED_USER -->
<dl>
<dt>&nbsp;</dt>
- <dd><label for="cc_email"><input type="checkbox" name="cc_email" id="cc_email" value="1" checked="checked" tabindex="5" /> {L_CC_EMAIL}</label></dd>
+ <dd><label for="cc_sender"><input type="checkbox" name="cc_sender" id="cc_sender" value="1" checked="checked" tabindex="5" /> {L_CC_SENDER}</label></dd>
</dl>
+ <!-- ENDIF -->
</fieldset>
</div>
diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html
index 4fba966151..ef5d29a8fa 100644
--- a/phpBB/styles/prosilver/template/memberlist_search.html
+++ b/phpBB/styles/prosilver/template/memberlist_search.html
@@ -6,6 +6,7 @@
<p>{L_FIND_USERNAME_EXPLAIN}</p>
+ <!-- EVENT memberlist_search_fields_before -->
<fieldset class="fields1 column1">
<dl style="overflow: visible;">
<dt><label for="username">{L_USERNAME}{L_COLON}</label></dt>
@@ -39,6 +40,7 @@
<dt><label for="search_group_id">{L_GROUP}{L_COLON}</label></dt>
<dd><select name="search_group_id" id="search_group_id">{S_GROUP_SELECT}</select></dd>
</dl>
+ <!-- EVENT memberlist_search_sorting_options_before -->
<dl>
<dt><label for="sk" class="label3">{L_SORT_BY}{L_COLON}</label></dt>
<dd><select name="sk" id="sk">{S_SORT_OPTIONS}</select> <select name="sd">{S_ORDER_SELECT}</select></dd>
@@ -66,6 +68,7 @@
<dd><input class="inputbox medium" type="text" name="ip" id="ip" value="{IP}" /></dd>
</dl>
<!-- ENDIF -->
+ <!-- EVENT memberlist_search_fields_after -->
</fieldset>
<div class="clear"></div>
diff --git a/phpBB/styles/prosilver/template/posting_buttons.html b/phpBB/styles/prosilver/template/posting_buttons.html
index 3dad6606bb..1555b12369 100644
--- a/phpBB/styles/prosilver/template/posting_buttons.html
+++ b/phpBB/styles/prosilver/template/posting_buttons.html
@@ -92,6 +92,9 @@
<!-- ENDIF -->
</select>
<input type="button" class="button2 bbcode-color" name="bbpalette" id="bbpalette" value="{L_FONT_COLOR}" onclick="change_palette();" title="{L_BBCODE_S_HELP}" />
+
+ <!-- EVENT posting_editor_buttons_custom_tags_before -->
+
<!-- BEGIN custom_tags -->
<input type="button" class="button2 bbcode-{custom_tags.BBCODE_TAG_CLEAN}" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})" title="{custom_tags.BBCODE_HELPLINE}" />
<!-- END custom_tags -->
diff --git a/phpBB/styles/prosilver/template/ucp_pm_message_header.html b/phpBB/styles/prosilver/template/ucp_pm_message_header.html
index d777de908d..7be51e0034 100644
--- a/phpBB/styles/prosilver/template/ucp_pm_message_header.html
+++ b/phpBB/styles/prosilver/template/ucp_pm_message_header.html
@@ -48,6 +48,7 @@
<!-- IF S_VIEW_MESSAGE -->
<a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_CURRENT_FOLDER}">{L_RETURN_TO_FOLDER}</a>
<!-- ELSEIF FOLDER_CUR_MESSAGES neq 0 -->
+ <!-- IF U_MARK_ALL --><a href="{U_MARK_ALL}" class="mark">{L_PM_MARK_ALL_READ}</a> &bull; <!-- ENDIF -->
{TOTAL_MESSAGES}
<!-- IF .pagination -->
<!-- INCLUDE pagination.html -->
diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html
index 8a6ea1a0bb..02c5f5b1a5 100644
--- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html
+++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html
@@ -29,7 +29,7 @@
<!-- IF RANK_TITLE or RANK_IMG --><dd class="profile-rank">{RANK_TITLE}<!-- IF RANK_TITLE and RANK_IMG --><br /><!-- ENDIF -->{RANK_IMG}</dd><!-- ENDIF -->
- <dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> {AUTHOR_POSTS}</dd>
+ <dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> <!-- IF U_AUTHOR_POSTS != '' --><a href="{U_AUTHOR_POSTS}">{AUTHOR_POSTS}</a><!-- ELSE -->{AUTHOR_POSTS}<!-- ENDIF --></dd>
<!-- IF AUTHOR_JOINED --><dd class="profile-joined"><strong>{L_JOINED}{L_COLON}</strong> {AUTHOR_JOINED}</dd><!-- ENDIF -->
<!-- EVENT ucp_pm_viewmessage_custom_fields_before -->
diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css
index adcd04b15e..9da24b6ef9 100644
--- a/phpBB/styles/prosilver/theme/common.css
+++ b/phpBB/styles/prosilver/theme/common.css
@@ -601,7 +601,7 @@ ul.linklist.bulletin > li.no-bulletin:before {
}
.breadcrumbs .crumb:before {
- content: '‹';
+ content: '\2039';
font-weight: bold;
padding: 0 0.5em;
}
diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css
index 9388496c53..4768309c29 100644
--- a/phpBB/styles/prosilver/theme/content.css
+++ b/phpBB/styles/prosilver/theme/content.css
@@ -497,7 +497,7 @@ blockquote.uncited {
text-transform: uppercase;
border-bottom: 1px solid transparent;
margin-bottom: 3px;
- font-size: 0.8em;
+ font-size: 0.8em !important;
font-weight: bold;
display: block;
}
diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css
index 014bb91e7a..81b6d9bf64 100644
--- a/phpBB/styles/prosilver/theme/cp.css
+++ b/phpBB/styles/prosilver/theme/cp.css
@@ -59,10 +59,6 @@ ul.cplist {
border-bottom: none;
}
-#cp-main .postbody p {
- font-size: 1.1em;
-}
-
#cp-main .pm-message {
border: 1px solid transparent;
margin: 10px 0;
@@ -78,6 +74,10 @@ ul.cplist {
margin-top: 0;
}
+.panel-container .postbody p.author {
+ font-size: 1.1em;
+}
+
#cp-main .buttons {
margin-left: 0;
}
diff --git a/phpBB/styles/subsilver2/style.cfg b/phpBB/styles/subsilver2/style.cfg
index b8de165608..6014b89e66 100644
--- a/phpBB/styles/subsilver2/style.cfg
+++ b/phpBB/styles/subsilver2/style.cfg
@@ -21,8 +21,8 @@
# General Information about this style
name = subsilver2
copyright = © 2005 phpBB Limited
-style_version = 3.1.0-RC5
-phpbb_version = 3.1.0-RC5
+style_version = 3.1.2
+phpbb_version = 3.1.2
# Defining a different template bitfield
# template_bitfield = lNg=
diff --git a/phpBB/styles/subsilver2/template/confirm_delete_body.html b/phpBB/styles/subsilver2/template/confirm_delete_body.html
index 18df397fc3..44aec9b60a 100644
--- a/phpBB/styles/subsilver2/template/confirm_delete_body.html
+++ b/phpBB/styles/subsilver2/template/confirm_delete_body.html
@@ -14,6 +14,7 @@
<p class="gen">{MESSAGE_TEXT}</p>
<br />
+ <!-- IF not S_SHADOW_TOPICS -->
<table border="0" width="90%" cellspacing="2" cellpadding="1">
<!-- IF not S_SOFTDELETED and S_ALLOWED_DELETE and S_ALLOWED_SOFTDELETE -->
<tr>
@@ -30,6 +31,7 @@
</tr>
</table>
<br />
+ <!-- ENDIF -->
{S_HIDDEN_FIELDS}
<input type="submit" name="confirm" value="{L_YES}" class="btnmain" />&nbsp;&nbsp;
diff --git a/phpBB/styles/subsilver2/template/index_body.html b/phpBB/styles/subsilver2/template/index_body.html
index 1a2786015f..bfc2229221 100644
--- a/phpBB/styles/subsilver2/template/index_body.html
+++ b/phpBB/styles/subsilver2/template/index_body.html
@@ -14,6 +14,8 @@
<!-- INCLUDE forumlist_body.html -->
+<!-- EVENT index_body_forumlist_body_after -->
+
<!-- IF not S_IS_BOT or U_TEAM -->
<span class="gensmall">
<!-- IF not S_IS_BOT --><a href="{U_DELETE_COOKIES}">{L_DELETE_COOKIES}</a><!-- ENDIF -->
diff --git a/phpBB/styles/subsilver2/template/memberlist_email.html b/phpBB/styles/subsilver2/template/memberlist_email.html
index 13ff4baace..1416aa0c10 100644
--- a/phpBB/styles/subsilver2/template/memberlist_email.html
+++ b/phpBB/styles/subsilver2/template/memberlist_email.html
@@ -66,17 +66,19 @@
<td class="row1" valign="top"><b class="genmed">{L_MESSAGE_BODY}</b><br /><span class="gensmall">{L_EMAIL_BODY_EXPLAIN}</span></td>
<td class="row2"><textarea class="post" name="message" rows="15" cols="76" tabindex="3">{MESSAGE}</textarea></td>
</tr>
+ <!-- IF S_REGISTERED_USER -->
<tr>
<td class="row1" valign="top"><span class="gen"><b>{L_OPTIONS}</b></span></td>
<td class="row2">
<table cellspacing="0" cellpadding="1" border="0">
<tr>
- <td><input type="checkbox" class="radio" name="cc_email" value="1" checked="checked" /></td>
- <td class="gen">{L_CC_EMAIL}</td>
+ <td><input type="checkbox" class="radio" name="cc_sender" value="1" checked="checked" /></td>
+ <td class="gen">{L_CC_SENDER}</td>
</tr>
</table>
</td>
</tr>
+ <!-- ENDIF -->
<tr>
<td class="cat" colspan="2" align="center"><input type="submit" tabindex="6" name="submit" class="btnmain" value="{L_SEND_EMAIL}" /></td>
</tr>
diff --git a/phpBB/styles/subsilver2/template/memberlist_search.html b/phpBB/styles/subsilver2/template/memberlist_search.html
index 12dd10be2e..2096062607 100644
--- a/phpBB/styles/subsilver2/template/memberlist_search.html
+++ b/phpBB/styles/subsilver2/template/memberlist_search.html
@@ -66,6 +66,7 @@
<form method="post" action="{S_MODE_ACTION}" name="search">
+<!-- EVENT memberlist_search_fields_before -->
<table class="tablebg" width="100%" cellspacing="1">
<tr>
<th colspan="4">{L_FIND_USERNAME}</th>
@@ -111,6 +112,7 @@
<td colspan="2" class="row1">&nbsp;</td>
<!-- ENDIF -->
</tr>
+<!-- EVENT memberlist_search_sorting_options_before -->
<tr>
<td class="row1"><b class="genmed">{L_SORT_BY}{L_COLON}</b></td>
<td class="row2" nowrap="nowrap"><select name="sk">{S_SORT_OPTIONS}</select> <select name="sd">{S_ORDER_SELECT}</select>&nbsp;</td>
@@ -120,6 +122,7 @@
<td class="cat" colspan="4" align="center"><input class="btnmain" type="submit" name="submit" value="{L_SEARCH}" />&nbsp;&nbsp;<input class="btnlite" type="reset" value="{L_RESET}" /></td>
</tr>
</table>
+<!-- EVENT memberlist_search_fields_after -->
{S_FORM_TOKEN}
</form>
diff --git a/phpBB/styles/subsilver2/template/posting_buttons.html b/phpBB/styles/subsilver2/template/posting_buttons.html
index d1c0f79a16..516cd0922b 100644
--- a/phpBB/styles/subsilver2/template/posting_buttons.html
+++ b/phpBB/styles/subsilver2/template/posting_buttons.html
@@ -69,21 +69,18 @@
<!-- ENDIF -->
</select></span>
</div>
- <!-- EVENT posting_editor_buttons_after -->
-<!-- ENDIF -->
- </td>
-</tr>
-<!-- IF S_BBCODE_ALLOWED and .custom_tags -->
- <tr valign="middle" align="{S_CONTENT_FLOW_BEGIN}">
- <td colspan="2">
+ <!-- EVENT posting_editor_buttons_custom_tags_before -->
+ <!-- IF .custom_tags -->
<div id="custom-bbcode-buttons">
- <!-- BEGIN custom_tags -->
+ <!-- BEGIN custom_tags -->
<input type="button" class="btnbbcode bbcode-{custom_tags.BBCODE_TAG_CLEAN}" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})"<!-- IF custom_tags.BBCODE_HELPLINE !== '' --> onmouseover="helpline('cb_{custom_tags.BBCODE_ID}')" onmouseout="helpline('tip')"<!-- ENDIF --> />
- <!-- END custom_tags -->
+ <!-- END custom_tags -->
</div>
- </td>
- </tr>
+ <!-- ENDIF -->
+ <!-- EVENT posting_editor_buttons_after -->
<!-- ENDIF -->
+ </td>
+</tr>
<!-- IF S_BBCODE_ALLOWED -->
<tr>
<td<!-- IF $S_SIGNATURE or S_EDIT_DRAFT --> colspan="2"<!-- ENDIF -->><input type="text" readonly="readonly" name="helpbox" style="width:100%" class="helpline" value="{L_STYLES_TIP}" /></td>
diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php
index 6379da6802..1f455494f7 100644
--- a/phpBB/viewforum.php
+++ b/phpBB/viewforum.php
@@ -504,8 +504,8 @@ if ($start > $topics_count / 2)
// Select the sort order
$direction = (($sort_dir == 'd') ? 'ASC' : 'DESC');
- $sql_limit = $pagination->reverse_limit($start, $sql_limit, $topics_count);
- $sql_start = $pagination->reverse_start($start, $sql_limit, $topics_count);
+ $sql_limit = $pagination->reverse_limit($start, $sql_limit, $topics_count - sizeof($announcement_list));
+ $sql_start = $pagination->reverse_start($start, $sql_limit, $topics_count - sizeof($announcement_list));
}
else
{
@@ -694,10 +694,10 @@ if ($s_display_active)
// We need to remove the global announcements from the forums total topic count,
// otherwise the number is different from the one on the forum list
-$total_topic_count = $topics_count - sizeof($global_announce_forums);
+$total_topic_count = $topics_count - sizeof($announcement_list);
$base_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&amp;$u_sort_param" : ''));
-$pagination->generate_template_pagination($base_url, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start);
+$pagination->generate_template_pagination($base_url, 'pagination', 'start', $total_topic_count, $config['topics_per_page'], $start);
$template->assign_vars(array(
'TOTAL_TOPICS' => ($s_display_active) ? false : $user->lang('VIEW_FORUM_TOPICS', (int) $total_topic_count),
diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index 7bedcdfb49..a44169d3f1 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -616,7 +616,9 @@ $base_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=
* @var int topic_id Topic ID
* @var array topic_tracking_info Array with topic tracking data
* @var int total_posts Topic total posts count
+* @var string viewtopic_url URL to the topic page
* @since 3.1.0-RC4
+* @change 3.1.2-RC1 Added viewtopic_url
*/
$vars = array(
'base_url',
@@ -628,6 +630,7 @@ $vars = array(
'topic_id',
'topic_tracking_info',
'total_posts',
+ 'viewtopic_url',
);
extract($phpbb_dispatcher->trigger_event('core.viewtopic_assign_template_vars_before', compact($vars)));
@@ -1247,7 +1250,7 @@ while ($row = $db->sql_fetchrow($result))
'contact_user' => $user->lang('CONTACT_USER', get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['username'])),
'online' => false,
- 'jabber' => ($row['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&amp;action=jabber&amp;u=$poster_id") : '',
+ 'jabber' => ($config['jab_enable'] && $row['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&amp;action=jabber&amp;u=$poster_id") : '',
'search' => ($config['load_search'] && $auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id=$poster_id&amp;sr=posts") : '',
'author_full' => get_username_string('full', $poster_id, $row['username'], $row['user_colour']),
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 3475742288..c6e539b7ba 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -16,6 +16,7 @@
<directory suffix="_test.php">./tests</directory>
<exclude>./tests/functional</exclude>
<exclude>./tests/lint_test.php</exclude>
+ <exclude>./tests/ui</exclude>
</testsuite>
<testsuite name="phpBB Functional Tests">
<directory suffix="_test.php">./tests/functional</directory>
@@ -23,6 +24,10 @@
<testsuite name="phpBB Lint Test">
<file>./tests/lint_test.php</file>
</testsuite>
+ <testsuite name="phpBB UI Tests">
+ <directory suffix="_test.php" phpVersion="5.3.19"
+ phpVersionOperator=">=">./tests/ui</directory>
+ </testsuite>
</testsuites>
<groups>
@@ -32,15 +37,9 @@
</groups>
<filter>
- <blacklist>
- <directory>./tests</directory>
- </blacklist>
<whitelist>
<directory suffix=".php">./phpBB/includes/</directory>
<directory suffix=".php">./phpBB/phpbb/</directory>
- <exclude>
- <directory suffix=".php">./phpBB/includes/captcha/</directory>
- </exclude>
</whitelist>
</filter>
</phpunit>
diff --git a/tests/auth/provider_db_test.php b/tests/auth/provider_db_test.php
index e33eae6b54..09ca0816bf 100644
--- a/tests/auth/provider_db_test.php
+++ b/tests/auth/provider_db_test.php
@@ -78,7 +78,14 @@ class phpbb_auth_provider_db_test extends phpbb_database_test_case
),
);
- $this->assertEquals($expected, $provider->login('foobar', 'example'));
+ $login_return = $provider->login('foobar', 'example');
+ $this->assertEquals($expected['status'], $login_return['status']);
+ $this->assertEquals($expected['error_msg'], $login_return['error_msg']);
+
+ foreach ($expected['user_row'] as $key => $value)
+ {
+ $this->assertEquals($value, $login_return['user_row'][$key]);
+ }
// Check if convert works
$login_return = $provider->login('foobar2', 'example');
diff --git a/tests/avatar/fixtures/users.xml b/tests/avatar/fixtures/users.xml
index 3e6586e909..1773d438c2 100644
--- a/tests/avatar/fixtures/users.xml
+++ b/tests/avatar/fixtures/users.xml
@@ -29,5 +29,33 @@
<value></value>
<value></value>
</row>
+ <row>
+ <value>3</value>
+ <value>foo</value>
+ <value></value>
+ <value></value>
+ <value>g5_1414350991.jpg</value>
+ <value>avatar.driver.upload</value>
+ <value>80</value>
+ <value>80</value>
+ </row>
+ </table>
+ <table name="phpbb_groups">
+ <column>group_id</column>
+ <column>group_type</column>
+ <column>group_name</column>
+ <column>group_avatar</column>
+ <column>group_avatar_type</column>
+ <column>group_avatar_width</column>
+ <column>group_avatar_height</column>
+ <row>
+ <value>5</value>
+ <value>3</value>
+ <value>ADMINISTRATORS</value>
+ <value>g5_1414350991.jpg</value>
+ <value>avatar.driver.upload</value>
+ <value>80</value>
+ <value>80</value>
+ </row>
</table>
</dataset>
diff --git a/tests/avatar/manager_test.php b/tests/avatar/manager_test.php
index 81c153aed4..a109a7b5de 100644
--- a/tests/avatar/manager_test.php
+++ b/tests/avatar/manager_test.php
@@ -299,17 +299,32 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case
public function data_handle_avatar_delete()
{
return array(
- array(array(
- 'avatar' => '',
- 'avatar_type' => '',
- 'avatar_width' => 0,
- 'avatar_height' => 0,
- ), 1, array(
- 'avatar' => 'foobar@example.com',
- 'avatar_type' => 'avatar.driver.gravatar',
- 'avatar_width' => '16',
- 'avatar_height' => '16',
- ), USERS_TABLE, 'user_'),
+ array(
+ array(
+ 'avatar' => '',
+ 'avatar_type' => '',
+ 'avatar_width' => 0,
+ 'avatar_height' => 0,
+ ), 1, array(
+ 'avatar' => 'foobar@example.com',
+ 'avatar_type' => 'avatar.driver.gravatar',
+ 'avatar_width' => '16',
+ 'avatar_height' => '16',
+ ), USERS_TABLE, 'user_',
+ ),
+ array(
+ array(
+ 'avatar' => '',
+ 'avatar_type' => '',
+ 'avatar_width' => 0,
+ 'avatar_height' => 0,
+ ), 5, array(
+ 'avatar' => 'g5_1414350991.jpg',
+ 'avatar_type' => 'avatar.driver.upload',
+ 'avatar_width' => '80',
+ 'avatar_height' => '80'
+ ), GROUPS_TABLE, 'group_',
+ ),
);
}
@@ -333,4 +348,23 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case
$this->assertEquals($value, $row[$key]);
}
}
+
+ /**
+ * @dependsOn test_handle_avatar_delete
+ */
+ public function test_user_group_avatar_deleted()
+ {
+ $sql = 'SELECT * FROM ' . USERS_TABLE . '
+ WHERE user_id = 3';
+ $result = $this->db->sql_query_limit($sql, 1);
+ $row = $this->manager->clean_row($this->db->sql_fetchrow($result), 'user');
+ $this->db->sql_freeresult($result);
+
+ $this->assertEquals(array(
+ 'avatar' => '',
+ 'avatar_type' => '',
+ 'avatar_width' => 0,
+ 'avatar_height' => 0,
+ ), $row);
+ }
}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 40c6ef7dfa..0e81f4372a 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -33,3 +33,9 @@ require_once 'test_framework/phpbb_test_case.php';
require_once 'test_framework/phpbb_database_test_case.php';
require_once 'test_framework/phpbb_database_test_connection_manager.php';
require_once 'test_framework/phpbb_functional_test_case.php';
+require_once 'test_framework/phpbb_ui_test_case.php';
+
+if (version_compare(PHP_VERSION, '5.3.19', ">=") && file_exists(__DIR__ . '/vendor/autoload.php'))
+{
+ require_once __DIR__ . '/vendor/autoload.php';
+}
diff --git a/tests/composer.json b/tests/composer.json
new file mode 100644
index 0000000000..69512f30a6
--- /dev/null
+++ b/tests/composer.json
@@ -0,0 +1,5 @@
+{
+ "require-dev": {
+ "facebook/webdriver": "dev-master"
+ }
+}
diff --git a/tests/composer.lock b/tests/composer.lock
new file mode 100644
index 0000000000..f714495d84
--- /dev/null
+++ b/tests/composer.lock
@@ -0,0 +1,66 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
+ ],
+ "hash": "cf1d8a4841e5e669b148e0df6645a788",
+ "packages": [
+
+ ],
+ "packages-dev": [
+ {
+ "name": "facebook/webdriver",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/facebook/php-webdriver.git",
+ "reference": "b6e002e5bf811a8edba393ce6872322c1b7cf796"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/b6e002e5bf811a8edba393ce6872322c1b7cf796",
+ "reference": "b6e002e5bf811a8edba393ce6872322c1b7cf796",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.19"
+ },
+ "require-dev": {
+ "phpdocumentor/phpdocumentor": "2.*",
+ "phpunit/phpunit": "3.7.*"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "lib/"
+ ]
+ },
+ "notification-url": "http://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "description": "A php client for WebDriver",
+ "homepage": "https://github.com/facebook/php-webdriver",
+ "keywords": [
+ "facebook",
+ "php",
+ "selenium",
+ "webdriver"
+ ],
+ "time": "2014-08-05 02:55:46"
+ }
+ ],
+ "aliases": [
+
+ ],
+ "minimum-stability": "stable",
+ "stability-flags": {
+ "facebook/webdriver": 20
+ },
+ "platform": [
+
+ ],
+ "platform-dev": [
+
+ ]
+}
diff --git a/tests/console/cron/run_test.php b/tests/console/cron/run_test.php
index 029dc5249b..f76e967484 100644
--- a/tests/console/cron/run_test.php
+++ b/tests/console/cron/run_test.php
@@ -16,6 +16,7 @@ use Symfony\Component\Console\Tester\CommandTester;
use phpbb\console\command\cron\run;
require_once dirname(__FILE__) . '/tasks/simple.php';
+require_once dirname(__FILE__) . '/../../../phpBB/includes/functions.php';
class phpbb_console_command_cron_run_test extends phpbb_database_test_case
{
diff --git a/tests/controller/common_helper_route.php b/tests/controller/common_helper_route.php
index 859832412d..6723e3bc52 100644
--- a/tests/controller/common_helper_route.php
+++ b/tests/controller/common_helper_route.php
@@ -63,21 +63,21 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
protected function generate_route_objects()
{
- $request = new phpbb_mock_request();
- $request->overwrite('SCRIPT_NAME', $this->get_uri(), \phpbb\request\request_interface::SERVER);
- $request->overwrite('SCRIPT_FILENAME', $this->get_script_name(), \phpbb\request\request_interface::SERVER);
- $request->overwrite('REQUEST_URI', $this->get_uri(), \phpbb\request\request_interface::SERVER);
- $request->overwrite('SERVER_NAME', 'localhost', \phpbb\request\request_interface::SERVER);
- $request->overwrite('SERVER_PORT', '80', \phpbb\request\request_interface::SERVER);
+ $this->request = new phpbb_mock_request();
+ $this->request->overwrite('SCRIPT_NAME', $this->get_uri(), \phpbb\request\request_interface::SERVER);
+ $this->request->overwrite('SCRIPT_FILENAME', $this->get_script_name(), \phpbb\request\request_interface::SERVER);
+ $this->request->overwrite('REQUEST_URI', $this->get_uri(), \phpbb\request\request_interface::SERVER);
+ $this->request->overwrite('SERVER_NAME', 'localhost', \phpbb\request\request_interface::SERVER);
+ $this->request->overwrite('SERVER_PORT', '80', \phpbb\request\request_interface::SERVER);
$this->symfony_request = new \phpbb\symfony_request(
- $request
+ $this->request
);
$this->filesystem = new \phpbb\filesystem();
$this->phpbb_path_helper = new \phpbb\path_helper(
$this->symfony_request,
$this->filesystem,
- $this->getMock('\phpbb\request\request'),
+ $this->request,
$phpbb_root_path,
$phpEx
);
@@ -130,7 +130,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
*/
public function test_helper_url_no_rewrite($route, $params, $is_amp, $session_id, $expected, $description)
{
- $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
+ $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id));
}
@@ -170,7 +170,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1'));
- $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
+ $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id));
}
@@ -210,7 +210,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_absolute($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0'));
- $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
+ $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::ABSOLUTE_URL));
}
@@ -250,7 +250,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_relative_path($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0'));
- $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
+ $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::RELATIVE_PATH));
}
@@ -290,7 +290,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_network($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0'));
- $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
+ $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::NETWORK_PATH));
}
//TODO
@@ -330,7 +330,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_absolute_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1'));
- $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
+ $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::ABSOLUTE_URL));
}
@@ -370,7 +370,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_relative_path_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1'));
- $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
+ $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::RELATIVE_PATH));
}
@@ -410,7 +410,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_network_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1'));
- $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
+ $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/');
$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::NETWORK_PATH));
}
}
diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php
index 58bcf0ef81..62feee3fed 100644
--- a/tests/controller/controller_test.php
+++ b/tests/controller/controller_test.php
@@ -11,6 +11,8 @@
*
*/
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
+
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
diff --git a/tests/datetime/from_format_test.php b/tests/datetime/from_format_test.php
index f10402e8cb..8968619bb5 100644
--- a/tests/datetime/from_format_test.php
+++ b/tests/datetime/from_format_test.php
@@ -60,44 +60,44 @@ class phpbb_datetime_from_format_test extends phpbb_test_case
// If the current time is too close to the testing time,
// the relative time will use "x minutes ago" instead of "today ..."
// So we use 18:01 in the morning and 06:01 in the afternoon.
- $testing_time = date('H') <= 12 ? '18:01' : '06:01';
+ $testing_time = gmdate('H') <= 12 ? '18:01' : '06:01';
return array(
array(
- date('Y-m-d', time() + 2 * 86400) . ' ' . $testing_time, false,
- date('Y-m-d', time() + 2 * 86400) . ' ' . $testing_time,
+ gmdate('Y-m-d', time() + 2 * 86400) . ' ' . $testing_time, false,
+ gmdate('Y-m-d', time() + 2 * 86400) . ' ' . $testing_time,
),
array(
- date('Y-m-d', time() + 86400) . ' ' . $testing_time, false,
+ gmdate('Y-m-d', time() + 86400) . ' ' . $testing_time, false,
'Tomorrow ' . $testing_time,
),
array(
- date('Y-m-d', time() + 86400) . ' ' . $testing_time, true,
- date('Y-m-d', time() + 86400) . ' ' . $testing_time,
+ gmdate('Y-m-d', time() + 86400) . ' ' . $testing_time, true,
+ gmdate('Y-m-d', time() + 86400) . ' ' . $testing_time,
),
array(
- date('Y-m-d') . ' ' . $testing_time, false,
+ gmdate('Y-m-d') . ' ' . $testing_time, false,
'Today ' . $testing_time,
),
array(
- date('Y-m-d') . ' ' . $testing_time, true,
- date('Y-m-d') . ' ' . $testing_time,
+ gmdate('Y-m-d') . ' ' . $testing_time, true,
+ gmdate('Y-m-d') . ' ' . $testing_time,
),
array(
- date('Y-m-d', time() - 86400) . ' ' . $testing_time, false,
+ gmdate('Y-m-d', time() - 86400) . ' ' . $testing_time, false,
'Yesterday ' . $testing_time,
),
array(
- date('Y-m-d', time() - 86400) . ' ' . $testing_time, true,
- date('Y-m-d', time() - 86400) . ' ' . $testing_time,
+ gmdate('Y-m-d', time() - 86400) . ' ' . $testing_time, true,
+ gmdate('Y-m-d', time() - 86400) . ' ' . $testing_time,
),
array(
- date('Y-m-d', time() - 2 * 86400) . ' ' . $testing_time, false,
- date('Y-m-d', time() - 2 * 86400) . ' ' . $testing_time,
+ gmdate('Y-m-d', time() - 2 * 86400) . ' ' . $testing_time, false,
+ gmdate('Y-m-d', time() - 2 * 86400) . ' ' . $testing_time,
),
);
}
diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php
index 8e27b39459..fab1d3af3a 100644
--- a/tests/extension/metadata_manager_test.php
+++ b/tests/extension/metadata_manager_test.php
@@ -123,6 +123,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case
}
$json = json_decode(file_get_contents($this->phpbb_root_path . 'ext/vendor2/foo/composer.json'), true);
+ array_walk_recursive($json, array($manager, 'sanitize_json'));
$this->assertEquals($metadata, $json);
}
diff --git a/tests/functional/acp_groups_test.php b/tests/functional/acp_groups_test.php
index 4eb4747572..9dfdc93474 100644
--- a/tests/functional/acp_groups_test.php
+++ b/tests/functional/acp_groups_test.php
@@ -11,12 +11,12 @@
*
*/
-require_once dirname(__FILE__) . '/common_groups_test.php';
+require_once dirname(__FILE__) . '/common_groups_test_case.php';
/**
* @group functional
*/
-class phpbb_functional_acp_groups_test extends phpbb_functional_common_groups_test
+class phpbb_functional_acp_groups_test extends phpbb_functional_common_groups_test_case
{
protected $form_data;
diff --git a/tests/functional/acp_registration_test.php b/tests/functional/acp_registration_test.php
new file mode 100644
index 0000000000..ef9843679e
--- /dev/null
+++ b/tests/functional/acp_registration_test.php
@@ -0,0 +1,55 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+/**
+* @group functional
+*/
+class phpbb_functional_acp_registration_test extends phpbb_functional_test_case
+{
+ protected function set_email_enable($db, $status)
+ {
+ $sql = "UPDATE phpbb_config
+ SET config_value = '" . (($status) ? '1' : '0') . "'
+ WHERE config_name = 'email_enable'";
+ $db->sql_query($sql);
+
+ $this->purge_cache();
+ }
+
+ public function test_submitting_activation_method()
+ {
+ $db = $this->get_db();
+
+ $this->set_email_enable($db, false);
+
+ $this->add_lang('acp/board');
+ $this->login();
+ $this->admin_login();
+
+ $crawler = self::request('GET', 'adm/index.php?i=acp_board&mode=registration&sid=' . $this->sid);
+ $this->assertContainsLang('ACP_REGISTER_SETTINGS_EXPLAIN', $this->get_content());
+
+ $form = $crawler->selectButton($this->lang('SUBMIT'))->form();
+ $form['config[require_activation]']->select(USER_ACTIVATION_ADMIN);
+ $crawler = self::submit($form);
+ $this->assertContainsLang('ACC_ACTIVATION_WARNING', $crawler->filter('div.main')->text());
+
+ $crawler = self::request('GET', 'adm/index.php?i=acp_board&mode=registration&sid=' . $this->sid);
+ $form = $crawler->selectButton($this->lang('SUBMIT'))->form();
+ $form['config[require_activation]']->select(USER_ACTIVATION_NONE);
+ $crawler = self::submit($form);
+ $this->assertNotContainsLang('ACC_ACTIVATION_WARNING', $crawler->filter('div.main')->text());
+
+ $this->set_email_enable($db, true);
+ }
+}
diff --git a/tests/functional/auth_test.php b/tests/functional/auth_test.php
index b4b4279bf1..76e1709afb 100644
--- a/tests/functional/auth_test.php
+++ b/tests/functional/auth_test.php
@@ -34,6 +34,25 @@ class phpbb_functional_auth_test extends phpbb_functional_test_case
}
/**
+ * @dependsOn test_login_other
+ */
+ public function test_login_ucp_other_auth_provider()
+ {
+ global $cache, $config;
+ $cache = new phpbb_mock_null_cache;
+ $db = $this->get_db();
+ $sql = 'UPDATE ' . CONFIG_TABLE . " SET config_value = 'foobar' WHERE config_name = 'auth_method'";
+ $db->sql_query($sql);
+ $config['auth_method'] = 'foobar';
+ $this->login('anothertestuser');
+ $crawler = self::request('GET', 'index.php');
+ $this->assertContains('anothertestuser', $crawler->filter('#username_logged_in')->text());
+ $sql = 'UPDATE ' . CONFIG_TABLE . " SET config_value = 'db' WHERE config_name = 'auth_method'";
+ $db->sql_query($sql);
+ $config['auth_method'] = 'db';
+ }
+
+ /**
* @depends test_login
*/
public function test_logout()
diff --git a/tests/functional/avatar_acp_groups_test.php b/tests/functional/avatar_acp_groups_test.php
index 925335a2f7..ca8c84ab2e 100644
--- a/tests/functional/avatar_acp_groups_test.php
+++ b/tests/functional/avatar_acp_groups_test.php
@@ -11,12 +11,12 @@
*
*/
-require_once dirname(__FILE__) . '/common_avatar_test.php';
+require_once dirname(__FILE__) . '/common_avatar_test_case.php';
/**
* @group functional
*/
-class phpbb_functional_avatar_acp_groups_test extends phpbb_functional_common_avatar_test
+class phpbb_functional_avatar_acp_groups_test extends phpbb_functional_common_avatar_test_case
{
public function get_url()
{
diff --git a/tests/functional/avatar_acp_users_test.php b/tests/functional/avatar_acp_users_test.php
index 5eca473157..8b05a28658 100644
--- a/tests/functional/avatar_acp_users_test.php
+++ b/tests/functional/avatar_acp_users_test.php
@@ -11,12 +11,12 @@
*
*/
-require_once dirname(__FILE__) . '/common_avatar_test.php';
+require_once dirname(__FILE__) . '/common_avatar_test_case.php';
/**
* @group functional
*/
-class phpbb_functional_avatar_acp_users_test extends phpbb_functional_common_avatar_test
+class phpbb_functional_avatar_acp_users_test extends phpbb_functional_common_avatar_test_case
{
public function get_url()
{
diff --git a/tests/functional/avatar_ucp_groups_test.php b/tests/functional/avatar_ucp_groups_test.php
index 1e8ca911c6..52ef67543e 100644
--- a/tests/functional/avatar_ucp_groups_test.php
+++ b/tests/functional/avatar_ucp_groups_test.php
@@ -10,12 +10,12 @@
* the docs/CREDITS.txt file.
*
*/
-require_once dirname(__FILE__) . '/common_avatar_test.php';
+require_once dirname(__FILE__) . '/common_avatar_test_case.php';
/**
* @group functional
*/
-class phpbb_functional_avatar_ucp_groups_test extends phpbb_functional_common_avatar_test
+class phpbb_functional_avatar_ucp_groups_test extends phpbb_functional_common_avatar_test_case
{
public function get_url()
{
diff --git a/tests/functional/avatar_ucp_users_test.php b/tests/functional/avatar_ucp_users_test.php
index 972bfa0fb2..2f0832e092 100644
--- a/tests/functional/avatar_ucp_users_test.php
+++ b/tests/functional/avatar_ucp_users_test.php
@@ -11,12 +11,12 @@
*
*/
-require_once dirname(__FILE__) . '/common_avatar_test.php';
+require_once dirname(__FILE__) . '/common_avatar_test_case.php';
/**
* @group functional
*/
-class phpbb_functional_avatar_ucp_users_test extends phpbb_functional_common_avatar_test
+class phpbb_functional_avatar_ucp_users_test extends phpbb_functional_common_avatar_test_case
{
public function get_url()
{
diff --git a/tests/functional/common_avatar_test.php b/tests/functional/common_avatar_test_case.php
index 82d7136c98..7278f23bcc 100644
--- a/tests/functional/common_avatar_test.php
+++ b/tests/functional/common_avatar_test_case.php
@@ -14,7 +14,7 @@
/**
* @group functional
*/
-abstract class phpbb_functional_common_avatar_test extends phpbb_functional_test_case
+abstract class phpbb_functional_common_avatar_test_case extends phpbb_functional_test_case
{
private $path;
private $form_content;
diff --git a/tests/functional/common_groups_test.php b/tests/functional/common_groups_test_case.php
index 748d4d5e0a..521b7c84d2 100644
--- a/tests/functional/common_groups_test.php
+++ b/tests/functional/common_groups_test_case.php
@@ -14,7 +14,7 @@
/**
* @group functional
*/
-abstract class phpbb_functional_common_groups_test extends phpbb_functional_test_case
+abstract class phpbb_functional_common_groups_test_case extends phpbb_functional_test_case
{
abstract protected function get_url();
diff --git a/tests/functional/feed_test.php b/tests/functional/feed_test.php
index 7aa2d0da7d..9041c8dc69 100644
--- a/tests/functional/feed_test.php
+++ b/tests/functional/feed_test.php
@@ -322,15 +322,9 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
$post = $this->create_topic($this->data['forums']['Feeds #news'], 'Feeds #news - Topic #1', 'This is a test topic posted by the testing framework.');
$this->data['topics']['Feeds #news - Topic #1'] = (int) $post['topic_id'];
- // Travis is too fast, so we have to wait
- sleep(1);
-
$post = $this->create_topic($this->data['forums']['Feeds #news'], 'Feeds #news - Topic #2', 'This is a test topic posted by the testing framework.');
$crawler = self::request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}");
- // Travis is too fast, so we have to wait
- sleep(1);
-
$this->assertContains('Feeds #news - Topic #2', $crawler->filter('html')->text());
$this->data['topics']['Feeds #news - Topic #2'] = (int) $post['topic_id'];
$this->data['posts']['Feeds #news - Topic #2'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p');
@@ -456,9 +450,6 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
$post = $this->create_topic($this->data['forums']['Feeds #1'], 'Feeds #1 - Topic #1', 'This is a test topic posted by the testing framework.');
$this->data['topics']['Feeds #1 - Topic #1'] = (int) $post['topic_id'];
- // Travis is too fast, so we have to wait
- sleep(1);
-
$post = $this->create_topic($this->data['forums']['Feeds #1.1'], 'Feeds #1.1 - Topic #1', 'This is a test topic posted by the testing framework.');
$this->data['topics']['Feeds #1.1 - Topic #1'] = (int) $post['topic_id'];
}
@@ -494,9 +485,6 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
$post = $this->create_topic($this->data['forums']['Feeds #1'], 'Feeds #1 - Topic #2', 'This is a test topic posted by the testing framework.');
$this->data['topics']['Feeds #1 - Topic #2'] = (int) $post['topic_id'];
- // Travis is too fast, so we have to wait
- sleep(1);
-
// Test creating a reply
$post2 = $this->create_post($this->data['forums']['Feeds #1'], $post['topic_id'], 'Re: Feeds #1 - Topic #2', 'This is a test post posted by the testing framework.');
$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
@@ -852,9 +840,7 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
'Feeds #1.1',
),
));
-
- // We have to wait because of the flood interval.
- sleep(15);
+ $this->set_flood_interval(0);
$this->login('disapprove_user');
$post = $this->create_topic($this->data['forums']['Feeds #1.1'], 'Feeds #1.1 - Topic #3', 'This is a test topic posted by the testing framework.', array(), 'POST_STORED_MOD');
@@ -862,6 +848,27 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
$crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Feeds #1.1']}&sid={$this->sid}");
$this->assertNotContains('Feeds #1.1 - Topic #3', $crawler->filter('html')->text());
+
+ $this->logout();
+ $this->set_flood_interval(15);
+ }
+
+ protected function set_flood_interval($flood_interval)
+ {
+ $this->login();
+ $this->admin_login();
+
+ $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=post');
+
+ $form = $crawler->selectButton('Submit')->form();
+ $values = $form->getValues();
+
+ $values["config[flood_interval]"] = $flood_interval;
+ $form->setValues($values);
+ $crawler = self::submit($form);
+ $this->assertGreaterThan(0, $crawler->filter('.successbox')->count());
+
+ $this->logout();
}
public function test_feeds_unapproved_topic_admin()
diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php
index c76ba6e37d..1da5c39401 100644
--- a/tests/functional/memberlist_test.php
+++ b/tests/functional/memberlist_test.php
@@ -106,4 +106,32 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case
$this->assertContains('admin', $crawler->eq(0)->text());
$this->assertNotContains('admin', $crawler->eq(1)->text());
}
+
+ public function test_group_rank()
+ {
+ copy(__DIR__ . '/fixtures/files/valid.jpg', __DIR__ . '/../../phpBB/images/ranks/valid.jpg');
+
+ $this->login();
+ $this->admin_login();
+ $this->add_lang(array('acp/groups', 'acp/posting'));
+
+ // Set a group rank to the registered users
+ $crawler = self::request('GET', "adm/index.php?sid={$this->sid}&i=acp_groups&mode=manage&action=edit&g=2");
+ $form = $crawler->selectButton('Submit')->form();
+ $form['group_rank']->select('1');
+ $crawler = self::submit($form);
+ $this->assertContainsLang('GROUP_UPDATED', $crawler->filter('.successbox')->text());
+
+ // Set a rank image for site_admin
+ $crawler = self::request('GET', "adm/index.php?sid={$this->sid}&i=acp_ranks&mode=ranks&action=edit&id=1");
+ $form = $crawler->selectButton('Submit')->form();
+ $form['rank_image']->select('valid.jpg');
+ $crawler = self::submit($form);
+ $this->assertContainsLang('RANK_UPDATED', $crawler->filter('.successbox')->text());
+
+ $crawler = self::request('GET', 'memberlist.php?mode=group&g=2');
+ $this->assertContains('memberlist-test-user', $crawler->text());
+
+ unlink(__DIR__ . '/../../phpBB/images/ranks/valid.jpg');
+ }
}
diff --git a/tests/functional/prune_shadow_topic_test.php b/tests/functional/prune_shadow_topic_test.php
index 84f07e9802..f00303060d 100644
--- a/tests/functional/prune_shadow_topic_test.php
+++ b/tests/functional/prune_shadow_topic_test.php
@@ -129,8 +129,8 @@ class phpbb_functional_prune_shadow_topic_test extends phpbb_functional_test_cas
$result = $this->db->sql_query($sql);
$crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Prune Shadow']}&sid={$this->sid}");
- $cron_link = $crawler->filter('img')->last()->attr('src');
- $crawler = self::request('GET', $cron_link . "&sid={$this->sid}", array(), false);
+ $this->assertNotEmpty($crawler->filter('img')->last()->attr('src'));
+ self::request('GET', "cron.php?cron_type=cron.task.core.prune_shadow_topics&f={$this->data['forums']['Prune Shadow']}&sid={$this->sid}", array(), false);
$this->assert_forum_details($this->data['forums']['Prune Shadow'], array(
'forum_posts_approved' => 0,
diff --git a/tests/functional/registration_test.php b/tests/functional/registration_test.php
index 45a684db19..690f4ae9f2 100644
--- a/tests/functional/registration_test.php
+++ b/tests/functional/registration_test.php
@@ -45,12 +45,23 @@ class phpbb_functional_registration_test extends phpbb_functional_test_case
$form = $crawler->selectButton('Submit')->form(array(
'username' => 'user-reg-test',
'email' => 'user-reg-test@phpbb.com',
- 'new_password' => 'testtest',
- 'password_confirm' => 'testtest',
+ 'new_password' => 'user-reg-testuser-reg-test',
+ 'password_confirm' => 'user-reg-testuser-reg-test',
));
$form['tz']->select('Europe/Berlin');
$crawler = self::submit($form);
$this->assertContainsLang('ACCOUNT_ADDED', $crawler->filter('#message')->text());
}
+
+ /**
+ * @depends test_register_new_account
+ */
+ public function test_default_subscription_options()
+ {
+ $this->login('user-reg-test');
+ $crawler = self::request('GET', 'ucp.php?i=ucp_notifications&mode=notification_options&sid=' . $this->sid);
+ $this->assert_checkbox_is_checked($crawler, 'notification.type.post_notification.method.email');
+ $this->assert_checkbox_is_checked($crawler, 'notification.type.topic_notification.method.email');
+ }
}
diff --git a/tests/functional/ucp_groups_test.php b/tests/functional/ucp_groups_test.php
index 2b075b37a5..cd18a0fcae 100644
--- a/tests/functional/ucp_groups_test.php
+++ b/tests/functional/ucp_groups_test.php
@@ -11,12 +11,12 @@
*
*/
-require_once dirname(__FILE__) . '/common_groups_test.php';
+require_once dirname(__FILE__) . '/common_groups_test_case.php';
/**
* @group functional
*/
-class phpbb_functional_ucp_groups_test extends phpbb_functional_common_groups_test
+class phpbb_functional_ucp_groups_test extends phpbb_functional_common_groups_test_case
{
protected $db;
diff --git a/tests/functional/viewforum_paging_test.php b/tests/functional/viewforum_paging_test.php
new file mode 100644
index 0000000000..4a574bebbb
--- /dev/null
+++ b/tests/functional/viewforum_paging_test.php
@@ -0,0 +1,256 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+/**
+* @group functional
+*/
+class viewforum_paging_test extends phpbb_functional_test_case
+{
+ protected $data = array();
+
+ public function test_setup_forums()
+ {
+ $this->login();
+ $this->admin_login();
+
+ $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}");
+ $form = $crawler->selectButton('addforum')->form(array(
+ 'forum_name' => 'Viewforum Pagination Test #1',
+ ));
+ $crawler = self::submit($form);
+ $form = $crawler->selectButton('update')->form(array(
+ 'forum_perm_from' => 2,
+ ));
+ self::submit($form);
+
+ $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}");
+ $form = $crawler->selectButton('addforum')->form(array(
+ 'forum_name' => 'Viewforum Pagination Test #2',
+ ));
+ $crawler = self::submit($form);
+ $form = $crawler->selectButton('update')->form(array(
+ 'forum_perm_from' => 2,
+ ));
+ self::submit($form);
+
+ $this->set_post_settings(array(
+ 'flood_interval' => 0,
+ 'topics_per_page' => 3,
+ ));
+ }
+
+ public function test_create_posts()
+ {
+ $this->login();
+ $this->load_ids(array(
+ 'forums' => array(
+ 'Viewforum Pagination Test #1',
+ 'Viewforum Pagination Test #2',
+ ),
+ ));
+
+ $this->assert_forum_details($this->data['forums']['Viewforum Pagination Test #1'], array(
+ 'forum_posts_approved' => 0,
+ 'forum_posts_unapproved' => 0,
+ 'forum_posts_softdeleted' => 0,
+ 'forum_topics_approved' => 0,
+ 'forum_topics_unapproved' => 0,
+ 'forum_topics_softdeleted' => 0,
+ 'forum_last_post_id' => 0,
+ ), 'initial comparison');
+
+ for ($topic_id = 1; $topic_id <= 6; $topic_id++)
+ {
+ $this->create_topic($this->data['forums']['Viewforum Pagination Test #1'], 'Viewforum Pagination TestTopic #' . $topic_id, 'This is a test topic posted by the testing framework.');
+ }
+
+ $this->create_topic($this->data['forums']['Viewforum Pagination Test #2'], 'Viewforum Pagination TestTopic #GA1', 'This is a test topic posted by the testing framework.', array(
+ 'topic_type' => POST_GLOBAL,
+ ));
+
+ $this->assert_forum_details($this->data['forums']['Viewforum Pagination Test #1'], array(
+ 'forum_posts_approved' => 6,
+ 'forum_posts_unapproved' => 0,
+ 'forum_posts_softdeleted' => 0,
+ 'forum_topics_approved' => 6,
+ 'forum_topics_unapproved' => 0,
+ 'forum_topics_softdeleted' => 0,
+ ), 'after creating topics');
+
+ $this->assert_forum_details($this->data['forums']['Viewforum Pagination Test #2'], array(
+ 'forum_posts_approved' => 1,
+ 'forum_posts_unapproved' => 0,
+ 'forum_posts_softdeleted' => 0,
+ 'forum_topics_approved' => 1,
+ 'forum_topics_unapproved' => 0,
+ 'forum_topics_softdeleted' => 0,
+ ), 'after creating GA');
+
+ // Set flood interval back to 15
+ $this->admin_login();
+ $this->set_post_settings(array(
+ 'flood_interval' => 15,
+ ));
+ }
+
+ public function test_viewforum_first_page()
+ {
+ $this->load_ids(array(
+ 'forums' => array(
+ 'Viewforum Pagination Test #1',
+ 'Viewforum Pagination Test #2',
+ ),
+ ));
+ $crawler = self::request('GET', 'viewforum.php?f=' . $this->data['forums']['Viewforum Pagination Test #1']);
+
+ // Test the topics that are displayed
+ $topiclists = $crawler->filter('.forumbg .topics');
+ $this->assertEquals(2, $topiclists->count());
+ $topiclist = $topiclists->eq(0)->filter('li');
+ $this->assertStringEndsWith('TestTopic #GA1', $topiclist->eq(0)->filter('.topictitle')->text());
+ $topiclist = $topiclists->eq(1)->filter('li');
+ $this->assertStringEndsWith('TestTopic #6', $topiclist->eq(0)->filter('.topictitle')->text());
+ $this->assertStringEndsWith('TestTopic #5', $topiclist->eq(1)->filter('.topictitle')->text());
+ $this->assertStringEndsWith('TestTopic #4', $topiclist->eq(2)->filter('.topictitle')->text());
+
+ // Test the pagination, should only have: 1 - 2 - Next
+ $this->assertEquals(2, $crawler->filter('div.pagination')->count());
+ $top_pagination = $crawler->filter('div.pagination')->eq(0);
+ $this->assertEquals(3, $top_pagination->filter('li')->count(), 'Number of pagination items on page 1 does not match');
+ $this->assertContains('1', $top_pagination->filter('li')->eq(0)->text());
+ $this->assertContains('2', $top_pagination->filter('li')->eq(1)->text());
+ $this->assertContainsLang('NEXT', $top_pagination->filter('li')->eq(2)->text());
+ }
+
+ public function test_viewforum_second_page()
+ {
+ $this->load_ids(array(
+ 'forums' => array(
+ 'Viewforum Pagination Test #1',
+ 'Viewforum Pagination Test #2',
+ ),
+ ));
+ $crawler = self::request('GET', 'viewforum.php?f=' . $this->data['forums']['Viewforum Pagination Test #1'] . '&start=3');
+
+ // Test the topics that are displayed
+ $topiclists = $crawler->filter('.forumbg .topics');
+ $this->assertEquals(2, $topiclists->count());
+ $topiclist = $topiclists->eq(0)->filter('li');
+ $this->assertStringEndsWith('TestTopic #GA1', $topiclist->eq(0)->filter('.topictitle')->text());
+ $topiclist = $topiclists->eq(1)->filter('li');
+ $this->assertStringEndsWith('TestTopic #3', $topiclist->eq(0)->filter('.topictitle')->text());
+ $this->assertStringEndsWith('TestTopic #2', $topiclist->eq(1)->filter('.topictitle')->text());
+ $this->assertStringEndsWith('TestTopic #1', $topiclist->eq(2)->filter('.topictitle')->text());
+
+ // Test the pagination, should only have: Previous - 1 - 2
+ $this->assertEquals(2, $crawler->filter('div.pagination')->count());
+ $top_pagination = $crawler->filter('div.pagination')->eq(0);
+ $this->assertEquals(3, $top_pagination->filter('li')->count(), 'Number of pagination items on page 2 does not match');
+ $this->assertContainsLang('PREVIOUS', $top_pagination->filter('li')->eq(0)->text());
+ $this->assertContains('1', $top_pagination->filter('li')->eq(1)->text());
+ $this->assertContains('2', $top_pagination->filter('li')->eq(2)->text());
+ }
+
+ protected function assert_forum_details($forum_id, $details, $additional_error_message = '')
+ {
+ $this->db = $this->get_db();
+
+ $sql = 'SELECT ' . implode(', ', array_keys($details)) . '
+ FROM phpbb_forums
+ WHERE forum_id = ' . (int) $forum_id;
+ $result = $this->db->sql_query($sql);
+ $data = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ $this->assertEquals($details, $data, "Forum {$forum_id} does not match expected {$additional_error_message}");
+ }
+
+ /**
+ * Sets the post setting via the ACP page
+ *
+ * @param array $settings
+ */
+ protected function set_post_settings($settings)
+ {
+ $crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=post');
+
+ $form = $crawler->selectButton('Submit')->form();
+ $values = $form->getValues();
+
+ foreach ($settings as $setting => $value)
+ {
+ $values["config[{$setting}]"] = $value;
+ }
+ $form->setValues($values);
+ $crawler = self::submit($form);
+ $this->assertGreaterThan(0, $crawler->filter('.successbox')->count());
+ }
+
+ /**
+ * Loads forum, topic and post IDs
+ *
+ * @param array $data
+ */
+ protected function load_ids($data)
+ {
+ $this->db = $this->get_db();
+
+ if (!empty($data['forums']))
+ {
+ $sql = 'SELECT *
+ FROM phpbb_forums
+ WHERE ' . $this->db->sql_in_set('forum_name', $data['forums']);
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ if (in_array($row['forum_name'], $data['forums']))
+ {
+ $this->data['forums'][$row['forum_name']] = (int) $row['forum_id'];
+ }
+ }
+ $this->db->sql_freeresult($result);
+ }
+
+ if (!empty($data['topics']))
+ {
+ $sql = 'SELECT *
+ FROM phpbb_topics
+ WHERE ' . $this->db->sql_in_set('topic_title', $data['topics']);
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ if (in_array($row['topic_title'], $data['topics']))
+ {
+ $this->data['topics'][$row['topic_title']] = (int) $row['topic_id'];
+ }
+ }
+ $this->db->sql_freeresult($result);
+ }
+
+ if (!empty($data['posts']))
+ {
+ $sql = 'SELECT *
+ FROM phpbb_posts
+ WHERE ' . $this->db->sql_in_set('post_subject', $data['posts']);
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ if (in_array($row['post_subject'], $data['posts']))
+ {
+ $this->data['posts'][$row['post_subject']] = (int) $row['post_id'];
+ }
+ }
+ $this->db->sql_freeresult($result);
+ }
+ }
+}
diff --git a/tests/functions/build_url_test.php b/tests/functions/build_url_test.php
index 06415a424e..a59b94c744 100644
--- a/tests/functions/build_url_test.php
+++ b/tests/functions/build_url_test.php
@@ -69,6 +69,11 @@ class phpbb_build_url_test extends phpbb_test_case
array('f', 'style', 't'),
'http://test.phpbb.com/viewtopic.php?',
),
+ array(
+ 'posting.php?f=2&mode=delete&p=20%22%3Cscript%3Ealert%281%29%3B%3C%2Fscript%3E',
+ false,
+ 'phpBB/posting.php?f=2&amp;mode=delete&amp;p=20%22%3Cscript%3Ealert%281%29%3B%3C%2Fscript%3E',
+ )
);
}
diff --git a/tests/functions/make_clickable_test.php b/tests/functions/make_clickable_test.php
new file mode 100644
index 0000000000..e61cb2c30e
--- /dev/null
+++ b/tests/functions/make_clickable_test.php
@@ -0,0 +1,100 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php';
+
+class phpbb_functions_make_clickable_test extends phpbb_test_case
+{
+ /**
+ * Tags:
+ * 'm' - full URL like xxxx://aaaaa.bbb.cccc.
+ * 'l' - local relative board URL like http://domain.tld/path/to/board/index.php
+ * 'w' - URL without http/https protocol like www.xxxx.yyyy[/zzzz] aka 'lazy' URLs
+ * 'e' - email@domain type address
+ *
+ * Classes:
+ * "postlink-local" for 'l' URLs
+ * "postlink" for the rest of URLs
+ * empty for email addresses
+ **/
+ public function data_test_make_clickable_url_positive()
+ {
+ return array(
+ array(
+ 'http://www.phpbb.com/community/',
+ '<!-- m --><a class="postlink" href="http://www.phpbb.com/community/">http://www.phpbb.com/community/</a><!-- m -->'
+ ),
+ array(
+ 'http://www.phpbb.com/path/file.ext#section',
+ '<!-- m --><a class="postlink" href="http://www.phpbb.com/path/file.ext#section">http://www.phpbb.com/path/file.ext#section</a><!-- m -->'
+ ),
+ array(
+ 'ftp://ftp.phpbb.com/',
+ '<!-- m --><a class="postlink" href="ftp://ftp.phpbb.com/">ftp://ftp.phpbb.com/</a><!-- m -->'
+ ),
+ array(
+ 'sip://bantu@phpbb.com',
+ '<!-- m --><a class="postlink" href="sip://bantu@phpbb.com">sip://bantu@phpbb.com</a><!-- m -->'
+ ),
+ array(
+ 'www.phpbb.com/community/',
+ '<!-- w --><a class="postlink" href="http://www.phpbb.com/community/">www.phpbb.com/community/</a><!-- w -->'
+ ),
+ array(
+ 'http://testhost/viewtopic.php?t=1',
+ '<!-- l --><a class="postlink-local" href="http://testhost/viewtopic.php?t=1">viewtopic.php?t=1</a><!-- l -->'
+ ),
+ array(
+ 'email@domain.com',
+ '<!-- e --><a href="mailto:email@domain.com">email@domain.com</a><!-- e -->'
+ ),
+ // Test appending punctuation mark to the URL
+ array(
+ 'http://testhost/viewtopic.php?t=1!',
+ '<!-- l --><a class="postlink-local" href="http://testhost/viewtopic.php?t=1">viewtopic.php?t=1</a><!-- l -->!'
+ ),
+ array(
+ 'www.phpbb.com/community/?',
+ '<!-- w --><a class="postlink" href="http://www.phpbb.com/community/">www.phpbb.com/community/</a><!-- w -->?'
+ ),
+ // Test shortened text for URL > 55 characters long
+ // URL text should be turned into: first 39 chars + ' ... ' + last 10 chars
+ array(
+ 'http://www.phpbb.com/community/path/to/long/url/file.ext#section',
+ '<!-- m --><a class="postlink" href="http://www.phpbb.com/community/path/to/long/url/file.ext#section">http://www.phpbb.com/community/path/to/ ... xt#section</a><!-- m -->'
+ ),
+
+ // IDN is not parsed and returned as is
+ array('http://домен.рф', 'http://домен.рф'),
+ array('почта@домен.рф', 'почта@домен.рф'),
+ );
+ }
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ global $config, $user, $request;
+ $user = new phpbb_mock_user();
+ $request = new phpbb_mock_request();
+ }
+
+ /**
+ * @dataProvider data_test_make_clickable_url_positive
+ */
+ public function test_urls_matching_positive($url, $expected)
+ {
+ $this->assertSame($expected, make_clickable($url));
+ }
+}
diff --git a/tests/functions/validate_username_test.php b/tests/functions/validate_username_test.php
index dc9f685f04..4fa5af7ff3 100644
--- a/tests/functions/validate_username_test.php
+++ b/tests/functions/validate_username_test.php
@@ -11,6 +11,7 @@
*
*/
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php';
require_once dirname(__FILE__) . '/../mock/cache.php';
diff --git a/tests/functions/insert_config_array_test.php b/tests/functions_acp/insert_config_array_test.php
index bfcb05862e..1264b35bf4 100644
--- a/tests/functions/insert_config_array_test.php
+++ b/tests/functions_acp/insert_config_array_test.php
@@ -11,6 +11,8 @@
*
*/
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions_acp.php';
+
class phpbb_functions_insert_config_array_test extends phpbb_test_case
{
public function config_display_vars()
diff --git a/tests/mock/controller_helper.php b/tests/mock/controller_helper.php
index 9c13c309f2..ae3e7bf432 100644
--- a/tests/mock/controller_helper.php
+++ b/tests/mock/controller_helper.php
@@ -13,12 +13,13 @@
class phpbb_mock_controller_helper extends \phpbb\controller\helper
{
- public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext, $phpbb_root_path_ext)
+ public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext, $phpbb_root_path_ext)
{
$this->template = $template;
$this->user = $user;
$this->config = $config;
$this->symfony_request = $symfony_request;
+ $this->request = $request;
$this->filesystem = $filesystem;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
diff --git a/tests/mock/file_downloader.php b/tests/mock/file_downloader.php
new file mode 100644
index 0000000000..d8951cebf6
--- /dev/null
+++ b/tests/mock/file_downloader.php
@@ -0,0 +1,27 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+class phpbb_mock_file_downloader extends \phpbb\file_downloader
+{
+ public $data;
+
+ public function set($data)
+ {
+ $this->data = $data;
+ }
+
+ public function get($host, $directory, $filename, $port = 80, $timeout = 6)
+ {
+ return $this->data;
+ }
+}
diff --git a/tests/mock/metadata_manager.php b/tests/mock/metadata_manager.php
index 16900a0fc1..2443fad560 100644
--- a/tests/mock/metadata_manager.php
+++ b/tests/mock/metadata_manager.php
@@ -15,11 +15,13 @@ class phpbb_mock_metadata_manager extends \phpbb\extension\metadata_manager
{
public function set_metadata($metadata)
{
+ array_walk_recursive($metadata, array($this, 'sanitize_json'));
$this->metadata = $metadata;
}
public function merge_metadata($metadata)
{
+ array_walk_recursive($metadata, array($this, 'sanitize_json'));
$this->metadata = array_merge($this->metadata, $metadata);
}
}
diff --git a/tests/mock/request.php b/tests/mock/request.php
index 304fcf0eaf..e7217a94a9 100644
--- a/tests/mock/request.php
+++ b/tests/mock/request.php
@@ -114,4 +114,25 @@ class phpbb_mock_request implements \phpbb\request\request_interface
{
$this->data[$super_global] = array_merge($this->data[$super_global], $values);
}
+
+ public function escape($var, $multibyte)
+ {
+ $type_cast_helper = new \phpbb\request\type_cast_helper();
+ if (is_array($var))
+ {
+ $result = array();
+ foreach ($var as $key => $value)
+ {
+ $type_cast_helper->set_var($key, $key, gettype($key), $multibyte);
+ $result[$key] = $this->escape($value, $multibyte);
+ }
+ $var = $result;
+ }
+ else
+ {
+ $type_cast_helper->set_var($var, $var, 'string', $multibyte);
+ }
+
+ return $var;
+ }
}
diff --git a/tests/notification/group_request_test.php b/tests/notification/group_request_test.php
index afbc586601..0d1bda95ce 100644
--- a/tests/notification/group_request_test.php
+++ b/tests/notification/group_request_test.php
@@ -12,6 +12,7 @@
*/
require_once dirname(__FILE__) . '/base.php';
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
class phpbb_notification_group_request_test extends phpbb_tests_notification_base
{
diff --git a/tests/pagination/pagination_test.php b/tests/pagination/pagination_test.php
index d36aa11a8a..494c667198 100644
--- a/tests/pagination/pagination_test.php
+++ b/tests/pagination/pagination_test.php
@@ -57,7 +57,7 @@ class phpbb_pagination_pagination_test extends phpbb_template_template_test_case
$request
);
- $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $provider, $manager, $symfony_request, $filesystem, '', 'php', dirname(__FILE__) . '/');
+ $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $provider, $manager, $symfony_request, $request, $filesystem, '', 'php', dirname(__FILE__) . '/');
$this->pagination = new \phpbb\pagination($this->template, $this->user, $this->helper, $phpbb_dispatcher);
}
diff --git a/tests/passwords/drivers_test.php b/tests/passwords/drivers_test.php
index ccfb05c40f..5f9fd523c9 100644
--- a/tests/passwords/drivers_test.php
+++ b/tests/passwords/drivers_test.php
@@ -35,7 +35,7 @@ class phpbb_passwords_helper_test extends \phpbb_test_case
'passwords.driver.md5_vb' => new \phpbb\passwords\driver\md5_vb($config, $this->driver_helper),
'passwords.driver.sha_xf1' => new \phpbb\passwords\driver\sha_xf1($config, $this->driver_helper),
);
- $this->passwords_drivers['passwords.driver.md5_phpbb2'] = new \phpbb\passwords\driver\md5_phpbb2($request, $this->passwords_drivers['passwords.driver.salted_md5'], $phpbb_root_path, $php_ext);
+ $this->passwords_drivers['passwords.driver.md5_phpbb2'] = new \phpbb\passwords\driver\md5_phpbb2($request, $this->passwords_drivers['passwords.driver.salted_md5'], $this->driver_helper, $phpbb_root_path, $php_ext);
$this->passwords_drivers['passwords.driver.bcrypt_wcf2'] = new \phpbb\passwords\driver\bcrypt_wcf2($this->passwords_drivers['passwords.driver.bcrypt'], $this->driver_helper);
}
diff --git a/tests/passwords/manager_test.php b/tests/passwords/manager_test.php
index e46cf820f2..333834ee07 100644
--- a/tests/passwords/manager_test.php
+++ b/tests/passwords/manager_test.php
@@ -41,7 +41,7 @@ class phpbb_passwords_manager_test extends \phpbb_test_case
'passwords.driver.md5_vb' => new \phpbb\passwords\driver\md5_vb($config, $this->driver_helper),
'passwords.driver.sha_xf1' => new \phpbb\passwords\driver\sha_xf1($config, $this->driver_helper),
);
- $this->passwords_drivers['passwords.driver.md5_phpbb2'] = new \phpbb\passwords\driver\md5_phpbb2($request, $this->passwords_drivers['passwords.driver.salted_md5'], $phpbb_root_path, $php_ext);
+ $this->passwords_drivers['passwords.driver.md5_phpbb2'] = new \phpbb\passwords\driver\md5_phpbb2($request, $this->passwords_drivers['passwords.driver.salted_md5'], $this->driver_helper, $phpbb_root_path, $php_ext);
$this->passwords_drivers['passwords.driver.bcrypt_wcf2'] = new \phpbb\passwords\driver\bcrypt_wcf2($this->passwords_drivers['passwords.driver.bcrypt'], $this->driver_helper);
$this->helper = new \phpbb\passwords\helper;
@@ -326,4 +326,22 @@ class phpbb_passwords_manager_test extends \phpbb_test_case
$this->assertFalse($this->manager->hash(str_repeat('a', 1024 * 1024 * 16)));
$this->assertLessThanOrEqual(5, time() - $start_time);
}
+
+ public function data_test_string_compare()
+ {
+ return array(
+ array('foo', 'bar', false),
+ array(1, '1', false),
+ array('one', 'one', true),
+ array('foobar', 'foobaf', false),
+ );
+ }
+
+ /**
+ * @dataProvider data_test_string_compare
+ */
+ public function test_string_compare($a, $b, $expected)
+ {
+ $this->assertSame($expected, $this->driver_helper->string_compare($a, $b));
+ }
}
diff --git a/tests/path_helper/path_helper_test.php b/tests/path_helper/path_helper_test.php
index 3832307897..bb68f8b3bc 100644
--- a/tests/path_helper/path_helper_test.php
+++ b/tests/path_helper/path_helper_test.php
@@ -411,6 +411,21 @@ class phpbb_path_helper_test extends phpbb_test_case
'http://www.phpbb.com/community',
'../community/',
),
+ array(
+ 'http://www.phpbb.com/foobar',
+ 'http://www.phpbb.com',
+ '',
+ ),
+ array(
+ 'http://www.foobar.com',
+ 'http://www.phpbb.com',
+ '/www.phpbb.com/',
+ ),
+ array(
+ 'foobar',
+ 'http://www.phpbb.com/community',
+ '',
+ )
);
}
diff --git a/tests/security/base.php b/tests/security/base.php
index 5519cac441..330408b448 100644
--- a/tests/security/base.php
+++ b/tests/security/base.php
@@ -13,6 +13,8 @@
abstract class phpbb_security_test_base extends phpbb_test_case
{
+ protected $server = array();
+
/**
* Set up the required user object and server variables for the suites
*/
@@ -21,17 +23,18 @@ abstract class phpbb_security_test_base extends phpbb_test_case
global $user, $phpbb_root_path, $phpEx, $request, $symfony_request, $phpbb_filesystem;
// Put this into a global function being run by every test to init a proper user session
- $server['HTTP_HOST'] = 'localhost';
- $server['SERVER_NAME'] = 'localhost';
- $server['SERVER_ADDR'] = '127.0.0.1';
- $server['SERVER_PORT'] = 80;
- $server['REMOTE_ADDR'] = '127.0.0.1';
- $server['QUERY_STRING'] = '';
- $server['REQUEST_URI'] = '/tests/';
- $server['SCRIPT_NAME'] = '/tests/index.php';
- $server['PHP_SELF'] = '/tests/index.php';
- $server['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14';
- $server['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
+ $this->server['HTTP_HOST'] = 'localhost';
+ $this->server['SERVER_NAME'] = 'localhost';
+ $this->server['SERVER_ADDR'] = '127.0.0.1';
+ $this->server['SERVER_PORT'] = 80;
+ $this->server['REMOTE_ADDR'] = '127.0.0.1';
+ $this->server['QUERY_STRING'] = '';
+ $this->server['REQUEST_URI'] = '/tests/';
+ $this->server['SCRIPT_NAME'] = '/tests/index.php';
+ $this->server['SCRIPT_FILENAME'] = '/var/www/tests/index.php';
+ $this->server['PHP_SELF'] = '/tests/index.php';
+ $this->server['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14';
+ $this->server['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
/*
[HTTP_ACCEPT_ENCODING] => gzip,deflate
@@ -40,31 +43,18 @@ abstract class phpbb_security_test_base extends phpbb_test_case
[SCRIPT_FILENAME] => /var/www/tests/index.php
*/
- $request = new phpbb_mock_request(array(), array(), array(), $server);
- $symfony_request = $this->getMock("\phpbb\symfony_request", array(), array(
- $request,
- ));
- $symfony_request->expects($this->any())
- ->method('getScriptName')
- ->will($this->returnValue($server['SCRIPT_NAME']));
- $symfony_request->expects($this->any())
- ->method('getQueryString')
- ->will($this->returnValue($server['QUERY_STRING']));
- $symfony_request->expects($this->any())
- ->method('getBasePath')
- ->will($this->returnValue($server['REQUEST_URI']));
- $symfony_request->expects($this->any())
- ->method('getPathInfo')
- ->will($this->returnValue('/'));
- $phpbb_filesystem = new \phpbb\filesystem($symfony_request, $phpbb_root_path, $phpEx);
+ $request = new phpbb_mock_request(array(), array(), array(), $this->server);
+ $symfony_request = new \phpbb\symfony_request($request);
+
+ $phpbb_filesystem = new \phpbb\filesystem();
// Set no user and trick a bit to circumvent errors
$user = new \phpbb\user('\phpbb\datetime');
$user->lang = true;
- $user->browser = $server['HTTP_USER_AGENT'];
+ $user->browser = $this->server['HTTP_USER_AGENT'];
$user->referer = '';
$user->forwarded_for = '';
- $user->host = $server['HTTP_HOST'];
+ $user->host = $this->server['HTTP_HOST'];
$user->page = \phpbb\session::extract_current_page($phpbb_root_path);
}
diff --git a/tests/security/extract_current_page_test.php b/tests/security/extract_current_page_test.php
index 58dea68dc8..767b901a43 100644
--- a/tests/security/extract_current_page_test.php
+++ b/tests/security/extract_current_page_test.php
@@ -20,33 +20,25 @@ class phpbb_security_extract_current_page_test extends phpbb_security_test_base
public function security_variables()
{
return array(
- array('http://localhost/phpBB/index.php', 'mark=forums&x="><script>alert(/XSS/);</script>', 'mark=forums&x=%22%3E%3Cscript%3Ealert(/XSS/);%3C/script%3E'),
- array('http://localhost/phpBB/index.php', 'mark=forums&x=%22%3E%3Cscript%3Ealert(/XSS/);%3C/script%3E', 'mark=forums&x=%22%3E%3Cscript%3Ealert(/XSS/);%3C/script%3E'),
+ array('mark=forums&x="><script>alert(/XSS/);</script>', 'mark=forums&x=%22%3E%3Cscript%3Ealert%28%2FXSS%2F%29%3B%3C%2Fscript%3E'),
+ array('mark=forums&x=%22%3E%3Cscript%3Ealert(/XSS/);%3C/script%3E', 'mark=forums&x=%22%3E%3Cscript%3Ealert%28%2FXSS%2F%29%3B%3C%2Fscript%3E'),
+ array('mark=forums&x=%22%3E%3Cscript%3Ealert%28%2FXSS%2F%29%3B%3C%2Fscript%3E', 'mark=forums&x=%22%3E%3Cscript%3Ealert%28%2FXSS%2F%29%3B%3C%2Fscript%3E'),
);
}
/**
* @dataProvider security_variables
*/
- public function test_query_string_php_self($url, $query_string, $expected)
+ public function test_query_string_php_self($query_string, $expected)
{
global $symfony_request, $request;
- $symfony_request = $this->getMock("\phpbb\symfony_request", array(), array(
- $request,
- ));
- $symfony_request->expects($this->any())
- ->method('getScriptName')
- ->will($this->returnValue($url));
- $symfony_request->expects($this->any())
- ->method('getQueryString')
- ->will($this->returnValue($query_string));
- $symfony_request->expects($this->any())
- ->method('getBasePath')
- ->will($this->returnValue($server['REQUEST_URI']));
- $symfony_request->expects($this->any())
- ->method('getPathInfo')
- ->will($this->returnValue('/'));
+ $this->server['REQUEST_URI'] = '';
+ $this->server['QUERY_STRING'] = $query_string;
+
+ $request = new phpbb_mock_request(array(), array(), array(), $this->server);
+ $symfony_request = new \phpbb\symfony_request($request);
+
$result = \phpbb\session::extract_current_page('./');
$label = 'Running extract_current_page on ' . $query_string . ' with PHP_SELF filled.';
@@ -56,25 +48,14 @@ class phpbb_security_extract_current_page_test extends phpbb_security_test_base
/**
* @dataProvider security_variables
*/
- public function test_query_string_request_uri($url, $query_string, $expected)
+ public function test_query_string_request_uri($query_string, $expected)
{
global $symfony_request, $request;
- $symfony_request = $this->getMock("\phpbb\symfony_request", array(), array(
- $request,
- ));
- $symfony_request->expects($this->any())
- ->method('getScriptName')
- ->will($this->returnValue($url));
- $symfony_request->expects($this->any())
- ->method('getQueryString')
- ->will($this->returnValue($query_string));
- $symfony_request->expects($this->any())
- ->method('getBasePath')
- ->will($this->returnValue($server['REQUEST_URI']));
- $symfony_request->expects($this->any())
- ->method('getPathInfo')
- ->will($this->returnValue('/'));
+ $this->server['QUERY_STRING'] = $query_string;
+
+ $request = new phpbb_mock_request(array(), array(), array(), $this->server);
+ $symfony_request = new \phpbb\symfony_request($request);
$result = \phpbb\session::extract_current_page('./');
diff --git a/tests/security/redirect_test.php b/tests/security/redirect_test.php
index 3961c2781e..21fb103ed1 100644
--- a/tests/security/redirect_test.php
+++ b/tests/security/redirect_test.php
@@ -73,6 +73,8 @@ class phpbb_security_redirect_test extends phpbb_security_test_base
protected function setUp()
{
+ global $phpbb_dispatcher;
+
parent::setUp();
$GLOBALS['config'] = array(
@@ -80,6 +82,8 @@ class phpbb_security_redirect_test extends phpbb_security_test_base
);
$this->path_helper = $this->get_path_helper();
+
+ $phpbb_dispatcher = new phpbb_mock_event_dispatcher();
}
/**
diff --git a/tests/session/extract_page_test.php b/tests/session/extract_page_test.php
index f314d35f87..f0d1cdb60e 100644
--- a/tests/session/extract_page_test.php
+++ b/tests/session/extract_page_test.php
@@ -12,6 +12,7 @@
*/
require_once dirname(__FILE__) . '/../test_framework/phpbb_session_test_case.php';
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
class phpbb_session_extract_page_test extends phpbb_session_test_case
{
@@ -99,7 +100,7 @@ class phpbb_session_extract_page_test extends phpbb_session_test_case
// ^-- Ignored because .. returns different directory in live vs testing
'query_string' => '',
'script_path' => '/phpBB/adm/',
- //'root_script_path' => '/phpBB/',
+ //'root_script_path' => '/phpBB/adm/',
//'page' => 'adm/index.php',
'forum' => 0,
),
@@ -108,15 +109,15 @@ class phpbb_session_extract_page_test extends phpbb_session_test_case
'./',
'/phpBB/adm/app.php',
'page=1&test=2',
- '/phpBB/',
+ '/phpBB/adm/',
'/foo/bar',
array(
'page_name' => 'app.php/foo/bar',
- 'page_dir' => '',
+ //'page_dir' => '',
'query_string' => 'page=1&test=2',
- 'script_path' => '/phpBB/',
- 'root_script_path' => '/phpBB/',
- 'page' => 'app.php/foo/bar?page=1&test=2',
+ 'script_path' => '/phpBB/adm/',
+ //'root_script_path' => '/phpBB/adm/',
+ //'page' => 'app.php/foo/bar?page=1&test=2',
'forum' => 0,
),
),
@@ -142,23 +143,25 @@ class phpbb_session_extract_page_test extends phpbb_session_test_case
/** @dataProvider extract_current_page_data */
function test_extract_current_page($root_path, $getScriptName, $getQueryString, $getBasePath, $getPathInfo, $expected)
{
- global $symfony_request;
+ global $symfony_request, $request, $phpbb_filesystem;
+
+ $phpbb_filesystem = new \phpbb\filesystem();
+
+ $server['HTTP_HOST'] = 'localhost';
+ $server['SERVER_NAME'] = 'localhost';
+ $server['SERVER_ADDR'] = '127.0.0.1';
+ $server['SERVER_PORT'] = 80;
+ $server['REMOTE_ADDR'] = '127.0.0.1';
+ $server['QUERY_STRING'] = $getQueryString;
+ $server['REQUEST_URI'] = $getScriptName . $getPathInfo . ($getQueryString === '' ? '' : '?' . $getQueryString);
+ $server['SCRIPT_NAME'] = $getScriptName;
+ $server['SCRIPT_FILENAME'] = '/var/www/' . $getScriptName;
+ $server['PHP_SELF'] = $getScriptName;
+ $server['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14';
+ $server['HTTP_ACCEPT_LANGUAGE'] = 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3';
- $symfony_request = $this->getMock("\phpbb\symfony_request", array(), array(
- new phpbb_mock_request(),
- ));
- $symfony_request->expects($this->any())
- ->method('getScriptName')
- ->will($this->returnValue($getScriptName));
- $symfony_request->expects($this->any())
- ->method('getQueryString')
- ->will($this->returnValue($getQueryString));
- $symfony_request->expects($this->any())
- ->method('getBasePath')
- ->will($this->returnValue($getBasePath));
- $symfony_request->expects($this->any())
- ->method('getPathInfo')
- ->will($this->returnValue($getPathInfo));
+ $request = new phpbb_mock_request(array(), array(), array(), $server);
+ $symfony_request = new \phpbb\symfony_request($request);
$output = \phpbb\session::extract_current_page($root_path);
diff --git a/tests/template/ext/include/css/styles/all/theme/child_only.css b/tests/template/ext/include/css/styles/all/theme/child_only.css
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/template/ext/include/css/styles/all/theme/child_only.css
diff --git a/tests/template/ext/include/css/styles/all/theme/test.css b/tests/template/ext/include/css/styles/all/theme/test.css
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/template/ext/include/css/styles/all/theme/test.css
diff --git a/tests/template/template_includecss_test.php b/tests/template/template_includecss_test.php
index ab91dd7a49..49bd9dec8b 100644
--- a/tests/template/template_includecss_test.php
+++ b/tests/template/template_includecss_test.php
@@ -15,18 +15,90 @@ require_once dirname(__FILE__) . '/template_test_case_with_tree.php';
class phpbb_template_template_includecss_test extends phpbb_template_template_test_case_with_tree
{
- public function test_includecss_compilation()
+ protected function setup_engine(array $new_config = array())
+ {
+ global $phpbb_root_path, $phpEx, $user;
+
+ $defaults = $this->config_defaults();
+ $config = new \phpbb\config\config(array_merge($defaults, $new_config));
+
+ $this->phpbb_path_helper = new \phpbb\path_helper(
+ new \phpbb\symfony_request(
+ new phpbb_mock_request()
+ ),
+ new \phpbb\filesystem(),
+ $this->getMock('\phpbb\request\request'),
+ $phpbb_root_path,
+ $phpEx
+ );
+
+ $this->template_path = $this->test_path . '/templates';
+ $this->parent_template_path = $this->test_path . '/parent_templates';
+ $this->template = new phpbb\template\twig\twig(
+ $this->phpbb_path_helper,
+ $config,
+ $user,
+ new phpbb\template\context(),
+ new phpbb_mock_extension_manager(
+ dirname(__FILE__) . '/',
+ array(
+ 'include/css' => array(
+ 'ext_name' => 'include/css',
+ 'ext_active' => '1',
+ 'ext_path' => 'ext/include/css/',
+ ),
+ )
+ )
+ );
+ $this->template->set_custom_style('tests', array($this->template_path, $this->parent_template_path));
+ }
+
+ public function template_data()
+ {
+ $url_base = explode('/', dirname(__FILE__));
+ foreach ($url_base as &$dir)
+ {
+ $dir = rawurlencode($dir);
+ }
+ $url_base = implode('/', $url_base);
+
+ return array(
+ /*
+ array(
+ // vars
+ // expected
+ ),
+ */
+ array(
+ array('TEST' => 1),
+ '<link href="tests/template/templates/child_only.css?assets_version=1" rel="stylesheet" type="text/css" media="screen, projection" />',
+ ),
+ array(
+ array('TEST' => 2),
+ '<link href="tests/template/parent_templates/parent_only.css?assets_version=1" rel="stylesheet" type="text/css" media="screen, projection" />',
+ ),
+ array(
+ array('TEST' => 3),
+ '<link href="' . $url_base . '/ext/include/css/styles/all/theme/test.css?assets_version=1" rel="stylesheet" type="text/css" media="screen, projection" />',
+ ),
+ array(
+ array('TEST' => 4),
+ '<link href="' . $url_base . '/ext/include/css/styles/all/theme/child_only.css?assets_version=1" rel="stylesheet" type="text/css" media="screen, projection" />',
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider template_data
+ */
+ public function test_includecss_compilation($vars, $expected)
{
// Reset the engine state
$this->setup_engine(array('assets_version' => 1));
- // Prepare correct result
- $scripts = array(
- '<link href="tests/template/templates/child_only.css?assets_version=1" rel="stylesheet" type="text/css" media="screen, projection" />',
- '<link href="tests/template/parent_templates/parent_only.css?assets_version=1" rel="stylesheet" type="text/css" media="screen, projection" />',
- );
+ $this->template->assign_vars($vars);
// Run test
- $this->run_template('includecss.html', array(), array(), array(), implode('', $scripts));
+ $this->run_template('includecss.html', array(), array(), array(), $expected);
}
}
diff --git a/tests/template/templates/includecss.html b/tests/template/templates/includecss.html
index a09e44f240..23e3c426d7 100644
--- a/tests/template/templates/includecss.html
+++ b/tests/template/templates/includecss.html
@@ -1,3 +1,10 @@
-<!-- INCLUDECSS child_only.css -->
-<!-- INCLUDECSS parent_only.css -->
+<!-- IF TEST === 1 -->
+ <!-- INCLUDECSS child_only.css -->
+<!-- ELSEIF TEST === 2 -->
+ <!-- INCLUDECSS parent_only.css -->
+<!-- ELSEIF TEST === 3 -->
+ <!-- INCLUDECSS @include_css/test.css -->
+<!-- ELSEIF TEST === 4 -->
+ <!-- INCLUDECSS @include_css/child_only.css -->
+<!-- ENDIF -->
{$STYLESHEETS}
diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php
index 49cc72363e..51bae7a723 100644
--- a/tests/test_framework/phpbb_functional_test_case.php
+++ b/tests/test_framework/phpbb_functional_test_case.php
@@ -38,6 +38,7 @@ class phpbb_functional_test_case extends phpbb_test_case
static protected $config = array();
static protected $already_installed = false;
+ static protected $last_post_timestamp = 0;
static public function setUpBeforeClass()
{
@@ -556,12 +557,10 @@ class phpbb_functional_test_case extends phpbb_test_case
$cache = new phpbb_mock_null_cache;
$cache_driver = new \phpbb\cache\driver\null();
- $phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
- $phpbb_container
- ->expects($this->any())
- ->method('get')
- ->with('cache.driver')
- ->will($this->returnValue($cache_driver));
+ $phpbb_container = new phpbb_mock_container_builder();
+ $phpbb_container->set('cache.driver', $cache_driver);
+ $phpbb_notifications = new phpbb_mock_notification_manager();
+ $phpbb_container->set('notification_manager', $phpbb_notifications);
if (!function_exists('utf_clean_string'))
{
@@ -1100,6 +1099,12 @@ class phpbb_functional_test_case extends phpbb_test_case
*/
protected function submit_message($posting_url, $posting_contains, $form_data)
{
+ if (time() == self::$last_post_timestamp)
+ {
+ // Travis is too fast, so we have to wait to not mix up the post/topic order
+ sleep(1);
+ }
+ self::$last_post_timestamp = time();
$crawler = self::request('GET', $posting_url);
$this->assertContains($this->lang($posting_contains), $crawler->filter('html')->text());
diff --git a/tests/test_framework/phpbb_session_test_case.php b/tests/test_framework/phpbb_session_test_case.php
index efad4d5166..1bf0277fe0 100644
--- a/tests/test_framework/phpbb_session_test_case.php
+++ b/tests/test_framework/phpbb_session_test_case.php
@@ -11,6 +11,7 @@
*
*/
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
require_once dirname(__FILE__) . '/../session/testable_factory.php';
require_once dirname(__FILE__) . '/../session/testable_facade.php';
diff --git a/tests/test_framework/phpbb_test_case.php b/tests/test_framework/phpbb_test_case.php
index c39f7835d1..01d26fb67d 100644
--- a/tests/test_framework/phpbb_test_case.php
+++ b/tests/test_framework/phpbb_test_case.php
@@ -26,7 +26,7 @@ class phpbb_test_case extends PHPUnit_Framework_TestCase
'PHP_Token_Stream' => array('customTokens'),
'PHP_Token_Stream_CachingFactory' => array('cache'),
- 'phpbb_database_test_case' => array('already_connected'),
+ 'phpbb_database_test_case' => array('already_connected', 'last_post_timestamp'),
);
}
diff --git a/tests/test_framework/phpbb_ui_test_case.php b/tests/test_framework/phpbb_ui_test_case.php
new file mode 100644
index 0000000000..c8ac492e25
--- /dev/null
+++ b/tests/test_framework/phpbb_ui_test_case.php
@@ -0,0 +1,204 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+require_once __DIR__ . '/../../phpBB/includes/functions_install.php';
+
+class phpbb_ui_test_case extends phpbb_test_case
+{
+ static protected $host = '127.0.0.1';
+ static protected $port = 8910;
+
+ /**
+ * @var \RemoteWebDriver
+ */
+ static protected $webDriver;
+
+ static protected $config;
+ static protected $root_url;
+ static protected $already_installed = false;
+
+ static public function setUpBeforeClass()
+ {
+ parent::setUpBeforeClass();
+
+ if (version_compare(PHP_VERSION, '5.3.19', '<'))
+ {
+ self::markTestSkipped('UI test case requires at least PHP 5.3.19.');
+ }
+ else if (!class_exists('\RemoteWebDriver'))
+ {
+ self::markTestSkipped(
+ 'Could not find RemoteWebDriver class. ' .
+ 'Run "php ../composer.phar install" from the tests folder.'
+ );
+ }
+
+ self::$config = phpbb_test_case_helpers::get_test_config();
+ self::$root_url = self::$config['phpbb_functional_url'];
+
+ // Important: this is used both for installation and by
+ // test cases for querying the tables.
+ // Therefore table prefix must be set before a board is
+ // installed, and also before each test case is run.
+ self::$config['table_prefix'] = 'phpbb_';
+
+ if (!isset(self::$config['phpbb_functional_url']))
+ {
+ self::markTestSkipped('phpbb_functional_url was not set in test_config and wasn\'t set as PHPBB_FUNCTIONAL_URL environment variable either.');
+ }
+
+ if (!self::$webDriver)
+ {
+ try {
+ $capabilities = array(\WebDriverCapabilityType::BROWSER_NAME => 'firefox');
+ self::$webDriver = RemoteWebDriver::create(self::$host . ':' . self::$port, $capabilities);
+ } catch (WebDriverCurlException $e) {
+ self::markTestSkipped('PhantomJS webserver is not running.');
+ }
+ }
+
+ if (!self::$already_installed)
+ {
+ self::install_board();
+ self::$already_installed = true;
+ }
+ }
+
+ static public function visit($path)
+ {
+ self::$webDriver->get(self::$root_url . $path);
+ }
+
+ static protected function recreate_database($config)
+ {
+ $db_conn_mgr = new phpbb_database_test_connection_manager($config);
+ $db_conn_mgr->recreate_db();
+ }
+
+ static public function find_element($type, $value)
+ {
+ return self::$webDriver->findElement(WebDriverBy::$type($value));
+ }
+
+ static public function submit($type = 'id', $value = 'submit')
+ {
+ $element = self::find_element($type, $value);
+ $element->click();
+ }
+
+ static public function install_board()
+ {
+ global $phpbb_root_path, $phpEx;
+
+ self::recreate_database(self::$config);
+
+ $config_file = $phpbb_root_path . "config.$phpEx";
+ $config_file_dev = $phpbb_root_path . "config_dev.$phpEx";
+ $config_file_test = $phpbb_root_path . "config_test.$phpEx";
+
+ if (file_exists($config_file))
+ {
+ if (!file_exists($config_file_dev))
+ {
+ rename($config_file, $config_file_dev);
+ }
+ else
+ {
+ unlink($config_file);
+ }
+ }
+
+ $parseURL = parse_url(self::$config['phpbb_functional_url']);
+
+ self::visit('install/index.php?mode=install&language=en');
+ self::assertContains('Welcome to Installation', self::find_element('id', 'main')->getText());
+
+ // install/index.php?mode=install&sub=requirements
+ self::submit();
+ self::assertContains('Installation compatibility', self::find_element('id', 'main')->getText());
+
+ // install/index.php?mode=install&sub=database
+ self::submit();
+ self::assertContains('Database configuration', self::find_element('id', 'main')->getText());
+
+ self::find_element('id','dbms')->sendKeys(str_replace('phpbb\db\driver\\', '', self::$config['dbms']));
+ self::find_element('id','dbhost')->sendKeys(self::$config['dbhost']);
+ self::find_element('id','dbport')->sendKeys(self::$config['dbport']);
+ self::find_element('id','dbname')->sendKeys(self::$config['dbname']);
+ self::find_element('id','dbuser')->sendKeys(self::$config['dbuser']);
+ self::find_element('id','dbpasswd')->sendKeys(self::$config['dbpasswd']);
+
+ // Need to clear default phpbb_ prefix
+ self::find_element('id','table_prefix')->clear();
+ self::find_element('id','table_prefix')->sendKeys(self::$config['table_prefix']);
+
+ // install/index.php?mode=install&sub=database
+ self::submit();
+ self::assertContains('Successful connection', self::find_element('id','main')->getText());
+
+ // install/index.php?mode=install&sub=administrator
+ self::submit();
+ self::assertContains('Administrator configuration', self::find_element('id','main')->getText());
+
+ self::find_element('id','admin_name')->sendKeys('admin');
+ self::find_element('id','admin_pass1')->sendKeys('adminadmin');
+ self::find_element('id','admin_pass2')->sendKeys('adminadmin');
+ self::find_element('id','board_email')->sendKeys('nobody@example.com');
+
+ // install/index.php?mode=install&sub=administrator
+ self::submit();
+ self::assertContains('Tests passed', self::find_element('id','main')->getText());
+
+ // install/index.php?mode=install&sub=config_file
+ self::submit();
+
+ // Installer has created a config.php file, we will overwrite it with a
+ // config file of our own in order to get the DEBUG constants defined
+ $config_php_data = phpbb_create_config_file_data(self::$config, self::$config['dbms'], true, false, true);
+ $config_created = file_put_contents($config_file, $config_php_data) !== false;
+ if (!$config_created)
+ {
+ self::markTestSkipped("Could not write $config_file file.");
+ }
+
+ if (strpos(self::find_element('id','main')->getText(), 'The configuration file has been written') === false)
+ {
+ self::submit('id', 'dldone');
+ }
+ self::assertContains('The configuration file has been written', self::find_element('id','main')->getText());
+
+ // install/index.php?mode=install&sub=advanced
+ self::submit();
+ self::assertContains('The settings on this page are only necessary to set if you know that you require something different from the default.', self::find_element('id','main')->getText());
+
+ self::find_element('id','smtp_delivery')->sendKeys('1');
+ self::find_element('id','smtp_host')->sendKeys('nxdomain.phpbb.com');
+ self::find_element('id','smtp_user')->sendKeys('nxuser');
+ self::find_element('id','smtp_pass')->sendKeys('nxpass');
+ self::find_element('id','server_protocol')->sendKeys($parseURL['scheme'] . '://');
+ self::find_element('id','server_name')->sendKeys('localhost');
+ self::find_element('id','server_port')->sendKeys(isset($parseURL['port']) ? $parseURL['port'] : 80);
+ self::find_element('id','script_path')->sendKeys($parseURL['path']);
+
+ // install/index.php?mode=install&sub=create_table
+ self::submit();
+ self::assertContains('The database tables used by phpBB', self::find_element('id','main')->getText());
+ self::assertContains('have been created and populated with some initial data.', self::find_element('id','main')->getText());
+
+ // install/index.php?mode=install&sub=final
+ self::submit();
+ self::assertContains('You have successfully installed', self::find_element('id', 'main')->getText());
+
+ copy($config_file, $config_file_test);
+ }
+}
diff --git a/tests/tree/nestedset_forum_base.php b/tests/tree/nestedset_forum_base.php
index 449b2e5ca8..c56be1f81e 100644
--- a/tests/tree/nestedset_forum_base.php
+++ b/tests/tree/nestedset_forum_base.php
@@ -11,6 +11,8 @@
*
*/
+require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
+
class phpbb_tests_tree_nestedset_forum_base extends phpbb_database_test_case
{
public function getDataSet()
diff --git a/tests/ui/quick_links_test.php b/tests/ui/quick_links_test.php
new file mode 100644
index 0000000000..5bddb44a8b
--- /dev/null
+++ b/tests/ui/quick_links_test.php
@@ -0,0 +1,27 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+/**
+* @group ui
+*/
+class quick_links_test extends phpbb_ui_test_case
+{
+
+ public function test_quick_links()
+ {
+ $this->visit('index.php');
+ $this->assertEmpty(self::find_element('className', 'dropdown')->getText());
+ self::find_element('className', 'dropdown-toggle')->click();
+ $this->assertNotNull(self::find_element('className', 'dropdown')->getText());
+ }
+}
diff --git a/tests/version/version_fetch_test.php b/tests/version/version_fetch_test.php
index 05eac58a52..cfc87183cf 100644
--- a/tests/version/version_fetch_test.php
+++ b/tests/version/version_fetch_test.php
@@ -33,6 +33,7 @@ class phpbb_version_helper_fetch_test extends phpbb_test_case
new \phpbb\config\config(array(
'version' => '3.1.0',
)),
+ new \phpbb\file_downloader(),
new \phpbb\user('\phpbb\datetime')
);
}
diff --git a/tests/version/version_helper_remote_test.php b/tests/version/version_helper_remote_test.php
new file mode 100644
index 0000000000..65ae7646b9
--- /dev/null
+++ b/tests/version/version_helper_remote_test.php
@@ -0,0 +1,173 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+class version_helper_remote_test extends \phpbb_test_case
+{
+ protected $file_downloader;
+ protected $cache;
+ protected $version_helper;
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ global $phpbb_root_path, $phpEx;
+
+ include_once($phpbb_root_path . 'includes/functions.' . $phpEx);
+
+ $config = new \phpbb\config\config(array(
+ 'version' => '3.1.0',
+ ));
+ $container = new \phpbb_mock_container_builder();
+ $db = new \phpbb\db\driver\factory($container);
+ $this->cache = $this->getMock('\phpbb\cache\service', array('get'), array(new \phpbb\cache\driver\null(), $config, $db, '../../', 'php'));
+ $this->cache->expects($this->any())
+ ->method('get')
+ ->with($this->anything())
+ ->will($this->returnValue(false));
+ $this->file_downloader = new phpbb_mock_file_downloader();
+
+ $this->version_helper = new \phpbb\version_helper(
+ $this->cache,
+ $config,
+ $this->file_downloader,
+ new \phpbb\user('\phpbb\datetime')
+ );
+ $this->user = new \phpbb\user('\phpbb\datetime');
+ $this->user->add_lang('acp/common');
+ }
+
+ public function provider_get_versions()
+ {
+ return array(
+ array('', false),
+ array('foobar', false),
+ array('{
+ "stable": {
+ "1.0": {
+ "current": "1.0.1",
+ "download": "https://www.phpbb.com/customise/db/download/104136",
+ "announcement": "https://www.phpbb.com/customise/db/extension/boardrules/",
+ "eol": null,
+ "security": false
+ }
+ }
+}', true, array (
+ 'stable' => array (
+ '1.0' => array (
+ 'current' => '1.0.1',
+ 'download' => 'https://www.phpbb.com/customise/db/download/104136',
+ 'announcement' => 'https://www.phpbb.com/customise/db/extension/boardrules/',
+ 'eol' => NULL,
+ 'security' => false,
+ ),
+ ),
+ 'unstable' => array (
+ '1.0' => array (
+ 'current' => '1.0.1',
+ 'download' => 'https://www.phpbb.com/customise/db/download/104136',
+ 'announcement' => 'https://www.phpbb.com/customise/db/extension/boardrules/',
+ 'eol' => NULL,
+ 'security' => false,
+ ),
+ ),
+ )),
+ array('{
+ "foobar": {
+ "1.0": {
+ "current": "1.0.1",
+ "download": "https://www.phpbb.com/customise/db/download/104136",
+ "announcement": "https://www.phpbb.com/customise/db/extension/boardrules/",
+ "eol": null,
+ "security": false
+ }
+ }
+}', false),
+ array('{
+ "stable": {
+ "1.0": {
+ "current": "1.0.1<script>alert(\'foo\');</script>",
+ "download": "https://www.phpbb.com/customise/db/download/104136<script>alert(\'foo\');</script>",
+ "announcement": "https://www.phpbb.com/customise/db/extension/boardrules/<script>alert(\'foo\');</script>",
+ "eol": "<script>alert(\'foo\');</script>",
+ "security": "<script>alert(\'foo\');</script>"
+ }
+ }
+}', true, array (
+ 'stable' => array (
+ '1.0' => array (
+ 'current' => '1.0.1&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'download' => 'https://www.phpbb.com/customise/db/download/104136&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'announcement' => 'https://www.phpbb.com/customise/db/extension/boardrules/&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'eol' => '&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'security' => '&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ ),
+ ),
+ 'unstable' => array (
+ '1.0' => array (
+ 'current' => '1.0.1&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'download' => 'https://www.phpbb.com/customise/db/download/104136&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'announcement' => 'https://www.phpbb.com/customise/db/extension/boardrules/&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'eol' => '&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'security' => '&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ ),
+ ),
+ )),
+ array('{
+ "unstable": {
+ "1.0": {
+ "current": "1.0.1<script>alert(\'foo\');</script>",
+ "download": "https://www.phpbb.com/customise/db/download/104136<script>alert(\'foo\');</script>",
+ "announcement": "https://www.phpbb.com/customise/db/extension/boardrules/<script>alert(\'foo\');</script>",
+ "eol": "<script>alert(\'foo\');</script>",
+ "security": "<script>alert(\'foo\');</script>"
+ }
+ }
+}', true, array (
+ 'unstable' => array (
+ '1.0' => array (
+ 'current' => '1.0.1&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'download' => 'https://www.phpbb.com/customise/db/download/104136&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'announcement' => 'https://www.phpbb.com/customise/db/extension/boardrules/&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'eol' => '&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ 'security' => '&lt;script&gt;alert(\'foo\');&lt;/script&gt;',
+ ),
+ ),
+ 'stable' => array(),
+ )),
+ );
+ }
+
+ /**
+ * @dataProvider provider_get_versions
+ */
+ public function test_get_versions($input, $valid_data, $expected_return = '')
+ {
+ $this->file_downloader->set($input);
+
+ if (!$valid_data)
+ {
+ try {
+ $return = $this->version_helper->get_versions();
+ } catch (\RuntimeException $e) {
+ $this->assertEquals((string)$e->getMessage(), $this->user->lang('VERSIONCHECK_FAIL'));
+ }
+ }
+ else
+ {
+ $return = $this->version_helper->get_versions();
+ }
+
+ $this->assertEquals($expected_return, $return);
+ }
+}
diff --git a/tests/version/version_test.php b/tests/version/version_test.php
index ba31c79a79..528f1602d6 100644
--- a/tests/version/version_test.php
+++ b/tests/version/version_test.php
@@ -30,6 +30,7 @@ class phpbb_version_helper_test extends phpbb_test_case
new \phpbb\config\config(array(
'version' => '3.1.0',
)),
+ new \phpbb\file_downloader(),
new \phpbb\user('\phpbb\datetime')
);
}
@@ -208,6 +209,7 @@ class phpbb_version_helper_test extends phpbb_test_case
new \phpbb\config\config(array(
'version' => $current_version,
)),
+ new \phpbb\file_downloader(),
new \phpbb\user('\phpbb\datetime'),
))
->getMock()
@@ -318,6 +320,7 @@ class phpbb_version_helper_test extends phpbb_test_case
new \phpbb\config\config(array(
'version' => $current_version,
)),
+ new \phpbb\file_downloader(),
new \phpbb\user('\phpbb\datetime'),
))
->getMock()
diff --git a/travis/check-sami-parse-errors.sh b/travis/check-sami-parse-errors.sh
index 847c54a61a..c3338e34db 100755
--- a/travis/check-sami-parse-errors.sh
+++ b/travis/check-sami-parse-errors.sh
@@ -20,7 +20,7 @@ then
# and
# https://github.com/fabpot/Sami/issues/117
errors=$(
- unbuffer phpBB/vendor/bin/sami.php parse travis/sami.conf.php -v | \
+ unbuffer phpBB/vendor/bin/sami.php parse build/sami-checkout.conf.php -v | \
sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | \
grep "ERROR: " | \
tee /dev/tty | \
diff --git a/travis/install-phpbb-test-dependencies.sh b/travis/install-phpbb-test-dependencies.sh
new file mode 100755
index 0000000000..25743ff2b1
--- /dev/null
+++ b/travis/install-phpbb-test-dependencies.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+#
+# This file is part of the phpBB Forum Software package.
+#
+# @copyright (c) phpBB Limited <https://www.phpbb.com>
+# @license GNU General Public License, version 2 (GPL-2.0)
+#
+# For full copyright and license information, please see
+# the docs/CREDITS.txt file.
+#
+set -e
+set -x
+
+cd tests
+php ../composer.phar install --dev --no-interaction --prefer-source
+cd ..
diff --git a/travis/phpunit-mariadb-travis.xml b/travis/phpunit-mariadb-travis.xml
index aa245a8224..53a206b9b0 100644
--- a/travis/phpunit-mariadb-travis.xml
+++ b/travis/phpunit-mariadb-travis.xml
@@ -16,10 +16,14 @@
<directory suffix="_test.php">../tests</directory>
<exclude>../tests/functional</exclude>
<exclude>../tests/lint_test.php</exclude>
+ <exclude>../tests/ui</exclude>
</testsuite>
<testsuite name="phpBB Functional Tests">
<directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/functional</directory>
</testsuite>
+ <testsuite name="phpBB UI Tests">
+ <directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/ui</directory>
+ </testsuite>
</testsuites>
<groups>
diff --git a/travis/phpunit-mysql-travis.xml b/travis/phpunit-mysql-travis.xml
index 21122ccaeb..d0d3e3c0c0 100644
--- a/travis/phpunit-mysql-travis.xml
+++ b/travis/phpunit-mysql-travis.xml
@@ -16,10 +16,14 @@
<directory suffix="_test.php">../tests</directory>
<exclude>../tests/functional</exclude>
<exclude>../tests/lint_test.php</exclude>
+ <exclude>../tests/ui</exclude>
</testsuite>
<testsuite name="phpBB Functional Tests">
<directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/functional</directory>
</testsuite>
+ <testsuite name="phpBB UI Tests">
+ <directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/ui</directory>
+ </testsuite>
</testsuites>
<groups>
diff --git a/travis/phpunit-mysqli-travis.xml b/travis/phpunit-mysqli-travis.xml
index 60c279d774..4c963895fc 100644
--- a/travis/phpunit-mysqli-travis.xml
+++ b/travis/phpunit-mysqli-travis.xml
@@ -16,6 +16,7 @@
<directory suffix="_test.php">../tests</directory>
<exclude>../tests/functional</exclude>
<exclude>../tests/lint_test.php</exclude>
+ <exclude>../tests/ui</exclude>
</testsuite>
<testsuite name="phpBB Lint Test">
<file>../tests/lint_test.php</file>
@@ -23,6 +24,9 @@
<testsuite name="phpBB Functional Tests">
<directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/functional</directory>
</testsuite>
+ <testsuite name="phpBB UI Tests">
+ <directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/ui</directory>
+ </testsuite>
</testsuites>
<groups>
diff --git a/travis/phpunit-postgres-travis.xml b/travis/phpunit-postgres-travis.xml
index 956278e90c..fa497a1264 100644
--- a/travis/phpunit-postgres-travis.xml
+++ b/travis/phpunit-postgres-travis.xml
@@ -16,10 +16,14 @@
<directory suffix="_test.php">../tests</directory>
<exclude>../tests/functional</exclude>
<exclude>../tests/lint_test.php</exclude>
+ <exclude>../tests/ui</exclude>
</testsuite>
<testsuite name="phpBB Functional Tests">
<directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/functional</directory>
</testsuite>
+ <testsuite name="phpBB UI Tests">
+ <directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/ui</directory>
+ </testsuite>
</testsuites>
<groups>
diff --git a/travis/phpunit-sqlite3-travis.xml b/travis/phpunit-sqlite3-travis.xml
index 72b8b8c8ca..5baab791e0 100644
--- a/travis/phpunit-sqlite3-travis.xml
+++ b/travis/phpunit-sqlite3-travis.xml
@@ -16,10 +16,14 @@
<directory suffix="_test.php">../tests</directory>
<exclude>../tests/functional</exclude>
<exclude>../tests/lint_test.php</exclude>
+ <exclude>../tests/ui</exclude>
</testsuite>
<testsuite name="phpBB Functional Tests">
<directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/functional</directory>
</testsuite>
+ <testsuite name="phpBB UI Tests">
+ <directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/ui</directory>
+ </testsuite>
</testsuites>
<groups>
diff --git a/travis/setup-phpbb.sh b/travis/setup-phpbb.sh
index d829772196..205f23b876 100755
--- a/travis/setup-phpbb.sh
+++ b/travis/setup-phpbb.sh
@@ -33,6 +33,7 @@ fi
if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.3.19', '>=');"` == "1" ]
then
travis/setup-webserver.sh
+ travis/install-phpbb-test-dependencies.sh
fi
cd phpBB