aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.jscsrc78
-rw-r--r--.jshintrc24
-rw-r--r--build/build.xml16
-rw-r--r--build/build_helper.php6
-rw-r--r--build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php94
-rw-r--r--build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningParenthesisSniff.php60
-rw-r--r--build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php51
-rw-r--r--build/code_sniffer/ruleset-php-legacy.xml3
-rw-r--r--build/sami-all.conf.php1
-rw-r--r--phpBB/adm/style/acp_jabber.html2
-rw-r--r--phpBB/assets/javascript/core.js322
-rw-r--r--phpBB/assets/javascript/editor.js2
-rw-r--r--phpBB/assets/javascript/plupload.js270
-rw-r--r--phpBB/composer.json2
-rw-r--r--phpBB/composer.lock418
-rw-r--r--phpBB/config/default/container/services.yml2
-rw-r--r--phpBB/config/default/container/services_db.yml63
-rw-r--r--phpBB/config/default/container/services_migrator.yml4
-rw-r--r--phpBB/config/default/container/services_module.yml10
-rw-r--r--phpBB/config/default/container/services_routing.yml1
-rw-r--r--phpBB/develop/search_fill.php2
-rw-r--r--phpBB/docs/CHANGELOG.html85
-rw-r--r--phpBB/docs/CREDITS.txt1
-rw-r--r--phpBB/docs/events.md63
-rw-r--r--phpBB/includes/acp/acp_board.php18
-rw-r--r--phpBB/includes/acp/acp_jabber.php7
-rw-r--r--phpBB/includes/acp/acp_main.php2
-rw-r--r--phpBB/includes/acp/acp_modules.php617
-rw-r--r--phpBB/includes/acp/acp_prune.php10
-rw-r--r--phpBB/includes/acp/acp_search.php4
-rw-r--r--phpBB/includes/acp/acp_styles.php2
-rw-r--r--phpBB/includes/functions.php30
-rw-r--r--phpBB/includes/functions_acp.php7
-rw-r--r--phpBB/includes/functions_admin.php25
-rw-r--r--phpBB/includes/functions_compatibility.php5
-rw-r--r--phpBB/includes/functions_convert.php2
-rw-r--r--phpBB/includes/functions_display.php33
-rw-r--r--phpBB/includes/functions_module.php2
-rw-r--r--phpBB/includes/functions_posting.php2
-rw-r--r--phpBB/includes/functions_privmsgs.php35
-rw-r--r--phpBB/includes/functions_user.php35
-rw-r--r--phpBB/includes/mcp/mcp_main.php4
-rw-r--r--phpBB/includes/mcp/mcp_post.php47
-rw-r--r--phpBB/includes/startup.php6
-rw-r--r--phpBB/includes/ucp/ucp_notifications.php14
-rw-r--r--phpBB/includes/ucp/ucp_pm_compose.php12
-rw-r--r--phpBB/install/convertors/convert_phpbb20.php2
-rw-r--r--phpBB/install/install_convert.php4
-rw-r--r--phpBB/install/install_install.php47
-rw-r--r--phpBB/language/en/acp/groups.php4
-rw-r--r--phpBB/phpbb/auth/provider/base.php2
-rw-r--r--phpBB/phpbb/auth/provider/ldap.php3
-rw-r--r--phpBB/phpbb/auth/provider/oauth/oauth.php9
-rw-r--r--phpBB/phpbb/auth/provider/oauth/token_storage.php1
-rw-r--r--phpBB/phpbb/auth/provider/provider_interface.php6
-rw-r--r--phpBB/phpbb/cache/driver/memcache.php2
-rw-r--r--phpBB/phpbb/db/extractor/mssql_extractor.php2
-rw-r--r--phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php11
-rw-r--r--phpBB/phpbb/db/migration/data/v310/dev.php11
-rw-r--r--phpBB/phpbb/db/migration/data/v31x/v315.php31
-rw-r--r--phpBB/phpbb/db/migration/data/v31x/v315rc1.php31
-rw-r--r--phpBB/phpbb/db/migration/tool/module.php55
-rw-r--r--phpBB/phpbb/db/migration/tool/permission.php22
-rw-r--r--phpBB/phpbb/db/sql_insert_buffer.php2
-rw-r--r--phpBB/phpbb/di/container_builder.php3
-rw-r--r--phpBB/phpbb/language/language_file_loader.php2
-rw-r--r--phpBB/phpbb/log/log.php2
-rw-r--r--phpBB/phpbb/module/exception/module_exception.php19
-rw-r--r--phpBB/phpbb/module/exception/module_not_found_exception.php19
-rw-r--r--phpBB/phpbb/module/module_manager.php564
-rw-r--r--phpBB/phpbb/notification/method/base.php4
-rw-r--r--phpBB/phpbb/notification/type/admin_activate_user.php2
-rw-r--r--phpBB/phpbb/notification/type/group_request.php2
-rw-r--r--phpBB/phpbb/notification/type/pm.php2
-rw-r--r--phpBB/phpbb/notification/type/post.php2
-rw-r--r--phpBB/phpbb/notification/type/report_pm.php2
-rw-r--r--phpBB/phpbb/notification/type/report_pm_closed.php2
-rw-r--r--phpBB/phpbb/notification/type/report_post.php2
-rw-r--r--phpBB/phpbb/notification/type/report_post_closed.php2
-rw-r--r--phpBB/phpbb/notification/type/topic.php2
-rw-r--r--phpBB/phpbb/passwords/driver/helper.php16
-rw-r--r--phpBB/phpbb/routing/router.php131
-rw-r--r--phpBB/phpbb/search/fulltext_mysql.php108
-rw-r--r--phpBB/phpbb/search/fulltext_native.php117
-rw-r--r--phpBB/phpbb/search/fulltext_postgres.php108
-rw-r--r--phpBB/phpbb/search/fulltext_sphinx.php12
-rw-r--r--phpBB/phpbb/template/twig/node/definenode.php1
-rw-r--r--phpBB/phpbb/template/twig/node/event.php1
-rw-r--r--phpBB/phpbb/template/twig/node/expression/binary/equalequal.php1
-rw-r--r--phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php1
-rw-r--r--phpBB/phpbb/template/twig/node/includenode.php1
-rw-r--r--phpBB/phpbb/template/twig/node/includephp.php1
-rw-r--r--phpBB/phpbb/template/twig/node/php.php1
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/defineparser.php1
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/event.php1
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includejs.php1
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includeparser.php1
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includephp.php1
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/php.php1
-rw-r--r--phpBB/phpbb/textformatter/s9e/factory.php15
-rw-r--r--phpBB/phpbb/tree/nestedset.php6
-rw-r--r--phpBB/phpbb/user_loader.php5
-rw-r--r--phpBB/posting.php66
-rw-r--r--phpBB/search.php2
-rw-r--r--phpBB/styles/prosilver/template/ajax.js45
-rw-r--r--phpBB/styles/prosilver/template/forum_fn.js62
-rw-r--r--phpBB/styles/prosilver/template/index_body.html2
-rw-r--r--phpBB/styles/prosilver/template/login_body.html2
-rw-r--r--phpBB/styles/prosilver/template/login_forum.html2
-rw-r--r--phpBB/styles/prosilver/template/mcp_post.html4
-rw-r--r--phpBB/styles/prosilver/template/overall_footer.html1
-rw-r--r--phpBB/styles/prosilver/template/overall_header.html18
-rw-r--r--phpBB/styles/prosilver/template/simple_header.html28
-rw-r--r--phpBB/styles/prosilver/template/ucp_login_link.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_profile_reg_details.html8
-rw-r--r--phpBB/styles/prosilver/template/ucp_register.html6
-rw-r--r--phpBB/styles/prosilver/template/viewforum_body.html2
-rw-r--r--phpBB/styles/prosilver/template/viewtopic_print.html2
-rw-r--r--phpBB/styles/prosilver/theme/content.css4
-rw-r--r--phpBB/viewtopic.php2
-rw-r--r--tests/controller/common_helper_route.php24
-rw-r--r--tests/controller/controller_test.php5
-rw-r--r--tests/controller/ext/vendor2/foo/config/routing.yml4
-rw-r--r--tests/dbal/fixtures/migrator_permission.xml134
-rw-r--r--tests/dbal/migrator_tool_module_test.php5
-rw-r--r--tests/dbal/migrator_tool_permission_test.php62
-rw-r--r--tests/di/fixtures/config/production/container/environment.yml12
-rw-r--r--tests/extension/modules_test.php51
-rw-r--r--tests/functional/extension_module_test.php11
-rw-r--r--tests/functional/posting_test.php36
-rw-r--r--tests/functions/fixtures/user_delete.xml46
-rw-r--r--tests/functions/user_delete_test.php113
-rw-r--r--tests/functions_acp/build_cfg_template_test.php2
-rw-r--r--tests/functions_privmsgs/fixtures/get_max_setting_from_group.xml83
-rw-r--r--tests/functions_privmsgs/get_max_setting_from_group_test.php64
-rw-r--r--tests/functions_user/delete_user_test.php10
-rw-r--r--tests/lint_test.php2
-rw-r--r--tests/pagination/pagination_test.php2
-rw-r--r--tests/search/mysql_test.php3
-rw-r--r--tests/search/native_test.php3
-rw-r--r--tests/search/postgres_test.php3
-rw-r--r--tests/test_framework/phpbb_functional_test_case.php20
-rw-r--r--tests/text_processing/tickets_data/PHPBB3-10922.html10
-rw-r--r--tests/text_processing/tickets_data/PHPBB3-10922.txt10
145 files changed, 3277 insertions, 1604 deletions
diff --git a/.jscsrc b/.jscsrc
new file mode 100644
index 0000000000..9dd5ab82e6
--- /dev/null
+++ b/.jscsrc
@@ -0,0 +1,78 @@
+
+{
+ "excludeFiles": ["node_modules/**", "**/build/**"],
+ "requireCurlyBraces": [
+ "if", "else", "for", "while", "do", "try", "catch"
+ ],
+ "requireSpaceBeforeKeywords": [
+ "else", "while", "catch"
+ ],
+ "requireSpaceAfterKeywords": [
+ "do", "for", "if", "else", "switch", "case", "try", "catch", "while", "return", "typeof"
+ ],
+ "requireSpaceBeforeBlockStatements": true,
+ "requireParenthesesAroundIIFE": true,
+ "requireSpacesInConditionalExpression": {
+ "afterTest": true,
+ "beforeConsequent": true,
+ "afterConsequent": true,
+ "beforeAlternate": true
+ },
+ "requireSpacesInAnonymousFunctionExpression": {
+ "beforeOpeningCurlyBrace": true
+ },
+ "disallowSpacesInNamedFunctionExpression": {
+ "beforeOpeningRoundBrace": true
+ },
+ "requireSpacesInFunction": {
+ "beforeOpeningCurlyBrace": true
+ },
+ "disallowSpacesInCallExpression": true,
+ "requireBlocksOnNewline": true,
+ "requirePaddingNewlinesBeforeKeywords": ["case"],
+ "disallowEmptyBlocks": true,
+ "disallowSpacesInsideArrayBrackets": "nested",
+ "disallowSpacesInsideParentheses": true,
+ "requireSpacesInsideObjectBrackets": "all",
+ "disallowQuotedKeysInObjects": "allButReserved",
+ "disallowSpaceAfterObjectKeys": true,
+ "requireSpaceBeforeObjectValues": true,
+ "requireCommaBeforeLineBreak": true,
+ "requireOperatorBeforeLineBreak": [
+ "?", "=", "+", "-", "/", "*", "===", "!==", ">", ">=", "<", "<="
+ ],
+ "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
+ "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
+ "requireSpaceBeforeBinaryOperators": [
+ "=", "+", "+=", "-", "-=", "/", "/=", "*", "*=", "===", "!==", "<", "<=", ">", ">="
+ ],
+ "requireSpaceAfterBinaryOperators": [
+ "=", "+", "+=", "-", "-=", "/", "/=", "*", "*=", "===", "!==", "<", "<=", ">", ">="
+ ],
+ "disallowKeywords": ["with"],
+ "disallowMultipleLineStrings": true,
+ "disallowMixedSpacesAndTabs": "smart",
+ "disallowTrailingWhitespace": true,
+ "disallowTrailingComma": true,
+ "disallowKeywordsOnNewLine": ["else"],
+ "requireLineFeedAtFileEnd": true,
+ "maximumLineLength": {
+ "value": 120,
+ "tabSize": 4,
+ "allowUrlComments": true,
+ "allowRegex": true
+ },
+ "requireCapitalizedConstructors": true,
+ "requireDotNotation": true,
+ "disallowYodaConditions": true,
+ "requireSpaceAfterLineComment": {
+ "allExcept": ["#", "="]
+ },
+ "disallowNewlineBeforeBlockStatements": true,
+ "validateQuoteMarks": {
+ "mark": "'",
+ "escape": true
+ },
+ "validateParameterSeparator": ", ",
+ "safeContextKeyword": ["that"]
+}
diff --git a/.jshintrc b/.jshintrc
new file mode 100644
index 0000000000..90d3bb613e
--- /dev/null
+++ b/.jshintrc
@@ -0,0 +1,24 @@
+
+{
+ "bitwise": true,
+ "curly": true,
+ "eqeqeq": true,
+ "es3": true,
+ "forin": false,
+ "freeze": true,
+ "newcap": true,
+ "noarg": true,
+ "noempty": true,
+ "nonbsp": true,
+ "undef": true,
+ "unused": true,
+ "strict": true,
+
+ "browser": true,
+ "devel": true,
+ "jquery": true,
+
+ "globals": {
+ "JSON": true
+ }
+}
diff --git a/build/build.xml b/build/build.xml
index cf617952d0..eb5e9bcfb7 100644
--- a/build/build.xml
+++ b/build/build.xml
@@ -3,8 +3,8 @@
<project name="phpBB" description="The phpBB forum software" default="all" basedir="../">
<!-- a few settings for the build -->
<property name="newversion" value="3.2.0-a1-dev" />
- <property name="prevversion" value="3.1.4" />
- <property name="olderversions" value="3.0.12, 3.0.13, 3.0.13-PL1, 3.0.14, 3.1.0, 3.1.1, 3.1.2, 3.1.3" />
+ <property name="prevversion" value="3.1.5" />
+ <property name="olderversions" value="3.0.12, 3.0.13, 3.0.13-PL1, 3.0.14, 3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4" />
<!-- no configuration should be needed beyond this point -->
<property name="oldversions" value="${olderversions}, ${prevversion}" />
@@ -75,14 +75,14 @@
<target name="sniff">
<exec command="phpBB/vendor/bin/phpcs
- -s
+ -s -p
--extensions=php
--standard=build/code_sniffer/ruleset-php-strict-core.xml
--ignore=${project.basedir}/phpBB/phpbb/db/migration/data/v30x/*
phpBB/phpbb"
dir="." returnProperty="retval-php-strict" passthru="true" />
<exec command="phpBB/vendor/bin/phpcs
- -s
+ -s -p
--extensions=php
--standard=build/code_sniffer/ruleset-php-legacy-core.xml
--ignore=${project.basedir}/phpBB/cache/*
@@ -98,7 +98,7 @@
phpBB"
dir="." returnProperty="retval-php-legacy" passthru="true" />
<exec command="phpBB/vendor/bin/phpcs
- -s
+ -s -p
--extensions=php
--standard=build/code_sniffer/ruleset-php-extensions.xml
--ignore=${project.basedir}/phpBB/ext/*/tests/*
@@ -149,7 +149,7 @@
<property name="dir" value="build/old_versions/release-${version}" />
</phingcall>
- <exec dir="build/old_versions" command="LC_ALL=C diff -crNEBwd release-${version} release-${newversion} >
+ <exec dir="build/old_versions" command="LC_ALL=C diff -crNEBZbd release-${version} release-${newversion} >
../new_version/patches/phpBB-${version}_to_${newversion}.patch" escape="false" />
<exec dir="build/old_versions" command="LC_ALL=C diff -qr release-${version} release-${newversion} | grep 'Only in release-${version}' > ../new_version/patches/phpBB-${version}_to_${newversion}.deleted" escape="false" />
</target>
@@ -177,10 +177,10 @@
<target name="package" depends="clean,prepare,prepare-new-version,old-version-diffs">
<exec dir="build" command="php -f package.php '${versions}' > logs/package.log" escape="false" />
<exec dir="build" escape="false"
- command="diff -crNEBwd old_versions/release-${prevversion}/language new_version/phpBB3/language >
+ command="LC_ALL=C diff -crNEBZbd old_versions/release-${prevversion}/language new_version/phpBB3/language >
save/phpbb-${prevversion}_to_${newversion}_language.patch" />
<exec dir="build" escape="false"
- command="diff -crNEBwd old_versions/release-${prevversion}/styles/prosilver new_version/phpBB3/styles/prosilver >
+ command="LC_ALL=C diff -crNEBZbd old_versions/release-${prevversion}/styles/prosilver new_version/phpBB3/styles/prosilver >
save/phpbb-${prevversion}_to_${newversion}_prosilver.patch" />
<exec dir="build" escape="false"
diff --git a/build/build_helper.php b/build/build_helper.php
index 35e8cd744b..3ff1b89eab 100644
--- a/build/build_helper.php
+++ b/build/build_helper.php
@@ -22,11 +22,11 @@ class build_package
// -r - compare recursive
// -N - Treat missing files as empty
// -E - Ignore tab expansions
- // not used: -b - Ignore space changes.
- // -w - Ignore all whitespace
+ // -Z - Ignore white space at line end.
+ // -b - Ignore changes in the amount of white space.
// -B - Ignore blank lines
// -d - Try to find smaller set of changes
- var $diff_options = '-crNEBwd';
+ var $diff_options = '-crNEBZbd';
var $diff_options_long = '-x images -crNEB'; // -x fonts -x imageset //imageset not used here, because it includes the imageset.cfg file. ;)
var $verbose = false;
diff --git a/build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php b/build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php
index 8337cf02ee..8c0ec853ff 100644
--- a/build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php
+++ b/build/code_sniffer/phpbb/Sniffs/Commenting/FileCommentSniff.php
@@ -60,14 +60,14 @@ class phpbb_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff
return;
}
// Mark as error if this is not a doc comment
- else if ($start === false || $tokens[$start]['code'] !== T_DOC_COMMENT)
+ else if ($start === false || $tokens[$start]['code'] !== T_DOC_COMMENT_OPEN_TAG)
{
$phpcsFile->addError('Missing required file doc comment.', $stackPtr);
return;
}
// Find comment end token
- $end = $phpcsFile->findNext(T_DOC_COMMENT, $start + 1, null, true) - 1;
+ $end = $tokens[$start]['comment_closer'];
// If there is no end, skip processing here
if ($end === false)
@@ -75,38 +75,30 @@ class phpbb_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff
return;
}
- // List of found comment tags
- $tags = array();
-
// check comment lines without the first(/**) an last(*/) line
- for ($i = $start + 1, $c = $end - 1; $i <= $c; ++$i)
+ for ($token = $start + 1, $c = $end - 2; $token <= $c; ++$token)
{
- $line = $tokens[$i]['content'];
-
// Check that each line starts with a '*'
- if (substr($line, 0, 1) !== '*' && substr($line, 0, 2) !== ' *')
+ if ($tokens[$token]['column'] === 1 && (($tokens[$token]['content'] !== '*' && $tokens[$token]['content'] !== ' ') || ($tokens[$token]['content'] === ' ' && $tokens[$token + 1]['content'] !== '*')))
{
$message = 'The file doc comment should not be indented.';
- $phpcsFile->addWarning($message, $i);
- }
- else if (preg_match('/^[ ]?\*\s+@([\w]+)\s+(.*)$/', $line, $match) !== 0)
- {
- if (!isset($tags[$match[1]]))
- {
- $tags[$match[1]] = array();
- }
-
- $tags[$match[1]][] = array($match[2], $i);
+ $phpcsFile->addWarning($message, $token);
}
}
// Check that the first and last line is empty
- if (trim($tokens[$start + 1]['content']) !== '*')
+ // /**T_WHITESPACE
+ // (T_WHITESPACE)*T_WHITESPACE
+ // (T_WHITESPACE)* ...
+ // (T_WHITESPACE)*T_WHITESPACE
+ // T_WHITESPACE*/
+ if (!(($tokens[$start + 2]['content'] !== '*' && $tokens[$start + 4]['content'] !== '*') || ($tokens[$start + 3]['content'] !== '*' && $tokens[$start + 6]['content'] !== '*')))
{
$message = 'The first file comment line should be empty.';
$phpcsFile->addWarning($message, ($start + 1));
}
- if (trim($tokens[$end - 1]['content']) !== '*')
+
+ if ($tokens[$end - 3]['content'] !== '*' && $tokens[$end - 6]['content'] !== '*')
{
$message = 'The last file comment line should be empty.';
$phpcsFile->addWarning($message, $end - 1);
@@ -114,8 +106,8 @@ class phpbb_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff
//$this->processPackage($phpcsFile, $start, $tags);
//$this->processVersion($phpcsFile, $start, $tags);
- $this->processCopyright($phpcsFile, $start, $tags);
- $this->processLicense($phpcsFile, $start, $tags);
+ $this->processCopyright($phpcsFile, $start, $tokens[$start]['comment_tags']);
+ $this->processLicense($phpcsFile, $start, $tokens[$start]['comment_tags']);
}
/**
@@ -176,17 +168,24 @@ class phpbb_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff
protected function processCopyright(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags)
{
$copyright = '(c) phpBB Limited <https://www.phpbb.com>';
+ $tokens = $phpcsFile->getTokens();
- if (!isset($tags['copyright']))
+ foreach ($tags as $tag)
{
- $message = 'Missing require @copyright tag in file doc comment.';
- $phpcsFile->addError($message, $ptr);
- }
- else if ($tags['copyright'][0][0] !== $copyright)
- {
- $message = 'Invalid content found for the first @copyright tag, use "' . $copyright . '".';
- $phpcsFile->addError($message, $tags['copyright'][0][1]);
+ if ($tokens[$tag]['content'] === '@copyright')
+ {
+ if ($tokens[$tag + 2]['content'] !== $copyright)
+ {
+ $message = 'Invalid content found for the first @copyright tag, use "' . $copyright . '".';
+ $phpcsFile->addError($message, $tags['copyright'][0][1]);
+ }
+
+ return;
+ }
}
+
+ $message = 'Missing require @copyright tag in file doc comment.';
+ $phpcsFile->addError($message, $ptr);
}
/**
@@ -201,22 +200,33 @@ class phpbb_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff
protected function processLicense(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags)
{
$license = 'GNU General Public License, version 2 (GPL-2.0)';
+ $tokens = $phpcsFile->getTokens();
- if (!isset($tags['license']))
+ $found = false;
+ foreach ($tags as $tag)
{
- $message = 'Missing require @license tag in file doc comment.';
- $phpcsFile->addError($message, $ptr);
+ if ($tokens[$tag]['content'] === '@license')
+ {
+ if ($found)
+ {
+ $message = 'It must be only one @license tag in file doc comment.';
+ $phpcsFile->addError($message, $ptr);
+ }
+
+ $found = true;
+
+ if ($tokens[$tag + 2]['content'] !== $license)
+ {
+ $message = 'Invalid content found for @license tag, use "' . $license . '".';
+ $phpcsFile->addError($message, $tags['license'][0][1]);
+ }
+ }
}
- else if (sizeof($tags['license']) !== 1)
+
+ if (!$found)
{
- $message = 'It must be only one @license tag in file doc comment.';
+ $message = 'Missing require @license tag in file doc comment.';
$phpcsFile->addError($message, $ptr);
}
- else if (trim($tags['license'][0][0]) !== $license)
- {
- $message = 'Invalid content found for @license tag, use '
- . '"' . $license . '".';
- $phpcsFile->addError($message, $tags['license'][0][1]);
- }
}
}
diff --git a/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningParenthesisSniff.php b/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningParenthesisSniff.php
new file mode 100644
index 0000000000..349bccbb02
--- /dev/null
+++ b/build/code_sniffer/phpbb/Sniffs/ControlStructures/OpeningParenthesisSniff.php
@@ -0,0 +1,60 @@
+<?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.
+ *
+ */
+
+/**
+ * Checks that there is exactly one space between the keyword and the opening
+ * parenthesis of a control structures.
+ */
+class phpbb_Sniffs_ControlStructures_OpeningParenthesisSniff implements PHP_CodeSniffer_Sniff
+{
+ /**
+ * Registers the tokens that this sniff wants to listen for.
+ */
+ public function register()
+ {
+ return array(
+ T_IF,
+ T_FOREACH,
+ T_WHILE,
+ T_FOR,
+ T_SWITCH,
+ T_ELSEIF,
+ T_CATCH,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if ($tokens[$stackPtr + 1]['content'] === '(')
+ {
+ $error = 'There should be exactly one space between the keyword and opening parenthesis';
+ $phpcsFile->addError($error, $stackPtr, 'NoSpaceBeforeOpeningParenthesis');
+ }
+ else if ($tokens[$stackPtr + 1]['content'] !== ' ')
+ {
+ $error = 'There should be exactly one space between the keyword and opening parenthesis';
+ $phpcsFile->addError($error, $stackPtr, 'IncorrectSpaceBeforeOpeningParenthesis');
+ }
+ }
+}
diff --git a/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php b/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php
index 3618871b7a..7ffd1aadd6 100644
--- a/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php
+++ b/build/code_sniffer/phpbb/Sniffs/Namespaces/UnusedUseSniff.php
@@ -138,6 +138,7 @@ class phpbb_Sniffs_Namespaces_UnusedUseSniff implements PHP_CodeSniffer_Sniff
// Check docblocks
$find = array(
T_COMMENT,
+ T_DOC_COMMENT_CLOSE_TAG,
T_DOC_COMMENT,
T_CLASS,
T_FUNCTION,
@@ -147,43 +148,31 @@ class phpbb_Sniffs_Namespaces_UnusedUseSniff implements PHP_CodeSniffer_Sniff
$comment_end = $phpcsFile->findPrevious($find, ($function_declaration - 1));
if ($comment_end !== false)
{
- if (!$tokens[$comment_end]['code'] !== T_DOC_COMMENT)
+ if ($tokens[$comment_end]['code'] === T_DOC_COMMENT_CLOSE_TAG)
{
- $comment_start = ($phpcsFile->findPrevious(T_DOC_COMMENT, ($comment_end - 1), null, true) + 1);
- $comment = $phpcsFile->getTokensAsString($comment_start, ($comment_end - $comment_start + 1));
-
- try
- {
- $comment_parser = new PHP_CodeSniffer_CommentParser_FunctionCommentParser($comment, $phpcsFile);
- $comment_parser->parse();
-
- // Check @param
- foreach ($comment_parser->getParams() as $param) {
- $type = $param->getType();
- $types = explode('|', str_replace('[]', '', $type));
- foreach ($types as $type)
- {
- $ok = $this->check($phpcsFile, $type, $class_name_full, $class_name_short, $param->getLine() + $comment_start) ? true : $ok;
- }
+ $comment_start = $tokens[$comment_end]['comment_opener'];
+ foreach ($tokens[$comment_start]['comment_tags'] as $tag) {
+ if ($tokens[$tag]['content'] !== '@param' && $tokens[$tag]['content'] !== '@return' && $tokens[$tag]['content'] !== '@throws') {
+ continue;
}
- // Check @return
- $return = $comment_parser->getReturn();
- if ($return !== null)
+ $classes = $tokens[($tag + 2)]['content'];
+ $space = strpos($classes, ' ');
+ if ($space !== false) {
+ $classes = substr($classes, 0, $space);
+ }
+
+ $tab = strpos($classes, "\t");
+ if ($tab !== false) {
+ $classes = substr($classes, 0, $tab);
+ }
+
+ $classes = explode('|', str_replace('[]', '', $classes));
+ foreach ($classes as $class)
{
- $type = $return->getValue();
- $types = explode('|', str_replace('[]', '', $type));
- foreach ($types as $type)
- {
- $ok = $this->check($phpcsFile, $type, $class_name_full, $class_name_short, $return->getLine() + $comment_start) ? true : $ok;
- }
+ $ok = $this->check($phpcsFile, $class, $class_name_full, $class_name_short, $tokens[$tag + 2]['line']) ? true : $ok;
}
}
- catch (PHP_CodeSniffer_CommentParser_ParserException $e)
- {
- $line = ($e->getLineWithinComment() + $comment_start);
- $phpcsFile->addError($e->getMessage(), $line, 'FailedParse');
- }
}
}
diff --git a/build/code_sniffer/ruleset-php-legacy.xml b/build/code_sniffer/ruleset-php-legacy.xml
index b0110e8b12..c740c6080f 100644
--- a/build/code_sniffer/ruleset-php-legacy.xml
+++ b/build/code_sniffer/ruleset-php-legacy.xml
@@ -86,4 +86,7 @@
<!-- The ?> closing tag MUST be omitted from files containing only PHP. -->
<rule ref="Zend.Files.ClosingTag" />
+ <!-- There MUST be one space between control structure and opening parenthesis -->
+ <rule ref="./phpbb/Sniffs/ControlStructures/OpeningParenthesisSniff.php" />
+
</ruleset>
diff --git a/build/sami-all.conf.php b/build/sami-all.conf.php
index fb1a269206..9c10209e8b 100644
--- a/build/sami-all.conf.php
+++ b/build/sami-all.conf.php
@@ -25,6 +25,7 @@ $config['versions'] = Sami\Version\GitVersionCollection::create(__DIR__ . '/../'
*/
->add('3.0.x')
->add('3.1.x')
+ ->add('master')
;
return new Sami\Sami($iterator, $config);
diff --git a/phpBB/adm/style/acp_jabber.html b/phpBB/adm/style/acp_jabber.html
index 4d0b1b0d97..9246987f1f 100644
--- a/phpBB/adm/style/acp_jabber.html
+++ b/phpBB/adm/style/acp_jabber.html
@@ -39,7 +39,7 @@
</dl>
<dl>
<dt><label for="jab_password">{L_JAB_PASSWORD}{L_COLON}</label><br /><span>{L_JAB_PASSWORD_EXPLAIN}</span></dt>
- <dd><input type="password" id="jab_password" name="jab_password" value="{JAB_PASSWORD}" /></dd>
+ <dd><input type="password" id="jab_password" name="jab_password" value="{JAB_PASSWORD}" autocomplete="off" /></dd>
</dl>
<!-- IF S_CAN_USE_SSL -->
<dl>
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index 9eb931270a..953b6be0bd 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -1,3 +1,5 @@
+/* global bbfontstyle */
+
var phpbb = {};
phpbb.alertTime = 100;
@@ -13,7 +15,7 @@ var keymap = {
};
var $dark = $('#darkenwrapper');
-var $loadingIndicator = $('#loading_indicator');
+var $loadingIndicator;
var phpbbAlertTimer = null;
phpbb.isTouch = (window && typeof window.ontouchstart !== 'undefined');
@@ -21,9 +23,14 @@ phpbb.isTouch = (window && typeof window.ontouchstart !== 'undefined');
/**
* Display a loading screen
*
- * @returns object Returns loadingIndicator.
+ * @returns {object} Returns loadingIndicator.
*/
phpbb.loadingIndicator = function() {
+ if (!$loadingIndicator) {
+ $loadingIndicator = $('<div />', { id: 'loading_indicator' });
+ $loadingIndicator.appendTo('#page-footer');
+ }
+
if (!$loadingIndicator.is(':visible')) {
$loadingIndicator.fadeIn(phpbb.alertTime);
// Wait fifteen seconds and display an error if nothing has been returned by then.
@@ -54,7 +61,7 @@ phpbb.clearLoadingTimeout = function() {
/**
* Close popup alert after a specified delay
*
-* @param int Delay in ms until darkenwrapper's click event is triggered
+* @param {int} delay Delay in ms until darkenwrapper's click event is triggered
*/
phpbb.closeDarkenWrapper = function(delay) {
phpbbAlertTimer = setTimeout(function() {
@@ -67,14 +74,12 @@ phpbb.closeDarkenWrapper = function(delay) {
*
* You can only call one alert or confirm box at any one time.
*
- * @param string title Title of the message, eg "Information" (HTML).
- * @param string msg Message to display (HTML).
- * @param bool fadedark Remove the dark background when done? Defaults
- * to yes.
+ * @param {string} title Title of the message, eg "Information" (HTML).
+ * @param {string} msg Message to display (HTML).
*
- * @returns object Returns the div created.
+ * @returns {object} Returns the div created.
*/
-phpbb.alert = function(title, msg, fadedark) {
+phpbb.alert = function(title, msg) {
var $alert = $('#phpbb_alert');
$alert.find('.alert_title').html(title);
$alert.find('.alert_text').html(msg);
@@ -94,14 +99,14 @@ phpbb.alert = function(title, msg, fadedark) {
/**
* Handler for opening an alert box.
*
-* @param jQuery $alert jQuery object.
+* @param {jQuery} $alert jQuery object.
*/
phpbb.alert.open = function($alert) {
if (!$dark.is(':visible')) {
$dark.fadeIn(phpbb.alertTime);
}
- if ($loadingIndicator.is(':visible')) {
+ if ($loadingIndicator && $loadingIndicator.is(':visible')) {
$loadingIndicator.fadeOut(phpbb.alertTime, function() {
$dark.append($alert);
$alert.fadeIn(phpbb.alertTime);
@@ -134,8 +139,8 @@ phpbb.alert.open = function($alert) {
/**
* Handler for closing an alert box.
*
-* @param jQuery $alert jQuery object.
-* @param bool fadedark Whether to remove dark background.
+* @param {jQuery} $alert jQuery object.
+* @param {bool} fadedark Whether to remove dark background.
*/
phpbb.alert.close = function($alert, fadedark) {
var $fade = (fadedark) ? $dark : $alert;
@@ -153,13 +158,13 @@ phpbb.alert.close = function($alert, fadedark) {
*
* You can only call one alert or confirm box at any one time.
*
- * @param string msg Message to display (HTML).
- * @param function callback Callback. Bool param, whether the user pressed
+ * @param {string} msg Message to display (HTML).
+ * @param {function} callback Callback. Bool param, whether the user pressed
* yes or no (or whatever their language is).
- * @param bool fadedark Remove the dark background when done? Defaults
+ * @param {bool} fadedark Remove the dark background when done? Defaults
* to yes.
*
- * @returns object Returns the div created.
+ * @returns {object} Returns the div created.
*/
phpbb.confirm = function(msg, callback, fadedark) {
var $confirmDiv = $('#phpbb_confirm');
@@ -197,8 +202,8 @@ phpbb.confirm = function(msg, callback, fadedark) {
/**
* Turn a querystring into an array.
*
- * @argument string string The querystring to parse.
- * @returns object The object created.
+ * @argument {string} string The querystring to parse.
+ * @returns {object} The object created.
*/
phpbb.parseQuerystring = function(string) {
var params = {}, i, split;
@@ -223,12 +228,7 @@ phpbb.parseQuerystring = function(string) {
* For more info, view the following page on the phpBB wiki:
* http://wiki.phpbb.com/JavaScript_Function.phpbb.ajaxify
*
- * @param object options Options.
- * @param bool/function refresh If we are sent back a refresh, should it be
- * acted upon? This can either be true / false / a function.
- * @param function callback Callback to call on completion of event. Has
- * three parameters: the element that the event was evoked from, the JSON
- * that was returned and (if it is a form) the form action.
+ * @param {object} options Options.
*/
phpbb.ajaxify = function(options) {
var $elements = $(options.selector),
@@ -262,11 +262,16 @@ phpbb.ajaxify = function(options) {
console.log('AJAX error. status: ' + textStatus + ', message: ' + errorThrown);
}
phpbb.clearLoadingTimeout();
- var errorText = false;
- if (typeof errorThrown === 'string' && errorThrown.length > 0) {
+ var responseText, errorText = false;
+ try {
+ responseText = JSON.parse(jqXHR.responseText);
+ responseText = responseText.message;
+ } catch (e) {}
+ if (typeof responseText === 'string' && responseText.length > 0) {
+ errorText = responseText;
+ } else if (typeof errorThrown === 'string' && errorThrown.length > 0) {
errorText = errorThrown;
- }
- else {
+ } else {
errorText = $dark.attr('data-ajax-error-text-' + textStatus);
if (typeof errorText !== 'string' || !errorText.length) {
errorText = $dark.attr('data-ajax-error-text');
@@ -283,7 +288,7 @@ phpbb.ajaxify = function(options) {
* It cannot be called from outside this function, and is purely here to
* avoid repetition of code.
*
- * @param object res The object sent back by the server.
+ * @param {object} res The object sent back by the server.
*/
function returnHandler(res) {
var alert;
@@ -427,10 +432,10 @@ phpbb.search = {
};
/**
- * Get cached search data.
+ * Get cached search data.
*
- * @param string id Search ID.
- * @return bool|object. Cached data object. Returns false if no data exists.
+ * @param {string} id Search ID.
+ * @returns {bool|object} Cached data object. Returns false if no data exists.
*/
phpbb.search.cache.get = function(id) {
if (this.data[id]) {
@@ -440,39 +445,35 @@ phpbb.search.cache.get = function(id) {
};
/**
- * Set search cache data value.
- *
- * @param string id Search ID.
- * @param string key Data key.
- * @param string value Data value.
+ * Set search cache data value.
*
- * @return undefined
+ * @param {string} id Search ID.
+ * @param {string} key Data key.
+ * @param {string} value Data value.
*/
phpbb.search.cache.set = function(id, key, value) {
if (!this.data[id]) {
- this.data[id] = {results: []};
+ this.data[id] = { results: [] };
}
this.data[id][key] = value;
};
/**
- * Cache search result.
+ * Cache search result.
*
- * @param string id Search ID.
- * @param string keyword Keyword.
- * @param array results Search results.
- *
- * @return undefined
+ * @param {string} id Search ID.
+ * @param {string} keyword Keyword.
+ * @param {Array} results Search results.
*/
-phpbb.search.cache.setResults = function(id, keyword, value) {
- this.data[id].results[keyword] = value;
+phpbb.search.cache.setResults = function(id, keyword, results) {
+ this.data[id].results[keyword] = results;
};
/**
* Trim spaces from keyword and lower its case.
*
- * @param string keyword Search keyword to clean.
- * @return string Cleaned string.
+ * @param {string} keyword Search keyword to clean.
+ * @returns {string} Cleaned string.
*/
phpbb.search.cleanKeyword = function(keyword) {
return $.trim(keyword).toLowerCase();
@@ -482,11 +483,11 @@ phpbb.search.cleanKeyword = function(keyword) {
* Get clean version of search keyword. If textarea supports several keywords
* (one per line), it fetches the current keyword based on the caret position.
*
- * @param jQuery $input Search input|textarea.
- * @param string keyword Input|textarea value.
- * @param bool multiline Whether textarea supports multiple search keywords.
+ * @param {jQuery} $input Search input|textarea.
+ * @param {string} keyword Input|textarea value.
+ * @param {bool} multiline Whether textarea supports multiple search keywords.
*
- * @return string Clean string.
+ * @returns string Clean string.
*/
phpbb.search.getKeyword = function($input, keyword, multiline) {
if (multiline) {
@@ -498,10 +499,10 @@ phpbb.search.getKeyword = function($input, keyword, multiline) {
/**
* Get the textarea line number on which the keyword resides - for textareas
- * that support multiple keywords (one per line).
+ * that support multiple keywords (one per line).
*
- * @param jQuery $textarea Search textarea.
- * @return int
+ * @param {jQuery} $textarea Search textarea.
+ * @returns {int} The line number.
*/
phpbb.search.getKeywordLine = function ($textarea) {
var selectionStart = $textarea.get(0).selectionStart;
@@ -512,11 +513,9 @@ phpbb.search.getKeywordLine = function ($textarea) {
* Set the value on the input|textarea. If textarea supports multiple
* keywords, only the active keyword is replaced.
*
- * @param jQuery $input Search input|textarea.
- * @param string value Value to set.
- * @param bool multiline Whether textarea supports multiple search keywords.
- *
- * @return undefined
+ * @param {jQuery} $input Search input|textarea.
+ * @param {string} value Value to set.
+ * @param {bool} multiline Whether textarea supports multiple search keywords.
*/
phpbb.search.setValue = function($input, value, multiline) {
if (multiline) {
@@ -529,14 +528,13 @@ phpbb.search.setValue = function($input, value, multiline) {
};
/**
- * Sets the onclick event to set the value on the input|textarea to the selected search result.
+ * Sets the onclick event to set the value on the input|textarea to the
+ * selected search result.
*
- * @param jQuery $input Search input|textarea.
- * @param object value Result object.
- * @param jQuery $row Result element.
- * @param jQuery $container jQuery object for the search container.
- *
- * @return undefined
+ * @param {jQuery} $input Search input|textarea.
+ * @param {object} value Result object.
+ * @param {jQuery} $row Result element.
+ * @param {jQuery} $container jQuery object for the search container.
*/
phpbb.search.setValueOnClick = function($input, value, $row, $container) {
$row.click(function() {
@@ -551,16 +549,16 @@ phpbb.search.setValueOnClick = function($input, value, $row, $container) {
* already, those are displayed instead. Executes the AJAX request function
* itself due to the need to use a timeout to limit the number of requests.
*
- * @param array data Data to be sent to the server.
- * @param object event Onkeyup event object.
- * @param function sendRequest Function to execute AJAX request.
+ * @param {Array} data Data to be sent to the server.
+ * @param {object} event Onkeyup event object.
+ * @param {function} sendRequest Function to execute AJAX request.
*
- * @return bool Returns false.
+ * @returns {bool} Returns false.
*/
phpbb.search.filter = function(data, event, sendRequest) {
var $this = $(this),
dataName = ($this.attr('data-name') !== undefined) ? $this.attr('data-name') : $this.attr('name'),
- minLength = parseInt($this.attr('data-min-length')),
+ minLength = parseInt($this.attr('data-min-length'), 10),
searchID = $this.attr('data-results'),
keyword = phpbb.search.getKeyword($this, data[dataName], $this.attr('data-multiline')),
cache = phpbb.search.cache.get(searchID),
@@ -582,7 +580,10 @@ phpbb.search.filter = function(data, event, sendRequest) {
} else {
// Do we already have results for this?
if (cache.results[keyword]) {
- var response = {keyword: keyword, results: cache.results[keyword]};
+ var response = {
+ keyword: keyword,
+ results: cache.results[keyword]
+ };
phpbb.search.handleResponse(response, $this, true);
proceed = false;
}
@@ -593,8 +594,8 @@ phpbb.search.filter = function(data, event, sendRequest) {
phpbb.search.cache.set(searchID, 'lastSearch', keyword);
phpbb.search.cache.setResults(searchID, keyword, []);
proceed = false;
- }
- }
+ }
+ }
}
if (proceed) {
@@ -607,14 +608,12 @@ phpbb.search.filter = function(data, event, sendRequest) {
};
/**
- * Handle search result response.
- *
- * @param object res Data received from server.
- * @param jQuery $input Search input|textarea.
- * @param bool fromCache Whether the results are from the cache.
- * @param function callback Optional callback to run when assigning each search result.
+ * Handle search result response.
*
- * @return undefined
+ * @param {object} res Data received from server.
+ * @param {jQuery} $input Search input|textarea.
+ * @param {bool} fromCache Whether the results are from the cache.
+ * @param {function} callback Optional callback to run when assigning each search result.
*/
phpbb.search.handleResponse = function(res, $input, fromCache, callback) {
if (typeof res !== 'object') {
@@ -641,12 +640,10 @@ phpbb.search.handleResponse = function(res, $input, fromCache, callback) {
/**
* Show search results.
*
- * @param array results Search results.
- * @param jQuery $input Search input|textarea.
- * @param jQuery $container Search results container element.
- * @param function callback Optional callback to run when assigning each search result.
- *
- * @return undefined
+ * @param {Array} results Search results.
+ * @param {jQuery} $input Search input|textarea.
+ * @param {jQuery} $container Search results container element.
+ * @param {function} callback Optional callback to run when assigning each search result.
*/
phpbb.search.showResults = function(results, $input, $container, callback) {
var $resultContainer = $('.search-results', $container);
@@ -683,8 +680,7 @@ phpbb.search.showResults = function(results, $input, $container, callback) {
/**
* Clear search results.
*
- * @param jQuery $container Search results container.
- * @return undefined
+ * @param {jQuery} $container Search results container.
*/
phpbb.search.clearResults = function($container) {
$container.children(':not(.search-result-tpl)').remove();
@@ -703,8 +699,8 @@ phpbb.history = {};
/**
* Check whether a method in the native history object is supported.
*
-* @param string fn Method name.
-* @return bool Returns true if the method is supported.
+* @param {string} fn Method name.
+* @returns {bool} Returns true if the method is supported.
*/
phpbb.history.isSupported = function(fn) {
return !(typeof history === 'undefined' || typeof history[fn] === 'undefined');
@@ -714,12 +710,10 @@ phpbb.history.isSupported = function(fn) {
* Wrapper for the pushState and replaceState methods of the
* native history object.
*
-* @param string mode Mode. Either push or replace.
-* @param string url New URL.
-* @param string title Optional page title.
-* @patam object obj Optional state object.
-*
-* @return undefined
+* @param {string} mode Mode. Either push or replace.
+* @param {string} url New URL.
+* @param {string} [title] Optional page title.
+* @param {object} [obj] Optional state object.
*/
phpbb.history.alterUrl = function(mode, url, title, obj) {
var fn = mode + 'State';
@@ -740,11 +734,9 @@ phpbb.history.alterUrl = function(mode, url, title, obj) {
/**
* Wrapper for the native history.replaceState method.
*
-* @param string url New URL.
-* @param string title Optional page title.
-* @patam object obj Optional state object.
-*
-* @return undefined
+* @param {string} url New URL.
+* @param {string} [title] Optional page title.
+* @param {object} [obj] Optional state object.
*/
phpbb.history.replaceUrl = function(url, title, obj) {
phpbb.history.alterUrl('replace', url, title, obj);
@@ -753,11 +745,9 @@ phpbb.history.replaceUrl = function(url, title, obj) {
/**
* Wrapper for the native history.pushState method.
*
-* @param string url New URL.
-* @param string title Optional page title.
-* @patam object obj Optional state object.
-*
-* @return undefined
+* @param {string} url New URL.
+* @param {string} [title] Optional page title.
+* @param {object} [obj] Optional state object.
*/
phpbb.history.pushUrl = function(url, title, obj) {
phpbb.history.alterUrl('push', url, title, obj);
@@ -766,7 +756,8 @@ phpbb.history.pushUrl = function(url, title, obj) {
/**
* Hide the optgroups that are not the selected timezone
*
-* @param bool keepSelection Shall we keep the value selected, or shall the user be forced to repick one.
+* @param {bool} keepSelection Shall we keep the value selected, or shall the
+* user be forced to repick one.
*/
phpbb.timezoneSwitchDate = function(keepSelection) {
var $timezoneCopy = $('#timezone_copy');
@@ -789,7 +780,7 @@ phpbb.timezoneSwitchDate = function(keepSelection) {
}
if ($tzDate.val() !== '') {
- $timezone.children('optgroup').remove(':not([data-tz-value="' + $('#tz_date').val() + '"])');
+ $timezone.children('optgroup').remove(':not([data-tz-value="' + $tzDate.val() + '"])');
}
if ($tzDate.val() === $tzSelectDateSuggest.attr('data-suggested-tz')) {
@@ -797,7 +788,7 @@ phpbb.timezoneSwitchDate = function(keepSelection) {
} else {
$tzSelectDateSuggest.css('display', 'inline');
}
-
+
var $tzOptions = $timezone.children('optgroup[data-tz-value="' + $tzDate.val() + '"]').children('option');
if ($tzOptions.length === 1) {
@@ -824,7 +815,7 @@ phpbb.timezoneEnableDateSelection = function() {
/**
* Preselect a date/time or suggest one, if it is not picked.
*
-* @param bool forceSelector Shall we select the suggestion?
+* @param {bool} forceSelector Shall we select the suggestion?
*/
phpbb.timezonePreselectSelect = function(forceSelector) {
@@ -893,8 +884,8 @@ phpbb.ajaxCallbacks = {};
*
* See the phpbb.ajaxify comments for information on stuff like parameters.
*
- * @param string id The name of the callback.
- * @param function callback The callback to be called.
+ * @param {string} id The name of the callback.
+ * @param {function} callback The callback to be called.
*/
phpbb.addAjaxCallback = function(id, callback) {
if (typeof callback === 'function') {
@@ -985,7 +976,7 @@ phpbb.addAjaxCallback('toggle_link', function() {
* types text.
*
* @param {jQuery} $items jQuery object(s) to resize
-* @param {object} options Optional parameter that adjusts default
+* @param {object} [options] Optional parameter that adjusts default
* configuration. See configuration variable
*
* Optional parameters:
@@ -1022,15 +1013,19 @@ phpbb.resizeTextArea = function($items, options) {
function resetAutoResize(item) {
var $item = $(item);
if ($item.hasClass('auto-resized')) {
- $(item).css({height: '', resize: ''}).removeClass('auto-resized');
+ $(item)
+ .css({ height: '', resize: '' })
+ .removeClass('auto-resized');
configuration.resetCallback.call(item, $item);
}
}
function autoResize(item) {
function setHeight(height) {
- height += parseInt($item.css('height')) - $item.height();
- $item.css({height: height + 'px', resize: 'none'}).addClass('auto-resized');
+ height += parseInt($item.css('height'), 10) - $item.height();
+ $item
+ .css({ height: height + 'px', resize: 'none' })
+ .addClass('auto-resized');
configuration.resizeCallback.call(item, $item);
}
@@ -1046,7 +1041,7 @@ phpbb.resizeTextArea = function($items, options) {
configuration.maxHeight
),
$item = $(item),
- height = parseInt($item.height()),
+ height = parseInt($item.height(), 10),
scrollHeight = (item.scrollHeight) ? item.scrollHeight : 0;
if (height < 0) {
@@ -1055,8 +1050,7 @@ phpbb.resizeTextArea = function($items, options) {
if (height > maxHeight) {
setHeight(maxHeight);
- }
- else if (scrollHeight > (height + 5)) {
+ } else if (scrollHeight > (height + 5)) {
setHeight(Math.min(maxHeight, scrollHeight));
}
}
@@ -1085,7 +1079,7 @@ phpbb.resizeTextArea = function($items, options) {
* @param {Array} endTags List of end tags to look for
* For example, Array('[/code]')
*
-* @return {boolean} True if cursor is in bbcode tag
+* @returns {boolean} True if cursor is in bbcode tag
*/
phpbb.inBBCodeTag = function(textarea, startTags, endTags) {
var start = textarea.selectionStart,
@@ -1157,7 +1151,7 @@ phpbb.applyCodeEditor = function(textarea) {
* @param {boolean} stripCodeStart If true, only part of line
* after [code] tag will be returned.
*
- * @return {string} Line of text
+ * @returns {string} Line of text
*/
function getLastLine(stripCodeStart) {
var start = textarea.selectionStart,
@@ -1173,7 +1167,7 @@ phpbb.applyCodeEditor = function(textarea) {
var tagLength = startTags[i].length;
value = value.substring(index + tagLength);
- if (startTags[i].lastIndexOf(startTagsEnd) != tagLength) {
+ if (startTags[i].lastIndexOf(startTagsEnd) !== tagLength) {
index = value.indexOf(startTagsEnd);
if (index >= 0) {
@@ -1190,7 +1184,7 @@ phpbb.applyCodeEditor = function(textarea) {
/**
* Append text at cursor position
*
- * @param {string} Text Text to append
+ * @param {string} text Text to append
*/
function appendText(text) {
var start = textarea.selectionStart,
@@ -1238,10 +1232,10 @@ phpbb.applyCodeEditor = function(textarea) {
* This function will enable the drag and drop animation for a specified
* textarea.
*
- * @param {object} textarea Textarea DOM object to apply editor to
+ * @param {HTMLElement} textarea Textarea DOM object to apply editor to
*/
phpbb.showDragNDrop = function(textarea) {
- if (textarea == null) {
+ if (!textarea) {
return;
}
@@ -1349,12 +1343,15 @@ phpbb.toggleDropdown = function() {
fullFreeSpace = freeSpace + parent.outerWidth();
options.dropdown.find('.dropdown-contents').each(function() {
- contentWidth = parseInt($(this).outerWidth());
- $(this).css({marginLeft: 0, left: 0});
+ contentWidth = parseInt($(this).outerWidth(), 10);
+ $(this).css({ marginLeft: 0, left: 0 });
});
var maxOffset = Math.min(contentWidth, fullFreeSpace) + 'px';
- options.dropdown.css({'width': maxOffset, 'margin-left': '-' + maxOffset});
+ options.dropdown.css({
+ width: maxOffset,
+ marginLeft: -maxOffset
+ });
}
} else {
options.dropdown.css('margin-right', '-' + (windowWidth + freeSpace) + 'px');
@@ -1416,14 +1413,12 @@ phpbb.registerDropdown = function(toggle, dropdown, options) {
/**
* Get the HTML for a color palette table.
*
-* @param string dir Palette direction - either v or h
-* @param int width Palette cell width.
-* @param int height Palette cell height.
+* @param {string} dir Palette direction - either v or h
+* @param {int} width Palette cell width.
+* @param {int} height Palette cell height.
*/
phpbb.colorPalette = function(dir, width, height) {
- var r = 0,
- g = 0,
- b = 0,
+ var r, g, b,
numberList = new Array(6),
color = '',
html = '';
@@ -1434,32 +1429,33 @@ phpbb.colorPalette = function(dir, width, height) {
numberList[3] = 'BF';
numberList[4] = 'FF';
- var tableClass = (dir == 'h') ? 'horizontal-palette' : 'vertical-palette';
+ var tableClass = (dir === 'h') ? 'horizontal-palette' : 'vertical-palette';
html += '<table class="not-responsive colour-palette ' + tableClass + '" style="width: auto;">';
for (r = 0; r < 5; r++) {
- if (dir == 'h') {
+ if (dir === 'h') {
html += '<tr>';
}
for (g = 0; g < 5; g++) {
- if (dir == 'v') {
+ if (dir === 'v') {
html += '<tr>';
}
for (b = 0; b < 5; b++) {
- color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]);
- html += '<td style="background-color: #' + color + '; width: ' + width + 'px; height: ' + height + 'px;">';
- html += '<a href="#" data-color="' + color + '" style="display: block; width: ' + width + 'px; height: ' + height + 'px; " alt="#' + color + '" title="#' + color + '"></a>';
+ color = '' + numberList[r] + numberList[g] + numberList[b];
+ html += '<td style="background-color: #' + color + '; width: ' + width + 'px; height: ' +
+ height + 'px;"><a href="#" data-color="' + color + '" style="display: block; width: ' +
+ width + 'px; height: ' + height + 'px; " alt="#' + color + '" title="#' + color + '"></a>';
html += '</td>';
}
- if (dir == 'v') {
+ if (dir === 'v') {
html += '</tr>';
}
}
- if (dir == 'h') {
+ if (dir === 'h') {
html += '</tr>';
}
}
@@ -1470,7 +1466,7 @@ phpbb.colorPalette = function(dir, width, height) {
/**
* Register a color palette.
*
-* @param object el jQuery object for the palette container.
+* @param {jQuery} el jQuery object for the palette container.
*/
phpbb.registerPalette = function(el) {
var orientation = el.attr('data-orientation'),
@@ -1499,15 +1495,15 @@ phpbb.registerPalette = function(el) {
}
e.preventDefault();
});
-}
+};
/**
* Set display of page element
*
-* @param string id The ID of the element to change
-* @param int action Set to 0 if element display should be toggled, -1 for
+* @param {string} id The ID of the element to change
+* @param {int} action Set to 0 if element display should be toggled, -1 for
* hiding the element, and 1 for showing it.
-* @param string type Display type that should be used, e.g. inline, block or
+* @param {string} type Display type that should be used, e.g. inline, block or
* other CSS "display" types
*/
phpbb.toggleDisplay = function(id, action, type) {
@@ -1528,8 +1524,7 @@ phpbb.toggleDisplay = function(id, action, type) {
* Toggle additional settings based on the selected
* option of select element.
*
-* @param jQuery el jQuery select element object.
-* @return undefined
+* @param {jQuery} el jQuery select element object.
*/
phpbb.toggleSelectSettings = function(el) {
el.children().each(function() {
@@ -1543,11 +1538,11 @@ phpbb.toggleSelectSettings = function(el) {
* Get function from name.
* Based on http://stackoverflow.com/a/359910
*
-* @param string functionName Function to get.
-* @return function
+* @param {string} functionName Function to get.
+* @returns function
*/
phpbb.getFunctionByName = function (functionName) {
- var namespaces = functionName.split('.'),
+ var namespaces = functionName.split('.'),
func = namespaces.pop(),
context = window;
@@ -1613,6 +1608,21 @@ phpbb.registerPageDropdowns = function() {
};
/**
+ * Handle avatars to be lazy loaded.
+ */
+phpbb.lazyLoadAvatars = function loadAvatars() {
+ $('.avatar[data-src]').each(function () {
+ var $avatar = $(this);
+
+ $avatar
+ .attr('src', $avatar.data('src'))
+ .removeAttr('data-src');
+ });
+};
+
+$(window).load(phpbb.lazyLoadAvatars);
+
+/**
* Apply code editor to all textarea elements with data-bbcode attribute
*/
$(function() {
diff --git a/phpBB/assets/javascript/editor.js b/phpBB/assets/javascript/editor.js
index c58e4d19dd..298526ab1f 100644
--- a/phpBB/assets/javascript/editor.js
+++ b/phpBB/assets/javascript/editor.js
@@ -159,7 +159,7 @@ function insert_text(text, spaces, popup) {
/**
* Add inline attachment at position
*/
-function attach_inline(index, filename) {
+function attachInline(index, filename) {
insert_text('[attachment=' + index + ']' + filename + '[/attachment]');
document.forms[form_name].elements[text_name].focus();
}
diff --git a/phpBB/assets/javascript/plupload.js b/phpBB/assets/javascript/plupload.js
index e0d2e05a84..96e5ca96e6 100644
--- a/phpBB/assets/javascript/plupload.js
+++ b/phpBB/assets/javascript/plupload.js
@@ -1,14 +1,14 @@
+/* global phpbb, plupload, attachInline */
+
plupload.addI18n(phpbb.plupload.i18n);
phpbb.plupload.ids = [];
(function($) { // Avoid conflicts with other libraries
-"use strict";
+'use strict';
/**
* Set up the uploader.
- *
- * @return undefined
*/
phpbb.plupload.initialize = function() {
// Initialize the Plupload uploader.
@@ -20,7 +20,7 @@ phpbb.plupload.initialize = function() {
// Only execute if Plupload initialized successfully.
phpbb.plupload.uploader.bind('Init', function() {
- phpbb.plupload.form = $(phpbb.plupload.config.form_hook)[0],
+ phpbb.plupload.form = $(phpbb.plupload.config.form_hook)[0];
phpbb.plupload.rowTpl = $('#attach-row-tpl')[0].outerHTML;
// Hide the basic upload panel and remove the attach row template.
@@ -48,8 +48,6 @@ phpbb.plupload.initialize = function() {
/**
* Unsets all elements in the object uploader.settings.multipart_params whose keys
* begin with 'attachment_data['
- *
- * @return undefined
*/
phpbb.plupload.clearParams = function() {
var obj = phpbb.plupload.uploader.settings.multipart_params;
@@ -65,20 +63,17 @@ phpbb.plupload.clearParams = function() {
/**
* Update uploader.settings.multipart_params object with new data.
*
- * @param object obj
- * @return undefined
+ * @param {object} obj
*/
phpbb.plupload.updateMultipartParams = function(obj) {
- phpbb.plupload.uploader.settings.multipart_params = $.extend(
- phpbb.plupload.uploader.settings.multipart_params,
- obj
- );
+ var settings = phpbb.plupload.uploader.settings;
+ settings.multipart_params = $.extend(settings.multipart_params, obj);
};
/**
* Convert the array of attachment objects into an object that PHP would expect as POST data.
*
- * @return object An object in the form 'attachment_data[i][key]': value as
+ * @returns {object} An object in the form 'attachment_data[i][key]': value as
* expected by the server
*/
phpbb.plupload.getSerializedData = function() {
@@ -100,22 +95,19 @@ phpbb.plupload.getSerializedData = function() {
* Get the index from the phpbb.plupload.data array where the given
* attachment id appears.
*
- * @param int attach_id The attachment id of the file.
- * @return bool Returns false if the id cannot be found.
- * @return int Returns the index of the file if it exists.
+ * @param {int} attachId The attachment id of the file.
+ * @returns {bool|int} Index of the file if exists, otherwise false.
*/
-phpbb.plupload.getIndex = function(attach_id) {
- var index = $.inArray(Number(attach_id), phpbb.plupload.ids);
+phpbb.plupload.getIndex = function(attachId) {
+ var index = $.inArray(Number(attachId), phpbb.plupload.ids);
return (index !== -1) ? index : false;
};
/**
* Set the data in phpbb.plupload.data and phpbb.plupload.ids arrays.
- *
- * @param array data Array containing the new data to use. In the form of
- * array(index => object(property: value). Requires attach_id to be one of the object properties.
*
- * @return undefined
+ * @param {Array} data Array containing the new data to use. In the form of
+ * array(index => object(property: value). Requires attach_id to be one of the object properties.
*/
phpbb.plupload.setData = function(data) {
// Make sure that the array keys are reset.
@@ -129,12 +121,11 @@ phpbb.plupload.setData = function(data) {
/**
* Update the attachment data in the HTML and the phpbb & phpbb.plupload objects.
- *
- * @param array data Array containing the new data to use.
- * @param string action The action that required the update. Used to update the inline attachment bbcodes.
- * @param int index The index from phpbb.plupload_ids that was affected by the action.
- * @param array downloadUrl Optional array of download urls to update.
- * @return undefined
+ *
+ * @param {Array} data Array containing the new data to use.
+ * @param {string} action The action that required the update. Used to update the inline attachment bbcodes.
+ * @param {int} index The index from phpbb.plupload_ids that was affected by the action.
+ * @param {Array} downloadUrl Optional array of download urls to update.
*/
phpbb.plupload.update = function(data, action, index, downloadUrl) {
@@ -147,9 +138,8 @@ phpbb.plupload.update = function(data, action, index, downloadUrl) {
/**
* Update the relevant elements and hidden data for all attachments.
- *
- * @param array downloadUrl Optional array of download urls to update.
- * @return undefined
+ *
+ * @param {Array} downloadUrl Optional array of download urls to update.
*/
phpbb.plupload.updateRows = function(downloadUrl) {
for (var i = 0; i < phpbb.plupload.ids.length; i++) {
@@ -162,9 +152,8 @@ phpbb.plupload.updateRows = function(downloadUrl) {
* using the id "attach-row-tpl" to be present. This snippet is cloned and the
* data for the file inserted into it. The row is then appended or prepended to
* #file-list based on the attach_order setting.
- *
- * @param object file Plupload file object for the new attachment.
- * @return undefined
+ *
+ * @param {object} file Plupload file object for the new attachment.
*/
phpbb.plupload.insertRow = function(file) {
var row = $(phpbb.plupload.rowTpl);
@@ -173,7 +162,7 @@ phpbb.plupload.insertRow = function(file) {
row.find('.file-name').html(plupload.xmlEncode(file.name));
row.find('.file-size').html(plupload.formatSize(file.size));
- if (phpbb.plupload.order == 'desc') {
+ if (phpbb.plupload.order === 'desc') {
$('#file-list').prepend(row);
} else {
$('#file-list').append(row);
@@ -182,10 +171,9 @@ phpbb.plupload.insertRow = function(file) {
/**
* Update the relevant elements and hidden data for an attachment.
- *
- * @param int index The index from phpbb.plupload.ids of the attachment to edit.
- * @param array downloadUrl Optional array of download urls to update.
- * @return undefined
+ *
+ * @param {int} index The index from phpbb.plupload.ids of the attachment to edit.
+ * @param {Array} downloadUrl Optional array of download urls to update.
*/
phpbb.plupload.updateRow = function(index, downloadUrl) {
var attach = phpbb.plupload.data[index],
@@ -197,7 +185,7 @@ phpbb.plupload.updateRow = function(index, downloadUrl) {
link = $('<a></a>');
link.attr('href', url).html(attach.real_filename);
- row.find('.file-name').html(link)
+ row.find('.file-name').html(link);
}
row.find('textarea').attr('name', 'comment_list[' + index + ']');
@@ -207,18 +195,21 @@ phpbb.plupload.updateRow = function(index, downloadUrl) {
/**
* Update hidden input data for an attachment.
*
- * @param object row jQuery object for the attachment row.
- * @param object attach Attachment data object from phpbb.plupload.data
- * @param int index Attachment index from phpbb.plupload.ids
- * @return undefined
+ * @param {object} row jQuery object for the attachment row.
+ * @param {object} attach Attachment data object from phpbb.plupload.data
+ * @param {int} index Attachment index from phpbb.plupload.ids
*/
phpbb.plupload.updateHiddenData = function(row, attach, index) {
row.find('input[type="hidden"]').remove();
for (var key in attach) {
+ if (!attach.hasOwnProperty(key)) {
+ return;
+ }
+
var input = $('<input />')
.attr('type', 'hidden')
- .attr('name', 'attachment_data[' + index + '][' + key +']')
+ .attr('name', 'attachment_data[' + index + '][' + key + ']')
.attr('value', attach[key]);
$('textarea', row).after(input);
}
@@ -230,10 +221,8 @@ phpbb.plupload.updateHiddenData = function(row, attach, index) {
* responds with the updated attachment data list so that any future
* uploads can maintain state with the server
*
- * @param object row jQuery object for the attachment row.
- * @param int attachId Attachment id of the file to be removed.
- *
- * @return undefined
+ * @param {object} row jQuery object for the attachment row.
+ * @param {int} attachId Attachment id of the file to be removed.
*/
phpbb.plupload.deleteFile = function(row, attachId) {
// If there's no attach id, then the file hasn't been uploaded. Simply delete the row.
@@ -267,7 +256,7 @@ phpbb.plupload.deleteFile = function(row, attachId) {
// trigger_error() was called which likely means a permission error was encountered.
if (typeof response.title !== 'undefined') {
- phpbb.plupload.uploader.trigger('Error', {message: response.message});
+ phpbb.plupload.uploader.trigger('Error', { message: response.message });
// We will have to assume that the deletion failed. So leave the file status as uploaded.
row.find('.file-status').toggleClass('file-uploaded');
@@ -292,7 +281,7 @@ phpbb.plupload.deleteFile = function(row, attachId) {
$.ajax(phpbb.plupload.config.url, {
type: 'POST',
data: $.extend(fields, phpbb.plupload.getSerializedData()),
- headers: {'X-PHPBB-USING-PLUPLOAD': '1', 'X-Requested-With': 'XMLHttpRequest'}
+ headers: { 'X-PHPBB-USING-PLUPLOAD': '1', 'X-Requested-With': 'XMLHttpRequest' }
})
.always(always)
.done(done);
@@ -300,25 +289,21 @@ phpbb.plupload.deleteFile = function(row, attachId) {
/**
* Check the attachment list and hide its container if it's empty.
- *
- * @return undefined
*/
phpbb.plupload.hideEmptyList = function() {
if (!$('#file-list').children().length) {
$('#file-list-container').slideUp(100);
}
-}
+};
/**
- * Update the indices used in inline attachment bbcodes. This ensures that the bbcodes
- * correspond to the correct file after a file is added or removed. This should be called
- * before the phpbb.plupload,data and phpbb.plupload.ids arrays are updated, otherwise it will
- * not work correctly.
+ * Update the indices used in inline attachment bbcodes. This ensures that the
+ * bbcodes correspond to the correct file after a file is added or removed.
+ * This should be called before the phpbb.plupload,data and phpbb.plupload.ids
+ * arrays are updated, otherwise it will not work correctly.
*
- * @param string action The action that occurred -- either "addition" or "removal"
- * @param int index The index of the attachment from phpbb.plupload.ids that was affected.
- *
- * @return undefined
+ * @param {string} action The action that occurred -- either "addition" or "removal"
+ * @param {int} index The index of the attachment from phpbb.plupload.ids that was affected.
*/
phpbb.plupload.updateBbcode = function(action, index) {
var textarea = $('#message', phpbb.plupload.form),
@@ -330,46 +315,41 @@ phpbb.plupload.updateBbcode = function(action, index) {
return;
}
- // Private function used to replace the bbcode.
- var updateBbcode = function(match, fileName) {
- // Remove the bbcode if the file was removed.
- if (removal && index === i) {
- return '';
- }
- var newIndex = i + ((removal) ? -1 : 1);
- return '[attachment=' + newIndex +']' + fileName + '[/attachment]';
- };
-
- // Private function used to generate search regexp
- var searchRegexp = function(index) {
- return new RegExp('\\[attachment=' + index + '\\](.*?)\\[\\/attachment\\]', 'g');
+ function runUpdate(i) {
+ var regex = new RegExp('\\[attachment=' + i + '\\](.*?)\\[\\/attachment\\]', 'g');
+ text = text.replace(regex, function updateBbcode(_, fileName) {
+ // Remove the bbcode if the file was removed.
+ if (removal && index === i) {
+ return '';
+ }
+ var newIndex = i + ((removal) ? -1 : 1);
+ return '[attachment=' + newIndex + ']' + fileName + '[/attachment]';
+ });
}
- // The update order of the indices is based on the action taken to ensure that we don't corrupt
- // the bbcode index by updating it several times as we move through the loop.
- // Removal loop starts at the removed index and moves to the end of the array.
- // Addition loop starts at the end of the array and moves to the added index at 0.
- var searchLoop = function() {
- if (typeof i === 'undefined') {
- i = (removal) ? index : phpbb.plupload.ids.length - 1;
+
+ // Loop forwards when removing and backwards when adding ensures we don't
+ // corrupt the bbcode index.
+ var i;
+ if (removal) {
+ for (i = index; i < phpbb.plupload.ids.length; i++) {
+ runUpdate(i);
+ }
+ } else {
+ for (i = phpbb.plupload.ids.length - 1; i >= index; i--) {
+ runUpdate(i);
}
- return (removal) ? (i < phpbb.plupload.ids.length): (i >= index);
}
- var i;
- while (searchLoop()) {
- text = text.replace(searchRegexp(i), updateBbcode);
- (removal) ? i++ : i--;
- }
textarea.val(text);
};
/**
* Get Plupload file objects based on their upload status.
*
- * @param int status Plupload status - plupload.DONE, plupload.FAILED, plupload.QUEUED,
- * plupload.STARTED, plupload.STOPPED
+ * @param {int} status Plupload status - plupload.DONE, plupload.FAILED,
+ * plupload.QUEUED, plupload.STARTED, plupload.STOPPED
*
- * @return Returns an array of the Plupload file objects matching the status.
+ * @returns {Array} The Plupload file objects matching the status.
*/
phpbb.plupload.getFilesByStatus = function(status) {
var files = [];
@@ -380,14 +360,14 @@ phpbb.plupload.getFilesByStatus = function(status) {
}
});
return files;
-}
+};
/**
* Check whether the user has reached the maximun number of files that he's allowed
* to upload. If so, disables the uploader and marks the queued files as failed. Otherwise
* makes sure that the uploader is enabled.
*
- * @return bool Returns true if the limit has been reached. False if otherwise.
+ * @returns {bool} True if the limit has been reached. False if otherwise.
*/
phpbb.plupload.handleMaxFilesReached = function() {
// If there is no limit, the user is an admin or moderator.
@@ -400,41 +380,36 @@ phpbb.plupload.handleMaxFilesReached = function() {
phpbb.plupload.markQueuedFailed(phpbb.plupload.lang.TOO_MANY_ATTACHMENTS);
// Disable the uploader.
phpbb.plupload.disableUploader();
- phpbb.plupload.uploader.trigger('Error', {message: phpbb.plupload.lang.TOO_MANY_ATTACHMENTS});
+ phpbb.plupload.uploader.trigger('Error', { message: phpbb.plupload.lang.TOO_MANY_ATTACHMENTS });
return true;
- } else if(phpbb.plupload.maxFiles > phpbb.plupload.ids.length) {
+ } else if (phpbb.plupload.maxFiles > phpbb.plupload.ids.length) {
// Enable the uploader if the user is under the limit
phpbb.plupload.enableUploader();
}
return false;
-}
+};
/**
* Disable the uploader
- *
- * @return undefined
*/
phpbb.plupload.disableUploader = function() {
$('#add_files').addClass('disabled');
phpbb.plupload.uploader.disableBrowse();
-}
+};
/**
* Enable the uploader
- *
- * @return undefined
*/
phpbb.plupload.enableUploader = function() {
$('#add_files').removeClass('disabled');
phpbb.plupload.uploader.disableBrowse(false);
-}
+};
/**
* Mark all queued files as failed.
*
- * @param string error Error message to present to the user.
- * @return undefined
+ * @param {string} error Error message to present to the user.
*/
phpbb.plupload.markQueuedFailed = function(error) {
var files = phpbb.plupload.getFilesByStatus(plupload.QUEUED);
@@ -443,22 +418,24 @@ phpbb.plupload.markQueuedFailed = function(error) {
$('#' + file.id).find('.file-progress').hide();
phpbb.plupload.fileError(file, error);
});
-}
+};
/**
* Marks a file as failed and sets the error message for it.
*
- * @param object file Plupload file object that failed.
- * @param string error Error message to present to the user.
- * @return undefined
+ * @param {object} file Plupload file object that failed.
+ * @param {string} error Error message to present to the user.
*/
phpbb.plupload.fileError = function(file, error) {
file.status = plupload.FAILED;
file.error = error;
- $('#' + file.id).find('.file-status').addClass('file-error').attr({'data-error-title': phpbb.plupload.lang.ERROR, 'data-error-message': error});
-}
-
-
+ $('#' + file.id).find('.file-status')
+ .addClass('file-error')
+ .attr({
+ 'data-error-title': phpbb.plupload.lang.ERROR,
+ 'data-error-message': error
+ });
+};
/**
@@ -467,24 +444,23 @@ phpbb.plupload.fileError = function(file, error) {
phpbb.plupload.uploader = new plupload.Uploader(phpbb.plupload.config);
phpbb.plupload.initialize();
-
-
+var $fileList = $('#file-list');
/**
* Insert inline attachment bbcode.
*/
- $('#file-list').on('click', '.file-inline-bbcode', function(e) {
+$fileList.on('click', '.file-inline-bbcode', function(e) {
var attachId = $(this).parents('.attach-row').attr('data-attach-id'),
index = phpbb.plupload.getIndex(attachId);
- attach_inline(index, phpbb.plupload.data[index].real_filename);
+ attachInline(index, phpbb.plupload.data[index].real_filename);
e.preventDefault();
});
/**
* Delete a file.
*/
-$('#file-list').on('click', '.file-delete', function(e) {
+$fileList.on('click', '.file-delete', function(e) {
var row = $(this).parents('.attach-row'),
attachId = row.attr('data-attach-id');
@@ -495,7 +471,7 @@ $('#file-list').on('click', '.file-delete', function(e) {
/**
* Display the error message for a particular file when the error icon is clicked.
*/
-$('#file-list').on('click', '.file-error', function(e) {
+$fileList.on('click', '.file-error', function(e) {
phpbb.alert($(this).attr('data-error-title'), $(this).attr('data-error-message'));
e.preventDefault();
});
@@ -520,18 +496,15 @@ phpbb.plupload.uploader.bind('Error', function(up, error) {
* send the real filename along with the chunk. This is necessary because
* for some reason the filename is set to 'blob' whenever a file is chunked
*
- * @param object up The plupload.Uploader object
- * @param object file The plupload.File object that is about to be
- * uploaded
- *
- * @return undefined
+ * @param {object} up The plupload.Uploader object
+ * @param {object} file The plupload.File object that is about to be uploaded
*/
phpbb.plupload.uploader.bind('BeforeUpload', function(up, file) {
if (phpbb.plupload.handleMaxFilesReached()) {
return;
}
- phpbb.plupload.updateMultipartParams({'real_filename': file.name});
+ phpbb.plupload.updateMultipartParams({ real_filename: file.name });
});
/**
@@ -539,12 +512,10 @@ phpbb.plupload.uploader.bind('BeforeUpload', function(up, file) {
* response from the server and checks for an error. If an error occurs it
* is reported to the user and the upload of this particular file is halted
*
- * @param object up The plupload.Uploader object
- * @param object file The plupload.File object whose chunk has just
+ * @param {object} up The plupload.Uploader object
+ * @param {object} file The plupload.File object whose chunk has just
* been uploaded
- * @param object response The response object from the server
- *
- * @return undefined
+ * @param {object} response The response object from the server
*/
phpbb.plupload.uploader.bind('ChunkUploaded', function(up, file, response) {
if (response.chunk >= response.chunks - 1) {
@@ -567,7 +538,7 @@ phpbb.plupload.uploader.bind('ChunkUploaded', function(up, file, response) {
// If trigger_error() was called, then a permission error likely occurred.
if (typeof json.title !== 'undefined') {
- json.error = {message: json.message};
+ json.error = { message: json.message };
}
if (json.error) {
@@ -584,8 +555,6 @@ phpbb.plupload.uploader.bind('ChunkUploaded', function(up, file, response) {
/**
* Fires when files are added to the queue.
- *
- * @return undefined
*/
phpbb.plupload.uploader.bind('FilesAdded', function(up, files) {
// Prevent unnecessary requests to the server if the user already uploaded
@@ -595,13 +564,14 @@ phpbb.plupload.uploader.bind('FilesAdded', function(up, files) {
}
// Switch the active tab if the style supports it
- if (typeof activateSubPanel == 'function') {
- activateSubPanel('attach-panel');
+ if (typeof activateSubPanel === 'function') {
+ activateSubPanel('attach-panel'); // jshint ignore: line
}
// Show the file list if there aren't any files currently.
- if (!$('#file-list-container').is(':visible')) {
- $('#file-list-container').show(100);
+ var $fileListContainer = $('#file-list-container');
+ if (!$fileListContainer.is(':visible')) {
+ $fileListContainer.show(100);
}
$.each(files, function(i, file) {
@@ -609,7 +579,7 @@ phpbb.plupload.uploader.bind('FilesAdded', function(up, files) {
});
up.bind('UploadProgress', function(up, file) {
- $('#' + file.id + " .file-progress-bar").css('width', file.percent + '%');
+ $('.file-progress-bar', '#' + file.id).css('width', file.percent + '%');
$('#file-total-progress-bar').css('width', up.total.percent + '%');
});
@@ -627,12 +597,10 @@ phpbb.plupload.uploader.bind('FilesAdded', function(up, files) {
* appends it to the next file upload so that the server can maintain state
* with regards to the attachments in a given post
*
- * @param object up The plupload.Uploader object
- * @param object file The plupload.File object that has just been
+ * @param {object} up The plupload.Uploader object
+ * @param {object} file The plupload.File object that has just been
* uploaded
- * @param string response The response string from the server
- *
- * @return undefined
+ * @param {string} response The response string from the server
*/
phpbb.plupload.uploader.bind('FileUploaded', function(up, file, response) {
var json = {},
@@ -643,7 +611,7 @@ phpbb.plupload.uploader.bind('FileUploaded', function(up, file, response) {
row.find('.file-progress').hide();
try {
- json = $.parseJSON(response.response);
+ json = JSON.parse(response.response);
} catch (e) {
error = 'Error parsing server response.';
}
@@ -651,7 +619,7 @@ phpbb.plupload.uploader.bind('FileUploaded', function(up, file, response) {
// If trigger_error() was called, then a permission error likely occurred.
if (typeof json.title !== 'undefined') {
error = json.message;
- up.trigger('Error', {message: error});
+ up.trigger('Error', { message: error });
// The rest of the queue will fail.
phpbb.plupload.markQueuedFailed(error);
@@ -662,25 +630,19 @@ phpbb.plupload.uploader.bind('FileUploaded', function(up, file, response) {
if (typeof error !== 'undefined') {
phpbb.plupload.fileError(file, error);
} else if (file.status === plupload.DONE) {
- file.attachment_data = json['data'][0];
+ file.attachment_data = json.data[0];
row.attr('data-attach-id', file.attachment_data.attach_id);
row.find('.file-inline-bbcode').show();
row.find('.file-status').addClass('file-uploaded');
- phpbb.plupload.update(json['data'], 'addition', 0, [json['download_url']]);
+ phpbb.plupload.update(json.data, 'addition', 0, [json.download_url]);
}
});
/**
- * Fires when the entire queue of files have been uploaded.
- *
- * @param object up The plupload.Uploader object
- * @param array files An array of plupload.File objects that have just
- * been uploaded as part of a queue
- *
- * @return undefined
+ * Fires when the entire queue of files have been uploaded.
*/
-phpbb.plupload.uploader.bind('UploadComplete', function(up, files) {
+phpbb.plupload.uploader.bind('UploadComplete', function() {
// Hide the progress bar
setTimeout(function() {
$('#file-total-progress-bar').fadeOut(500, function() {
diff --git a/phpBB/composer.json b/phpBB/composer.json
index 419779e5f7..2edd33a217 100644
--- a/phpBB/composer.json
+++ b/phpBB/composer.json
@@ -50,7 +50,7 @@
"phpunit/dbunit": "1.3.*",
"phpunit/phpunit": "4.1.*",
"sami/sami": "1.*",
- "squizlabs/php_codesniffer": "1.*",
+ "squizlabs/php_codesniffer": "2.*",
"symfony/browser-kit": "2.8.*@dev",
"symfony/css-selector": "2.8.*@dev",
"symfony/debug": "2.8.*@dev",
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index 64927a409a..2d965ecbee 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "c14bcbf5a6c4fd121492568aa3654c07",
+ "hash": "94d0f6dab53f11dab1de63c0ae519ee6",
"packages": [
{
"name": "lusitanian/oauth",
@@ -220,12 +220,12 @@
"source": {
"type": "git",
"url": "https://github.com/s9e/TextFormatter.git",
- "reference": "0a6016ab96ab1da5be73f7a407f96f57d307b6b6"
+ "reference": "4c124782e8f74cc462c4f27e81f81192b2853408"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/0a6016ab96ab1da5be73f7a407f96f57d307b6b6",
- "reference": "0a6016ab96ab1da5be73f7a407f96f57d307b6b6",
+ "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/4c124782e8f74cc462c4f27e81f81192b2853408",
+ "reference": "4c124782e8f74cc462c4f27e81f81192b2853408",
"shasum": ""
},
"require": {
@@ -270,21 +270,20 @@
"parser",
"shortcodes"
],
- "time": "2015-05-23 17:07:15"
+ "time": "2015-05-30 02:58:41"
},
{
"name": "symfony/config",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/Config",
"source": {
"type": "git",
"url": "https://github.com/symfony/Config.git",
- "reference": "c9a779b0f02f0fdf41cc4decc4fb451005365086"
+ "reference": "291e3f1ce92fec71632eada0d492833b41531718"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Config/zipball/c9a779b0f02f0fdf41cc4decc4fb451005365086",
- "reference": "c9a779b0f02f0fdf41cc4decc4fb451005365086",
+ "url": "https://api.github.com/repos/symfony/Config/zipball/291e3f1ce92fec71632eada0d492833b41531718",
+ "reference": "291e3f1ce92fec71632eada0d492833b41531718",
"shasum": ""
},
"require": {
@@ -301,7 +300,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Config\\": ""
}
},
@@ -311,31 +310,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Config Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-11 08:55:16"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
},
{
"name": "symfony/console",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
- "reference": "32f19477d488649a77227d57a7f5775b17cb336b"
+ "reference": "7e857a2b52b5833ed27d78a6b1b846bd440ee8bd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Console/zipball/32f19477d488649a77227d57a7f5775b17cb336b",
- "reference": "32f19477d488649a77227d57a7f5775b17cb336b",
+ "url": "https://api.github.com/repos/symfony/Console/zipball/7e857a2b52b5833ed27d78a6b1b846bd440ee8bd",
+ "reference": "7e857a2b52b5833ed27d78a6b1b846bd440ee8bd",
"shasum": ""
},
"require": {
@@ -359,7 +357,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Console\\": ""
}
},
@@ -369,31 +367,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Console Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-11 08:55:16"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
},
{
"name": "symfony/debug",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/Debug",
"source": {
"type": "git",
"url": "https://github.com/symfony/Debug.git",
- "reference": "2b867c246f3fb653611c9acdc3fdac9cc1957e3f"
+ "reference": "eda866deb149108bfeb4185593083919b186a463"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Debug/zipball/2b867c246f3fb653611c9acdc3fdac9cc1957e3f",
- "reference": "2b867c246f3fb653611c9acdc3fdac9cc1957e3f",
+ "url": "https://api.github.com/repos/symfony/Debug/zipball/eda866deb149108bfeb4185593083919b186a463",
+ "reference": "eda866deb149108bfeb4185593083919b186a463",
"shasum": ""
},
"require": {
@@ -420,7 +417,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Debug\\": ""
}
},
@@ -430,31 +427,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Debug Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
},
{
"name": "symfony/dependency-injection",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/DependencyInjection",
"source": {
"type": "git",
"url": "https://github.com/symfony/DependencyInjection.git",
- "reference": "ae47d9690326b0e970598a8f5b6710ece8f5fee4"
+ "reference": "90a75274cb85bd6f9aaf4a017e5dee616ffe8a1d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/ae47d9690326b0e970598a8f5b6710ece8f5fee4",
- "reference": "ae47d9690326b0e970598a8f5b6710ece8f5fee4",
+ "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/90a75274cb85bd6f9aaf4a017e5dee616ffe8a1d",
+ "reference": "90a75274cb85bd6f9aaf4a017e5dee616ffe8a1d",
"shasum": ""
},
"require": {
@@ -481,7 +477,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\DependencyInjection\\": ""
}
},
@@ -491,31 +487,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DependencyInjection Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-12 15:16:46"
},
{
"name": "symfony/event-dispatcher",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/EventDispatcher",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
- "reference": "15bbd5beed94cca89ffcce18fb76eeac38937240"
+ "reference": "8766cebf28beac9a45b511d7dba053da9d35eb9f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/15bbd5beed94cca89ffcce18fb76eeac38937240",
- "reference": "15bbd5beed94cca89ffcce18fb76eeac38937240",
+ "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/8766cebf28beac9a45b511d7dba053da9d35eb9f",
+ "reference": "8766cebf28beac9a45b511d7dba053da9d35eb9f",
"shasum": ""
},
"require": {
@@ -540,7 +535,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\EventDispatcher\\": ""
}
},
@@ -550,31 +545,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony EventDispatcher Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-12 15:16:46"
},
{
"name": "symfony/filesystem",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/Filesystem",
"source": {
"type": "git",
"url": "https://github.com/symfony/Filesystem.git",
- "reference": "59a58a369bafa7c2ded4e0b08d726482be7a7e6b"
+ "reference": "45cc231f1ecac70a8790bf1c88a823af8ce57056"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Filesystem/zipball/59a58a369bafa7c2ded4e0b08d726482be7a7e6b",
- "reference": "59a58a369bafa7c2ded4e0b08d726482be7a7e6b",
+ "url": "https://api.github.com/repos/symfony/Filesystem/zipball/45cc231f1ecac70a8790bf1c88a823af8ce57056",
+ "reference": "45cc231f1ecac70a8790bf1c88a823af8ce57056",
"shasum": ""
},
"require": {
@@ -590,7 +584,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Filesystem\\": ""
}
},
@@ -600,31 +594,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Filesystem Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
},
{
"name": "symfony/finder",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/Finder",
"source": {
"type": "git",
"url": "https://github.com/symfony/Finder.git",
- "reference": "ad159e0da47e9ffe719bafdc004159ad6e395567"
+ "reference": "fd26bdbb67bc8753884eff5767a4f1ee90e2284b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Finder/zipball/ad159e0da47e9ffe719bafdc004159ad6e395567",
- "reference": "ad159e0da47e9ffe719bafdc004159ad6e395567",
+ "url": "https://api.github.com/repos/symfony/Finder/zipball/fd26bdbb67bc8753884eff5767a4f1ee90e2284b",
+ "reference": "fd26bdbb67bc8753884eff5767a4f1ee90e2284b",
"shasum": ""
},
"require": {
@@ -640,7 +633,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Finder\\": ""
}
},
@@ -650,31 +643,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Finder Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
},
{
"name": "symfony/http-foundation",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/HttpFoundation",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpFoundation.git",
- "reference": "75b824419347be1926b3bb9ad14bb3c09d0b5141"
+ "reference": "06aa08b5d9157abc10bee99712124b8b994d4259"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/75b824419347be1926b3bb9ad14bb3c09d0b5141",
- "reference": "75b824419347be1926b3bb9ad14bb3c09d0b5141",
+ "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/06aa08b5d9157abc10bee99712124b8b994d4259",
+ "reference": "06aa08b5d9157abc10bee99712124b8b994d4259",
"shasum": ""
},
"require": {
@@ -691,11 +683,11 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\HttpFoundation\\": ""
},
"classmap": [
- "Symfony/Component/HttpFoundation/Resources/stubs"
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -704,31 +696,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony HttpFoundation Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
},
{
"name": "symfony/http-kernel",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/HttpKernel",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpKernel.git",
- "reference": "53e7ff047f0b19edea9bae99bd1de6e1c35139c5"
+ "reference": "c587069bb67bea9db7ed8aa82e4fe0c9b7867fa2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/53e7ff047f0b19edea9bae99bd1de6e1c35139c5",
- "reference": "53e7ff047f0b19edea9bae99bd1de6e1c35139c5",
+ "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/c587069bb67bea9db7ed8aa82e4fe0c9b7867fa2",
+ "reference": "c587069bb67bea9db7ed8aa82e4fe0c9b7867fa2",
"shasum": ""
},
"require": {
@@ -775,7 +766,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\HttpKernel\\": ""
}
},
@@ -785,31 +776,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony HttpKernel Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-11 08:55:16"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
},
{
"name": "symfony/routing",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/Routing",
"source": {
"type": "git",
"url": "https://github.com/symfony/Routing.git",
- "reference": "cc81fccd24bce7fde640d2e4b070fe76b60f0f6a"
+ "reference": "76b18edcf09a967590d6e132851d0f964866e2e8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Routing/zipball/cc81fccd24bce7fde640d2e4b070fe76b60f0f6a",
- "reference": "cc81fccd24bce7fde640d2e4b070fe76b60f0f6a",
+ "url": "https://api.github.com/repos/symfony/Routing/zipball/76b18edcf09a967590d6e132851d0f964866e2e8",
+ "reference": "76b18edcf09a967590d6e132851d0f964866e2e8",
"shasum": ""
},
"require": {
@@ -841,7 +831,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Routing\\": ""
}
},
@@ -851,37 +841,36 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Routing Component",
- "homepage": "http://symfony.com",
+ "homepage": "https://symfony.com",
"keywords": [
"router",
"routing",
"uri",
"url"
],
- "time": "2015-04-10 08:56:33"
+ "time": "2015-05-15 14:11:12"
},
{
"name": "symfony/security-core",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/Security/Core",
"source": {
"type": "git",
"url": "https://github.com/symfony/security-core.git",
- "reference": "992d40a1cd8b2647dce652b63a27fd18ff74e243"
+ "reference": "2c218453a47553aadc3fef60f44b9c10cdee34ac"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/security-core/zipball/992d40a1cd8b2647dce652b63a27fd18ff74e243",
- "reference": "992d40a1cd8b2647dce652b63a27fd18ff74e243",
+ "url": "https://api.github.com/repos/symfony/security-core/zipball/2c218453a47553aadc3fef60f44b9c10cdee34ac",
+ "reference": "2c218453a47553aadc3fef60f44b9c10cdee34ac",
"shasum": ""
},
"require": {
@@ -911,7 +900,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Security\\Core\\": ""
}
},
@@ -921,31 +910,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Security Component - Core Library",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
},
{
"name": "symfony/security-csrf",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/Security/Csrf",
"source": {
"type": "git",
"url": "https://github.com/symfony/security-csrf.git",
- "reference": "80cf46a34308e7374700889a3af115ef5d772d23"
+ "reference": "9e859301e5b19953338a50a5d3e1aeb01d37e9d1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/security-csrf/zipball/80cf46a34308e7374700889a3af115ef5d772d23",
- "reference": "80cf46a34308e7374700889a3af115ef5d772d23",
+ "url": "https://api.github.com/repos/symfony/security-csrf/zipball/9e859301e5b19953338a50a5d3e1aeb01d37e9d1",
+ "reference": "9e859301e5b19953338a50a5d3e1aeb01d37e9d1",
"shasum": ""
},
"require": {
@@ -966,7 +954,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Security\\Csrf\\": ""
}
},
@@ -976,31 +964,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Security Component - CSRF Library",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-13 11:36:16"
},
{
"name": "symfony/twig-bridge",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Bridge/Twig",
"source": {
"type": "git",
"url": "https://github.com/symfony/TwigBridge.git",
- "reference": "f05d28fb139db14d9793aee9b01244dc654810c2"
+ "reference": "2e072a1ff57989abf76a04dc6b02838b7bdccb44"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/TwigBridge/zipball/f05d28fb139db14d9793aee9b01244dc654810c2",
- "reference": "f05d28fb139db14d9793aee9b01244dc654810c2",
+ "url": "https://api.github.com/repos/symfony/TwigBridge/zipball/2e072a1ff57989abf76a04dc6b02838b7bdccb44",
+ "reference": "2e072a1ff57989abf76a04dc6b02838b7bdccb44",
"shasum": ""
},
"require": {
@@ -1012,7 +999,7 @@
"symfony/console": "~2.7|~3.0.0",
"symfony/expression-language": "~2.4|~3.0.0",
"symfony/finder": "~2.3|~3.0.0",
- "symfony/form": "~2.7|~3.0.0",
+ "symfony/form": "~2.8|~3.0.0",
"symfony/http-kernel": "~2.3|~3.0.0",
"symfony/intl": "~2.3|~3.0.0",
"symfony/phpunit-bridge": "~2.7|~3.0.0",
@@ -1045,7 +1032,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Bridge\\Twig\\": ""
}
},
@@ -1055,31 +1042,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Twig Bridge",
- "homepage": "http://symfony.com",
- "time": "2015-04-11 08:55:16"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-20 08:44:53"
},
{
"name": "symfony/yaml",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
- "reference": "fdded56dde4ca9efce6322887bf5eaa7bb0aae3e"
+ "reference": "2396832f6f9ab2b8f62f00b5d3f2e722fc773d65"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Yaml/zipball/fdded56dde4ca9efce6322887bf5eaa7bb0aae3e",
- "reference": "fdded56dde4ca9efce6322887bf5eaa7bb0aae3e",
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/2396832f6f9ab2b8f62f00b5d3f2e722fc773d65",
+ "reference": "2396832f6f9ab2b8f62f00b5d3f2e722fc773d65",
"shasum": ""
},
"require": {
@@ -1095,7 +1081,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Yaml\\": ""
}
},
@@ -1105,17 +1091,17 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-12 15:16:46"
},
{
"name": "twig/twig",
@@ -2389,41 +2375,45 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "1.5.2",
+ "version": "2.3.2",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "a76a39b317ce8106abe6264daa505e24e1731860"
+ "reference": "e96d8579fbed0c95ecf2a0501ec4f307a4aa6404"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/a76a39b317ce8106abe6264daa505e24e1731860",
- "reference": "a76a39b317ce8106abe6264daa505e24e1731860",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/e96d8579fbed0c95ecf2a0501ec4f307a4aa6404",
+ "reference": "e96d8579fbed0c95ecf2a0501ec4f307a4aa6404",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
"php": ">=5.1.2"
},
- "suggest": {
- "phpunit/php-timer": "dev-master"
- },
"bin": [
- "scripts/phpcs"
+ "scripts/phpcs",
+ "scripts/phpcbf"
],
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
"autoload": {
"classmap": [
"CodeSniffer.php",
"CodeSniffer/CLI.php",
"CodeSniffer/Exception.php",
"CodeSniffer/File.php",
+ "CodeSniffer/Fixer.php",
"CodeSniffer/Report.php",
"CodeSniffer/Reporting.php",
"CodeSniffer/Sniff.php",
"CodeSniffer/Tokens.php",
"CodeSniffer/Reports/",
- "CodeSniffer/CommentParser/",
"CodeSniffer/Tokenizers/",
"CodeSniffer/DocGenerators/",
"CodeSniffer/Standards/AbstractPatternSniff.php",
@@ -2449,27 +2439,26 @@
"role": "lead"
}
],
- "description": "PHP_CodeSniffer tokenises PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
"homepage": "http://www.squizlabs.com/php-codesniffer",
"keywords": [
"phpcs",
"standards"
],
- "time": "2014-02-04 23:49:58"
+ "time": "2015-04-28 23:28:20"
},
{
"name": "symfony/browser-kit",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/BrowserKit",
"source": {
"type": "git",
"url": "https://github.com/symfony/BrowserKit.git",
- "reference": "e7ac73ecdd97f5b114152eb670607e96db7a2e17"
+ "reference": "491639704334283b5f1d87bb3298400f1f5cd2bf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/e7ac73ecdd97f5b114152eb670607e96db7a2e17",
- "reference": "e7ac73ecdd97f5b114152eb670607e96db7a2e17",
+ "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/491639704334283b5f1d87bb3298400f1f5cd2bf",
+ "reference": "491639704334283b5f1d87bb3298400f1f5cd2bf",
"shasum": ""
},
"require": {
@@ -2491,7 +2480,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\BrowserKit\\": ""
}
},
@@ -2501,31 +2490,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony BrowserKit Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-12 15:16:46"
},
{
"name": "symfony/css-selector",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/CssSelector",
"source": {
"type": "git",
"url": "https://github.com/symfony/CssSelector.git",
- "reference": "c315f95be51278f548d36664d51a8425e19e2cda"
+ "reference": "5b0968a01e1f6fb724ecc8b7334d662ad4c8cda6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/CssSelector/zipball/c315f95be51278f548d36664d51a8425e19e2cda",
- "reference": "c315f95be51278f548d36664d51a8425e19e2cda",
+ "url": "https://api.github.com/repos/symfony/CssSelector/zipball/5b0968a01e1f6fb724ecc8b7334d662ad4c8cda6",
+ "reference": "5b0968a01e1f6fb724ecc8b7334d662ad4c8cda6",
"shasum": ""
},
"require": {
@@ -2541,7 +2529,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\CssSelector\\": ""
}
},
@@ -2551,35 +2539,34 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony CssSelector Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
},
{
"name": "symfony/dom-crawler",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/DomCrawler",
"source": {
"type": "git",
"url": "https://github.com/symfony/DomCrawler.git",
- "reference": "c7bd5b7d8444175f04e4278fa220fd3470c851fe"
+ "reference": "3a523d1725d5835e4a7277358190e7efae7d872f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/c7bd5b7d8444175f04e4278fa220fd3470c851fe",
- "reference": "c7bd5b7d8444175f04e4278fa220fd3470c851fe",
+ "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/3a523d1725d5835e4a7277358190e7efae7d872f",
+ "reference": "3a523d1725d5835e4a7277358190e7efae7d872f",
"shasum": ""
},
"require": {
@@ -2599,7 +2586,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\DomCrawler\\": ""
}
},
@@ -2609,31 +2596,30 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DomCrawler Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-12 15:16:46"
},
{
"name": "symfony/process",
"version": "2.8.x-dev",
- "target-dir": "Symfony/Component/Process",
"source": {
"type": "git",
"url": "https://github.com/symfony/Process.git",
- "reference": "5c73c03223e922c3c5f2c4128984e82a44089bbc"
+ "reference": "daf96f1491cf0b8d8de60e6d3b5fda8e502b3798"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Process/zipball/5c73c03223e922c3c5f2c4128984e82a44089bbc",
- "reference": "5c73c03223e922c3c5f2c4128984e82a44089bbc",
+ "url": "https://api.github.com/repos/symfony/Process/zipball/daf96f1491cf0b8d8de60e6d3b5fda8e502b3798",
+ "reference": "daf96f1491cf0b8d8de60e6d3b5fda8e502b3798",
"shasum": ""
},
"require": {
@@ -2649,7 +2635,7 @@
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\Process\\": ""
}
},
@@ -2659,17 +2645,17 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Process Component",
- "homepage": "http://symfony.com",
- "time": "2015-04-10 08:56:33"
+ "homepage": "https://symfony.com",
+ "time": "2015-05-15 14:11:12"
}
],
"aliases": [],
diff --git a/phpBB/config/default/container/services.yml b/phpBB/config/default/container/services.yml
index 6577a44195..cab82a5d9c 100644
--- a/phpBB/config/default/container/services.yml
+++ b/phpBB/config/default/container/services.yml
@@ -10,7 +10,9 @@ imports:
- { resource: services_feed.yml }
- { resource: services_help.yml }
- { resource: services_language.yml }
+ - { resource: services_migrator.yml }
- { resource: services_mimetype_guesser.yml }
+ - { resource: services_module.yml }
- { resource: services_notification.yml }
- { resource: services_password.yml }
- { resource: services_profilefield.yml }
diff --git a/phpBB/config/default/container/services_db.yml b/phpBB/config/default/container/services_db.yml
index ae2707b9a5..ed3f88c704 100644
--- a/phpBB/config/default/container/services_db.yml
+++ b/phpBB/config/default/container/services_db.yml
@@ -79,66 +79,3 @@ services:
- %core.root_path%
- @request
- @dbal.conn.driver
-
-# ----- Migrator -----
- migrator:
- class: phpbb\db\migrator
- arguments:
- - @service_container
- - @config
- - @dbal.conn
- - @dbal.tools
- - %tables.migrations%
- - %core.root_path%
- - %core.php_ext%
- - %core.table_prefix%
- - @migrator.tool_collection
- - @migrator.helper
-
- migrator.helper:
- class: phpbb\db\migration\helper
-
-# ----- Migrator's tools -----
- migrator.tool_collection:
- class: phpbb\di\service_collection
- arguments:
- - @service_container
- tags:
- - { name: service_collection, tag: migrator.tool }
-
- migrator.tool.config:
- class: phpbb\db\migration\tool\config
- arguments:
- - @config
- tags:
- - { name: migrator.tool }
-
- migrator.tool.config_text:
- class: phpbb\db\migration\tool\config_text
- arguments:
- - @config_text
- tags:
- - { name: migrator.tool }
-
- migrator.tool.module:
- class: phpbb\db\migration\tool\module
- arguments:
- - @dbal.conn
- - @cache
- - @user
- - %core.root_path%
- - %core.php_ext%
- - %tables.modules%
- tags:
- - { name: migrator.tool }
-
- migrator.tool.permission:
- class: phpbb\db\migration\tool\permission
- arguments:
- - @dbal.conn
- - @cache
- - @auth
- - %core.root_path%
- - %core.php_ext%
- tags:
- - { name: migrator.tool }
diff --git a/phpBB/config/default/container/services_migrator.yml b/phpBB/config/default/container/services_migrator.yml
index cd04eea5c2..01bd7d3a11 100644
--- a/phpBB/config/default/container/services_migrator.yml
+++ b/phpBB/config/default/container/services_migrator.yml
@@ -1,7 +1,9 @@
services:
+# ----- Migrator -----
migrator:
class: phpbb\db\migrator
arguments:
+ - @service_container
- @config
- @dbal.conn
- @dbal.tools
@@ -15,6 +17,7 @@ services:
migrator.helper:
class: phpbb\db\migration\helper
+# ----- Migrator's tools -----
migrator.tool_collection:
class: phpbb\di\service_collection
arguments:
@@ -42,6 +45,7 @@ services:
- @dbal.conn
- @cache
- @user
+ - @module.manager
- %core.root_path%
- %core.php_ext%
- %tables.modules%
diff --git a/phpBB/config/default/container/services_module.yml b/phpBB/config/default/container/services_module.yml
new file mode 100644
index 0000000000..513b71553a
--- /dev/null
+++ b/phpBB/config/default/container/services_module.yml
@@ -0,0 +1,10 @@
+services:
+ module.manager:
+ class: phpbb\module\module_manager
+ arguments:
+ - @cache.driver
+ - @dbal.conn
+ - @ext.manager
+ - %tables.modules%
+ - %core.root_path%
+ - %core.php_ext%
diff --git a/phpBB/config/default/container/services_routing.yml b/phpBB/config/default/container/services_routing.yml
index 6749202c0d..f76b5e5ede 100644
--- a/phpBB/config/default/container/services_routing.yml
+++ b/phpBB/config/default/container/services_routing.yml
@@ -2,6 +2,7 @@ services:
router:
class: phpbb\routing\router
arguments:
+ - @service_container
- @filesystem
- %core.root_path%
- %core.php_ext%
diff --git a/phpBB/develop/search_fill.php b/phpBB/develop/search_fill.php
index 2a4dfb212c..07c4024b2f 100644
--- a/phpBB/develop/search_fill.php
+++ b/phpBB/develop/search_fill.php
@@ -40,7 +40,7 @@ if (!class_exists($search_type))
}
$error = false;
-$search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+$search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if ($error)
{
diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html
index 88df39a6d5..c9b292ab6d 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -49,6 +49,7 @@
<ol>
<li><a href="#changelog">Changelog</a>
<ul>
+ <li><a href="#v314">Changes since 3.1.4</a></li>
<li><a href="#v313">Changes since 3.1.3</a></li>
<li><a href="#v313rc1">Changes since 3.1.3-RC1</a></li>
<li><a href="#v312">Changes since 3.1.2</a></li>
@@ -111,6 +112,90 @@
<div class="content">
+ <a name="v314"></a><h3>Changes since 3.1.4</h3>
+
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9563">PHPBB3-9563</a>] - Empty categories showing up on index</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11521">PHPBB3-11521</a>] - Missing language string when migration is invalid</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11532">PHPBB3-11532</a>] - acp_users_overview.html autocompletes &quot;confirm email&quot; and &quot;password&quot; fields in chrome</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13516">PHPBB3-13516</a>] - icc-profiler check should skip extensions vendor</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13564">PHPBB3-13564</a>] - User is not removed from oauth tables upon deletion</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13664">PHPBB3-13664</a>] - Allow changing total list for unapproved posts in mcp_front</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13755">PHPBB3-13755</a>] - uploading attachments results in error: parsing server response. </li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13763">PHPBB3-13763</a>] - Language Spelling Error: Completly</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13771">PHPBB3-13771</a>] - AJAX responses do not support exceptions messages</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13772">PHPBB3-13772</a>] - Error in @param variable type for phpbb\passwords\manager</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13779">PHPBB3-13779</a>] - Permission set migration tool grants regular users heightened permissions</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13787">PHPBB3-13787</a>] - Duplicate entry of poll_delete in prosilver template</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13792">PHPBB3-13792</a>] - Travis fails installing hhvm-nigthly</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13819">PHPBB3-13819</a>] - Add missing sql_freeresult() to files in includes/</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13822">PHPBB3-13822</a>] - Permissions are in the wrong category</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13823">PHPBB3-13823</a>] - Update package is missing file with inline whitespace changes</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13827">PHPBB3-13827</a>] - controller\helper::message does not return JSON object for AJAX requests</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13830">PHPBB3-13830</a>] - phpcs doesn't detect class using in catch blocks</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13833">PHPBB3-13833</a>] - Submit a lot of messages without timeout between messages</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13838">PHPBB3-13838</a>] - Add a sniff to ensure that the opening brace of a control statement is on the line after</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13852">PHPBB3-13852</a>] - Inconsistent tab navigation when login in</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13861">PHPBB3-13861</a>] - Old styles are not removed by style update migration</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13868">PHPBB3-13868</a>] - Adding multiple language files for acp/mcp/ucp modules is incorrectly handled for extensions</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13873">PHPBB3-13873</a>] - Remove broken print stylesheet in preference of &amp;view=print</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13875">PHPBB3-13875</a>] - Lint test should ignore cache, ext, and store folder</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13878">PHPBB3-13878</a>] - Properly display background images when printing with webkit browser</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13888">PHPBB3-13888</a>] - &quot;Couldn't fetch mysqli_result&quot; error on username search and egosearch</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13913">PHPBB3-13913</a>] - Post subject of password protected and list-only forums shown on board index</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13922">PHPBB3-13922</a>] - Whitespace found at end of line phpBB/includes/functions_admin.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13928">PHPBB3-13928</a>] - Fix build_cfg_template_test after ticket/sec-184 </li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13939">PHPBB3-13939</a>] - phpBB no longer shows error messages when uploading files with drag/drop</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13942">PHPBB3-13942</a>] - phpbb\user::set_lang() adds extra path and PHP extension to ext lang files</li>
+ </ul>
+ <h4>Improvement</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12101">PHPBB3-12101</a>] - Redirect for Microsoft servers in /includes/functions.php:redirect()</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12542">PHPBB3-12542</a>] - Highlight textarea when files are dragged over it</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12717">PHPBB3-12717</a>] - Improve the code sniffer</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13200">PHPBB3-13200</a>] - Add autocomplete=&quot;off&quot; to additional password fields</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13648">PHPBB3-13648</a>] - Allow extensions using custom bbcode validation methods</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13699">PHPBB3-13699</a>] - Add template events in viewforum_body.html before and after the title</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13745">PHPBB3-13745</a>] - Add veiwtopic.php core event to allow manipulating poll data</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13750">PHPBB3-13750</a>] - Add generate_forum_nav() core event to allow modifying navlinks text</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13752">PHPBB3-13752</a>] - Add viewonline.php core event to allow modifying forum data SQL query</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13753">PHPBB3-13753</a>] - Add template events to forum category header</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13778">PHPBB3-13778</a>] - Misleading instruction text for recaptcha plugin</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13790">PHPBB3-13790</a>] - Update phpcs to 2.3.2</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13791">PHPBB3-13791</a>] - Add more post buttons template events to viewtopic_body.html</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13808">PHPBB3-13808</a>] - Add event before and after the search form</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13809">PHPBB3-13809</a>] - Test php parsing on php7 on travis</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13841">PHPBB3-13841</a>] - Add event when topics are moved</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13858">PHPBB3-13858</a>] - Make the Plupload uploader instance available in the global namespace</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13872">PHPBB3-13872</a>] - Allow template events to have a changed tag</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13876">PHPBB3-13876</a>] - Use async webfontloader to load webfont from googles CDN</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13905">PHPBB3-13905</a>] - loading.gif loaded before document load when it isn't needed</li>
+ </ul>
+ <h4>Security Issue</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13917">PHPBB3-13917</a>] - Use hash_equals() if possible in password driver helper</li>
+ <li>[SECURITY-184] - Do not output passwords to HTML input fields</li>
+ </ul>
+ <h4>Sub-task</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13660">PHPBB3-13660</a>] - Allow changing the query for total reports in mcp_front</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13661">PHPBB3-13661</a>] - Allow changing how and which logs are retrieved</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13668">PHPBB3-13668</a>] - Allow modifying the query to get details from the post report</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13672">PHPBB3-13672</a>] - Allow changing the query to obtain the user-submitted report.</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13685">PHPBB3-13685</a>] - Allow modifying the keywords search query for mysql fulltext search</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13686">PHPBB3-13686</a>] - Allow modifying the fulltext native search query for total results before before</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13689">PHPBB3-13689</a>] - Allow modifying the Postgres native search query for results</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13691">PHPBB3-13691</a>] - Allow modifying the fulltext native search query for total results for author</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13693">PHPBB3-13693</a>] - Allow modifying the MySQL author search query for results</li>
+ </ul>
+ <h4>Task</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13807">PHPBB3-13807</a>] - Extend event exporter to filter by min or max version to allow generating event diffs for releases</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13887">PHPBB3-13887</a>] - JS could use some refactoring</li>
+ </ul>
+
+
<a name="v313"></a><h3>Changes since 3.1.3</h3>
<h4>Security</h4>
diff --git a/phpBB/docs/CREDITS.txt b/phpBB/docs/CREDITS.txt
index e3f2b325e8..deb36339b0 100644
--- a/phpBB/docs/CREDITS.txt
+++ b/phpBB/docs/CREDITS.txt
@@ -23,6 +23,7 @@ phpBB Project Manager: Marshalrusty (Yuriy Rusko)
phpBB Lead Developer: naderman (Nils Adermann)
phpBB Developers: bantu (Andreas Fischer)
+ CHItA (Máté Bartus)
dhruv.goel92 (Dhruv Goel)
Elsensee (Oliver Schramm)
marc1706 (Marc Alexander)
diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md
index df62034304..d15f86a6a3 100644
--- a/phpBB/docs/events.md
+++ b/phpBB/docs/events.md
@@ -501,6 +501,41 @@ mcp_front_latest_unapproved_before
* Since: 3.1.3-RC1
* Purpose: Add content before latest unapproved posts list
+mcp_post_additional_options
+===
+* Locations:
+ + styles/prosilver/template/mcp_post.html
+* Since: 3.1.5-RC1
+* Purpose: Add content within the list of post moderation actions
+
+mcp_warn_post_add_warning_field_after
+===
+* Locations:
+ + styles/prosilver/template/mcp_warn_post.html
+* Since: 3.1.0-RC4
+* Purpose: Add content during warning for a post - after add warning field.
+
+mcp_warn_post_add_warning_field_before
+===
+* Locations:
+ + styles/prosilver/template/mcp_warn_post.html
+* Since: 3.1.0-RC4
+* Purpose: Add content during warning for a post - before add warning field.
+
+mcp_warn_user_add_warning_field_after
+===
+* Locations:
+ + styles/prosilver/template/mcp_warn_user.html
+* Since: 3.1.0-RC4
+* Purpose: Add content during warning a user - after add warning field.
+
+mcp_warn_user_add_warning_field_before
+===
+* Locations:
+ + styles/prosilver/template/mcp_warn_user.html
+* Since: 3.1.0-RC4
+* Purpose: Add content during warning a user - before add warning field.
+
memberlist_body_username_append
===
* Locations:
@@ -580,34 +615,6 @@ memberlist_view_user_statistics_before
* Since: 3.1.0-a1
* Purpose: Add entries before the user statistics part of any user profile
-mcp_warn_post_add_warning_field_after
-===
-* Locations:
- + styles/prosilver/template/mcp_warn_post.html
-* Since: 3.1.0-RC4
-* Purpose: Add content during warning for a post - after add warning field.
-
-mcp_warn_post_add_warning_field_before
-===
-* Locations:
- + styles/prosilver/template/mcp_warn_post.html
-* Since: 3.1.0-RC4
-* Purpose: Add content during warning for a post - before add warning field.
-
-mcp_warn_user_add_warning_field_after
-===
-* Locations:
- + styles/prosilver/template/mcp_warn_user.html
-* Since: 3.1.0-RC4
-* Purpose: Add content during warning a user - after add warning field.
-
-mcp_warn_user_add_warning_field_before
-===
-* Locations:
- + styles/prosilver/template/mcp_warn_user.html
-* Since: 3.1.0-RC4
-* Purpose: Add content during warning a user - before add warning field.
-
navbar_header_logged_out_content
===
* Locations:
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index ff3b50174b..018eedda2a 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -501,7 +501,7 @@ class acp_board
}
// We go through the display_vars to make sure no one is trying to set variables he/she is not allowed to...
- foreach ($display_vars['vars'] as $config_name => $null)
+ foreach ($display_vars['vars'] as $config_name => $data)
{
if (!isset($cfg_array[$config_name]) || strpos($config_name, 'legend') !== false)
{
@@ -533,6 +533,13 @@ class acp_board
if ($submit)
{
+ if (strpos($data['type'], 'password') === 0 && $config_value === '********')
+ {
+ // Do not update password fields if the content is ********,
+ // because that is the password replacement we use to not
+ // send the password to the output
+ continue;
+ }
$config->set($config_name, $config_value);
if ($config_name == 'allow_quick_reply' && isset($_POST['allow_quick_reply_enable']))
@@ -562,6 +569,7 @@ class acp_board
$old_auth_config = array();
foreach ($auth_providers as $provider)
{
+ /** @var \phpbb\auth\provider\provider_interface $provider */
if ($fields = $provider->acp())
{
// Check if we need to create config fields for this plugin and save config when submit was pressed
@@ -577,6 +585,14 @@ class acp_board
continue;
}
+ if (substr($field, -9) === '_password' && $cfg_array[$field] === '********')
+ {
+ // Do not update password fields if the content is ********,
+ // because that is the password replacement we use to not
+ // send the password to the output
+ continue;
+ }
+
$old_auth_config[$field] = $this->new_config[$field];
$config_value = $cfg_array[$field];
$this->new_config[$field] = $config_value;
diff --git a/phpBB/includes/acp/acp_jabber.php b/phpBB/includes/acp/acp_jabber.php
index d860ae27f4..5058e9c769 100644
--- a/phpBB/includes/acp/acp_jabber.php
+++ b/phpBB/includes/acp/acp_jabber.php
@@ -107,7 +107,10 @@ class acp_jabber
$config->set('jab_host', $jab_host);
$config->set('jab_port', $jab_port);
$config->set('jab_username', $jab_username);
- $config->set('jab_password', $jab_password);
+ if ($jab_password !== '********')
+ {
+ $config->set('jab_password', $jab_password);
+ }
$config->set('jab_package_size', $jab_package_size);
$config->set('jab_use_ssl', $jab_use_ssl);
@@ -122,7 +125,7 @@ class acp_jabber
'JAB_HOST' => $jab_host,
'JAB_PORT' => ($jab_port) ? $jab_port : '',
'JAB_USERNAME' => $jab_username,
- 'JAB_PASSWORD' => $jab_password,
+ 'JAB_PASSWORD' => $jab_password !== '' ? '********' : '',
'JAB_PACKAGE_SIZE' => $jab_package_size,
'JAB_USE_SSL' => $jab_use_ssl,
'S_CAN_USE_SSL' => jabber::can_use_ssl(),
diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php
index 8680b7786a..8a53edb8ee 100644
--- a/phpBB/includes/acp/acp_main.php
+++ b/phpBB/includes/acp/acp_main.php
@@ -638,7 +638,7 @@ class acp_main
{
$error = false;
$search_type = $config['search_type'];
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if (!$search->index_created())
{
diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php
index 4fca366868..c2407f15b4 100644
--- a/phpBB/includes/acp/acp_modules.php
+++ b/phpBB/includes/acp/acp_modules.php
@@ -19,6 +19,8 @@ if (!defined('IN_PHPBB'))
exit;
}
+use phpbb\module\exception\module_exception;
+
/**
* - Able to check for new module versions (modes changed/adjusted/added/removed)
* Icons for:
@@ -37,8 +39,10 @@ class acp_modules
function main($id, $mode)
{
- global $db, $user, $auth, $template, $module, $request, $phpbb_log;
- global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx;
+ global $db, $user, $template, $module, $request, $phpbb_log, $phpbb_container;
+
+ /** @var \phpbb\module\module_manager $module_manager */
+ $module_manager = $phpbb_container->get('module.manager');
// Set a global define for modules we might include (the author is able to prevent execution of code by checking this constant)
define('MODULE_INCLUDE', true);
@@ -91,13 +95,20 @@ class acp_modules
$db->sql_freeresult($result);
}
- $errors = $this->delete_module($module_id);
-
- if (!sizeof($errors))
+ try
{
- $this->remove_cache_file();
- trigger_error($user->lang['MODULE_DELETED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
+ $row = $module_manager->get_module_row($module_id, $this->module_class);
+ $module_manager->delete_module($module_id, $this->module_class);
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_REMOVED', false, array($user->lang($row['module_langname'])));
}
+ catch (module_exception $e)
+ {
+ $msg = $user->lang($e->getMessage());
+ trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
+ }
+
+ $module_manager->remove_cache_file($this->module_class);
+ trigger_error($user->lang['MODULE_DELETED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
}
else
{
@@ -138,8 +149,8 @@ class acp_modules
AND module_id = $module_id";
$db->sql_query($sql);
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_' . strtoupper($action), false, array($this->lang_name($row['module_langname'])));
- $this->remove_cache_file();
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_' . strtoupper($action), false, array($user->lang($row['module_langname'])));
+ $module_manager->remove_cache_file($this->module_class);
break;
@@ -163,12 +174,16 @@ class acp_modules
trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
}
- $move_module_name = $this->move_module_by($row, $action, 1);
+ try
+ {
+ $move_module_name = $module_manager->move_module_by($row, $this->module_class, $action, 1);
- if ($move_module_name !== false)
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_' . strtoupper($action), false, array($user->lang($row['module_langname']), $move_module_name));
+ $module_manager->remove_cache_file($this->module_class);
+ }
+ catch (module_exception $e)
{
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_' . strtoupper($action), false, array($this->lang_name($row['module_langname']), $move_module_name));
- $this->remove_cache_file();
+ // Do nothing
}
if ($request->is_ajax())
@@ -194,7 +209,7 @@ class acp_modules
list($module_basename, $module_mode) = explode('::', $quick_install);
// Check if module name and mode exist...
- $fileinfo = $this->get_module_infos($module_basename);
+ $fileinfo = $module_manager->get_module_infos($this->module_class, $module_basename);
$fileinfo = $fileinfo[$module_basename];
if (isset($fileinfo['modes'][$module_mode]))
@@ -210,11 +225,20 @@ class acp_modules
'module_auth' => $fileinfo['modes'][$module_mode]['auth'],
);
- $errors = $this->update_module_data($module_data);
+ try
+ {
+ $module_manager->update_module_data($module_data);
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_ADD', false, array($user->lang($module_data['module_langname'])));
+ }
+ catch (\phpbb\module\exception\module_exception $e)
+ {
+ $msg = $user->lang($e->getMessage());
+ trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
+ }
if (!sizeof($errors))
{
- $this->remove_cache_file();
+ $module_manager->remove_cache_file($this->module_class);
trigger_error($user->lang['MODULE_ADDED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
}
@@ -240,7 +264,15 @@ class acp_modules
trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
}
- $module_row = $this->get_module_row($module_id);
+ try
+ {
+ $module_row = $module_manager->get_module_row($module_id, $this->module_class);
+ }
+ catch (\phpbb\module\exception\module_not_found_exception $e)
+ {
+ $msg = $user->lang($e->getMessage());
+ trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
+ }
// no break
@@ -294,15 +326,29 @@ class acp_modules
// Adjust auth row
if ($module_data['module_basename'] && $module_data['module_mode'])
{
- $fileinfo = $this->get_module_infos($module_data['module_basename']);
+ $fileinfo = $module_manager->get_module_infos($this->module_class, $module_data['module_basename']);
$module_data['module_auth'] = $fileinfo[$module_data['module_basename']]['modes'][$module_data['module_mode']]['auth'];
}
- $errors = $this->update_module_data($module_data);
+ try
+ {
+ $module_manager->update_module_data($module_data);
+ $phpbb_log->add('admin',
+ $user->data['user_id'],
+ $user->ip,
+ ($action === 'edit') ? 'LOG_MODULE_EDIT' : 'LOG_MODULE_ADD',
+ false,
+ array($user->lang($module_data['module_langname']))
+ ); }
+ catch (\phpbb\module\exception\module_exception $e)
+ {
+ $msg = $user->lang($e->getMessage());
+ trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
+ }
if (!sizeof($errors))
{
- $this->remove_cache_file();
+ $module_manager->remove_cache_file($this->module_class);
trigger_error((($action == 'add') ? $user->lang['MODULE_ADDED'] : $user->lang['MODULE_EDITED']) . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
}
@@ -312,7 +358,7 @@ class acp_modules
$is_cat = (!$module_data['module_basename']) ? true : false;
// Get module information
- $module_infos = $this->get_module_infos();
+ $module_infos = $module_manager->get_module_infos($this->module_class);
// Build name options
$s_name_options = $s_mode_options = '';
@@ -324,7 +370,7 @@ class acp_modules
}
// Name options
- $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $this->lang_name($values['title']) . ' [' . $option . ']</option>';
+ $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $user->lang($values['title']) . ' [' . $option . ']</option>';
$template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option)));
@@ -333,14 +379,14 @@ class acp_modules
{
if ($option == $module_data['module_basename'])
{
- $s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $this->lang_name($m_values['title']) . '</option>';
+ $s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $user->lang($m_values['title']) . '</option>';
}
$template->assign_block_vars('m_names.modes', array(
'OPTION' => $m_mode,
- 'VALUE' => $this->lang_name($m_values['title']),
+ 'VALUE' => $user->lang($m_values['title']),
'A_OPTION' => addslashes($m_mode),
- 'A_VALUE' => addslashes($this->lang_name($m_values['title'])))
+ 'A_VALUE' => addslashes($user->lang($m_values['title'])))
);
}
}
@@ -358,7 +404,7 @@ class acp_modules
'L_TITLE' => $user->lang[strtoupper($action) . '_MODULE'],
- 'MODULENAME' => $this->lang_name($module_data['module_langname']),
+ 'MODULENAME' => $user->lang($module_data['module_langname']),
'ACTION' => $action,
'MODULE_ID' => $module_id,
@@ -406,11 +452,11 @@ class acp_modules
{
$navigation = '<a href="' . $this->u_action . '">' . strtoupper($this->module_class) . '</a>';
- $modules_nav = $this->get_module_branch($this->parent_id, 'parents', 'descending');
+ $modules_nav = $module_manager->get_module_branch($this->parent_id, $this->module_class, 'parents');
foreach ($modules_nav as $row)
{
- $langname = $this->lang_name($row['module_langname']);
+ $langname = $user->lang($row['module_langname']);
if ($row['module_id'] == $this->parent_id)
{
@@ -437,7 +483,7 @@ class acp_modules
{
do
{
- $langname = $this->lang_name($row['module_langname']);
+ $langname = $user->lang($row['module_langname']);
if (!$row['module_enabled'])
{
@@ -472,7 +518,15 @@ class acp_modules
}
else if ($this->parent_id)
{
- $row = $this->get_module_row($this->parent_id);
+ try
+ {
+ $row = $module_manager->get_module_row($this->parent_id, $this->module_class);
+ }
+ catch (\phpbb\module\exception\module_not_found_exception $e)
+ {
+ $msg = $user->lang($e->getMessage());
+ trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
+ }
$url = $this->u_action . '&amp;parent_id=' . $this->parent_id . '&amp;m=' . $row['module_id'];
@@ -491,19 +545,19 @@ class acp_modules
$db->sql_freeresult($result);
// Quick adding module
- $module_infos = $this->get_module_infos();
+ $module_infos = $module_manager->get_module_infos($this->module_class);
// Build quick options
$s_install_options = '';
foreach ($module_infos as $option => $values)
{
// Name options
- $s_install_options .= '<optgroup label="' . $this->lang_name($values['title']) . ' [' . $option . ']">';
+ $s_install_options .= '<optgroup label="' . $user->lang($values['title']) . ' [' . $option . ']">';
// Build module modes
foreach ($values['modes'] as $m_mode => $m_values)
{
- $s_install_options .= '<option value="' . $option . '::' . $m_mode . '">&nbsp; &nbsp;' . $this->lang_name($m_values['title']) . '</option>';
+ $s_install_options .= '<option value="' . $option . '::' . $m_mode . '">&nbsp; &nbsp;' . $user->lang($m_values['title']) . '</option>';
}
$s_install_options .= '</optgroup>';
@@ -521,104 +575,6 @@ class acp_modules
}
/**
- * Get row for specified module
- */
- function get_module_row($module_id)
- {
- global $db, $user;
-
- $sql = 'SELECT *
- FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND module_id = $module_id";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if (!$row)
- {
- trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
- }
-
- return $row;
- }
-
- /**
- * Get available module information from module files
- *
- * @param string $module
- * @param bool|string $module_class
- * @param bool $use_all_available Use all available instead of just all
- * enabled extensions
- * @return array
- */
- function get_module_infos($module = '', $module_class = false, $use_all_available = false)
- {
- global $phpbb_extension_manager, $phpbb_root_path, $phpEx;
-
- $module_class = ($module_class === false) ? $this->module_class : $module_class;
-
- $directory = $phpbb_root_path . 'includes/' . $module_class . '/info/';
- $fileinfo = array();
-
- $finder = $phpbb_extension_manager->get_finder($use_all_available);
-
- $modules = $finder
- ->extension_suffix('_module')
- ->extension_directory("/$module_class")
- ->core_path("includes/$module_class/info/")
- ->core_prefix($module_class . '_')
- ->get_classes(true);
-
- foreach ($modules as $cur_module)
- {
- // Skip entries we do not need if we know the module we are
- // looking for
- if ($module && strpos(str_replace('\\', '_', $cur_module), $module) === false && $module !== $cur_module)
- {
- continue;
- }
-
- $info_class = preg_replace('/_module$/', '_info', $cur_module);
-
- // If the class does not exist it might be following the old
- // format. phpbb_acp_info_acp_foo needs to be turned into
- // acp_foo_info and the respective file has to be included
- // manually because it does not support auto loading
- $old_info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module);
- $old_info_class = $old_info_class_file . '_info';
-
- if (class_exists($old_info_class))
- {
- $info_class = $old_info_class;
- }
- else if (!class_exists($info_class))
- {
- $info_class = $old_info_class;
- // need to check class exists again because previous checks triggered autoloading
- if (!class_exists($info_class) && file_exists($directory . $old_info_class_file . '.' . $phpEx))
- {
- include($directory . $old_info_class_file . '.' . $phpEx);
- }
- }
-
- if (class_exists($info_class))
- {
- $info = new $info_class();
- $module_info = $info->module();
-
- $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $cur_module;
-
- $fileinfo[$main_class] = $module_info;
- }
- }
-
- ksort($fileinfo);
-
- return $fileinfo;
- }
-
- /**
* Simple version of jumpbox, just lists modules
*/
function make_module_select($select_id = false, $ignore_id = false, $ignore_acl = false, $ignore_nonpost = false, $ignore_emptycat = true, $ignore_noncat = false)
@@ -678,7 +634,7 @@ class acp_modules
$selected = (is_array($select_id)) ? ((in_array($row['module_id'], $select_id)) ? ' selected="selected"' : '') : (($row['module_id'] == $select_id) ? ' selected="selected"' : '');
- $langname = $this->lang_name($row['module_langname']);
+ $langname = $user->lang($row['module_langname']);
$module_list .= '<option value="' . $row['module_id'] . '"' . $selected . ((!$row['module_enabled']) ? ' class="disabled"' : '') . '>' . $padding . $langname . '</option>';
$iteration++;
@@ -689,401 +645,4 @@ class acp_modules
return $module_list;
}
-
- /**
- * Get module branch
- */
- function get_module_branch($module_id, $type = 'all', $order = 'descending', $include_module = true)
- {
- global $db;
-
- switch ($type)
- {
- case 'parents':
- $condition = 'm1.left_id BETWEEN m2.left_id AND m2.right_id';
- break;
-
- case 'children':
- $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id';
- break;
-
- default:
- $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id OR m1.left_id BETWEEN m2.left_id AND m2.right_id';
- break;
- }
-
- $rows = array();
-
- $sql = 'SELECT m2.*
- FROM ' . MODULES_TABLE . ' m1
- LEFT JOIN ' . MODULES_TABLE . " m2 ON ($condition)
- WHERE m1.module_class = '" . $db->sql_escape($this->module_class) . "'
- AND m2.module_class = '" . $db->sql_escape($this->module_class) . "'
- AND m1.module_id = $module_id
- ORDER BY m2.left_id " . (($order == 'descending') ? 'ASC' : 'DESC');
- $result = $db->sql_query($sql);
-
- while ($row = $db->sql_fetchrow($result))
- {
- if (!$include_module && $row['module_id'] == $module_id)
- {
- continue;
- }
-
- $rows[] = $row;
- }
- $db->sql_freeresult($result);
-
- return $rows;
- }
-
- /**
- * Remove modules cache file
- */
- function remove_cache_file()
- {
- global $phpbb_container;
-
- // Sanitise for future path use, it's escaped as appropriate for queries
- $p_class = str_replace(array('.', '/', '\\'), '', basename($this->module_class));
-
- $phpbb_container->get('cache.driver')->destroy('_modules_' . $p_class);
-
- // Additionally remove sql cache
- $phpbb_container->get('cache.driver')->destroy('sql', MODULES_TABLE);
- }
-
- /**
- * Return correct language name
- */
- function lang_name($module_langname)
- {
- global $user;
-
- return (!empty($user->lang[$module_langname])) ? $user->lang[$module_langname] : $module_langname;
- }
-
- /**
- * Update/Add module
- *
- * @param array &$module_data The module data
- * @param bool $run_inline if set to true errors will be returned and no logs being written
- */
- function update_module_data(&$module_data, $run_inline = false)
- {
- global $db, $user, $phpbb_log;
-
- if (!isset($module_data['module_id']))
- {
- // no module_id means we're creating a new category/module
- if ($module_data['parent_id'])
- {
- $sql = 'SELECT left_id, right_id
- FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
- AND module_id = " . (int) $module_data['parent_id'];
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if (!$row)
- {
- if ($run_inline)
- {
- return 'PARENT_NO_EXIST';
- }
-
- trigger_error($user->lang['PARENT_NO_EXIST'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
- }
-
- // Workaround
- $row['left_id'] = (int) $row['left_id'];
- $row['right_id'] = (int) $row['right_id'];
-
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id + 2, right_id = right_id + 2
- WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
- AND left_id > {$row['right_id']}";
- $db->sql_query($sql);
-
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET right_id = right_id + 2
- WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
- AND {$row['left_id']} BETWEEN left_id AND right_id";
- $db->sql_query($sql);
-
- $module_data['left_id'] = (int) $row['right_id'];
- $module_data['right_id'] = (int) $row['right_id'] + 1;
- }
- else
- {
- $sql = 'SELECT MAX(right_id) AS right_id
- FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- $module_data['left_id'] = (int) $row['right_id'] + 1;
- $module_data['right_id'] = (int) $row['right_id'] + 2;
- }
-
- $sql = 'INSERT INTO ' . MODULES_TABLE . ' ' . $db->sql_build_array('INSERT', $module_data);
- $db->sql_query($sql);
-
- $module_data['module_id'] = $db->sql_nextid();
-
- if (!$run_inline)
- {
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_ADD', false, array($this->lang_name($module_data['module_langname'])));
- }
- }
- else
- {
- $row = $this->get_module_row($module_data['module_id']);
-
- if ($module_data['module_basename'] && !$row['module_basename'])
- {
- // we're turning a category into a module
- $branch = $this->get_module_branch($module_data['module_id'], 'children', 'descending', false);
-
- if (sizeof($branch))
- {
- return array($user->lang['NO_CATEGORY_TO_MODULE']);
- }
- }
-
- if ($row['parent_id'] != $module_data['parent_id'])
- {
- $this->move_module($module_data['module_id'], $module_data['parent_id']);
- }
-
- $update_ary = $module_data;
- unset($update_ary['module_id']);
-
- $sql = 'UPDATE ' . MODULES_TABLE . '
- SET ' . $db->sql_build_array('UPDATE', $update_ary) . "
- WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'
- AND module_id = " . (int) $module_data['module_id'];
- $db->sql_query($sql);
-
- if (!$run_inline)
- {
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_EDIT', false, array($this->lang_name($module_data['module_langname'])));
- }
- }
-
- return array();
- }
-
- /**
- * Move module around the tree
- */
- function move_module($from_module_id, $to_parent_id)
- {
- global $db;
-
- $moved_modules = $this->get_module_branch($from_module_id, 'children', 'descending');
- $from_data = $moved_modules[0];
- $diff = sizeof($moved_modules) * 2;
-
- $moved_ids = array();
- for ($i = 0; $i < sizeof($moved_modules); ++$i)
- {
- $moved_ids[] = $moved_modules[$i]['module_id'];
- }
-
- // Resync parents
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET right_id = right_id - $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id < " . (int) $from_data['right_id'] . '
- AND right_id > ' . (int) $from_data['right_id'];
- $db->sql_query($sql);
-
- // Resync righthand side of tree
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id - $diff, right_id = right_id - $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id > " . (int) $from_data['right_id'];
- $db->sql_query($sql);
-
- if ($to_parent_id > 0)
- {
- $to_data = $this->get_module_row($to_parent_id);
-
- // Resync new parents
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET right_id = right_id + $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND " . (int) $to_data['right_id'] . ' BETWEEN left_id AND right_id
- AND ' . $db->sql_in_set('module_id', $moved_ids, true);
- $db->sql_query($sql);
-
- // Resync the righthand side of the tree
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id + $diff, right_id = right_id + $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id > " . (int) $to_data['right_id'] . '
- AND ' . $db->sql_in_set('module_id', $moved_ids, true);
- $db->sql_query($sql);
-
- // Resync moved branch
- $to_data['right_id'] += $diff;
- if ($to_data['right_id'] > $from_data['right_id'])
- {
- $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1);
- }
- else
- {
- $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1);
- }
- }
- else
- {
- $sql = 'SELECT MAX(right_id) AS right_id
- FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND " . $db->sql_in_set('module_id', $moved_ids, true);
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- $diff = '+ ' . (int) ($row['right_id'] - $from_data['left_id'] + 1);
- }
-
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id $diff, right_id = right_id $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND " . $db->sql_in_set('module_id', $moved_ids);
- $db->sql_query($sql);
- }
-
- /**
- * Remove module from tree
- */
- function delete_module($module_id)
- {
- global $db, $user, $phpbb_log;
-
- $row = $this->get_module_row($module_id);
-
- $branch = $this->get_module_branch($module_id, 'children', 'descending', false);
-
- if (sizeof($branch))
- {
- return array($user->lang['CANNOT_REMOVE_MODULE']);
- }
-
- // If not move
- $diff = 2;
- $sql = 'DELETE FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND module_id = $module_id";
- $db->sql_query($sql);
-
- $row['right_id'] = (int) $row['right_id'];
- $row['left_id'] = (int) $row['left_id'];
-
- // Resync tree
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET right_id = right_id - $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id < {$row['right_id']} AND right_id > {$row['right_id']}";
- $db->sql_query($sql);
-
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id - $diff, right_id = right_id - $diff
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id > {$row['right_id']}";
- $db->sql_query($sql);
-
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_REMOVED', false, array($this->lang_name($row['module_langname'])));
-
- return array();
-
- }
-
- /**
- * Move module position by $steps up/down
- */
- function move_module_by($module_row, $action = 'move_up', $steps = 1)
- {
- global $db;
-
- /**
- * Fetch all the siblings between the module's current spot
- * and where we want to move it to. If there are less than $steps
- * siblings between the current spot and the target then the
- * module will move as far as possible
- */
- $sql = 'SELECT module_id, left_id, right_id, module_langname
- FROM ' . MODULES_TABLE . "
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND parent_id = " . (int) $module_row['parent_id'] . '
- AND ' . (($action == 'move_up') ? 'right_id < ' . (int) $module_row['right_id'] . ' ORDER BY right_id DESC' : 'left_id > ' . (int) $module_row['left_id'] . ' ORDER BY left_id ASC');
- $result = $db->sql_query_limit($sql, $steps);
-
- $target = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $target = $row;
- }
- $db->sql_freeresult($result);
-
- if (!sizeof($target))
- {
- // The module is already on top or bottom
- return false;
- }
-
- /**
- * $left_id and $right_id define the scope of the nodes that are affected by the move.
- * $diff_up and $diff_down are the values to substract or add to each node's left_id
- * and right_id in order to move them up or down.
- * $move_up_left and $move_up_right define the scope of the nodes that are moving
- * up. Other nodes in the scope of ($left_id, $right_id) are considered to move down.
- */
- if ($action == 'move_up')
- {
- $left_id = (int) $target['left_id'];
- $right_id = (int) $module_row['right_id'];
-
- $diff_up = (int) ($module_row['left_id'] - $target['left_id']);
- $diff_down = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
-
- $move_up_left = (int) $module_row['left_id'];
- $move_up_right = (int) $module_row['right_id'];
- }
- else
- {
- $left_id = (int) $module_row['left_id'];
- $right_id = (int) $target['right_id'];
-
- $diff_up = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
- $diff_down = (int) ($target['right_id'] - $module_row['right_id']);
-
- $move_up_left = (int) ($module_row['right_id'] + 1);
- $move_up_right = (int) $target['right_id'];
- }
-
- // Now do the dirty job
- $sql = 'UPDATE ' . MODULES_TABLE . "
- SET left_id = left_id + CASE
- WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
- ELSE {$diff_down}
- END,
- right_id = right_id + CASE
- WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
- ELSE {$diff_down}
- END
- WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
- AND left_id BETWEEN {$left_id} AND {$right_id}
- AND right_id BETWEEN {$left_id} AND {$right_id}";
- $db->sql_query($sql);
-
- $this->remove_cache_file();
-
- return $this->lang_name($target['module_langname']);
- }
}
diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php
index 63a103aa0c..ed40b0d424 100644
--- a/phpBB/includes/acp/acp_prune.php
+++ b/phpBB/includes/acp/acp_prune.php
@@ -507,9 +507,9 @@ class acp_prune
WHERE ug.group_id = ' . (int) $group_id . '
AND ug.user_id <> ' . ANONYMOUS . '
AND u.user_type <> ' . USER_FOUNDER . '
- AND ug.user_pending = 0 ' .
- ((!empty($user_ids)) ? ' AND ' . $db->sql_in_set('ug.user_id', $user_ids) : '') . '
- AND u.user_id = ug.user_id';
+ AND ug.user_pending = 0
+ AND u.user_id = ug.user_id
+ ' . (!empty($user_ids) ? ' AND ' . $db->sql_in_set('ug.user_id', $user_ids) : '');
$result = $db->sql_query($sql);
// we're performing an intersection operation, so all the relevant users
@@ -533,10 +533,10 @@ class acp_prune
$sql = 'SELECT u.user_id, u.username, COUNT(p.post_id) AS queue_posts
FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
WHERE u.user_id <> ' . ANONYMOUS . '
- AND u.user_type <> ' . USER_FOUNDER .
- ((!empty($user_ids)) ? ' AND ' . $db->sql_in_set('p.poster_id', $user_ids) : '') . '
+ AND u.user_type <> ' . USER_FOUNDER . '
AND ' . $db->sql_in_set('p.post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . '
AND u.user_id = p.poster_id
+ ' . (!empty($user_ids) ? ' AND ' . $db->sql_in_set('p.poster_id', $user_ids) : '') . '
GROUP BY p.poster_id
HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue;
$result = $db->sql_query($sql);
diff --git a/phpBB/includes/acp/acp_search.php b/phpBB/includes/acp/acp_search.php
index e0991158fe..25fc1ed8dc 100644
--- a/phpBB/includes/acp/acp_search.php
+++ b/phpBB/includes/acp/acp_search.php
@@ -596,7 +596,7 @@ class acp_search
*/
function init_search($type, &$search, &$error)
{
- global $phpbb_root_path, $phpEx, $user, $auth, $config, $db;
+ global $phpbb_root_path, $phpEx, $user, $auth, $config, $db, $phpbb_dispatcher;
if (!class_exists($type) || !method_exists($type, 'keyword_search'))
{
@@ -605,7 +605,7 @@ class acp_search
}
$error = false;
- $search = new $type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
return $error;
}
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php
index b652fd6587..de3ca5f787 100644
--- a/phpBB/includes/acp/acp_styles.php
+++ b/phpBB/includes/acp/acp_styles.php
@@ -1013,7 +1013,7 @@ class acp_styles
// Assign template variables
$this->template->assign_block_vars('styles_list', $row);
- foreach($actions as $action)
+ foreach ($actions as $action)
{
$this->template->assign_block_vars('styles_list.actions', $action);
}
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index b722c30416..6a1a50952f 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -686,6 +686,10 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
{
$forum_id = array($forum_id);
}
+ else
+ {
+ $forum_id = array_unique($forum_id);
+ }
/* @var $phpbb_notifications \phpbb\notification\manager */
$phpbb_notifications = $phpbb_container->get('notification_manager');
@@ -3983,10 +3987,11 @@ function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config
* @param array $row Row cleaned by \phpbb\avatar\manager::clean_row
* @param string $alt Optional language string for alt tag within image, can be a language key or text
* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+* @param bool $lazy If true, will be lazy loaded (requires JS)
*
* @return string Avatar html
*/
-function phpbb_get_avatar($row, $alt, $ignore_config = false)
+function phpbb_get_avatar($row, $alt, $ignore_config = false, $lazy = false)
{
global $user, $config, $cache, $phpbb_root_path, $phpEx;
global $request;
@@ -4025,7 +4030,28 @@ function phpbb_get_avatar($row, $alt, $ignore_config = false)
if (!empty($avatar_data['src']))
{
- $html = '<img src="' . $avatar_data['src'] . '" ' .
+ if ($lazy)
+ {
+ // Determine board url - we may need it later
+ $board_url = generate_board_url() . '/';
+ // This path is sent with the base template paths in the assign_vars()
+ // call below. We need to correct it in case we are accessing from a
+ // controller because the web paths will be incorrect otherwise.
+ $phpbb_path_helper = $phpbb_container->get('path_helper');
+ $corrected_path = $phpbb_path_helper->get_web_root_path();
+
+ $web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $corrected_path;
+
+ $theme = "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme';
+
+ $src = 'src="' . $theme . '/images/no_avatar.gif" data-src="' . $avatar_data['src'] . '"';
+ }
+ else
+ {
+ $src = 'src="' . $avatar_data['src'] . '"';
+ }
+
+ $html = '<img class="avatar" ' . $src .
($avatar_data['width'] ? ('width="' . $avatar_data['width'] . '" ') : '') .
($avatar_data['height'] ? ('height="' . $avatar_data['height'] . '" ') : '') .
'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />';
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index 6d59b513af..eea18a0c47 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -245,8 +245,13 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars)
switch ($tpl_type[0])
{
- case 'text':
case 'password':
+ if ($new[$config_key] !== '')
+ {
+ // replace passwords with asterixes
+ $new[$config_key] = '********';
+ }
+ case 'text':
case 'url':
case 'email':
case 'color':
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index fce4bf841b..7ca1f621ff 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -500,7 +500,7 @@ function filelist($rootdir, $dir = '', $type = 'gif|jpg|jpeg|png')
*/
function move_topics($topic_ids, $forum_id, $auto_sync = true)
{
- global $db;
+ global $db, $phpbb_dispatcher;
if (empty($topic_ids))
{
@@ -534,6 +534,27 @@ function move_topics($topic_ids, $forum_id, $auto_sync = true)
}
$table_ary = array(TOPICS_TABLE, POSTS_TABLE, LOG_TABLE, DRAFTS_TABLE, TOPICS_TRACK_TABLE);
+
+ /**
+ * Perform additional actions before topics move
+ *
+ * @event core.move_topics_before_query
+ * @var array table_ary Array of tables from which forum_id will be updated for all rows that hold the moved topics
+ * @var array topic_ids Array of the moved topic ids
+ * @var string forum_id The forum id from where the topics are moved
+ * @var array forum_ids Array of the forums where the topics are moving (includes also forum_id)
+ * @var bool auto_sync Whether or not to perform auto sync
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'table_ary',
+ 'topic_ids',
+ 'forum_id',
+ 'forum_ids',
+ 'auto_sync',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.move_topics_before_query', compact($vars)));
+
foreach ($table_ary as $table)
{
$sql = "UPDATE $table
@@ -921,7 +942,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
}
$error = false;
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if ($error)
{
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
index 31019061a9..4b085a6050 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -30,10 +30,11 @@ if (!defined('IN_PHPBB'))
* @param string $avatar_height Height of users avatar
* @param string $alt Optional language string for alt tag within image, can be a language key or text
* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+* @param bool $lazy If true, will be lazy loaded (requires JS)
*
* @return string Avatar image
*/
-function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $alt = 'USER_AVATAR', $ignore_config = false)
+function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $alt = 'USER_AVATAR', $ignore_config = false, $lazy = false)
{
// map arguments to new function phpbb_get_avatar()
$row = array(
@@ -43,7 +44,7 @@ function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $
'avatar_height' => $avatar_height,
);
- return phpbb_get_avatar($row, $alt, $ignore_config);
+ return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
}
/**
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index ad693f4019..0a25ae8c36 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -966,7 +966,7 @@ function get_remote_avatar_dim($src, $axis)
$protocol = (isset($url_info['scheme'])) ? $url_info['scheme'] : 'http';
if (empty($port))
{
- switch(strtolower($protocol))
+ switch (strtolower($protocol))
{
case 'ftp':
$port = 21;
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index f89068327c..3a96119dbe 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -150,7 +150,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql);
- $forum_tracking_info = array();
+ $forum_tracking_info = $valid_categories = array();
$branch_root_id = $root_data['forum_id'];
/* @var $phpbb_content_visibility \phpbb\content_visibility */
@@ -251,6 +251,12 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
}
}
+ // Fill list of categories with forums
+ if (isset($forum_rows[$row['parent_id']]))
+ {
+ $valid_categories[$row['parent_id']] = true;
+ }
+
//
if ($row['parent_id'] == $root_data['forum_id'] || $row['parent_id'] == $branch_root_id)
{
@@ -268,6 +274,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$branch_root_id = $forum_id;
}
$forum_rows[$parent_id]['forum_id_last_post'] = $row['forum_id'];
+ $forum_rows[$parent_id]['forum_password_last_post'] = $row['forum_password'];
$forum_rows[$parent_id]['orig_forum_last_post_time'] = $row['forum_last_post_time'];
}
else if ($row['forum_type'] != FORUM_CAT)
@@ -309,6 +316,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$forum_rows[$parent_id]['forum_last_poster_name'] = $row['forum_last_poster_name'];
$forum_rows[$parent_id]['forum_last_poster_colour'] = $row['forum_last_poster_colour'];
$forum_rows[$parent_id]['forum_id_last_post'] = $forum_id;
+ $forum_rows[$parent_id]['forum_password_last_post'] = $row['forum_password'];
}
}
@@ -405,6 +413,12 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
// Category
if ($row['parent_id'] == $root_data['forum_id'] && $row['forum_type'] == FORUM_CAT)
{
+ // Do not display categories without any forums to display
+ if (!isset($valid_categories[$row['forum_id']]))
+ {
+ continue;
+ }
+
$cat_row = array(
'S_IS_CAT' => true,
'FORUM_ID' => $row['forum_id'],
@@ -523,8 +537,15 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
// Create last post link information, if appropriate
if ($row['forum_last_post_id'])
{
- $last_post_subject = $row['forum_last_post_subject'];
- $last_post_subject_truncated = truncate_string(censor_text($last_post_subject), 30, 255, false, $user->lang['ELLIPSIS']);
+ if ($row['forum_password_last_post'] === '' && $auth->acl_get('f_read', $row['forum_id_last_post']))
+ {
+ $last_post_subject = censor_text($row['forum_last_post_subject']);
+ $last_post_subject_truncated = truncate_string($last_post_subject, 30, 255, false, $user->lang['ELLIPSIS']);
+ }
+ else
+ {
+ $last_post_subject = $last_post_subject_truncated = '';
+ }
$last_post_time = $user->format_date($row['forum_last_post_time']);
$last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id_last_post'] . '&amp;p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id'];
}
@@ -584,7 +605,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'S_LOCKED_FORUM' => ($row['forum_status'] == ITEM_LOCKED) ? true : false,
'S_LIST_SUBFORUMS' => ($row['display_subforum_list']) ? true : false,
'S_SUBFORUMS' => (sizeof($subforums_list)) ? true : false,
- 'S_DISPLAY_SUBJECT' => ($last_post_subject && $config['display_last_subject'] && !$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? true : false,
+ 'S_DISPLAY_SUBJECT' => ($last_post_subject !== '' && $config['display_last_subject']) ? true : false,
'S_FEED_ENABLED' => ($config['feed_forum'] && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $row['forum_options']) && $row['forum_type'] == FORUM_POST) ? true : false,
'FORUM_ID' => $row['forum_id'],
@@ -597,8 +618,8 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'FORUM_FOLDER_IMG_ALT' => isset($user->lang[$folder_alt]) ? $user->lang[$folder_alt] : '',
'FORUM_IMAGE' => ($row['forum_image']) ? '<img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="' . $user->lang[$folder_alt] . '" />' : '',
'FORUM_IMAGE_SRC' => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '',
- 'LAST_POST_SUBJECT' => (!$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? censor_text($last_post_subject) : "",
- 'LAST_POST_SUBJECT_TRUNCATED' => (!$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? $last_post_subject_truncated : "",
+ 'LAST_POST_SUBJECT' => $last_post_subject,
+ 'LAST_POST_SUBJECT_TRUNCATED' => $last_post_subject_truncated,
'LAST_POST_TIME' => $last_post_time,
'LAST_POSTER' => get_username_string('username', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
'LAST_POSTER_COLOUR' => get_username_string('colour', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php
index 01d3f000c4..144e6b4e7c 100644
--- a/phpBB/includes/functions_module.php
+++ b/phpBB/includes/functions_module.php
@@ -978,7 +978,7 @@ class p_master
*
* @param string $class module class (acp/mcp/ucp)
* @param string $name module name (class name of the module, or its basename
- * phpbb_ext_foo_acp_bar_module, ucp_zebra or zebra)
+ * phpbb_ext_foo_acp_bar_module, ucp_zebra or zebra)
* @param string $mode mode, as passed through to the module
*
*/
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index fcab667cb2..5ba8c3ca1a 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -2226,7 +2226,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
}
$error = false;
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if ($error)
{
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index c8b5280c8c..245b1c0d1a 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -2127,17 +2127,42 @@ function set_user_message_limit()
{
global $user, $db, $config;
- // Get maximum about from user memberships - if it is 0, there is no limit set and we use the maximum value within the config.
- $sql = 'SELECT MAX(g.group_message_limit) as max_message_limit
+ // Get maximum about from user memberships
+ $message_limit = phpbb_get_max_setting_from_group($db, $user->data['user_id'], 'message_limit');
+
+ // If it is 0, there is no limit set and we use the maximum value within the config.
+ $user->data['message_limit'] = (!$message_limit) ? $config['pm_max_msgs'] : $message_limit;
+}
+
+/**
+ * Get the maximum PM setting for the groups of the user
+ *
+ * @param \phpbb\db\driver\driver_interface $db
+ * @param int $user_id
+ * @param string $setting Only 'max_recipients' and 'message_limit' are supported
+ * @return int The maximum setting for all groups of the user, unless one group has '0'
+ * @throws \InvalidArgumentException If selected group setting is not supported
+ */
+function phpbb_get_max_setting_from_group(\phpbb\db\driver\driver_interface $db, $user_id, $setting)
+{
+ if ($setting !== 'max_recipients' && $setting !== 'message_limit')
+ {
+ throw new InvalidArgumentException('Setting "' . $setting . '" is not supported');
+ }
+
+ // Get maximum number of allowed recipients
+ $sql = 'SELECT MIN(g.group_' . $setting . ') as min_setting, MAX(g.group_' . $setting . ') as max_setting
FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug
- WHERE ug.user_id = ' . $user->data['user_id'] . '
+ WHERE ug.user_id = ' . (int) $user_id . '
AND ug.user_pending = 0
AND ug.group_id = g.group_id';
$result = $db->sql_query($sql);
- $message_limit = (int) $db->sql_fetchfield('max_message_limit');
+ $row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
+ $max_setting = (int) $row['max_setting'];
+ $min_setting = (int) $row['min_setting'];
- $user->data['message_limit'] = (!$message_limit) ? $config['pm_max_msgs'] : $message_limit;
+ return ($min_setting > 0) ? $max_setting : 0;
}
/**
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 85b6f2be62..b0f58ba680 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -502,6 +502,9 @@ function user_delete($mode, $user_ids, $retain_username = true)
$num_users_delta = 0;
+ // Get auth provider collection in case accounts might need to be unlinked
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+
// Some things need to be done in the loop (if the query changes based
// on which user is currently being deleted)
$added_guest_posts = 0;
@@ -512,6 +515,38 @@ function user_delete($mode, $user_ids, $retain_username = true)
avatar_delete('user', $user_row);
}
+ // Unlink accounts
+ foreach ($provider_collection as $provider_name => $auth_provider)
+ {
+ $provider_data = $auth_provider->get_auth_link_data($user_id);
+
+ if ($provider_data !== null)
+ {
+ $link_data = array(
+ 'user_id' => $user_id,
+ 'link_method' => 'user_delete',
+ );
+
+ // BLOCK_VARS might contain hidden fields necessary for unlinking accounts
+ if (isset($provider_data['BLOCK_VARS']) && is_array($provider_data['BLOCK_VARS']))
+ {
+ foreach ($provider_data['BLOCK_VARS'] as $provider_service)
+ {
+ if (!array_key_exists('HIDDEN_FIELDS', $provider_service))
+ {
+ $provider_service['HIDDEN_FIELDS'] = array();
+ }
+
+ $auth_provider->unlink_account(array_merge($link_data, $provider_service['HIDDEN_FIELDS']));
+ }
+ }
+ else
+ {
+ $auth_provider->unlink_account($link_data);
+ }
+ }
+ }
+
// Decrement number of users if this user is active
if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE)
{
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index e8ab0167f5..2659a4bf01 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -1188,7 +1188,7 @@ function mcp_delete_post($post_ids, $is_soft = false, $soft_delete_reason = '',
function mcp_fork_topic($topic_ids)
{
global $auth, $user, $db, $template, $config;
- global $phpEx, $phpbb_root_path, $phpbb_log, $request;
+ global $phpEx, $phpbb_root_path, $phpbb_log, $request, $phpbb_dispatcher;
if (!phpbb_check_ids($topic_ids, TOPICS_TABLE, 'topic_id', array('m_')))
{
@@ -1266,7 +1266,7 @@ function mcp_fork_topic($topic_ids)
}
$error = false;
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
$search_mode = 'post';
if ($error)
diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php
index b70dfbb514..f7983c57bf 100644
--- a/phpBB/includes/mcp/mcp_post.php
+++ b/phpBB/includes/mcp/mcp_post.php
@@ -26,6 +26,7 @@ function mcp_post_details($id, $mode, $action)
{
global $phpEx, $phpbb_root_path, $config, $request;
global $template, $db, $user, $auth, $cache;
+ global $phpbb_dispatcher;
$user->add_lang('posting');
@@ -106,6 +107,21 @@ function mcp_post_details($id, $mode, $action)
}
break;
+
+ default:
+
+ /**
+ * This event allows you to handle custom post moderation options
+ *
+ * @event core.mcp_post_additional_options
+ * @var string action Post moderation action name
+ * @var array post_info Information on the affected post
+ * @since 3.1.5-RC1
+ */
+ $vars = array('action', 'post_info');
+ extract($phpbb_dispatcher->trigger_event('core.mcp_post_additional_options', compact($vars)));
+
+ break;
}
// Set some vars
@@ -197,7 +213,7 @@ function mcp_post_details($id, $mode, $action)
$l_deleted_by = '';
}
- $template->assign_vars(array(
+ $mcp_post_template_data = array(
'U_MCP_ACTION' => "$url&amp;i=main&amp;quickmod=1&amp;mode=post_details", // Use this for mode paramaters
'U_POST_ACTION' => "$url&amp;i=$id&amp;mode=post_details", // Use this for action parameters
'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;p=$post_id&amp;f={$post_info['forum_id']}"),
@@ -249,7 +265,32 @@ function mcp_post_details($id, $mode, $action)
'U_LOOKUP_IP' => ($auth->acl_get('m_info', $post_info['forum_id'])) ? "$url&amp;i=$id&amp;mode=$mode&amp;lookup={$post_info['poster_ip']}#ip" : '',
'U_WHOIS' => ($auth->acl_get('m_info', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&amp;mode=$mode&amp;action=whois&amp;p=$post_id&amp;ip={$post_info['poster_ip']}") : '',
- ));
+ );
+
+ $s_additional_opts = false;
+
+ /**
+ * Event to add/modify MCP post template data
+ *
+ * @event core.mcp_post_template_data
+ * @var array post_info Array with the post information
+ * @var array mcp_post_template_data Array with the MCP post template data
+ * @var array attachments Array with the post attachments, if any
+ * @var bool s_additional_opts Must be set to true in extension if additional options are presented in MCP post panel
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'post_info',
+ 'mcp_post_template_data',
+ 'attachments',
+ 's_additional_opts',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_post_template_data', compact($vars)));
+
+ $template->assign_vars($mcp_post_template_data);
+ $template->assign_var('S_MCP_POST_ADDITIONAL_OPTS', $s_additional_opts);
+
+ unset($mcp_post_template_data);
// Get User Notes
$log_data = array();
@@ -497,7 +538,7 @@ function change_poster(&$post_info, $userdata)
{
// We do some additional checks in the module to ensure it can actually be utilised
$error = false;
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if (!$error && method_exists($search, 'destroy_cache'))
{
diff --git a/phpBB/includes/startup.php b/phpBB/includes/startup.php
index c90fd79366..5900016c39 100644
--- a/phpBB/includes/startup.php
+++ b/phpBB/includes/startup.php
@@ -90,7 +90,11 @@ if (version_compare(PHP_VERSION, '5.4.0-dev', '>='))
}
else
{
- @set_magic_quotes_runtime(0);
+ if (get_magic_quotes_runtime())
+ {
+ // Deactivate
+ @set_magic_quotes_runtime(0);
+ }
// Be paranoid with passed vars
if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on' || !function_exists('ini_get'))
diff --git a/phpBB/includes/ucp/ucp_notifications.php b/phpBB/includes/ucp/ucp_notifications.php
index b778ffdf12..6d0d4f06a6 100644
--- a/phpBB/includes/ucp/ucp_notifications.php
+++ b/phpBB/includes/ucp/ucp_notifications.php
@@ -55,11 +55,11 @@ class ucp_notifications
$notification_methods = $phpbb_notifications->get_subscription_methods();
- foreach($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
+ foreach ($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
{
- foreach($subscription_types as $type => $data)
+ foreach ($subscription_types as $type => $data)
{
- foreach($notification_methods as $method => $method_data)
+ foreach ($notification_methods as $method => $method_data)
{
if ($request->is_set_post(str_replace('.', '_', $type . '_' . $method_data['id'])) && (!isset($subscriptions[$type]) || !in_array($method_data['id'], $subscriptions[$type])))
{
@@ -183,13 +183,13 @@ class ucp_notifications
{
$notification_methods = $phpbb_notifications->get_subscription_methods();
- foreach($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
+ foreach ($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
{
$template->assign_block_vars($block, array(
'GROUP_NAME' => $user->lang($group),
));
- foreach($subscription_types as $type => $data)
+ foreach ($subscription_types as $type => $data)
{
$template->assign_block_vars($block, array(
'TYPE' => $type,
@@ -200,7 +200,7 @@ class ucp_notifications
'SUBSCRIBED' => (isset($subscriptions[$type])) ? true : false,
));
- foreach($notification_methods as $method => $method_data)
+ foreach ($notification_methods as $method => $method_data)
{
$template->assign_block_vars($block . '.notification_methods', array(
'METHOD' => $method_data['id'],
@@ -230,7 +230,7 @@ class ucp_notifications
{
$notification_methods = $phpbb_notifications->get_subscription_methods();
- foreach($notification_methods as $method => $method_data)
+ foreach ($notification_methods as $method => $method_data)
{
$template->assign_block_vars($block, array(
'METHOD' => $method_data['id'],
diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php
index 9859fd938c..61dab982df 100644
--- a/phpBB/includes/ucp/ucp_pm_compose.php
+++ b/phpBB/includes/ucp/ucp_pm_compose.php
@@ -55,7 +55,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
$address_list = $request->variable('address_list', array('' => array(0 => '')));
- $submit = (isset($_POST['post'])) ? true : false;
$preview = (isset($_POST['preview'])) ? true : false;
$save = (isset($_POST['save'])) ? true : false;
$load = (isset($_POST['load'])) ? true : false;
@@ -69,6 +68,7 @@ function compose_pm($id, $mode, $action, $user_folders = array())
$refresh = isset($_POST['add_file']) || isset($_POST['delete_file']) || $save || $load
|| $remove_u || $remove_g || $add_to || $add_bcc;
+ $submit = $request->is_set_post('post') && !$refresh && !$preview;
$action = ($delete && !$preview && !$refresh && $submit) ? 'delete' : $action;
$select_single = ($config['allow_mass_pm'] && $auth->acl_get('u_masspm')) ? false : true;
@@ -530,15 +530,9 @@ function compose_pm($id, $mode, $action, $user_folders = array())
}
// Get maximum number of allowed recipients
- $sql = 'SELECT MAX(g.group_max_recipients) as max_recipients
- FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . ' ug
- WHERE ug.user_id = ' . $user->data['user_id'] . '
- AND ug.user_pending = 0
- AND ug.group_id = g.group_id';
- $result = $db->sql_query($sql);
- $max_recipients = (int) $db->sql_fetchfield('max_recipients');
- $db->sql_freeresult($result);
+ $max_recipients = phpbb_get_max_setting_from_group($db, $user->data['user_id'], 'max_recipients');
+ // If it is 0, there is no limit set and we use the maximum value within the config.
$max_recipients = (!$max_recipients) ? $config['pm_max_recipients'] : $max_recipients;
// If this is a quote/reply "to all"... we may increase the max_recpients to the number of original recipients
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php
index 553d873b25..a19bb2504b 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.4',
+ 'phpbb_version' => '3.1.5',
'author' => '<a href="https://www.phpbb.com/">phpBB Limited</a>',
'dbms' => $dbms,
'dbhost' => $dbhost,
diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php
index dd9835113b..d72ee1a633 100644
--- a/phpBB/install/install_convert.php
+++ b/phpBB/install/install_convert.php
@@ -625,7 +625,7 @@ class install_convert extends module
{
global $template, $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache, $auth;
global $convert, $convert_row, $message_parser, $skip_rows, $language;
- global $request, $phpbb_config_php_file;
+ global $request, $phpbb_config_php_file, $phpbb_dispatcher;
extract($phpbb_config_php_file->get_all());
@@ -800,7 +800,7 @@ class install_convert extends module
}
$error = false;
- $convert->fulltext_search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $convert->fulltext_search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if ($error)
{
diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php
index e8890a3d08..0e223866b1 100644
--- a/phpBB/install/install_install.php
+++ b/phpBB/install/install_install.php
@@ -1494,7 +1494,7 @@ class install_install extends module
*/
function build_search_index($mode, $sub)
{
- global $db, $lang, $phpbb_root_path, $phpEx, $config, $auth, $user;
+ global $db, $lang, $phpbb_root_path, $phpbb_dispatcher, $phpEx, $config, $auth, $user;
// Obtain any submitted data
$data = $this->get_submitted_data();
@@ -1525,7 +1525,7 @@ class install_install extends module
$config = new \phpbb\config\db($db, new \phpbb\cache\driver\dummy, CONFIG_TABLE);
$error = false;
- $search = new \phpbb\search\fulltext_native($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new \phpbb\search\fulltext_native($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
$sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id
FROM ' . POSTS_TABLE;
@@ -1552,9 +1552,14 @@ class install_install extends module
$phpbb_extension_manager = $phpbb_container->get('ext.manager');
}
- include_once($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx);
-
- $_module = new acp_modules();
+ $_module = new \phpbb\module\module_manager(
+ new \phpbb\cache\driver\dummy(),
+ $db,
+ $phpbb_extension_manager,
+ MODULES_TABLE,
+ $phpbb_root_path,
+ $phpEx
+ );
$module_classes = array('acp', 'mcp', 'ucp');
// Add categories
@@ -1585,7 +1590,7 @@ class install_install extends module
);
// Add category
- $_module->update_module_data($module_data, true);
+ $_module->update_module_data($module_data);
// Check for last sql error happened
if ($db->get_sql_error_triggered())
@@ -1619,7 +1624,7 @@ class install_install extends module
'module_auth' => '',
);
- $_module->update_module_data($module_data, true);
+ $_module->update_module_data($module_data);
// Check for last sql error happened
if ($db->get_sql_error_triggered())
@@ -1635,7 +1640,7 @@ class install_install extends module
}
// Get the modules we want to add... returned sorted by name
- $module_info = $_module->get_module_infos('', $module_class);
+ $module_info = $_module->get_module_infos($module_class);
foreach ($module_info as $module_basename => $fileinfo)
{
@@ -1659,7 +1664,7 @@ class install_install extends module
'module_auth' => $row['auth'],
);
- $_module->update_module_data($module_data, true);
+ $_module->update_module_data($module_data);
// Check for last sql error happened
if ($db->get_sql_error_triggered())
@@ -1684,7 +1689,7 @@ class install_install extends module
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- $_module->move_module_by($row, 'move_up', 4);
+ $_module->move_module_by($row, 'acp', 'move_up', 4);
// Move permissions intro screen module 4 up...
$sql = 'SELECT *
@@ -1696,7 +1701,7 @@ class install_install extends module
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- $_module->move_module_by($row, 'move_up', 4);
+ $_module->move_module_by($row, 'acp', 'move_up', 4);
// Move manage users screen module 5 up...
$sql = 'SELECT *
@@ -1708,7 +1713,7 @@ class install_install extends module
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- $_module->move_module_by($row, 'move_up', 5);
+ $_module->move_module_by($row, 'acp', 'move_up', 5);
// Move extension management module 1 up...
$sql = 'SELECT *
@@ -1721,7 +1726,7 @@ class install_install extends module
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- $_module->move_module_by($row, 'move_up', 1);
+ $_module->move_module_by($row, 'acp', 'move_up', 1);
}
if ($module_class == 'mcp')
@@ -1736,7 +1741,7 @@ class install_install extends module
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- $_module->move_module_by($row, 'move_down', 3);
+ $_module->move_module_by($row, 'mcp', 'move_down', 3);
// Move closed pm reports module 3 down...
$sql = 'SELECT *
@@ -1748,7 +1753,7 @@ class install_install extends module
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- $_module->move_module_by($row, 'move_down', 3);
+ $_module->move_module_by($row, 'mcp', 'move_down', 3);
// Move open pm reports module 3 down...
$sql = 'SELECT *
@@ -1760,7 +1765,7 @@ class install_install extends module
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- $_module->move_module_by($row, 'move_down', 3);
+ $_module->move_module_by($row, 'mcp', 'move_down', 3);
}
if ($module_class == 'ucp')
@@ -1775,7 +1780,7 @@ class install_install extends module
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- $_module->move_module_by($row, 'move_down', 4);
+ $_module->move_module_by($row, 'ucp', 'move_down', 4);
// Move notification options module 4 down...
$sql = 'SELECT *
@@ -1787,7 +1792,7 @@ class install_install extends module
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- $_module->move_module_by($row, 'move_down', 4);
+ $_module->move_module_by($row, 'ucp', 'move_down', 4);
// Move OAuth module 5 down...
$sql = 'SELECT *
@@ -1799,7 +1804,7 @@ class install_install extends module
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
- $_module->move_module_by($row, 'move_down', 5);
+ $_module->move_module_by($row, 'ucp', 'move_down', 5);
}
// And now for the special ones
@@ -1838,7 +1843,7 @@ class install_install extends module
'module_auth' => $row['module_auth'],
);
- $_module->update_module_data($module_data, true);
+ $_module->update_module_data($module_data);
// Check for last sql error happened
if ($db->get_sql_error_triggered())
@@ -1850,7 +1855,7 @@ class install_install extends module
}
}
- $_module->remove_cache_file();
+ $_module->remove_cache_file($module_class);
}
}
diff --git a/phpBB/language/en/acp/groups.php b/phpBB/language/en/acp/groups.php
index a7700ed681..421075ce5e 100644
--- a/phpBB/language/en/acp/groups.php
+++ b/phpBB/language/en/acp/groups.php
@@ -83,7 +83,7 @@ $lang = array_merge($lang, array(
'GROUP_MEMBERS' => 'Group members',
'GROUP_MEMBERS_EXPLAIN' => 'This is a complete listing of all the members of this usergroup. It includes separate sections for leaders, pending and existing members. From here you can manage all aspects of who has membership of this group and what their role is. To remove a leader but keep them in the group use Demote rather than delete. Similarly use Promote to make an existing member a leader.',
'GROUP_MESSAGE_LIMIT' => 'Group private message limit per folder',
- 'GROUP_MESSAGE_LIMIT_EXPLAIN' => 'This setting overrides the per-user folder message limit. A value of 0 means the user default limit will be used.',
+ 'GROUP_MESSAGE_LIMIT_EXPLAIN' => 'This setting overrides the per-user folder message limit. The maximum for all groups of the user is used to determine the actual value.<br />Set this value to 0 to overwrite the setting for all users of this group with the board-wide setting.',
'GROUP_MODS_ADDED' => 'New group leaders added successfully.',
'GROUP_MODS_DEMOTED' => 'Group leaders demoted successfully.',
'GROUP_MODS_PROMOTED' => 'Group members promoted successfully.',
@@ -92,7 +92,7 @@ $lang = array_merge($lang, array(
'GROUP_OPEN' => 'Open',
'GROUP_PENDING' => 'Pending members',
'GROUP_MAX_RECIPIENTS' => 'Maximum number of allowed recipients per private message',
- 'GROUP_MAX_RECIPIENTS_EXPLAIN' => 'The maximum number of allowed recipients in a private message. If 0 is entered, the board-wide setting is used.',
+ 'GROUP_MAX_RECIPIENTS_EXPLAIN' => 'The maximum number of allowed recipients in a private message. The maximum for all groups of the user is used to determine the actual value.<br />Set this value to 0 to overwrite the setting for all users of this group with the board-wide setting.',
'GROUP_OPTIONS_SAVE' => 'Group wide options',
'GROUP_PROMOTE' => 'Promote to group leader',
'GROUP_RANK' => 'Group rank',
diff --git a/phpBB/phpbb/auth/provider/base.php b/phpBB/phpbb/auth/provider/base.php
index 4c49070eaf..dea27ccc25 100644
--- a/phpBB/phpbb/auth/provider/base.php
+++ b/phpBB/phpbb/auth/provider/base.php
@@ -61,7 +61,7 @@ abstract class base implements \phpbb\auth\provider\provider_interface
/**
* {@inheritdoc}
*/
- public function get_auth_link_data()
+ public function get_auth_link_data($user_id = 0)
{
return;
}
diff --git a/phpBB/phpbb/auth/provider/ldap.php b/phpBB/phpbb/auth/provider/ldap.php
index c71950c698..c48b771ab0 100644
--- a/phpBB/phpbb/auth/provider/ldap.php
+++ b/phpBB/phpbb/auth/provider/ldap.php
@@ -289,7 +289,6 @@ class ldap extends \phpbb\auth\provider\base
/**
* {@inheritdoc}
*/
-
public function acp()
{
// These are fields required in the config table
@@ -308,7 +307,7 @@ class ldap extends \phpbb\auth\provider\base
'TEMPLATE_VARS' => array(
'AUTH_LDAP_BASE_DN' => $new_config['ldap_base_dn'],
'AUTH_LDAP_EMAIL' => $new_config['ldap_email'],
- 'AUTH_LDAP_PASSORD' => $new_config['ldap_password'],
+ 'AUTH_LDAP_PASSORD' => $new_config['ldap_password'] !== '' ? '********' : '',
'AUTH_LDAP_PORT' => $new_config['ldap_port'],
'AUTH_LDAP_SERVER' => $new_config['ldap_server'],
'AUTH_LDAP_UID' => $new_config['ldap_uid'],
diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php
index c0ce3f1fba..be0fbf5831 100644
--- a/phpBB/phpbb/auth/provider/oauth/oauth.php
+++ b/phpBB/phpbb/auth/provider/oauth/oauth.php
@@ -553,13 +553,13 @@ class oauth extends \phpbb\auth\provider\base
/**
* {@inheritdoc}
*/
- public function get_auth_link_data()
+ public function get_auth_link_data($user_id = 0)
{
$block_vars = array();
// Get all external accounts tied to the current user
$data = array(
- 'user_id' => (int) $this->user->data['user_id'],
+ 'user_id' => ($user_id <= 0) ? (int) $this->user->data['user_id'] : (int) $user_id,
);
$sql = 'SELECT oauth_provider_id, provider FROM ' . $this->auth_provider_oauth_token_account_assoc . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
@@ -616,10 +616,13 @@ class oauth extends \phpbb\auth\provider\base
return 'LOGIN_LINK_MISSING_DATA';
}
+ // Remove user specified in $link_data if possible
+ $user_id = isset($link_data['user_id']) ? $link_data['user_id'] : $this->user->data['user_id'];
+
// Remove the link
$sql = 'DELETE FROM ' . $this->auth_provider_oauth_token_account_assoc . "
WHERE provider = '" . $this->db->sql_escape($link_data['oauth_service']) . "'
- AND user_id = " . (int) $this->user->data['user_id'];
+ AND user_id = " . (int) $user_id;
$this->db->sql_query($sql);
// Clear all tokens belonging to the user on this servce
diff --git a/phpBB/phpbb/auth/provider/oauth/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php
index f488c2022d..9b6afae255 100644
--- a/phpBB/phpbb/auth/provider/oauth/token_storage.php
+++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php
@@ -13,7 +13,6 @@
namespace phpbb\auth\provider\oauth;
-
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Storage\TokenStorageInterface;
diff --git a/phpBB/phpbb/auth/provider/provider_interface.php b/phpBB/phpbb/auth/provider/provider_interface.php
index 613297cefc..35e0f559a1 100644
--- a/phpBB/phpbb/auth/provider/provider_interface.php
+++ b/phpBB/phpbb/auth/provider/provider_interface.php
@@ -166,6 +166,10 @@ interface provider_interface
/**
* Returns an array of data necessary to build the ucp_auth_link page
*
+ * @param int $user_id User ID for whom the data should be retrieved.
+ * defaults to 0, which is not a valid ID. The method
+ * should fall back to the current user's ID in this
+ * case.
* @return array|null If this function is not implemented on an auth
* provider then it returns null. If it is implemented
* it will return an array of up to four elements of
@@ -181,7 +185,7 @@ interface provider_interface
* 'VARS' => array(...),
* )
*/
- public function get_auth_link_data();
+ public function get_auth_link_data($user_id = 0);
/**
* Unlinks an external account from a phpBB account.
diff --git a/phpBB/phpbb/cache/driver/memcache.php b/phpBB/phpbb/cache/driver/memcache.php
index 406ab11ddd..caa82fb0b1 100644
--- a/phpBB/phpbb/cache/driver/memcache.php
+++ b/phpBB/phpbb/cache/driver/memcache.php
@@ -50,7 +50,7 @@ class memcache extends \phpbb\cache\driver\memory
parent::__construct();
$this->memcache = new \Memcache;
- foreach(explode(',', PHPBB_ACM_MEMCACHE) as $u)
+ foreach (explode(',', PHPBB_ACM_MEMCACHE) as $u)
{
$parts = explode('/', $u);
$this->memcache->addServer(trim($parts[0]), trim($parts[1]));
diff --git a/phpBB/phpbb/db/extractor/mssql_extractor.php b/phpBB/phpbb/db/extractor/mssql_extractor.php
index d0aa78f1f5..fc30f4789d 100644
--- a/phpBB/phpbb/db/extractor/mssql_extractor.php
+++ b/phpBB/phpbb/db/extractor/mssql_extractor.php
@@ -184,7 +184,7 @@ class mssql_extractor extends base_extractor
{
$this->write_data_mssql($table_name);
}
- else if($this->db->get_sql_layer() === 'mssqlnative')
+ else if ($this->db->get_sql_layer() === 'mssqlnative')
{
$this->write_data_mssqlnative($table_name);
}
diff --git a/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php b/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php
index 0ca4f2f19c..725c57ca86 100644
--- a/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php
+++ b/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php
@@ -13,7 +13,7 @@
namespace phpbb\db\migration\data\v310;
-class acp_prune_users_module extends \phpbb\db\migration\migration
+class acp_prune_users_module extends \phpbb\db\migration\container_aware_migration
{
public function effectively_installed()
{
@@ -70,12 +70,7 @@ class acp_prune_users_module extends \phpbb\db\migration\migration
$acp_cat_users_id = (int) $this->db->sql_fetchfield('module_id');
$this->db->sql_freeresult($result);
- if (!class_exists('\acp_modules'))
- {
- include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext);
- }
- $module_manager = new \acp_modules();
- $module_manager->module_class = 'acp';
- $module_manager->move_module($acp_prune_users_id, $acp_cat_users_id);
+ $module_manager = $this->container->get('module.manager');
+ $module_manager->move_module($acp_prune_users_id, $acp_cat_users_id, 'acp');
}
}
diff --git a/phpBB/phpbb/db/migration/data/v310/dev.php b/phpBB/phpbb/db/migration/data/v310/dev.php
index f037191c2a..250258eea7 100644
--- a/phpBB/phpbb/db/migration/data/v310/dev.php
+++ b/phpBB/phpbb/db/migration/data/v310/dev.php
@@ -13,7 +13,7 @@
namespace phpbb\db\migration\data\v310;
-class dev extends \phpbb\db\migration\migration
+class dev extends \phpbb\db\migration\container_aware_migration
{
public function effectively_installed()
{
@@ -204,18 +204,13 @@ class dev extends \phpbb\db\migration\migration
$language_management_module_id = $this->db->sql_fetchfield('module_id');
$this->db->sql_freeresult($result);
- if (!class_exists('acp_modules'))
- {
- include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext);
- }
// acp_modules calls adm_back_link, which is undefined at this point
if (!function_exists('adm_back_link'))
{
include($this->phpbb_root_path . 'includes/functions_acp.' . $this->php_ext);
}
- $module_manager = new \acp_modules();
- $module_manager->module_class = 'acp';
- $module_manager->move_module($language_module_id, $language_management_module_id);
+ $module_manager = $this->container->get('module.manager');
+ $module_manager->move_module($language_module_id, $language_management_module_id, 'acp');
}
public function update_ucp_pm_basename()
diff --git a/phpBB/phpbb/db/migration/data/v31x/v315.php b/phpBB/phpbb/db/migration/data/v31x/v315.php
new file mode 100644
index 0000000000..778cdf717e
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v31x/v315.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 v315 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v31x\v315rc1',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.5')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v31x/v315rc1.php b/phpBB/phpbb/db/migration/data/v31x/v315rc1.php
new file mode 100644
index 0000000000..4cf4472aa7
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v31x/v315rc1.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 v315rc1 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v31x\v314',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.5-RC1')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php
index b6f0372181..69ac71abb7 100644
--- a/phpBB/phpbb/db/migration/tool/module.php
+++ b/phpBB/phpbb/db/migration/tool/module.php
@@ -13,6 +13,8 @@
namespace phpbb\db\migration\tool;
+use phpbb\module\exception\module_exception;
+
/**
* Migration module management tool
*/
@@ -27,6 +29,9 @@ class module implements \phpbb\db\migration\tool\tool_interface
/** @var \phpbb\user */
protected $user;
+ /** @var \phpbb\module\module_manager */
+ protected $module_manager;
+
/** @var string */
protected $phpbb_root_path;
@@ -42,15 +47,17 @@ class module implements \phpbb\db\migration\tool\tool_interface
* @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\cache\service $cache
* @param \phpbb\user $user
+ * @param \phpbb\module\module_manager $module_manager
* @param string $phpbb_root_path
* @param string $php_ext
* @param string $modules_table
*/
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\user $user, $phpbb_root_path, $php_ext, $modules_table)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\user $user, \phpbb\module\module_manager $module_manager, $phpbb_root_path, $php_ext, $modules_table)
{
$this->db = $db;
$this->cache = $cache;
$this->user = $user;
+ $this->module_manager = $module_manager;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
$this->modules_table = $modules_table;
@@ -188,7 +195,6 @@ class module implements \phpbb\db\migration\tool\tool_interface
$basename = (isset($data['module_basename'])) ? $data['module_basename'] : '';
$module = $this->get_module_info($class, $basename);
- $result = '';
foreach ($module['modes'] as $mode => $module_info)
{
if (!isset($data['modes']) || in_array($mode, $data['modes']))
@@ -239,13 +245,6 @@ class module implements \phpbb\db\migration\tool\tool_interface
return;
}
- if (!class_exists('acp_modules'))
- {
- include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext);
- $this->user->add_lang('acp/modules');
- }
- $acp_modules = new \acp_modules();
-
$module_data = array(
'module_enabled' => (isset($data['module_enabled'])) ? $data['module_enabled'] : 1,
'module_display' => (isset($data['module_display'])) ? $data['module_display'] : 1,
@@ -256,16 +255,11 @@ class module implements \phpbb\db\migration\tool\tool_interface
'module_mode' => (isset($data['module_mode'])) ? $data['module_mode'] : '',
'module_auth' => (isset($data['module_auth'])) ? $data['module_auth'] : '',
);
- $result = $acp_modules->update_module_data($module_data, true);
- // update_module_data can either return a string or an empty array...
- if (is_string($result))
- {
- // Error
- throw new \phpbb\db\migration\exception('MODULE_ERROR', $result);
- }
- else
+ try
{
+ $this->module_manager->update_module_data($module_data);
+
// Success
$module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']);
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_ADD', false, array($module_log_name));
@@ -318,6 +312,11 @@ class module implements \phpbb\db\migration\tool\tool_interface
$this->db->sql_query($sql);
}
}
+ catch (module_exception $e)
+ {
+ // Error
+ throw new \phpbb\db\migration\exception('MODULE_ERROR', $e->getMessage());
+ }
// Clear the Modules Cache
$this->cache->destroy("_modules_$class");
@@ -417,21 +416,9 @@ class module implements \phpbb\db\migration\tool\tool_interface
$module_ids[] = (int) $module;
}
- if (!class_exists('acp_modules'))
- {
- include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext);
- $this->user->add_lang('acp/modules');
- }
- $acp_modules = new \acp_modules();
- $acp_modules->module_class = $class;
-
foreach ($module_ids as $module_id)
{
- $result = $acp_modules->delete_module($module_id);
- if (!empty($result))
- {
- return;
- }
+ $this->module_manager->delete_module($module_id, $class);
}
$this->cache->destroy("_modules_$class");
@@ -474,13 +461,7 @@ class module implements \phpbb\db\migration\tool\tool_interface
*/
protected function get_module_info($class, $basename)
{
- if (!class_exists('acp_modules'))
- {
- include($this->phpbb_root_path . 'includes/acp/acp_modules.' . $this->php_ext);
- $this->user->add_lang('acp/modules');
- }
- $acp_modules = new \acp_modules();
- $module = $acp_modules->get_module_infos($basename, $class, true);
+ $module = $this->module_manager->get_module_infos($class, $basename, true);
if (empty($module))
{
diff --git a/phpBB/phpbb/db/migration/tool/permission.php b/phpBB/phpbb/db/migration/tool/permission.php
index 1a91127d2d..ceff6d7d5a 100644
--- a/phpBB/phpbb/db/migration/tool/permission.php
+++ b/phpBB/phpbb/db/migration/tool/permission.php
@@ -425,13 +425,27 @@ class permission implements \phpbb\db\migration\tool\tool_interface
$role_id = (int) $this->db->sql_fetchfield('auth_role_id');
if ($role_id)
{
- $sql = 'SELECT role_name
+ $sql = 'SELECT role_name, role_type
FROM ' . ACL_ROLES_TABLE . '
WHERE role_id = ' . $role_id;
$this->db->sql_query($sql);
- $role_name = $this->db->sql_fetchfield('role_name');
-
- return $this->permission_set($role_name, $auth_option, 'role', $has_permission);
+ $role_data = $this->db->sql_fetchrow();
+ $role_name = $role_data['role_name'];
+ $role_type = $role_data['role_type'];
+
+ // Filter new auth options to match the role type: a_ | f_ | m_ | u_
+ // Set new auth options to the role only if options matching the role type were found
+ $auth_option = array_filter($auth_option,
+ function ($option) use ($role_type)
+ {
+ return strpos($option, $role_type) === 0;
+ }
+ );
+
+ if (sizeof($auth_option))
+ {
+ return $this->permission_set($role_name, $auth_option, 'role', $has_permission);
+ }
}
$sql = 'SELECT auth_option_id, auth_setting
diff --git a/phpBB/phpbb/db/sql_insert_buffer.php b/phpBB/phpbb/db/sql_insert_buffer.php
index 14e3c54f09..18e4814a77 100644
--- a/phpBB/phpbb/db/sql_insert_buffer.php
+++ b/phpBB/phpbb/db/sql_insert_buffer.php
@@ -107,7 +107,7 @@ class sql_insert_buffer
* first building a huge rowset. Or at least sizeof($rows) should be kept
* small.
*
- * @param array $rows
+ * @param array $rows
*
* @return bool True when some data was flushed to the database.
* False otherwise.
diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php
index 4a31339b9a..c9adbe7d63 100644
--- a/phpBB/phpbb/di/container_builder.php
+++ b/phpBB/phpbb/di/container_builder.php
@@ -499,8 +499,7 @@ class container_builder
*/
protected function get_container_filename()
{
- $filename = str_replace(array('/', '.'), array('slash', 'dot'), $this->phpbb_root_path);
- return $this->get_cache_dir() . 'container_' . $filename . '.' . $this->php_ext;
+ return $this->get_cache_dir() . 'container_' . md5($this->phpbb_root_path) . '.' . $this->php_ext;
}
/**
diff --git a/phpBB/phpbb/language/language_file_loader.php b/phpBB/phpbb/language/language_file_loader.php
index 9862cfc3aa..359202fd63 100644
--- a/phpBB/phpbb/language/language_file_loader.php
+++ b/phpBB/phpbb/language/language_file_loader.php
@@ -154,7 +154,7 @@ class language_file_loader
*
* @return string Relative path to language file
*
- * @throws \phpbb\language\exception\language_file_not_found When the path to the file cannot be resolved
+ * @throws language_file_not_found When the path to the file cannot be resolved
*/
protected function get_language_file_path($path, $filename, $locales)
{
diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php
index a1bf0f8e88..1b02d98b82 100644
--- a/phpBB/phpbb/log/log.php
+++ b/phpBB/phpbb/log/log.php
@@ -535,7 +535,7 @@ class log implements \phpbb\log\log_interface
'ORDER_BY' => $sort_by,
);
- if($log_time)
+ if ($log_time)
{
$get_logs_sql_ary['WHERE'] = 'l.log_time >= ' . (int) $log_time . '
AND ' . $get_logs_sql_ary['WHERE'];
diff --git a/phpBB/phpbb/module/exception/module_exception.php b/phpBB/phpbb/module/exception/module_exception.php
new file mode 100644
index 0000000000..8ad75112bc
--- /dev/null
+++ b/phpBB/phpbb/module/exception/module_exception.php
@@ -0,0 +1,19 @@
+<?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\module\exception;
+
+class module_exception extends \phpbb\exception\runtime_exception
+{
+
+}
diff --git a/phpBB/phpbb/module/exception/module_not_found_exception.php b/phpBB/phpbb/module/exception/module_not_found_exception.php
new file mode 100644
index 0000000000..2d485e7b35
--- /dev/null
+++ b/phpBB/phpbb/module/exception/module_not_found_exception.php
@@ -0,0 +1,19 @@
+<?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\module\exception;
+
+class module_not_found_exception extends module_exception
+{
+
+}
diff --git a/phpBB/phpbb/module/module_manager.php b/phpBB/phpbb/module/module_manager.php
new file mode 100644
index 0000000000..a812d06736
--- /dev/null
+++ b/phpBB/phpbb/module/module_manager.php
@@ -0,0 +1,564 @@
+<?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\module;
+
+use phpbb\module\exception\module_exception;
+use phpbb\module\exception\module_not_found_exception;
+
+class module_manager
+{
+ /**
+ * @var \phpbb\cache\driver\driver_interface
+ */
+ protected $cache;
+
+ /**
+ * @var \phpbb\db\driver\driver_interface
+ */
+ protected $db;
+
+ /**
+ * @var \phpbb\extension\manager
+ */
+ protected $extension_manager;
+
+ /**
+ * @var string
+ */
+ protected $modules_table;
+
+ /**
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * @var string
+ */
+ protected $php_ext;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\cache\driver\driver_interface $cache Cache driver
+ * @param \phpbb\db\driver\driver_interface $db Database driver
+ * @param \phpbb\extension\manager $ext_manager Extension manager
+ * @param string $modules_table Module database table's name
+ * @param string $phpbb_root_path Path to phpBB's root
+ * @param string $php_ext Extension of PHP files
+ */
+ public function __construct(\phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\extension\manager $ext_manager, $modules_table, $phpbb_root_path, $php_ext)
+ {
+ $this->cache = $cache;
+ $this->db = $db;
+ $this->extension_manager = $ext_manager;
+ $this->modules_table = $modules_table;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ }
+
+ /**
+ * Get row for specified module
+ *
+ * @param int $module_id ID of the module
+ * @param string $module_class Class of the module (acp, ucp, mcp etc...)
+ *
+ * @return array Array of data fetched from the database
+ *
+ * @throws \phpbb\module\exception\module_not_found_exception When there is no module with $module_id
+ */
+ public function get_module_row($module_id, $module_class)
+ {
+ $module_id = (int) $module_id;
+
+ $sql = 'SELECT *
+ FROM ' . $this->modules_table . "
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND module_id = $module_id";
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if (!$row)
+ {
+ throw new module_not_found_exception('NO_MODULE');
+ }
+
+ return $row;
+ }
+
+ /**
+ * Get available module information from module files
+ *
+ * @param string $module_class Class of the module (acp, ucp, mcp etc...)
+ * @param string $module ID of module
+ * @param bool $use_all_available Use all available instead of just all
+ * enabled extensions
+ *
+ * @return array Array with module information gathered from module info files.
+ */
+ public function get_module_infos($module_class, $module = '', $use_all_available = false)
+ {
+ $directory = $this->phpbb_root_path . 'includes/' . $module_class . '/info/';
+ $fileinfo = array();
+
+ $finder = $this->extension_manager->get_finder($use_all_available);
+
+ $modules = $finder
+ ->extension_suffix('_module')
+ ->extension_directory("/$module_class")
+ ->core_path("includes/$module_class/info/")
+ ->core_prefix($module_class . '_')
+ ->get_classes(true);
+
+ foreach ($modules as $cur_module)
+ {
+ // Skip entries we do not need if we know the module we are
+ // looking for
+ if ($module && strpos(str_replace('\\', '_', $cur_module), $module) === false && $module !== $cur_module)
+ {
+ continue;
+ }
+
+ $info_class = preg_replace('/_module$/', '_info', $cur_module);
+
+ // If the class does not exist it might be following the old
+ // format. phpbb_acp_info_acp_foo needs to be turned into
+ // acp_foo_info and the respective file has to be included
+ // manually because it does not support auto loading
+ $old_info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module);
+ $old_info_class = $old_info_class_file . '_info';
+
+ if (class_exists($old_info_class))
+ {
+ $info_class = $old_info_class;
+ }
+ else if (!class_exists($info_class))
+ {
+ $info_class = $old_info_class;
+
+ // need to check class exists again because previous checks triggered autoloading
+ if (!class_exists($info_class) && file_exists($directory . $old_info_class_file . '.' . $this->php_ext))
+ {
+ include($directory . $old_info_class_file . '.' . $this->php_ext);
+ }
+ }
+
+ if (class_exists($info_class))
+ {
+ $info = new $info_class();
+ $module_info = $info->module();
+
+ $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $cur_module;
+
+ $fileinfo[$main_class] = $module_info;
+ }
+ }
+
+ ksort($fileinfo);
+
+ return $fileinfo;
+ }
+
+ /**
+ * Get module branch
+ *
+ * @param int $module_id ID of the module
+ * @param string $module_class Class of the module (acp, ucp, mcp etc...)
+ * @param string $type Type of branch (Expected values: all, parents or children)
+ * @param bool $include_module Whether or not to include the specified module with $module_id
+ *
+ * @return array Returns an array containing the modules in the specified branch type.
+ */
+ public function get_module_branch($module_id, $module_class, $type = 'all', $include_module = true)
+ {
+ $module_id = (int) $module_id;
+
+ switch ($type)
+ {
+ case 'parents':
+ $condition = 'm1.left_id BETWEEN m2.left_id AND m2.right_id';
+ break;
+
+ case 'children':
+ $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id';
+ break;
+
+ default:
+ $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id OR m1.left_id BETWEEN m2.left_id AND m2.right_id';
+ break;
+ }
+
+ $rows = array();
+
+ $sql = 'SELECT m2.*
+ FROM ' . $this->modules_table . ' m1
+ LEFT JOIN ' . $this->modules_table . " m2 ON ($condition)
+ WHERE m1.module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND m2.module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND m1.module_id = $module_id
+ ORDER BY m2.left_id DESC";
+ $result = $this->db->sql_query($sql);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ if (!$include_module && $row['module_id'] == $module_id)
+ {
+ continue;
+ }
+
+ $rows[] = $row;
+ }
+ $this->db->sql_freeresult($result);
+
+ return $rows;
+ }
+
+ /**
+ * Remove modules cache file
+ *
+ * @param string $module_class Class of the module (acp, ucp, mcp etc...)
+ */
+ public function remove_cache_file($module_class)
+ {
+ // Sanitise for future path use, it's escaped as appropriate for queries
+ $cache_class = str_replace(array('.', '/', '\\'), '', basename($module_class));
+ $this->cache->destroy('_modules_' . $cache_class);
+ $this->cache->destroy('sql', $this->modules_table);
+ }
+
+ /**
+ * Update/Add module
+ *
+ * @param array &$module_data The module data
+ *
+ * @throws \phpbb\module\exception\module_not_found_exception When parent module or the category is not exist
+ */
+ public function update_module_data(&$module_data)
+ {
+ if (!isset($module_data['module_id']))
+ {
+ // no module_id means we're creating a new category/module
+ if ($module_data['parent_id'])
+ {
+ $sql = 'SELECT left_id, right_id
+ FROM ' . $this->modules_table . "
+ WHERE module_class = '" . $this->db->sql_escape($module_data['module_class']) . "'
+ AND module_id = " . (int) $module_data['parent_id'];
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if (!$row)
+ {
+ throw new module_not_found_exception('PARENT_NOT_EXIST');
+ }
+
+ // Workaround
+ $row['left_id'] = (int) $row['left_id'];
+ $row['right_id'] = (int) $row['right_id'];
+
+ $sql = 'UPDATE ' . $this->modules_table . "
+ SET left_id = left_id + 2, right_id = right_id + 2
+ WHERE module_class = '" . $this->db->sql_escape($module_data['module_class']) . "'
+ AND left_id > {$row['right_id']}";
+ $this->db->sql_query($sql);
+
+ $sql = 'UPDATE ' . $this->modules_table . "
+ SET right_id = right_id + 2
+ WHERE module_class = '" . $this->db->sql_escape($module_data['module_class']) . "'
+ AND {$row['left_id']} BETWEEN left_id AND right_id";
+ $this->db->sql_query($sql);
+
+ $module_data['left_id'] = (int) $row['right_id'];
+ $module_data['right_id'] = (int) $row['right_id'] + 1;
+ }
+ else
+ {
+ $sql = 'SELECT MAX(right_id) AS right_id
+ FROM ' . $this->modules_table . "
+ WHERE module_class = '" . $this->db->sql_escape($module_data['module_class']) . "'";
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ $module_data['left_id'] = (int) $row['right_id'] + 1;
+ $module_data['right_id'] = (int) $row['right_id'] + 2;
+ }
+
+ $sql = 'INSERT INTO ' . $this->modules_table . ' ' . $this->db->sql_build_array('INSERT', $module_data);
+ $this->db->sql_query($sql);
+
+ $module_data['module_id'] = $this->db->sql_nextid();
+ }
+ else
+ {
+ $row = $this->get_module_row($module_data['module_id'], $module_data['module_class']);
+
+ if ($module_data['module_basename'] && !$row['module_basename'])
+ {
+ // we're turning a category into a module
+ $branch = $this->get_module_branch($module_data['module_id'], $module_data['module_class'], 'children', false);
+
+ if (sizeof($branch))
+ {
+ throw new module_not_found_exception('NO_CATEGORY_TO_MODULE');
+ }
+ }
+
+ if ($row['parent_id'] != $module_data['parent_id'])
+ {
+ $this->move_module($module_data['module_id'], $module_data['parent_id'], $module_data['module_class']);
+ }
+
+ $update_ary = $module_data;
+ unset($update_ary['module_id']);
+
+ $sql = 'UPDATE ' . $this->modules_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $update_ary) . "
+ WHERE module_class = '" . $this->db->sql_escape($module_data['module_class']) . "'
+ AND module_id = " . (int) $module_data['module_id'];
+ $this->db->sql_query($sql);
+ }
+ }
+
+ /**
+ * Move module around the tree
+ *
+ * @param int $from_module_id ID of the current parent module
+ * @param int $to_parent_id ID of the target parent module
+ * @param string $module_class Class of the module (acp, ucp, mcp etc...)
+ *
+ * @throws \phpbb\module\exception\module_not_found_exception If the module specified to move modules from does not
+ * have any children.
+ */
+ public function move_module($from_module_id, $to_parent_id, $module_class)
+ {
+ $moved_modules = $this->get_module_branch($from_module_id, $module_class, 'children');
+
+ if (empty($moved_modules))
+ {
+ throw new module_not_found_exception();
+ }
+
+ $from_data = $moved_modules[0];
+ $diff = sizeof($moved_modules) * 2;
+
+ $moved_ids = array();
+ for ($i = 0; $i < sizeof($moved_modules); ++$i)
+ {
+ $moved_ids[] = $moved_modules[$i]['module_id'];
+ }
+
+ // Resync parents
+ $sql = 'UPDATE ' . $this->modules_table . "
+ SET right_id = right_id - $diff
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND left_id < " . (int) $from_data['right_id'] . '
+ AND right_id > ' . (int) $from_data['right_id'];
+ $this->db->sql_query($sql);
+
+ // Resync righthand side of tree
+ $sql = 'UPDATE ' . $this->modules_table . "
+ SET left_id = left_id - $diff, right_id = right_id - $diff
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND left_id > " . (int) $from_data['right_id'];
+ $this->db->sql_query($sql);
+
+ if ($to_parent_id > 0)
+ {
+ $to_data = $this->get_module_row($to_parent_id, $module_class);
+
+ // Resync new parents
+ $sql = 'UPDATE ' . $this->modules_table . "
+ SET right_id = right_id + $diff
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND " . (int) $to_data['right_id'] . ' BETWEEN left_id AND right_id
+ AND ' . $this->db->sql_in_set('module_id', $moved_ids, true);
+ $this->db->sql_query($sql);
+
+ // Resync the righthand side of the tree
+ $sql = 'UPDATE ' . $this->modules_table . "
+ SET left_id = left_id + $diff, right_id = right_id + $diff
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND left_id > " . (int) $to_data['right_id'] . '
+ AND ' . $this->db->sql_in_set('module_id', $moved_ids, true);
+ $this->db->sql_query($sql);
+
+ // Resync moved branch
+ $to_data['right_id'] += $diff;
+ if ($to_data['right_id'] > $from_data['right_id'])
+ {
+ $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1);
+ }
+ else
+ {
+ $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1);
+ }
+ }
+ else
+ {
+ $sql = 'SELECT MAX(right_id) AS right_id
+ FROM ' . $this->modules_table . "
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND " . $this->db->sql_in_set('module_id', $moved_ids, true);
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ $diff = '+ ' . (int) ($row['right_id'] - $from_data['left_id'] + 1);
+ }
+
+ $sql = 'UPDATE ' . $this->modules_table . "
+ SET left_id = left_id $diff, right_id = right_id $diff
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND " . $this->db->sql_in_set('module_id', $moved_ids);
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * Remove module from tree
+ *
+ * @param int $module_id ID of the module to delete
+ * @param string $module_class Class of the module (acp, ucp, mcp etc...)
+ *
+ * @throws \phpbb\module\exception\module_exception When the specified module cannot be removed
+ */
+ public function delete_module($module_id, $module_class)
+ {
+ $module_id = (int) $module_id;
+
+ $row = $this->get_module_row($module_id, $module_class);
+
+ $branch = $this->get_module_branch($module_id, $module_class, 'children', false);
+
+ if (sizeof($branch))
+ {
+ throw new module_exception('CANNOT_REMOVE_MODULE');
+ }
+
+ // If not move
+ $diff = 2;
+ $sql = 'DELETE FROM ' . $this->modules_table . "
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND module_id = $module_id";
+ $this->db->sql_query($sql);
+
+ $row['right_id'] = (int) $row['right_id'];
+ $row['left_id'] = (int) $row['left_id'];
+
+ // Resync tree
+ $sql = 'UPDATE ' . $this->modules_table . "
+ SET right_id = right_id - $diff
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND left_id < {$row['right_id']} AND right_id > {$row['right_id']}";
+ $this->db->sql_query($sql);
+
+ $sql = 'UPDATE ' . $this->modules_table . "
+ SET left_id = left_id - $diff, right_id = right_id - $diff
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND left_id > {$row['right_id']}";
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * Move module position by $steps up/down
+ *
+ * @param array $module_row Array of module data
+ * @param string $module_class Class of the module (acp, ucp, mcp etc...)
+ * @param string $action Direction of moving (valid values: move_up or move_down)
+ * @param int $steps Number of steps to move module
+ *
+ * @return string Returns the language name of the module
+ *
+ * @throws \phpbb\module\exception\module_not_found_exception When the specified module does not exists
+ */
+ public function move_module_by($module_row, $module_class, $action = 'move_up', $steps = 1)
+ {
+ /**
+ * Fetch all the siblings between the module's current spot
+ * and where we want to move it to. If there are less than $steps
+ * siblings between the current spot and the target then the
+ * module will move as far as possible
+ */
+ $sql = 'SELECT module_id, left_id, right_id, module_langname
+ FROM ' . $this->modules_table . "
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND parent_id = " . (int) $module_row['parent_id'] . '
+ AND ' . (($action == 'move_up') ? 'right_id < ' . (int) $module_row['right_id'] . ' ORDER BY right_id DESC' : 'left_id > ' . (int) $module_row['left_id'] . ' ORDER BY left_id ASC');
+ $result = $this->db->sql_query_limit($sql, $steps);
+
+ $target = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $target = $row;
+ }
+ $this->db->sql_freeresult($result);
+
+ if (!sizeof($target))
+ {
+ // The module is already on top or bottom
+ throw new module_not_found_exception();
+ }
+
+ /**
+ * $left_id and $right_id define the scope of the nodes that are affected by the move.
+ * $diff_up and $diff_down are the values to substract or add to each node's left_id
+ * and right_id in order to move them up or down.
+ * $move_up_left and $move_up_right define the scope of the nodes that are moving
+ * up. Other nodes in the scope of ($left_id, $right_id) are considered to move down.
+ */
+ if ($action == 'move_up')
+ {
+ $left_id = (int) $target['left_id'];
+ $right_id = (int) $module_row['right_id'];
+
+ $diff_up = (int) ($module_row['left_id'] - $target['left_id']);
+ $diff_down = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
+
+ $move_up_left = (int) $module_row['left_id'];
+ $move_up_right = (int) $module_row['right_id'];
+ }
+ else
+ {
+ $left_id = (int) $module_row['left_id'];
+ $right_id = (int) $target['right_id'];
+
+ $diff_up = (int) ($module_row['right_id'] + 1 - $module_row['left_id']);
+ $diff_down = (int) ($target['right_id'] - $module_row['right_id']);
+
+ $move_up_left = (int) ($module_row['right_id'] + 1);
+ $move_up_right = (int) $target['right_id'];
+ }
+
+ // Now do the dirty job
+ $sql = 'UPDATE ' . $this->modules_table . "
+ SET left_id = left_id + CASE
+ WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
+ ELSE {$diff_down}
+ END,
+ right_id = right_id + CASE
+ WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up}
+ ELSE {$diff_down}
+ END
+ WHERE module_class = '" . $this->db->sql_escape($module_class) . "'
+ AND left_id BETWEEN {$left_id} AND {$right_id}
+ AND right_id BETWEEN {$left_id} AND {$right_id}";
+ $this->db->sql_query($sql);
+
+ $this->remove_cache_file($module_class);
+
+ return $target['module_langname'];
+ }
+}
diff --git a/phpBB/phpbb/notification/method/base.php b/phpBB/phpbb/notification/method/base.php
index a0bbed6fcd..6ee1d2984a 100644
--- a/phpBB/phpbb/notification/method/base.php
+++ b/phpBB/phpbb/notification/method/base.php
@@ -60,7 +60,7 @@ abstract class base implements \phpbb\notification\method\method_interface
/**
* Notification Method Base Constructor
- *
+ *
* @param \phpbb\user_loader $user_loader
* @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\cache\driver\driver_interface $cache
@@ -85,7 +85,7 @@ abstract class base implements \phpbb\notification\method\method_interface
/**
* Set notification manager (required)
- *
+ *
* @param \phpbb\notification\manager $notification_manager
*/
public function set_notification_manager(\phpbb\notification\manager $notification_manager)
diff --git a/phpBB/phpbb/notification/type/admin_activate_user.php b/phpBB/phpbb/notification/type/admin_activate_user.php
index 73ed612480..0e2924e29c 100644
--- a/phpBB/phpbb/notification/type/admin_activate_user.php
+++ b/phpBB/phpbb/notification/type/admin_activate_user.php
@@ -104,7 +104,7 @@ class admin_activate_user extends \phpbb\notification\type\base
*/
public function get_avatar()
{
- return $this->user_loader->get_avatar($this->item_id);
+ return $this->user_loader->get_avatar($this->item_id, false, true);
}
/**
diff --git a/phpBB/phpbb/notification/type/group_request.php b/phpBB/phpbb/notification/type/group_request.php
index 19665624df..2d7925c1b4 100644
--- a/phpBB/phpbb/notification/type/group_request.php
+++ b/phpBB/phpbb/notification/type/group_request.php
@@ -96,7 +96,7 @@ class group_request extends \phpbb\notification\type\base
*/
public function get_avatar()
{
- return $this->user_loader->get_avatar($this->item_id);
+ return $this->user_loader->get_avatar($this->item_id, false, true);
}
/**
diff --git a/phpBB/phpbb/notification/type/pm.php b/phpBB/phpbb/notification/type/pm.php
index 29b4b79216..5d4f7fe0c6 100644
--- a/phpBB/phpbb/notification/type/pm.php
+++ b/phpBB/phpbb/notification/type/pm.php
@@ -100,7 +100,7 @@ class pm extends \phpbb\notification\type\base
*/
public function get_avatar()
{
- return $this->user_loader->get_avatar($this->get_data('from_user_id'));
+ return $this->user_loader->get_avatar($this->get_data('from_user_id'), false, true);
}
/**
diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php
index d6aa8a8af9..f6b3136a21 100644
--- a/phpBB/phpbb/notification/type/post.php
+++ b/phpBB/phpbb/notification/type/post.php
@@ -165,7 +165,7 @@ class post extends \phpbb\notification\type\base
*/
public function get_avatar()
{
- return $this->user_loader->get_avatar($this->get_data('poster_id'));
+ return $this->user_loader->get_avatar($this->get_data('poster_id'), false, true);
}
/**
diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php
index 1904680d5a..e7d385f59f 100644
--- a/phpBB/phpbb/notification/type/report_pm.php
+++ b/phpBB/phpbb/notification/type/report_pm.php
@@ -223,7 +223,7 @@ class report_pm extends \phpbb\notification\type\pm
*/
public function get_avatar()
{
- return $this->user_loader->get_avatar($this->get_data('reporter_id'));
+ return $this->user_loader->get_avatar($this->get_data('reporter_id'), false, true);
}
/**
diff --git a/phpBB/phpbb/notification/type/report_pm_closed.php b/phpBB/phpbb/notification/type/report_pm_closed.php
index 9f301ee2cc..1c99db60c3 100644
--- a/phpBB/phpbb/notification/type/report_pm_closed.php
+++ b/phpBB/phpbb/notification/type/report_pm_closed.php
@@ -130,7 +130,7 @@ class report_pm_closed extends \phpbb\notification\type\pm
*/
public function get_avatar()
{
- return $this->user_loader->get_avatar($this->get_data('closer_id'));
+ return $this->user_loader->get_avatar($this->get_data('closer_id'), false, true);
}
/**
diff --git a/phpBB/phpbb/notification/type/report_post.php b/phpBB/phpbb/notification/type/report_post.php
index b64862078a..8289a04cf1 100644
--- a/phpBB/phpbb/notification/type/report_post.php
+++ b/phpBB/phpbb/notification/type/report_post.php
@@ -196,7 +196,7 @@ class report_post extends \phpbb\notification\type\post_in_queue
*/
public function get_avatar()
{
- return $this->user_loader->get_avatar($this->get_data('reporter_id'));
+ return $this->user_loader->get_avatar($this->get_data('reporter_id'), false, true);
}
/**
diff --git a/phpBB/phpbb/notification/type/report_post_closed.php b/phpBB/phpbb/notification/type/report_post_closed.php
index a0bb187a0d..3f4378628b 100644
--- a/phpBB/phpbb/notification/type/report_post_closed.php
+++ b/phpBB/phpbb/notification/type/report_post_closed.php
@@ -137,7 +137,7 @@ class report_post_closed extends \phpbb\notification\type\post
*/
public function get_avatar()
{
- return $this->user_loader->get_avatar($this->get_data('closer_id'));
+ return $this->user_loader->get_avatar($this->get_data('closer_id'), false, true);
}
/**
diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php
index a1a17535b5..f0681b9eb8 100644
--- a/phpBB/phpbb/notification/type/topic.php
+++ b/phpBB/phpbb/notification/type/topic.php
@@ -119,7 +119,7 @@ class topic extends \phpbb\notification\type\base
*/
public function get_avatar()
{
- return $this->user_loader->get_avatar($this->get_data('poster_id'));
+ return $this->user_loader->get_avatar($this->get_data('poster_id'), false, true);
}
/**
diff --git a/phpBB/phpbb/passwords/driver/helper.php b/phpBB/phpbb/passwords/driver/helper.php
index caa65080ac..f80c3e3df6 100644
--- a/phpBB/phpbb/passwords/driver/helper.php
+++ b/phpBB/phpbb/passwords/driver/helper.php
@@ -153,11 +153,23 @@ class helper
*/
public function string_compare($string_a, $string_b)
{
- $difference = strlen($string_a) != strlen($string_b);
+ // Return if input variables are not strings or if length does not match
+ if (!is_string($string_a) || !is_string($string_b) || strlen($string_a) != strlen($string_b))
+ {
+ return false;
+ }
+
+ // Use hash_equals() if it's available
+ if (function_exists('hash_equals'))
+ {
+ return hash_equals($string_a, $string_b);
+ }
+
+ $difference = 0;
for ($i = 0; $i < strlen($string_a) && $i < strlen($string_b); $i++)
{
- $difference |= $string_a[$i] != $string_b[$i];
+ $difference |= ord($string_a[$i]) ^ ord($string_b[$i]);
}
return $difference === 0;
diff --git a/phpBB/phpbb/routing/router.php b/phpBB/phpbb/routing/router.php
index 2f89d4e884..5af005769f 100644
--- a/phpBB/phpbb/routing/router.php
+++ b/phpBB/phpbb/routing/router.php
@@ -15,6 +15,9 @@ namespace phpbb\routing;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Filesystem\Exception\IOException;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
+use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
use Symfony\Component\Routing\Matcher\UrlMatcher;
@@ -92,18 +95,24 @@ class router implements RouterInterface
protected $filesystem;
/**
+ * @var ContainerInterface
+ */
+ protected $container;
+
+ /**
* Construct method
*
+ * @param ContainerInterface $container DI container
* @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem helper
- * @param string $phpbb_root_path phpBB root path
- * @param string $php_ext PHP file extension
- * @param string $environment Name of the current environment
- * @param manager|null $extension_manager Extension manager
- * @param array $routing_files Array of strings containing paths to YAML files
- * holding route information
+ * @param string $phpbb_root_path phpBB root path
+ * @param string $php_ext PHP file extension
+ * @param string $environment Name of the current environment
+ * @param manager $extension_manager Extension manager
+ * @param array $routing_files Array of strings containing paths to YAML files holding route information
*/
- public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path, $php_ext, $environment, manager $extension_manager = null, $routing_files = array())
+ public function __construct(ContainerInterface $container, \phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path, $php_ext, $environment, manager $extension_manager = null, $routing_files = array())
{
+ $this->container = $container;
$this->filesystem = $filesystem;
$this->extension_manager = $extension_manager;
$this->routing_files = $routing_files;
@@ -162,10 +171,118 @@ class router implements RouterInterface
}
}
+ $this->resolveParameters($this->route_collection);
+
return $this;
}
/**
+ * Replaces placeholders with service container parameter values in:
+ * - the route defaults,
+ * - the route requirements,
+ * - the route path,
+ * - the route host,
+ * - the route schemes,
+ * - the route methods.
+ *
+ * @param RouteCollection $collection
+ */
+ private function resolveParameters(RouteCollection $collection)
+ {
+ foreach ($collection as $route)
+ {
+ foreach ($route->getDefaults() as $name => $value)
+ {
+ $route->setDefault($name, $this->resolve($value));
+ }
+
+ $requirements = $route->getRequirements();
+ unset($requirements['_scheme']);
+ unset($requirements['_method']);
+
+ foreach ($requirements as $name => $value)
+ {
+ $route->setRequirement($name, $this->resolve($value));
+ }
+
+ $route->setPath($this->resolve($route->getPath()));
+ $route->setHost($this->resolve($route->getHost()));
+
+ $schemes = array();
+ foreach ($route->getSchemes() as $scheme)
+ {
+ $schemes = array_merge($schemes, explode('|', $this->resolve($scheme)));
+ }
+
+ $route->setSchemes($schemes);
+ $methods = array();
+ foreach ($route->getMethods() as $method)
+ {
+ $methods = array_merge($methods, explode('|', $this->resolve($method)));
+ }
+
+ $route->setMethods($methods);
+ $route->setCondition($this->resolve($route->getCondition()));
+ }
+ }
+
+ /**
+ * Recursively replaces placeholders with the service container parameters.
+ *
+ * @param mixed $value The source which might contain "%placeholders%"
+ *
+ * @return mixed The source with the placeholders replaced by the container
+ * parameters. Arrays are resolved recursively.
+ *
+ * @throws ParameterNotFoundException When a placeholder does not exist as a container parameter
+ * @throws RuntimeException When a container value is not a string or a numeric value
+ */
+ private function resolve($value)
+ {
+ if (is_array($value))
+ {
+ foreach ($value as $key => $val)
+ {
+ $value[$key] = $this->resolve($val);
+ }
+
+ return $value;
+ }
+
+ if (!is_string($value))
+ {
+ return $value;
+ }
+
+ $container = $this->container;
+ $escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($container, $value)
+ {
+ // skip %%
+ if (!isset($match[1]))
+ {
+ return '%%';
+ }
+
+ $resolved = $container->getParameter($match[1]);
+ if (is_string($resolved) || is_numeric($resolved))
+ {
+ return (string) $resolved;
+ }
+
+ throw new RuntimeException(sprintf(
+ 'The container parameter "%s", used in the route configuration value "%s", '.
+ 'must be a string or numeric, but it is of type %s.',
+ $match[1],
+ $value,
+ gettype($resolved)
+ )
+ );
+ }, $value);
+
+ return str_replace('%%', '%', $escapedValue);
+ }
+
+ /**
* Get the list of routes
*
* @return RouteCollection Get the route collection
diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php
index da9de56009..9f1aaec7c2 100644
--- a/phpBB/phpbb/search/fulltext_mysql.php
+++ b/phpBB/phpbb/search/fulltext_mysql.php
@@ -43,6 +43,12 @@ class fulltext_mysql extends \phpbb\search\base
protected $db;
/**
+ * phpBB event dispatcher object
+ * @var \phpbb\event\dispatcher_interface
+ */
+ protected $phpbb_dispatcher;
+
+ /**
* User object
* @var \phpbb\user
*/
@@ -79,11 +85,13 @@ class fulltext_mysql extends \phpbb\search\base
* @param \phpbb\config\config $config Config object
* @param \phpbb\db\driver\driver_interface Database object
* @param \phpbb\user $user User object
+ * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object
*/
- public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user)
+ public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher)
{
$this->config = $config;
$this->db = $db;
+ $this->phpbb_dispatcher = $phpbb_dispatcher;
$this->user = $user;
$this->word_length = array('min' => $this->config['fulltext_mysql_min_word_len'], 'max' => $this->config['fulltext_mysql_max_word_len']);
@@ -447,6 +455,55 @@ class fulltext_mysql extends \phpbb\search\base
break;
}
+ $search_query = $this->search_query;
+
+ /**
+ * Allow changing the query used to search for posts using fulltext_mysql
+ *
+ * @event core.search_mysql_keywords_main_query_before
+ * @var string search_query The parsed keywords used for this search
+ * @var int result_count The previous result count for the format of the query.
+ * Set to 0 to force a re-count
+ * @var bool join_topic Weather or not TOPICS_TABLE should be CROSS JOIN'ED
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @var string author_name An extra username to search on (!empty(author_ary) must be true, to be relevant)
+ * @var array ex_fid_ary Which forums not to search on
+ * @var int topic_id Limit the search to this topic_id only
+ * @var string sql_sort_table Extra tables to include in the SQL query.
+ * Used in conjunction with sql_sort_join
+ * @var string sql_sort_join SQL conditions to join all the tables used together.
+ * Used in conjunction with sql_sort_table
+ * @var int sort_days Time, in days, of the oldest possible post to list
+ * @var string sql_match Which columns to do the search on.
+ * @var string sql_match_where Extra conditions to use to properly filter the matching process
+ * @var string sort_by_sql The possible predefined sort types
+ * @var string sort_key The sort type used from the possible sort types
+ * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used
+ * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir
+ * @var int start How many posts to skip in the search results (used for pagination)
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'search_query',
+ 'result_count',
+ 'join_topic',
+ 'author_ary',
+ 'author_name',
+ 'ex_fid_ary',
+ 'topic_id',
+ 'sql_sort_table',
+ 'sql_sort_join',
+ 'sort_days',
+ 'sql_match',
+ 'sql_match_where',
+ 'sort_by_sql',
+ 'sort_key',
+ 'sort_dir',
+ 'sql_sort',
+ 'start',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_mysql_keywords_main_query_before', compact($vars)));
+
$sql_select = (!$result_count) ? 'SQL_CALC_FOUND_ROWS ' : '';
$sql_select = ($type == 'posts') ? $sql_select . 'p.post_id' : 'DISTINCT ' . $sql_select . 't.topic_id';
$sql_from = ($join_topic) ? TOPICS_TABLE . ' t, ' : '';
@@ -620,6 +677,55 @@ class fulltext_mysql extends \phpbb\search\base
$m_approve_fid_sql = ' AND ' . $post_visibility;
+ /**
+ * Allow changing the query used to search for posts by author in fulltext_mysql
+ *
+ * @event core.search_mysql_author_query_before
+ * @var int result_count The previous result count for the format of the query.
+ * Set to 0 to force a re-count
+ * @var string sql_sort_table CROSS JOIN'ed table to allow doing the sort chosen
+ * @var string sql_sort_join Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @var string author_name An extra username to search on
+ * @var string sql_author SQL WHERE condition for the post author ids
+ * @var int topic_id Limit the search to this topic_id only
+ * @var string sql_topic_id SQL of topic_id
+ * @var string sort_by_sql The possible predefined sort types
+ * @var string sort_key The sort type used from the possible sort types
+ * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used
+ * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir
+ * @var string sort_days Time, in days, that the oldest post showing can have
+ * @var string sql_time The SQL to search on the time specifyed by sort_days
+ * @var bool firstpost_only Wether or not to search only on the first post of the topics
+ * @var array ex_fid_ary Forum ids that must not be searched on
+ * @var array sql_fora SQL query for ex_fid_ary
+ * @var string m_approve_fid_sql WHERE clause condition on post_visibility restrictions
+ * @var int start How many posts to skip in the search results (used for pagination)
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'result_count',
+ 'sql_sort_table',
+ 'sql_sort_join',
+ 'author_ary',
+ 'author_name',
+ 'sql_author',
+ 'topic_id',
+ 'sql_topic_id',
+ 'sort_by_sql',
+ 'sort_key',
+ 'sort_dir',
+ 'sql_sort',
+ 'sort_days',
+ 'sql_time',
+ 'firstpost_only',
+ 'ex_fid_ary',
+ 'sql_fora',
+ 'm_approve_fid_sql',
+ 'start',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_mysql_author_query_before', compact($vars)));
+
// If the cache was completely empty count the results
$calc_results = ($result_count) ? '' : 'SQL_CALC_FOUND_ROWS ';
diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php
index 42ad97da30..43f399eb13 100644
--- a/phpBB/phpbb/search/fulltext_native.php
+++ b/phpBB/phpbb/search/fulltext_native.php
@@ -94,6 +94,12 @@ class fulltext_native extends \phpbb\search\base
protected $db;
/**
+ * phpBB event dispatcher object
+ * @var \phpbb\event\dispatcher_interface
+ */
+ protected $phpbb_dispatcher;
+
+ /**
* User object
* @var \phpbb\user
*/
@@ -103,13 +109,15 @@ class fulltext_native extends \phpbb\search\base
* Initialises the fulltext_native search backend with min/max word length
*
* @param boolean|string &$error is passed by reference and should either be set to false on success or an error message on failure
+ * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object
*/
- public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user)
+ public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher)
{
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $phpEx;
$this->config = $config;
$this->db = $db;
+ $this->phpbb_dispatcher = $phpbb_dispatcher;
$this->user = $user;
$this->word_length = array('min' => $this->config['fulltext_native_min_chars'], 'max' => $this->config['fulltext_native_max_chars']);
@@ -715,6 +723,68 @@ class fulltext_native extends \phpbb\search\base
$sql_where[] = $post_visibility;
+ $search_query = $this->search_query;
+ $must_exclude_one_ids = $this->must_exclude_one_ids;
+ $must_not_contain_ids = $this->must_not_contain_ids;
+ $must_contain_ids = $this->must_contain_ids;
+
+ /**
+ * Allow changing the query used for counting for posts using fulltext_native
+ *
+ * @event core.search_native_keywords_count_query_before
+ * @var string search_query The parsed keywords used for this search
+ * @var array must_not_contain_ids Ids that cannot be taken into account for the results
+ * @var array must_exclude_one_ids Ids that cannot be on the results
+ * @var array must_contain_ids Ids that must be on the results
+ * @var int result_count The previous result count for the format of the query
+ * Set to 0 to force a re-count
+ * @var bool join_topic Weather or not TOPICS_TABLE should be CROSS JOIN'ED
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @var string author_name An extra username to search on (!empty(author_ary) must be true, to be relevant)
+ * @var array ex_fid_ary Which forums not to search on
+ * @var int topic_id Limit the search to this topic_id only
+ * @var string sql_sort_table Extra tables to include in the SQL query.
+ * Used in conjunction with sql_sort_join
+ * @var string sql_sort_join SQL conditions to join all the tables used together.
+ * Used in conjunction with sql_sort_table
+ * @var int sort_days Time, in days, of the oldest possible post to list
+ * @var string sql_where An array of the current WHERE clause conditions
+ * @var string sql_match Which columns to do the search on
+ * @var string sql_match_where Extra conditions to use to properly filter the matching process
+ * @var string group_by Whether or not the SQL query requires a GROUP BY for the elements in the SELECT clause
+ * @var string sort_by_sql The possible predefined sort types
+ * @var string sort_key The sort type used from the possible sort types
+ * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used
+ * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir
+ * @var int start How many posts to skip in the search results (used for pagination)
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'search_query',
+ 'must_not_contain_ids',
+ 'must_exclude_one_ids',
+ 'must_contain_ids',
+ 'result_count',
+ 'join_topic',
+ 'author_ary',
+ 'author_name',
+ 'ex_fid_ary',
+ 'topic_id',
+ 'sql_sort_table',
+ 'sql_sort_join',
+ 'sort_days',
+ 'sql_where',
+ 'sql_match',
+ 'sql_match_where',
+ 'group_by',
+ 'sort_by_sql',
+ 'sort_key',
+ 'sort_dir',
+ 'sql_sort',
+ 'start',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_native_keywords_count_query_before', compact($vars)));
+
if ($topic_id)
{
$sql_where[] = 'p.topic_id = ' . $topic_id;
@@ -975,6 +1045,49 @@ class fulltext_native extends \phpbb\search\base
$select = ($type == 'posts') ? 'p.post_id' : 't.topic_id';
$is_mysql = false;
+ /**
+ * Allow changing the query used to search for posts by author in fulltext_native
+ *
+ * @event core.search_native_author_count_query_before
+ * @var int total_results The previous result count for the format of the query.
+ * Set to 0 to force a re-count
+ * @var string select SQL SELECT clause for what to get
+ * @var string sql_sort_table CROSS JOIN'ed table to allow doing the sort chosen
+ * @var string sql_sort_join Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table
+ * @var array sql_author SQL WHERE condition for the post author ids
+ * @var int topic_id Limit the search to this topic_id only
+ * @var string sort_by_sql The possible predefined sort types
+ * @var string sort_key The sort type used from the possible sort types
+ * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used
+ * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir
+ * @var string sort_days Time, in days, that the oldest post showing can have
+ * @var string sql_time The SQL to search on the time specifyed by sort_days
+ * @var bool firstpost_only Wether or not to search only on the first post of the topics
+ * @var array ex_fid_ary Forum ids that must not be searched on
+ * @var array sql_fora SQL query for ex_fid_ary
+ * @var int start How many posts to skip in the search results (used for pagination)
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'total_results',
+ 'select',
+ 'sql_sort_table',
+ 'sql_sort_join',
+ 'sql_author',
+ 'topic_id',
+ 'sort_by_sql',
+ 'sort_key',
+ 'sort_dir',
+ 'sql_sort',
+ 'sort_days',
+ 'sql_time',
+ 'firstpost_only',
+ 'ex_fid_ary',
+ 'sql_fora',
+ 'start',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_native_author_count_query_before', compact($vars)));
+
// If the cache was completely empty count the results
if (!$total_results)
{
@@ -1078,7 +1191,7 @@ class fulltext_native extends \phpbb\search\base
// Count rows for the executed queries. Replace $select within $sql with SQL_CALC_FOUND_ROWS, and run it.
$sql_calc = str_replace('SELECT ' . $select, 'SELECT DISTINCT SQL_CALC_FOUND_ROWS p.post_id', $sql);
- $this->db->sql_query($sql_calc);
+ $result = $this->db->sql_query($sql_calc);
$this->db->sql_freeresult($result);
$sql_count = 'SELECT FOUND_ROWS() as total_results';
diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php
index 5a68f0cbfb..8fe80a39a3 100644
--- a/phpBB/phpbb/search/fulltext_postgres.php
+++ b/phpBB/phpbb/search/fulltext_postgres.php
@@ -56,6 +56,12 @@ class fulltext_postgres extends \phpbb\search\base
protected $db;
/**
+ * phpBB event dispatcher object
+ * @var \phpbb\event\dispatcher_interface
+ */
+ protected $phpbb_dispatcher;
+
+ /**
* User object
* @var \phpbb\user
*/
@@ -92,11 +98,13 @@ class fulltext_postgres extends \phpbb\search\base
* @param \phpbb\config\config $config Config object
* @param \phpbb\db\driver\driver_interface Database object
* @param \phpbb\user $user User object
+ * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object
*/
- public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user)
+ public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher)
{
$this->config = $config;
$this->db = $db;
+ $this->phpbb_dispatcher = $phpbb_dispatcher;
$this->user = $user;
$this->word_length = array('min' => $this->config['fulltext_postgres_min_word_len'], 'max' => $this->config['fulltext_postgres_max_word_len']);
@@ -409,6 +417,55 @@ class fulltext_postgres extends \phpbb\search\base
break;
}
+ $tsearch_query = $this->tsearch_query;
+
+ /**
+ * Allow changing the query used to search for posts using fulltext_postgres
+ *
+ * @event core.search_postgres_keywords_main_query_before
+ * @var string tsearch_query The parsed keywords used for this search
+ * @var int result_count The previous result count for the format of the query.
+ * Set to 0 to force a re-count
+ * @var bool join_topic Weather or not TOPICS_TABLE should be CROSS JOIN'ED
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @var string author_name An extra username to search on (!empty(author_ary) must be true, to be relevant)
+ * @var array ex_fid_ary Which forums not to search on
+ * @var int topic_id Limit the search to this topic_id only
+ * @var string sql_sort_table Extra tables to include in the SQL query.
+ * Used in conjunction with sql_sort_join
+ * @var string sql_sort_join SQL conditions to join all the tables used together.
+ * Used in conjunction with sql_sort_table
+ * @var int sort_days Time, in days, of the oldest possible post to list
+ * @var string sql_match Which columns to do the search on.
+ * @var string sql_match_where Extra conditions to use to properly filter the matching process
+ * @var string sort_by_sql The possible predefined sort types
+ * @var string sort_key The sort type used from the possible sort types
+ * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used
+ * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir
+ * @var int start How many posts to skip in the search results (used for pagination)
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'tsearch_query',
+ 'result_count',
+ 'join_topic',
+ 'author_ary',
+ 'author_name',
+ 'ex_fid_ary',
+ 'topic_id',
+ 'sql_sort_table',
+ 'sql_sort_join',
+ 'sort_days',
+ 'sql_match',
+ 'sql_match_where',
+ 'sort_by_sql',
+ 'sort_key',
+ 'sort_dir',
+ 'sql_sort',
+ 'start',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_keywords_main_query_before', compact($vars)));
+
$sql_select = ($type == 'posts') ? 'p.post_id' : 'DISTINCT t.topic_id';
$sql_from = ($join_topic) ? TOPICS_TABLE . ' t, ' : '';
$field = ($type == 'posts') ? 'post_id' : 'topic_id';
@@ -595,6 +652,55 @@ class fulltext_postgres extends \phpbb\search\base
$m_approve_fid_sql = ' AND ' . $post_visibility;
+ /**
+ * Allow changing the query used to search for posts by author in fulltext_postgres
+ *
+ * @event core.search_postgres_author_count_query_before
+ * @var int result_count The previous result count for the format of the query.
+ * Set to 0 to force a re-count
+ * @var string sql_sort_table CROSS JOIN'ed table to allow doing the sort chosen
+ * @var string sql_sort_join Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table
+ * @var array author_ary Array of user_id containing the users to filter the results to
+ * @var string author_name An extra username to search on
+ * @var string sql_author SQL WHERE condition for the post author ids
+ * @var int topic_id Limit the search to this topic_id only
+ * @var string sql_topic_id SQL of topic_id
+ * @var string sort_by_sql The possible predefined sort types
+ * @var string sort_key The sort type used from the possible sort types
+ * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used
+ * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir
+ * @var string sort_days Time, in days, that the oldest post showing can have
+ * @var string sql_time The SQL to search on the time specifyed by sort_days
+ * @var bool firstpost_only Wether or not to search only on the first post of the topics
+ * @var array ex_fid_ary Forum ids that must not be searched on
+ * @var array sql_fora SQL query for ex_fid_ary
+ * @var string m_approve_fid_sql WHERE clause condition on post_visibility restrictions
+ * @var int start How many posts to skip in the search results (used for pagination)
+ * @since 3.1.5-RC1
+ */
+ $vars = array(
+ 'result_count',
+ 'sql_sort_table',
+ 'sql_sort_join',
+ 'author_ary',
+ 'author_name',
+ 'sql_author',
+ 'topic_id',
+ 'sql_topic_id',
+ 'sort_by_sql',
+ 'sort_key',
+ 'sort_dir',
+ 'sql_sort',
+ 'sort_days',
+ 'sql_time',
+ 'firstpost_only',
+ 'ex_fid_ary',
+ 'sql_fora',
+ 'm_approve_fid_sql',
+ 'start',
+ );
+ extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_author_count_query_before', compact($vars)));
+
// Build the query for really selecting the post_ids
if ($type == 'posts')
{
diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php
index a5ad96b114..937292fd38 100644
--- a/phpBB/phpbb/search/fulltext_sphinx.php
+++ b/phpBB/phpbb/search/fulltext_sphinx.php
@@ -96,6 +96,12 @@ class fulltext_sphinx
protected $dbtype;
/**
+ * phpBB event dispatcher object
+ * @var \phpbb\event\dispatcher_interface
+ */
+ protected $phpbb_dispatcher;
+
+ /**
* User object
* @var \phpbb\user
*/
@@ -125,12 +131,14 @@ class fulltext_sphinx
* @param \phpbb\config\config $config Config object
* @param \phpbb\db\driver\driver_interface Database object
* @param \phpbb\user $user User object
+ * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object
*/
- public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user)
+ public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher)
{
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $phpEx;
$this->config = $config;
+ $this->phpbb_dispatcher = $phpbb_dispatcher;
$this->user = $user;
$this->db = $db;
$this->auth = $auth;
@@ -139,7 +147,7 @@ class fulltext_sphinx
global $phpbb_container; // TODO inject into object
$this->db_tools = $phpbb_container->get('dbal.tools');
- if(!$this->config['fulltext_sphinx_id'])
+ if (!$this->config['fulltext_sphinx_id'])
{
$this->config->set('fulltext_sphinx_id', unique_id());
}
diff --git a/phpBB/phpbb/template/twig/node/definenode.php b/phpBB/phpbb/template/twig/node/definenode.php
index c110785c4b..ddbd151d20 100644
--- a/phpBB/phpbb/template/twig/node/definenode.php
+++ b/phpBB/phpbb/template/twig/node/definenode.php
@@ -14,7 +14,6 @@
namespace phpbb\template\twig\node;
-
class definenode extends \Twig_Node
{
public function __construct($capture, \Twig_NodeInterface $name, \Twig_NodeInterface $value, $lineno, $tag = null)
diff --git a/phpBB/phpbb/template/twig/node/event.php b/phpBB/phpbb/template/twig/node/event.php
index 8fc4ba4775..b765bde98d 100644
--- a/phpBB/phpbb/template/twig/node/event.php
+++ b/phpBB/phpbb/template/twig/node/event.php
@@ -13,7 +13,6 @@
namespace phpbb\template\twig\node;
-
class event extends \Twig_Node
{
/**
diff --git a/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php b/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php
index 8c7f7b378d..2cd15d59da 100644
--- a/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php
+++ b/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php
@@ -13,7 +13,6 @@
namespace phpbb\template\twig\node\expression\binary;
-
class equalequal extends \Twig_Node_Expression_Binary
{
public function operator(\Twig_Compiler $compiler)
diff --git a/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php b/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php
index 2e95c68090..5f2908fb9b 100644
--- a/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php
+++ b/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php
@@ -13,7 +13,6 @@
namespace phpbb\template\twig\node\expression\binary;
-
class notequalequal extends \Twig_Node_Expression_Binary
{
public function operator(\Twig_Compiler $compiler)
diff --git a/phpBB/phpbb/template/twig/node/includenode.php b/phpBB/phpbb/template/twig/node/includenode.php
index 42428b6106..c36ac3c324 100644
--- a/phpBB/phpbb/template/twig/node/includenode.php
+++ b/phpBB/phpbb/template/twig/node/includenode.php
@@ -13,7 +13,6 @@
namespace phpbb\template\twig\node;
-
class includenode extends \Twig_Node_Include
{
/**
diff --git a/phpBB/phpbb/template/twig/node/includephp.php b/phpBB/phpbb/template/twig/node/includephp.php
index 659495fd9e..76182c2f84 100644
--- a/phpBB/phpbb/template/twig/node/includephp.php
+++ b/phpBB/phpbb/template/twig/node/includephp.php
@@ -14,7 +14,6 @@
namespace phpbb\template\twig\node;
-
class includephp extends \Twig_Node
{
/** @var \Twig_Environment */
diff --git a/phpBB/phpbb/template/twig/node/php.php b/phpBB/phpbb/template/twig/node/php.php
index 3a24513dca..4ee415e446 100644
--- a/phpBB/phpbb/template/twig/node/php.php
+++ b/phpBB/phpbb/template/twig/node/php.php
@@ -13,7 +13,6 @@
namespace phpbb\template\twig\node;
-
class php extends \Twig_Node
{
/** @var \Twig_Environment */
diff --git a/phpBB/phpbb/template/twig/tokenparser/defineparser.php b/phpBB/phpbb/template/twig/tokenparser/defineparser.php
index 2b88d61118..b755836ccd 100644
--- a/phpBB/phpbb/template/twig/tokenparser/defineparser.php
+++ b/phpBB/phpbb/template/twig/tokenparser/defineparser.php
@@ -14,7 +14,6 @@
namespace phpbb\template\twig\tokenparser;
-
class defineparser extends \Twig_TokenParser
{
/**
diff --git a/phpBB/phpbb/template/twig/tokenparser/event.php b/phpBB/phpbb/template/twig/tokenparser/event.php
index 4c7c8e07d9..f73ef4ae25 100644
--- a/phpBB/phpbb/template/twig/tokenparser/event.php
+++ b/phpBB/phpbb/template/twig/tokenparser/event.php
@@ -13,7 +13,6 @@
namespace phpbb\template\twig\tokenparser;
-
class event extends \Twig_TokenParser
{
/**
diff --git a/phpBB/phpbb/template/twig/tokenparser/includejs.php b/phpBB/phpbb/template/twig/tokenparser/includejs.php
index 4156048e42..4b67d2c468 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includejs.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includejs.php
@@ -13,7 +13,6 @@
namespace phpbb\template\twig\tokenparser;
-
class includejs extends \Twig_TokenParser
{
/**
diff --git a/phpBB/phpbb/template/twig/tokenparser/includeparser.php b/phpBB/phpbb/template/twig/tokenparser/includeparser.php
index 6ee78e5562..aa7236aaa6 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includeparser.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includeparser.php
@@ -14,7 +14,6 @@
namespace phpbb\template\twig\tokenparser;
-
class includeparser extends \Twig_TokenParser_Include
{
/**
diff --git a/phpBB/phpbb/template/twig/tokenparser/includephp.php b/phpBB/phpbb/template/twig/tokenparser/includephp.php
index c09f7729b0..3992636f8c 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includephp.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includephp.php
@@ -14,7 +14,6 @@
namespace phpbb\template\twig\tokenparser;
-
class includephp extends \Twig_TokenParser
{
/**
diff --git a/phpBB/phpbb/template/twig/tokenparser/php.php b/phpBB/phpbb/template/twig/tokenparser/php.php
index 557a70cca1..f11ce35896 100644
--- a/phpBB/phpbb/template/twig/tokenparser/php.php
+++ b/phpBB/phpbb/template/twig/tokenparser/php.php
@@ -13,7 +13,6 @@
namespace phpbb\template\twig\tokenparser;
-
class php extends \Twig_TokenParser
{
/**
diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php
index 9576abe1f0..e07a1b52ca 100644
--- a/phpBB/phpbb/textformatter/s9e/factory.php
+++ b/phpBB/phpbb/textformatter/s9e/factory.php
@@ -68,7 +68,7 @@ class factory implements \phpbb\textformatter\cache_interface
'b' => '[B]{TEXT}[/B]',
'code' => '[CODE]{TEXT}[/CODE]',
'color' => '[COLOR={COLOR}]{TEXT}[/COLOR]',
- 'email' => '[EMAIL={EMAIL;useContent}]{TEXT}[/EMAIL]',
+ 'email' => '[EMAIL={EMAIL;useContent} subject={TEXT;optional;postFilter=rawurlencode} body={TEXT;optional;postFilter=rawurlencode}]{TEXT}[/EMAIL]',
'flash' => '[FLASH={NUMBER1},{NUMBER2} width={NUMBER1;postFilter=#flashwidth} height={NUMBER2;postFilter=#flashheight} url={URL;useContent} /]',
'i' => '[I]{TEXT}[/I]',
'img' => '[IMG src={IMAGEURL;useContent}]',
@@ -97,7 +97,18 @@ class factory implements \phpbb\textformatter\cache_interface
'img' => '<img src="{IMAGEURL}" alt="{L_IMAGE}"/>',
'size' => '<span style="font-size: {FONTSIZE}%; line-height: normal"><xsl:apply-templates/></span>',
'color' => '<span style="color: {COLOR}"><xsl:apply-templates/></span>',
- 'email' => '<a href="mailto:{EMAIL}"><xsl:apply-templates/></a>',
+ 'email' => '<a>
+ <xsl:attribute name="href">
+ <xsl:text>mailto:</xsl:text>
+ <xsl:value-of select="@email"/>
+ <xsl:if test="@subject or @body">
+ <xsl:text>?</xsl:text>
+ <xsl:if test="@subject">subject=<xsl:value-of select="@subject"/></xsl:if>
+ <xsl:if test="@body"><xsl:if test="@subject">&amp;</xsl:if>body=<xsl:value-of select="@body"/></xsl:if>
+ </xsl:if>
+ </xsl:attribute>
+ <xsl:apply-templates/>
+ </a>',
);
/**
diff --git a/phpBB/phpbb/tree/nestedset.php b/phpBB/phpbb/tree/nestedset.php
index 57d109652e..8490c7c299 100644
--- a/phpBB/phpbb/tree/nestedset.php
+++ b/phpBB/phpbb/tree/nestedset.php
@@ -837,7 +837,10 @@ abstract class nestedset implements \phpbb\tree\tree_interface
' . $this->get_sql_where('AND') . '
ORDER BY ' . $this->column_left_id . ', ' . $this->column_item_id . ' ASC';
$result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
+ $rows = $this->db->sql_fetchrowset($result);
+ $this->db->sql_freeresult($result);
+
+ foreach ($rows as $row)
{
// First we update the left_id for this module
if ($row[$this->column_left_id] != $new_id)
@@ -862,7 +865,6 @@ abstract class nestedset implements \phpbb\tree\tree_interface
}
$new_id++;
}
- $this->db->sql_freeresult($result);
if ($acquired_new_lock)
{
diff --git a/phpBB/phpbb/user_loader.php b/phpBB/phpbb/user_loader.php
index 0b192e4452..cdd28329db 100644
--- a/phpBB/phpbb/user_loader.php
+++ b/phpBB/phpbb/user_loader.php
@@ -179,9 +179,10 @@ class user_loader
* @param bool $query Should we query the database if this user has not yet been loaded?
* Typically this should be left as false and you should make sure
* you load users ahead of time with load_users()
+ * @param bool @lazy If true, will be lazy loaded (requires JS)
* @return string
*/
- public function get_avatar($user_id, $query = false)
+ public function get_avatar($user_id, $query = false, $lazy = false)
{
if (!($user = $this->get_user($user_id, $query)))
{
@@ -195,7 +196,7 @@ class user_loader
'avatar_height' => $user['user_avatar_height'],
);
- return phpbb_get_avatar($row, 'USER_AVATAR');
+ return phpbb_get_avatar($row, 'USER_AVATAR', false, $lazy);
}
/**
diff --git a/phpBB/posting.php b/phpBB/posting.php
index 1c7b756fc2..ed6a9713e7 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -35,7 +35,6 @@ $forum_id = $request->variable('f', 0);
$draft_id = $request->variable('d', 0);
$lastclick = $request->variable('lastclick', 0);
-$submit = (isset($_POST['post'])) ? true : false;
$preview = (isset($_POST['preview'])) ? true : false;
$save = (isset($_POST['save'])) ? true : false;
$load = (isset($_POST['load'])) ? true : false;
@@ -43,6 +42,7 @@ $confirm = $request->is_set_post('confirm');
$cancel = (isset($_POST['cancel']) && !isset($_POST['save'])) ? true : false;
$refresh = (isset($_POST['add_file']) || isset($_POST['delete_file']) || isset($_POST['cancel_unglobalise']) || $save || $load || $preview);
+$submit = $request->is_set_post('post') && !$refresh && !$preview;
$mode = $request->variable('mode', '');
// If the user is not allowed to delete the post, we try to soft delete it, so we overwrite the mode here.
@@ -1245,6 +1245,7 @@ if ($submit || $preview || $refresh)
*
* @event core.posting_modify_submission_errors
* @var array post_data Array with post data
+ * @var array poll Array with poll data from post (must be used instead of the post_data equivalent)
* @var string mode What action to take if the form is submitted
* post|reply|quote|edit|delete|bump|smilies|popup
* @var string page_title Title of the mode page
@@ -1255,9 +1256,11 @@ if ($submit || $preview || $refresh)
* @var array error Any error strings; a non-empty array aborts form submission.
* NOTE: Should be actual language strings, NOT language keys.
* @since 3.1.0-RC5
+ * @change 3.1.5-RC1 Added poll array to the event
*/
$vars = array(
'post_data',
+ 'poll',
'mode',
'page_title',
'post_id',
@@ -1487,14 +1490,11 @@ if (!sizeof($error) && $preview)
// Signature
if ($post_data['enable_sig'] && $config['allow_sig'] && $preview_signature && $auth->acl_get('f_sigs', $forum_id))
{
- $parse_sig = new parse_message($preview_signature);
- $parse_sig->bbcode_uid = $preview_signature_uid;
- $parse_sig->bbcode_bitfield = $preview_signature_bitfield;
-
- // Not sure about parameters for bbcode/smilies/urls... in signatures
- $parse_sig->format_display($config['allow_sig_bbcode'], $config['allow_sig_links'], $config['allow_sig_smilies']);
- $preview_signature = $parse_sig->message;
- unset($parse_sig);
+ $flags = ($config['allow_sig_bbcode']) ? OPTION_FLAG_BBCODE : 0;
+ $flags |= ($config['allow_sig_links']) ? OPTION_FLAG_LINKS : 0;
+ $flags |= ($config['allow_sig_smilies']) ? OPTION_FLAG_SMILIES : 0;
+
+ $preview_signature = generate_text_for_display($preview_signature, $preview_signature_uid, $preview_signature_bitfield, $flags, false);
}
else
{
@@ -1816,6 +1816,30 @@ $page_data = array(
'S_IN_POSTING' => true,
);
+// Build custom bbcodes array
+display_custom_bbcodes();
+
+// Poll entry
+if (($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']/* && (!$post_data['poll_last_vote'] || $auth->acl_get('m_edit', $forum_id))*/))
+ && $auth->acl_get('f_poll', $forum_id))
+{
+ $page_data = array_merge($page_data, array(
+ 'S_SHOW_POLL_BOX' => true,
+ 'S_POLL_VOTE_CHANGE' => ($auth->acl_get('f_votechg', $forum_id) && $auth->acl_get('f_vote', $forum_id)),
+ 'S_POLL_DELETE' => ($mode == 'edit' && sizeof($post_data['poll_options']) && ((!$post_data['poll_last_vote'] && $post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id)) || $auth->acl_get('m_delete', $forum_id))),
+ 'S_POLL_DELETE_CHECKED' => (!empty($poll_delete)) ? true : false,
+
+ 'L_POLL_OPTIONS_EXPLAIN' => $user->lang('POLL_OPTIONS_' . (($mode == 'edit') ? 'EDIT_' : '') . 'EXPLAIN', (int) $config['max_poll_options']),
+
+ 'VOTE_CHANGE_CHECKED' => (!empty($post_data['poll_vote_change'])) ? ' checked="checked"' : '',
+ 'POLL_TITLE' => (isset($post_data['poll_title'])) ? $post_data['poll_title'] : '',
+ 'POLL_OPTIONS' => (!empty($post_data['poll_options'])) ? implode("\n", $post_data['poll_options']) : '',
+ 'POLL_MAX_OPTIONS' => (isset($post_data['poll_max_options'])) ? (int) $post_data['poll_max_options'] : 1,
+ 'POLL_LENGTH' => $post_data['poll_length'],
+ )
+ );
+}
+
/**
* This event allows you to modify template variables for the posting screen
*
@@ -1854,6 +1878,7 @@ $page_data = array(
* 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
+* @change 3.1.5-RC1 Added poll variables to the page_data array
*/
$vars = array(
'post_data',
@@ -1882,29 +1907,6 @@ extract($phpbb_dispatcher->trigger_event('core.posting_modify_template_vars', co
// Start assigning vars for main posting page ...
$template->assign_vars($page_data);
-// Build custom bbcodes array
-display_custom_bbcodes();
-
-// Poll entry
-if (($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']/* && (!$post_data['poll_last_vote'] || $auth->acl_get('m_edit', $forum_id))*/))
- && $auth->acl_get('f_poll', $forum_id))
-{
- $template->assign_vars(array(
- 'S_SHOW_POLL_BOX' => true,
- 'S_POLL_VOTE_CHANGE' => ($auth->acl_get('f_votechg', $forum_id) && $auth->acl_get('f_vote', $forum_id)),
- 'S_POLL_DELETE' => ($mode == 'edit' && sizeof($post_data['poll_options']) && ((!$post_data['poll_last_vote'] && $post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id)) || $auth->acl_get('m_delete', $forum_id))),
- 'S_POLL_DELETE_CHECKED' => (!empty($poll_delete)) ? true : false,
-
- 'L_POLL_OPTIONS_EXPLAIN' => $user->lang('POLL_OPTIONS_' . (($mode == 'edit') ? 'EDIT_' : '') . 'EXPLAIN', (int) $config['max_poll_options']),
-
- 'VOTE_CHANGE_CHECKED' => (!empty($post_data['poll_vote_change'])) ? ' checked="checked"' : '',
- 'POLL_TITLE' => (isset($post_data['poll_title'])) ? $post_data['poll_title'] : '',
- 'POLL_OPTIONS' => (!empty($post_data['poll_options'])) ? implode("\n", $post_data['poll_options']) : '',
- 'POLL_MAX_OPTIONS' => (isset($post_data['poll_max_options'])) ? (int) $post_data['poll_max_options'] : 1,
- 'POLL_LENGTH' => $post_data['poll_length'])
- );
-}
-
// Show attachment box for adding attachments if true
$allowed = ($auth->acl_get('f_attach', $forum_id) && $auth->acl_get('u_attach') && $config['allow_attachments'] && $form_enctype);
diff --git a/phpBB/search.php b/phpBB/search.php
index 053492fda0..6bdac290d6 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -277,7 +277,7 @@ if ($keywords || $author || $author_id || $search_id || $submit)
}
// We do some additional checks in the module to ensure it can actually be utilised
$error = false;
- $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
+ $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
if ($error)
{
diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js
index 168efff4b4..76c605dd19 100644
--- a/phpBB/styles/prosilver/template/ajax.js
+++ b/phpBB/styles/prosilver/template/ajax.js
@@ -9,9 +9,9 @@ phpbb.addAjaxCallback('mark_forums_read', function(res) {
var readTitle = res.NO_UNREAD_POSTS;
var unreadTitle = res.UNREAD_POSTS;
var iconsArray = {
- 'forum_unread': 'forum_read',
- 'forum_unread_subforum': 'forum_read_subforum',
- 'forum_unread_locked': 'forum_read_locked'
+ forum_unread: 'forum_read',
+ forum_unread_subforum: 'forum_read_subforum',
+ forum_unread_locked: 'forum_read_locked'
};
$('li.row').find('dl[class*="forum_unread"]').each(function() {
@@ -39,20 +39,20 @@ phpbb.addAjaxCallback('mark_forums_read', function(res) {
phpbb.closeDarkenWrapper(3000);
});
-/**
+/**
* This callback will mark all topic icons read
*
-* @param update_topic_links bool Whether "Mark topics read" links should be
-* updated. Defaults to true.
+* @param {bool} [update_topic_links=true] Whether "Mark topics read" links
+* should be updated. Defaults to true.
*/
phpbb.addAjaxCallback('mark_topics_read', function(res, updateTopicLinks) {
var readTitle = res.NO_UNREAD_POSTS;
var unreadTitle = res.UNREAD_POSTS;
var iconsArray = {
- 'global_unread': 'global_read',
- 'announce_unread': 'announce_read',
- 'sticky_unread': 'sticky_read',
- 'topic_unread': 'topic_read'
+ global_unread: 'global_read',
+ announce_unread: 'announce_read',
+ sticky_unread: 'sticky_read',
+ topic_unread: 'topic_read'
};
var iconsState = ['', '_hot', '_hot_mine', '_locked', '_locked_mine', '_mine'];
var unreadClassSelectors;
@@ -138,9 +138,9 @@ phpbb.markNotifications = function($popup, unreadCount) {
}
// Update page title
- $('title').text(
- (unreadCount ? '(' + unreadCount + ')' : '') + $('title').text().replace(/(\(([0-9])\))/, '')
- );
+ var $title = $('title');
+ var originalTitle = $title.text().replace(/(\((\d+)\))/, '');
+ $title.text((unreadCount ? '(' + unreadCount + ')' : '') + originalTitle);
};
// This callback finds the post from the delete link, and removes it.
@@ -205,7 +205,7 @@ phpbb.addAjaxCallback('vote_poll', function(res) {
// Set min-height to prevent the page from jumping when the content changes
var updatePanelHeight = function (height) {
- var height = (typeof height === 'undefined') ? panel.find('.inner').outerHeight() : height;
+ height = (typeof height === 'undefined') ? panel.find('.inner').outerHeight() : height;
panel.css('min-height', height);
};
updatePanelHeight();
@@ -223,7 +223,7 @@ phpbb.addAjaxCallback('vote_poll', function(res) {
// If the user can still vote, simply slide down the results
poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500);
}
-
+
// Get the votes count of the highest poll option
poll.find('[data-poll-option-id]').each(function() {
var option = $(this);
@@ -252,7 +252,7 @@ phpbb.addAjaxCallback('vote_poll', function(res) {
var newBarClass = (percent === 100) ? 'pollbar5' : 'pollbar' + (Math.floor(percent / 20) + 1);
setTimeout(function () {
- bar.animate({width: percentRel + '%'}, 500)
+ bar.animate({ width: percentRel + '%' }, 500)
.removeClass('pollbar1 pollbar2 pollbar3 pollbar4 pollbar5')
.addClass(newBarClass)
.html(res.vote_counts[optionId]);
@@ -287,10 +287,10 @@ phpbb.addAjaxCallback('vote_poll', function(res) {
var panelHeight = panel.height();
var innerHeight = panel.find('.inner').outerHeight();
- if (panelHeight != innerHeight) {
- panel.css({'min-height': '', 'height': panelHeight})
- .animate({height: innerHeight}, time, function () {
- panel.css({'min-height': innerHeight, 'height': ''});
+ if (panelHeight !== innerHeight) {
+ panel.css({ minHeight: '', height: panelHeight })
+ .animate({ height: innerHeight }, time, function () {
+ panel.css({ minHeight: innerHeight, height: '' });
});
}
};
@@ -377,8 +377,9 @@ $('#member_search').click(function () {
* Automatically resize textarea
*/
$(function() {
- phpbb.resizeTextArea($('textarea:not(#message-box textarea, .no-auto-resize)'), {minHeight: 75, maxHeight: 250});
- phpbb.resizeTextArea($('#message-box textarea'));
+ var $textarea = $('textarea:not(#message-box textarea, .no-auto-resize)');
+ phpbb.resizeTextArea($textarea, { minHeight: 75, maxHeight: 250 });
+ phpbb.resizeTextArea($('textarea', '#message-box'));
});
diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js
index 7a377a4973..ccedf19604 100644
--- a/phpBB/styles/prosilver/template/forum_fn.js
+++ b/phpBB/styles/prosilver/template/forum_fn.js
@@ -1,3 +1,5 @@
+/* global phpbb */
+
/**
* phpBB3 forum functions
*/
@@ -37,7 +39,7 @@ function pageJump(item) {
baseUrl = item.attr('data-base-url'),
startName = item.attr('data-start-name');
- if (page !== null && !isNaN(page) && page == Math.floor(page) && page > 0) {
+ if (page !== null && !isNaN(page) && page === Math.floor(page) && page > 0) {
if (baseUrl.indexOf('?') === -1) {
document.location.href = baseUrl + '?' + startName + '=' + ((page - 1) * perPage);
} else {
@@ -124,7 +126,7 @@ function activateSubPanel(p, panels) {
var i, showPanel;
- if (typeof(p) === 'string') {
+ if (typeof p === 'string') {
showPanel = p;
}
$('input[name="show_panel"]').val(showPanel);
@@ -277,8 +279,7 @@ jQuery(function($) {
/**
* Functions for user search popup
*/
-function insertUser(formId, value)
-{
+function insertUser(formId, value) {
'use strict';
var $form = jQuery(formId),
@@ -286,7 +287,7 @@ function insertUser(formId, value)
fieldName = $form.attr('data-field-name'),
item = opener.document.forms[formName][fieldName];
- if (item.value.length && item.type == 'textarea') {
+ if (item.value.length && item.type === 'textarea') {
value = item.value + '\n' + value;
}
@@ -319,7 +320,7 @@ function parseDocument($container) {
'use strict';
var test = document.createElement('div'),
- oldBrowser = (typeof test.style.borderRadius == 'undefined'),
+ oldBrowser = (typeof test.style.borderRadius === 'undefined'),
$body = $('body');
/**
@@ -359,7 +360,10 @@ function parseDocument($container) {
*/
if (oldBrowser) {
// Fix .linklist.bulletin lists
- $container.find('ul.linklist.bulletin > li:first-child, ul.linklist.bulletin > li.rightside:last-child').addClass('no-bulletin');
+ $container
+ .find('ul.linklist.bulletin > li')
+ .filter(':first-child, .rightside:last-child')
+ .addClass('no-bulletin');
}
/**
@@ -420,12 +424,12 @@ function parseDocument($container) {
width;
// Test max-width set in code for .navlinks above
- width = parseInt($this.css('max-width'));
+ width = parseInt($this.css('max-width'), 10);
if (!width) {
- width = $body.width();
+ width = $body.width();
}
- maxHeight = parseInt($this.css('line-height'));
+ maxHeight = parseInt($this.css('line-height'), 10);
$links.each(function() {
if ($(this).height() > 0) {
maxHeight = Math.max(maxHeight, $(this).outerHeight(true));
@@ -452,8 +456,8 @@ function parseDocument($container) {
return;
}
- for (var i = 0; i < classesLength; i ++) {
- for (var j = length - 1; j >= 0; j --) {
+ for (var i = 0; i < classesLength; i++) {
+ for (var j = length - 1; j >= 0; j--) {
$links.eq(j).addClass('wrapped ' + classes[i]);
if ($this.height() <= maxHeight) {
return;
@@ -470,7 +474,9 @@ function parseDocument($container) {
/**
* Responsive link lists
*/
- $container.find('.linklist:not(.navlinks, [data-skip-responsive]), .postbody .post-buttons:not([data-skip-responsive])').each(function() {
+ var selector = '.linklist:not(.navlinks, [data-skip-responsive]),' +
+ '.postbody .post-buttons:not([data-skip-responsive])';
+ $container.find(selector).each(function() {
var $this = $(this),
filterSkip = '.breadcrumbs, [data-skip-responsive]',
filterLast = '.edit-icon, .quote-icon, [data-last-responsive]',
@@ -478,7 +484,7 @@ function parseDocument($container) {
$linksNotSkip = $linksAll.not(filterSkip), // All items that can potentially be hidden
$linksFirst = $linksNotSkip.not(filterLast), // The items that will be hidden first
$linksLast = $linksNotSkip.filter(filterLast), // The items that will be hidden last
- persistent = $this.attr('id') == 'nav-main', // Does this list already have a menu (such as quick-links)?
+ persistent = $this.attr('id') === 'nav-main', // Does this list already have a menu (such as quick-links)?
html = '<li class="responsive-menu hidden"><a href="javascript:void(0);" class="responsive-menu-link">&nbsp;</a><div class="dropdown hidden"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>',
slack = 3; // Vertical slack space (in pixels). Determines how sensitive the script is in determining whether a line-break has occured.
@@ -675,7 +681,7 @@ function parseDocument($container) {
$children = column.children(),
html = column.html();
- if ($children.length == 1 && $children.text() == column.text()) {
+ if ($children.length === 1 && $children.text() === column.text()) {
html = $children.html();
}
@@ -717,8 +723,7 @@ function parseDocument($container) {
if (!$block.length) {
$this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />');
$block = $this.find('dt .responsive-show:last-child');
- }
- else {
+ } else {
first = ($.trim($block.text()).length === 0);
}
@@ -728,7 +733,7 @@ function parseDocument($container) {
children = column.children(),
html = column.html();
- if (children.length == 1 && children.text() == column.text()) {
+ if (children.length === 1 && children.text() === column.text()) {
html = children.html();
}
@@ -757,7 +762,7 @@ function parseDocument($container) {
// Find each header
$th.each(function(column) {
var cell = $(this),
- colspan = parseInt(cell.attr('colspan')),
+ colspan = parseInt(cell.attr('colspan'), 10),
dfn = cell.attr('data-dfn'),
text = dfn ? dfn : cell.text();
@@ -788,14 +793,14 @@ function parseDocument($container) {
cells = row.children('td'),
column = 0;
- if (cells.length == 1) {
+ if (cells.length === 1) {
row.addClass('big-column');
return;
}
cells.each(function() {
var cell = $(this),
- colspan = parseInt(cell.attr('colspan')),
+ colspan = parseInt(cell.attr('colspan'), 10),
text = $.trim(cell.text());
if (headersLength <= column) {
@@ -871,19 +876,26 @@ function parseDocument($container) {
total = $availableTabs.length,
i, $tab;
- for (i = total - 1; i >= 0; i --) {
+ for (i = total - 1; i >= 0; i--) {
$tab = $availableTabs.eq(i);
$menu.prepend($tab.clone(true).removeClass('tab'));
$tab.hide();
if ($this.height() <= maxHeight) {
- $menu.find('a').click(function() { check(true); });
+ $menu.find('a').click(function() {
+ check(true);
+ });
return;
}
}
- $menu.find('a').click(function() { check(true); });
+ $menu.find('a').click(function() {
+ check(true);
+ });
}
- phpbb.registerDropdown($item.find('a.responsive-tab-link'), $item.find('.dropdown'), {visibleClass: 'activetab'});
+ var $tabLink = $item.find('a.responsive-tab-link');
+ phpbb.registerDropdown($tabLink, $item.find('.dropdown'), {
+ visibleClass: 'activetab'
+ });
check(true);
$(window).resize(check);
diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html
index 5ac2d2aca3..ec5bf35476 100644
--- a/phpBB/styles/prosilver/template/index_body.html
+++ b/phpBB/styles/prosilver/template/index_body.html
@@ -20,7 +20,7 @@
<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>
<fieldset class="quick-login">
<label for="username"><span>{L_USERNAME}{L_COLON}</span> <input type="text" tabindex="1" name="username" id="username" size="10" class="inputbox" title="{L_USERNAME}" /></label>
- <label for="password"><span>{L_PASSWORD}{L_COLON}</span> <input type="password" tabindex="2" name="password" id="password" size="10" class="inputbox" title="{L_PASSWORD}" /></label>
+ <label for="password"><span>{L_PASSWORD}{L_COLON}</span> <input type="password" tabindex="2" name="password" id="password" size="10" class="inputbox" title="{L_PASSWORD}" autocomplete="off" /></label>
<!-- IF U_SEND_PASSWORD -->
<a href="{U_SEND_PASSWORD}">{L_FORGOT_PASS}</a>
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/login_body.html b/phpBB/styles/prosilver/template/login_body.html
index c852ffd5f2..ef08035717 100644
--- a/phpBB/styles/prosilver/template/login_body.html
+++ b/phpBB/styles/prosilver/template/login_body.html
@@ -15,7 +15,7 @@
</dl>
<dl>
<dt><label for="{PASSWORD_CREDENTIAL}">{L_PASSWORD}{L_COLON}</label></dt>
- <dd><input type="password" tabindex="2" id="{PASSWORD_CREDENTIAL}" name="{PASSWORD_CREDENTIAL}" size="25" class="inputbox autowidth" /></dd>
+ <dd><input type="password" tabindex="2" id="{PASSWORD_CREDENTIAL}" name="{PASSWORD_CREDENTIAL}" size="25" class="inputbox autowidth" autocomplete="off" /></dd>
<!-- IF S_DISPLAY_FULL_LOGIN and (U_SEND_PASSWORD or U_RESEND_ACTIVATION) -->
<!-- IF U_SEND_PASSWORD --><dd><a href="{U_SEND_PASSWORD}">{L_FORGOT_PASS}</a></dd><!-- ENDIF -->
<!-- IF U_RESEND_ACTIVATION --><dd><a href="{U_RESEND_ACTIVATION}">{L_RESEND_ACTIVATION}</a></dd><!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/login_forum.html b/phpBB/styles/prosilver/template/login_forum.html
index 18a95c0a8f..7fa9736a96 100644
--- a/phpBB/styles/prosilver/template/login_forum.html
+++ b/phpBB/styles/prosilver/template/login_forum.html
@@ -22,7 +22,7 @@
<dl>
<dt><label for="password">{L_PASSWORD}{L_COLON}</label></dt>
- <dd><input type="password" tabindex="1" id="password" name="password" size="25" class="inputbox narrow" /></dd>
+ <dd><input type="password" tabindex="1" id="password" name="password" size="25" class="inputbox narrow" autocomplete="off" /></dd>
</dl>
{S_LOGIN_REDIRECT}
<dl>
diff --git a/phpBB/styles/prosilver/template/mcp_post.html b/phpBB/styles/prosilver/template/mcp_post.html
index 10ec6f3ea9..81d1be795e 100644
--- a/phpBB/styles/prosilver/template/mcp_post.html
+++ b/phpBB/styles/prosilver/template/mcp_post.html
@@ -144,7 +144,7 @@
</div>
</div>
-<!-- IF S_CAN_LOCK_POST or S_CAN_DELETE_POST or S_CAN_CHGPOSTER -->
+<!-- IF S_CAN_LOCK_POST or S_CAN_DELETE_POST or S_CAN_CHGPOSTER or S_MCP_POST_ADDITIONAL_OPTS -->
<div class="panel">
<div class="inner">
@@ -168,6 +168,8 @@
</form>
<!-- ENDIF -->
+ <!-- EVENT mcp_post_additional_options -->
+
<!-- IF S_CAN_LOCK_POST or S_CAN_DELETE_POST -->
<form method="post" id="mcp" action="{U_MCP_ACTION}">
diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html
index 8749ce60e8..ecba72f6f4 100644
--- a/phpBB/styles/prosilver/template/overall_footer.html
+++ b/phpBB/styles/prosilver/template/overall_footer.html
@@ -18,7 +18,6 @@
<div id="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}" data-ajax-error-text-abort="{L_AJAX_ERROR_TEXT_ABORT}" data-ajax-error-text-timeout="{L_AJAX_ERROR_TEXT_TIMEOUT}" data-ajax-error-text-parsererror="{L_AJAX_ERROR_TEXT_PARSERERROR}">
<div id="darken">&nbsp;</div>
</div>
- <div id="loading_indicator"></div>
<div id="phpbb_alert" class="phpbb_alert" data-l-err="{L_ERROR}" data-l-timeout-processing-req="{L_TIMEOUT_PROCESSING_REQ}">
<a href="#" class="alert_close"></a>
diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html
index 4e2013e276..2b2036883b 100644
--- a/phpBB/styles/prosilver/template/overall_header.html
+++ b/phpBB/styles/prosilver/template/overall_header.html
@@ -7,17 +7,17 @@
<title><!-- IF UNREAD_NOTIFICATIONS_COUNT -->({UNREAD_NOTIFICATIONS_COUNT}) <!-- ENDIF --><!-- IF not S_VIEWTOPIC and not S_VIEWFORUM -->{SITENAME} - <!-- ENDIF --><!-- IF S_IN_MCP -->{L_MCP} - <!-- ELSEIF S_IN_UCP -->{L_UCP} - <!-- ENDIF -->{PAGE_TITLE}<!-- IF S_VIEWTOPIC or S_VIEWFORUM --> - {SITENAME}<!-- ENDIF --></title>
<!-- IF S_ENABLE_FEEDS -->
- <!-- IF S_ENABLE_FEEDS_OVERALL --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {SITENAME}" href="{U_FEED}" /><!-- ENDIF -->
- <!-- IF S_ENABLE_FEEDS_NEWS --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FEED_NEWS}" href="{U_FEED}?mode=news" /><!-- ENDIF -->
- <!-- IF S_ENABLE_FEEDS_FORUMS --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_ALL_FORUMS}" href="{U_FEED}?mode=forums" /><!-- ENDIF -->
- <!-- IF S_ENABLE_FEEDS_TOPICS --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FEED_TOPICS_NEW}" href="{U_FEED}?mode=topics" /><!-- ENDIF -->
- <!-- IF S_ENABLE_FEEDS_TOPICS_ACTIVE --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FEED_TOPICS_ACTIVE}" href="{U_FEED}?mode=topics_active" /><!-- ENDIF -->
- <!-- IF S_ENABLE_FEEDS_FORUM and S_FORUM_ID --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FORUM} - {FORUM_NAME}" href="{U_FEED}?f={S_FORUM_ID}" /><!-- ENDIF -->
- <!-- IF S_ENABLE_FEEDS_TOPIC and S_TOPIC_ID --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_TOPIC} - {TOPIC_TITLE}" href="{U_FEED}?f={S_FORUM_ID}&amp;t={S_TOPIC_ID}" /><!-- ENDIF -->
+ <!-- IF S_ENABLE_FEEDS_OVERALL --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {SITENAME}" href="{U_FEED}"><!-- ENDIF -->
+ <!-- IF S_ENABLE_FEEDS_NEWS --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FEED_NEWS}" href="{U_FEED}?mode=news"><!-- ENDIF -->
+ <!-- IF S_ENABLE_FEEDS_FORUMS --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_ALL_FORUMS}" href="{U_FEED}?mode=forums"><!-- ENDIF -->
+ <!-- IF S_ENABLE_FEEDS_TOPICS --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FEED_TOPICS_NEW}" href="{U_FEED}?mode=topics"><!-- ENDIF -->
+ <!-- IF S_ENABLE_FEEDS_TOPICS_ACTIVE --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FEED_TOPICS_ACTIVE}" href="{U_FEED}?mode=topics_active"><!-- ENDIF -->
+ <!-- IF S_ENABLE_FEEDS_FORUM and S_FORUM_ID --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FORUM} - {FORUM_NAME}" href="{U_FEED}?f={S_FORUM_ID}"><!-- ENDIF -->
+ <!-- IF S_ENABLE_FEEDS_TOPIC and S_TOPIC_ID --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_TOPIC} - {TOPIC_TITLE}" href="{U_FEED}?f={S_FORUM_ID}&amp;t={S_TOPIC_ID}"><!-- ENDIF -->
<!-- ENDIF -->
<!-- IF U_CANONICAL -->
- <link rel="canonical" href="{U_CANONICAL}" />
+ <link rel="canonical" href="{U_CANONICAL}">
<!-- ENDIF -->
<!--
@@ -45,7 +45,7 @@
<!-- ENDIF -->
<link href="{T_STYLESHEET_LINK}" rel="stylesheet">
<link href="{T_STYLESHEET_LANG_LINK}" rel="stylesheet">
-<link href="{T_THEME_PATH}/responsive.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" media="all and (max-width: 700px), all and (max-device-width: 700px)" />
+<link href="{T_THEME_PATH}/responsive.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" media="all and (max-width: 700px), all and (max-device-width: 700px)">
<!-- IF S_CONTENT_DIRECTION eq 'rtl' -->
<link href="{T_THEME_PATH}/bidi.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">
diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html
index ab4f855a97..637ac59465 100644
--- a/phpBB/styles/prosilver/template/simple_header.html
+++ b/phpBB/styles/prosilver/template/simple_header.html
@@ -6,18 +6,32 @@
{META}
<title>{SITENAME} &bull; <!-- IF S_IN_MCP -->{L_MCP} &bull; <!-- ELSEIF S_IN_UCP -->{L_UCP} &bull; <!-- ENDIF -->{PAGE_TITLE}</title>
-<link href="{T_THEME_PATH}/print.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="print" title="printonly" />
-<!-- IF S_ALLOW_CDN --><link href="//fonts.googleapis.com/css?family=Open+Sans:600&amp;subset=latin,cyrillic-ext,latin-ext,cyrillic,greek-ext,greek,vietnamese" rel="stylesheet" type="text/css" media="screen, projection" /><!-- ENDIF -->
-<link href="{T_STYLESHEET_LINK}" rel="stylesheet" type="text/css" media="screen, projection" />
-<link href="{T_STYLESHEET_LANG_LINK}" rel="stylesheet" type="text/css" media="screen, projection" />
-<link href="{T_THEME_PATH}/responsive.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="only screen and (max-width: 700px), only screen and (max-device-width: 700px)" />
+<!-- IF S_ALLOW_CDN -->
+<script>
+ WebFontConfig = {
+ google: {
+ families: ['Open Sans:n6']
+ }
+ };
+
+ (function(d) {
+ var wf = d.createElement('script'), s = d.scripts[0];
+ wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js';
+ wf.async = true;
+ s.parentNode.insertBefore(wf, s);
+ })(document);
+</script>
+<!-- ENDIF -->
+<link href="{T_STYLESHEET_LINK}" rel="stylesheet">
+<link href="{T_STYLESHEET_LANG_LINK}" rel="stylesheet">
+<link href="{T_THEME_PATH}/responsive.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" media="only screen and (max-width: 700px), only screen and (max-device-width: 700px)">
<!-- IF S_CONTENT_DIRECTION eq 'rtl' -->
- <link href="{T_THEME_PATH}/bidi.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" />
+ <link href="{T_THEME_PATH}/bidi.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">
<!-- ENDIF -->
<!--[if lte IE 8]>
- <link href="{T_THEME_PATH}/tweaks.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" />
+ <link href="{T_THEME_PATH}/tweaks.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">
<![endif]-->
<!-- DEFINE $POPUP = 1 -->
diff --git a/phpBB/styles/prosilver/template/ucp_login_link.html b/phpBB/styles/prosilver/template/ucp_login_link.html
index d3c6931ce3..be173318cb 100644
--- a/phpBB/styles/prosilver/template/ucp_login_link.html
+++ b/phpBB/styles/prosilver/template/ucp_login_link.html
@@ -36,7 +36,7 @@
</dl>
<dl>
<dt><label for="{PASSWORD_CREDENTIAL}">{L_PASSWORD}{L_COLON}</label></dt>
- <dd><input type="password" tabindex="3" id="{PASSWORD_CREDENTIAL}" name="{PASSWORD_CREDENTIAL}" size="25" class="inputbox autowidth" /></dd>
+ <dd><input type="password" tabindex="3" id="{PASSWORD_CREDENTIAL}" name="{PASSWORD_CREDENTIAL}" size="25" class="inputbox autowidth" autocomplete="off" /></dd>
</dl>
<!-- IF CAPTCHA_TEMPLATE and S_CONFIRM_CODE -->
<!-- DEFINE $CAPTCHA_TAB_INDEX = 4 -->
diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html
index 7fe0d67077..55d81b4e69 100644
--- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html
+++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html
@@ -6,7 +6,7 @@
{META}
<title>{SITENAME} &bull; {PAGE_TITLE}</title>
-<link href="{T_THEME_PATH}/print.css" rel="stylesheet" type="text/css" />
+<link href="{T_THEME_PATH}/print.css" rel="stylesheet">
<!-- EVENT ucp_pm_viewmessage_print_head_append -->
</head>
<body id="phpbb">
diff --git a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html
index 2642b7a419..462a7f8f20 100644
--- a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html
+++ b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html
@@ -19,16 +19,16 @@
</dl>
<dl>
<dt><label for="email">{L_EMAIL_ADDRESS}{L_COLON}</label></dt>
- <dd><!-- IF S_CHANGE_EMAIL --><input type="email" name="email" id="email" maxlength="100" value="{EMAIL}" class="inputbox" title="{L_EMAIL_ADDRESS}" /><!-- ELSE --><strong>{EMAIL}</strong><!-- ENDIF --></dd>
+ <dd><!-- IF S_CHANGE_EMAIL --><input type="email" name="email" id="email" maxlength="100" value="{EMAIL}" class="inputbox" title="{L_EMAIL_ADDRESS}" autocomplete="off" /><!-- ELSE --><strong>{EMAIL}</strong><!-- ENDIF --></dd>
</dl>
<!-- IF S_CHANGE_PASSWORD -->
<dl>
<dt><label for="new_password">{L_NEW_PASSWORD}{L_COLON}</label><br /><span>{L_CHANGE_PASSWORD_EXPLAIN}</span></dt>
- <dd><input type="password" name="new_password" id="new_password" maxlength="255" value="{NEW_PASSWORD}" class="inputbox" title="{L_CHANGE_PASSWORD}" /></dd>
+ <dd><input type="password" name="new_password" id="new_password" maxlength="255" value="{NEW_PASSWORD}" class="inputbox" title="{L_CHANGE_PASSWORD}" autocomplete="off" /></dd>
</dl>
<dl>
<dt><label for="password_confirm">{L_CONFIRM_PASSWORD}{L_COLON}</label><br /><span>{L_CONFIRM_PASSWORD_EXPLAIN}</span></dt>
- <dd><input type="password" name="password_confirm" id="password_confirm" maxlength="255" value="{PASSWORD_CONFIRM}" class="inputbox" title="{L_CONFIRM_PASSWORD}" /></dd>
+ <dd><input type="password" name="password_confirm" id="password_confirm" maxlength="255" value="{PASSWORD_CONFIRM}" class="inputbox" title="{L_CONFIRM_PASSWORD}" autocomplete="off" /></dd>
</dl>
<!-- ENDIF -->
<!-- EVENT ucp_profile_register_details_after -->
@@ -42,7 +42,7 @@
<fieldset>
<dl>
<dt><label for="cur_password">{L_CURRENT_PASSWORD}{L_COLON}</label><br /><span><!-- IF S_CHANGE_PASSWORD -->{L_CURRENT_CHANGE_PASSWORD_EXPLAIN}<!-- ELSE -->{L_CURRENT_PASSWORD_EXPLAIN}<!-- ENDIF --></span></dt>
- <dd><input type="password" name="cur_password" id="cur_password" maxlength="255" value="{CUR_PASSWORD}" class="inputbox" title="{L_CURRENT_PASSWORD}" /></dd>
+ <dd><input type="password" name="cur_password" id="cur_password" maxlength="255" value="{CUR_PASSWORD}" class="inputbox" title="{L_CURRENT_PASSWORD}" autocomplete="off" /></dd>
</dl>
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html
index 020f69cb26..fafd0cce00 100644
--- a/phpBB/styles/prosilver/template/ucp_register.html
+++ b/phpBB/styles/prosilver/template/ucp_register.html
@@ -33,15 +33,15 @@
</dl>
<dl>
<dt><label for="email">{L_EMAIL_ADDRESS}{L_COLON}</label></dt>
- <dd><input type="email" tabindex="2" name="email" id="email" size="25" maxlength="100" value="{EMAIL}" class="inputbox autowidth" title="{L_EMAIL_ADDRESS}" /></dd>
+ <dd><input type="email" tabindex="2" name="email" id="email" size="25" maxlength="100" value="{EMAIL}" class="inputbox autowidth" title="{L_EMAIL_ADDRESS}" autocomplete="off" /></dd>
</dl>
<dl>
<dt><label for="new_password">{L_PASSWORD}{L_COLON}</label><br /><span>{L_PASSWORD_EXPLAIN}</span></dt>
- <dd><input type="password" tabindex="4" name="new_password" id="new_password" size="25" value="{PASSWORD}" class="inputbox autowidth" title="{L_NEW_PASSWORD}" /></dd>
+ <dd><input type="password" tabindex="4" name="new_password" id="new_password" size="25" value="{PASSWORD}" class="inputbox autowidth" title="{L_NEW_PASSWORD}" autocomplete="off" /></dd>
</dl>
<dl>
<dt><label for="password_confirm">{L_CONFIRM_PASSWORD}{L_COLON}</label></dt>
- <dd><input type="password" tabindex="5" name="password_confirm" id="password_confirm" size="25" value="{PASSWORD_CONFIRM}" class="inputbox autowidth" title="{L_CONFIRM_PASSWORD}" /></dd>
+ <dd><input type="password" tabindex="5" name="password_confirm" id="password_confirm" size="25" value="{PASSWORD_CONFIRM}" class="inputbox autowidth" title="{L_CONFIRM_PASSWORD}" autocomplete="off" /></dd>
</dl>
<!-- EVENT ucp_register_credentials_after -->
diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html
index b1e9d1be2c..2679a2cd29 100644
--- a/phpBB/styles/prosilver/template/viewforum_body.html
+++ b/phpBB/styles/prosilver/template/viewforum_body.html
@@ -100,7 +100,7 @@
</dl>
<dl>
<dt><label for="password">{L_PASSWORD}{L_COLON}</label></dt>
- <dd><input type="password" tabindex="2" id="password" name="password" size="25" class="inputbox autowidth" /></dd>
+ <dd><input type="password" tabindex="2" id="password" name="password" size="25" class="inputbox autowidth" autocomplete="off" /></dd>
<!-- IF S_AUTOLOGIN_ENABLED --><dd><label for="autologin"><input type="checkbox" name="autologin" id="autologin" tabindex="3" /> {L_LOG_ME_IN}</label></dd><!-- ENDIF -->
<dd><label for="viewonline"><input type="checkbox" name="viewonline" id="viewonline" tabindex="4" /> {L_HIDE_ME}</label></dd>
</dl>
diff --git a/phpBB/styles/prosilver/template/viewtopic_print.html b/phpBB/styles/prosilver/template/viewtopic_print.html
index 66199295bb..f65f1ab542 100644
--- a/phpBB/styles/prosilver/template/viewtopic_print.html
+++ b/phpBB/styles/prosilver/template/viewtopic_print.html
@@ -6,7 +6,7 @@
{META}
<title>{SITENAME} &bull; {PAGE_TITLE}</title>
-<link href="{T_THEME_PATH}/print.css" rel="stylesheet" type="text/css" />
+<link href="{T_THEME_PATH}/print.css" rel="stylesheet">
<!-- EVENT viewtopic_print_head_append -->
</head>
<body id="phpbb">
diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css
index 85c3cb9f4c..f8eefb1b8e 100644
--- a/phpBB/styles/prosilver/theme/content.css
+++ b/phpBB/styles/prosilver/theme/content.css
@@ -460,7 +460,7 @@ blockquote {
background: transparent none 6px 8px no-repeat;
border: 1px solid transparent;
font-size: 0.95em;
- margin: 0.5em 1px 0 25px;
+ margin: 1em 1px 1em 25px;
overflow: hidden;
padding: 5px;
}
@@ -468,7 +468,7 @@ blockquote {
blockquote blockquote {
/* Nested quotes */
font-size: 1em;
- margin: 0.5em 1px 0 15px;
+ margin: 1em 1px 1em 15px;
}
blockquote cite {
diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index faf5768edf..4a42d78b2b 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -590,7 +590,7 @@ $quickmod_array = array(
'topic_logs' => array('VIEW_TOPIC_LOGS', $auth->acl_get('m_', $forum_id)),
);
-foreach($quickmod_array as $option => $qm_ary)
+foreach ($quickmod_array as $option => $qm_ary)
{
if (!empty($qm_ary[1]))
{
diff --git a/tests/controller/common_helper_route.php b/tests/controller/common_helper_route.php
index 44e5e12ab0..3c74c16bae 100644
--- a/tests/controller/common_helper_route.php
+++ b/tests/controller/common_helper_route.php
@@ -89,6 +89,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
$this->user = new \phpbb\user($lang, '\phpbb\datetime');;
$container = new phpbb_mock_container_builder();
+ $container->setParameter('core.environment', PHPBB_ENVIRONMENT);
$cache_path = $phpbb_root_path . 'cache/twig';
$context = new \phpbb\template\context();
$loader = new \phpbb\template\twig\loader($this->filesystem, '');
@@ -121,7 +122,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
)
);
- $this->router = new phpbb_mock_router($this->filesystem, dirname(__FILE__) . '/', 'php', PHPBB_ENVIRONMENT, $this->extension_manager);
+ $this->router = new phpbb_mock_router($container, $this->filesystem, dirname(__FILE__) . '/', 'php', PHPBB_ENVIRONMENT, $this->extension_manager);
$this->router->find_routing_files($this->extension_manager->all_enabled(false));
$this->router->find(dirname(__FILE__) . '/');
// Set correct current phpBB root path
@@ -155,6 +156,9 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
array('controller2', array(), true, false, '/' . $this->path_to_app() . 'app.php/foo/bar', 'no params using empty array'),
array('controller2', array(), false, false, '/' . $this->path_to_app() . 'app.php/foo/bar', 'no params using empty array'),
array('controller3', array('p' => 3), true, false, '/' . $this->path_to_app() . 'app.php/foo/bar/p-3', 'no params using empty array'),
+
+ // Resolves DI parameters
+ array('controller4', array(), true, false, '/' . $this->path_to_app() . 'app.php/foo/' . PHPBB_ENVIRONMENT, 'di parameter'),
);
}
@@ -195,6 +199,9 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
array('controller2', array(), true, false, '/' . $this->path_to_app() . 'foo/bar', 'no params using empty array'),
array('controller2', array(), false, false, '/' . $this->path_to_app() . 'foo/bar', 'no params using empty array'),
array('controller3', array('p' => 3), true, false, '/' . $this->path_to_app() . 'foo/bar/p-3', 'no params using empty array'),
+
+ // Resolves DI parameters
+ array('controller4', array(), true, false, '/' . $this->path_to_app() . 'foo/' . PHPBB_ENVIRONMENT, 'di parameter'),
);
}
@@ -235,6 +242,9 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
array('controller2', array(), true, false, 'http://localhost/' . $this->path_to_app() . 'app.php/foo/bar', 'no params using empty array'),
array('controller2', array(), false, false, 'http://localhost/' . $this->path_to_app() . 'app.php/foo/bar', 'no params using empty array'),
array('controller3', array('p' => 3), true, false, 'http://localhost/' . $this->path_to_app() . 'app.php/foo/bar/p-3', 'no params using empty array'),
+
+ // Resolves DI parameters
+ array('controller4', array(), true, false, 'http://localhost/' . $this->path_to_app() . 'app.php/foo/' . PHPBB_ENVIRONMENT, 'di parameter'),
);
}
@@ -275,6 +285,9 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
array('controller2', array(), true, false, 'app.php/foo/bar', 'no params using empty array'),
array('controller2', array(), false, false, 'app.php/foo/bar', 'no params using empty array'),
array('controller3', array('p' => 3), true, false, 'app.php/foo/bar/p-3', 'no params using empty array'),
+
+ // Resolves DI parameters
+ array('controller4', array(), true, false, 'app.php/foo/' . PHPBB_ENVIRONMENT, 'di parameter'),
);
}
@@ -315,6 +328,9 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
array('controller2', array(), true, false, '//localhost/' . $this->path_to_app() . 'app.php/foo/bar', 'no params using empty array'),
array('controller2', array(), false, false, '//localhost/' . $this->path_to_app() . 'app.php/foo/bar', 'no params using empty array'),
array('controller3', array('p' => 3), true, false, '//localhost/' . $this->path_to_app() . 'app.php/foo/bar/p-3', 'no params using empty array'),
+
+ // Resolves DI parameters
+ array('controller4', array(), true, false, '//localhost/' . $this->path_to_app() . 'app.php/foo/' . PHPBB_ENVIRONMENT, 'di parameter'),
);
}
@@ -355,6 +371,9 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
array('controller2', array(), true, false, 'http://localhost/' . $this->path_to_app() . 'foo/bar', 'no params using empty array'),
array('controller2', array(), false, false, 'http://localhost/' . $this->path_to_app() . 'foo/bar', 'no params using empty array'),
array('controller3', array('p' => 3), true, false, 'http://localhost/' . $this->path_to_app() . 'foo/bar/p-3', 'no params using empty array'),
+
+ // Resolves DI parameters
+ array('controller4', array(), true, false, 'http://localhost/' . $this->path_to_app() . 'foo/' . PHPBB_ENVIRONMENT, 'di parameter'),
);
}
@@ -435,6 +454,9 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
array('controller2', array(), true, false, '//localhost/' . $this->path_to_app() . 'foo/bar', 'no params using empty array'),
array('controller2', array(), false, false, '//localhost/' . $this->path_to_app() . 'foo/bar', 'no params using empty array'),
array('controller3', array('p' => 3), true, false, '//localhost/' . $this->path_to_app() . 'foo/bar/p-3', 'no params using empty array'),
+
+ // Resolves DI parameters
+ array('controller4', array(), true, false, '//localhost/' . $this->path_to_app() . 'foo/' . PHPBB_ENVIRONMENT, 'di parameter'),
);
}
diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php
index 5781d3ebc1..d0295d66bc 100644
--- a/tests/controller/controller_test.php
+++ b/tests/controller/controller_test.php
@@ -40,7 +40,10 @@ class phpbb_controller_controller_test extends phpbb_test_case
public function test_router_find_files()
{
- $router = new \phpbb\routing\router(new \phpbb\filesystem\filesystem(), dirname(__FILE__) . '/', 'php', PHPBB_ENVIRONMENT, $this->extension_manager);
+ $container = new phpbb_mock_container_builder();
+ $container->setParameter('core.environment', PHPBB_ENVIRONMENT);
+
+ $router = new \phpbb\routing\router($container, new \phpbb\filesystem\filesystem(), dirname(__FILE__) . '/', 'php', PHPBB_ENVIRONMENT, $this->extension_manager);
$router->find_routing_files($this->extension_manager->all_enabled(false));
$routes = $router->find(__DIR__)->get_routes();
diff --git a/tests/controller/ext/vendor2/foo/config/routing.yml b/tests/controller/ext/vendor2/foo/config/routing.yml
index e3e8ee5f98..7d4ac7be93 100644
--- a/tests/controller/ext/vendor2/foo/config/routing.yml
+++ b/tests/controller/ext/vendor2/foo/config/routing.yml
@@ -5,3 +5,7 @@ controller1:
include_controller2:
resource: "routing_2.yml"
prefix: /foo
+
+controller4:
+ path: /foo/%core.environment%
+ defaults: { _controller: foo.controller:handle }
diff --git a/tests/dbal/fixtures/migrator_permission.xml b/tests/dbal/fixtures/migrator_permission.xml
index 08cec42a42..c07956fa85 100644
--- a/tests/dbal/fixtures/migrator_permission.xml
+++ b/tests/dbal/fixtures/migrator_permission.xml
@@ -27,5 +27,139 @@
<value>1</value>
<value>0</value>
</row>
+ <row>
+ <value>4</value>
+ <value>a_test</value>
+ <value>1</value>
+ <value>0</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>5</value>
+ <value>m_test</value>
+ <value>1</value>
+ <value>0</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>6</value>
+ <value>u_test</value>
+ <value>1</value>
+ <value>0</value>
+ <value>0</value>
+ </row>
+ </table>
+
+ <table name="phpbb_groups">
+ <column>group_id</column>
+ <column>group_name</column>
+ <column>group_desc</column>
+ <row>
+ <value>2</value>
+ <value>REGISTERED</value>
+ <value></value>
+ </row>
+ <row>
+ <value>4</value>
+ <value>GLOBAL_MODERATORS</value>
+ <value></value>
+ </row>
+ <row>
+ <value>5</value>
+ <value>ADMINISTRATORS</value>
+ <value></value>
+ </row>
+ </table>
+
+ <table name="phpbb_acl_groups">
+ <column>group_id</column>
+ <column>auth_role_id</column>
+ <column>forum_id</column>
+ <row>
+ <value>2</value>
+ <value>5</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>4</value>
+ <value>5</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>4</value>
+ <value>10</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>5</value>
+ <value>1</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>5</value>
+ <value>5</value>
+ <value>0</value>
+ </row>
+ </table>
+
+ <table name="phpbb_acl_roles">
+ <column>role_id</column>
+ <column>role_name</column>
+ <column>role_type</column>
+ <column>role_description</column>
+ <row>
+ <value>1</value>
+ <value>ROLE_ADMIN_STANDARD</value>
+ <value>a_</value>
+ <value></value>
+ </row>
+ <row>
+ <value>5</value>
+ <value>ROLE_USER_FULL</value>
+ <value>u_</value>
+ <value></value>
+ </row>
+ <row>
+ <value>10</value>
+ <value>ROLE_MOD_FULL</value>
+ <value>m_</value>
+ <value></value>
+ </row>
+ </table>
+
+ <table name="phpbb_acl_roles_data">
+ <column>role_id</column>
+ <column>auth_option_id</column>
+ <column>auth_setting</column>
+ <row>
+ <value>1</value>
+ <value>4</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>1</value>
+ <value>5</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>1</value>
+ <value>6</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>6</value>
+ <value>6</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>10</value>
+ <value>5</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>10</value>
+ <value>6</value>
+ <value>0</value>
+ </row>
</table>
</dataset>
diff --git a/tests/dbal/migrator_tool_module_test.php b/tests/dbal/migrator_tool_module_test.php
index 695a7e7a7f..a71334f23f 100644
--- a/tests/dbal/migrator_tool_module_test.php
+++ b/tests/dbal/migrator_tool_module_test.php
@@ -41,7 +41,10 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case
$auth = $this->getMock('\phpbb\auth\auth');
$phpbb_log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE);
- $this->tool = new \phpbb\db\migration\tool\module($this->db, $this->cache, $this->user, $phpbb_root_path, $phpEx, 'phpbb_modules');
+ $phpbb_extension_manager = new phpbb_mock_extension_manager($phpbb_root_path);
+ $module_manager = new \phpbb\module\module_manager($cache, $this->db, $phpbb_extension_manager, MODULES_TABLE, $phpbb_root_path, $phpEx);
+
+ $this->tool = new \phpbb\db\migration\tool\module($this->db, $this->cache, $this->user, $module_manager, $phpbb_root_path, $phpEx, 'phpbb_modules');
}
public function exists_data()
diff --git a/tests/dbal/migrator_tool_permission_test.php b/tests/dbal/migrator_tool_permission_test.php
index 3d190e7a11..bfb2e07080 100644
--- a/tests/dbal/migrator_tool_permission_test.php
+++ b/tests/dbal/migrator_tool_permission_test.php
@@ -15,6 +15,12 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
class phpbb_dbal_migrator_tool_permission_test extends phpbb_database_test_case
{
+ public $group_ids = array(
+ 'REGISTERED' => 2,
+ 'GLOBAL_MODERATORS' => 4,
+ 'ADMINISTRATORS' => 5,
+ );
+
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/migrator_permission.xml');
@@ -158,4 +164,60 @@ class phpbb_dbal_migrator_tool_permission_test extends phpbb_database_test_case
}
$this->assertFalse($this->tool->exists('global_test', true));
}
+
+ public function test_permission_set_data()
+ {
+ return array(
+ array(
+ 'ADMINISTRATORS',
+ 'a_test',
+ 'group',
+ true,
+ ),
+ array(
+ 'GLOBAL_MODERATORS',
+ 'm_test',
+ 'group',
+ true,
+ ),
+ array(
+ 'REGISTERED',
+ 'u_test',
+ 'group',
+ true,
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider test_permission_set_data
+ */
+ public function test_permission_set($group_name, $auth_option, $type, $has_permission)
+ {
+ $this->tool->permission_set($group_name, $auth_option, $type, $has_permission);
+ $administrators_perm = $this->auth->acl_group_raw_data($this->group_ids['ADMINISTRATORS'], $auth_option);
+ $global_moderators_perm = $this->auth->acl_group_raw_data($this->group_ids['GLOBAL_MODERATORS'], $auth_option);
+ $registered_users_perm = $this->auth->acl_group_raw_data($this->group_ids['REGISTERED'], $auth_option);
+
+ switch($group_name)
+ {
+ case 'GLOBAL_MODERATORS':
+ $this->assertEquals(false, empty($administrators_perm), 'm_test is not empty for Administrators');
+ $this->assertEquals(false, empty($global_moderators_perm), 'm_test is not empty for Global moderators');
+ $this->assertEquals(true, empty($registered_users_perm), 'm_test empty for Registered users');
+ break;
+
+ case 'ADMINISTRATORS':
+ $this->assertEquals(false, empty($administrators_perm), 'a_test is not empty for Administrators');
+ $this->assertEquals(true, empty($global_moderators_perm), 'a_test is empty for Global moderators');
+ $this->assertEquals(true, empty($registered_users_perm), 'a_test is empty for Registered users');
+ break;
+
+ case 'REGISTERED':
+ $this->assertEquals(false, empty($administrators_perm), 'u_test is not empty for Administrators');
+ $this->assertEquals(false, empty($global_moderators_perm), 'u_test is not empty for Global moderators');
+ $this->assertEquals(false, empty($registered_users_perm), 'u_test is not empty for Registered users');
+ break;
+ }
+ }
}
diff --git a/tests/di/fixtures/config/production/container/environment.yml b/tests/di/fixtures/config/production/container/environment.yml
index 6ac07a44d9..9dcf11d865 100644
--- a/tests/di/fixtures/config/production/container/environment.yml
+++ b/tests/di/fixtures/config/production/container/environment.yml
@@ -15,3 +15,15 @@ services:
ext.manager:
class: phpbb\extension\manager_mock
+
+ template.twig.environment:
+ class: Exception
+ arguments:
+ - ~
+ - ~
+ - ~
+ - ~
+ - ~
+ - ~
+ - ~
+ - []
diff --git a/tests/extension/modules_test.php b/tests/extension/modules_test.php
index cbcfdfb787..88634bc6ba 100644
--- a/tests/extension/modules_test.php
+++ b/tests/extension/modules_test.php
@@ -22,6 +22,7 @@ class phpbb_extension_modules_test extends phpbb_test_case
{
protected $extension_manager;
protected $finder;
+ protected $module_manager;
public function setUp()
{
@@ -43,7 +44,14 @@ class phpbb_extension_modules_test extends phpbb_test_case
));
$phpbb_extension_manager = $this->extension_manager;
- $this->acp_modules = new acp_modules();
+ $this->module_manager = new \phpbb\module\module_manager(
+ new \phpbb\cache\driver\dummy(),
+ $this->getMock('\phpbb\db\driver\driver_interface'),
+ $this->extension_manager,
+ MODULES_TABLE,
+ dirname(__FILE__) . '/',
+ 'php'
+ );
}
public function test_get_module_infos()
@@ -56,8 +64,7 @@ class phpbb_extension_modules_test extends phpbb_test_case
$phpbb_root_path = dirname(__FILE__) . '/';
// Find acp module info files
- $this->acp_modules->module_class = 'acp';
- $acp_modules = $this->acp_modules->get_module_infos();
+ $acp_modules = $this->module_manager->get_module_infos('acp');
$this->assertEquals(array(
'vendor2\\foo\\acp\\a_module' => array(
'filename' => 'vendor2\\foo\\acp\\a_module',
@@ -76,8 +83,7 @@ class phpbb_extension_modules_test extends phpbb_test_case
), $acp_modules);
// Find mcp module info files
- $this->acp_modules->module_class = 'mcp';
- $acp_modules = $this->acp_modules->get_module_infos();
+ $acp_modules = $this->module_manager->get_module_infos('mcp');
$this->assertEquals(array(
'vendor2\\foo\\mcp\\a_module' => array(
'filename' => 'vendor2\\foo\\mcp\\a_module',
@@ -89,21 +95,7 @@ class phpbb_extension_modules_test extends phpbb_test_case
), $acp_modules);
// Find a specific module info file (mcp_a_module)
- $this->acp_modules->module_class = 'mcp';
- $acp_modules = $this->acp_modules->get_module_infos('mcp_a_module');
- $this->assertEquals(array(
- 'vendor2\\foo\\mcp\\a_module' => array(
- 'filename' => 'vendor2\\foo\\mcp\\a_module',
- 'title' => 'Foobar',
- 'modes' => array(
- 'config' => array('title' => 'Config', 'auth' => '', 'cat' => array('MCP_MAIN')),
- ),
- ),
- ), $acp_modules);
-
- // Find a specific module info file (mcp_a_module) with passing the module_class
- $this->acp_modules->module_class = '';
- $acp_modules = $this->acp_modules->get_module_infos('mcp_a_module', 'mcp');
+ $acp_modules = $this->module_manager->get_module_infos('mcp', 'mcp_a_module');
$this->assertEquals(array(
'vendor2\\foo\\mcp\\a_module' => array(
'filename' => 'vendor2\\foo\\mcp\\a_module',
@@ -115,18 +107,15 @@ class phpbb_extension_modules_test extends phpbb_test_case
), $acp_modules);
// The mcp module info file we're looking for shouldn't exist
- $this->acp_modules->module_class = 'mcp';
- $acp_modules = $this->acp_modules->get_module_infos('mcp_a_fail');
+ $acp_modules = $this->module_manager->get_module_infos('mcp', 'mcp_a_fail');
$this->assertEquals(array(), $acp_modules);
// As there are no ucp modules we shouldn't find any
- $this->acp_modules->module_class = 'ucp';
- $acp_modules = $this->acp_modules->get_module_infos();
+ $acp_modules = $this->module_manager->get_module_infos('ucp');
$this->assertEquals(array(), $acp_modules);
// Get module info of specified extension module
- $this->acp_modules->module_class = 'acp';
- $acp_modules = $this->acp_modules->get_module_infos('foo_acp_a_module');
+ $acp_modules = $this->module_manager->get_module_infos('acp', 'foo_acp_a_module');
$this->assertEquals(array(
'vendor2\\foo\\acp\\a_module' => array (
'filename' => 'vendor2\\foo\\acp\\a_module',
@@ -138,18 +127,16 @@ class phpbb_extension_modules_test extends phpbb_test_case
), $acp_modules);
// No specific module and module class set to an incorrect name
- $acp_modules = $this->acp_modules->get_module_infos('', 'wcp', true);
+ $acp_modules = $this->module_manager->get_module_infos('wcp', '', true);
$this->assertEquals(array(), $acp_modules);
// No specific module, no module_class set in the function parameter, and an incorrect module class
- $this->acp_modules->module_class = 'wcp';
- $acp_modules = $this->acp_modules->get_module_infos();
+ $acp_modules = $this->module_manager->get_module_infos('wcp');
$this->assertEquals(array(), $acp_modules);
// No specific module, module class set to false (will default to the above acp)
// Setting $use_all_available will cause get_module_infos() to also load not enabled extensions (vendor2/bar)
- $this->acp_modules->module_class = 'acp';
- $acp_modules = $this->acp_modules->get_module_infos('', false, true);
+ $acp_modules = $this->module_manager->get_module_infos('acp', '', true);
$this->assertEquals(array(
'vendor2\\foo\\acp\\a_module' => array(
'filename' => 'vendor2\\foo\\acp\\a_module',
@@ -175,7 +162,7 @@ class phpbb_extension_modules_test extends phpbb_test_case
), $acp_modules);
// Specific module set to disabled extension
- $acp_modules = $this->acp_modules->get_module_infos('vendor2_bar_acp_a_module', 'acp', true);
+ $acp_modules = $this->module_manager->get_module_infos('acp', 'vendor2_bar_acp_a_module', true);
$this->assertEquals(array(
'vendor2\\bar\\acp\\a_module' => array(
'filename' => 'vendor2\\bar\\acp\\a_module',
diff --git a/tests/functional/extension_module_test.php b/tests/functional/extension_module_test.php
index ee084720e4..95107665cd 100644
--- a/tests/functional/extension_module_test.php
+++ b/tests/functional/extension_module_test.php
@@ -49,8 +49,9 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case
$this->phpbb_extension_manager = $this->get_extension_manager();
$this->phpbb_extension_manager->enable('foo/bar');
- $modules = new acp_modules();
$db = $this->get_db();
+ $cache = $this->get_cache_driver();
+ $modules = new \phpbb\module\module_manager($cache, $db, $this->phpbb_extension_manager, MODULES_TABLE, dirname(__FILE__) . '/../../phpBB/', 'php');
$sql = 'SELECT module_id
FROM ' . MODULES_TABLE . "
@@ -70,7 +71,7 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case
'module_mode' => '',
'module_auth' => '',
);
- $modules->update_module_data($parent_data, true);
+ $modules->update_module_data($parent_data);
$module_data = array(
'module_basename' => 'foo\\bar\\acp\\main_module',
@@ -82,7 +83,7 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case
'module_mode' => 'mode',
'module_auth' => '',
);
- $modules->update_module_data($module_data, true);
+ $modules->update_module_data($module_data);
$parent_data = array(
'module_basename' => '',
@@ -94,7 +95,7 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case
'module_mode' => '',
'module_auth' => '',
);
- $modules->update_module_data($parent_data, true);
+ $modules->update_module_data($parent_data);
$module_data = array(
'module_basename' => 'foo\\bar\\ucp\\main_module',
@@ -106,7 +107,7 @@ class phpbb_functional_extension_module_test extends phpbb_functional_test_case
'module_mode' => 'mode',
'module_auth' => '',
);
- $modules->update_module_data($module_data, true);
+ $modules->update_module_data($module_data);
$this->purge_cache();
}
diff --git a/tests/functional/posting_test.php b/tests/functional/posting_test.php
index 8677237772..ccfeb10deb 100644
--- a/tests/functional/posting_test.php
+++ b/tests/functional/posting_test.php
@@ -166,4 +166,40 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
$crawler = self::submit($form);
$this->assertEquals(1, $crawler->filter('.successbox')->count());
}
+
+ public function test_ticket_8420()
+ {
+ $text = '[b][url=http://example.org] :arrow: here[/url][/b]';
+
+ $this->login();
+ $crawler = self::request('GET', 'posting.php?mode=post&f=2');
+ $form = $crawler->selectButton('Preview')->form(array(
+ 'subject' => 'Test subject',
+ 'message' => $text
+ ));
+ $crawler = self::submit($form);
+ $this->assertEquals($text, $crawler->filter('#message')->text());
+ }
+
+ public function test_old_signature_in_preview()
+ {
+ $sql = 'UPDATE ' . USERS_TABLE . "
+ SET user_sig = '[b:2u8sdcwb]My signature[/b:2u8sdcwb]',
+ user_sig_bbcode_uid = '2u8sdcwb',
+ user_sig_bbcode_bitfield = 'QA=='
+ WHERE user_id = 2";
+ $this->get_db()->sql_query($sql);
+
+ $this->login();
+ $crawler = self::request('GET', 'posting.php?mode=post&f=2');
+ $form = $crawler->selectButton('Preview')->form(array(
+ 'subject' => 'Test subject',
+ 'message' => 'My post',
+ ));
+ $crawler = self::submit($form);
+ $this->assertContains(
+ '<span style="font-weight: bold">My signature</span>',
+ $crawler->filter('#preview .signature')->html()
+ );
+ }
}
diff --git a/tests/functions/fixtures/user_delete.xml b/tests/functions/fixtures/user_delete.xml
new file mode 100644
index 0000000000..4c4479d29b
--- /dev/null
+++ b/tests/functions/fixtures/user_delete.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<dataset>
+ <table name="phpbb_users">
+ <column>user_id</column>
+ <column>username_clean</column>
+ <column>username</column>
+ <column>user_permissions</column>
+ <column>user_sig</column>
+ <row>
+ <value>1</value>
+ <value>anonymous</value>
+ <value>anonymous</value>
+ <value></value>
+ <value></value>
+ </row>
+ <row>
+ <value>2</value>
+ <value>2</value>
+ <value>2</value>
+ <value></value>
+ <value></value>
+ </row>
+ </table>
+ <table name="phpbb_oauth_accounts">
+ <column>user_id</column>
+ <column>provider</column>
+ <column>oauth_provider_id</column>
+ <row>
+ <value>2</value>
+ <value>google</value>
+ <value>1234567890123456789</value>
+ </row>
+ </table>
+ <table name="phpbb_oauth_tokens">
+ <column>user_id</column>
+ <column>session_id</column>
+ <column>provider</column>
+ <column>oauth_token</column>
+ <row>
+ <value>2</value>
+ <value>897a897b797c8789997d7979879</value>
+ <value>auth.provider.oauth.service.google</value>
+ <value>{"accessToken":"ya29.YPHwCWVkrvwu1kgbYKiDNYaQ451ZuHy9OEQAGVME8if-WBzR-v7a9ftxbx41kaL)5VLEXB-6qJEvri","endOfLife":1429959670,"extraParams":{"token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsImupZCI6IjE0YuRjNzc2MDQwYjUyNDZmNTI5OWFkZDVlMmQ1NWNOPTdjMDdlZTAifQ.eyJpc3MiOiJhY2NvdW90cy5nb78nbGUuY29tIiwic3ViIjoiMTExMDMwNwerNjM4MTM5NTQwMTM1IiwiYXpwIjoiOTk3MzUwMTY0NzE0LWhwOXJrYjZpcjM4MW80YjV1NjRpaGtmM29zMnRvbWxhLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiZW1haWwiOiJtYXJjLmFsZXhhbmRlci4zN0BnbWFpbC5jb20iLCJhdF9oYXNoIjoiWHk2b1JabnVZUWRfRTZDeDV0RkItdyIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhdWQiOiI5OTczNTAxNjQ3MTQtaHA5cmtiNmlyMzgxbzRiNXU2NGloa2Yzb3MydG9tbGEuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJpYXQiOjE0Mjk5NTYwNzEsImV4cCI6MTQyOTk1OTY3MX0.C5gfSzjqwlRRvVMuTP6jfWIuEHMXn55oYHsSA3eh97n2BZL0TZHhUm4K206Fgucd6ufAphan4l0J7y6tMAHLZPr-kk6KDINxWnPG-up99reblGutay0lRYjMCcrhJAOql8EI1bi84GyliZFYHL67pE0ZtSf-CMb1CeH18TFe-Fk"},"refreshToken":null,"token_class":"OAuth\\\\OAuth2\\\\Token\\\\StdOAuth2Token"}</value>
+ </row>
+ </table>
+</dataset>
diff --git a/tests/functions/user_delete_test.php b/tests/functions/user_delete_test.php
new file mode 100644
index 0000000000..21561492fd
--- /dev/null
+++ b/tests/functions/user_delete_test.php
@@ -0,0 +1,113 @@
+<?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_user.php';
+
+class phpbb_functions_user_delete_test extends phpbb_database_test_case
+{
+ /** @var \phpbb\db\driver\driver_interface */
+ protected $db;
+
+ public function getDataSet()
+ {
+ return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/user_delete.xml');
+ }
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ global $cache, $config, $db, $phpbb_container, $phpbb_dispatcher, $user, $phpbb_root_path, $phpEx;
+
+ $this->db = $db = $this->new_dbal();
+ $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx);
+ $lang = new \phpbb\language\language($lang_loader);
+ $user = new \phpbb\user($lang, '\phpbb\datetime');
+ $phpbb_dispatcher = new phpbb_mock_event_dispatcher();
+ $phpbb_container = new phpbb_mock_container_builder();
+ $config = new \phpbb\config\config(array(
+ 'auth_method' => 'oauth',
+ 'auth_oauth_google_key' => 'foo',
+ 'auth_oauth_google_secret' => 'bar',
+ ));
+ $cache = new \phpbb\cache\driver\dummy();
+ $request = new phpbb_mock_request();
+ $notification_manager = new phpbb_mock_notification_manager();
+ $provider_collection = new \phpbb\auth\provider_collection($phpbb_container, $config);
+ $oauth_provider_google = new \phpbb\auth\provider\oauth\service\google($config, $request);
+ $oauth_provider_collection = new \phpbb\di\service_collection($phpbb_container);
+ $oauth_provider_collection->offsetSet('auth.provider.oauth.service.google', $oauth_provider_google);
+
+ $driver_helper = new \phpbb\passwords\driver\helper($config);
+ $passwords_drivers = array(
+ 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $driver_helper),
+ 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $driver_helper),
+ 'passwords.driver.salted_md5' => new \phpbb\passwords\driver\salted_md5($config, $driver_helper),
+ 'passwords.driver.phpass' => new \phpbb\passwords\driver\phpass($config, $driver_helper),
+ );
+
+ $passwords_helper = new \phpbb\passwords\helper;
+ // Set up passwords manager
+ $passwords_manager = new \phpbb\passwords\manager($config, $passwords_drivers, $passwords_helper, array_keys($passwords_drivers));
+
+ $oauth_provider = new \phpbb\auth\provider\oauth\oauth(
+ $db,
+ $config,
+ $passwords_manager,
+ $request,
+ $user,
+ 'phpbb_oauth_tokens',
+ 'phpbb_oauth_accounts',
+ $oauth_provider_collection,
+ 'phpbb_users',
+ $phpbb_container,
+ $this->phpbb_root_path,
+ $this->php_ext
+ );
+ $provider_collection->offsetSet('auth.provider.oauth', $oauth_provider);
+
+ $phpbb_container->set('auth.provider.oauth', $oauth_provider);
+ $phpbb_container->set('auth.provider.oauth.service.google', $oauth_provider_google);
+ $phpbb_container->set('auth.provider_collection', $provider_collection);
+ $phpbb_container->set('notification_manager', $notification_manager);
+ }
+
+ public function test_user_delete()
+ {
+ // Check that user is linked
+ $sql = 'SELECT ot.user_id AS user_id
+ FROM phpbb_oauth_accounts oa, phpbb_oauth_tokens ot
+ WHERE oa.user_id = 2
+ AND ot.user_id = oa.user_id';
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ $this->assertEquals(array('user_id' => '2'), $row);
+
+ // user_delete() should return false
+ $this->assertFalse(user_delete('remove', array(2)));
+
+ // Make sure user link was removed
+ $sql = 'SELECT ot.user_id AS user_id
+ FROM phpbb_oauth_accounts oa, phpbb_oauth_tokens ot
+ WHERE oa.user_id = 2
+ AND ot.user_id = oa.user_id';
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ $this->assertEmpty($row);
+ }
+}
diff --git a/tests/functions_acp/build_cfg_template_test.php b/tests/functions_acp/build_cfg_template_test.php
index 8ae78b97db..a8d7ae6f09 100644
--- a/tests/functions_acp/build_cfg_template_test.php
+++ b/tests/functions_acp/build_cfg_template_test.php
@@ -32,7 +32,7 @@ class phpbb_functions_acp_build_cfg_template_test extends phpbb_test_case
array('config_key_name' => '2'),
'config_key_name',
array(),
- '<input id="key_name" type="password" size="20" maxlength="128" name="config[config_key_name]" value="2" autocomplete="off" />',
+ '<input id="key_name" type="password" size="20" maxlength="128" name="config[config_key_name]" value="********" autocomplete="off" />',
),
array(
array('text', 0, 255),
diff --git a/tests/functions_privmsgs/fixtures/get_max_setting_from_group.xml b/tests/functions_privmsgs/fixtures/get_max_setting_from_group.xml
new file mode 100644
index 0000000000..c78d63f7cb
--- /dev/null
+++ b/tests/functions_privmsgs/fixtures/get_max_setting_from_group.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<dataset>
+ <table name="phpbb_groups">
+ <column>group_id</column>
+ <column>group_desc</column>
+ <column>group_message_limit</column>
+ <column>group_max_recipients</column>
+ <row>
+ <value>1</value>
+ <value></value>
+ <value>1</value>
+ <value>3</value>
+ </row>
+ <row>
+ <value>2</value>
+ <value></value>
+ <value>2</value>
+ <value>4</value>
+ </row>
+ <row>
+ <value>3</value>
+ <value></value>
+ <value>0</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>4</value>
+ <value></value>
+ <value>0</value>
+ <value>5</value>
+ </row>
+ </table>
+ <table name="phpbb_user_group">
+ <column>user_id</column>
+ <column>group_id</column>
+ <column>user_pending</column>
+ <row>
+ <value>1</value>
+ <value>1</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>1</value>
+ <value>2</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>1</value>
+ <value>3</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>2</value>
+ <value>1</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>2</value>
+ <value>2</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>3</value>
+ <value>3</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>4</value>
+ <value>4</value>
+ <value>0</value>
+ </row>
+ <row>
+ <value>5</value>
+ <value>3</value>
+ <value>1</value>
+ </row>
+ <row>
+ <value>5</value>
+ <value>2</value>
+ <value>0</value>
+ </row>
+ </table>
+</dataset>
diff --git a/tests/functions_privmsgs/get_max_setting_from_group_test.php b/tests/functions_privmsgs/get_max_setting_from_group_test.php
new file mode 100644
index 0000000000..3eb7866802
--- /dev/null
+++ b/tests/functions_privmsgs/get_max_setting_from_group_test.php
@@ -0,0 +1,64 @@
+<?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_privmsgs.php';
+
+class phpbb_functions_privmsgs_get_max_setting_from_group_test extends phpbb_database_test_case
+{
+ public function getDataSet()
+ {
+ return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/get_max_setting_from_group.xml');
+ }
+
+ /** @var \phpbb\db\driver\driver_interface */
+ protected $db;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->db = $this->new_dbal();
+ }
+
+ static public function get_max_setting_from_group_data()
+ {
+ return array(
+ array(1, 0, 'message_limit'),
+ array(2, 2, 'message_limit'),
+ array(3, 0, 'message_limit'),
+ array(4, 0, 'message_limit'),
+ array(5, 2, 'message_limit'),
+ array(1, 0, 'max_recipients'),
+ array(2, 4, 'max_recipients'),
+ array(3, 0, 'max_recipients'),
+ array(4, 5, 'max_recipients'),
+ array(5, 4, 'max_recipients'),
+ );
+ }
+
+ /**
+ * @dataProvider get_max_setting_from_group_data
+ */
+ public function test_get_max_setting_from_group($user_id, $expected, $setting)
+ {
+ $this->assertEquals($expected, phpbb_get_max_setting_from_group($this->db, $user_id, $setting));
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function test_get_max_setting_from_group_throws()
+ {
+ phpbb_get_max_setting_from_group($this->db, ANONYMOUS, 'not_a_setting');
+ }
+}
diff --git a/tests/functions_user/delete_user_test.php b/tests/functions_user/delete_user_test.php
index 0cb171c885..9e2caf9d21 100644
--- a/tests/functions_user/delete_user_test.php
+++ b/tests/functions_user/delete_user_test.php
@@ -36,6 +36,16 @@ class phpbb_functions_user_delete_user_test extends phpbb_database_test_case
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$phpbb_container = new phpbb_mock_container_builder();
$phpbb_container->set('notification_manager', new phpbb_mock_notification_manager());
+ $phpbb_container->set(
+ 'auth.provider.db',
+ new phpbb_mock_auth_provider()
+ );
+ $provider_collection = new \phpbb\auth\provider_collection($phpbb_container, $config);
+ $provider_collection->add('auth.provider.db');
+ $phpbb_container->set(
+ 'auth.provider_collection',
+ $provider_collection
+ );
}
public function first_last_post_data()
diff --git a/tests/lint_test.php b/tests/lint_test.php
index fb43196bae..70046bdfd2 100644
--- a/tests/lint_test.php
+++ b/tests/lint_test.php
@@ -84,6 +84,8 @@ class phpbb_lint_test extends phpbb_test_case
dirname(__FILE__) . '/../build/new_version',
dirname(__FILE__) . '/../build/old_versions',
dirname(__FILE__) . '/../phpBB/cache',
+ dirname(__FILE__) . '/../phpBB/ext',
+ dirname(__FILE__) . '/../phpBB/store',
// PHP Fatal error: Cannot declare class Container because the name is already in use in /var/www/projects/phpbb3/tests/../phpBB/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php on line 20
// https://gist.github.com/e003913ffd493da63cbc
dirname(__FILE__) . '/../phpBB/vendor',
diff --git a/tests/pagination/pagination_test.php b/tests/pagination/pagination_test.php
index 67c3d0a30f..07f9ec9c56 100644
--- a/tests/pagination/pagination_test.php
+++ b/tests/pagination/pagination_test.php
@@ -41,7 +41,7 @@ class phpbb_pagination_pagination_test extends phpbb_template_template_test_case
$manager = new phpbb_mock_extension_manager(dirname(__FILE__) . '/', array());
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1'));
- $router = new phpbb_mock_router($filesystem, dirname(__FILE__) . '/', 'php', PHPBB_ENVIRONMENT, $manager);
+ $router = new phpbb_mock_router(new phpbb_mock_container_builder(), $filesystem, dirname(__FILE__) . '/', 'php', PHPBB_ENVIRONMENT, $manager);
$router->find_routing_files($manager->all_enabled(false));
$router->find(dirname(__FILE__) . '/');
diff --git a/tests/search/mysql_test.php b/tests/search/mysql_test.php
index c0c16456f4..3a791f5e81 100644
--- a/tests/search/mysql_test.php
+++ b/tests/search/mysql_test.php
@@ -37,8 +37,9 @@ class phpbb_search_mysql_test extends phpbb_search_common_test_case
$config['fulltext_mysql_max_word_len'] = 254;
$this->db = $this->new_dbal();
+ $phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$error = null;
$class = self::get_search_wrapper('\phpbb\search\fulltext_mysql');
- $this->search = new $class($error, $phpbb_root_path, $phpEx, null, $config, $this->db, $user);
+ $this->search = new $class($error, $phpbb_root_path, $phpEx, null, $config, $this->db, $user, $phpbb_dispatcher);
}
}
diff --git a/tests/search/native_test.php b/tests/search/native_test.php
index 61fde7d098..29d0d0a8d3 100644
--- a/tests/search/native_test.php
+++ b/tests/search/native_test.php
@@ -33,11 +33,12 @@ class phpbb_search_native_test extends phpbb_search_test_case
$cache = new phpbb_mock_cache();
$this->db = $this->new_dbal();
+ $phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$error = null;
$class = self::get_search_wrapper('\phpbb\search\fulltext_native');
$config['fulltext_native_min_chars'] = 2;
$config['fulltext_native_max_chars'] = 14;
- $this->search = new $class($error, $phpbb_root_path, $phpEx, null, $config, $this->db, $user);
+ $this->search = new $class($error, $phpbb_root_path, $phpEx, null, $config, $this->db, $user, $phpbb_dispatcher);
}
public function keywords()
diff --git a/tests/search/postgres_test.php b/tests/search/postgres_test.php
index f96d71e2bc..97cca0e70c 100644
--- a/tests/search/postgres_test.php
+++ b/tests/search/postgres_test.php
@@ -37,8 +37,9 @@ class phpbb_search_postgres_test extends phpbb_search_common_test_case
$config['fulltext_postgres_max_word_len'] = 254;
$this->db = $this->new_dbal();
+ $phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$error = null;
$class = self::get_search_wrapper('\phpbb\search\fulltext_postgres');
- $this->search = new $class($error, $phpbb_root_path, $phpEx, null, $config, $this->db, $user);
+ $this->search = new $class($error, $phpbb_root_path, $phpEx, null, $config, $this->db, $user, $phpbb_dispatcher);
}
}
diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php
index 0fec3c2dff..bef1208609 100644
--- a/tests/test_framework/phpbb_functional_test_case.php
+++ b/tests/test_framework/phpbb_functional_test_case.php
@@ -863,15 +863,15 @@ class phpbb_functional_test_case extends phpbb_test_case
*/
static public function assert_response_html($status_code = 200)
{
- if ($status_code !== false)
- {
- self::assert_response_status_code($status_code);
- }
-
// Any output before the doc type means there was an error
$content = self::$client->getResponse()->getContent();
self::assertNotContains('[phpBB Debug]', $content);
self::assertStringStartsWith('<!DOCTYPE', trim($content), 'Output found before DOCTYPE specification.');
+
+ if ($status_code !== false)
+ {
+ self::assert_response_status_code($status_code);
+ }
}
/*
@@ -884,15 +884,15 @@ class phpbb_functional_test_case extends phpbb_test_case
*/
static public function assert_response_xml($status_code = 200)
{
- if ($status_code !== false)
- {
- self::assert_response_status_code($status_code);
- }
-
// Any output before the xml opening means there was an error
$content = self::$client->getResponse()->getContent();
self::assertNotContains('[phpBB Debug]', $content);
self::assertStringStartsWith('<?xml', trim($content), 'Output found before XML specification.');
+
+ if ($status_code !== false)
+ {
+ self::assert_response_status_code($status_code);
+ }
}
/**
diff --git a/tests/text_processing/tickets_data/PHPBB3-10922.html b/tests/text_processing/tickets_data/PHPBB3-10922.html
index cdf8316df0..3ff117f171 100644
--- a/tests/text_processing/tickets_data/PHPBB3-10922.html
+++ b/tests/text_processing/tickets_data/PHPBB3-10922.html
@@ -1 +1,9 @@
-<a href="mailto:user@example.org">user@example.org</a><a href="mailto:user@example.org">...</a> \ No newline at end of file
+<a href="mailto:user@example.org">user@example.org</a><br>
+<a href="mailto:user@example.org">...</a><br>
+<a href="mailto:user@example.org">...</a><br>
+<a href="mailto:user@example.org?subject=Hello">...</a><br>
+<a href="mailto:user@example.org?subject=Hi%20there">user@example.org</a><br>
+<a href="mailto:user@example.org?body=Hi%20there">user@example.org</a><br>
+<a href="mailto:user@example.org?subject=Hello&amp;body=Sent%20from%20phpBB">user@example.org</a><br>
+<a href="mailto:user@example.org?subject=Hello&amp;body=Sent%20from%20phpBB">user@example.org</a><br>
+<a href="mailto:user@example.org?subject=Hello&amp;body=Sent%20from%20phpBB">...</a><br>
diff --git a/tests/text_processing/tickets_data/PHPBB3-10922.txt b/tests/text_processing/tickets_data/PHPBB3-10922.txt
index 348f8a1541..e533ce6ed5 100644
--- a/tests/text_processing/tickets_data/PHPBB3-10922.txt
+++ b/tests/text_processing/tickets_data/PHPBB3-10922.txt
@@ -1 +1,9 @@
-[email]user@example.org[/email][email=user@example.org]...[/email] \ No newline at end of file
+[email]user@example.org[/email]
+[email=user@example.org]...[/email]
+[email=user@example.org ]...[/email]
+[email=user@example.org subject="Hello"]...[/email]
+[email subject="Hi there"]user@example.org[/email]
+[email body="Hi there"]user@example.org[/email]
+[email subject="Hello" body="Sent from phpBB"]user@example.org[/email]
+[email body="Sent from phpBB" subject="Hello"]user@example.org[/email]
+[email body="Sent from phpBB" subject="Hello" email="user@example.org"]...[/email]