diff options
51 files changed, 1330 insertions, 178 deletions
diff --git a/phpBB/adm/style/acp_ext_details.html b/phpBB/adm/style/acp_ext_details.html index 465a89e17a..bd9eca623a 100644 --- a/phpBB/adm/style/acp_ext_details.html +++ b/phpBB/adm/style/acp_ext_details.html @@ -21,6 +21,7 @@ <p>{VERSIONCHECK_FAIL_REASON}</p> </div> <!-- ENDIF --> +<!-- EVENT acp_ext_details_notice --> <fieldset> <legend>{L_EXT_DETAILS}</legend> diff --git a/phpBB/adm/style/acp_jabber.html b/phpBB/adm/style/acp_jabber.html index 3c3b895624..e76c9a0323 100644 --- a/phpBB/adm/style/acp_jabber.html +++ b/phpBB/adm/style/acp_jabber.html @@ -47,6 +47,21 @@ <dd><label><input type="radio" class="radio" id="jab_use_ssl" name="jab_use_ssl" value="1"<!-- IF JAB_USE_SSL --> checked="checked"<!-- ENDIF --> /> {L_YES}</label> <label><input type="radio" class="radio" name="jab_use_ssl" value="0"<!-- IF not JAB_USE_SSL --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> </dl> +<dl> + <dt><label for="jab_verify_peer">{L_JAB_VERIFY_PEER}{L_COLON}</label><br /><span>{L_JAB_VERIFY_PEER_EXPLAIN}</span></dt> + <dd><label><input type="radio" class="radio" id="jab_verify_peer" name="jab_verify_peer" value="1"<!-- IF JAB_VERIFY_PEER --> checked="checked"<!-- ENDIF --> /> {L_YES}</label> + <label><input type="radio" class="radio" name="jab_verify_peer" value="0"<!-- IF not JAB_VERIFY_PEER --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> +</dl> +<dl> + <dt><label for="jab_verify_peer_name">{L_JAB_VERIFY_PEER_NAME}{L_COLON}</label><br /><span>{L_JAB_VERIFY_PEER_NAME_EXPLAIN}</span></dt> + <dd><label><input type="radio" class="radio" id="jab_verify_peer_name" name="jab_verify_peer_name" value="1"<!-- IF JAB_VERIFY_PEER_NAME --> checked="checked"<!-- ENDIF --> /> {L_YES}</label> + <label><input type="radio" class="radio" name="jab_verify_peer_name" value="0"<!-- IF not JAB_VERIFY_PEER_NAME --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> +</dl> +<dl> + <dt><label for="jab_allow_self_signed">{L_JAB_ALLOW_SELF_SIGNED}{L_COLON}</label><br /><span>{L_JAB_ALLOW_SELF_SIGNED_EXPLAIN}</span></dt> + <dd><label><input type="radio" class="radio" id="jab_allow_self_signed" name="jab_allow_self_signed" value="1"<!-- IF JAB_ALLOW_SELF_SIGNED --> checked="checked"<!-- ENDIF --> /> {L_YES}</label> + <label><input type="radio" class="radio" name="jab_allow_self_signed" value="0"<!-- IF not JAB_ALLOW_SELF_SIGNED --> checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> +</dl> <!-- ENDIF --> <dl> <dt><label for="jab_package_size">{L_JAB_PACKAGE_SIZE}{L_COLON}</label><br /><span>{L_JAB_PACKAGE_SIZE_EXPLAIN}</span></dt> diff --git a/phpBB/adm/style/acp_profile.html b/phpBB/adm/style/acp_profile.html index cebd2e9632..bd3935b464 100644 --- a/phpBB/adm/style/acp_profile.html +++ b/phpBB/adm/style/acp_profile.html @@ -85,6 +85,7 @@ <dd><input type="checkbox" class="radio" id="field_is_contact" name="field_is_contact" value="1"<!-- IF S_FIELD_CONTACT --> checked="checked"<!-- ENDIF --> /></dd> <dd><input class="text medium" type="text" name="field_contact_desc" id="field_contact_desc" value="{FIELD_CONTACT_DESC}" /> <label for="field_contact_desc">{L_FIELD_CONTACT_DESC}</label></dd> <dd><input class="text medium" type="text" name="field_contact_url" id="field_contact_url" value="{FIELD_CONTACT_URL}" /> <label for="field_contact_url">{L_FIELD_CONTACT_URL}</label></dd> + <!-- EVENT acp_profile_contact_last --> </dl> </fieldset> diff --git a/phpBB/composer.json b/phpBB/composer.json index 6b3a2c9918..32770c4cd0 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -34,7 +34,7 @@ "symfony/http-kernel": "2.3.*", "symfony/routing": "2.3.*", "symfony/yaml": "2.3.*", - "twig/twig": "1.*" + "twig/twig": "^1.0,<1.25" }, "require-dev": { "fabpot/goutte": "1.0.*", diff --git a/phpBB/composer.lock b/phpBB/composer.lock index 5d6b1ba7a7..f5cce659af 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "33fa9de480a8a9c8f7e3f2926cd4c034", - "content-hash": "2d9c1857e65554ceb4cfa435495df188", + "hash": "ab3d7f33388bce90e6032110a537e61f", + "content-hash": "9c138398f4bc789098b020ed37f6ae20", "packages": [ { "name": "lusitanian/oauth", @@ -72,22 +72,30 @@ }, { "name": "psr/log", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, + "require": { + "php": ">=5.3.0" + }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", @@ -101,12 +109,13 @@ } ], "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], - "time": "2012-12-21 11:40:51" + "time": "2016-10-10 12:19:37" }, { "name": "symfony/config", @@ -575,16 +584,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.2.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "dff51f72b0706335131b00a7f49606168c582594" + "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", - "reference": "dff51f72b0706335131b00a7f49606168c582594", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", + "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", "shasum": "" }, "require": { @@ -596,7 +605,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -630,7 +639,7 @@ "portable", "shim" ], - "time": "2016-05-18 14:26:46" + "time": "2016-11-14 01:06:16" }, { "name": "symfony/routing", @@ -746,16 +755,16 @@ }, { "name": "twig/twig", - "version": "v1.24.1", + "version": "v1.24.2", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512" + "reference": "33093f6e310e6976baeac7b14f3a6ec02f2d79b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/3566d311a92aae4deec6e48682dc5a4528c4a512", - "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/33093f6e310e6976baeac7b14f3a6ec02f2d79b7", + "reference": "33093f6e310e6976baeac7b14f3a6ec02f2d79b7", "shasum": "" }, "require": { @@ -803,7 +812,7 @@ "keywords": [ "templating" ], - "time": "2016-05-30 09:11:59" + "time": "2016-09-01 17:50:53" } ], "packages-dev": [ @@ -1067,16 +1076,16 @@ }, { "name": "michelf/php-markdown", - "version": "1.6.0", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/michelf/php-markdown.git", - "reference": "156e56ee036505ec637d761ee62dc425d807183c" + "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/michelf/php-markdown/zipball/156e56ee036505ec637d761ee62dc425d807183c", - "reference": "156e56ee036505ec637d761ee62dc425d807183c", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/1f51cc520948f66cd2af8cbc45a5ee175e774220", + "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220", "shasum": "" }, "require": { @@ -1114,7 +1123,7 @@ "keywords": [ "markdown" ], - "time": "2015-12-24 01:37:31" + "time": "2016-10-29 18:58:20" }, { "name": "nikic/php-parser", @@ -1422,25 +1431,30 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.8", + "version": "1.0.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", - "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4|~5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -1462,20 +1476,20 @@ "keywords": [ "timer" ], - "time": "2016-05-12 18:03:57" + "time": "2017-02-26 11:10:40" }, { "name": "phpunit/php-token-stream", - "version": "1.4.8", + "version": "1.4.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", "shasum": "" }, "require": { @@ -1511,7 +1525,7 @@ "keywords": [ "tokenizer" ], - "time": "2015-09-15 10:49:45" + "time": "2017-02-27 10:12:30" }, { "name": "phpunit/phpunit", @@ -1751,22 +1765,22 @@ }, { "name": "sebastian/comparator", - "version": "1.2.0", + "version": "1.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", "shasum": "" }, "require": { "php": ">=5.3.3", "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" + "sebastian/exporter": "~1.2 || ~2.0" }, "require-dev": { "phpunit/phpunit": "~4.4" @@ -1811,27 +1825,27 @@ "compare", "equality" ], - "time": "2015-07-26 15:48:44" + "time": "2017-01-29 09:50:25" }, { "name": "sebastian/diff", - "version": "1.4.1", + "version": "1.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.8" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", "extra": { @@ -1863,27 +1877,27 @@ "keywords": [ "diff" ], - "time": "2015-12-08 07:14:41" + "time": "2017-05-22 07:24:03" }, { "name": "sebastian/environment", - "version": "1.3.7", + "version": "1.3.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716" + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716", - "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^4.8 || ^5.0" }, "type": "library", "extra": { @@ -1913,7 +1927,7 @@ "environment", "hhvm" ], - "time": "2016-05-17 03:18:57" + "time": "2016-08-18 05:49:44" }, { "name": "sebastian/exporter", @@ -1984,16 +1998,16 @@ }, { "name": "sebastian/recursion-context", - "version": "1.0.2", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791" + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", "shasum": "" }, "require": { @@ -2033,7 +2047,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-11-11 19:50:13" + "time": "2016-10-03 07:41:43" }, { "name": "sebastian/version", @@ -2072,16 +2086,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "2.6.2", + "version": "2.9.1", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "4edb770cb853def6e60c93abb088ad5ac2010c83" + "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/4edb770cb853def6e60c93abb088ad5ac2010c83", - "reference": "4edb770cb853def6e60c93abb088ad5ac2010c83", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dcbed1074f8244661eecddfc2a675430d8d33f62", + "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62", "shasum": "" }, "require": { @@ -2146,7 +2160,7 @@ "phpcs", "standards" ], - "time": "2016-07-13 23:29:13" + "time": "2017-05-22 02:43:20" }, { "name": "symfony/browser-kit", diff --git a/phpBB/config/console.yml b/phpBB/config/console.yml index 1e18a7dd37..55ffd358e4 100644 --- a/phpBB/config/console.yml +++ b/phpBB/config/console.yml @@ -139,3 +139,24 @@ services: - @dbal.conn tags: - { name: console.command } + + console.command.fixup.update_hashes: + class: phpbb\console\command\fixup\update_hashes + arguments: + - @config + - @user + - @dbal.conn + - @passwords.manager + - @passwords.driver_collection + - %passwords.algorithms% + tags: + - { name: console.command } + + console.command.fixup.fix_left_right_ids: + class: phpbb\console\command\fixup\fix_left_right_ids + arguments: + - @user + - @dbal.conn + - @cache.driver + tags: + - { name: console.command } diff --git a/phpBB/config/cron.yml b/phpBB/config/cron.yml index c5b88df181..dc628b43ff 100644 --- a/phpBB/config/cron.yml +++ b/phpBB/config/cron.yml @@ -146,3 +146,17 @@ services: - [set_name, [cron.task.core.tidy_warnings]] tags: - { name: cron.task } + + cron.task.core.update_hashes: + class: phpbb\cron\task\core\update_hashes + arguments: + - @config + - @dbal.conn + - @passwords.update.lock + - @passwords.manager + - @passwords.driver_collection + - %passwords.algorithms% + calls: + - [set_name, [cron.task.core.update_hashes]] + tags: + - { name: cron.task } diff --git a/phpBB/config/password.yml b/phpBB/config/password.yml index cb45ec3d42..938cef7e16 100644 --- a/phpBB/config/password.yml +++ b/phpBB/config/password.yml @@ -122,3 +122,10 @@ services: - @passwords.driver_helper tags: - { name: passwords.driver } + + passwords.update.lock: + class: phpbb\lock\db + arguments: + - update_hashes_lock + - '@config' + - '@dbal.conn' diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index 2f28307c24..417666c09e 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -64,6 +64,12 @@ acp_ext_details_end * Since: 3.1.11-RC1 * Purpose: Add more detailed information on extension after the available information. +acp_ext_details_notice +=== +* Location: adm/style/acp_ext_details.html +* Since: 3.1.11-RC1 +* Purpose: Add extension detail notices after version check information. + acp_ext_list_disabled_name_after === * Location: adm/style/acp_ext_list.html @@ -387,6 +393,13 @@ acp_profile_contact_before * Since: 3.1.6-RC1 * Purpose: Add extra options to custom profile field configuration in the ACP +acp_profile_contact_last +=== +* Locations: + + adm/style/acp_profile.html +* Since: 3.1.11-RC1 +* Purpose: Add contact specific options to custom profile fields in the ACP + acp_profile_step_one_lang_after === * Locations: @@ -687,6 +700,22 @@ forumlist_body_last_post_title_prepend * Since: 3.1.0-a1 * Purpose: Add content before the post title of the latest post in a forum on the forum list. +forumlist_body_subforum_link_append +=== +* Locations: + + styles/prosilver/template/forumlist_body.html + + styles/subsilver2/template/forumlist_body.html +* Since: 3.1.11-RC1 +* Purpose: Add content at the end of subforum link item. + +forumlist_body_subforum_link_prepend +=== +* Locations: + + styles/prosilver/template/forumlist_body.html + + styles/subsilver2/template/forumlist_body.html +* Since: 3.1.11-RC1 +* Purpose: Add content at the start of subforum link item. + forumlist_body_subforums_after === * Locations: @@ -711,6 +740,14 @@ forumlist_body_last_row_after * Since: 3.1.0-b2 * Purpose: Add content after the very last row of the forum list. +index_body_birthday_block_before +=== +* Locations: + + styles/prosilver/template/index_body.html + + styles/subsilver2/template/index_body.html +* Since: 3.1.11-RC1 +* Purpose: Add new statistic blocks before the Birthday block + index_body_block_birthday_append === * Locations: @@ -959,6 +996,20 @@ mcp_topic_postrow_post_details_before * Since: 3.1.10-RC1 * Purpose: Add content before post details in topic moderation +mcp_topic_postrow_post_subject_after +=== +* Locations: + + styles/prosilver/template/mcp_topic.html +* Since: 3.1.11-RC1 +* Purpose: Add content after post subject in topic moderation + +mcp_topic_postrow_post_subject_before +=== +* Locations: + + styles/prosilver/template/mcp_topic.html +* Since: 3.1.11-RC1 +* Purpose: Add content before post subject in topic moderation + mcp_topic_topic_title_after === * Locations: @@ -1963,6 +2014,13 @@ search_results_topic_before * Since: 3.1.0-b4 * Purpose: Add data before search result topics +search_results_topic_title_after +=== +* Locations: + + styles/prosilver/template/search_results.html +* Since: 3.1.11-RC1 +* Purpose: Add data after search results topic title + simple_footer_after === * Locations: diff --git a/phpBB/faq.php b/phpBB/faq.php index 5fe155eab0..cf34ce809a 100644 --- a/phpBB/faq.php +++ b/phpBB/faq.php @@ -25,6 +25,7 @@ $auth->acl($user->data); $user->setup(); $mode = request_var('mode', ''); +$template_file = 'faq_body.html'; // Load the appropriate faq file switch ($mode) @@ -47,13 +48,16 @@ switch ($mode) * @var string lang_file Language file containing the help data * @var string ext_name Vendor and extension name where the help * language file can be loaded from + * @var string template_file Template file name * @since 3.1.4-RC1 + * @changed 3.1.11-RC1 Added template_file var */ $vars = array( 'page_title', 'mode', 'lang_file', 'ext_name', + 'template_file', ); extract($phpbb_dispatcher->trigger_event('core.faq_mode_validation', compact($vars))); @@ -106,7 +110,7 @@ $template->assign_vars(array( page_header($l_title); $template->set_filenames(array( - 'body' => 'faq_body.html') + 'body' => $template_file) ); make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx")); diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index bcecb2f300..5c3c7f30aa 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -318,9 +318,9 @@ class acp_board 'title' => 'ACP_COOKIE_SETTINGS', 'vars' => array( 'legend1' => 'ACP_COOKIE_SETTINGS', - 'cookie_domain' => array('lang' => 'COOKIE_DOMAIN', 'validate' => 'string', 'type' => 'text::255', 'explain' => false), - 'cookie_name' => array('lang' => 'COOKIE_NAME', 'validate' => 'string', 'type' => 'text::16', 'explain' => false), - 'cookie_path' => array('lang' => 'COOKIE_PATH', 'validate' => 'string', 'type' => 'text::255', 'explain' => false), + 'cookie_domain' => array('lang' => 'COOKIE_DOMAIN', 'validate' => 'string', 'type' => 'text::255', 'explain' => true), + 'cookie_name' => array('lang' => 'COOKIE_NAME', 'validate' => 'string', 'type' => 'text::16', 'explain' => true), + 'cookie_path' => array('lang' => 'COOKIE_PATH', 'validate' => 'string', 'type' => 'text::255', 'explain' => true), 'cookie_secure' => array('lang' => 'COOKIE_SECURE', 'validate' => 'bool', 'type' => 'radio:disabled_enabled', 'explain' => true), ) ); diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index 9e72ab83f8..f0348817c8 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -212,6 +212,15 @@ class acp_extensions meta_refresh(0, $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('enable.' . $ext_name)); } } + + // Update custom style for admin area + $this->template->set_custom_style(array( + array( + 'name' => 'adm', + 'ext_path' => 'adm/style/', + ), + ), array($phpbb_root_path . 'adm/style')); + $this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_ENABLE', time(), array($ext_name)); } catch (\phpbb\db\migration\exception $e) diff --git a/phpBB/includes/acp/acp_jabber.php b/phpBB/includes/acp/acp_jabber.php index a482b41e1d..3b958c0ea1 100644 --- a/phpBB/includes/acp/acp_jabber.php +++ b/phpBB/includes/acp/acp_jabber.php @@ -50,13 +50,16 @@ class acp_jabber $this->tpl_name = 'acp_jabber'; $this->page_title = 'ACP_JABBER_SETTINGS'; - $jab_enable = request_var('jab_enable', (bool) $config['jab_enable']); - $jab_host = request_var('jab_host', (string) $config['jab_host']); - $jab_port = request_var('jab_port', (int) $config['jab_port']); - $jab_username = request_var('jab_username', (string) $config['jab_username']); - $jab_password = request_var('jab_password', (string) $config['jab_password']); - $jab_package_size = request_var('jab_package_size', (int) $config['jab_package_size']); - $jab_use_ssl = request_var('jab_use_ssl', (bool) $config['jab_use_ssl']); + $jab_enable = request_var('jab_enable', (bool) $config['jab_enable']); + $jab_host = request_var('jab_host', (string) $config['jab_host']); + $jab_port = request_var('jab_port', (int) $config['jab_port']); + $jab_username = request_var('jab_username', (string) $config['jab_username']); + $jab_password = request_var('jab_password', (string) $config['jab_password']); + $jab_package_size = request_var('jab_package_size', (int) $config['jab_package_size']); + $jab_use_ssl = request_var('jab_use_ssl', (bool) $config['jab_use_ssl']); + $jab_verify_peer = request_var('jab_verify_peer', (bool) $config['jab_verify_peer']); + $jab_verify_peer_name = request_var('jab_verify_peer_name', (bool) $config['jab_verify_peer_name']); + $jab_allow_self_signed = request_var('jab_allow_self_signed', (bool) $config['jab_allow_self_signed']); $form_name = 'acp_jabber'; add_form_key($form_name); @@ -76,7 +79,7 @@ class acp_jabber // Is this feature enabled? Then try to establish a connection if ($jab_enable) { - $jabber = new jabber($jab_host, $jab_port, $jab_username, $jab_password, $jab_use_ssl); + $jabber = new jabber($jab_host, $jab_port, $jab_username, $jab_password, $jab_use_ssl, $jab_verify_peer, $jab_verify_peer_name, $jab_allow_self_signed); if (!$jabber->connect()) { @@ -116,6 +119,9 @@ class acp_jabber } set_config('jab_package_size', $jab_package_size); set_config('jab_use_ssl', $jab_use_ssl); + set_config('jab_verify_peer', $jab_verify_peer); + set_config('jab_verify_peer_name', $jab_verify_peer_name); + set_config('jab_allow_self_signed', $jab_allow_self_signed); add_log('admin', 'LOG_' . $log); trigger_error($message . adm_back_link($this->u_action)); @@ -131,6 +137,9 @@ class acp_jabber 'JAB_PASSWORD' => $jab_password !== '' ? '********' : '', 'JAB_PACKAGE_SIZE' => $jab_package_size, 'JAB_USE_SSL' => $jab_use_ssl, + 'JAB_VERIFY_PEER' => $jab_verify_peer, + 'JAB_VERIFY_PEER_NAME' => $jab_verify_peer_name, + 'JAB_ALLOW_SELF_SIGNED' => $jab_allow_self_signed, 'S_CAN_USE_SSL' => jabber::can_use_ssl(), 'S_GTALK_NOTE' => (!@function_exists('dns_get_record')) ? true : false, )); diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index 8858d1a307..f671f33ed0 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -679,9 +679,11 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb * @var string uid The BBCode UID * @var string bitfield The BBCode Bitfield * @var int flags The BBCode Flags + * @var string message_parser The message_parser object * @since 3.1.0-a1 + * @changed 3.1.11-RC1 Added message_parser to vars */ - $vars = array('text', 'uid', 'bitfield', 'flags'); + $vars = array('text', 'uid', 'bitfield', 'flags', 'message_parser'); extract($phpbb_dispatcher->trigger_event('core.modify_text_for_storage_after', compact($vars))); return $message_parser->warn_msg; diff --git a/phpBB/includes/functions_jabber.php b/phpBB/includes/functions_jabber.php index bd2e9e93ac..c9ec6fea61 100644 --- a/phpBB/includes/functions_jabber.php +++ b/phpBB/includes/functions_jabber.php @@ -41,6 +41,9 @@ class jabber var $username; var $password; var $use_ssl; + var $verify_peer; + var $verify_peer_name; + var $allow_self_signed; var $resource = 'functions_jabber.phpbb.php'; var $enable_logging; @@ -49,8 +52,18 @@ class jabber var $features = array(); /** + * Constructor + * + * @param string $server Jabber server + * @param int $port Jabber server port + * @param string $username Jabber username or JID + * @param string $password Jabber password + * @param boold $use_ssl Use ssl + * @param bool $verify_peer Verify SSL certificate + * @param bool $verify_peer_name Verify Jabber peer name + * @param bool $allow_self_signed Allow self signed certificates */ - function jabber($server, $port, $username, $password, $use_ssl = false) + function __construct($server, $port, $username, $password, $use_ssl = false, $verify_peer = true, $verify_peer_name = true, $allow_self_signed = false) { $this->connect_server = ($server) ? $server : 'localhost'; $this->port = ($port) ? $port : 5222; @@ -71,6 +84,9 @@ class jabber $this->password = $password; $this->use_ssl = ($use_ssl && self::can_use_ssl()) ? true : false; + $this->verify_peer = $verify_peer; + $this->verify_peer_name = $verify_peer_name; + $this->allow_self_signed = $allow_self_signed; // Change port if we use SSL if ($this->port == 5222 && $this->use_ssl) @@ -96,7 +112,7 @@ class jabber */ static public function can_use_tls() { - if (!@extension_loaded('openssl') || !function_exists('stream_socket_enable_crypto') || !function_exists('stream_get_meta_data') || !function_exists('socket_set_blocking') || !function_exists('stream_get_wrappers')) + if (!@extension_loaded('openssl') || !function_exists('stream_socket_enable_crypto') || !function_exists('stream_get_meta_data') || !function_exists('stream_set_blocking') || !function_exists('stream_get_wrappers')) { return false; } @@ -139,7 +155,7 @@ class jabber $this->session['ssl'] = $this->use_ssl; - if ($this->open_socket($this->connect_server, $this->port, $this->use_ssl)) + if ($this->open_socket($this->connect_server, $this->port, $this->use_ssl, $this->verify_peer, $this->verify_peer_name, $this->allow_self_signed)) { $this->send("<?xml version='1.0' encoding='UTF-8' ?" . ">\n"); $this->send("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n"); @@ -227,10 +243,13 @@ class jabber * @param string $server host to connect to * @param int $port port number * @param bool $use_ssl use ssl or not + * @param bool $verify_peer verify ssl certificate + * @param bool $verify_peer_name verify peer name + * @param bool $allow_self_signed allow self-signed ssl certificates * @access public * @return bool */ - function open_socket($server, $port, $use_ssl = false) + function open_socket($server, $port, $use_ssl, $verify_peer, $verify_peer_name, $allow_self_signed) { if (@function_exists('dns_get_record')) { @@ -241,12 +260,26 @@ class jabber } } - $server = $use_ssl ? 'ssl://' . $server : $server; + $options = array(); - if ($this->connection = @fsockopen($server, $port, $errorno, $errorstr, $this->timeout)) + if ($use_ssl) { - socket_set_blocking($this->connection, 0); - socket_set_timeout($this->connection, 60); + $remote_socket = 'ssl://' . $server . ':' . $port; + + // Set ssl context options, see http://php.net/manual/en/context.ssl.php + $options['ssl'] = array('verify_peer' => $verify_peer, 'verify_peer_name' => $verify_peer_name, 'allow_self_signed' => $allow_self_signed); + } + else + { + $remote_socket = $server . ':' . $port; + } + + $socket_context = stream_context_create($options); + + if ($this->connection = @stream_socket_client($remote_socket, $errorno, $errorstr, $this->timeout, STREAM_CLIENT_CONNECT, $socket_context)) + { + stream_set_blocking($this->connection, 0); + stream_set_timeout($this->connection, 60); return true; } @@ -563,7 +596,7 @@ class jabber case 'proceed': // continue switching to TLS $meta = stream_get_meta_data($this->connection); - socket_set_blocking($this->connection, 1); + stream_set_blocking($this->connection, 1); if (!stream_socket_enable_crypto($this->connection, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { @@ -571,7 +604,7 @@ class jabber return false; } - socket_set_blocking($this->connection, $meta['blocked']); + stream_set_blocking($this->connection, $meta['blocked']); $this->session['tls'] = true; // new stream diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index a6e4cb0679..98975b9d8f 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -312,10 +312,16 @@ class messenger /** * Send the mail out to the recipients set previously in var $this->addresses + * + * @param int $method User notification method NOTIFY_EMAIL|NOTIFY_IM|NOTIFY_BOTH + * @param bool $break Flag indicating if the function only formats the subject + * and the message without sending it + * + * @return bool */ function send($method = NOTIFY_EMAIL, $break = false) { - global $config, $user; + global $config, $user, $phpbb_dispatcher; // We add some standard variables we always use, no need to specify them always $this->assign_vars(array( @@ -324,6 +330,30 @@ class messenger 'SITENAME' => htmlspecialchars_decode($config['sitename']), )); + $subject = $this->subject; + $message = $this->msg; + /** + * Event to modify notification message text before parsing + * + * @event core.modify_notification_message + * @var int method User notification method NOTIFY_EMAIL|NOTIFY_IM|NOTIFY_BOTH + * @var bool break Flag indicating if the function only formats the subject + * and the message without sending it + * @var string subject The message subject + * @var string message The message text + * @since 3.1.11-RC1 + */ + $vars = array( + 'method', + 'break', + 'subject', + 'message', + ); + extract($phpbb_dispatcher->trigger_event('core.modify_notification_message', compact($vars))); + $this->subject = $subject; + $this->msg = $message; + unset($subject, $message); + // Parse message through template $this->msg = trim($this->template->assign_display('body')); @@ -625,7 +655,7 @@ class messenger if (!$use_queue) { include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx); - $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl']); + $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl'], $config['jab_verify_peer'], $config['jab_verify_peer_name'], $config['jab_allow_self_signed']); if (!$this->jabber->connect()) { @@ -800,7 +830,7 @@ class queue } include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx); - $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl']); + $this->jabber = new jabber($config['jab_host'], $config['jab_port'], $config['jab_username'], htmlspecialchars_decode($config['jab_password']), $config['jab_use_ssl'], $config['jab_verify_peer'], $config['jab_verify_peer_name'], $config['jab_allow_self_signed']); if (!$this->jabber->connect()) { @@ -1057,7 +1087,7 @@ function smtpmail($addresses, $subject, $message, &$err_msg, $headers = false) $options['ssl'] = array('verify_peer' => $verify_peer, 'verify_peer_name' => $verify_peer_name, 'allow_self_signed' => $allow_self_signed); $socket_context = stream_context_create($options); - $smtp->socket = stream_socket_client($remote_socket, $errno, $errstr, 20, STREAM_CLIENT_CONNECT, $socket_context); + $smtp->socket = @stream_socket_client($remote_socket, $errno, $errstr, 20, STREAM_CLIENT_CONNECT, $socket_context); $collector->uninstall(); $error_contents = $collector->format_errors(); diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 71c89a0e62..9712b6e922 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -1315,7 +1315,7 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id */ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $softdelete_reason = '') { - global $db, $user, $auth, $phpbb_container; + global $db, $user, $auth, $phpbb_container, $phpbb_dispatcher; global $config, $phpEx, $phpbb_root_path; // Specify our post mode @@ -1566,6 +1566,34 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $ sync('topic_reported', 'topic_id', array($topic_id)); } + /** + * This event is used for performing actions directly after a post or topic + * has been deleted. + * + * @event core.delete_post_after + * @var int forum_id Post forum ID + * @var int topic_id Post topic ID + * @var int post_id Post ID + * @var array data Post data + * @var bool is_soft Soft delete flag + * @var string softdelete_reason Soft delete reason + * @var string post_mode delete_topic, delete_first_post, delete_last_post or delete + * @var mixed next_post_id Next post ID in the topic (post ID or false) + * + * @since 3.1.11-RC1 + */ + $vars = array( + 'forum_id', + 'topic_id', + 'post_id', + 'data', + 'is_soft', + 'softdelete_reason', + 'post_mode', + 'next_post_id', + ); + extract($phpbb_dispatcher->trigger_event('core.delete_post_after', compact($vars))); + return $next_post_id; } diff --git a/phpBB/includes/mcp/mcp_ban.php b/phpBB/includes/mcp/mcp_ban.php index 4d2151fded..2f3405f915 100644 --- a/phpBB/includes/mcp/mcp_ban.php +++ b/phpBB/includes/mcp/mcp_ban.php @@ -28,7 +28,10 @@ class mcp_ban global $db, $user, $auth, $template, $request, $phpbb_dispatcher; global $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('user_ban')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } // Include the admin banning interface... include($phpbb_root_path . 'includes/acp/acp_ban.' . $phpEx); diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 491697d2e9..69c66639df 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -630,10 +630,13 @@ function mcp_move_topic($topic_ids) * * @event core.mcp_main_modify_shadow_sql * @var array shadow SQL array to be used by $db->sql_build_array + * @var array row Topic data * @since 3.1.11-RC1 + * @changed 3.1.11-RC1 Added variable: row */ $vars = array( 'shadow', + 'row', ); extract($phpbb_dispatcher->trigger_event('core.mcp_main_modify_shadow_sql', compact($vars))); @@ -1297,11 +1300,14 @@ function mcp_fork_topic($topic_ids) * Perform actions before forked topic is created. * * @event core.mcp_main_modify_fork_sql - * @var array sql_ary SQL array to be used by $db->sql_build_array + * @var array sql_ary SQL array to be used by $db->sql_build_array + * @var array topic_row Topic data * @since 3.1.11-RC1 + * @changed 3.1.11-RC1 Added variable: topic_row */ $vars = array( 'sql_ary', + 'topic_row', ); extract($phpbb_dispatcher->trigger_event('core.mcp_main_modify_fork_sql', compact($vars))); diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php index 2dcfcd608b..1cf4a74234 100644 --- a/phpBB/includes/mcp/mcp_post.php +++ b/phpBB/includes/mcp/mcp_post.php @@ -24,8 +24,8 @@ if (!defined('IN_PHPBB')) */ function mcp_post_details($id, $mode, $action) { - global $phpEx, $phpbb_root_path, $config; - global $template, $db, $user, $auth, $cache; + global $phpEx, $phpbb_root_path, $config, $request; + global $template, $db, $user, $auth, $cache, $phpbb_container; global $phpbb_dispatcher; $user->add_lang('posting'); @@ -53,7 +53,10 @@ function mcp_post_details($id, $mode, $action) if ($auth->acl_get('m_info', $post_info['forum_id'])) { $ip = request_var('ip', ''); - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('user_ipwhois')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $template->assign_vars(array( 'RETURN_POST' => sprintf($user->lang['RETURN_POST'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&mode=$mode&p=$post_id") . '">', '</a>'), @@ -355,7 +358,11 @@ function mcp_post_details($id, $mode, $action) // Get IP if ($auth->acl_get('m_info', $post_info['forum_id'])) { - $rdns_ip_num = request_var('rdns', ''); + /** @var \phpbb\pagination $pagination */ + $pagination = $phpbb_container->get('pagination'); + + $rdns_ip_num = $request->variable('rdns', ''); + $start_users = $request->variable('start_users', 0); if ($rdns_ip_num != 'all') { @@ -364,23 +371,46 @@ function mcp_post_details($id, $mode, $action) ); } + $num_users = false; + if ($start_users) + { + $num_users = phpbb_get_num_posters_for_ip($db, $post_info['poster_ip']); + $start_users = $pagination->validate_start($start_users, $config['posts_per_page'], $num_users); + } + // Get other users who've posted under this IP $sql = 'SELECT poster_id, COUNT(poster_id) as postings FROM ' . POSTS_TABLE . " WHERE poster_ip = '" . $db->sql_escape($post_info['poster_ip']) . "' + AND poster_id <> " . (int) $post_info['poster_id'] . " GROUP BY poster_id - ORDER BY postings DESC"; - $result = $db->sql_query($sql); + ORDER BY postings DESC, poster_id ASC"; + $result = $db->sql_query_limit($sql, $config['posts_per_page'], $start_users); + $page_users = 0; while ($row = $db->sql_fetchrow($result)) { - // Fill the user select list with users who have posted under this IP - if ($row['poster_id'] != $post_info['poster_id']) + $page_users++; + $users_ary[$row['poster_id']] = $row; + } + $db->sql_freeresult($result); + + if ($page_users == $config['posts_per_page'] || $start_users) + { + if ($num_users === false) { - $users_ary[$row['poster_id']] = $row; + $num_users = phpbb_get_num_posters_for_ip($db, $post_info['poster_ip']); } + + $pagination->generate_template_pagination( + $url . '&i=main&mode=post_details', + 'pagination', + 'start_users', + $num_users, + $config['posts_per_page'], + $start_users + ); } - $db->sql_freeresult($result); if (sizeof($users_ary)) { @@ -415,16 +445,26 @@ function mcp_post_details($id, $mode, $action) // A compound index on poster_id, poster_ip (posts table) would help speed up this query a lot, // but the extra size is only valuable if there are persons having more than a thousands posts. // This is better left to the really really big forums. + $start_ips = $request->variable('start_ips', 0); + + $num_ips = false; + if ($start_ips) + { + $num_ips = phpbb_get_num_ips_for_poster($db, $post_info['poster_id']); + $start_ips = $pagination->validate_start($start_ips, $config['posts_per_page'], $num_ips); + } $sql = 'SELECT poster_ip, COUNT(poster_ip) AS postings FROM ' . POSTS_TABLE . ' WHERE poster_id = ' . $post_info['poster_id'] . " GROUP BY poster_ip - ORDER BY postings DESC"; - $result = $db->sql_query($sql); + ORDER BY postings DESC, poster_ip ASC"; + $result = $db->sql_query_limit($sql, $config['posts_per_page'], $start_ips); + $page_ips = 0; while ($row = $db->sql_fetchrow($result)) { + $page_ips++; $hostname = (($rdns_ip_num == $row['poster_ip'] || $rdns_ip_num == 'all') && $row['poster_ip']) ? @gethostbyaddr($row['poster_ip']) : ''; $template->assign_block_vars('iprow', array( @@ -439,6 +479,23 @@ function mcp_post_details($id, $mode, $action) } $db->sql_freeresult($result); + if ($page_ips == $config['posts_per_page'] || $start_ips) + { + if ($num_ips === false) + { + $num_ips = phpbb_get_num_ips_for_poster($db, $post_info['poster_id']); + } + + $pagination->generate_template_pagination( + $url . '&i=main&mode=post_details', + 'pagination_ips', + 'start_ips', + $num_ips, + $config['posts_per_page'], + $start_ips + ); + } + $user_select = ''; if (sizeof($usernames_ary)) @@ -457,6 +514,44 @@ function mcp_post_details($id, $mode, $action) } /** + * Get the number of posters for a given ip + * + * @param \phpbb\db\driver\driver_interface $db DBAL interface + * @param string $poster_ip IP + * @return int Number of posters + */ +function phpbb_get_num_posters_for_ip(\phpbb\db\driver\driver_interface $db, $poster_ip) +{ + $sql = 'SELECT COUNT(DISTINCT poster_id) as num_users + FROM ' . POSTS_TABLE . " + WHERE poster_ip = '" . $db->sql_escape($poster_ip) . "'"; + $result = $db->sql_query($sql); + $num_users = (int) $db->sql_fetchfield('num_users'); + $db->sql_freeresult($result); + + return $num_users; +} + +/** + * Get the number of ips for a given poster + * + * @param \phpbb\db\driver\driver_interface $db + * @param int $poster_id Poster user ID + * @return int Number of IPs for given poster + */ +function phpbb_get_num_ips_for_poster(\phpbb\db\driver\driver_interface $db, $poster_id) +{ + $sql = 'SELECT COUNT(DISTINCT poster_ip) as num_ips + FROM ' . POSTS_TABLE . ' + WHERE poster_id = ' . (int) $poster_id; + $result = $db->sql_query($sql); + $num_ips = (int) $db->sql_fetchfield('num_ips'); + $db->sql_freeresult($result); + + return $num_ips; +} + +/** * Change a post's poster */ function change_poster(&$post_info, $userdata) diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 2217f8fdeb..d5415302c8 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -407,6 +407,7 @@ function mcp_topic_view($id, $mode, $action) function split_topic($action, $topic_id, $to_forum_id, $subject) { global $db, $template, $user, $phpEx, $phpbb_root_path, $auth, $config; + global $phpbb_dispatcher; $post_id_list = request_var('post_id_list', array(0)); $forum_id = request_var('forum_id', 0); @@ -567,6 +568,47 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) WHERE post_id = {$post_id_list[0]}"; $db->sql_query($sql); + // Grab data for first post in split topic + $sql_array = array( + 'SELECT' => 'p.post_id, p.forum_id, p.poster_id, p.post_text, f.enable_indexing', + 'FROM' => array( + POSTS_TABLE => 'p', + ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(FORUMS_TABLE => 'f'), + 'ON' => 'p.forum_id = f.forum_id', + ) + ), + 'WHERE' => "post_id = {$post_id_list[0]}", + ); + $sql = $db->sql_build_query('SELECT', $sql_array); + $result = $db->sql_query($sql); + $first_post_data = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + // Index first post as if it were edited + if ($first_post_data['enable_indexing']) + { + // Select the search method and do some additional checks to ensure it can actually be utilised + $search_type = $config['search_type']; + + if (!class_exists($search_type)) + { + trigger_error('NO_SUCH_SEARCH_MODULE'); + } + + $error = false; + $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher); + + if ($error) + { + trigger_error($error); + } + + $search->index('edit', $first_post_data['post_id'], $first_post_data['post_text'], $subject, $first_post_data['poster_id'], $first_post_data['forum_id']); + } + // Copy topic subscriptions to new topic $sql = 'SELECT user_id, notify_status FROM ' . TOPICS_WATCH_TABLE . ' @@ -634,7 +676,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) */ function merge_posts($topic_id, $to_topic_id) { - global $db, $template, $user, $phpEx, $phpbb_root_path, $auth; + global $db, $template, $user, $phpEx, $phpbb_root_path, $auth, $phpbb_dispatcher; if (!$to_topic_id) { @@ -735,6 +777,20 @@ function merge_posts($topic_id, $to_topic_id) $redirect = request_var('redirect', "{$phpbb_root_path}viewtopic.$phpEx?f=$to_forum_id&t=$to_topic_id"); $redirect = reapply_sid($redirect); + /** + * Perform additional actions after merging posts. + * + * @event core.mcp_topics_merge_posts_after + * @var int topic_id The topic ID from which posts are being moved + * @var int to_topic_id The topic ID to which posts are being moved + * @since 3.1.11-RC1 + */ + $vars = array( + 'topic_id', + 'to_topic_id', + ); + extract($phpbb_dispatcher->trigger_event('core.mcp_topics_merge_posts_after', compact($vars))); + meta_refresh(3, $redirect); trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); } diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index d365e8b489..4906eec1bb 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -450,6 +450,17 @@ function compose_pm($id, $mode, $action, $user_folders = array()) $message_attachment = 0; $message_text = $message_subject = ''; + /** + * Predefine message text and subject + * + * @event core.ucp_pm_compose_predefined_message + * @var string message_text Message text + * @var string message_subject Messate subject + * @since 3.1.11-RC1 + */ + $vars = array('message_text', 'message_subject'); + extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_predefined_message', compact($vars))); + if ($to_user_id && $to_user_id != ANONYMOUS && $action == 'post') { $address_list['u'][$to_user_id] = 'to'; diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 8b5e113b16..8bb5327028 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -345,11 +345,14 @@ $lang = array_merge($lang, array( // Cookie Settings $lang = array_merge($lang, array( - 'ACP_COOKIE_SETTINGS_EXPLAIN' => 'These details define the data used to send cookies to your users browsers. In most cases the default values for the cookie settings should be sufficient. If you do need to change any do so with care, incorrect settings can prevent users logging in.', + 'ACP_COOKIE_SETTINGS_EXPLAIN' => 'These details define the data used to send cookies to your users browsers. In most cases the default values for the cookie settings should be sufficient. If you do need to change any do so with care, incorrect settings can prevent users logging in. If you have problems with users staying logging in to your board, visit the <b><a href="https://www.phpbb.com/support/go/cookie-settings/">phpBB.com Knowledge Base - Fixing incorrect cookie settings</a></b>.', 'COOKIE_DOMAIN' => 'Cookie domain', + 'COOKIE_DOMAIN_EXPLAIN' => 'In most cases the cookie domain is optional. Leave it blank if you are unsure.<br /><br /> In the case where you have a board integrated with other software or have multiple domains, then to determine the cookie domain you need to do the following. If you have something like <i>example.com</i> and <i>forums.example.com</i>, or perhaps <i>forums.example.com</i> and <i>blog.example.com</i>. Remove the subdomains until you find the common domain, <i>example.com</i>. Now add a dot in front of the common domain and you would enter .example.com (note the dot at the beginning).', 'COOKIE_NAME' => 'Cookie name', + 'COOKIE_NAME_EXPLAIN' => 'This can be anything what you want, make it original. Whenever the cookie settings are changed the name of the cookie should be changed.', 'COOKIE_PATH' => 'Cookie path', + 'COOKIE_PATH_EXPLAIN' => 'Note that this is always a slash, it does not matter what your board URL is.', 'COOKIE_SECURE' => 'Cookie secure', 'COOKIE_SECURE_EXPLAIN' => 'If your server is running via SSL set this to enabled else leave as disabled. Having this enabled and not running via SSL will result in server errors during redirects.', 'ONLINE_LENGTH' => 'View online time span', @@ -589,20 +592,26 @@ $lang = array_merge($lang, array( $lang = array_merge($lang, array( 'ACP_JABBER_SETTINGS_EXPLAIN' => 'Here you can enable and control the use of Jabber for instant messaging and board notifications. Jabber is an open source protocol and therefore available for use by anyone. Some Jabber servers include gateways or transports which allow you to contact users on other networks. Not all servers offer all transports and changes in protocols can prevent transports from operating. Please be sure to enter already registered account details - phpBB will use the details you enter here as is.', - 'JAB_ENABLE' => 'Enable Jabber', - 'JAB_ENABLE_EXPLAIN' => 'Enables use of Jabber messaging and notifications.', - 'JAB_GTALK_NOTE' => 'Please note that GTalk will not work because the <samp>dns_get_record</samp> function could not be found. This function is not available in PHP4, and is not implemented on Windows platforms. It currently does not work on BSD-based systems, including Mac OS.', - 'JAB_PACKAGE_SIZE' => 'Jabber package size', - 'JAB_PACKAGE_SIZE_EXPLAIN' => 'This is the number of messages sent in one package. If set to 0 the message is sent immediately and will not be queued for later sending.', - 'JAB_PASSWORD' => 'Jabber password', - 'JAB_PASSWORD_EXPLAIN' => '<em><strong>Warning:</strong> This password will be stored as plain text in the database, visible to everybody who can access your database or who can view this configuration page.</em>', - 'JAB_PORT' => 'Jabber port', - 'JAB_PORT_EXPLAIN' => 'Leave blank unless you know it is not port 5222.', - 'JAB_SERVER' => 'Jabber server', - 'JAB_SERVER_EXPLAIN' => 'See %sjabber.org%s for a list of servers.', - 'JAB_SETTINGS_CHANGED' => 'Jabber settings changed successfully.', - 'JAB_USE_SSL' => 'Use SSL to connect', - 'JAB_USE_SSL_EXPLAIN' => 'If enabled a secure connection is tried to be established. The Jabber port will be modified to 5223 if port 5222 is specified.', - 'JAB_USERNAME' => 'Jabber username or JID', - 'JAB_USERNAME_EXPLAIN' => 'Specify a registered username or a valid JID. The username will not be checked for validity. If you only specify a username, then your JID will be the username and the server you specified above. Else, specify a valid JID, for example user@jabber.org.', + 'JAB_ALLOW_SELF_SIGNED' => 'Allow self-signed SSL certificates', + 'JAB_ALLOW_SELF_SIGNED_EXPLAIN' => 'Allow connections to Jabber server with self-signed SSL certificate.<em><strong>Warning:</strong> Allowing self-signed SSL certificates may cause security implications.</em>', + 'JAB_ENABLE' => 'Enable Jabber', + 'JAB_ENABLE_EXPLAIN' => 'Enables use of Jabber messaging and notifications.', + 'JAB_GTALK_NOTE' => 'Please note that GTalk will not work because the <samp>dns_get_record</samp> function could not be found. This function is not available in PHP4, and is not implemented on Windows platforms. It currently does not work on BSD-based systems, including Mac OS.', + 'JAB_PACKAGE_SIZE' => 'Jabber package size', + 'JAB_PACKAGE_SIZE_EXPLAIN' => 'This is the number of messages sent in one package. If set to 0 the message is sent immediately and will not be queued for later sending.', + 'JAB_PASSWORD' => 'Jabber password', + 'JAB_PASSWORD_EXPLAIN' => '<em><strong>Warning:</strong> This password will be stored as plain text in the database, visible to everybody who can access your database or who can view this configuration page.</em>', + 'JAB_PORT' => 'Jabber port', + 'JAB_PORT_EXPLAIN' => 'Leave blank unless you know it is not port 5222.', + 'JAB_SERVER' => 'Jabber server', + 'JAB_SERVER_EXPLAIN' => 'See %sjabber.org%s for a list of servers.', + 'JAB_SETTINGS_CHANGED' => 'Jabber settings changed successfully.', + 'JAB_USE_SSL' => 'Use SSL to connect', + 'JAB_USE_SSL_EXPLAIN' => 'If enabled a secure connection is tried to be established. The Jabber port will be modified to 5223 if port 5222 is specified.', + 'JAB_USERNAME' => 'Jabber username or JID', + 'JAB_USERNAME_EXPLAIN' => 'Specify a registered username or a valid JID. The username will not be checked for validity. If you only specify a username, then your JID will be the username and the server you specified above. Else, specify a valid JID, for example user@jabber.org.', + 'JAB_VERIFY_PEER' => 'Verify SSL certificate', + 'JAB_VERIFY_PEER_EXPLAIN' => 'Require verification of SSL certificate used by Jabber server.<em><strong>Warning:</strong> Connecting peers with unverified SSL certificates may cause security implications.</em>', + 'JAB_VERIFY_PEER_NAME' => 'Verify Jabber peer name', + 'JAB_VERIFY_PEER_NAME_EXPLAIN' => 'Require verification of peer name for Jabber servers using SSL / TLS connections.<em><strong>Warning:</strong> Connecting to unverified peers may cause security implications.</em>', )); diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php index 6989f26f72..4e27be48cc 100644 --- a/phpBB/language/en/cli.php +++ b/phpBB/language/en/cli.php @@ -55,6 +55,7 @@ $lang = array_merge($lang, array( 'CLI_DESCRIPTION_DISABLE_EXTENSION' => 'Disables the specified extension.', 'CLI_DESCRIPTION_ENABLE_EXTENSION' => 'Enables the specified extension.', 'CLI_DESCRIPTION_FIND_MIGRATIONS' => 'Finds migrations that are not depended upon.', + 'CLI_DESCRIPTION_FIX_LEFT_RIGHT_IDS' => 'Repairs the tree structure of the forums and modules.', 'CLI_DESCRIPTION_GET_CONFIG' => 'Gets a configuration option’s value', 'CLI_DESCRIPTION_INCREMENT_CONFIG' => 'Increments a configuration option’s integer value', 'CLI_DESCRIPTION_LIST_EXTENSIONS' => 'Lists all extensions in the database and on the filesystem.', @@ -64,6 +65,7 @@ $lang = array_merge($lang, array( 'CLI_DESCRIPTION_RECALCULATE_EMAIL_HASH' => 'Recalculates the user_email_hash column of the users table.', 'CLI_DESCRIPTION_SET_ATOMIC_CONFIG' => 'Sets a configuration option’s value only if the old matches the current value', 'CLI_DESCRIPTION_SET_CONFIG' => 'Sets a configuration option’s value', + 'CLI_DESCRIPTION_UPDATE_HASH_BCRYPT' => 'Updates outdated password hashes to be hashed with bcrypt.', 'CLI_EXTENSION_DISABLE_FAILURE' => 'Could not disable extension %s', 'CLI_EXTENSION_DISABLE_SUCCESS' => 'Successfully disabled extension %s', @@ -77,7 +79,9 @@ $lang = array_merge($lang, array( 'CLI_EXTENSIONS_DISABLED' => 'Disabled', 'CLI_EXTENSIONS_ENABLED' => 'Enabled', + 'CLI_FIXUP_FIX_LEFT_RIGHT_IDS_SUCCESS' => 'Successfully repaired the tree structure of the forums and modules.', 'CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS' => 'Successfully recalculated all email hashes.', + 'CLI_FIXUP_UPDATE_HASH_BCRYPT_SUCCESS' => 'Successfully updated outdated password hashes to bcrypt.' )); // Additional help for commands. diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index b93476b3bb..b1982958d5 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -101,7 +101,10 @@ switch ($mode) { case 'team': // Display a listing of board admins, moderators - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('user_get_id_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $page_title = $user->lang['THE_TEAM']; $template_html = 'memberlist_team.html'; diff --git a/phpBB/phpbb/cache/driver/memcache.php b/phpBB/phpbb/cache/driver/memcache.php index caa82fb0b1..57f138f574 100644 --- a/phpBB/phpbb/cache/driver/memcache.php +++ b/phpBB/phpbb/cache/driver/memcache.php @@ -52,8 +52,8 @@ class memcache extends \phpbb\cache\driver\memory $this->memcache = new \Memcache; foreach (explode(',', PHPBB_ACM_MEMCACHE) as $u) { - $parts = explode('/', $u); - $this->memcache->addServer(trim($parts[0]), trim($parts[1])); + preg_match('#(.*)/(\d+)#', $u, $parts); + $this->memcache->addServer(trim($parts[1]), (int) trim($parts[2])); } $this->flags = (PHPBB_ACM_MEMCACHE_COMPRESS) ? MEMCACHE_COMPRESSED : 0; } diff --git a/phpBB/phpbb/cache/driver/memcached.php b/phpBB/phpbb/cache/driver/memcached.php index 105e763af4..a7da22d7e8 100644 --- a/phpBB/phpbb/cache/driver/memcached.php +++ b/phpBB/phpbb/cache/driver/memcached.php @@ -67,8 +67,8 @@ class memcached extends \phpbb\cache\driver\memory foreach (explode(',', PHPBB_ACM_MEMCACHE) as $u) { - $parts = explode('/', $u); - $this->memcached->addServer(trim($parts[0]), trim($parts[1])); + preg_match('#(.*)/(\d+)#', $u, $parts); + $this->memcache->addServer(trim($parts[1]), (int) trim($parts[2])); } } diff --git a/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php b/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php new file mode 100644 index 0000000000..f55e1761bc --- /dev/null +++ b/phpBB/phpbb/console/command/fixup/fix_left_right_ids.php @@ -0,0 +1,134 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\console\command\fixup; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class fix_left_right_ids extends \phpbb\console\command\command +{ + /** @var \phpbb\user */ + protected $user; + + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\cache\driver\driver_interface */ + protected $cache; + + /** + * Constructor + * + * @param \phpbb\user $user User instance + * @param \phpbb\db\driver\driver_interface $db Database connection + * @param \phpbb\cache\driver\driver_interface $cache Cache instance + */ + public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache) + { + $this->user = $user; + $this->db = $db; + $this->cache = $cache; + + parent::__construct($user); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('fixup:fix-left-right-ids') + ->setDescription($this->user->lang('CLI_DESCRIPTION_FIX_LEFT_RIGHT_IDS')) + ; + } + + /** + * Executes the command fixup:fix-left-right-ids. + * + * Repairs the tree structure of the forums and modules. + * The code is mainly borrowed from Support toolkit for phpBB Olympus + * + * @param InputInterface $input An InputInterface instance + * @param OutputInterface $output An OutputInterface instance + * + * @return void + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + // Fix Left/Right IDs for the modules table + $result = $this->db->sql_query('SELECT DISTINCT(module_class) FROM ' . MODULES_TABLE); + while ($row = $this->db->sql_fetchrow($result)) + { + $i = 1; + $where = array("module_class = '" . $this->db->sql_escape($row['module_class']) . "'"); + $this->fix_ids_tree($i, 'module_id', MODULES_TABLE, 0, $where); + } + $this->db->sql_freeresult($result); + + // Fix the Left/Right IDs for the forums table + $i = 1; + $this->fix_ids_tree($i, 'forum_id', FORUMS_TABLE); + + $this->cache->purge(); + + $output->writeln('<info>' . $this->user->lang('CLI_FIXUP_FIX_LEFT_RIGHT_IDS_SUCCESS') . '</info>'); + } + + /** + * Item's tree structure rebuild helper + * The item is either forum or ACP/MCP/UCP module + * + * @param int $i Item id offset index + * @param string $field The key field to fix, forum_id|module_id + * @param string $table The table name to perform, FORUMS_TABLE|MODULES_TABLE + * @param int $parent_id Parent item id + * @param array $where Additional WHERE clause condition + * + * @return bool True on rebuild success, false otherwise + */ + protected function fix_ids_tree(&$i, $field, $table, $parent_id = 0, $where = array()) + { + $changes_made = false; + $sql = 'SELECT * FROM ' . $table . ' + WHERE parent_id = ' . (int) $parent_id . + ((!empty($where)) ? ' AND ' . implode(' AND ', $where) : '') . ' + ORDER BY left_id ASC'; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Update the left_id for the item + if ($row['left_id'] != $i) + { + $this->db->sql_query('UPDATE ' . $table . ' SET ' . $this->db->sql_build_array('UPDATE', array('left_id' => $i)) . " WHERE $field = " . (int) $row[$field]); + $changes_made = true; + } + $i++; + + // Go through children and update their left/right IDs + $changes_made = (($this->fix_ids_tree($i, $field, $table, $row[$field], $where)) || $changes_made) ? true : false; + + // Update the right_id for the item + if ($row['right_id'] != $i) + { + $this->db->sql_query('UPDATE ' . $table . ' SET ' . $this->db->sql_build_array('UPDATE', array('right_id' => $i)) . " WHERE $field = " . (int) $row[$field]); + $changes_made = true; + } + $i++; + } + $this->db->sql_freeresult($result); + + return $changes_made; + } +} diff --git a/phpBB/phpbb/console/command/fixup/update_hashes.php b/phpBB/phpbb/console/command/fixup/update_hashes.php new file mode 100644 index 0000000000..4bcc3b5d19 --- /dev/null +++ b/phpBB/phpbb/console/command/fixup/update_hashes.php @@ -0,0 +1,117 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ +namespace phpbb\console\command\fixup; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Helper\ProgressBar; + +class update_hashes extends \phpbb\console\command\command +{ + /** @var \phpbb\config\config */ + protected $config; + + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\passwords\manager */ + protected $passwords_manager; + + /** @var string Default hashing type */ + protected $default_type; + + /** + * Update_hashes constructor + * + * @param \phpbb\config\config $config + * @param \phpbb\user $user + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\passwords\manager $passwords_manager + * @param array $hashing_algorithms Hashing driver + * service collection + * @param array $defaults Default password types + */ + public function __construct(\phpbb\config\config $config, \phpbb\user $user, + \phpbb\db\driver\driver_interface $db, \phpbb\passwords\manager $passwords_manager, + $hashing_algorithms, $defaults) + { + $this->config = $config; + $this->db = $db; + + $this->passwords_manager = $passwords_manager; + + foreach ($defaults as $type) + { + if ($hashing_algorithms[$type]->is_supported()) + { + $this->default_type = $type; + break; + } + } + + parent::__construct($user); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('fixup:update-hashes') + ->setDescription($this->user->lang('CLI_DESCRIPTION_UPDATE_HASH_BCRYPT')) + ; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + // Get count to be able to display progress + $sql = 'SELECT COUNT(user_id) AS count + FROM ' . USERS_TABLE . ' + WHERE user_password ' . $this->db->sql_like_expression('$H$' . $this->db->get_any_char()) . ' + OR user_password ' . $this->db->sql_like_expression('$CP$' . $this->db->get_any_char()); + $result = $this->db->sql_query($sql); + $total_update_passwords = $this->db->sql_fetchfield('count'); + $this->db->sql_freeresult($result); + + // Create progress bar + $progress_bar = new ProgressBar($output, $total_update_passwords); + $progress_bar->start(); + + $sql = 'SELECT user_id, user_password + FROM ' . USERS_TABLE . ' + WHERE user_password ' . $this->db->sql_like_expression('$H$' . $this->db->get_any_char()) . ' + OR user_password ' . $this->db->sql_like_expression('$CP$' . $this->db->get_any_char()); + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $new_hash = $this->passwords_manager->hash($row['user_password'], array($this->default_type)); + + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_password = "' . $this->db->sql_escape($new_hash) . '" + WHERE user_id = ' . (int) $row['user_id']; + $this->db->sql_query($sql); + $progress_bar->advance(); + } + + $this->config->set('update_hashes_last_cron', time()); + + $progress_bar->finish(); + + $output->writeln('<info>' . $this->user->lang('CLI_FIXUP_UPDATE_HASH_BCRYPT_SUCCESS') . '</info>'); + } +} diff --git a/phpBB/phpbb/cron/task/core/update_hashes.php b/phpBB/phpbb/cron/task/core/update_hashes.php new file mode 100644 index 0000000000..a4fe477d99 --- /dev/null +++ b/phpBB/phpbb/cron/task/core/update_hashes.php @@ -0,0 +1,130 @@ +<?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\cron\task\core; + +/** + * Update old hashes to the current default hashing algorithm + * + * It is intended to gradually update all "old" style hashes to the + * current default hashing algorithm. + */ +class update_hashes extends \phpbb\cron\task\base +{ + /** @var \phpbb\config\config */ + protected $config; + + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\lock\db */ + protected $update_lock; + + /** @var \phpbb\passwords\manager */ + protected $passwords_manager; + + /** @var string Default hashing type */ + protected $default_type; + + /** + * Constructor. + * + * @param \phpbb\config\config $config + * @param \phpbb\db\driver\driver_interface $db + * @param \phpbb\lock\db $update_lock + * @param \phpbb\passwords\manager $passwords_manager + * @param array $hashing_algorithms Hashing driver + * service collection + * @param array $defaults Default password types + */ + public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\lock\db $update_lock, \phpbb\passwords\manager $passwords_manager, $hashing_algorithms, $defaults) + { + $this->config = $config; + $this->db = $db; + $this->passwords_manager = $passwords_manager; + $this->update_lock = $update_lock; + + foreach ($defaults as $type) + { + if ($hashing_algorithms[$type]->is_supported()) + { + $this->default_type = $type; + break; + } + } + } + + /** + * {@inheritdoc} + */ + public function is_runnable() + { + return !$this->config['use_system_cron']; + } + + /** + * {@inheritdoc} + */ + public function should_run() + { + if (!empty($this->config['update_hashes_lock'])) + { + $last_run = explode(' ', $this->config['update_hashes_lock']); + if ($last_run[0] + 60 >= time()) + { + return false; + } + } + + return $this->config['enable_update_hashes'] && $this->config['update_hashes_last_cron'] < (time() - 60); + } + + /** + * {@inheritdoc} + */ + public function run() + { + if ($this->update_lock->acquire()) + { + $sql = 'SELECT user_id, user_password + FROM ' . USERS_TABLE . ' + WHERE user_password ' . $this->db->sql_like_expression('$H$' . $this->db->get_any_char()) . ' + OR user_password ' . $this->db->sql_like_expression('$CP$' . $this->db->get_any_char()); + $result = $this->db->sql_query_limit($sql, 20); + + $affected_rows = 0; + + while ($row = $this->db->sql_fetchrow($result)) + { + $new_hash = $this->passwords_manager->hash($row['user_password'], array($this->default_type)); + + // Increase number so we know that users were selected from the database + $affected_rows++; + + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_password = "' . $this->db->sql_escape($new_hash) . '" + WHERE user_id = ' . (int) $row['user_id']; + $this->db->sql_query($sql); + } + + $this->config->set('update_hashes_last_cron', time()); + $this->update_lock->release(); + + // Stop cron for good once all hashes are converted + if ($affected_rows === 0) + { + $this->config->set('enable_update_hashes', '0'); + } + } + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/add_jabber_ssl_context_config_options.php b/phpBB/phpbb/db/migration/data/v31x/add_jabber_ssl_context_config_options.php new file mode 100644 index 0000000000..9f416fe069 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/add_jabber_ssl_context_config_options.php @@ -0,0 +1,32 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v31x; + +class add_jabber_ssl_context_config_options extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v31x\v3110'); + } + + public function update_data() + { + return array( + // See http://php.net/manual/en/context.ssl.php + array('config.add', array('jab_verify_peer', 1)), + array('config.add', array('jab_verify_peer_name', 1)), + array('config.add', array('jab_allow_self_signed', 0)), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/add_latest_topics_index.php b/phpBB/phpbb/db/migration/data/v31x/add_latest_topics_index.php new file mode 100644 index 0000000000..fa2899e348 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/add_latest_topics_index.php @@ -0,0 +1,51 @@ +<?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 add_latest_topics_index extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v3110', + ); + } + + public function update_schema() + { + return array( + 'add_index' => array( + $this->table_prefix . 'topics' => array( + 'latest_topics' => array( + 'forum_id', + 'topic_last_post_time', + 'topic_last_post_id', + 'topic_moved_id', + ), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_keys' => array( + $this->table_prefix . 'topics' => array( + 'latest_topics', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/update_hashes.php b/phpBB/phpbb/db/migration/data/v31x/update_hashes.php new file mode 100644 index 0000000000..aa83c3ffbf --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/update_hashes.php @@ -0,0 +1,33 @@ +<?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 update_hashes extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v3110', + ); + } + + public function update_data() + { + return array( + array('config.add', array('enable_update_hashes', '1')), + array('config.add', array('update_hashes_lock', '')), + array('config.add', array('update_hashes_last_cron', '0')) + ); + } +} diff --git a/phpBB/phpbb/profilefields/type/type_date.php b/phpBB/phpbb/profilefields/type/type_date.php index 90ac9a6703..63a0c79a3d 100644 --- a/phpBB/phpbb/profilefields/type/type_date.php +++ b/phpBB/phpbb/profilefields/type/type_date.php @@ -264,7 +264,7 @@ class type_date extends type_base } $profile_row['s_year_options'] = '<option value="0"' . ((!$year) ? ' selected="selected"' : '') . '>--</option>'; - for ($i = $now['year'] - 100; $i <= $now['year'] + 100; $i++) + for ($i = 1901; $i <= $now['year'] + 50; $i++) { $profile_row['s_year_options'] .= '<option value="' . $i . '"' . (($i == $year) ? ' selected="selected"' : '') . ">$i</option>"; } diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index eb5543b50b..45e82df591 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -460,6 +460,9 @@ class session $this->data['is_bot'] = (!$this->data['is_registered'] && $this->data['user_id'] != ANONYMOUS) ? true : false; $this->data['user_lang'] = basename($this->data['user_lang']); + // Is user banned? Are they excluded? Won't return on ban, exists within method + $this->check_ban_for_current_session($config); + return true; } } @@ -666,19 +669,7 @@ class session // session exists in which case session_id will also be set // Is user banned? Are they excluded? Won't return on ban, exists within method - if ($this->data['user_type'] != USER_FOUNDER) - { - if (!$config['forwarded_for_check']) - { - $this->check_ban($this->data['user_id'], $this->ip); - } - else - { - $ips = explode(' ', $this->forwarded_for); - $ips[] = $this->ip; - $this->check_ban($this->data['user_id'], $ips); - } - } + $this->check_ban_for_current_session($config); $this->data['is_registered'] = (!$bot && $this->data['user_id'] != ANONYMOUS && ($this->data['user_type'] == USER_NORMAL || $this->data['user_type'] == USER_FOUNDER)) ? true : false; $this->data['is_bot'] = ($bot) ? true : false; @@ -1268,9 +1259,6 @@ class session $message .= ($ban_row['ban_give_reason']) ? '<br /><br />' . sprintf($this->lang['BOARD_BAN_REASON'], $ban_row['ban_give_reason']) : ''; $message .= '<br /><br /><em>' . $this->lang['BAN_TRIGGERED_BY_' . strtoupper($ban_triggered_by)] . '</em>'; - // To circumvent session_begin returning a valid value and the check_ban() not called on second page view, we kill the session again - $this->session_kill(false); - // A very special case... we are within the cron script which is not supposed to print out the ban message... show blank page if (defined('IN_CRON')) { @@ -1279,6 +1267,9 @@ class session exit; } + // To circumvent session_begin returning a valid value and the check_ban() not called on second page view, we kill the session again + $this->session_kill(false); + trigger_error($message); } @@ -1286,6 +1277,28 @@ class session } /** + * Check the current session for bans + * + * @return true if session user is banned. + */ + protected function check_ban_for_current_session($config) + { + if (!defined('SKIP_CHECK_BAN') && $this->data['user_type'] != USER_FOUNDER) + { + if (!$config['forwarded_for_check']) + { + $this->check_ban($this->data['user_id'], $this->ip); + } + else + { + $ips = explode(' ', $this->forwarded_for); + $ips[] = $this->ip; + $this->check_ban($this->data['user_id'], $ips); + } + } + } + + /** * Check if ip is blacklisted * This should be called only where absolutely necessary * @@ -1576,7 +1589,7 @@ class session } // Only update session DB a minute or so after last update or if page changes - if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page'])) + if ($this->time_now - ((isset($this->data['session_time'])) ? $this->data['session_time'] : 0) > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page'])) { $sql_ary = array('session_time' => $this->time_now); diff --git a/phpBB/posting.php b/phpBB/posting.php index 4651a1fd2c..35c1f84fa3 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -340,11 +340,6 @@ switch ($mode) $is_authed = true; $mode = 'soft_delete'; } - else if (!$is_authed) - { - // Display the same error message for softdelete we use for delete - $mode = 'delete'; - } break; } /** @@ -393,13 +388,13 @@ $vars = array( ); extract($phpbb_dispatcher->trigger_event('core.modify_posting_auth', compact($vars))); -if (!$is_authed) +if (!$is_authed || !empty($error)) { - $check_auth = ($mode == 'quote') ? 'reply' : $mode; + $check_auth = ($mode == 'quote') ? 'reply' : (($mode == 'soft_delete') ? 'delete' : $mode); if ($user->data['is_registered']) { - trigger_error('USER_CANNOT_' . strtoupper($check_auth)); + trigger_error(empty($error) ? 'USER_CANNOT_' . strtoupper($check_auth) : implode('<br/>', $error)); } $message = $user->lang['LOGIN_EXPLAIN_' . strtoupper($mode)]; @@ -1066,7 +1061,10 @@ if ($submit || $preview || $refresh) // Validate username if (($post_data['username'] && !$user->data['is_registered']) || ($mode == 'edit' && $post_data['poster_id'] == ANONYMOUS && $post_data['username'] && $post_data['post_username'] && $post_data['post_username'] != $post_data['username'])) { - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('validate_username')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $user->add_lang('ucp'); diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index f8d6e36c8c..a197545b90 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -47,7 +47,7 @@ <!-- EVENT forumlist_body_subforums_before --> <br /><strong>{forumrow.L_SUBFORUM_STR}{L_COLON}</strong> <!-- BEGIN subforum --> - <a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.S_UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->{L_COMMA_SEPARATOR}<!-- ENDIF --> + <!-- EVENT forumlist_body_subforum_link_prepend --><a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.S_UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->{L_COMMA_SEPARATOR}<!-- ENDIF --><!-- EVENT forumlist_body_subforum_link_append --> <!-- END subforum --> <!-- EVENT forumlist_body_subforums_after --> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html index ec5bf35476..b292c40eb2 100644 --- a/phpBB/styles/prosilver/template/index_body.html +++ b/phpBB/styles/prosilver/template/index_body.html @@ -40,13 +40,18 @@ <!-- IF U_VIEWONLINE --><h3><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a></h3><!-- ELSE --><h3>{L_WHO_IS_ONLINE}</h3><!-- ENDIF --> <p> <!-- EVENT index_body_block_online_prepend --> - {TOTAL_USERS_ONLINE} ({L_ONLINE_EXPLAIN})<br />{RECORD_USERS}<br /> <br />{LOGGED_IN_USER_LIST} - <!-- IF LEGEND --><br /><em>{L_LEGEND}{L_COLON} {LEGEND}</em><!-- ENDIF --> + {TOTAL_USERS_ONLINE} ({L_ONLINE_EXPLAIN})<br />{RECORD_USERS}<br /> + <!-- IF U_VIEWONLINE --> + <br />{LOGGED_IN_USER_LIST} + <!-- IF LEGEND --><br /><em>{L_LEGEND}{L_COLON} {LEGEND}</em><!-- ENDIF --> + <!-- ENDIF --> <!-- EVENT index_body_block_online_append --> </p> </div> <!-- ENDIF --> +<!-- EVENT index_body_birthday_block_before --> + <!-- IF S_DISPLAY_BIRTHDAY_LIST --> <div class="stat-block birthday-list"> <h3>{L_BIRTHDAYS}</h3> diff --git a/phpBB/styles/prosilver/template/mcp_post.html b/phpBB/styles/prosilver/template/mcp_post.html index e5777d206a..5acdcef859 100644 --- a/phpBB/styles/prosilver/template/mcp_post.html +++ b/phpBB/styles/prosilver/template/mcp_post.html @@ -294,6 +294,14 @@ </tbody> </table> + <div class="pagination"> + <!-- INCLUDE pagination.html --> + </div> + </div> + </div> + + <div class="panel"> + <div class="inner"> <table class="table1"> <thead> <tr> @@ -315,7 +323,27 @@ </tbody> </table> - <p><a href="{U_LOOKUP_ALL}#ip">{L_LOOKUP_ALL}</a></p> + <div class="buttons"> + <p><a href="{U_LOOKUP_ALL}#ip">{L_LOOKUP_ALL}</a></p> + </div> + + <div class="pagination"> + <ul> + <!-- BEGIN pagination_ips --> + <!-- IF pagination_ips.S_IS_PREV --> + <li class="previous"><a href="{pagination_ips.PAGE_URL}" rel="prev" role="button">{L_PREVIOUS}</a></li> + <!-- ELSEIF pagination_ips.S_IS_CURRENT --> + <li class="active"><span>{pagination_ips.PAGE_NUMBER}</span></li> + <!-- ELSEIF pagination_ips.S_IS_ELLIPSIS --> + <li class="ellipsis" role="separator"><span>{L_ELLIPSIS}</span></li> + <!-- ELSEIF pagination_ips.S_IS_NEXT --> + <li class="next"><a href="{pagination_ips.PAGE_URL}" rel="next" role="button">{L_NEXT}</a></li> + <!-- ELSE --> + <li><a href="{pagination_ips.PAGE_URL}" role="button">{pagination_ips.PAGE_NUMBER}</a></li> + <!-- ENDIF --> + <!-- END pagination_ips --> + </ul> + </div> </div> </div> diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index 22d837b3d1..af4b63265f 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -111,7 +111,9 @@ </li> </ul> + <!-- EVENT mcp_topic_postrow_post_subject_before --> <h3><a href="{postrow.U_POST_DETAILS}">{postrow.POST_SUBJECT}</a></h3> + <!-- EVENT mcp_topic_postrow_post_subject_after --> <!-- EVENT mcp_topic_postrow_post_details_before --> <p class="author"><a href="#pr{postrow.POST_ID}">{postrow.MINI_POST_IMG}</a> {L_POSTED} {postrow.POST_DATE} {L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong><!-- IF postrow.U_MCP_DETAILS --> [ <a href="{postrow.U_MCP_DETAILS}">{L_POST_DETAILS}</a> ]<!-- ENDIF --></p> diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index 4365482314..4c83e95a1b 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -137,6 +137,7 @@ <dd class="search-result-date">{searchresults.POST_DATE}</dd> <dd>{L_FORUM}{L_COLON} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a></dd> <dd>{L_TOPIC}{L_COLON} <a href="{searchresults.U_VIEW_TOPIC}">{searchresults.TOPIC_TITLE}</a></dd> + <!-- EVENT search_results_topic_title_after --> <dd>{L_REPLIES}{L_COLON} <strong>{searchresults.TOPIC_REPLIES}</strong></dd> <dd>{L_VIEWS}{L_COLON} <strong>{searchresults.TOPIC_VIEWS}</strong></dd> <!-- EVENT search_results_postprofile_after --> diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index 643b78823f..f6fc07ea55 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -261,9 +261,9 @@ <!-- INCLUDE jumpbox.html --> -<!-- IF S_DISPLAY_ONLINE_LIST --> +<!-- IF S_DISPLAY_ONLINE_LIST and U_VIEWONLINE --> <div class="stat-block online-list"> - <h3><!-- IF U_VIEWONLINE --><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a><!-- ELSE -->{L_WHO_IS_ONLINE}<!-- ENDIF --></h3> + <h3><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a></h3> <p>{LOGGED_IN_USER_LIST}</p> </div> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index d2a253bb77..22a77779bf 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -408,9 +408,9 @@ <!-- EVENT viewtopic_body_footer_before --> <!-- INCLUDE jumpbox.html --> -<!-- IF S_DISPLAY_ONLINE_LIST --> +<!-- IF S_DISPLAY_ONLINE_LIST and U_VIEWONLINE --> <div class="stat-block online-list"> - <h3><!-- IF U_VIEWONLINE --><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a><!-- ELSE -->{L_WHO_IS_ONLINE}<!-- ENDIF --></h3> + <h3><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a></h3> <p>{LOGGED_IN_USER_LIST}</p> </div> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css index 777f011c35..235c230ed4 100644 --- a/phpBB/styles/prosilver/theme/forms.css +++ b/phpBB/styles/prosilver/theme/forms.css @@ -288,7 +288,7 @@ textarea.inputbox { } input[type="number"] { - -moz-padding-end: inherit; + -moz-padding-end: 0; } input[type="search"] { diff --git a/phpBB/styles/subsilver2/template/forumlist_body.html b/phpBB/styles/subsilver2/template/forumlist_body.html index 6c9b64827a..6b7f884aaa 100644 --- a/phpBB/styles/subsilver2/template/forumlist_body.html +++ b/phpBB/styles/subsilver2/template/forumlist_body.html @@ -56,7 +56,7 @@ <!-- EVENT forumlist_body_subforums_before --> <p class="forumdesc"><strong>{forumrow.L_SUBFORUM_STR}{L_COLON}</strong> <!-- BEGIN subforum --> - <a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.S_UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->{L_COMMA_SEPARATOR}<!-- ENDIF --> + <!-- EVENT forumlist_body_subforum_link_prepend --><a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.S_UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->{L_COMMA_SEPARATOR}<!-- ENDIF --><!-- EVENT forumlist_body_subforum_link_append --> <!-- END subforum --> </p> <!-- EVENT forumlist_body_subforums_after --> diff --git a/phpBB/styles/subsilver2/template/index_body.html b/phpBB/styles/subsilver2/template/index_body.html index c0a8d5fd57..de1523b11c 100644 --- a/phpBB/styles/subsilver2/template/index_body.html +++ b/phpBB/styles/subsilver2/template/index_body.html @@ -66,6 +66,8 @@ </table> <!-- ENDIF --> +<!-- EVENT index_body_birthday_block_before --> + <!-- IF S_DISPLAY_BIRTHDAY_LIST --> <br clear="all" /> diff --git a/phpBB/ucp.php b/phpBB/ucp.php index 8c74ca1f3c..5cd602bab5 100644 --- a/phpBB/ucp.php +++ b/phpBB/ucp.php @@ -237,6 +237,19 @@ switch ($mode) add_log('admin', 'LOG_ACL_TRANSFER_PERMISSIONS', $user_row['username']); $message = sprintf($user->lang['PERMISSIONS_TRANSFERRED'], $user_row['username']) . '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>'); + + /** + * Event to run code after permissions are switched + * + * @event core.ucp_switch_permissions + * @var int user_id User ID to switch permission to + * @var array user_row User data + * @var string message Success message + * @since 3.1.11-RC1 + */ + $vars = array('user_id', 'user_row', 'message'); + extract($phpbb_dispatcher->trigger_event('core.ucp_switch_permissions', compact($vars))); + trigger_error($message); break; @@ -260,6 +273,18 @@ switch ($mode) add_log('admin', 'LOG_ACL_RESTORE_PERMISSIONS', $username); $message = $user->lang['PERMISSIONS_RESTORED'] . '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>'); + + /** + * Event to run code after permissions are restored + * + * @event core.ucp_restore_permissions + * @var string username User name + * @var string message Success message + * @since 3.1.11-RC1 + */ + $vars = array('username', 'message'); + extract($phpbb_dispatcher->trigger_event('core.ucp_restore_permissions', compact($vars))); + trigger_error($message); break; diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php index 5cb1175528..0a8af2001c 100644 --- a/phpBB/viewonline.php +++ b/phpBB/viewonline.php @@ -60,7 +60,10 @@ $order_by = $sort_key_sql[$sort_key] . ' ' . (($sort_dir == 'a') ? 'ASC' : 'DESC // Whois requested if ($mode == 'whois' && $auth->acl_get('a_') && $session_id) { - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('user_get_id_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $sql = 'SELECT u.user_id, u.username, u.user_type, s.session_ip FROM ' . USERS_TABLE . ' u, ' . SESSIONS_TABLE . " s diff --git a/tests/functional/visibility_softdelete_test.php b/tests/functional/visibility_softdelete_test.php index 39efc99a35..6450c00c1e 100644 --- a/tests/functional/visibility_softdelete_test.php +++ b/tests/functional/visibility_softdelete_test.php @@ -564,7 +564,7 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_ $this->assertContainsLang('SPLIT_TOPIC_EXPLAIN', $crawler->text()); $form = $crawler->selectButton('Submit')->form(array( - 'subject' => 'Soft Delete Topic #2', + 'subject' => 'Soft Delete Topic #2 with bang', )); $form['to_forum_id']->select($this->data['forums']['Soft Delete #2']); $form['post_id_list'][1]->tick(); @@ -597,6 +597,11 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_ 'forum_topics_softdeleted' => 1, 'forum_last_post_id' => 0, ), 'after restoring #2'); + + // Assert new topic title is indexed as well + $this->add_lang('search'); + self::request('GET', "search.php?keywords=bang&sid={$this->sid}"); + $this->assertContains(sprintf($this->lang['FOUND_SEARCH_MATCHES'][1], 1), self::get_content()); } public function test_move_topic_back() @@ -609,7 +614,7 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_ ), 'topics' => array( 'Soft Delete Topic #1', - 'Soft Delete Topic #2', + 'Soft Delete Topic #2 with bang', ), 'posts' => array( 'Soft Delete Topic #1', @@ -618,7 +623,7 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_ ), )); - $crawler = $this->get_quickmod_page($this->data['topics']['Soft Delete Topic #2'], 'MOVE_TOPIC'); + $crawler = $this->get_quickmod_page($this->data['topics']['Soft Delete Topic #2 with bang'], 'MOVE_TOPIC'); $form = $crawler->selectButton('Yes')->form(); $form['to_forum_id']->select($this->data['forums']['Soft Delete #1']); $crawler = self::submit($form); @@ -644,7 +649,7 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_ ), 'topics' => array( 'Soft Delete Topic #1', - 'Soft Delete Topic #2', + 'Soft Delete Topic #2 with bang', ), 'posts' => array( 'Soft Delete Topic #1', @@ -664,7 +669,7 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_ ), 'before merging #1'); $this->add_lang('viewtopic'); - $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #2']}&sid={$this->sid}"); + $crawler = self::request('GET', "viewtopic.php?t={$this->data['topics']['Soft Delete Topic #2 with bang']}&sid={$this->sid}"); $bookmark_tag = $crawler->filter('a.bookmark-link'); $this->assertContainsLang('BOOKMARK_TOPIC', $bookmark_tag->text()); @@ -673,10 +678,10 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_ $this->assertContainsLang('BOOKMARK_ADDED', $crawler_bookmark->text()); $this->add_lang('mcp'); - $crawler = $this->get_quickmod_page($this->data['topics']['Soft Delete Topic #2'], 'MERGE_TOPIC', $crawler); + $crawler = $this->get_quickmod_page($this->data['topics']['Soft Delete Topic #2 with bang'], 'MERGE_TOPIC', $crawler); $this->assertContainsLang('SELECT_MERGE', $crawler->text()); - $crawler = self::request('GET', "mcp.php?f={$this->data['forums']['Soft Delete #1']}&t={$this->data['topics']['Soft Delete Topic #2']}&i=main&mode=forum_view&action=merge_topic&to_topic_id={$this->data['topics']['Soft Delete Topic #1']}"); + $crawler = self::request('GET', "mcp.php?f={$this->data['forums']['Soft Delete #1']}&t={$this->data['topics']['Soft Delete Topic #2 with bang']}&i=main&mode=forum_view&action=merge_topic&to_topic_id={$this->data['topics']['Soft Delete Topic #1']}"); $this->assertContainsLang('MERGE_TOPICS_CONFIRM', $crawler->text()); $form = $crawler->selectButton('Yes')->form(); diff --git a/tests/mcp/fixtures/post_ip.xml b/tests/mcp/fixtures/post_ip.xml new file mode 100644 index 0000000000..fad2193396 --- /dev/null +++ b/tests/mcp/fixtures/post_ip.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_posts"> + <column>post_id</column> + <column>poster_id</column> + <column>post_edit_user</column> + <column>post_delete_user</column> + <column>post_username</column> + <column>topic_id</column> + <column>forum_id</column> + <column>post_visibility</column> + <column>post_time</column> + <column>post_text</column> + <column>post_reported</column> + <column>poster_ip</column> + <row> + <value>1</value> + <value>2</value> + <value>2</value> + <value>2</value> + <value></value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value></value> + <value>1</value> + <value>127.0.0.1</value> + </row> + <row> + <value>2</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>Other</value> + <value>2</value> + <value>2</value> + <value>1</value> + <value>1</value> + <value></value> + <value>1</value> + <value>127.0.0.2</value> + </row> + <row> + <value>3</value> + <value>2</value> + <value>2</value> + <value>2</value> + <value></value> + <value>3</value> + <value>3</value> + <value>1</value> + <value>1</value> + <value></value> + <value>1</value> + <value>127.0.0.3</value> + </row> + <row> + <value>4</value> + <value>1</value> + <value>1</value> + <value>1</value> + <value>Other</value> + <value>4</value> + <value>4</value> + <value>1</value> + <value>1</value> + <value></value> + <value>1</value> + <value>127.0.0.1</value> + </row> + </table> +</dataset> diff --git a/tests/mcp/post_ip_test.php b/tests/mcp/post_ip_test.php new file mode 100644 index 0000000000..72a9f62774 --- /dev/null +++ b/tests/mcp/post_ip_test.php @@ -0,0 +1,67 @@ +<?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/mcp/mcp_post.php'; + +class phpbb_mcp_post_ip_test extends phpbb_database_test_case +{ + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/post_ip.xml'); + } + + protected function setUp() + { + parent::setUp(); + + $this->db = $this->new_dbal(); + } + + public function data_get_num_ips() + { + return array( + array(2, 1), + array(2, 2), + array(0, 3), + ); + } + + /** + * @dataProvider data_get_num_ips + */ + public function test_get_num_ips($expected, $poster_id) + { + $this->assertSame($expected, phpbb_get_num_ips_for_poster($this->db, $poster_id)); + } + + public function data_get_num_posters() + { + return array( + array(2, '127.0.0.1'), + array(1, '127.0.0.2'), + array(1, '127.0.0.3'), + array(0, '127.0.0.4'), + ); + } + + /** + * @dataProvider data_get_num_posters + */ + public function test_get_num_posters($expected, $ip) + { + $this->assertSame($expected, phpbb_get_num_posters_for_ip($this->db, $ip)); + } +} |