diff options
52 files changed, 1369 insertions, 178 deletions
diff --git a/composer.phar b/composer.phar Binary files differindex 3481b599b7..a3bd28e4f4 100755 --- a/composer.phar +++ b/composer.phar diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html index 756092a1f0..0d8b8ad583 100644 --- a/phpBB/adm/style/acp_forums.html +++ b/phpBB/adm/style/acp_forums.html @@ -343,6 +343,8 @@ <!-- EVENT acp_forums_rules_settings_append --> </fieldset> </div> + + <!-- EVENT acp_forums_custom_settings --> <fieldset class="submit-buttons"> <legend>{L_SUBMIT}</legend> diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css index 992af0997f..23bd563ba0 100644 --- a/phpBB/adm/style/admin.css +++ b/phpBB/adm/style/admin.css @@ -17,6 +17,10 @@ font-size: 100%; } +abbr { + text-decoration: none; +} + body, div, p, th, td, li, dd { font-size: x-small; voice-family: "\"}\""; diff --git a/phpBB/composer.lock b/phpBB/composer.lock index aaff9a8968..15d3e8a7ff 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -1,7 +1,7 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], "hash": "94d0f6dab53f11dab1de63c0ae519ee6", @@ -224,7 +224,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/6c568ac8b01b33650d9d77b5b6399eed9c18ac94", + "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/fb39bdd38f6706b96422a7583b89c9283a58960f", "reference": "beee0e5693f7ca8ed16a94294acf53b6e6207e7c", "shasum": "" }, @@ -279,12 +279,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "358ec929e494b6f12d8508d88357cbd7383a10ca" + "reference": "3f495530550377a55c0cced5ddf8f58cfcd9ce5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/358ec929e494b6f12d8508d88357cbd7383a10ca", - "reference": "358ec929e494b6f12d8508d88357cbd7383a10ca", + "url": "https://api.github.com/repos/symfony/Config/zipball/3f495530550377a55c0cced5ddf8f58cfcd9ce5b", + "reference": "3f495530550377a55c0cced5ddf8f58cfcd9ce5b", "shasum": "" }, "require": { @@ -321,7 +321,7 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2015-07-09 16:11:14" + "time": "2015-08-03 08:27:53" }, { "name": "symfony/console", @@ -329,12 +329,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "fd85e7517e79a2bceafcee8f7e8b7bbd0919a90a" + "reference": "eb0fcf6f58054ac9d07539451e27aa4e17aebfe0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/fd85e7517e79a2bceafcee8f7e8b7bbd0919a90a", - "reference": "fd85e7517e79a2bceafcee8f7e8b7bbd0919a90a", + "url": "https://api.github.com/repos/symfony/Console/zipball/eb0fcf6f58054ac9d07539451e27aa4e17aebfe0", + "reference": "eb0fcf6f58054ac9d07539451e27aa4e17aebfe0", "shasum": "" }, "require": { @@ -378,7 +378,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2015-07-16 12:22:14" + "time": "2015-08-04 15:59:05" }, { "name": "symfony/debug", @@ -386,12 +386,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/Debug.git", - "reference": "d1114d892ae70f833871dc55599f17084191efaa" + "reference": "e6ce720c140d144e2b2e2b14d36b887011e2a578" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Debug/zipball/d1114d892ae70f833871dc55599f17084191efaa", - "reference": "d1114d892ae70f833871dc55599f17084191efaa", + "url": "https://api.github.com/repos/symfony/Debug/zipball/e6ce720c140d144e2b2e2b14d36b887011e2a578", + "reference": "e6ce720c140d144e2b2e2b14d36b887011e2a578", "shasum": "" }, "require": { @@ -403,14 +403,9 @@ }, "require-dev": { "symfony/class-loader": "~2.2|~3.0.0", - "symfony/http-foundation": "~2.1|~3.0.0", "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0", "symfony/phpunit-bridge": "~2.7|~3.0.0" }, - "suggest": { - "symfony/http-foundation": "", - "symfony/http-kernel": "" - }, "type": "library", "extra": { "branch-alias": { @@ -438,7 +433,7 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2015-07-09 16:11:14" + "time": "2015-08-01 06:34:55" }, { "name": "symfony/dependency-injection", @@ -446,12 +441,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "f279142fb6bc21e83fcd40e0a01a62ff527268be" + "reference": "b0e1cef8acbc3b6df877c47b8e0b8449defcfc5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/f279142fb6bc21e83fcd40e0a01a62ff527268be", - "reference": "f279142fb6bc21e83fcd40e0a01a62ff527268be", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/b0e1cef8acbc3b6df877c47b8e0b8449defcfc5f", + "reference": "b0e1cef8acbc3b6df877c47b8e0b8449defcfc5f", "shasum": "" }, "require": { @@ -498,7 +493,7 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2015-07-16 10:10:53" + "time": "2015-08-05 15:50:26" }, { "name": "symfony/event-dispatcher", @@ -662,12 +657,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "5339030f5af0d6fef7c897130291ac168278289f" + "reference": "caede1f3361223098395b955bdbf3fe59d58d3ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/5339030f5af0d6fef7c897130291ac168278289f", - "reference": "5339030f5af0d6fef7c897130291ac168278289f", + "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/caede1f3361223098395b955bdbf3fe59d58d3ba", + "reference": "caede1f3361223098395b955bdbf3fe59d58d3ba", "shasum": "" }, "require": { @@ -707,7 +702,7 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2015-07-16 12:22:14" + "time": "2015-08-05 15:58:16" }, { "name": "symfony/http-kernel", @@ -715,19 +710,19 @@ "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel.git", - "reference": "f24d2cb4778ecc5f6c8e8f7f31bc4691099a920d" + "reference": "8480ac939c8f6441e3575badb2306b936e14184a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/f24d2cb4778ecc5f6c8e8f7f31bc4691099a920d", - "reference": "f24d2cb4778ecc5f6c8e8f7f31bc4691099a920d", + "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/8480ac939c8f6441e3575badb2306b936e14184a", + "reference": "8480ac939c8f6441e3575badb2306b936e14184a", "shasum": "" }, "require": { "php": ">=5.3.9", "psr/log": "~1.0", "symfony/debug": "~2.6,>=2.6.2", - "symfony/event-dispatcher": "~2.5.9|~2.6,>=2.6.2|~3.0.0", + "symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0", "symfony/http-foundation": "~2.5,>=2.5.4|~3.0.0" }, "conflict": { @@ -739,7 +734,7 @@ "symfony/config": "~2.7", "symfony/console": "~2.3|~3.0.0", "symfony/css-selector": "~2.0,>=2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.2|~3.0.0", + "symfony/dependency-injection": "~2.8|~3.0.0", "symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0", "symfony/expression-language": "~2.4|~3.0.0", "symfony/finder": "~2.0,>=2.0.5|~3.0.0", @@ -787,7 +782,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2015-07-09 16:11:14" + "time": "2015-08-01 06:34:21" }, { "name": "symfony/routing", @@ -795,12 +790,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/Routing.git", - "reference": "9e797cd70762db18d87c59dc6bc1ab7c3eb963ed" + "reference": "b7c7ba4300592b5127318301d3d5aef537c05664" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/9e797cd70762db18d87c59dc6bc1ab7c3eb963ed", - "reference": "9e797cd70762db18d87c59dc6bc1ab7c3eb963ed", + "url": "https://api.github.com/repos/symfony/Routing/zipball/b7c7ba4300592b5127318301d3d5aef537c05664", + "reference": "b7c7ba4300592b5127318301d3d5aef537c05664", "shasum": "" }, "require": { @@ -858,40 +853,53 @@ "uri", "url" ], - "time": "2015-07-09 16:11:14" + "time": "2015-08-05 15:58:16" }, { - "name": "symfony/security-core", + "name": "symfony/security", "version": "2.8.x-dev", "source": { "type": "git", - "url": "https://github.com/symfony/security-core.git", - "reference": "8253e027bf8a1c9c573a7b3c494027847058c959" + "url": "https://github.com/symfony/Security.git", + "reference": "b57956299e1d75663d748645564d76efcb9e72f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/8253e027bf8a1c9c573a7b3c494027847058c959", - "reference": "8253e027bf8a1c9c573a7b3c494027847058c959", + "url": "https://api.github.com/repos/symfony/Security/zipball/b57956299e1d75663d748645564d76efcb9e72f3", + "reference": "b57956299e1d75663d748645564d76efcb9e72f3", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/event-dispatcher": "~2.2|~3.0.0", + "symfony/http-foundation": "~2.1|~3.0.0", + "symfony/http-kernel": "~2.4|~3.0.0" + }, + "replace": { + "symfony/security-acl": "self.version", + "symfony/security-core": "self.version", + "symfony/security-csrf": "self.version", + "symfony/security-http": "self.version" }, "require-dev": { - "ircmaxell/password-compat": "1.0.*", + "doctrine/common": "~2.2", + "doctrine/dbal": "~2.2", + "ircmaxell/password-compat": "~1.0", "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1|~3.0.0", "symfony/expression-language": "~2.6|~3.0.0", - "symfony/http-foundation": "~2.4|~3.0.0", + "symfony/intl": "~2.3|~3.0.0", "symfony/phpunit-bridge": "~2.7|~3.0.0", + "symfony/routing": "~2.2|~3.0.0", "symfony/translation": "~2.0,>=2.0.5|~3.0.0", "symfony/validator": "~2.5,>=2.5.5|~3.0.0" }, "suggest": { + "doctrine/dbal": "For using the built-in ACL implementation", "ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5", - "symfony/event-dispatcher": "", + "symfony/class-loader": "For using the ACL generateSql script", "symfony/expression-language": "For using the expression voter", - "symfony/http-foundation": "", + "symfony/finder": "For using the ACL generateSql script", + "symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs", "symfony/validator": "For using the user password constraint" }, "type": "library", @@ -902,7 +910,7 @@ }, "autoload": { "psr-4": { - "Symfony\\Component\\Security\\Core\\": "" + "Symfony\\Component\\Security\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -919,76 +927,22 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Security Component - Core Library", + "description": "Symfony Security Component", "homepage": "https://symfony.com", "time": "2015-07-09 16:11:14" }, { - "name": "symfony/security-csrf", - "version": "2.8.x-dev", - "source": { - "type": "git", - "url": "https://github.com/symfony/security-csrf.git", - "reference": "9e859301e5b19953338a50a5d3e1aeb01d37e9d1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/9e859301e5b19953338a50a5d3e1aeb01d37e9d1", - "reference": "9e859301e5b19953338a50a5d3e1aeb01d37e9d1", - "shasum": "" - }, - "require": { - "php": ">=5.3.9", - "symfony/security-core": "~2.4|~3.0.0" - }, - "require-dev": { - "symfony/http-foundation": "~2.1|~3.0.0", - "symfony/phpunit-bridge": "~2.7|~3.0.0" - }, - "suggest": { - "symfony/http-foundation": "For using the class SessionTokenStorage." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Security\\Csrf\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Security Component - CSRF Library", - "homepage": "https://symfony.com", - "time": "2015-05-13 11:36:16" - }, - { "name": "symfony/twig-bridge", "version": "2.8.x-dev", "source": { "type": "git", "url": "https://github.com/symfony/TwigBridge.git", - "reference": "a02e3a8ff1f8eda04d0e0655d2cefcbe9ecc4e14" + "reference": "f7cbabeaaaf27c904951876f4a5bde5363833382" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/TwigBridge/zipball/a02e3a8ff1f8eda04d0e0655d2cefcbe9ecc4e14", - "reference": "a02e3a8ff1f8eda04d0e0655d2cefcbe9ecc4e14", + "url": "https://api.github.com/repos/symfony/TwigBridge/zipball/f7cbabeaaaf27c904951876f4a5bde5363833382", + "reference": "f7cbabeaaaf27c904951876f4a5bde5363833382", "shasum": "" }, "require": { @@ -1000,12 +954,13 @@ "symfony/console": "~2.7|~3.0.0", "symfony/expression-language": "~2.4|~3.0.0", "symfony/finder": "~2.3|~3.0.0", - "symfony/form": "~2.8|~3.0.0", + "symfony/form": "~2.8", "symfony/http-kernel": "~2.3|~3.0.0", "symfony/intl": "~2.3|~3.0.0", "symfony/phpunit-bridge": "~2.7|~3.0.0", "symfony/routing": "~2.2|~3.0.0", "symfony/security": "~2.6|~3.0.0", + "symfony/security-acl": "~2.6|~3.0.0", "symfony/stopwatch": "~2.2|~3.0.0", "symfony/templating": "~2.1|~3.0.0", "symfony/translation": "~2.7|~3.0.0", @@ -1053,7 +1008,7 @@ ], "description": "Symfony Twig Bridge", "homepage": "https://symfony.com", - "time": "2015-07-09 16:11:14" + "time": "2015-08-01 09:43:59" }, { "name": "symfony/yaml", @@ -1061,12 +1016,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "000e7fc2653335cd42c6d21405dac1c74224a387" + "reference": "6eef1477f3c4451b6024fadb1254009be4602908" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/000e7fc2653335cd42c6d21405dac1c74224a387", - "reference": "000e7fc2653335cd42c6d21405dac1c74224a387", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/6eef1477f3c4451b6024fadb1254009be4602908", + "reference": "6eef1477f3c4451b6024fadb1254009be4602908", "shasum": "" }, "require": { @@ -1102,29 +1057,29 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2015-07-01 14:16:54" + "time": "2015-07-29 07:12:56" }, { "name": "twig/twig", - "version": "v1.18.0", + "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "4cf7464348e7f9893a93f7096a90b73722be99cf" + "reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/4cf7464348e7f9893a93f7096a90b73722be99cf", - "reference": "4cf7464348e7f9893a93f7096a90b73722be99cf", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844", + "reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844", "shasum": "" }, "require": { - "php": ">=5.2.4" + "php": ">=5.2.7" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-master": "1.20-dev" } }, "autoload": { @@ -1159,7 +1114,7 @@ "keywords": [ "templating" ], - "time": "2015-01-25 17:32:08" + "time": "2015-08-12 15:56:39" } ], "packages-dev": [ diff --git a/phpBB/config/default/container/services_avatar.yml b/phpBB/config/default/container/services_avatar.yml index c74bef3d66..1b0c109298 100644 --- a/phpBB/config/default/container/services_avatar.yml +++ b/phpBB/config/default/container/services_avatar.yml @@ -64,6 +64,7 @@ services: - @filesystem - @path_helper - @mimetype.guesser + - @dispatcher - @cache.driver calls: - [set_name, [avatar.driver.upload]] diff --git a/phpBB/config/default/container/services_console.yml b/phpBB/config/default/container/services_console.yml index 49d0626b4f..aee3cbdee6 100644 --- a/phpBB/config/default/container/services_console.yml +++ b/phpBB/config/default/container/services_console.yml @@ -157,3 +157,30 @@ services: - @config_text tags: - { name: console.command } + + console.command.thumbnail.delete: + class: phpbb\console\command\thumbnail\delete + arguments: + - @user + - @dbal.conn + - %core.root_path% + tags: + - { name: console.command } + + console.command.thumbnail.generate: + class: phpbb\console\command\thumbnail\generate + arguments: + - @user + - @dbal.conn + - @cache + - %core.root_path% + - %core.php_ext% + tags: + - { name: console.command } + + console.command.thumbnail.recreate: + class: phpbb\console\command\thumbnail\recreate + arguments: + - @user + tags: + - { name: console.command } diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index 8bd7ac47e0..b1db7b6f36 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -49,6 +49,7 @@ <ol> <li><a href="#changelog">Changelog</a> <ul> + <li><a href="#v315">Changes since 3.1.5</a></li> <li><a href="#v314">Changes since 3.1.4</a></li> <li><a href="#v313">Changes since 3.1.3</a></li> <li><a href="#v313rc1">Changes since 3.1.3-RC1</a></li> @@ -112,6 +113,94 @@ <div class="content"> + <a name="v315"></a><h3>Changes since 3.1.5</h3> + + <h4>Bug</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10711">PHPBB3-10711</a>] - SQL error DUPLICATE for KEY in FORUMS_TRACK_TABLE </li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13711">PHPBB3-13711</a>] - disabled accounts receive mails</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13815">PHPBB3-13815</a>] - Event parameters in posting do not affect behavior as expected</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13903">PHPBB3-13903</a>] - Container naming doesn't allow Windows' semicolon</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13930">PHPBB3-13930</a>] - Check for correct spacing between keyword & parenthesis in codesniffer</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13941">PHPBB3-13941</a>] - One test is blocked in an inifinite loop on php 5.5+ and with sqlite3</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13948">PHPBB3-13948</a>] - Only reports top level WHOIS IP for a user in ACP</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13949">PHPBB3-13949</a>] - Replace colon with colon lang key in memberlist search page</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13951">PHPBB3-13951</a>] - Jump to page function does not work since 3.1.5 upgrade</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13952">PHPBB3-13952</a>] - Fulltext Native errors from tidy_search cron task</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13955">PHPBB3-13955</a>] - 3.1.5 not loading CDN resources</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13962">PHPBB3-13962</a>] - Forum dropdown in MCP queue could expand beyond screen size</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13966">PHPBB3-13966</a>] - Change post's author --> error message</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13967">PHPBB3-13967</a>] - BBCode guide - loading phpBB logo image breaks https</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13980">PHPBB3-13980</a>] - Current avatar not removed when uploading with different extension</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13984">PHPBB3-13984</a>] - AJAX Loading Indicator broken</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14037">PHPBB3-14037</a>] - Memberlist profile fields headlines not computed from same way as data</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14049">PHPBB3-14049</a>] - Plupload delete request should use config headers</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14069">PHPBB3-14069</a>] - Incorrect sql_fetchfield call in style_update_p1 migration</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14077">PHPBB3-14077</a>] - Select all code not work in Microsoft Edge</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14082">PHPBB3-14082</a>] - Fix wrong variables in fulltext native search for keyworded results</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14083">PHPBB3-14083</a>] - Fix wrong variables in fulltext mysql search for author search</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14093">PHPBB3-14093</a>] - Hardcoded language in ucp_pm_viewfolder.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14103">PHPBB3-14103</a>] - Underline in abbreviations in Firefox 40</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14104">PHPBB3-14104</a>] - Fix missing variable in fulltext native search query for total results for author</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14115">PHPBB3-14115</a>] - Microdata is not valid in prosilver</li> + </ul> + <h4>Improvement</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11530">PHPBB3-11530</a>] - Remove quotes that are too deep automatically</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12952">PHPBB3-12952</a>] - Display HTTP Output along with Status code in case assertion fails in functional tests</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13598">PHPBB3-13598</a>] - Add an option to post a locked topic</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13786">PHPBB3-13786</a>] - Add core events to add MCP post options</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13818">PHPBB3-13818</a>] - Browse Extensions Database link in Extension Manager</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13843">PHPBB3-13843</a>] - Add templates events to insert custom panel-tab into posting editor</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13863">PHPBB3-13863</a>] - [Template] - topiclist_row_append/topiclist_row_prepend in mcp_forum.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13879">PHPBB3-13879</a>] - We're using px most places but ems in others</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13882">PHPBB3-13882</a>] - Avatars in notifications should be lazy loaded</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13899">PHPBB3-13899</a>] - Add items to core.search_results_modify_search_title</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13911">PHPBB3-13911</a>] - Add configuration options to profile fields</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13931">PHPBB3-13931</a>] - Wrong order in docs/events.md</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13968">PHPBB3-13968</a>] - [PHP] - core.user_setup_after</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13971">PHPBB3-13971</a>] - Add draft_id variable to event core.posting_modify_template_vars</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13981">PHPBB3-13981</a>] - Events to intercept uploaded avatar deletion</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13995">PHPBB3-13995</a>] - Invalid HTML using Projection Media Type</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14002">PHPBB3-14002</a>] - Add template events before/after user details in ucp_main_front.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14005">PHPBB3-14005</a>] - Allow extensions control post buttons displaying</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14014">PHPBB3-14014</a>] - [PHP] - mcp_forum_view_actions</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14064">PHPBB3-14064</a>] - Add template events to ucp_pm_history.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14065">PHPBB3-14065</a>] - Add template events to attachment.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14067">PHPBB3-14067</a>] - Add template events to overall_header.html around feeds</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14068">PHPBB3-14068</a>] - New events around poll panel in viewtopic</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14072">PHPBB3-14072</a>] - Add core event to the function format_display()</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14085">PHPBB3-14085</a>] - [Template] - posting_topic_title_prepend</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14086">PHPBB3-14086</a>] - [Template] - Add mcp_forum_topic_title_*</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14090">PHPBB3-14090</a>] - [Template] - mcp_topic_topic_title_*</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14091">PHPBB3-14091</a>] - [Template] - mcp_topic_subject_*</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14101">PHPBB3-14101</a>] - Add core event to the download/file.php</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14116">PHPBB3-14116</a>] - sql_affectedrows has no arguments</li> + </ul> + <h4>New Feature</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12692">PHPBB3-12692</a>] - Add a console command to manage the thumbnail</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13311">PHPBB3-13311</a>] - Add php event to acp manage_forums when deleting content</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13974">PHPBB3-13974</a>] - Add php event for altering data when changing a post's poster</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13997">PHPBB3-13997</a>] - [Template] - posting_editor_submit_buttons</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14006">PHPBB3-14006</a>] - [PHP] - core.ucp_register_agreement</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14041">PHPBB3-14041</a>] - [Template] - viewtopic_dropdown_top_custom</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14042">PHPBB3-14042</a>] - [Template] - viewtopic_dropdown_bottom_custom</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14043">PHPBB3-14043</a>] - [PHP] - core.get_avatar_after</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14087">PHPBB3-14087</a>] - Add an event to ucp_activate.php.</li> + </ul> + <h4>Sub-task</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13694">PHPBB3-13694</a>] - Allow modifying the Postgres author search query for results</li> + </ul> + <h4>Task</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13947">PHPBB3-13947</a>] - Add CHItA to developer list</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14010">PHPBB3-14010</a>] - Update Plupload to 2.1.8</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14099">PHPBB3-14099</a>] - Update Twig to 1.20</li> + </ul> + + <a name="v314"></a><h3>Changes since 3.1.4</h3> <h4>Bug</h4> diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index b3d6602eeb..06d30fc1fa 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -22,6 +22,12 @@ acp_email_options_after * Since: 3.1.2-RC1 * Purpose: Add settings to mass email form +acp_forums_custom_settings +=== +* Location: adm/style/acp_forums.html +* Since: 3.1.6-RC1 +* Purpose: Add its own box (fieldset) for extension settings + acp_forums_main_settings_append === * Location: adm/style/acp_forums.html @@ -284,6 +290,34 @@ acp_users_prefs_view_prepend * Since: 3.1.0-b3 * Purpose: Add user options fieldset to the top of ACP users view prefs settings +attachment_file_after +=== +* Locations: + + styles/prosilver/template/attachment.html +* Since: 3.1.6-RC1 +* Purpose: Add content after the attachment. + +attachment_file_append +=== +* Locations: + + styles/prosilver/template/attachment.html +* Since: 3.1.6-RC1 +* Purpose: Add custom attachment types displaying to the bottom of attachment block. + +attachment_file_before +=== +* Locations: + + styles/prosilver/template/attachment.html +* Since: 3.1.6-RC1 +* Purpose: Add content before the attachment. + +attachment_file_prepend +=== +* Locations: + + styles/prosilver/template/attachment.html +* Since: 3.1.6-RC1 +* Purpose: Add custom attachment types displaying to the top of attachment block. + forumlist_body_category_header_after === * Locations: @@ -473,6 +507,20 @@ mcp_ban_unban_before * Since: 3.1.0-RC3 * Purpose: Add additional fields to the unban form in MCP +mcp_forum_topic_title_before +=== +* Locations: + + styles/prosilver/template/mcp_forum.html +* Since: 3.1.6-RC1 +* Purpose: Add some information before the topic title + +mcp_forum_topic_title_after +=== +* Locations: + + styles/prosilver/template/mcp_forum.html +* Since: 3.1.6-RC1 +* Purpose: Add some information after the topic title + mcp_front_latest_logs_after === * Locations: @@ -515,6 +563,34 @@ mcp_post_additional_options * Since: 3.1.5-RC1 * Purpose: Add content within the list of post moderation actions +mcp_topic_options_after +=== +* Locations: + + styles/prosilver/template/mcp_topic.html +* Since: 3.1.6-RC1 +* Purpose: Add some options (field, checkbox, ...) after the subject field when split a subject + +mcp_topic_options_before +=== +* Locations: + + styles/prosilver/template/mcp_topic.html +* Since: 3.1.6-RC1 +* Purpose: Add some options (field, checkbox, ...) before the subject field when split a subject + +mcp_topic_topic_title_after +=== +* Locations: + + styles/prosilver/template/mcp_topic.html +* Since: 3.1.6-RC1 +* Purpose: Add some information after the topic title + +mcp_topic_topic_title_before +=== +* Locations: + + styles/prosilver/template/mcp_topic.html +* Since: 3.1.6-RC1 +* Purpose: Add some information before the topic title + mcp_warn_post_add_warning_field_after === * Locations: @@ -841,6 +917,13 @@ overall_header_content_before * Since: 3.1.0-a3 * Purpose: Add content on all pages before the main content, after the header +overall_header_feeds +=== +* Locations: + + styles/prosilver/template/overall_header.html +* Since: 3.1.6-RC1 +* Purpose: Add custom feeds + overall_header_head_append === * Locations: @@ -989,6 +1072,13 @@ posting_editor_subject_before * Since: 3.1.0-a2 * Purpose: Add field (e.g. textbox) to the posting screen before the subject +posting_editor_submit_buttons +=== +* Locations: + + styles/prosilver/template/posting_editor.html +* Since: 3.1.6-RC1 +* Purpose: Add custom buttons in the posting editor + posting_layout_include_panel_body === * Locations: @@ -1031,6 +1121,13 @@ posting_poll_body_options_after * Since: 3.1.4-RC1 * Purpose: Add content after the poll options on creating a poll +posting_topic_title_before +=== +* Locations: + + styles/prosilver/template/posting_layout.html +* Since: 3.1.6-RC1 +* Purpose: Allows to add some information on the left of the topic title in the posting form + quickreply_editor_panel_after === * Locations: @@ -1163,7 +1260,9 @@ topiclist_row_prepend * Locations: + styles/prosilver/template/search_results.html + styles/prosilver/template/viewforum_body.html + + styles/prosilver/template/mcp_forum.html * Since: 3.1.0-a1 +* Changed: 3.1.6-RC1 Added event to mcp_forum.html * Purpose: Add content into topic rows (inside the elements containing topic titles) topiclist_row_append @@ -1171,7 +1270,9 @@ topiclist_row_append * Locations: + styles/prosilver/template/search_results.html + styles/prosilver/template/viewforum_body.html + + styles/prosilver/template/mcp_forum.html * Since: 3.1.0-a1 +* Changed: 3.1.6-RC1 Added event to mcp_forum.html * Purpose: Add content into topic rows (inside the elements containing topic titles) ucp_agreement_terms_after @@ -1202,6 +1303,52 @@ ucp_main_front_user_activity_before * Since: 3.1.6-RC1 * Purpose: Add content right before the user activity info viewing UCP front page +ucp_pm_history_post_buttons_after +=== +* Locations: + + styles/prosilver/template/ucp_pm_history.html +* Since: 3.1.6-RC1 +* Purpose: Add post button to private messages in history review (next to quote etc), at +the end of the list. + +ucp_pm_history_post_buttons_before +=== +* Locations: + + styles/prosilver/template/ucp_pm_history.html +* Since: 3.1.6-RC1 +* Purpose: Add post button to private messages in history review (next to quote etc), at +the start of the list. + +ucp_pm_history_post_buttons_list_after +=== +* Locations: + + styles/prosilver/template/ucp_pm_history.html +* Since: 3.1.6-RC1 +* Purpose: Add post button custom list to private messages in history review (next to quote etc), +after the original list. + +ucp_pm_history_post_buttons_list_before +=== +* Locations: + + styles/prosilver/template/ucp_pm_history.html +* Since: 3.1.6-RC1 +* Purpose: Add post button custom list to private messages in history review (next to quote etc), +before the original list. + +ucp_pm_history_review_after +=== +* Locations: + + styles/prosilver/template/ucp_pm_history.html +* Since: 3.1.6-RC1 +* Purpose: Add content after the private messages history review. + +ucp_pm_history_review_before +=== +* Locations: + + styles/prosilver/template/ucp_pm_history.html +* Since: 3.1.6-RC1 +* Purpose: Add content before the private messages history review. + ucp_pm_viewmessage_avatar_after === * Locations: @@ -1264,6 +1411,22 @@ ucp_pm_viewmessage_post_buttons_before * Purpose: Add post button to private messages (next to edit, quote etc), at the start of the list. +ucp_pm_viewmessage_post_buttons_list_after +=== +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html +* Since: 3.1.6-RC1 +* Purpose: Add post button custom list to private messages (next to edit, quote etc), +after the original list. + +ucp_pm_viewmessage_post_buttons_list_before +=== +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html +* Since: 3.1.6-RC1 +* Purpose: Add post button custom list to private messages (next to edit, quote etc), +before the original list. + ucp_pm_viewmessage_print_head_append === * Locations: @@ -1480,6 +1643,20 @@ viewtopic_buttons_top_after * Since: 3.1.0-RC5 * Purpose: Add buttons after Post Reply button on the top of the posts's list +viewtopic_dropdown_bottom_custom +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html +* Since: 3.1.6-RC1 +* Purpose: Create a custom dropdown menu + +viewtopic_dropdown_top_custom +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html +* Since: 3.1.6-RC1 +* Purpose: Create a custom dropdown menu + viewforum_forum_name_append === * Locations: @@ -1560,6 +1737,20 @@ viewtopic_body_footer_before * Purpose: Add content to the bottom of the View topic screen below the posts and quick reply, directly before the jumpbox in Prosilver. +viewtopic_body_poll_after +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html +* Since: 3.1.6-RC1 +* Purpose: Add content after the poll panel. + +viewtopic_body_poll_before +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html +* Since: 3.1.6-RC1 +* Purpose: Add content before the poll panel. + viewtopic_body_poll_option_after === * Locations: diff --git a/phpBB/download/file.php b/phpBB/download/file.php index 9d54b824f8..fb2b9602cd 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -260,6 +260,30 @@ else $display_cat = ATTACHMENT_CATEGORY_NONE; } + /** + * Event to modify data before sending file to browser + * + * @event core.download_file_send_to_browser_before + * @var int attach_id The attachment ID + * @var array attachment Array with attachment data + * @var int display_cat Attachment category + * @var int download_mode File extension specific download mode + * @var array extension Array with file extensions data + * @var string mode Download mode + * @var bool thumbnail Flag indicating if the file is a thumbnail + * @since 3.1.6-RC1 + */ + $vars = array( + 'attach_id', + 'attachment', + 'display_cat', + 'download_mode', + 'extension', + 'mode', + 'thumbnail', + ); + extract($phpbb_dispatcher->trigger_event('core.download_file_send_to_browser_before', compact($vars))); + if ($thumbnail) { $attachment['physical_filename'] = 'thumb_' . $attachment['physical_filename']; diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index a987213337..c6d63e13f4 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -3997,7 +3997,7 @@ function phpbb_get_avatar($row, $alt, $ignore_config = false, $lazy = false) { global $user, $config, $cache, $phpbb_root_path, $phpEx; global $request; - global $phpbb_container; + global $phpbb_container, $phpbb_dispatcher; if (!$config['allow_avatar'] && !$ignore_config) { @@ -4059,6 +4059,20 @@ function phpbb_get_avatar($row, $alt, $ignore_config = false, $lazy = false) 'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />'; } + /** + * Event to modify HTML <img> tag of avatar + * + * @event core.get_avatar_after + * @var array row Row cleaned by \phpbb\avatar\manager::clean_row + * @var string alt Optional language string for alt tag within image, can be a language key or text + * @var bool ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP + * @var array avatar_data The HTML attributes for avatar <img> tag + * @var string html The HTML <img> tag of generated avatar + * @since 3.1.6-RC1 + */ + $vars = array('row', 'alt', 'ignore_config', 'avatar_data', 'html'); + extract($phpbb_dispatcher->trigger_event('core.get_avatar_after', compact($vars))); + return $html; } diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index 06bbf1ce41..485c9d5eec 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -77,6 +77,30 @@ function mcp_forum_view($id, $mode, $action, $forum_info) break; } + /** + * Get some data in order to execute other actions. + * + * @event core.mcp_forum_view_before + * @var string action The action + * @var array forum_info Array with forum infos + * @var int start Start value + * @var array topic_id_list Array of topics ids + * @var array post_id_list Array of posts ids + * @var array source_topic_ids Array of source topics ids + * @var int to_topic_id Array of destination topics ids + * @since 3.1.6-RC1 + */ + $vars = array( + 'action', + 'forum_info', + 'start', + 'topic_id_list', + 'post_id_list', + 'source_topic_ids', + 'to_topic_id', + ); + extract($phpbb_dispatcher->trigger_event('core.mcp_forum_view_before', compact($vars))); + /* @var $pagination \phpbb\pagination */ $pagination = $phpbb_container->get('pagination'); diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index 5afbe5062e..c50212e8ff 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -1349,6 +1349,29 @@ class parse_message extends bbcode_firstpass $return_message = &$this->message; } + $text = $this->message; + $uid = $this->bbcode_uid; + + /** + * Event to modify the text before it is parsed + * + * @event core.modify_format_display_text_before + * @var string text The message text to parse + * @var string uid The bbcode uid + * @var bool allow_bbcode Do we allow bbcodes + * @var bool allow_magic_url Do we allow magic urls + * @var bool allow_smilies Do we allow smilies + * @var bool update_this_message Do we update the internal message + * with the parsed result + * @since 3.1.6-RC1 + */ + $vars = array('text', 'uid', 'allow_bbcode', 'allow_magic_url', 'allow_smilies', 'update_this_message'); + extract($phpbb_dispatcher->trigger_event('core.modify_format_display_text_before', compact($vars))); + + $this->message = $text; + $this->bbcode_uid = $uid; + unset($text, $uid); + // NOTE: message_status is unreliable for detecting unparsed text because some callers // change $this->message without resetting $this->message_status to 'plain' so we // inspect the message instead diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php index f535073434..5bfb688d3a 100644 --- a/phpBB/includes/ucp/ucp_activate.php +++ b/phpBB/includes/ucp/ucp_activate.php @@ -30,7 +30,7 @@ class ucp_activate function main($id, $mode) { global $config, $phpbb_root_path, $phpEx, $request; - global $db, $user, $auth, $template, $phpbb_container, $phpbb_log; + global $db, $user, $auth, $template, $phpbb_container, $phpbb_log, $phpbb_dispatcher; $user_id = $request->variable('u', 0); $key = $request->variable('k', ''); @@ -150,6 +150,17 @@ class ucp_activate } } + /** + * This event can be used to modify data after user account's activation + * + * @event core.ucp_activate_after + * @var array user_row Array with some user data + * @var string message Language string of the message that will be displayed to the user + * @since 3.1.6-RC1 + */ + $vars = array('user_row', 'message'); + extract($phpbb_dispatcher->trigger_event('core.ucp_activate_after', compact($vars))); + meta_refresh(3, append_sid("{$phpbb_root_path}index.$phpEx")); trigger_error($user->lang[$message]); } diff --git a/phpBB/includes/ucp/ucp_notifications.php b/phpBB/includes/ucp/ucp_notifications.php index c291cc1ddf..51bd77bd4c 100644 --- a/phpBB/includes/ucp/ucp_notifications.php +++ b/phpBB/includes/ucp/ucp_notifications.php @@ -122,7 +122,7 @@ class ucp_notifications if (!empty($mark_read)) { - $phpbb_notifications->mark_notifications_by_id($mark_read, $form_time); + $phpbb_notifications->mark_notifications_by_id('notification.method.board', $mark_read, $form_time); } } diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 7ff6506292..4f9639114f 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -178,6 +178,16 @@ class ucp_register } unset($lang_row); + /** + * Allows to modify the agreements. + * + * To assign data to the template, use $template->assign_vars() + * + * @event core.ucp_register_agreement + * @since 3.1.6-RC1 + */ + $phpbb_dispatcher->dispatch('core.ucp_register_agreement'); + $this->tpl_name = 'ucp_agreement'; return; } diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index a19bb2504b..e75cb4622f 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -38,7 +38,7 @@ $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms); $convertor_data = array( 'forum_name' => 'phpBB 2.0.x', 'version' => '1.0.3', - 'phpbb_version' => '3.1.5', + 'phpbb_version' => '3.1.6', 'author' => '<a href="https://www.phpbb.com/">phpBB Limited</a>', 'dbms' => $dbms, 'dbhost' => $dbhost, diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php index 9ba481e705..f3d6417945 100644 --- a/phpBB/language/en/cli.php +++ b/phpBB/language/en/cli.php @@ -73,6 +73,10 @@ $lang = array_merge($lang, array( '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_THUMBNAIL_DELETE' => 'Delete all existing thumbnails.', + 'CLI_DESCRIPTION_THUMBNAIL_GENERATE' => 'Generate all missing thumbnails.', + 'CLI_DESCRIPTION_THUMBNAIL_RECREATE' => 'Recreate all thumbnails.', + 'CLI_EXTENSION_DISABLE_FAILURE' => 'Could not disable extension %s', 'CLI_EXTENSION_DISABLE_SUCCESS' => 'Successfully disabled extension %s', 'CLI_EXTENSION_ENABLE_FAILURE' => 'Could not enable extension %s', @@ -90,4 +94,17 @@ $lang = array_merge($lang, array( 'CLI_REPARSER_REPARSE_REPARSING' => 'Reparsing %1$s (range %2$d..%3$d)', 'CLI_REPARSER_REPARSE_REPARSING_START' => 'Reparsing %s...', 'CLI_REPARSER_REPARSE_SUCCESS' => 'Reparsing ended with success', + + // In all the case %1$s is the logical name of the file and %2$s the real name on the filesystem + // eg: big_image.png (2_a51529ae7932008cf8454a95af84cacd) generated. + 'CLI_THUMBNAIL_DELETED' => '%1$s (%2$s) deleted.', + 'CLI_THUMBNAIL_DELETING' => 'Deleting thumbnails', + 'CLI_THUMBNAIL_SKIPPED' => '%1$s (%2$s) skipped.', + 'CLI_THUMBNAIL_GENERATED' => '%1$s (%2$s) generated.', + 'CLI_THUMBNAIL_GENERATING' => 'Generating thumbnails', + 'CLI_THUMBNAIL_GENERATING_DONE' => 'All thumbnails have been regenerated.', + 'CLI_THUMBNAIL_DELETING_DONE' => 'All thumbnails have been deleted.', + + 'CLI_THUMBNAIL_NOTHING_TO_GENERATE' => 'No thumbnails to generate.', + 'CLI_THUMBNAIL_NOTHING_TO_DELETE' => 'No thumbnails to delete.', )); diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index 60c9e9cc95..1939a91cfe 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -29,6 +29,11 @@ class upload extends \phpbb\avatar\driver\driver protected $mimetype_guesser; /** + * @var \phpbb\event\dispatcher_interface + */ + protected $dispatcher; + + /** * Construct a driver object * * @param \phpbb\config\config $config phpBB configuration @@ -37,9 +42,10 @@ class upload extends \phpbb\avatar\driver\driver * @param \phpbb\filesystem\filesystem_interface phpBB filesystem helper * @param \phpbb\path_helper $path_helper phpBB path helper * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser + * @param \phpbb\event\dispatcher_interface $dispatcher phpBB Event dispatcher object * @param \phpbb\cache\driver\driver_interface $cache Cache driver */ - public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\cache\driver\driver_interface $cache = null) { $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; @@ -47,6 +53,7 @@ class upload extends \phpbb\avatar\driver\driver $this->filesystem = $filesystem; $this->path_helper = $path_helper; $this->mimetype_guesser = $mimetype_guesser; + $this->dispatcher = $dispatcher; $this->cache = $cache; } @@ -144,6 +151,15 @@ class upload extends \phpbb\avatar\driver\driver $prefix = $this->config['avatar_salt'] . '_'; $file->clean_filename('avatar', $prefix, $row['id']); + // If there was an error during upload, then abort operation + if (sizeof($file->error)) + { + $file->remove(); + $error = $file->error; + return false; + } + + // Calculate new destination $destination = $this->config['avatar_path']; // Adjust destination path (no trailing slash) @@ -158,13 +174,35 @@ class upload extends \phpbb\avatar\driver\driver $destination = ''; } - // Move file and overwrite any existing image - $file->move_file($destination, true); + /** + * Before moving new file in place (and eventually overwriting the existing avatar with the newly uploaded avatar) + * + * @event core.avatar_driver_upload_move_file_before + * @var string destination Destination directory where the file is going to be moved + * @var string prefix Prefix for the avatar filename + * @var array row Array with avatar row data + * @var array error Array of errors, if filled in by this event file will not be moved + * @since 3.1.6-RC1 + */ + $vars = array( + 'destination', + 'prefix', + 'row', + 'error', + ); + extract($this->dispatcher->trigger_event('core.avatar_driver_upload_move_file_before', compact($vars))); - if (sizeof($file->error)) + if (!sizeof($error)) + { + // Move file and overwrite any existing image + $file->move_file($destination, true); + } + + // If there was an error during move, then clean up leftovers + $error = array_merge($error, $file->error); + if (sizeof($error)) { $file->remove(); - $error = array_merge($error, $file->error); return false; } @@ -199,10 +237,32 @@ class upload extends \phpbb\avatar\driver\driver */ public function delete($row) { + + $error = array(); + $destination = $this->config['avatar_path']; + $prefix = $this->config['avatar_salt'] . '_'; $ext = substr(strrchr($row['avatar'], '.'), 1); - $filename = $this->phpbb_root_path . $this->config['avatar_path'] . '/' . $this->config['avatar_salt'] . '_' . $row['id'] . '.' . $ext; + $filename = $this->phpbb_root_path . $destination . '/' . $prefix . $row['id'] . '.' . $ext; + + /** + * Before deleting an existing avatar + * + * @event core.avatar_driver_upload_delete_before + * @var string destination Destination directory where the file is going to be deleted + * @var string prefix Prefix for the avatar filename + * @var array row Array with avatar row data + * @var array error Array of errors, if filled in by this event file will not be deleted + * @since 3.1.6-RC1 + */ + $vars = array( + 'destination', + 'prefix', + 'row', + 'error', + ); + extract($this->dispatcher->trigger_event('core.avatar_driver_upload_delete_before', compact($vars))); - if (file_exists($filename)) + if (!sizeof($error) && file_exists($filename)) { @unlink($filename); } diff --git a/phpBB/phpbb/config/db_text.php b/phpBB/phpbb/config/db_text.php index ddc7c9aef0..818f6bdcc9 100644 --- a/phpBB/phpbb/config/db_text.php +++ b/phpBB/phpbb/config/db_text.php @@ -100,9 +100,9 @@ class db_text $sql = 'UPDATE ' . $this->table . " SET config_value = '" . $this->db->sql_escape($value) . "' WHERE config_name = '" . $this->db->sql_escape($key) . "'"; - $result = $this->db->sql_query($sql); + $this->db->sql_query($sql); - if (!$this->db->sql_affectedrows($result)) + if (!$this->db->sql_affectedrows()) { $sql = 'INSERT INTO ' . $this->table . ' ' . $this->db->sql_build_array('INSERT', array( 'config_name' => (string) $key, diff --git a/phpBB/phpbb/console/command/thumbnail/delete.php b/phpBB/phpbb/console/command/thumbnail/delete.php new file mode 100644 index 0000000000..e8e4cf568e --- /dev/null +++ b/phpBB/phpbb/console/command/thumbnail/delete.php @@ -0,0 +1,178 @@ +<?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\thumbnail; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; + +class delete extends \phpbb\console\command\command +{ + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * phpBB root path + * @var string + */ + protected $phpbb_root_path; + + /** + * Constructor + * + * @param \phpbb\user $user The user object (used to get language information) + * @param \phpbb\db\driver\driver_interface $db Database connection + * @param string $phpbb_root_path Root path + */ + public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, $phpbb_root_path) + { + $this->db = $db; + $this->phpbb_root_path = $phpbb_root_path; + + parent::__construct($user); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('thumbnail:delete') + ->setDescription($this->user->lang('CLI_DESCRIPTION_THUMBNAIL_DELETE')) + ; + } + + /** + * Executes the command thumbnail:delete. + * + * Deletes all existing thumbnails and updates the database accordingly. + * + * @param InputInterface $input The input stream used to get the argument and verbose option. + * @param OutputInterface $output The output stream, used for printing verbose-mode and error information. + * + * @return int 0 if all is ok, 1 if a thumbnail couldn't be deleted. + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + + $io->section($this->user->lang('CLI_THUMBNAIL_DELETING')); + + $sql = 'SELECT COUNT(*) AS nb_missing_thumbnails + FROM ' . ATTACHMENTS_TABLE . ' + WHERE thumbnail = 1'; + $result = $this->db->sql_query($sql); + $nb_missing_thumbnails = (int) $this->db->sql_fetchfield('nb_missing_thumbnails'); + $this->db->sql_freeresult($result); + + if ($nb_missing_thumbnails === 0) + { + $io->warning($this->user->lang('CLI_THUMBNAIL_NOTHING_TO_DELETE')); + return 0; + } + + $sql = 'SELECT attach_id, physical_filename, extension, real_filename, mimetype + FROM ' . ATTACHMENTS_TABLE . ' + WHERE thumbnail = 1'; + $result = $this->db->sql_query($sql); + + $progress = $io->createProgressBar($nb_missing_thumbnails); + if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE) + { + $progress->setFormat('<info>[%percent:3s%%]</info> %message%'); + $progress->setOverwrite(false); + } + else if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) + { + $progress->setFormat('<info>[%current:s%/%max:s%]</info><comment>[%elapsed%/%estimated%][%memory%]</comment> %message%'); + $progress->setOverwrite(false); + } + else + { + $io->newLine(2); + $progress->setFormat( + " %current:s%/%max:s% %bar% %percent:3s%%\n" . + " %elapsed:6s%/%estimated:-6s% %memory:6s%\n"); + $progress->setBarWidth(60); + } + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) + { + $progress->setEmptyBarCharacter('â–‘'); // light shade character \u2591 + $progress->setProgressCharacter(''); + $progress->setBarCharacter('â–“'); // dark shade character \u2593 + } + + $progress->setMessage($this->user->lang('CLI_THUMBNAIL_DELETING')); + + $progress->start(); + + $thumbnail_deleted = array(); + $return = 0; + while ($row = $this->db->sql_fetchrow($result)) + { + $thumbnail_path = $this->phpbb_root_path . 'files/thumb_' . $row['physical_filename']; + + if (@unlink($thumbnail_path)) + { + $thumbnail_deleted[] = $row['attach_id']; + + if (sizeof($thumbnail_deleted) === 250) + { + $this->commit_changes($thumbnail_deleted); + $thumbnail_deleted = array(); + } + + $progress->setMessage($this->user->lang('CLI_THUMBNAIL_DELETED', $row['real_filename'], $row['physical_filename'])); + } + else + { + $return = 1; + $progress->setMessage('<error>' . $this->user->lang('CLI_THUMBNAIL_SKIPPED', $row['real_filename'], $row['physical_filename']) . '</error>'); + } + + $progress->advance(); + } + $this->db->sql_freeresult($result); + + if (!empty($thumbnail_deleted)) + { + $this->commit_changes($thumbnail_deleted); + } + + $progress->finish(); + + $io->newLine(2); + $io->success($this->user->lang('CLI_THUMBNAIL_DELETING_DONE')); + + return $return; + } + + /** + * Commits the changes to the database + * + * @param array $thumbnail_deleted + */ + protected function commit_changes(array $thumbnail_deleted) + { + $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' + SET thumbnail = 0 + WHERE ' . $this->db->sql_in_set('attach_id', $thumbnail_deleted); + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/console/command/thumbnail/generate.php b/phpBB/phpbb/console/command/thumbnail/generate.php new file mode 100644 index 0000000000..e677db3a97 --- /dev/null +++ b/phpBB/phpbb/console/command/thumbnail/generate.php @@ -0,0 +1,204 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\console\command\thumbnail; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; + +class generate extends \phpbb\console\command\command +{ + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var \phpbb\cache\service + */ + protected $cache; + + /** + * phpBB root path + * @var string + */ + protected $phpbb_root_path; + + /** + * PHP extension. + * + * @var string + */ + protected $php_ext; + + /** + * Constructor + * + * @param \phpbb\user $user The user object (used to get language information) + * @param \phpbb\db\driver\driver_interface $db Database connection + * @param \phpbb\cache\service $cache The cache service + * @param string $phpbb_root_path Root path + * @param string $php_ext PHP extension + */ + public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, $phpbb_root_path, $php_ext) + { + $this->db = $db; + $this->cache = $cache; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + parent::__construct($user); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('thumbnail:generate') + ->setDescription($this->user->lang('CLI_DESCRIPTION_THUMBNAIL_GENERATE')) + ; + } + + /** + * Executes the command thumbnail:generate. + * + * Generate a thumbnail for all attachments which need one and don't have it yet. + * + * @param InputInterface $input The input stream used to get the argument and verboe option. + * @param OutputInterface $output The output stream, used for printing verbose-mode and error information. + * + * @return int 0. + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + + $io->section($this->user->lang('CLI_THUMBNAIL_GENERATING')); + + $sql = 'SELECT COUNT(*) AS nb_missing_thumbnails + FROM ' . ATTACHMENTS_TABLE . ' + WHERE thumbnail = 0'; + $result = $this->db->sql_query($sql); + $nb_missing_thumbnails = (int) $this->db->sql_fetchfield('nb_missing_thumbnails'); + $this->db->sql_freeresult($result); + + if ($nb_missing_thumbnails === 0) + { + $io->warning($this->user->lang('CLI_THUMBNAIL_NOTHING_TO_GENERATE')); + return 0; + } + + $extensions = $this->cache->obtain_attach_extensions(true); + + $sql = 'SELECT attach_id, physical_filename, extension, real_filename, mimetype + FROM ' . ATTACHMENTS_TABLE . ' + WHERE thumbnail = 0'; + $result = $this->db->sql_query($sql); + + if (!function_exists('create_thumbnail')) + { + require($this->phpbb_root_path . 'includes/functions_posting.' . $this->php_ext); + } + + $progress = $io->createProgressBar($nb_missing_thumbnails); + if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE) + { + $progress->setFormat('<info>[%percent:3s%%]</info> %message%'); + $progress->setOverwrite(false); + } + else if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) + { + $progress->setFormat('<info>[%current:s%/%max:s%]</info><comment>[%elapsed%/%estimated%][%memory%]</comment> %message%'); + $progress->setOverwrite(false); + } + else + { + $io->newLine(2); + $progress->setFormat( + " %current:s%/%max:s% %bar% %percent:3s%%\n" . + " %elapsed:6s%/%estimated:-6s% %memory:6s%\n"); + $progress->setBarWidth(60); + } + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) + { + $progress->setEmptyBarCharacter('â–‘'); // light shade character \u2591 + $progress->setProgressCharacter(''); + $progress->setBarCharacter('â–“'); // dark shade character \u2593 + } + + $progress->setMessage($this->user->lang('CLI_THUMBNAIL_GENERATING')); + + $progress->start(); + + $thumbnail_created = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + if (isset($extensions[$row['extension']]['display_cat']) && $extensions[$row['extension']]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE) + { + $source = $this->phpbb_root_path . 'files/' . $row['physical_filename']; + $destination = $this->phpbb_root_path . 'files/thumb_' . $row['physical_filename']; + + if (create_thumbnail($source, $destination, $row['mimetype'])) + { + $thumbnail_created[] = (int) $row['attach_id']; + + if (count($thumbnail_created) === 250) + { + $this->commit_changes($thumbnail_created); + $thumbnail_created = array(); + } + + $progress->setMessage($this->user->lang('CLI_THUMBNAIL_GENERATED', $row['real_filename'], $row['physical_filename'])); + } + else + { + $progress->setMessage('<info>' . $this->user->lang('CLI_THUMBNAIL_SKIPPED', $row['real_filename'], $row['physical_filename']) . '</info>'); + } + } + + $progress->advance(); + } + $this->db->sql_freeresult($result); + + if (!empty($thumbnail_created)) + { + $this->commit_changes($thumbnail_created); + } + + $progress->finish(); + + $io->newLine(2); + $io->success($this->user->lang('CLI_THUMBNAIL_GENERATING_DONE')); + + return 0; + } + + /** + * Commits the changes to the database + * + * @param array $thumbnail_created + */ + protected function commit_changes(array $thumbnail_created) + { + $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' + SET thumbnail = 1 + WHERE ' . $this->db->sql_in_set('attach_id', $thumbnail_created); + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/console/command/thumbnail/recreate.php b/phpBB/phpbb/console/command/thumbnail/recreate.php new file mode 100644 index 0000000000..382da290bf --- /dev/null +++ b/phpBB/phpbb/console/command/thumbnail/recreate.php @@ -0,0 +1,72 @@ +<?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\thumbnail; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Output\OutputInterface; + +class recreate extends \phpbb\console\command\command +{ + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('thumbnail:recreate') + ->setDescription($this->user->lang('CLI_DESCRIPTION_THUMBNAIL_RECREATE')) + ; + } + + /** + * Executes the command thumbnail:recreate. + * + * This command is a "macro" to execute thumbnail:delete and then thumbnail:generate. + * + * @param InputInterface $input The input stream used to get the argument and verboe option. + * @param OutputInterface $output The output stream, used for printing verbose-mode and error information. + * + * @return int 0 if all is ok, 1 if a thumbnail couldn't be deleted. + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $parameters = array( + 'command' => 'thumbnail:delete' + ); + + if ($input->getOption('verbose')) + { + $parameters['-' . str_repeat('v', $output->getVerbosity() - 1)] = true; + } + + $this->getApplication()->setAutoExit(false); + + $input_delete = new ArrayInput($parameters); + $return = $this->getApplication()->run($input_delete, $output); + + if ($return === 0) + { + $parameters['command'] = 'thumbnail:generate'; + + $input_create = new ArrayInput($parameters); + $return = $this->getApplication()->run($input_create, $output); + } + + $this->getApplication()->setAutoExit(true); + + return $return; + } +} diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 8d360fc3e2..2925765e94 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -962,7 +962,7 @@ abstract class driver implements driver_interface { if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query)) { - $this->sql_report .= 'Affected rows: <b>' . $this->sql_affectedrows($this->query_result) . '</b> | '; + $this->sql_report .= 'Affected rows: <b>' . $this->sql_affectedrows() . '</b> | '; } $this->sql_report .= 'Before: ' . sprintf('%.5f', $this->curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $this->curtime) . 's</b>'; } diff --git a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php index 3b0d53d803..2c7b7edf2e 100644 --- a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php +++ b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php @@ -160,7 +160,7 @@ class style_update_p1 extends \phpbb\db\migration\migration FROM ' . STYLES_TABLE . " WHERE style_name = 'prosilver'"; $result = $this->sql_query($sql); - $default_style = $this->db->sql_fetchfield($result); + $default_style = $this->db->sql_fetchfield('style_id'); $this->db->sql_freeresult($result); $this->config->set('default_style', $default_style); diff --git a/phpBB/phpbb/db/migration/data/v31x/v316rc1.php b/phpBB/phpbb/db/migration/data/v31x/v316rc1.php new file mode 100644 index 0000000000..487cd05e5d --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v316rc1.php @@ -0,0 +1,31 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v31x; + +class v316rc1 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v315', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.6-RC1')), + ); + } +} diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index cb4ddb8783..755edb5297 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -92,7 +92,8 @@ class installer $module_found = false; // Variable used to check if the install process have been finished - $install_finished = false; + $install_finished = false; + $fail_cleanup = false; // We are installing something, so the introduction stage can go now... $this->install_config->set_finished_navigation_stage(array('install', 0, 'introduction')); @@ -209,13 +210,19 @@ class installer { // Do nothing } + catch (\Exception $e) + { + $this->iohandler->add_error_message($e->getMessage()); + $this->iohandler->send_response(); + $fail_cleanup = true; + } if ($install_finished) { // Send install finished message $this->iohandler->set_progress('INSTALLER_FINISHED', $this->install_config->get_task_progress_count()); } - else + else if (!$fail_cleanup) { $this->iohandler->request_refresh(); } @@ -223,7 +230,7 @@ class installer // Save install progress try { - if ($install_finished) + if ($install_finished || $fail_cleanup) { $this->install_config->clean_up_config_file(); } diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index 04259382ba..4be678ac91 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -166,6 +166,7 @@ class manager $notification_type_id = false; } + /** @var method_interface $method */ foreach ($this->get_available_subscription_methods() as $method) { $method->mark_notifications($notification_type_id, $item_id, $user_id, $time, $mark_read); @@ -589,6 +590,7 @@ class manager $user_id = $user_id ?: $this->user->data['user_id']; $subscriptions = array(); + $default_methods = $this->get_default_methods(); $user_notifications = $this->get_user_notifications($user_id); @@ -596,27 +598,32 @@ class manager { foreach ($types as $id => $type) { - if (empty($user_notifications[$id])) - { - $subscriptions[$id] = $this->get_default_methods(); - } - else + $type_subscriptions = $default_methods; + if (!empty($user_notifications[$id])) { foreach ($user_notifications[$id] as $user_notification) { + $key = array_search($user_notification['method'], $type_subscriptions, true); if (!$user_notification['notify']) { + if ($key !== false) + { + unset($type_subscriptions[$key]); + } + continue; } - - if (!isset($subscriptions[$id])) + else if ($key === false) { - $subscriptions[$id] = array(); + $type_subscriptions[] = $user_notification['method']; } - - $subscriptions[$id][] = $user_notification['method']; } } + + if (!empty($type_subscriptions)) + { + $subscriptions[$id] = $type_subscriptions; + } } } diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index 06f7f9c615..31e853d7d9 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -503,7 +503,7 @@ abstract class base implements \phpbb\notification\type\type_interface } else { - $this->notification_manager->mark_notifications($this->get_type(), (int) $this->item_id, (int) $this->user_id, $this->notification_read); + $this->notification_manager->mark_notifications($this->get_type(), (int) $this->item_id, (int) $this->user_id, false, $this->notification_read); } } diff --git a/phpBB/phpbb/notification/type/type_interface.php b/phpBB/phpbb/notification/type/type_interface.php index 9b4446ac47..f9f832bdda 100644 --- a/phpBB/phpbb/notification/type/type_interface.php +++ b/phpBB/phpbb/notification/type/type_interface.php @@ -206,7 +206,7 @@ interface type_interface * @param bool $return True to return a string containing the SQL code to update this item, False to execute it (Default: False) * @return string */ - public function mark_read($return); + public function mark_read($return = false); /** * Mark this item unread @@ -214,5 +214,5 @@ interface type_interface * @param bool $return True to return a string containing the SQL code to update this item, False to execute it (Default: False) * @return string */ - public function mark_unread($return); + public function mark_unread($return = false); } diff --git a/phpBB/phpbb/profilefields/manager.php b/phpBB/phpbb/profilefields/manager.php index 4ad3214ae4..ea4b24af56 100644 --- a/phpBB/phpbb/profilefields/manager.php +++ b/phpBB/phpbb/profilefields/manager.php @@ -276,12 +276,32 @@ class manager $profile_field = $this->type_collection[$field_data['field_type']]; $tpl_fields[] = array( + 'PROFILE_FIELD_IDENT' => $field_ident, 'PROFILE_FIELD_TYPE' => $field_data['field_type'], 'PROFILE_FIELD_NAME' => $profile_field->get_field_name($field_data['lang_name']), 'PROFILE_FIELD_EXPLAIN' => $this->user->lang($field_data['lang_explain']), ); } + $profile_cache = $this->profile_cache; + + /** + * Event to modify template headlines of the generated profile fields + * + * @event core.generate_profile_fields_template_headlines + * @var string restrict_option Restrict the published fields to a certain profile field option + * @var array tpl_fields Array with template data fields + * @var array profile_cache A copy of the profile cache to make additional checks + * @since 3.1.6-RC1 + */ + $vars = array( + 'restrict_option', + 'tpl_fields', + 'profile_cache', + ); + extract($this->dispatcher->trigger_event('core.generate_profile_fields_template_headlines', compact($vars))); + unset($profile_cache); + return $tpl_fields; } diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index 9f1aaec7c2..ba9f5f3a77 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -685,6 +685,7 @@ class fulltext_mysql extends \phpbb\search\base * Set to 0 to force a re-count * @var string sql_sort_table CROSS JOIN'ed table to allow doing the sort chosen * @var string sql_sort_join Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table + * @var string type Either "posts" or "topics" specifying the type of search being made * @var array author_ary Array of user_id containing the users to filter the results to * @var string author_name An extra username to search on * @var string sql_author SQL WHERE condition for the post author ids @@ -697,6 +698,7 @@ class fulltext_mysql extends \phpbb\search\base * @var string sort_days Time, in days, that the oldest post showing can have * @var string sql_time The SQL to search on the time specifyed by sort_days * @var bool firstpost_only Wether or not to search only on the first post of the topics + * @var string sql_firstpost The SQL with the conditions to join the tables when using firstpost_only * @var array ex_fid_ary Forum ids that must not be searched on * @var array sql_fora SQL query for ex_fid_ary * @var string m_approve_fid_sql WHERE clause condition on post_visibility restrictions @@ -707,6 +709,7 @@ class fulltext_mysql extends \phpbb\search\base 'result_count', 'sql_sort_table', 'sql_sort_join', + 'type', 'author_ary', 'author_name', 'sql_author', @@ -719,6 +722,7 @@ class fulltext_mysql extends \phpbb\search\base 'sort_days', 'sql_time', 'firstpost_only', + 'sql_firstpost', 'ex_fid_ary', 'sql_fora', 'm_approve_fid_sql', diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 43f399eb13..41d3434c7d 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -736,9 +736,10 @@ class fulltext_native extends \phpbb\search\base * @var array must_not_contain_ids Ids that cannot be taken into account for the results * @var array must_exclude_one_ids Ids that cannot be on the results * @var array must_contain_ids Ids that must be on the results - * @var int result_count The previous result count for the format of the query + * @var int total_results The previous result count for the format of the query * Set to 0 to force a re-count - * @var bool join_topic Weather or not TOPICS_TABLE should be CROSS JOIN'ED + * @var array sql_array The data on how to search in the DB at this point + * @var bool left_join_topics Whether or not TOPICS_TABLE should be CROSS JOIN'ED * @var array author_ary Array of user_id containing the users to filter the results to * @var string author_name An extra username to search on (!empty(author_ary) must be true, to be relevant) * @var array ex_fid_ary Which forums not to search on @@ -751,7 +752,7 @@ class fulltext_native extends \phpbb\search\base * @var string sql_where An array of the current WHERE clause conditions * @var string sql_match Which columns to do the search on * @var string sql_match_where Extra conditions to use to properly filter the matching process - * @var string group_by Whether or not the SQL query requires a GROUP BY for the elements in the SELECT clause + * @var bool group_by Whether or not the SQL query requires a GROUP BY for the elements in the SELECT clause * @var string sort_by_sql The possible predefined sort types * @var string sort_key The sort type used from the possible sort types * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used @@ -764,8 +765,9 @@ class fulltext_native extends \phpbb\search\base 'must_not_contain_ids', 'must_exclude_one_ids', 'must_contain_ids', - 'result_count', - 'join_topic', + 'total_results', + 'sql_array', + 'left_join_topics', 'author_ary', 'author_name', 'ex_fid_ary', @@ -1051,6 +1053,7 @@ class fulltext_native extends \phpbb\search\base * @event core.search_native_author_count_query_before * @var int total_results The previous result count for the format of the query. * Set to 0 to force a re-count + * @var string type The type of search being made * @var string select SQL SELECT clause for what to get * @var string sql_sort_table CROSS JOIN'ed table to allow doing the sort chosen * @var string sql_sort_join Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table @@ -1063,6 +1066,7 @@ class fulltext_native extends \phpbb\search\base * @var string sort_days Time, in days, that the oldest post showing can have * @var string sql_time The SQL to search on the time specifyed by sort_days * @var bool firstpost_only Wether or not to search only on the first post of the topics + * @var string sql_firstpost The SQL used in the WHERE claused to filter by firstpost. * @var array ex_fid_ary Forum ids that must not be searched on * @var array sql_fora SQL query for ex_fid_ary * @var int start How many posts to skip in the search results (used for pagination) @@ -1070,6 +1074,7 @@ class fulltext_native extends \phpbb\search\base */ $vars = array( 'total_results', + 'type', 'select', 'sql_sort_table', 'sql_sort_join', @@ -1082,6 +1087,7 @@ class fulltext_native extends \phpbb\search\base 'sort_days', 'sql_time', 'firstpost_only', + 'sql_firstpost', 'ex_fid_ary', 'sql_fora', 'start', diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index fc125f5edc..173b20ee53 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -327,6 +327,14 @@ class user extends \phpbb\session // After calling it we continue script execution... phpbb_user_session_handler(); + /** + * Execute code at the end of user setup + * + * @event core.user_setup_after + * @since 3.1.6-RC1 + */ + $phpbb_dispatcher->dispatch('core.user_setup_after'); + // If this function got called from the error handler we are finished here. if (defined('IN_ERROR_HANDLER')) { diff --git a/phpBB/styles/prosilver/template/attachment.html b/phpBB/styles/prosilver/template/attachment.html index c227e710b1..4546f53d6c 100644 --- a/phpBB/styles/prosilver/template/attachment.html +++ b/phpBB/styles/prosilver/template/attachment.html @@ -1,8 +1,10 @@ +<!-- EVENT attachment_file_before --> <!-- BEGIN _file --> <!-- IF _file.S_DENIED --> <p>[{_file.DENIED_MESSAGE}]</p> <!-- ELSE --> + <!-- EVENT attachment_file_prepend --> <!-- IF _file.S_THUMBNAIL --> <dl class="thumbnail"> @@ -11,7 +13,6 @@ </dl> <!-- ENDIF --> - <!-- IF _file.S_IMAGE --> <dl class="file"> <dt class="attach-image"><img src="{_file.U_INLINE_LINK}" class="postimage" alt="{_file.DOWNLOAD_NAME}" onclick="viewableArea(this);" /></dt> @@ -28,8 +29,6 @@ </dl> <!-- ENDIF --> - - <!-- IF _file.S_WM_FILE --> <!-- method used here from http://alistapart.com/articles/byebyeembed / autosizing seems to not work always, this will not fix --> <object width="320" height="285" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" id="wmstream_{_file.ATTACH_ID}"> @@ -118,5 +117,7 @@ <a href="{_file.U_DOWNLOAD_LINK}">{_file.DOWNLOAD_NAME}</a> [ {_file.FILESIZE} {_file.SIZE_LANG} | {_file.L_DOWNLOAD_COUNT} ]</p> <!-- ENDIF --> + <!-- EVENT attachment_file_append --> <!-- ENDIF --> <!-- END _file --> +<!-- EVENT attachment_file_after --> diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js index 0d53a53d8e..8e5b257ba4 100644 --- a/phpBB/styles/prosilver/template/forum_fn.js +++ b/phpBB/styles/prosilver/template/forum_fn.js @@ -156,7 +156,11 @@ function selectCode(a) { // Safari and Chrome if (s.setBaseAndExtent) { var l = (e.innerText.length > 1) ? e.innerText.length - 1 : 1; - s.setBaseAndExtent(e, 0, e, l); + try { + s.setBaseAndExtent(e, 0, e, l); + } catch (error) { + s.setBaseAndExtent(e, 0, e, 1); + } } // Firefox and Opera else { diff --git a/phpBB/styles/prosilver/template/mcp_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html index f0d8d45e40..0758dd6f27 100644 --- a/phpBB/styles/prosilver/template/mcp_forum.html +++ b/phpBB/styles/prosilver/template/mcp_forum.html @@ -13,9 +13,9 @@ <div class="action-bar top"> <div class="pagination"> {TOTAL_TOPICS} - <!-- IF .pagination --> + <!-- IF .pagination --> <!-- INCLUDE pagination.html --> - <!-- ELSE --> + <!-- ELSE --> • {PAGE_NUMBER} <!-- ENDIF --> </div> @@ -40,9 +40,11 @@ <dt <!-- IF topicrow.TOPIC_ICON_IMG -->style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF -->> <!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}" class="icon-link"></a><!-- ENDIF --> <div class="list-inner"> - + <!-- EVENT topiclist_row_prepend --> <!-- IF topicrow.S_SELECT_TOPIC --><a href="{topicrow.U_SELECT_TOPIC}" class="topictitle">[ {L_SELECT_MERGE} ]</a> <!-- ENDIF --> + <!-- EVENT mcp_forum_topic_title_before --> <a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a> + <!-- EVENT mcp_forum_topic_title_after --> <!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF --> <!-- IF topicrow.S_TOPIC_DELETED or topicrow.S_POSTS_DELETED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.DELETED_IMG}</a> <!-- ENDIF --> <!-- IF topicrow.S_TOPIC_REPORTED --><a href="{topicrow.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --> @@ -74,7 +76,7 @@ <!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF --> {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} </div> - + <!-- EVENT topiclist_row_append --> </div> </dt> <dd class="posts">{topicrow.REPLIES} <dfn>{L_REPLIES}</dfn></dd> @@ -107,9 +109,9 @@ <div class="action-bar bottom"> <div class="pagination"> {TOTAL_TOPICS} - <!-- IF .pagination --> + <!-- IF .pagination --> <!-- INCLUDE pagination.html --> - <!-- ELSE --> + <!-- ELSE --> • {PAGE_NUMBER} <!-- ENDIF --> </div> diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index 082bea22f1..c21b676370 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -54,10 +54,12 @@ </dl> <!-- ENDIF --> + <!-- EVENT mcp_topic_options_before --> <dl> <dt><label for="subject">{L_SPLIT_SUBJECT}{L_COLON}</label></dt> <dd><input type="text" name="subject" id="subject" size="45" maxlength="124" tabindex="2" value="{SPLIT_SUBJECT}" title="{L_SPLIT_SUBJECT}" class="inputbox" /></dd> </dl> + <!-- EVENT mcp_topic_options_after --> <dl> <dt><label>{L_SPLIT_FORUM}{L_COLON}</label></dt> <dd><select name="to_forum_id">{S_FORUM_SELECT}</select></dd> @@ -87,7 +89,7 @@ <h3 id="review"> <span class="right-box"><a href="#review" onclick="viewableArea(getElementById('topicreview'), true); var rev_text = getElementById('review').getElementsByTagName('a').item(0).firstChild; if (rev_text.data == '{LA_EXPAND_VIEW}'){rev_text.data = '{LA_COLLAPSE_VIEW}'; } else if (rev_text.data == '{LA_COLLAPSE_VIEW}'){rev_text.data = '{LA_EXPAND_VIEW}'};">{L_EXPAND_VIEW}</a></span> - {L_TOPIC_REVIEW}{L_COLON} {TOPIC_TITLE} + {L_TOPIC_REVIEW}{L_COLON} <!-- EVENT mcp_topic_topic_title_before -->{TOPIC_TITLE}<!-- EVENT mcp_topic_topic_title_after --> </h3> <div id="topicreview"> @@ -153,9 +155,9 @@ <div class="action-bar bottom"> <div class="pagination"> {TOTAL_POSTS} - <!-- IF .pagination --> + <!-- IF .pagination --> <!-- INCLUDE pagination.html --> - <!-- ELSE --> + <!-- ELSE --> • {PAGE_NUMBER} <!-- ENDIF --> </div> diff --git a/phpBB/styles/prosilver/template/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html index 41c5793320..faf48e0b05 100644 --- a/phpBB/styles/prosilver/template/navbar_header.html +++ b/phpBB/styles/prosilver/template/navbar_header.html @@ -93,12 +93,12 @@ <!-- DEFINE $MICRODATA = ' itemtype="http://data-vocabulary.org/Breadcrumb" itemscope=""' --> <!-- EVENT overall_header_breadcrumbs_before --> <li class="small-icon icon-home breadcrumbs"> - <!-- IF U_SITE_HOME --><span class="crumb"><a href="{U_SITE_HOME}"{$MICRODATA} data-navbar-reference="home">{L_SITE_HOME}</a></span><!-- ENDIF --> + <!-- IF U_SITE_HOME --><span class="crumb"{$MICRODATA}><a href="{U_SITE_HOME}" data-navbar-reference="home" itemprop="url"><span itemprop="title">{L_SITE_HOME}</span></a></span><!-- ENDIF --> <!-- EVENT overall_header_breadcrumb_prepend --> - <span class="crumb"><a href="{U_INDEX}" accesskey="h"{$MICRODATA} data-navbar-reference="index">{L_INDEX}</a></span> + <span class="crumb"{$MICRODATA}><a href="{U_INDEX}" accesskey="h" data-navbar-reference="index" itemprop="url"><span itemprop="title">{L_INDEX}</span></a></span> <!-- BEGIN navlinks --> <!-- EVENT overall_header_navlink_prepend --> - <span class="crumb"><a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->>{navlinks.FORUM_NAME}</a></span> + <span class="crumb"{$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->><a href="{navlinks.U_VIEW_FORUM}" itemprop="url"><span itemprop="title">{navlinks.FORUM_NAME}</span></a></span> <!-- EVENT overall_header_navlink_append --> <!-- END navlinks --> <!-- EVENT overall_header_breadcrumb_append --> diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html index ebe6470fee..45f8eaa1c9 100644 --- a/phpBB/styles/prosilver/template/overall_header.html +++ b/phpBB/styles/prosilver/template/overall_header.html @@ -14,6 +14,7 @@ <!-- IF S_ENABLE_FEEDS_TOPICS_ACTIVE --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FEED_TOPICS_ACTIVE}" href="{U_FEED}?mode=topics_active"><!-- ENDIF --> <!-- IF S_ENABLE_FEEDS_FORUM and S_FORUM_ID --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FORUM} - {FORUM_NAME}" href="{U_FEED}?f={S_FORUM_ID}"><!-- ENDIF --> <!-- IF S_ENABLE_FEEDS_TOPIC and S_TOPIC_ID --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_TOPIC} - {TOPIC_TITLE}" href="{U_FEED}?f={S_FORUM_ID}&t={S_TOPIC_ID}"><!-- ENDIF --> + <!-- EVENT overall_header_feeds --> <!-- ENDIF --> <!-- IF U_CANONICAL --> diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html index 1581afdb12..1a9b3398aa 100644 --- a/phpBB/styles/prosilver/template/posting_editor.html +++ b/phpBB/styles/prosilver/template/posting_editor.html @@ -89,6 +89,7 @@ <fieldset class="submit-buttons"> {S_HIDDEN_ADDRESS_FIELD} {S_HIDDEN_FIELDS} + <!-- EVENT posting_editor_submit_buttons --> <!-- IF S_HAS_DRAFTS --><input type="submit" accesskey="d" tabindex="8" name="load" value="{L_LOAD_DRAFT}" class="button2" onclick="load_draft = true;" /> <!-- ENDIF --> <!-- IF S_SAVE_ALLOWED --><input type="submit" accesskey="k" tabindex="7" name="save" value="{L_SAVE_DRAFT}" class="button2" /> <!-- ENDIF --> <input type="submit" tabindex="5" name="preview" value="{L_PREVIEW}" class="button1"<!-- IF not S_PRIVMSGS --> onclick="document.getElementById('postform').action += '#preview';"<!-- ENDIF --> /> diff --git a/phpBB/styles/prosilver/template/posting_layout.html b/phpBB/styles/prosilver/template/posting_layout.html index 34f0c63d5c..19a7351d78 100644 --- a/phpBB/styles/prosilver/template/posting_layout.html +++ b/phpBB/styles/prosilver/template/posting_layout.html @@ -1,7 +1,7 @@ <!-- INCLUDE overall_header.html --> <!-- IF TOPIC_TITLE --> - <h2 class="posting-title"><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2> + <h2 class="posting-title"><!-- EVENT posting_topic_title_before --><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2> <!-- ELSE --> <h2 class="posting-title"><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2> <!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/ucp_pm_history.html b/phpBB/styles/prosilver/template/ucp_pm_history.html index 8f7b4fdb3e..f4dc1c3b34 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_history.html +++ b/phpBB/styles/prosilver/template/ucp_pm_history.html @@ -4,6 +4,7 @@ {L_MESSAGE_HISTORY}{L_COLON} </h3> +<!-- EVENT ucp_pm_history_review_before --> <div id="topicreview"> <script type="text/javascript"> // <![CDATA[ @@ -17,15 +18,22 @@ <div class="postbody" id="pr{history_row.MSG_ID}"> <h3><a href="{history_row.U_VIEW_MESSAGE}" <!-- IF history_row.S_CURRENT_MSG -->class="current"<!-- ENDIF -->>{history_row.SUBJECT}</a></h3> - <!-- IF history_row.U_QUOTE or history_row.MESSAGE_AUTHOR_QUOTE --> + <!-- DEFINE $SHOW_PM_HISTORY_POST_BUTTONS = (history_row.U_QUOTE or history_row.MESSAGE_AUTHOR_QUOTE) --> + <!-- EVENT ucp_pm_history_post_buttons_list_before --> + <!-- IF $SHOW_PM_HISTORY_POST_BUTTONS --> <ul class="post-buttons"> + <!-- EVENT ucp_pm_history_post_buttons_before --> + <!-- IF history_row.U_QUOTE or history_row.MESSAGE_AUTHOR_QUOTE --> <li> <a <!-- IF history_row.U_QUOTE -->href="{history_row.U_QUOTE}"<!-- ELSE -->href="#postingbox" onclick="addquote({history_row.MSG_ID}, '{history_row.MESSAGE_AUTHOR_QUOTE}', '{LA_WROTE}', {time:{history_row.MESSAGE_TIME},user_id:{history_row.USER_ID}});"<!-- ENDIF --> title="{L_QUOTE} {history_row.MESSAGE_AUTHOR}" class="button icon-button quote-icon"> <span>{L_QUOTE} {history_row.MESSAGE_AUTHOR}</span> </a> </li> + <!-- ENDIF --> + <!-- EVENT ucp_pm_history_post_buttons_after --> </ul> <!-- ENDIF --> + <!-- EVENT ucp_pm_history_post_buttons_list_after --> <p class="author">{history_row.MINI_POST_IMG} {L_SENT_AT}{L_COLON} <strong>{history_row.SENT_DATE}</strong><br /> {L_MESSAGE_BY_AUTHOR} {history_row.MESSAGE_AUTHOR_FULL}</p> @@ -37,6 +45,7 @@ </div> <!-- END history_row --> </div> +<!-- EVENT ucp_pm_history_review_after --> <hr /> <p><a href="#cp-main" class="top2">{L_BACK_TO_TOP}</a></p> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html index d93a62282e..47e4d1c63a 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html @@ -25,7 +25,7 @@ <fieldset class="submit-buttons"> <input type="hidden" name="export_option" value="CSV" /> <input class="button1" type="submit" name="submit_export" value="{L_EXPORT_FOLDER}" /> - <input class="button2" type="reset" value="Reset" name="reset" /> + <input class="button2" type="reset" value="{L_RESET}" name="reset" /> {S_FORM_TOKEN} </fieldset> </form> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index 7704209fc8..d92b90a045 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -75,7 +75,9 @@ <div class="postbody"> <h3 class="first">{SUBJECT}</h3> - <!-- IF U_DELETE or U_EDIT or U_QUOTE or U_REPORT --> + <!-- DEFINE $SHOW_PM_POST_BUTTONS = (U_EDIT or U_DELETE or U_REPORT or U_QUOTE) --> + <!-- EVENT ucp_pm_viewmessage_post_buttons_list_before --> + <!-- IF $SHOW_PM_POST_BUTTONS --> <ul class="post-buttons"> <!-- EVENT ucp_pm_viewmessage_post_buttons_before --> <!-- IF U_EDIT --> @@ -101,6 +103,7 @@ <!-- EVENT ucp_pm_viewmessage_post_buttons_after --> </ul> <!-- ENDIF --> + <!-- EVENT ucp_pm_viewmessage_post_buttons_list_after --> <p class="author"> <strong>{L_SENT_AT}{L_COLON}</strong> {SENT_DATE} diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index e2f04db3e1..87a9e95dce 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -40,6 +40,7 @@ </div> <!-- INCLUDE viewtopic_topic_tools.html --> + <!-- EVENT viewtopic_dropdown_top_custom --> <!-- IF S_DISPLAY_SEARCHBOX --> <div class="search-box" role="search"> @@ -67,6 +68,8 @@ <!-- EVENT viewtopic_body_pagination_top_after --> </div> +<!-- EVENT viewtopic_body_poll_before --> + <!-- IF S_HAS_POLL --> <form method="post" action="{S_POLL_ACTION}" data-ajax="vote_poll" class="topic_poll"> @@ -120,6 +123,8 @@ <hr /> <!-- ENDIF --> +<!-- EVENT viewtopic_body_poll_after --> + <!-- BEGIN postrow --> <!-- EVENT viewtopic_body_postrow_post_before --> <!-- IF postrow.S_FIRST_UNREAD --> @@ -212,9 +217,10 @@ <h3 <!-- IF postrow.S_FIRST_ROW -->class="first"<!-- ENDIF -->><!-- IF postrow.POST_ICON_IMG --><img src="{T_ICONS_PATH}{postrow.POST_ICON_IMG}" width="{postrow.POST_ICON_IMG_WIDTH}" height="{postrow.POST_ICON_IMG_HEIGHT}" alt="" /> <!-- ENDIF --><a href="#p{postrow.POST_ID}">{postrow.POST_SUBJECT}</a></h3> + <!-- DEFINE $SHOW_POST_BUTTONS = (postrow.U_EDIT or postrow.U_DELETE or postrow.U_REPORT or postrow.U_WARN or postrow.U_INFO or postrow.U_QUOTE) --> <!-- EVENT viewtopic_body_post_buttons_list_before --> <!-- IF not S_IS_BOT --> - <!-- IF postrow.U_EDIT or postrow.U_DELETE or postrow.U_REPORT or postrow.U_WARN or postrow.U_INFO or postrow.U_QUOTE --> + <!-- IF $SHOW_POST_BUTTONS --> <ul class="post-buttons"> <!-- EVENT viewtopic_body_post_buttons_before --> <!-- IF postrow.U_EDIT --> @@ -377,6 +383,8 @@ </div> </div> <!-- ENDIF --> + + <!-- EVENT viewtopic_dropdown_bottom_custom --> <!-- IF .pagination or TOTAL_POSTS --> <div class="pagination"> diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 702960f47c..19b0f65a2d 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -43,6 +43,9 @@ table { border-collapse: collapse; border-spacing: 0; } +abbr { + text-decoration: none; +} /* General Markup Styles ---------------------------------------- */ diff --git a/tests/avatar/manager_test.php b/tests/avatar/manager_test.php index 71f40c0b13..6d77f2ed3a 100644 --- a/tests/avatar/manager_test.php +++ b/tests/avatar/manager_test.php @@ -59,6 +59,8 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case $guesser = new \phpbb\mimetype\guesser($guessers); $imagesize = new \fastImageSize\fastImageSize(); + $dispatcher = new phpbb_mock_event_dispatcher(); + // $this->avatar_foobar will be needed later on $this->avatar_foobar = $this->getMock('\phpbb\avatar\driver\foobar', array('get_name'), array($this->config, $imagesize, $phpbb_root_path, $phpEx, $path_helper, $cache)); $this->avatar_foobar->expects($this->any()) @@ -79,7 +81,7 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case } else { - $cur_avatar = $this->getMock('\phpbb\avatar\driver\\' . $driver, array('get_name'), array($this->config, $phpbb_root_path, $phpEx, $filesystem, $path_helper, $guesser, $cache)); + $cur_avatar = $this->getMock('\phpbb\avatar\driver\\' . $driver, array('get_name'), array($this->config, $phpbb_root_path, $phpEx, $filesystem, $path_helper, $guesser, $dispatcher, $cache)); } $cur_avatar->expects($this->any()) ->method('get_name') diff --git a/tests/console/fixtures/png.png b/tests/console/fixtures/png.png Binary files differnew file mode 100644 index 0000000000..c143a26a06 --- /dev/null +++ b/tests/console/fixtures/png.png diff --git a/tests/console/fixtures/thumbnail.xml b/tests/console/fixtures/thumbnail.xml new file mode 100644 index 0000000000..8037523633 --- /dev/null +++ b/tests/console/fixtures/thumbnail.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_attachments"> + <column>attach_id</column> + <column>physical_filename</column> + <column>real_filename</column> + <column>thumbnail</column> + <column>extension</column> + <column>mimetype</column> + <column>attach_comment</column> + + <row> + <value>1</value> + <value>test_png_1</value> + <value>real_test.png</value> + <value>0</value> + <value>png</value> + <value>image/png</value> + <value></value> + </row> + <row> + <value>2</value> + <value>test_png_2</value> + <value>real_test.png</value> + <value>1</value> + <value>png</value> + <value>image/png</value> + <value></value> + </row> + <row> + <value>10</value> + <value>test_txt</value> + <value>real_test.txt</value> + <value>0</value> + <value>txt</value> + <value>text/plain</value> + <value></value> + </row> + </table> +</dataset> diff --git a/tests/console/fixtures/txt.txt b/tests/console/fixtures/txt.txt new file mode 100644 index 0000000000..a78c858f5c --- /dev/null +++ b/tests/console/fixtures/txt.txt @@ -0,0 +1,2 @@ +<HTML>mime trigger</HTML> +The HTML tags should remain uppercase so that case-insensitivity can be checked. diff --git a/tests/console/thumbnail_test.php b/tests/console/thumbnail_test.php new file mode 100644 index 0000000000..b5ed02b5e7 --- /dev/null +++ b/tests/console/thumbnail_test.php @@ -0,0 +1,120 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_compatibility.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Tester\CommandTester; +use phpbb\console\command\thumbnail\generate; +use phpbb\console\command\thumbnail\delete; +use phpbb\console\command\thumbnail\recreate; + +class phpbb_console_command_thumbnail_test extends phpbb_database_test_case +{ + protected $db; + protected $config; + protected $cache; + protected $user; + protected $phpEx; + protected $phpbb_root_path; + protected $application; + + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/thumbnail.xml'); + } + + public function setUp() + { + global $config, $phpbb_root_path, $phpEx, $phpbb_filesystem; + + parent::setUp(); + + $config = $this->config = new \phpbb\config\config(array( + 'img_min_thumb_filesize' => 2, + 'img_max_thumb_width' => 2, + 'img_imagick' => '', + )); + + $this->db = $this->db = $this->new_dbal(); + $this->user = $this->getMock('\phpbb\user', array(), array( + new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), + '\phpbb\datetime') + ); + $this->phpbb_root_path = $phpbb_root_path; + $this->phpEx = $phpEx; + + $this->cache = $this->getMock('\phpbb\cache\service', array(), array(new phpbb_mock_cache(), $this->config, $this->db, $this->phpbb_root_path, $this->phpEx)); + $this->cache->expects(self::any())->method('obtain_attach_extensions')->will(self::returnValue(array( + 'png' => array('display_cat' => ATTACHMENT_CATEGORY_IMAGE), + 'txt' => array('display_cat' => ATTACHMENT_CATEGORY_NONE), + ))); + + $this->application = new Application(); + $this->application->add(new generate($this->user, $this->db, $this->cache, $this->phpbb_root_path, $this->phpEx)); + $this->application->add(new delete($this->user, $this->db, $this->phpbb_root_path)); + $this->application->add(new recreate($this->user)); + + $phpbb_filesystem = new \phpbb\filesystem\filesystem(); + + copy(dirname(__FILE__) . '/fixtures/png.png', $this->phpbb_root_path . 'files/test_png_1'); + copy(dirname(__FILE__) . '/fixtures/png.png', $this->phpbb_root_path . 'files/test_png_2'); + copy(dirname(__FILE__) . '/fixtures/png.png', $this->phpbb_root_path . 'files/thumb_test_png_2'); + copy(dirname(__FILE__) . '/fixtures/txt.txt', $this->phpbb_root_path . 'files/test_txt'); + } + + protected function tearDown() + { + parent::tearDown(); + + unlink($this->phpbb_root_path . 'files/test_png_1'); + unlink($this->phpbb_root_path . 'files/test_png_2'); + unlink($this->phpbb_root_path . 'files/test_txt'); + unlink($this->phpbb_root_path . 'files/thumb_test_png_1'); + unlink($this->phpbb_root_path . 'files/thumb_test_png_2'); + } + + public function test_thumbnails() + { + $command_tester = $this->get_command_tester('thumbnail:generate'); + $exit_status = $command_tester->execute(array('command' => 'thumbnail:generate')); + + self::assertSame(true, file_exists($this->phpbb_root_path . 'files/thumb_test_png_1')); + self::assertSame(true, file_exists($this->phpbb_root_path . 'files/thumb_test_png_2')); + self::assertSame(false, file_exists($this->phpbb_root_path . 'files/thumb_test_txt')); + self::assertSame(0, $exit_status); + + $command_tester = $this->get_command_tester('thumbnail:delete'); + $exit_status = $command_tester->execute(array('command' => 'thumbnail:delete')); + + self::assertSame(false, file_exists($this->phpbb_root_path . 'files/thumb_test_png_1')); + self::assertSame(false, file_exists($this->phpbb_root_path . 'files/thumb_test_png_2')); + self::assertSame(false, file_exists($this->phpbb_root_path . 'files/thumb_test_txt')); + self::assertSame(0, $exit_status); + + $command_tester = $this->get_command_tester('thumbnail:recreate'); + $exit_status = $command_tester->execute(array('command' => 'thumbnail:recreate')); + + self::assertSame(true, file_exists($this->phpbb_root_path . 'files/thumb_test_png_1')); + self::assertSame(true, file_exists($this->phpbb_root_path . 'files/thumb_test_png_2')); + self::assertSame(false, file_exists($this->phpbb_root_path . 'files/thumb_test_txt')); + self::assertSame(0, $exit_status); + } + + public function get_command_tester($command_name) + { + $command = $this->application->find($command_name); + return new CommandTester($command); + } +} diff --git a/tests/datetime/from_format_test.php b/tests/datetime/from_format_test.php index 7ecb546768..32b88ff588 100644 --- a/tests/datetime/from_format_test.php +++ b/tests/datetime/from_format_test.php @@ -113,6 +113,10 @@ class phpbb_datetime_from_format_test extends phpbb_test_case { global $phpbb_root_path, $phpEx; + // This magically fixes the segmentation fault error on PHP7 tests + // while date_default_timezone_set('UTC') does not + date_default_timezone_set('Europe/Paris'); + $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); $lang = new \phpbb\language\language($lang_loader); $user = new \phpbb\user($lang, '\phpbb\datetime'); |