aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB')
-rw-r--r--phpBB/adm/style/acp_attachments.html22
-rw-r--r--phpBB/adm/style/acp_database.html2
-rw-r--r--phpBB/adm/style/acp_users_prefs.html2
-rw-r--r--phpBB/composer.lock285
-rw-r--r--phpBB/config/default/container/services.yml6
-rw-r--r--phpBB/config/default/container/services_console.yml2
-rw-r--r--phpBB/config/default/container/services_content.yml1
-rw-r--r--phpBB/docs/CHANGELOG.html97
-rw-r--r--phpBB/docs/INSTALL.html2
-rw-r--r--phpBB/docs/events.md585
-rw-r--r--phpBB/includes/acp/acp_attachments.php20
-rw-r--r--phpBB/includes/acp/acp_board.php10
-rw-r--r--phpBB/includes/acp/acp_database.php206
-rw-r--r--phpBB/includes/acp/acp_forums.php7
-rw-r--r--phpBB/includes/acp/acp_groups.php17
-rw-r--r--phpBB/includes/acp/acp_update.php16
-rw-r--r--phpBB/includes/acp/acp_users.php2
-rw-r--r--phpBB/includes/compatibility_globals.php5
-rw-r--r--phpBB/includes/constants.php2
-rw-r--r--phpBB/includes/functions.php159
-rw-r--r--phpBB/includes/functions_acp.php12
-rw-r--r--phpBB/includes/functions_admin.php4
-rw-r--r--phpBB/includes/functions_content.php3
-rw-r--r--phpBB/includes/functions_download.php4
-rw-r--r--phpBB/includes/functions_messenger.php19
-rw-r--r--phpBB/includes/functions_posting.php33
-rw-r--r--phpBB/includes/functions_privmsgs.php25
-rw-r--r--phpBB/includes/functions_user.php73
-rw-r--r--phpBB/includes/mcp/mcp_ban.php7
-rw-r--r--phpBB/includes/mcp/mcp_front.php5
-rw-r--r--phpBB/includes/mcp/mcp_main.php90
-rw-r--r--phpBB/includes/mcp/mcp_topic.php6
-rw-r--r--phpBB/includes/message_parser.php20
-rw-r--r--phpBB/includes/ucp/ucp_attachments.php30
-rw-r--r--phpBB/includes/ucp/ucp_groups.php26
-rw-r--r--phpBB/includes/ucp/ucp_main.php10
-rw-r--r--phpBB/includes/ucp/ucp_pm.php31
-rw-r--r--phpBB/includes/ucp/ucp_pm_compose.php27
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewfolder.php6
-rw-r--r--phpBB/includes/ucp/ucp_profile.php14
-rw-r--r--phpBB/index.php14
-rw-r--r--phpBB/install/app.php4
-rw-r--r--phpBB/install/convertors/convert_phpbb20.php2
-rwxr-xr-xphpBB/install/phpbbcli.php2
-rw-r--r--phpBB/install/schemas/schema_data.sql6
-rw-r--r--phpBB/language/en/acp/board.php10
-rw-r--r--phpBB/language/en/acp/common.php1
-rw-r--r--phpBB/language/en/acp/database.php13
-rw-r--r--phpBB/language/en/acp/forums.php1
-rw-r--r--phpBB/language/en/acp/groups.php1
-rw-r--r--phpBB/language/en/acp/permissions_phpbb.php4
-rw-r--r--phpBB/language/en/common.php4
-rw-r--r--phpBB/language/en/email/admin_activate.txt2
-rw-r--r--phpBB/language/en/email/report_pm.txt2
-rw-r--r--phpBB/language/en/posting.php1
-rw-r--r--phpBB/language/en/ucp.php5
-rw-r--r--phpBB/memberlist.php184
-rw-r--r--phpBB/phpbb/auth/provider/oauth/oauth.php56
-rw-r--r--phpBB/phpbb/auth/provider/provider_interface.php7
-rw-r--r--phpBB/phpbb/avatar/driver/upload.php3
-rw-r--r--phpBB/phpbb/avatar/manager.php2
-rw-r--r--phpBB/phpbb/captcha/plugins/qa.php2
-rw-r--r--phpBB/phpbb/console/command/thumbnail/delete.php11
-rw-r--r--phpBB/phpbb/console/command/thumbnail/generate.php13
-rw-r--r--phpBB/phpbb/db/migration/data/v32x/disable_remote_avatar.php34
-rw-r--r--phpBB/phpbb/db/migration/data/v32x/smtp_dynamic_data.php42
-rw-r--r--phpBB/phpbb/db/migration/data/v32x/timezone_p3.php29
-rw-r--r--phpBB/phpbb/db/migration/data/v32x/v326.php39
-rw-r--r--phpBB/phpbb/db/migration/data/v32x/v326rc1.php37
-rw-r--r--phpBB/phpbb/db/migration/data/v32x/v327.php37
-rw-r--r--phpBB/phpbb/db/migration/data/v32x/v327rc1.php36
-rw-r--r--phpBB/phpbb/db/tools/tools.php2
-rw-r--r--phpBB/phpbb/event/md_exporter.php21
-rw-r--r--phpBB/phpbb/group/helper.php260
-rw-r--r--phpBB/phpbb/install/helper/config.php2
-rw-r--r--phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php8
-rw-r--r--phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php6
-rw-r--r--phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php4
-rw-r--r--phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php8
-rw-r--r--phpBB/phpbb/message/admin_form.php30
-rw-r--r--phpBB/phpbb/notification/type/report_pm.php13
-rw-r--r--phpBB/phpbb/pagination.php8
-rw-r--r--phpBB/phpbb/search/fulltext_mysql.php14
-rw-r--r--phpBB/phpbb/search/fulltext_native.php38
-rw-r--r--phpBB/phpbb/session.php7
-rw-r--r--phpBB/phpbb/textformatter/s9e/link_helper.php6
-rw-r--r--phpBB/posting.php47
-rw-r--r--phpBB/styles/prosilver/style.cfg4
-rw-r--r--phpBB/styles/prosilver/template/forumlist_body.html6
-rw-r--r--phpBB/styles/prosilver/template/index_body.html1
-rw-r--r--phpBB/styles/prosilver/template/login_body.html1
-rw-r--r--phpBB/styles/prosilver/template/login_body_oauth.html10
-rw-r--r--phpBB/styles/prosilver/template/login_forum.html1
-rw-r--r--phpBB/styles/prosilver/template/mcp_ban.html6
-rw-r--r--phpBB/styles/prosilver/template/memberlist_body.html15
-rw-r--r--phpBB/styles/prosilver/template/navbar_header.html7
-rw-r--r--phpBB/styles/prosilver/template/posting_attach_body.html12
-rw-r--r--phpBB/styles/prosilver/template/posting_review.html2
-rw-r--r--phpBB/styles/prosilver/template/posting_topic_review.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_agreement.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_attachments.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_auth_link_oauth.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_pm_history.html3
-rw-r--r--phpBB/styles/prosilver/template/ucp_profile_signature.html1
-rw-r--r--phpBB/styles/prosilver/template/viewforum_body.html3
-rw-r--r--phpBB/styles/prosilver/theme/cp.css3
-rw-r--r--phpBB/styles/prosilver/theme/plupload.css4
-rw-r--r--phpBB/viewforum.php3
108 files changed, 2282 insertions, 779 deletions
diff --git a/phpBB/adm/style/acp_attachments.html b/phpBB/adm/style/acp_attachments.html
index 868e256ef5..6129d6a1a5 100644
--- a/phpBB/adm/style/acp_attachments.html
+++ b/phpBB/adm/style/acp_attachments.html
@@ -421,17 +421,25 @@
</tr>
</thead>
<tbody>
- <!-- BEGIN attachments -->
+ {% for attachments in attachments %}
<tr>
<td>
- <!-- IF attachments.S_IN_MESSAGE -->{L_EXTENSION_GROUP}{L_COLON} <strong><!-- IF attachments.EXT_GROUP_NAME -->{attachments.EXT_GROUP_NAME}<!-- ELSE -->{L_NO_EXT_GROUP}<!-- ENDIF --></strong><br />{attachments.L_DOWNLOAD_COUNT}<br />{L_IN} {L_PRIVATE_MESSAGE}
- <!-- ELSE --><a href="{attachments.U_FILE}" style="font-weight: bold;">{attachments.REAL_FILENAME}</a><br /><!-- IF attachments.COMMENT -->{attachments.COMMENT}<br /><!-- ENDIF -->{attachments.L_DOWNLOAD_COUNT}<br />{L_TOPIC}{L_COLON} <a href="{attachments.U_VIEW_TOPIC}">{attachments.TOPIC_TITLE}</a><!-- ENDIF -->
+ {{ lang('EXTENSION_GROUP') ~ lang('COLON') }} <strong>{{ attachments.EXT_GROUP_NAME }}</strong>
+ {% if attachments.S_IN_MESSAGE %}
+ <br>{{ attachments.L_DOWNLOAD_COUNT }}
+ <br>{{ lang('IN') }} {{ lang('PRIVATE_MESSAGE') }}
+ {% else %}
+ <br><a href="{{ attachments.U_FILE }}"><strong>{{ attachments.REAL_FILENAME }}</strong></a>
+ {% if attachments.COMMENT %}<br>{{ attachments.COMMENT }}{% endif %}
+ <br>{{ attachments.L_DOWNLOAD_COUNT }}
+ <br>{{ lang('TOPIC') ~ lang('COLON') }} <a href="{{ attachments.U_VIEW_TOPIC }}">{{ attachments.TOPIC_TITLE }}</a>
+ {% endif %}
</td>
- <td>{attachments.FILETIME}<br />{L_POST_BY_AUTHOR} {attachments.ATTACHMENT_POSTER}</td>
- <td class="centered-text">{attachments.FILESIZE}</td>
- <td class="centered-text"><input type="checkbox" class="radio" name="delete[{attachments.ATTACH_ID}]" /></td>
+ <td>{{ attachments.FILETIME }}<br>{{ lang('POST_BY_AUTHOR') }} {{ attachments.ATTACHMENT_POSTER }}</td>
+ <td class="centered-text">{{ attachments.FILESIZE }}</td>
+ <td class="centered-text"><input type="checkbox" class="radio" name="delete[{{ attachments.ATTACH_ID }}]" /></td>
</tr>
- <!-- END attachments -->
+ {% endfor %}
</tbody>
</table>
<!-- ELSE -->
diff --git a/phpBB/adm/style/acp_database.html b/phpBB/adm/style/acp_database.html
index 39f06319f9..ed0f4dd453 100644
--- a/phpBB/adm/style/acp_database.html
+++ b/phpBB/adm/style/acp_database.html
@@ -20,7 +20,6 @@
<p class="submit-buttons">
<input class="button1" type="submit" id="submit" name="submit" value="{L_START_RESTORE}" />&nbsp;
<input class="button2" type="submit" id="delete" name="delete" value="{L_DELETE_BACKUP}" />&nbsp;
- <input class="button2" type="submit" id="download" name="download" value="{L_DOWNLOAD_BACKUP}" />
</p>
{S_FORM_TOKEN}
</fieldset>
@@ -72,7 +71,6 @@
<dt><label for="where">{L_ACTION}{L_COLON}</label></dt>
<dd>
<label><input id="where" type="radio" class="radio" name="where" value="store" checked="checked" /> {L_STORE_LOCAL}</label>
- <label><input type="radio" class="radio" name="where" value="download" /> {L_DOWNLOAD}</label>
</dd>
</dl>
<dl>
diff --git a/phpBB/adm/style/acp_users_prefs.html b/phpBB/adm/style/acp_users_prefs.html
index 61904adc23..484c5b3976 100644
--- a/phpBB/adm/style/acp_users_prefs.html
+++ b/phpBB/adm/style/acp_users_prefs.html
@@ -33,7 +33,7 @@
<dt><label for="notifymethod">{L_NOTIFY_METHOD}{L_COLON}</label><br /><span>{L_NOTIFY_METHOD_EXPLAIN}</span></dt>
<dd><label><input type="radio" class="radio" name="notifymethod" value="0"<!-- IF NOTIFY_EMAIL --> id="notifymethod" checked="checked"<!-- ENDIF --> /> {L_NOTIFY_METHOD_EMAIL}</label>
<label><input type="radio" class="radio" name="notifymethod" value="1"<!-- IF NOTIFY_IM --> id="notifymethod" checked="checked"<!-- ENDIF --><!-- IF S_JABBER_DISABLED --> disabled="disabled"<!-- ENDIF --> /> {L_NOTIFY_METHOD_IM}</label>
- <label><input type="radio" class="radio" name="notifymethod" value="2"<!-- IF NOTIFY_BOTH --> id="notifymethod" checked="checked"<!-- ENDIF --> /> {L_NOTIFY_METHOD_BOTH}</label></dd>
+ <label><input type="radio" class="radio" name="notifymethod" value="2"<!-- IF NOTIFY_BOTH --> id="notifymethod" checked="checked"<!-- ENDIF --><!-- IF S_JABBER_DISABLED --> disabled="disabled"<!-- ENDIF --> /> {L_NOTIFY_METHOD_BOTH}</label></dd>
</dl>
<dl>
<dt><label for="notifypm">{L_NOTIFY_ON_PM}{L_COLON}</label></dt>
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index a80bac724e..7d4f355e64 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -342,7 +342,7 @@
"oauth",
"security"
],
- "time": "2016-07-12T22:15:00+00:00"
+ "time": "2018-02-14T22:37:14+00:00"
},
{
"name": "marc1706/fast-image-size",
@@ -505,7 +505,7 @@
"pseudorandom",
"random"
],
- "time": "2017-03-13T16:22:52+00:00"
+ "time": "2018-04-04T21:48:54+00:00"
},
{
"name": "patchwork/utf8",
@@ -568,16 +568,16 @@
},
{
"name": "psr/log",
- "version": "1.0.2",
+ "version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
"shasum": ""
},
"require": {
@@ -611,20 +611,20 @@
"psr",
"psr-3"
],
- "time": "2016-10-10T12:19:37+00:00"
+ "time": "2018-11-20T15:27:04+00:00"
},
{
"name": "react/promise",
- "version": "v2.7.0",
+ "version": "v2.7.1",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
- "reference": "f4edc2581617431aea50430749db55cc3fc031b3"
+ "reference": "31ffa96f8d2ed0341a57848cbb84d88b89dd664d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/reactphp/promise/zipball/f4edc2581617431aea50430749db55cc3fc031b3",
- "reference": "f4edc2581617431aea50430749db55cc3fc031b3",
+ "url": "https://api.github.com/repos/reactphp/promise/zipball/31ffa96f8d2ed0341a57848cbb84d88b89dd664d",
+ "reference": "31ffa96f8d2ed0341a57848cbb84d88b89dd664d",
"shasum": ""
},
"require": {
@@ -657,20 +657,20 @@
"promise",
"promises"
],
- "time": "2018-06-13T15:59:06+00:00"
+ "time": "2019-01-07T21:25:54+00:00"
},
{
"name": "s9e/text-formatter",
- "version": "1.3.2",
+ "version": "1.4.5",
"source": {
"type": "git",
"url": "https://github.com/s9e/TextFormatter.git",
- "reference": "640b65b0d4c1de93bc98000c003998c08b2e7256"
+ "reference": "6857c53658929b66dc0d92daece17f211c64ea61"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/640b65b0d4c1de93bc98000c003998c08b2e7256",
- "reference": "640b65b0d4c1de93bc98000c003998c08b2e7256",
+ "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/6857c53658929b66dc0d92daece17f211c64ea61",
+ "reference": "6857c53658929b66dc0d92daece17f211c64ea61",
"shasum": ""
},
"require": {
@@ -682,6 +682,7 @@
"require-dev": {
"matthiasmullie/minify": "*",
"php-coveralls/php-coveralls": "*",
+ "phpunit/phpunit": "<6",
"s9e/regexp-builder": "1.*"
},
"suggest": {
@@ -722,20 +723,20 @@
"parser",
"shortcodes"
],
- "time": "2018-12-23T20:27:39+00:00"
+ "time": "2019-06-04T15:47:55+00:00"
},
{
"name": "symfony/config",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "fb3469266daaa67a1e6d42fc78fa6cdc254689f6"
+ "reference": "7dd5f5040dc04c118d057fb5886563963eb70011"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/fb3469266daaa67a1e6d42fc78fa6cdc254689f6",
- "reference": "fb3469266daaa67a1e6d42fc78fa6cdc254689f6",
+ "url": "https://api.github.com/repos/symfony/config/zipball/7dd5f5040dc04c118d057fb5886563963eb70011",
+ "reference": "7dd5f5040dc04c118d057fb5886563963eb70011",
"shasum": ""
},
"require": {
@@ -779,20 +780,20 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
- "time": "2018-09-08T12:44:02+00:00"
+ "time": "2018-11-26T09:38:12+00:00"
},
{
"name": "symfony/console",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "aca0dcc0c75496e17e2aa0303bb9c8e6d79ed789"
+ "reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/aca0dcc0c75496e17e2aa0303bb9c8e6d79ed789",
- "reference": "aca0dcc0c75496e17e2aa0303bb9c8e6d79ed789",
+ "url": "https://api.github.com/repos/symfony/console/zipball/cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12",
+ "reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12",
"shasum": ""
},
"require": {
@@ -840,20 +841,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2018-09-30T03:33:07+00:00"
+ "time": "2018-11-20T15:55:20+00:00"
},
{
"name": "symfony/debug",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "4fd77efcd4a499bf76d4ff46d092c67f3fe9e347"
+ "reference": "74251c8d50dd3be7c4ce0c7b862497cdc641a5d0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/4fd77efcd4a499bf76d4ff46d092c67f3fe9e347",
- "reference": "4fd77efcd4a499bf76d4ff46d092c67f3fe9e347",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/74251c8d50dd3be7c4ce0c7b862497cdc641a5d0",
+ "reference": "74251c8d50dd3be7c4ce0c7b862497cdc641a5d0",
"shasum": ""
},
"require": {
@@ -897,20 +898,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2018-09-21T12:46:38+00:00"
+ "time": "2018-11-11T11:18:13+00:00"
},
{
"name": "symfony/dependency-injection",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
- "reference": "84219396d1a79d149a5a9d5f71afaf48dcfde7d0"
+ "reference": "a2f40df187f0053bc361bcea3b27ff2b85744d9f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/84219396d1a79d149a5a9d5f71afaf48dcfde7d0",
- "reference": "84219396d1a79d149a5a9d5f71afaf48dcfde7d0",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a2f40df187f0053bc361bcea3b27ff2b85744d9f",
+ "reference": "a2f40df187f0053bc361bcea3b27ff2b85744d9f",
"shasum": ""
},
"require": {
@@ -960,20 +961,20 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
- "time": "2018-09-08T12:44:02+00:00"
+ "time": "2018-11-11T11:18:13+00:00"
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "84ae343f39947aa084426ed1138bb96bf94d1f12"
+ "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/84ae343f39947aa084426ed1138bb96bf94d1f12",
- "reference": "84ae343f39947aa084426ed1138bb96bf94d1f12",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a77e974a5fecb4398833b0709210e3d5e334ffb0",
+ "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0",
"shasum": ""
},
"require": {
@@ -1020,20 +1021,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2018-07-26T09:03:18+00:00"
+ "time": "2018-11-21T14:20:20+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "91f194c5ec8d2ad5ce417a218ce3c46909e92f4d"
+ "reference": "7ae46872dad09dffb7fe1e93a0937097339d0080"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/91f194c5ec8d2ad5ce417a218ce3c46909e92f4d",
- "reference": "91f194c5ec8d2ad5ce417a218ce3c46909e92f4d",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/7ae46872dad09dffb7fe1e93a0937097339d0080",
+ "reference": "7ae46872dad09dffb7fe1e93a0937097339d0080",
"shasum": ""
},
"require": {
@@ -1070,20 +1071,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2018-09-24T08:04:37+00:00"
+ "time": "2018-11-11T11:18:13+00:00"
},
{
"name": "symfony/finder",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "5ebb438d1aabe9dba93099dd06e0500f97817a6e"
+ "reference": "1444eac52273e345d9b95129bf914639305a9ba4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/5ebb438d1aabe9dba93099dd06e0500f97817a6e",
- "reference": "5ebb438d1aabe9dba93099dd06e0500f97817a6e",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/1444eac52273e345d9b95129bf914639305a9ba4",
+ "reference": "1444eac52273e345d9b95129bf914639305a9ba4",
"shasum": ""
},
"require": {
@@ -1119,20 +1120,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2018-09-21T12:46:38+00:00"
+ "time": "2018-11-11T11:18:13+00:00"
},
{
"name": "symfony/http-foundation",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "9fcce5f0b6896a135d192cc9fd5394fd46f74eff"
+ "reference": "d0ab719bedc9fc6748a95b2dcb04137292a27b92"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9fcce5f0b6896a135d192cc9fd5394fd46f74eff",
- "reference": "9fcce5f0b6896a135d192cc9fd5394fd46f74eff",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d0ab719bedc9fc6748a95b2dcb04137292a27b92",
+ "reference": "d0ab719bedc9fc6748a95b2dcb04137292a27b92",
"shasum": ""
},
"require": {
@@ -1174,20 +1175,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "time": "2018-09-23T15:27:53+00:00"
+ "time": "2018-11-25T11:27:05+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "90411d2ad577b883f2fc9de06c86dd564d9ac676"
+ "reference": "3df0207d4c973eb9c91b38a608aef4654dc256fa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/90411d2ad577b883f2fc9de06c86dd564d9ac676",
- "reference": "90411d2ad577b883f2fc9de06c86dd564d9ac676",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3df0207d4c973eb9c91b38a608aef4654dc256fa",
+ "reference": "3df0207d4c973eb9c91b38a608aef4654dc256fa",
"shasum": ""
},
"require": {
@@ -1258,20 +1259,20 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
- "time": "2018-09-30T03:51:44+00:00"
+ "time": "2018-12-06T14:45:07+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.9.0",
+ "version": "v1.11.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
+ "reference": "82ebae02209c21113908c229e9883c419720738a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
- "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a",
+ "reference": "82ebae02209c21113908c229e9883c419720738a",
"shasum": ""
},
"require": {
@@ -1283,7 +1284,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.9-dev"
+ "dev-master": "1.11-dev"
}
},
"autoload": {
@@ -1305,7 +1306,7 @@
},
{
"name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
+ "email": "backendtea@gmail.com"
}
],
"description": "Symfony polyfill for ctype functions",
@@ -1316,20 +1317,20 @@
"polyfill",
"portable"
],
- "time": "2018-08-06T14:22:27+00:00"
+ "time": "2019-02-06T07:57:58+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.9.0",
+ "version": "v1.11.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8"
+ "reference": "fe5e94c604826c35a32fa832f35bd036b6799609"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8",
- "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fe5e94c604826c35a32fa832f35bd036b6799609",
+ "reference": "fe5e94c604826c35a32fa832f35bd036b6799609",
"shasum": ""
},
"require": {
@@ -1341,7 +1342,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.9-dev"
+ "dev-master": "1.11-dev"
}
},
"autoload": {
@@ -1375,20 +1376,20 @@
"portable",
"shim"
],
- "time": "2018-08-06T14:22:27+00:00"
+ "time": "2019-02-06T07:57:58+00:00"
},
{
"name": "symfony/polyfill-php54",
- "version": "v1.9.0",
+ "version": "v1.11.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php54.git",
- "reference": "412977e090c6a8472dc39d50d1beb7d59495a965"
+ "reference": "2964b17ddc32dba7bcba009d5501c84d3fba1452"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/412977e090c6a8472dc39d50d1beb7d59495a965",
- "reference": "412977e090c6a8472dc39d50d1beb7d59495a965",
+ "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/2964b17ddc32dba7bcba009d5501c84d3fba1452",
+ "reference": "2964b17ddc32dba7bcba009d5501c84d3fba1452",
"shasum": ""
},
"require": {
@@ -1397,7 +1398,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.9-dev"
+ "dev-master": "1.11-dev"
}
},
"autoload": {
@@ -1433,20 +1434,20 @@
"portable",
"shim"
],
- "time": "2018-08-06T14:22:27+00:00"
+ "time": "2019-02-06T07:57:58+00:00"
},
{
"name": "symfony/polyfill-php55",
- "version": "v1.9.0",
+ "version": "v1.11.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php55.git",
- "reference": "578b8528da843de0fc65ec395900fa3181f2ead7"
+ "reference": "96fa25cef405ea452919559a0025d5dc16e30e4c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/578b8528da843de0fc65ec395900fa3181f2ead7",
- "reference": "578b8528da843de0fc65ec395900fa3181f2ead7",
+ "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/96fa25cef405ea452919559a0025d5dc16e30e4c",
+ "reference": "96fa25cef405ea452919559a0025d5dc16e30e4c",
"shasum": ""
},
"require": {
@@ -1456,7 +1457,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.9-dev"
+ "dev-master": "1.11-dev"
}
},
"autoload": {
@@ -1489,20 +1490,20 @@
"portable",
"shim"
],
- "time": "2018-08-06T14:22:27+00:00"
+ "time": "2019-02-06T07:57:58+00:00"
},
{
"name": "symfony/proxy-manager-bridge",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/proxy-manager-bridge.git",
- "reference": "0fd7ab039e26a33c5e3d1e00642bc83412c0896a"
+ "reference": "9c5f8d58e9c8017affdbeaec86c89d558aee4ec8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/0fd7ab039e26a33c5e3d1e00642bc83412c0896a",
- "reference": "0fd7ab039e26a33c5e3d1e00642bc83412c0896a",
+ "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/9c5f8d58e9c8017affdbeaec86c89d558aee4ec8",
+ "reference": "9c5f8d58e9c8017affdbeaec86c89d558aee4ec8",
"shasum": ""
},
"require": {
@@ -1543,20 +1544,20 @@
],
"description": "Symfony ProxyManager Bridge",
"homepage": "https://symfony.com",
- "time": "2018-07-26T09:03:18+00:00"
+ "time": "2018-11-11T11:18:13+00:00"
},
{
"name": "symfony/routing",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "fed18962c40095adc36c2ad05bf0d957cc346f61"
+ "reference": "8b0df6869d1997baafff6a1541826eac5a03d067"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/fed18962c40095adc36c2ad05bf0d957cc346f61",
- "reference": "fed18962c40095adc36c2ad05bf0d957cc346f61",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/8b0df6869d1997baafff6a1541826eac5a03d067",
+ "reference": "8b0df6869d1997baafff6a1541826eac5a03d067",
"shasum": ""
},
"require": {
@@ -1617,20 +1618,20 @@
"uri",
"url"
],
- "time": "2018-09-08T12:44:02+00:00"
+ "time": "2018-11-20T15:55:20+00:00"
},
{
"name": "symfony/twig-bridge",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/twig-bridge.git",
- "reference": "69d2a5542ea37309292d10029ce52b32656523a0"
+ "reference": "ecc1e30d05fa99f25b504e2d6a8684555ae39f7c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/69d2a5542ea37309292d10029ce52b32656523a0",
- "reference": "69d2a5542ea37309292d10029ce52b32656523a0",
+ "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/ecc1e30d05fa99f25b504e2d6a8684555ae39f7c",
+ "reference": "ecc1e30d05fa99f25b504e2d6a8684555ae39f7c",
"shasum": ""
},
"require": {
@@ -1702,20 +1703,20 @@
],
"description": "Symfony Twig Bridge",
"homepage": "https://symfony.com",
- "time": "2018-08-29T13:11:53+00:00"
+ "time": "2018-11-11T11:18:13+00:00"
},
{
"name": "symfony/yaml",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "5baf0f821b14eee8ca415e6a0361a9fa140c002c"
+ "reference": "02c1859112aa779d9ab394ae4f3381911d84052b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/5baf0f821b14eee8ca415e6a0361a9fa140c002c",
- "reference": "5baf0f821b14eee8ca415e6a0361a9fa140c002c",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/02c1859112aa779d9ab394ae4f3381911d84052b",
+ "reference": "02c1859112aa779d9ab394ae4f3381911d84052b",
"shasum": ""
},
"require": {
@@ -1752,35 +1753,35 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2018-08-29T13:11:53+00:00"
+ "time": "2018-11-11T11:18:13+00:00"
},
{
"name": "twig/twig",
- "version": "v1.35.4",
+ "version": "v1.39.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "7e081e98378a1e78c29cc9eba4aefa5d78a05d2a"
+ "reference": "23e7b6f0cfa1d7ba3de69f30d8e05cf957412fec"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/7e081e98378a1e78c29cc9eba4aefa5d78a05d2a",
- "reference": "7e081e98378a1e78c29cc9eba4aefa5d78a05d2a",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/23e7b6f0cfa1d7ba3de69f30d8e05cf957412fec",
+ "reference": "23e7b6f0cfa1d7ba3de69f30d8e05cf957412fec",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
+ "php": ">=5.4.0",
"symfony/polyfill-ctype": "^1.8"
},
"require-dev": {
"psr/container": "^1.0",
"symfony/debug": "^2.7",
- "symfony/phpunit-bridge": "^3.3"
+ "symfony/phpunit-bridge": "^3.4.19|^4.1.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.35-dev"
+ "dev-master": "1.39-dev"
}
},
"autoload": {
@@ -1818,7 +1819,7 @@
"keywords": [
"templating"
],
- "time": "2018-07-13T07:12:17+00:00"
+ "time": "2019-04-16T17:12:57+00:00"
},
{
"name": "zendframework/zend-code",
@@ -2293,7 +2294,8 @@
"authors": [
{
"name": "Michiel Rook",
- "email": "mrook@php.net"
+ "email": "mrook@php.net",
+ "role": "Lead"
},
{
"name": "Phing Community",
@@ -2855,6 +2857,7 @@
"mock",
"xunit"
],
+ "abandoned": true,
"time": "2015-10-02T06:51:40+00:00"
},
{
@@ -3335,16 +3338,16 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "2.9.1",
+ "version": "2.9.2",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62"
+ "reference": "2acf168de78487db620ab4bc524135a13cfe6745"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dcbed1074f8244661eecddfc2a675430d8d33f62",
- "reference": "dcbed1074f8244661eecddfc2a675430d8d33f62",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745",
+ "reference": "2acf168de78487db620ab4bc524135a13cfe6745",
"shasum": ""
},
"require": {
@@ -3409,20 +3412,20 @@
"phpcs",
"standards"
],
- "time": "2017-05-22T02:43:20+00:00"
+ "time": "2018-11-07T22:31:41+00:00"
},
{
"name": "symfony/browser-kit",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
- "reference": "fe44362c97307e7935996cb09d320fcc22619656"
+ "reference": "b507697225f32a76a9d333d0766fb46353e9d00d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/browser-kit/zipball/fe44362c97307e7935996cb09d320fcc22619656",
- "reference": "fe44362c97307e7935996cb09d320fcc22619656",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/b507697225f32a76a9d333d0766fb46353e9d00d",
+ "reference": "b507697225f32a76a9d333d0766fb46353e9d00d",
"shasum": ""
},
"require": {
@@ -3466,20 +3469,20 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
- "time": "2018-07-26T09:03:18+00:00"
+ "time": "2018-11-26T06:55:10+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "4cca41ebe83cd5b4bd0c1a9f6bdfaec7103f97fb"
+ "reference": "7b1692e418d7ccac24c373528453bc90e42797de"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/4cca41ebe83cd5b4bd0c1a9f6bdfaec7103f97fb",
- "reference": "4cca41ebe83cd5b4bd0c1a9f6bdfaec7103f97fb",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/7b1692e418d7ccac24c373528453bc90e42797de",
+ "reference": "7b1692e418d7ccac24c373528453bc90e42797de",
"shasum": ""
},
"require": {
@@ -3519,20 +3522,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2018-09-08T12:44:02+00:00"
+ "time": "2018-11-11T11:18:13+00:00"
},
{
"name": "symfony/dom-crawler",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
- "reference": "ba0b706b5ac1c1afcf7d34507a5a272f51cc7721"
+ "reference": "2cdc7d3909eea6f982a6298d2e9ab7db01b6403c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/ba0b706b5ac1c1afcf7d34507a5a272f51cc7721",
- "reference": "ba0b706b5ac1c1afcf7d34507a5a272f51cc7721",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/2cdc7d3909eea6f982a6298d2e9ab7db01b6403c",
+ "reference": "2cdc7d3909eea6f982a6298d2e9ab7db01b6403c",
"shasum": ""
},
"require": {
@@ -3576,20 +3579,20 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
- "time": "2018-09-21T12:46:38+00:00"
+ "time": "2018-11-24T22:30:19+00:00"
},
{
"name": "symfony/process",
- "version": "v2.8.46",
+ "version": "v2.8.49",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "f09e21b7c5aba06c47bbfad9cbcf13ac7f0db0a6"
+ "reference": "c3591a09c78639822b0b290d44edb69bf9f05dc8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/f09e21b7c5aba06c47bbfad9cbcf13ac7f0db0a6",
- "reference": "f09e21b7c5aba06c47bbfad9cbcf13ac7f0db0a6",
+ "url": "https://api.github.com/repos/symfony/process/zipball/c3591a09c78639822b0b290d44edb69bf9f05dc8",
+ "reference": "c3591a09c78639822b0b290d44edb69bf9f05dc8",
"shasum": ""
},
"require": {
@@ -3625,7 +3628,7 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2018-09-06T17:11:15+00:00"
+ "time": "2018-11-11T11:18:13+00:00"
}
],
"aliases": [],
diff --git a/phpBB/config/default/container/services.yml b/phpBB/config/default/container/services.yml
index 9bb1d673f4..3ead1e6181 100644
--- a/phpBB/config/default/container/services.yml
+++ b/phpBB/config/default/container/services.yml
@@ -122,7 +122,13 @@ services:
group_helper:
class: phpbb\group\helper
arguments:
+ - '@auth'
+ - '@cache'
+ - '@config'
- '@language'
+ - '@dispatcher'
+ - '@path_helper'
+ - '@user'
log:
class: phpbb\log\log
diff --git a/phpBB/config/default/container/services_console.yml b/phpBB/config/default/container/services_console.yml
index a327b74ac4..05e467ff8d 100644
--- a/phpBB/config/default/container/services_console.yml
+++ b/phpBB/config/default/container/services_console.yml
@@ -208,6 +208,7 @@ services:
console.command.thumbnail.delete:
class: phpbb\console\command\thumbnail\delete
arguments:
+ - '@config'
- '@user'
- '@dbal.conn'
- '%core.root_path%'
@@ -217,6 +218,7 @@ services:
console.command.thumbnail.generate:
class: phpbb\console\command\thumbnail\generate
arguments:
+ - '@config'
- '@user'
- '@dbal.conn'
- '@cache'
diff --git a/phpBB/config/default/container/services_content.yml b/phpBB/config/default/container/services_content.yml
index 602fd25f4e..6717c20337 100644
--- a/phpBB/config/default/container/services_content.yml
+++ b/phpBB/config/default/container/services_content.yml
@@ -35,6 +35,7 @@ services:
- '@config_text'
- '@dbal.conn'
- '@user'
+ - '@dispatcher'
- '%core.root_path%'
- '%core.php_ext%'
diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html
index 09a3b8dff5..b21c0ca38f 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -50,6 +50,9 @@
<ol>
<li><a href="#changelog">Changelog</a>
<ul>
+ <li><a href="#v326">Changes since 3.2.6</a></li>
+ <li><a href="#v326rc1">Changes since 3.2.6-RC1</a></li>
+ <li><a href="#v325">Changes since 3.2.5</a></li>
<li><a href="#v325rc1">Changes since 3.2.5-RC1</a></li>
<li><a href="#v324">Changes since 3.2.4</a></li>
<li><a href="#v324rc1">Changes since 3.2.4-RC1</a></li>
@@ -135,6 +138,100 @@
<div class="inner">
<div class="content">
+ <a name="v326"></a><h3>Changes since 3.2.6</h3>
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16034">PHPBB3-16034</a>] - Links created with [url=] - are sometimes incorrectly shortened</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16036">PHPBB3-16036</a>] - Cannot login with 3.2.6</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16037">PHPBB3-16037</a>] - Private message ViewFolder Broken</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16039">PHPBB3-16039</a>] - Unable to change announcement to standard topic due to missing global</li>
+ </ul>
+ <h4>Improvement</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16042">PHPBB3-16042</a>] - Use S_LOGIN_REDIRECT to output login form token</li>
+ </ul>
+
+ <a name="v326rc1"></a><h3>Changes since 3.2.6-RC1</h3>
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16027">PHPBB3-16027</a>] - Appveyor builds fail on PHP 7.0</li>
+ </ul>
+ <h4>Security Issue</h4>
+ <ul>
+ <li>[SECURITY-231] - Remote avatar functionality allows checking for files and ports on local network</li>
+ <li>[SECURITY-235] - Fulltext native search can be used to cause long execution times</li>
+ </ul>
+ <h4>Hardening</h4>
+ <ul>
+ <li>[SECURITY-228] - Require form token in login_box</li>
+ <li>[SECURITY-233] - SMTP auth data shouldn't be cached</li>
+ <li>[SECURITY-234] - Main website URL in Admin Control Panel should not support JS URLs</li>
+ </ul>
+
+ <a name="v325"></a><h3>Changes since 3.2.5</h3>
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15509">PHPBB3-15509</a>] - Update database: info message is to scary</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15869">PHPBB3-15869</a>] - Cookies Problem with domains with special chars</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15876">PHPBB3-15876</a>] - Mysql 5.7 support Q&amp;A plugin</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15883">PHPBB3-15883</a>] - No error for invalid usernames on bulk add to usergroup</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15904">PHPBB3-15904</a>] - PHP warning when accessing modules in ACP System tab</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15917">PHPBB3-15917</a>] - Unapproved posts count towards forum post count</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15918">PHPBB3-15918</a>] - Ban reason messages show backslash (\) before apostrophe -- ex. (don\'t).</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15919">PHPBB3-15919</a>] - Lint test throws PHP warnings due to node modules folder</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15931">PHPBB3-15931</a>] - Issues in PM report emails</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15954">PHPBB3-15954</a>] - Some calls to include() don't have a safeguard</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15957">PHPBB3-15957</a>] - User preferences show notification method &quot;both&quot; with disabled Jabber in ACP</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15959">PHPBB3-15959</a>] - Travis Network Test is Failing for news.cnet.com</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15965">PHPBB3-15965</a>] - Console command to handle thumbnails have files directory hardcoded</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15975">PHPBB3-15975</a>] - Delete or prune an user doesn't remove its entries in the user_notifications table</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15986">PHPBB3-15986</a>] - Add missing language key for posting.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15996">PHPBB3-15996</a>] - Invalid data provider function name in migrator_tool_permission_test</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16006">PHPBB3-16006</a>] - Duplicate form IDs in UCP oauth form</li>
+ </ul>
+ <h4>Improvement</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15884">PHPBB3-15884</a>] - Add memberlist_body_* events</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15889">PHPBB3-15889</a>] - Add core.memberlist_modify_memberrow_sql</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15890">PHPBB3-15890</a>] - Add core.memberlist_modify_viewprofile_sql</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15891">PHPBB3-15891</a>] - Add core.memberlist_modify_view_profile_template_vars</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15898">PHPBB3-15898</a>] - Add core.ucp_pm_compose_template</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15899">PHPBB3-15899</a>] - Add core.modify_attachment_sql_ary_on_* events</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15901">PHPBB3-15901</a>] - Add mcp_post_* template events</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15910">PHPBB3-15910</a>] - Pass object arguments by reference implicitly</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15914">PHPBB3-15914</a>] - Add core.modify_memberlist_viewprofile_group_sql and core.modify_memberlist_viewprofile_group_data</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15915">PHPBB3-15915</a>] - Add template events to posting_attach_body.html</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15924">PHPBB3-15924</a>] - Move from precise to trusty builds</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15926">PHPBB3-15926</a>] - Deny installs on PHP &gt;= 7.3@dev - Increase min. req. to 5.4.7</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15928">PHPBB3-15928</a>] - Remove support for backup download</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15939">PHPBB3-15939</a>] - Pagination docblocks</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15941">PHPBB3-15941</a>] - Replace MAX SQL in functions_posting.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15942">PHPBB3-15942</a>] - Array to string conversion when permanently deleting a post</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15948">PHPBB3-15948</a>] - Add core.mcp_change_topic_type_after/before</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15949">PHPBB3-15949</a>] - [Template] - ucp_profile_signature_posting_editor_options_prepend</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15950">PHPBB3-15950</a>] - Add SQL transactions to mcp_main.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15960">PHPBB3-15960</a>] - Add SQL transactions to functions_admin.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15970">PHPBB3-15970</a>] - Add core.message_admin_form_submit_before</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15972">PHPBB3-15972</a>] - Add core.markread_after</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15992">PHPBB3-15992</a>] - Fix breadcrumb schema</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15995">PHPBB3-15995</a>] - Add core.memberlist_modify_sort_pagination_params</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15997">PHPBB3-15997</a>] - Increase webdriver timeout for UI tests</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16001">PHPBB3-16001</a>] - Append data to the OAuth's redirect URL</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16009">PHPBB3-16009</a>] - Display OAuth login's buttons in a row.</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16010">PHPBB3-16010</a>] - Automatically check order of events in events.md file</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16018">PHPBB3-16018</a>] - Update composer and dependencies for 3.2.6</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16020">PHPBB3-16020</a>] - Fix placement of event viewforum_body_topic_author_username_append</li>
+ </ul>
+ <h4>New Feature</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15944">PHPBB3-15944</a>] - Add core.posting_modify_quote_attributes</li>
+ </ul>
+ <h4>Task</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15921">PHPBB3-15921</a>] - Update TextFormatter to 1.3.2</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15953">PHPBB3-15953</a>] - pm reported missing border color</li>
+ </ul>
+
<a name="v325rc1"></a><h3>Changes since 3.2.5-RC1</h3>
<h4>Bug</h4>
<ul>
diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html
index 853607886b..4f7f07d3dc 100644
--- a/phpBB/docs/INSTALL.html
+++ b/phpBB/docs/INSTALL.html
@@ -147,7 +147,7 @@
<li>Oracle</li>
</ul>
</li>
- <li><strong>PHP 5.4.7+</strong> with support for the database you intend to use.</li>
+ <li><strong>PHP 5.4.7+</strong> but less than <strong>PHP 7.3</strong> with support for the database you intend to use.</li>
<li>The following PHP modules are required:
<ul>
<li>json</li>
diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md
index 8b38d554a3..39888bf671 100644
--- a/phpBB/docs/events.md
+++ b/phpBB/docs/events.md
@@ -28,29 +28,29 @@ acp_bbcodes_edit_fieldsets_after
* Since: 3.1.0-a3
* Purpose: Add settings to BBCode add/edit form
-acp_email_group_options_append
+acp_email_find_username_append
===
* Location: adm/style/acp_email.html
* Since: 3.1.7-RC1
-* Purpose: Add content at the end of the group options select box
+* Purpose: Add content at the end of the find username link
-acp_email_group_options_prepend
+acp_email_find_username_prepend
===
* Location: adm/style/acp_email.html
* Since: 3.1.7-RC1
-* Purpose: Add content at the start of the group options select box
+* Purpose: Add content at the start of the find username link
-acp_email_find_username_append
+acp_email_group_options_append
===
* Location: adm/style/acp_email.html
* Since: 3.1.7-RC1
-* Purpose: Add content at the end of the fimd username link
+* Purpose: Add content at the end of the group options select box
-acp_email_find_username_prepend
+acp_email_group_options_prepend
===
* Location: adm/style/acp_email.html
* Since: 3.1.7-RC1
-* Purpose: Add content at the start of the fimd username link
+* Purpose: Add content at the start of the group options select box
acp_email_options_after
===
@@ -160,17 +160,17 @@ acp_forums_rules_settings_prepend
* Since: 3.1.2-RC1
* Purpose: Add settings to forums before rules settings section
-acp_group_options_before
+acp_group_options_after
===
* Location: adm/style/acp_groups.html
* Since: 3.1.0-b4
-* Purpose: Add addtional options to group settings (before GROUP_FOUNDER_MANAGE)
+* Purpose: Add additional options to group settings (after GROUP_RECEIVE_PM)
-acp_group_options_after
+acp_group_options_before
===
* Location: adm/style/acp_groups.html
* Since: 3.1.0-b4
-* Purpose: Add addtional options to group settings (after GROUP_RECEIVE_PM)
+* Purpose: Add additional options to group settings (before GROUP_FOUNDER_MANAGE)
acp_groups_find_username_append
===
@@ -281,29 +281,29 @@ acp_overall_header_stylesheets_after
* Purpose: Add assets after stylesheets within the `<head>` tags in the ACP.
Note that INCLUDECSS will not work with this event.
-acp_permission_forum_copy_src_forum_append
+acp_permission_forum_copy_dest_forum_append
===
* Location: adm/style/permission_forum_copy.html
* Since: 3.1.7-RC1
-* Purpose: Add content after the sourse forum select form
+* Purpose: Add content after the destination forum select form
-acp_permission_forum_copy_src_forum_prepend
+acp_permission_forum_copy_dest_forum_prepend
===
* Location: adm/style/permission_forum_copy.html
* Since: 3.1.7-RC1
-* Purpose: Add content before the sourse forum select form
+* Purpose: Add content before the destination forum select form
-acp_permission_forum_copy_dest_forum_append
+acp_permission_forum_copy_src_forum_append
===
* Location: adm/style/permission_forum_copy.html
* Since: 3.1.7-RC1
-* Purpose: Add content after the destiny forum select form
+* Purpose: Add content after the source forum select form
-acp_permission_forum_copy_dest_forum_prepend
+acp_permission_forum_copy_src_forum_prepend
===
* Location: adm/style/permission_forum_copy.html
* Since: 3.1.7-RC1
-* Purpose: Add content before the destiny forum select form
+* Purpose: Add content before the source forum select form
acp_permissions_add_group_options_append
===
@@ -498,41 +498,6 @@ acp_ranks_list_header_before
* Purpose: Add content after the last header-column (but before the action column)
in the ranks list in the ACP
-acp_styles_list_before
-===
-* Locations:
- + adm/style/acp_styles.html
-* Since: 3.1.7-RC1
-* Purpose: Add content before list of styles
-
-acp_users_mode_add
-===
-* Locations:
- + adm/style/acp_users.html
-* Since: 3.2.2-RC1
-* Purpose: Add extra modes to the ACP user page
-
-acp_users_profile_before
-===
-* Locations:
- + adm/style/acp_users_profile.html
-* Since: 3.1.4-RC1
-* Purpose: Add content before the profile details when editing a user in the ACP
-
-acp_users_profile_after
-===
-* Locations:
- + adm/style/acp_users_profile.html
-* Since: 3.1.4-RC1
-* Purpose: Add content after the profile details but before the custom profile fields when editing a user in the ACP
-
-acp_users_profile_custom_after
-===
-* Locations:
- + adm/style/acp_users_profile.html
-* Since: 3.1.4-RC1
-* Purpose: Add content after the the custom profile fields when editing a user in the ACP
-
acp_simple_footer_after
===
* Location: adm/style/simple_footer.html
@@ -558,6 +523,20 @@ acp_simple_header_stylesheets_after
* Purpose: Add assets after stylesheets within the `<head>` tags in the simple header
of the ACP. Note that INCLUDECSS will not work with this event.
+acp_styles_list_before
+===
+* Locations:
+ + adm/style/acp_styles.html
+* Since: 3.1.7-RC1
+* Purpose: Add content before list of styles
+
+acp_users_mode_add
+===
+* Locations:
+ + adm/style/acp_users.html
+* Since: 3.2.2-RC1
+* Purpose: Add extra modes to the ACP user page
+
acp_users_overview_options_append
===
* Location: adm/style/acp_users_overview.html
@@ -570,12 +549,6 @@ acp_users_prefs_append
* Since: 3.1.0-b3
* Purpose: Add user options fieldset to the bottom of ACP users prefs settings
-acp_users_prefs_prepend
-===
-* Location: adm/style/acp_users_prefs.html
-* Since: 3.1.0-b3
-* Purpose: Add user options fieldset to the top of ACP users prefs settings
-
acp_users_prefs_personal_append
===
* Location: adm/style/acp_users_prefs.html
@@ -600,6 +573,12 @@ acp_users_prefs_post_prepend
* Since: 3.1.0-b3
* Purpose: Add user options fieldset to the top of ACP users post prefs settings
+acp_users_prefs_prepend
+===
+* Location: adm/style/acp_users_prefs.html
+* Since: 3.1.0-b3
+* Purpose: Add user options fieldset to the top of ACP users prefs settings
+
acp_users_prefs_view_append
===
* Location: adm/style/acp_users_prefs.html
@@ -612,6 +591,27 @@ acp_users_prefs_view_prepend
* Since: 3.1.0-b3
* Purpose: Add user options fieldset to the top of ACP users view prefs settings
+acp_users_profile_after
+===
+* Locations:
+ + adm/style/acp_users_profile.html
+* Since: 3.1.4-RC1
+* Purpose: Add content after the profile details but before the custom profile fields when editing a user in the ACP
+
+acp_users_profile_before
+===
+* Locations:
+ + adm/style/acp_users_profile.html
+* Since: 3.1.4-RC1
+* Purpose: Add content before the profile details when editing a user in the ACP
+
+acp_users_profile_custom_after
+===
+* Locations:
+ + adm/style/acp_users_profile.html
+* Since: 3.1.4-RC1
+* Purpose: Add content after the the custom profile fields when editing a user in the ACP
+
acp_users_select_group_after
===
* Location: adm/style/acp_users.html
@@ -764,6 +764,13 @@ forumlist_body_last_poster_username_prepend
* Since: 3.2.4-RC1
* Purpose: Prepend information to last poster username of member
+forumlist_body_last_row_after
+===
+* Locations:
+ + styles/prosilver/template/forumlist_body.html
+* Since: 3.1.0-b2
+* Purpose: Add content after the very last row of the forum list.
+
forumlist_body_subforum_link_append
===
* Locations:
@@ -792,13 +799,6 @@ forumlist_body_subforums_before
* Since: 3.1.0-a4
* Purpose: Add content before the list of subforums (if any) for each forum on the forum list.
-forumlist_body_last_row_after
-===
-* Locations:
- + styles/prosilver/template/forumlist_body.html
-* Since: 3.1.0-b2
-* Purpose: Add content after the very last row of the forum list.
-
index_body_birthday_block_before
===
* Locations:
@@ -932,19 +932,19 @@ mcp_forum_actions_before
* Since: 3.1.11-RC1
* Purpose: Add some information before actions fieldset
-mcp_forum_topic_title_before
+mcp_forum_topic_title_after
===
* Locations:
+ styles/prosilver/template/mcp_forum.html
* Since: 3.1.6-RC1
-* Purpose: Add some information before the topic title
+* Purpose: Add some information after the topic title
-mcp_forum_topic_title_after
+mcp_forum_topic_title_before
===
* Locations:
+ styles/prosilver/template/mcp_forum.html
* Since: 3.1.6-RC1
-* Purpose: Add some information after the topic title
+* Purpose: Add some information before the topic title
mcp_front_latest_logs_after
===
@@ -1128,6 +1128,83 @@ mcp_warn_user_add_warning_field_before
* Since: 3.1.0-RC4
* Purpose: Add content during warning a user - before add warning field.
+memberlist_body_group_desc_after
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data after the group description and type in the group profile page.
+
+memberlist_body_group_name_after
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data after the group name in the group profile page.
+
+memberlist_body_group_name_before
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data before the group name in the group profile page.
+
+memberlist_body_group_rank_after
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data after the group rank in the group profile page.
+
+memberlist_body_group_rank_before
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data before the group rank in the group profile page.
+
+memberlist_body_leaders_set_after
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data after the last row in the memberlist mode leaders.
+
+memberlist_body_memberlist_after
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data after the last row in the memberlist.
+
+memberlist_body_memberrow_after
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data after the last memberrow in the memberlist.
+
+memberlist_body_page_footer_before
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data before the page footer.
+
+memberlist_body_page_header_after
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data after the page header.
+
+memberlist_body_page_title_before
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data before the page title.
+
memberlist_body_rank_append
===
* Locations:
@@ -1144,6 +1221,13 @@ memberlist_body_rank_prepend
* Purpose: Add information before rank in memberlist. Works in
all display modes (leader, group and normal memberlist).
+memberlist_body_show_group_after
+===
+* Locations:
+ + styles/prosilver/template/memberlist_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add data after the last row in the memberlist mode group.
+
memberlist_body_username_append
===
* Locations:
@@ -1609,19 +1693,61 @@ overall_header_stylesheets_after
* Purpose: Add asset calls after stylesheets within the `</head>` tag.
Note that INCLUDECSS will not work with this event.
+posting_attach_body_attach_row_after
+===
+* Locations:
+ + styles/prosilver/template/posting_attach_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add content after attachment row in the file list
+
+posting_attach_body_attach_row_append
+===
+* Locations:
+ + styles/prosilver/template/posting_attach_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add content appending the attachment row in the file list
+
+posting_attach_body_attach_row_before
+===
+* Locations:
+ + styles/prosilver/template/posting_attach_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add content before attachment row in the file list
+
posting_attach_body_attach_row_controls_append
===
* Locations:
+ styles/prosilver/template/posting_attach_body.html
* Since: 3.2.2-RC1
-* Purpose: Add content after attachment control elements
+* Purpose: Add content after attachment control elements
posting_attach_body_attach_row_controls_prepend
===
* Locations:
+ styles/prosilver/template/posting_attach_body.html
* Since: 3.2.2-RC1
-* Purpose: Add content before attachment control elements
+* Purpose: Add content before attachment control elements
+
+posting_attach_body_attach_row_prepend
+===
+* Locations:
+ + styles/prosilver/template/posting_attach_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add content prepending attachment row in the file list
+
+posting_attach_body_file_list_after
+===
+* Locations:
+ + styles/prosilver/template/posting_attach_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add content after attachments list
+
+posting_attach_body_file_list_before
+===
+* Locations:
+ + styles/prosilver/template/posting_attach_body.html
+* Since: 3.2.6-RC1
+* Purpose: Add content before attachments list
posting_editor_add_panel_tab
===
@@ -1784,6 +1910,20 @@ posting_preview_poll_after
* Since: 3.1.7-RC1
* Purpose: Add content after the poll preview block
+posting_review_row_post_author_username_append
+===
+* Locations:
+ + styles/prosilver/template/posting_review.html
+* Since: 3.2.8-RC1
+* Purpose: Append information to post author username of member
+
+posting_review_row_post_author_username_prepend
+===
+* Locations:
+ + styles/prosilver/template/posting_review.html
+* Since: 3.2.8-RC1
+* Purpose: Prepend information to post author username of member
+
posting_topic_review_row_content_after
===
* Locations:
@@ -1791,6 +1931,20 @@ posting_topic_review_row_content_after
* Since: 3.2.4-RC1
* Purpose: Add content after the message content in topic review
+posting_topic_review_row_post_author_username_append
+===
+* Locations:
+ + styles/prosilver/template/posting_topic_review.html
+* Since: 3.2.8-RC1
+* Purpose: Append information to post author username of member
+
+posting_topic_review_row_post_author_username_prepend
+===
+* Locations:
+ + styles/prosilver/template/posting_topic_review.html
+* Since: 3.2.8-RC1
+* Purpose: Prepend information to post author username of member
+
posting_topic_review_row_post_details_after
===
* Locations:
@@ -1819,33 +1973,33 @@ posting_topic_title_before
* 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
+quickreply_editor_message_after
===
* Locations:
+ styles/prosilver/template/quickreply_editor.html
-* Since: 3.1.0-b2
-* Purpose: Add content after the quick reply panel (but inside the form)
+* Since: 3.1.0-a4
+* Purpose: Add content after the quick reply textbox
-quickreply_editor_panel_before
+quickreply_editor_message_before
===
* Locations:
+ styles/prosilver/template/quickreply_editor.html
-* Since: 3.1.0-b2
-* Purpose: Add content before the quick reply panel (but inside the form)
+* Since: 3.1.0-a4
+* Purpose: Add content before the quick reply textbox
-quickreply_editor_message_after
+quickreply_editor_panel_after
===
* Locations:
+ styles/prosilver/template/quickreply_editor.html
-* Since: 3.1.0-a4
-* Purpose: Add content after the quick reply textbox
+* Since: 3.1.0-b2
+* Purpose: Add content after the quick reply panel (but inside the form)
-quickreply_editor_message_before
+quickreply_editor_panel_before
===
* Locations:
+ styles/prosilver/template/quickreply_editor.html
-* Since: 3.1.0-a4
-* Purpose: Add content before the quick reply textbox
+* Since: 3.1.0-b2
+* Purpose: Add content before the quick reply panel (but inside the form)
quickreply_editor_subject_before
===
@@ -1976,14 +2130,14 @@ search_results_header_before
search_results_last_post_author_username_append
===
* Locations:
- + styles/prosilver/template/search_results.html
+ + styles/prosilver/template/search_results.html (2)
* Since: 3.2.4-RC1
* Purpose: Append information to last post author username of member
search_results_last_post_author_username_prepend
===
* Locations:
- + styles/prosilver/template/search_results.html
+ + styles/prosilver/template/search_results.html (2)
* Since: 3.2.4-RC1
* Purpose: Prepend information to last post author username of member
@@ -2107,7 +2261,7 @@ simple_header_stylesheets_after
* Purpose: Add asset calls after stylesheets within the `</head>` tag.
Note that INCLUDECSS will not work with this event.
-topiclist_row_prepend
+topiclist_row_append
===
* Locations:
+ styles/prosilver/template/search_results.html
@@ -2117,7 +2271,7 @@ topiclist_row_prepend
* 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
+topiclist_row_prepend
===
* Locations:
+ styles/prosilver/template/search_results.html
@@ -2150,6 +2304,20 @@ ucp_agreement_terms_before
* Since: 3.1.0-b3
* Purpose: Add content before the terms of agreement text at user registration
+ucp_friend_list_after
+===
+* Locations:
+ + styles/prosilver/template/ucp_zebra_friends.html
+* Since: 3.1.0-a4
+* Purpose: Add optional elements after list of friends in UCP
+
+ucp_friend_list_before
+===
+* Locations:
+ + styles/prosilver/template/ucp_zebra_friends.html
+* Since: 3.1.0-a4
+* Purpose: Add optional elements before list of friends in UCP
+
ucp_main_front_user_activity_after
===
* Locations:
@@ -2224,6 +2392,20 @@ ucp_pm_history_review_before
* Since: 3.1.6-RC1
* Purpose: Add content before the private messages history review.
+ucp_pm_history_row_message_author_username_append
+===
+* Locations:
+ + styles/prosilver/template/ucp_pm_history.html
+* Since: 3.2.8-RC1
+* Purpose: Append information to message author username of member
+
+ucp_pm_history_row_message_author_username_prepend
+===
+* Locations:
+ + styles/prosilver/template/ucp_pm_history.html
+* Since: 3.2.8-RC1
+* Purpose: Prepend information to message author username of member
+
ucp_pm_viewmessage_avatar_after
===
* Locations:
@@ -2332,6 +2514,13 @@ ucp_pm_viewmessage_rank_before
* Purpose: Add data before the rank on the user profile when viewing
a private message
+ucp_prefs_personal_append
+===
+* Locations:
+ + styles/prosilver/template/ucp_prefs_personal.html
+* Since: 3.1.0-a1
+* Purpose: Add user options to the bottom of the Edit Global Settings block
+
ucp_prefs_personal_prepend
===
* Locations:
@@ -2339,12 +2528,12 @@ ucp_prefs_personal_prepend
* Since: 3.1.0-a1
* Purpose: Add user options to the top of the Edit Global Settings block
-ucp_prefs_personal_append
+ucp_prefs_post_append
===
* Locations:
- + styles/prosilver/template/ucp_prefs_personal.html
+ + styles/prosilver/template/ucp_prefs_post.html
* Since: 3.1.0-a1
-* Purpose: Add user options to the bottom of the Edit Global Settings block
+* Purpose: Add user options to the bottom of the Edit Posting Defaults block
ucp_prefs_post_prepend
===
@@ -2353,12 +2542,13 @@ ucp_prefs_post_prepend
* Since: 3.1.0-a1
* Purpose: Add user options to the top of the Edit Posting Defaults block
-ucp_prefs_post_append
+ucp_prefs_view_radio_buttons_append
===
* Locations:
- + styles/prosilver/template/ucp_prefs_post.html
+ + styles/prosilver/template/ucp_prefs_view.html
* Since: 3.1.0-a1
-* Purpose: Add user options to the bottom of the Edit Posting Defaults block
+* Purpose: Add options to the bottom of the radio buttons block of the Edit
+Display Options screen
ucp_prefs_view_radio_buttons_prepend
===
@@ -2368,12 +2558,12 @@ ucp_prefs_view_radio_buttons_prepend
* Purpose: Add options to the top of the radio buttons block of the Edit
Display Options screen
-ucp_prefs_view_radio_buttons_append
+ucp_prefs_view_select_menu_append
===
* Locations:
+ styles/prosilver/template/ucp_prefs_view.html
* Since: 3.1.0-a1
-* Purpose: Add options to the bottom of the radio buttons block of the Edit
+* Purpose: Add options to the bottom of the drop-down lists block of the Edit
Display Options screen
ucp_prefs_view_select_menu_prepend
@@ -2384,13 +2574,12 @@ ucp_prefs_view_select_menu_prepend
* Purpose: Add options to the top of the drop-down lists block of the Edit
Display Options screen
-ucp_prefs_view_select_menu_append
+ucp_profile_profile_info_after
===
* Locations:
- + styles/prosilver/template/ucp_prefs_view.html
-* Since: 3.1.0-a1
-* Purpose: Add options to the bottom of the drop-down lists block of the Edit
-Display Options screen
+ + styles/prosilver/template/ucp_profile_profile_info.html
+* Since: 3.1.4-RC1
+* Purpose: Add options in profile page fieldset - after custom profile fields.
ucp_profile_profile_info_before
===
@@ -2399,12 +2588,12 @@ ucp_profile_profile_info_before
* Since: 3.1.4-RC1
* Purpose: Add options in profile page fieldset - before jabber field.
-ucp_profile_profile_info_after
+ucp_profile_register_details_after
===
* Locations:
- + styles/prosilver/template/ucp_profile_profile_info.html
+ + styles/prosilver/template/ucp_profile_reg_details.html
* Since: 3.1.4-RC1
-* Purpose: Add options in profile page fieldset - after custom profile fields.
+* Purpose: Add options in profile page fieldset - after confirm password field.
ucp_profile_register_details_before
===
@@ -2413,12 +2602,12 @@ ucp_profile_register_details_before
* Since: 3.1.4-RC1
* Purpose: Add options in profile page fieldset - before first field.
-ucp_profile_register_details_after
+ucp_profile_signature_posting_editor_options_prepend
===
* Locations:
- + styles/prosilver/template/ucp_profile_reg_details.html
-* Since: 3.1.4-RC1
-* Purpose: Add options in profile page fieldset - after confirm password field.
+ + styles/prosilver/template/ucp_profile_signature.html
+* Since: 3.2.6-RC1
+* Purpose: Add options signature posting editor - before first option.
ucp_register_buttons_before
===
@@ -2427,33 +2616,33 @@ ucp_register_buttons_before
* Since: 3.1.11-RC1
* Purpose: Add content before buttons in registration form.
-ucp_register_credentials_before
+ucp_register_credentials_after
===
* Locations:
+ styles/prosilver/template/ucp_register.html
* Since: 3.1.0-b5
-* Purpose: Add options in registration page fieldset - before first field.
+* Purpose: Add options in registration page fieldset - after password field.
-ucp_register_profile_fields_after
+ucp_register_credentials_before
===
* Locations:
+ styles/prosilver/template/ucp_register.html
* Since: 3.1.0-b5
-* Purpose: Add options in registration page fieldset - after last field.
+* Purpose: Add options in registration page fieldset - before first field.
-ucp_register_credentials_after
+ucp_register_options_before
===
* Locations:
+ styles/prosilver/template/ucp_register.html
* Since: 3.1.0-b5
-* Purpose: Add options in registration page fieldset - after password field.
+* Purpose: Add options in registration page fieldset - before language selector.
-ucp_register_options_before
+ucp_register_profile_fields_after
===
* Locations:
+ styles/prosilver/template/ucp_register.html
* Since: 3.1.0-b5
-* Purpose: Add options in registration page fieldset - before language selector.
+* Purpose: Add options in registration page fieldset - after last field.
ucp_register_profile_fields_before
===
@@ -2462,31 +2651,17 @@ ucp_register_profile_fields_before
* Since: 3.1.0-b5
* Purpose: Add options in registration page fieldset - before profile fields.
-ucp_friend_list_before
-===
-* Locations:
- + styles/prosilver/template/ucp_zebra_friends.html
-* Since: 3.1.0-a4
-* Purpose: Add optional elements before list of friends in UCP
-
-ucp_friend_list_after
-===
-* Locations:
- + styles/prosilver/template/ucp_zebra_friends.html
-* Since: 3.1.0-a4
-* Purpose: Add optional elements after list of friends in UCP
-
viewforum_body_last_post_author_username_append
===
* Locations:
- + styles/prosilver/template/viewforum_body.html
+ + styles/prosilver/template/viewforum_body.html (2)
* Since: 3.2.4-RC1
* Purpose: Append information to last post author username of member
viewforum_body_last_post_author_username_prepend
===
* Locations:
- + styles/prosilver/template/viewforum_body.html
+ + styles/prosilver/template/viewforum_body.html (2)
* Since: 3.2.4-RC1
* Purpose: Prepend information to last post author username of member
@@ -2539,13 +2714,6 @@ viewforum_body_topicrow_row_before
* Since: 3.1.10-RC1
* Purpose: Add content before list of topics.
-viewforum_buttons_bottom_before
-===
-* Locations:
- + styles/prosilver/template/viewforum_body.html
-* Since: 3.1.0-RC5
-* Purpose: Add buttons before New Topic button on the bottom of the topic's list
-
viewforum_buttons_bottom_after
===
* Locations:
@@ -2553,12 +2721,12 @@ viewforum_buttons_bottom_after
* Since: 3.1.0-RC5
* Purpose: Add buttons after New Topic button on the bottom of the topic's list
-viewforum_buttons_top_before
+viewforum_buttons_bottom_before
===
* Locations:
+ styles/prosilver/template/viewforum_body.html
* Since: 3.1.0-RC5
-* Purpose: Add buttons before New Topic button on the top of the topic's list
+* Purpose: Add buttons before New Topic button on the bottom of the topic's list
viewforum_buttons_top_after
===
@@ -2567,47 +2735,12 @@ viewforum_buttons_top_after
* Since: 3.1.0-RC5
* Purpose: Add buttons after New Topic button on the top of the topic's list
-viewtopic_buttons_bottom_before
-===
-* Locations:
- + styles/prosilver/template/viewtopic_body.html
-* Since: 3.1.0-RC5
-* Purpose: Add buttons before Post Reply button on the bottom of the posts's list
-
-viewtopic_buttons_bottom_after
-===
-* Locations:
- + styles/prosilver/template/viewtopic_body.html
-* Since: 3.1.0-RC5
-* Purpose: Add buttons after Post Reply button on the bottom of the posts's list
-
-viewtopic_buttons_top_before
-===
-* Locations:
- + styles/prosilver/template/viewtopic_body.html
-* Since: 3.1.0-RC5
-* Purpose: Add buttons before Post Reply button on the top of the posts's list
-
-viewtopic_buttons_top_after
+viewforum_buttons_top_before
===
* Locations:
- + styles/prosilver/template/viewtopic_body.html
+ + styles/prosilver/template/viewforum_body.html
* 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
+* Purpose: Add buttons before New Topic button on the top of the topic's list
viewforum_forum_name_append
===
@@ -2651,20 +2784,6 @@ viewonline_body_username_prepend
* Since: 3.2.4-RC1
* Purpose: Prepend information to username of member
-viewtopic_print_head_append
-===
-* Locations:
- + styles/prosilver/template/viewtopic_print.html
-* Since: 3.1.0-a1
-* Purpose: Add asset calls directly before the `</head>` tag of the Print Topic screen
-
-viewtopic_body_pagination_top_after
-===
-* Locations:
- + styles/prosilver/template/viewtopic_body.html
-* Since: 3.1.4-RC1
-* Purpose: Add content after the pagination at top
-
viewtopic_body_avatar_after
===
* Locations:
@@ -2703,6 +2822,13 @@ 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_pagination_top_after
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+* Since: 3.1.4-RC1
+* Purpose: Add content after the pagination at top
+
viewtopic_body_poll_after
===
* Locations:
@@ -2805,28 +2931,28 @@ viewtopic_body_postrow_back2top_after
* Locations:
+ styles/prosilver/template/viewtopic_body.html
* Since: 3.1.8-RC1
-* Purpose: Add content to the post's bottom after the back to top link
+* Purpose: Add content to the post's bottom after the back to top link
viewtopic_body_postrow_back2top_append
===
* Locations:
+ styles/prosilver/template/viewtopic_body.html
* Since: 3.1.8-RC1
-* Purpose: Add content to the post's bottom directly after the back to top link
+* Purpose: Add content to the post's bottom directly after the back to top link
viewtopic_body_postrow_back2top_before
===
* Locations:
+ styles/prosilver/template/viewtopic_body.html
* Since: 3.1.8-RC1
-* Purpose: Add content to the post's bottom before the back to top link
+* Purpose: Add content to the post's bottom before the back to top link
viewtopic_body_postrow_back2top_prepend
===
* Locations:
+ styles/prosilver/template/viewtopic_body.html
* Since: 3.1.8-RC1
-* Purpose: Add content to the post's bottom directly before the back to top link
+* Purpose: Add content to the post's bottom directly before the back to top link
viewtopic_body_postrow_content_after
===
@@ -2923,19 +3049,61 @@ viewtopic_body_topic_actions_before
* Since: 3.1.0-a4
* Purpose: Add data before the topic actions buttons (after the posts sorting options)
-viewtopic_topic_title_after
+viewtopic_buttons_bottom_after
===
* Locations:
+ styles/prosilver/template/viewtopic_body.html
-* Since: 3.1.7-RC1
-* Purpose: Add content directly after the topic title link on the View topic screen (outside of the h2 HTML tag)
+* Since: 3.1.0-RC5
+* Purpose: Add buttons after Post Reply button on the bottom of the posts's list
-viewtopic_topic_title_before
+viewtopic_buttons_bottom_before
===
* Locations:
+ styles/prosilver/template/viewtopic_body.html
-* Since: 3.2.2-RC1
-* Purpose: Add content directly before the topic title link on the View topic screen (outside of the h2 HTML tag)
+* Since: 3.1.0-RC5
+* Purpose: Add buttons before Post Reply button on the bottom of the posts's list
+
+viewtopic_buttons_top_after
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+* Since: 3.1.0-RC5
+* Purpose: Add buttons after Post Reply button on the top of the posts's list
+
+viewtopic_buttons_top_before
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+* Since: 3.1.0-RC5
+* Purpose: Add buttons before 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
+
+viewtopic_print_head_append
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_print.html
+* Since: 3.1.0-a1
+* Purpose: Add asset calls directly before the `</head>` tag of the Print Topic screen
+
+viewtopic_topic_title_after
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+* Since: 3.1.7-RC1
+* Purpose: Add content directly after the topic title link on the View topic screen (outside of the h2 HTML tag)
viewtopic_topic_title_append
===
@@ -2944,6 +3112,13 @@ viewtopic_topic_title_append
* Since: 3.1.0-b3
* Purpose: Add content directly after the topic title link on the View topic screen
+viewtopic_topic_title_before
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+* Since: 3.2.2-RC1
+* Purpose: Add content directly before the topic title link on the View topic screen (outside of the h2 HTML tag)
+
viewtopic_topic_title_prepend
===
* Locations:
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index 5b1db5c31b..94e3660de8 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -27,6 +27,9 @@ class acp_attachments
/** @var \phpbb\config\config */
protected $config;
+ /** @var \phpbb\language\language */
+ protected $language;
+
/** @var ContainerBuilder */
protected $phpbb_container;
@@ -54,6 +57,7 @@ class acp_attachments
$this->id = $id;
$this->db = $db;
$this->config = $config;
+ $this->language = $phpbb_container->get('language');
$this->template = $template;
$this->user = $user;
$this->phpbb_container = $phpbb_container;
@@ -128,7 +132,7 @@ class acp_attachments
$s_assigned_groups = array();
while ($row = $db->sql_fetchrow($result))
{
- $row['group_name'] = (isset($user->lang['EXT_GROUP_' . $row['group_name']])) ? $user->lang['EXT_GROUP_' . $row['group_name']] : $row['group_name'];
+ $row['group_name'] = $this->language->is_set('EXT_GROUP_' . utf8_strtoupper($row['group_name'])) ? $this->language->lang('EXT_GROUP_' . utf8_strtoupper($row['group_name'])) : $row['group_name'];
$s_assigned_groups[$row['cat_id']][] = $row['group_name'];
}
$db->sql_freeresult($result);
@@ -573,7 +577,7 @@ class acp_attachments
$group_id = $db->sql_nextid();
}
- $group_name = (isset($user->lang['EXT_GROUP_' . $group_name])) ? $user->lang['EXT_GROUP_' . $group_name] : $group_name;
+ $group_name = $this->language->is_set('EXT_GROUP_' . utf8_strtoupper($group_name)) ? $this->language->lang('EXT_GROUP_' . utf8_strtoupper($group_name)) : $group_name;
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ATTACH_EXTGROUP_' . strtoupper($action), false, array($group_name));
}
@@ -875,7 +879,7 @@ class acp_attachments
'U_EDIT' => $this->u_action . "&amp;action=edit&amp;g={$row['group_id']}",
'U_DELETE' => $this->u_action . "&amp;action=delete&amp;g={$row['group_id']}",
- 'GROUP_NAME' => (isset($user->lang['EXT_GROUP_' . $row['group_name']])) ? $user->lang['EXT_GROUP_' . $row['group_name']] : $row['group_name'],
+ 'GROUP_NAME' => $this->language->is_set('EXT_GROUP_' . utf8_strtoupper($row['group_name'])) ? $this->language->lang('EXT_GROUP_' . utf8_strtoupper($row['group_name'])) : $row['group_name'],
'CATEGORY' => $cat_lang[$row['cat_id']],
)
);
@@ -1244,15 +1248,11 @@ class acp_attachments
'ATTACHMENT_POSTER' => get_username_string('full', (int) $row['poster_id'], (string) $row['username'], (string) $row['user_colour'], (string) $row['username']),
'FILESIZE' => get_formatted_filesize((int) $row['filesize']),
'FILETIME' => $user->format_date((int) $row['filetime']),
- 'REAL_FILENAME' => (!$row['in_message']) ? utf8_basename((string) $row['real_filename']) : '',
- 'PHYSICAL_FILENAME' => utf8_basename((string) $row['physical_filename']),
- 'EXT_GROUP_NAME' => (!empty($extensions[$row['extension']]['group_name'])) ? $user->lang['EXT_GROUP_' . $extensions[$row['extension']]['group_name']] : '',
+ 'REAL_FILENAME' => utf8_basename((string) $row['real_filename']),
+ 'EXT_GROUP_NAME' => $this->language->is_set('EXT_GROUP_' . utf8_strtoupper($extensions[$row['extension']]['group_name'])) ? $this->language->lang('EXT_GROUP_' . utf8_strtoupper($extensions[$row['extension']]['group_name'])) : $extensions[$row['extension']]['group_name'],
'COMMENT' => $comment,
'TOPIC_TITLE' => (!$row['in_message']) ? (string) $row['topic_title'] : '',
'ATTACH_ID' => (int) $row['attach_id'],
- 'POST_ID' => (int) $row['post_msg_id'],
- 'TOPIC_ID' => (int) $row['topic_id'],
- 'POST_IDS' => (!empty($post_ids[$row['attach_id']])) ? (int) $post_ids[$row['attach_id']] : '',
'L_DOWNLOAD_COUNT' => $user->lang($l_downloaded_viewed, (int) $row['download_count']),
@@ -1434,7 +1434,7 @@ class acp_attachments
$group_name = array();
while ($row = $db->sql_fetchrow($result))
{
- $row['group_name'] = (isset($user->lang['EXT_GROUP_' . $row['group_name']])) ? $user->lang['EXT_GROUP_' . $row['group_name']] : $row['group_name'];
+ $row['group_name'] = $this->language->is_set('EXT_GROUP_' . utf8_strtoupper($row['group_name'])) ? $this->language->lang('EXT_GROUP_' . utf8_strtoupper($row['group_name'])) : $row['group_name'];
$group_name[] = $row;
}
$db->sql_freeresult($result);
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index f89f5535eb..e348c769bd 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -30,10 +30,13 @@ class acp_board
function main($id, $mode)
{
- global $user, $template, $request;
+ global $user, $template, $request, $language;
global $config, $phpbb_root_path, $phpEx;
global $cache, $phpbb_container, $phpbb_dispatcher, $phpbb_log;
+ /** @var \phpbb\language\language $language Language object */
+ $language = $phpbb_container->get('language');
+
$user->add_lang('acp/board');
$submit = (isset($_POST['submit']) || isset($_POST['allow_quick_reply_enable'])) ? true : false;
@@ -56,7 +59,7 @@ class acp_board
'legend1' => 'ACP_BOARD_SETTINGS',
'sitename' => array('lang' => 'SITE_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false),
'site_desc' => array('lang' => 'SITE_DESC', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false),
- 'site_home_url' => array('lang' => 'SITE_HOME_URL', 'validate' => 'string', 'type' => 'url:40:255', 'explain' => true),
+ 'site_home_url' => array('lang' => 'SITE_HOME_URL', 'validate' => 'url', 'type' => 'url:40:255', 'explain' => true),
'site_home_text' => array('lang' => 'SITE_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true),
'board_index_text' => array('lang' => 'BOARD_INDEX_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true),
'board_disable' => array('lang' => 'DISABLE_BOARD', 'validate' => 'bool', 'type' => 'custom', 'method' => 'board_disable', 'explain' => true),
@@ -122,6 +125,7 @@ class acp_board
$avatar_vars = array();
foreach ($avatar_drivers as $current_driver)
{
+ /** @var \phpbb\avatar\driver\driver_interface $driver */
$driver = $phpbb_avatar_manager->get_driver($current_driver, false);
/*
@@ -730,7 +734,7 @@ class acp_board
$template->assign_block_vars('options', array(
'KEY' => $config_key,
'TITLE' => (isset($user->lang[$vars['lang']])) ? $user->lang[$vars['lang']] : $vars['lang'],
- 'S_EXPLAIN' => $vars['explain'],
+ 'S_EXPLAIN' => $vars['explain'] && !empty($l_explain),
'TITLE_EXPLAIN' => $l_explain,
'CONTENT' => $content,
)
diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php
index 19c4f6e4f1..c33c2e4d6f 100644
--- a/phpBB/includes/acp/acp_database.php
+++ b/phpBB/includes/acp/acp_database.php
@@ -23,6 +23,7 @@ class acp_database
{
var $db_tools;
var $u_action;
+ public $page_title;
function main($id, $mode)
{
@@ -69,18 +70,13 @@ class acp_database
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
- $store = $download = $structure = $schema_data = false;
+ $store = $structure = $schema_data = false;
- if ($where == 'store_and_download' || $where == 'store')
+ if ($where == 'store')
{
$store = true;
}
- if ($where == 'store_and_download' || $where == 'download')
- {
- $download = true;
- }
-
if ($type == 'full' || $type == 'structure')
{
$structure = true;
@@ -98,8 +94,9 @@ class acp_database
$filename = 'backup_' . $time . '_' . unique_id();
+ /** @var phpbb\db\extractor\extractor_interface $extractor Database extractor */
$extractor = $phpbb_container->get('dbal.extractor');
- $extractor->init_extractor($format, $filename, $time, $download, $store);
+ $extractor->init_extractor($format, $filename, $time, false, $store);
$extractor->write_start($table_prefix);
@@ -145,11 +142,6 @@ class acp_database
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_BACKUP');
- if ($download == true)
- {
- exit;
- }
-
trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action));
break;
@@ -201,16 +193,10 @@ class acp_database
case 'submit':
$delete = $request->variable('delete', '');
$file = $request->variable('file', '');
- $download = $request->variable('download', '');
- if (!preg_match('#^backup_\d{10,}_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $file, $matches))
- {
- trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
- }
+ $backup_info = $this->get_backup_file($phpbb_root_path . 'store/', $file);
- $file_name = $phpbb_root_path . 'store/' . $matches[0];
-
- if (!file_exists($file_name) || !is_readable($file_name))
+ if (empty($backup_info) || !is_readable($backup_info['file_name']))
{
trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
@@ -219,7 +205,7 @@ class acp_database
{
if (confirm_box(true))
{
- unlink($file_name);
+ unlink($backup_info['file_name']);
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_DELETE');
trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action));
}
@@ -228,50 +214,12 @@ class acp_database
confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file)));
}
}
- else if ($download || confirm_box(true))
+ else if (confirm_box(true))
{
- if ($download)
- {
- $name = $matches[0];
-
- switch ($matches[1])
- {
- case 'sql':
- $mimetype = 'text/x-sql';
- break;
- case 'sql.bz2':
- $mimetype = 'application/x-bzip2';
- break;
- case 'sql.gz':
- $mimetype = 'application/x-gzip';
- break;
- }
-
- header('Cache-Control: private, no-cache');
- header("Content-Type: $mimetype; name=\"$name\"");
- header("Content-disposition: attachment; filename=$name");
-
- @set_time_limit(0);
-
- $fp = @fopen($file_name, 'rb');
-
- if ($fp !== false)
- {
- while (!feof($fp))
- {
- echo fread($fp, 8192);
- }
- fclose($fp);
- }
-
- flush();
- exit;
- }
-
- switch ($matches[1])
+ switch ($backup_info['extension'])
{
case 'sql':
- $fp = fopen($file_name, 'rb');
+ $fp = fopen($backup_info['file_name'], 'rb');
$read = 'fread';
$seek = 'fseek';
$eof = 'feof';
@@ -280,7 +228,7 @@ class acp_database
break;
case 'sql.bz2':
- $fp = bzopen($file_name, 'r');
+ $fp = bzopen($backup_info['file_name'], 'r');
$read = 'bzread';
$seek = '';
$eof = 'feof';
@@ -289,13 +237,17 @@ class acp_database
break;
case 'sql.gz':
- $fp = gzopen($file_name, 'rb');
+ $fp = gzopen($backup_info['file_name'], 'rb');
$read = 'gzread';
$seek = 'gzseek';
$eof = 'gzeof';
$close = 'gzclose';
$fgetd = 'fgetd';
break;
+
+ default:
+ trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
+ return;
}
switch ($db->get_sql_layer())
@@ -375,43 +327,13 @@ class acp_database
trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action));
break;
}
- else if (!$download)
+ else
{
confirm_box(false, $user->lang['RESTORE_SELECTED_BACKUP'], build_hidden_fields(array('file' => $file)));
}
default:
- $methods = array('sql');
- $available_methods = array('sql.gz' => 'zlib', 'sql.bz2' => 'bz2');
-
- foreach ($available_methods as $type => $module)
- {
- if (!@extension_loaded($module))
- {
- continue;
- }
- $methods[] = $type;
- }
-
- $dir = $phpbb_root_path . 'store/';
- $dh = @opendir($dir);
-
- $backup_files = array();
-
- if ($dh)
- {
- while (($file = readdir($dh)) !== false)
- {
- if (preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $file, $matches))
- {
- if (in_array($matches[2], $methods))
- {
- $backup_files[(int) $matches[1]] = $file;
- }
- }
- }
- closedir($dh);
- }
+ $backup_files = $this->get_file_list($phpbb_root_path . 'store/');
if (!empty($backup_files))
{
@@ -420,8 +342,8 @@ class acp_database
foreach ($backup_files as $name => $file)
{
$template->assign_block_vars('files', array(
- 'FILE' => $file,
- 'NAME' => $user->format_date($name, 'd-m-Y H:i:s', true),
+ 'FILE' => sha1($file),
+ 'NAME' => $user->format_date($name, 'd-m-Y H:i', true),
'SUPPORTED' => true,
));
}
@@ -435,6 +357,92 @@ class acp_database
break;
}
}
+
+ /**
+ * Get backup file from file hash
+ *
+ * @param string $directory Relative path to directory
+ * @param string $file_hash Hash of selected file
+ *
+ * @return array Backup file data or empty array if unable to find file
+ */
+ protected function get_backup_file($directory, $file_hash)
+ {
+ $backup_data = [];
+
+ $file_list = $this->get_file_list($directory);
+ $supported_extensions = $this->get_supported_extensions();
+
+ foreach ($file_list as $file)
+ {
+ preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $file, $matches);
+ if (sha1($file) === $file_hash && in_array($matches[2], $supported_extensions))
+ {
+ $backup_data = [
+ 'file_name' => $directory . $file,
+ 'extension' => $matches[2],
+ ];
+ break;
+ }
+ }
+
+ return $backup_data;
+ }
+
+ /**
+ * Get backup file list for directory
+ *
+ * @param string $directory Relative path to backup directory
+ *
+ * @return array List of backup files in specified directory
+ */
+ protected function get_file_list($directory)
+ {
+ $supported_extensions = $this->get_supported_extensions();
+
+ $dh = @opendir($directory);
+
+ $backup_files = [];
+
+ if ($dh)
+ {
+ while (($file = readdir($dh)) !== false)
+ {
+ if (preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $file, $matches))
+ {
+ if (in_array($matches[2], $supported_extensions))
+ {
+ $backup_files[(int) $matches[1]] = $file;
+ }
+ }
+ }
+ closedir($dh);
+ }
+
+ return $backup_files;
+ }
+
+ /**
+ * Get supported extensions for backup
+ *
+ * @return array List of supported extensions
+ */
+ protected function get_supported_extensions()
+ {
+ $extensions = ['sql'];
+ $available_methods = ['sql.gz' => 'zlib', 'sql.bz2' => 'bz2'];
+
+ foreach ($available_methods as $type => $module)
+ {
+ if (!@extension_loaded($module))
+ {
+ continue;
+ }
+ $extensions[] = $type;
+ }
+
+ return $extensions;
+ }
}
// get how much space we allow for a chunk of data, very similar to phpMyAdmin's way of doing things ;-) (hey, we only do this for MySQL anyway :P)
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index be5a7a2f26..cb0593b14a 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -986,6 +986,13 @@ class acp_forums
$errors[] = $user->lang['FORUM_NAME_EMPTY'];
}
+ // No Emojis
+ if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $forum_data_ary['forum_name'], $matches))
+ {
+ $character_list = implode('<br>', $matches[0]);
+ $errors[] = $user->lang('FORUM_NAME_EMOJI', $character_list);
+ }
+
if (utf8_strlen($forum_data_ary['forum_desc']) > 4000)
{
$errors[] = $user->lang['FORUM_DESC_TOO_LONG'];
diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php
index 0e058213e0..7b1dc706db 100644
--- a/phpBB/includes/acp/acp_groups.php
+++ b/phpBB/includes/acp/acp_groups.php
@@ -29,6 +29,9 @@ class acp_groups
global $phpbb_root_path, $phpbb_admin_path, $phpEx;
global $request, $phpbb_container, $phpbb_dispatcher;
+ /** @var \phpbb\language\language $language Language object */
+ $language = $phpbb_container->get('language');
+
$user->add_lang('acp/groups');
$this->tpl_name = 'acp_groups';
$this->page_title = 'ACP_GROUPS_MANAGE';
@@ -293,7 +296,19 @@ class acp_groups
// Add user/s to group
if ($error = group_user_add($group_id, false, $name_ary, $group_name, $default, $leader, 0, $group_row))
{
- trigger_error($user->lang[$error] . adm_back_link($this->u_action . '&amp;action=list&amp;g=' . $group_id), E_USER_WARNING);
+ $display_message = $language->lang($error);
+
+ if ($error == 'GROUP_USERS_INVALID')
+ {
+ // Find which users don't exist
+ $actual_name_ary = $name_ary;
+ $actual_user_id_ary = [];
+ user_get_id_name($actual_user_id_ary, $actual_name_ary, false, true);
+
+ $display_message = $language->lang('GROUP_USERS_INVALID', implode($language->lang('COMMA_SEPARATOR'), array_udiff($name_ary, $actual_name_ary, 'strcasecmp')));
+ }
+
+ trigger_error($display_message . adm_back_link($this->u_action . '&amp;action=list&amp;g=' . $group_id), E_USER_WARNING);
}
$message = ($leader) ? 'GROUP_MODS_ADDED' : 'GROUP_USERS_ADDED';
diff --git a/phpBB/includes/acp/acp_update.php b/phpBB/includes/acp/acp_update.php
index 9124a59ef2..fa3afa6ce3 100644
--- a/phpBB/includes/acp/acp_update.php
+++ b/phpBB/includes/acp/acp_update.php
@@ -59,17 +59,19 @@ class acp_update
$update_link = $phpbb_root_path . 'install/app.' . $phpEx;
- $template->assign_vars(array(
- 'S_UP_TO_DATE' => empty($updates_available),
- 'U_ACTION' => $this->u_action,
- 'U_VERSIONCHECK_FORCE' => append_sid($this->u_action . '&amp;versioncheck_force=1'),
+ $template_ary = [
+ 'S_UP_TO_DATE' => empty($updates_available),
+ 'U_ACTION' => $this->u_action,
+ 'U_VERSIONCHECK_FORCE' => append_sid($this->u_action . '&amp;versioncheck_force=1'),
- 'CURRENT_VERSION' => $config['version'],
+ 'CURRENT_VERSION' => $config['version'],
- 'UPDATE_INSTRUCTIONS' => sprintf($user->lang['UPDATE_INSTRUCTIONS'], $update_link),
+ 'UPDATE_INSTRUCTIONS' => $user->lang('UPDATE_INSTRUCTIONS', $update_link),
'S_VERSION_UPGRADEABLE' => !empty($upgrades_available),
'UPGRADE_INSTRUCTIONS' => !empty($upgrades_available) ? $user->lang('UPGRADE_INSTRUCTIONS', $upgrades_available['current'], $upgrades_available['announcement']) : false,
- ));
+ ];
+
+ $template->assign_vars($template_ary);
// Incomplete update?
if (phpbb_version_compare($config['version'], PHPBB_VERSION, '<'))
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 2d1eaadfae..fd4b5e8c24 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -855,7 +855,7 @@ class acp_users
$check_ary += array(
'username' => array(
array('string', false, $config['min_name_chars'], $config['max_name_chars']),
- array('username', $user_row['username'])
+ array('username', $user_row['username'], true)
),
);
}
diff --git a/phpBB/includes/compatibility_globals.php b/phpBB/includes/compatibility_globals.php
index 0f403896a7..ad394e3782 100644
--- a/phpBB/includes/compatibility_globals.php
+++ b/phpBB/includes/compatibility_globals.php
@@ -29,7 +29,7 @@ function register_compatibility_globals()
{
global $phpbb_container;
- global $cache, $phpbb_dispatcher, $request, $user, $auth, $db, $config, $phpbb_log;
+ global $cache, $phpbb_dispatcher, $request, $user, $auth, $db, $config, $language, $phpbb_log;
global $symfony_request, $phpbb_filesystem, $phpbb_path_helper, $phpbb_extension_manager, $template;
// set up caching
@@ -48,6 +48,9 @@ function register_compatibility_globals()
/* @var $user \phpbb\user */
$user = $phpbb_container->get('user');
+ /* @var \phpbb\language\language $language */
+ $language = $phpbb_container->get('language');
+
/* @var $auth \phpbb\auth\auth */
$auth = $phpbb_container->get('auth');
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index d80f348ac5..89d056f2e1 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))
*/
// phpBB Version
-@define('PHPBB_VERSION', '3.2.6-dev');
+@define('PHPBB_VERSION', '3.2.8-dev');
// QA-related
// define('PHPBB_QA', 1);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 99f65a0e92..2e2b2a01d8 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -680,8 +680,6 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
}
}
}
-
- return;
}
else if ($mode == 'topics')
{
@@ -808,8 +806,6 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
unset($tracking);
}
-
- return;
}
else if ($mode == 'topic')
{
@@ -923,8 +919,6 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
$user->set_cookie('track', tracking_serialize($tracking), $post_time + 31536000);
$request->overwrite($config['cookie_name'] . '_track', tracking_serialize($tracking), \phpbb\request\request_interface::COOKIE);
}
-
- return;
}
else if ($mode == 'post')
{
@@ -949,9 +943,28 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
$db->sql_return_on_error(false);
}
-
- return;
}
+
+ /**
+ * This event is used for performing actions directly after forums,
+ * topics or posts have been marked as read.
+ *
+ * @event core.markread_after
+ * @var string mode Variable containing marking mode value
+ * @var mixed forum_id Variable containing forum id, or false
+ * @var mixed topic_id Variable containing topic id, or false
+ * @var int post_time Variable containing post time
+ * @var int user_id Variable containing the user id
+ * @since 3.2.6-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'forum_id',
+ 'topic_id',
+ 'post_time',
+ 'user_id',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.markread_after', compact($vars)));
}
/**
@@ -1830,27 +1843,6 @@ function redirect($url, $return = false, $disable_cd_check = false)
garbage_collection();
}
- // Redirect via an HTML form for PITA webservers
- if (@preg_match('#WebSTAR|Xitami#', getenv('SERVER_SOFTWARE')))
- {
- header('Refresh: 0; URL=' . $url);
-
- echo '<!DOCTYPE html>';
- echo '<html dir="' . $user->lang['DIRECTION'] . '" lang="' . $user->lang['USER_LANG'] . '">';
- echo '<head>';
- echo '<meta charset="utf-8">';
- echo '<meta http-equiv="X-UA-Compatible" content="IE=edge">';
- echo '<meta http-equiv="refresh" content="0; url=' . str_replace('&', '&amp;', $url) . '" />';
- echo '<title>' . $user->lang['REDIRECT'] . '</title>';
- echo '</head>';
- echo '<body>';
- echo '<div style="text-align: center;">' . sprintf($user->lang['URL_REDIRECT'], '<a href="' . str_replace('&', '&amp;', $url) . '">', '</a>') . '</div>';
- echo '</body>';
- echo '</html>';
-
- exit;
- }
-
// Behave as per HTTP/1.1 spec for others
header('Location: ' . $url);
exit;
@@ -2130,25 +2122,29 @@ function check_form_key($form_name, $timespan = false)
/**
* Build Confirm box
* @param boolean $check True for checking if confirmed (without any additional parameters) and false for displaying the confirm box
-* @param string $title Title/Message used for confirm box.
+* @param string|array $title Title/Message used for confirm box.
* message text is _CONFIRM appended to title.
* If title cannot be found in user->lang a default one is displayed
* If title_CONFIRM cannot be found in user->lang the text given is used.
+* If title is an array, the first array value is used as explained per above,
+* all other array values are sent as parameters to the language function.
* @param string $hidden Hidden variables
* @param string $html_body Template used for confirm box
* @param string $u_action Custom form action
+*
+* @return bool True if confirmation was successful, false if not
*/
function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_body.html', $u_action = '')
{
global $user, $template, $db, $request;
- global $config, $phpbb_path_helper;
+ global $config, $language, $phpbb_path_helper, $phpbb_dispatcher;
if (isset($_POST['cancel']))
{
return false;
}
- $confirm = ($user->lang['YES'] === $request->variable('confirm', '', true, \phpbb\request\request_interface::POST));
+ $confirm = ($language->lang('YES') === $request->variable('confirm', '', true, \phpbb\request\request_interface::POST));
if ($check && $confirm)
{
@@ -2182,13 +2178,27 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
// generate activation key
$confirm_key = gen_rand_string(10);
+ // generate language strings
+ if (is_array($title))
+ {
+ $key = array_shift($title);
+ $count = array_shift($title);
+ $confirm_title = $language->is_set($key) ? $language->lang($key, $count, $title) : $language->lang('CONFIRM');
+ $confirm_text = $language->is_set($key . '_CONFIRM') ? $language->lang($key . '_CONFIRM', $count, $title) : $key;
+ }
+ else
+ {
+ $confirm_title = $language->is_set($title) ? $language->lang($title) : $language->lang('CONFIRM');
+ $confirm_text = $language->is_set($title . '_CONFIRM') ? $language->lang($title . '_CONFIRM') : $title;
+ }
+
if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
{
- adm_page_header((!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title]);
+ adm_page_header($confirm_title);
}
else
{
- page_header((!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title]);
+ page_header($confirm_title);
}
$template->set_filenames(array(
@@ -2208,10 +2218,10 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
$u_action .= ((strpos($u_action, '?') === false) ? '?' : '&amp;') . 'confirm_key=' . $confirm_key;
$template->assign_vars(array(
- 'MESSAGE_TITLE' => (!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang($title, 1),
- 'MESSAGE_TEXT' => (!isset($user->lang[$title . '_CONFIRM'])) ? $title : $user->lang[$title . '_CONFIRM'],
+ 'MESSAGE_TITLE' => $confirm_title,
+ 'MESSAGE_TEXT' => $confirm_text,
- 'YES_VALUE' => $user->lang['YES'],
+ 'YES_VALUE' => $language->lang('YES'),
'S_CONFIRM_ACTION' => $u_action,
'S_HIDDEN_FIELDS' => $hidden . $s_hidden_fields,
'S_AJAX_REQUEST' => $request->is_ajax(),
@@ -2224,16 +2234,36 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
if ($request->is_ajax())
{
$u_action .= '&confirm_uid=' . $user->data['user_id'] . '&sess=' . $user->session_id . '&sid=' . $user->session_id;
- $json_response = new \phpbb\json_response;
- $json_response->send(array(
+ $data = array(
'MESSAGE_BODY' => $template->assign_display('body'),
- 'MESSAGE_TITLE' => (!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title],
- 'MESSAGE_TEXT' => (!isset($user->lang[$title . '_CONFIRM'])) ? $title : $user->lang[$title . '_CONFIRM'],
+ 'MESSAGE_TITLE' => $confirm_title,
+ 'MESSAGE_TEXT' => $confirm_text,
- 'YES_VALUE' => $user->lang['YES'],
+ 'YES_VALUE' => $language->lang('YES'),
'S_CONFIRM_ACTION' => str_replace('&amp;', '&', $u_action), //inefficient, rewrite whole function
'S_HIDDEN_FIELDS' => $hidden . $s_hidden_fields
- ));
+ );
+
+ /**
+ * This event allows an extension to modify the ajax output of confirm box.
+ *
+ * @event core.confirm_box_ajax_before
+ * @var string u_action Action of the form
+ * @var array data Data to be sent
+ * @var string hidden Hidden fields generated by caller
+ * @var string s_hidden_fields Hidden fields generated by this function
+ * @since 3.2.8-RC1
+ */
+ $vars = array(
+ 'u_action',
+ 'data',
+ 'hidden',
+ 's_hidden_fields',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.confirm_box_ajax_before', compact($vars)));
+
+ $json_response = new \phpbb\json_response;
+ $json_response->send($data);
}
if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
@@ -2244,6 +2274,8 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
{
page_footer();
}
+
+ exit; // unreachable, page_footer() above will call exit()
}
/**
@@ -2255,6 +2287,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
global $request, $phpbb_container, $phpbb_dispatcher, $phpbb_log;
$err = '';
+ $form_name = 'login';
// Make sure user->setup() has been called
if (!$user->is_setup())
@@ -2330,8 +2363,19 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
trigger_error('NO_AUTH_ADMIN_USER_DIFFER');
}
- // If authentication is successful we redirect user to previous page
- $result = $auth->login($username, $password, $autologin, $viewonline, $admin);
+ // Check form key
+ if ($password && !check_form_key($form_name))
+ {
+ $result = array(
+ 'status' => false,
+ 'error_msg' => 'FORM_INVALID',
+ );
+ }
+ else
+ {
+ // If authentication is successful we redirect user to previous page
+ $result = $auth->login($username, $password, $autologin, $viewonline, $admin);
+ }
// If admin authentication and login, we will log if it was a success or not...
// We also break the operation on the first non-success login - it could be argued that the user already knows
@@ -2482,6 +2526,9 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
));
}
+ // Add form token for login box
+ add_form_key($form_name, '_LOGIN');
+
$s_hidden_fields = build_hidden_fields($s_hidden_fields);
$login_box_template_data = array(
@@ -2616,6 +2663,9 @@ function login_forum_box($forum_data)
page_header($user->lang['LOGIN']);
+ // Add form token for login box
+ add_form_key('login', '_LOGIN');
+
$template->assign_vars(array(
'FORUM_NAME' => isset($forum_data['forum_name']) ? $forum_data['forum_name'] : '',
'S_LOGIN_ACTION' => build_url(array('f')),
@@ -4081,9 +4131,9 @@ function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config =
*
* @return string Avatar html
*/
-function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config = false, $lazy = false)
+function phpbb_get_group_avatar($group_row, $alt = 'GROUP_AVATAR', $ignore_config = false, $lazy = false)
{
- $row = \phpbb\avatar\manager::clean_row($user_row, 'group');
+ $row = \phpbb\avatar\manager::clean_row($group_row, 'group');
return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
}
@@ -4388,6 +4438,19 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
$controller_helper = $phpbb_container->get('controller.helper');
$notification_mark_hash = generate_link_hash('mark_all_notifications_read');
+ $s_login_redirect = build_hidden_fields(array('redirect' => $phpbb_path_helper->remove_web_root_path(build_url())));
+ /**
+ * Workaround for missing template variable in pre phpBB 3.2.6 styles.
+ * @deprecated 3.2.7 (To be removed: 3.3.0-a1)
+ */
+ $form_token_login = $template->retrieve_var('S_FORM_TOKEN_LOGIN');
+ if (!empty($form_token_login))
+ {
+ $s_login_redirect .= $form_token_login;
+ // Remove S_FORM_TOKEN_LOGIN as it's already appended to S_LOGIN_REDIRECT
+ $template->assign_var('S_FORM_TOKEN_LOGIN', '');
+ }
+
// The following assigns all _common_ variables that may be used at any point in a template.
$template->assign_vars(array(
'SITENAME' => $config['sitename'],
@@ -4477,7 +4540,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'S_TOPIC_ID' => $topic_id,
'S_LOGIN_ACTION' => ((!defined('ADMIN_START')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') : append_sid("{$phpbb_admin_path}index.$phpEx", false, true, $user->session_id)),
- 'S_LOGIN_REDIRECT' => build_hidden_fields(array('redirect' => $phpbb_path_helper->remove_web_root_path(build_url()))),
+ 'S_LOGIN_REDIRECT' => $s_login_redirect,
'S_ENABLE_FEEDS' => ($config['feed_enable']) ? true : false,
'S_ENABLE_FEEDS_OVERALL' => ($config['feed_overall']) ? true : false,
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index 9b7491305c..dd326c3db6 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -419,7 +419,7 @@ function build_cfg_template($tpl_type, $key, &$new_ary, $config_key, $vars)
*/
function validate_config_vars($config_vars, &$cfg_array, &$error)
{
- global $phpbb_root_path, $user, $phpbb_dispatcher, $phpbb_filesystem;
+ global $phpbb_root_path, $user, $phpbb_dispatcher, $phpbb_filesystem, $language;
$type = 0;
$min = 1;
@@ -442,6 +442,16 @@ function validate_config_vars($config_vars, &$cfg_array, &$error)
// Validate a bit. ;) (0 = type, 1 = min, 2= max)
switch ($validator[$type])
{
+ case 'url':
+ $cfg_array[$config_name] = trim($cfg_array[$config_name]);
+
+ if (!empty($cfg_array[$config_name]) && !preg_match('#^' . get_preg_expression('url') . '$#iu', $cfg_array[$config_name]))
+ {
+ $error[] = $language->lang('URL_INVALID', $language->lang($config_definition['lang']));
+ }
+
+ // no break here
+
case 'string':
$length = utf8_strlen($cfg_array[$config_name]);
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index 2fb83770fe..c19d48b0be 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -3042,6 +3042,8 @@ function tidy_database()
}
$db->sql_freeresult($result);
+ $db->sql_transaction('begin');
+
// Delete those rows from the acl tables not having listed the forums above
$sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . '
WHERE ' . $db->sql_in_set('forum_id', $forum_ids, true);
@@ -3051,6 +3053,8 @@ function tidy_database()
WHERE ' . $db->sql_in_set('forum_id', $forum_ids, true);
$db->sql_query($sql);
+ $db->sql_transaction('commit');
+
$config->set('database_last_gc', time(), false);
}
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index a15a03f966..2542be5e02 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -1482,6 +1482,8 @@ function truncate_string($string, $max_length = 60, $max_store_length = 255, $al
* Get username details for placing into templates.
* This function caches all modes on first call, except for no_profile and anonymous user - determined by $user_id.
*
+* @html Username spans and links
+*
* @param string $mode Can be profile (for getting an url to the profile), username (for obtaining the username), colour (for obtaining the user colour), full (for obtaining a html string representing a coloured link to the users profile) or no_profile (the same as full but forcing no profile link)
* @param int $user_id The users id
* @param string $username The users name
@@ -1501,6 +1503,7 @@ function get_username_string($mode, $user_id, $username, $username_colour = '',
{
global $phpbb_root_path, $phpEx;
+ /** @html Username spans and links for usage in the template */
$_profile_cache['base_url'] = append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&amp;u={USER_ID}');
$_profile_cache['tpl_noprofile'] = '<span class="username">{USERNAME}</span>';
$_profile_cache['tpl_noprofile_colour'] = '<span style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</span>';
diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php
index 7be12baa13..1f409be58c 100644
--- a/phpBB/includes/functions_download.php
+++ b/phpBB/includes/functions_download.php
@@ -196,7 +196,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)
}
// Now the tricky part... let's dance
- header('Cache-Control: public');
+ header('Cache-Control: private');
// Send out the Headers. Do not set Content-Disposition to inline please, it is a security measure for users using the Internet Explorer.
header('Content-Type: ' . $attachment['mimetype']);
@@ -451,7 +451,7 @@ function set_modified_headers($stamp, $browser)
{
send_status_line(304, 'Not Modified');
// seems that we need those too ... browsers
- header('Cache-Control: public');
+ header('Cache-Control: private');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');
return true;
}
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index 4f0d40031d..7f8238e1bf 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -181,10 +181,9 @@ class messenger
/**
* Adds X-AntiAbuse headers
*
- * @param array $config Configuration array
- * @param user $user A user object
- *
- * @return null
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\user $user User object
+ * @return void
*/
function anti_abuse_headers($config, $user)
{
@@ -1582,6 +1581,14 @@ class smtp_class
*/
protected function starttls()
{
+ global $config;
+
+ // allow SMTPS (what was used by phpBB 3.0) if hostname is prefixed with tls:// or ssl://
+ if (strpos($config['smtp_host'], 'tls://') === 0 || strpos($config['smtp_host'], 'ssl://') === 0)
+ {
+ return true;
+ }
+
if (!function_exists('stream_socket_enable_crypto'))
{
return false;
@@ -1604,7 +1611,9 @@ class smtp_class
if (socket_set_blocking($this->socket, 1))
{
- $result = stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
+ // https://secure.php.net/manual/en/function.stream-socket-enable-crypto.php#119122
+ $crypto = (phpbb_version_compare(PHP_VERSION, '5.6.7', '<')) ? STREAM_CRYPTO_METHOD_TLS_CLIENT : STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
+ $result = stream_socket_enable_crypto($this->socket, true, $crypto);
socket_set_blocking($this->socket, (int) $stream_meta['blocked']);
}
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index c7d691287c..c5a7400ddf 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -202,11 +202,13 @@ function update_post_information($type, $ids, $return_update_sql = false)
if (count($ids) == 1)
{
- $sql = 'SELECT MAX(p.post_id) as last_post_id
+ $sql = 'SELECT p.post_id as last_post_id
FROM ' . POSTS_TABLE . " p $topic_join
WHERE " . $db->sql_in_set('p.' . $type . '_id', $ids) . "
$topic_condition
- AND p.post_visibility = " . ITEM_APPROVED;
+ AND p.post_visibility = " . ITEM_APPROVED . "
+ ORDER BY p.post_id DESC";
+ $result = $db->sql_query_limit($sql, 1);
}
else
{
@@ -216,8 +218,8 @@ function update_post_information($type, $ids, $return_update_sql = false)
$topic_condition
AND p.post_visibility = " . ITEM_APPROVED . "
GROUP BY p.{$type}_id";
+ $result = $db->sql_query($sql);
}
- $result = $db->sql_query($sql);
$last_post_ids = array();
while ($row = $db->sql_fetchrow($result))
@@ -976,6 +978,30 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
AND u.user_id = p.poster_id',
);
+ /**
+ * Event to modify the SQL query for topic reviews
+ *
+ * @event core.topic_review_modify_sql_ary
+ * @var int topic_id The topic ID that is being reviewed
+ * @var int forum_id The topic's forum ID
+ * @var string mode The topic review mode
+ * @var int cur_post_id Post offset ID
+ * @var bool show_quote_button Flag indicating if the quote button should be displayed
+ * @var array post_list Array with the post IDs
+ * @var array sql_ary Array with the SQL query
+ * @since 3.2.8-RC1
+ */
+ $vars = array(
+ 'topic_id',
+ 'forum_id',
+ 'mode',
+ 'cur_post_id',
+ 'show_quote_button',
+ 'post_list',
+ 'sql_ary',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.topic_review_modify_sql_ary', compact($vars)));
+
$sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql);
@@ -1282,6 +1308,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
delete_topics('topic_id', array($topic_id), false);
$phpbb_content_visibility->remove_topic_from_statistic($data, $sql_data);
+ $config->increment('num_posts', -1, false);
$update_sql = update_post_information('forum', $forum_id, true);
if (count($update_sql))
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index 444bf2c7e0..baadf5bdee 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -490,7 +490,7 @@ function place_pm_into_folder(&$global_privmsgs_rules, $release = false)
'bcc' => explode(':', $row['bcc_address']),
'friend' => (isset($zebra[$row['author_id']])) ? $zebra[$row['author_id']]['friend'] : 0,
'foe' => (isset($zebra[$row['author_id']])) ? $zebra[$row['author_id']]['foe'] : 0,
- 'user_in_group' => array($user->data['group_id']),
+ 'user_in_group' => $user->data['group_id'],
'author_in_group' => array())
);
@@ -1966,7 +1966,7 @@ function submit_pm($mode, $subject, &$data_ary, $put_in_outbox = true)
*/
function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode = false)
{
- global $db, $user, $template, $phpbb_root_path, $phpEx, $auth;
+ global $db, $user, $template, $phpbb_root_path, $phpEx, $auth, $phpbb_dispatcher;
// Select all receipts and the author from the pm we currently view, to only display their pm-history
$sql = 'SELECT author_id, user_id
@@ -2087,7 +2087,7 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode
$previous_history_pm = $prev_id;
}
- $template->assign_block_vars('history_row', array(
+ $template_vars = array(
'MESSAGE_AUTHOR_QUOTE' => (($decoded_message) ? addslashes(get_username_string('username', $author_id, $row['username'], $row['user_colour'], $row['username'])) : ''),
'MESSAGE_AUTHOR_FULL' => get_username_string('full', $author_id, $row['username'], $row['user_colour'], $row['username']),
'MESSAGE_AUTHOR_COLOUR' => get_username_string('colour', $author_id, $row['username'], $row['user_colour'], $row['username']),
@@ -2109,8 +2109,25 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode
'USER_ID' => $row['user_id'],
'U_VIEW_MESSAGE' => "$url&amp;f=$folder_id&amp;p=" . $row['msg_id'],
'U_QUOTE' => (!$in_post_mode && $auth->acl_get('u_sendpm') && $author_id != ANONYMOUS) ? "$url&amp;mode=compose&amp;action=quote&amp;f=" . $folder_id . "&amp;p=" . $row['msg_id'] : '',
- 'U_POST_REPLY_PM' => ($author_id != $user->data['user_id'] && $author_id != ANONYMOUS && $auth->acl_get('u_sendpm')) ? "$url&amp;mode=compose&amp;action=reply&amp;f=$folder_id&amp;p=" . $row['msg_id'] : '')
+ 'U_POST_REPLY_PM' => ($author_id != $user->data['user_id'] && $author_id != ANONYMOUS && $auth->acl_get('u_sendpm')) ? "$url&amp;mode=compose&amp;action=reply&amp;f=$folder_id&amp;p=" . $row['msg_id'] : ''
);
+
+ /**
+ * Modify the template vars for displaying the message history in private message
+ *
+ * @event core.message_history_modify_template_vars
+ * @var array template_vars Array containing the query
+ * @var array row Array containing the action user row
+ * @since 3.2.8-RC1
+ */
+ $vars = array(
+ 'template_vars',
+ 'row',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.message_history_modify_template_vars', compact($vars)));
+
+ $template->assign_block_vars('history_row', $template_vars);
+
unset($rowset[$i]);
$prev_id = $id;
}
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 26bb987561..3bf4aa16b7 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -26,8 +26,10 @@ if (!defined('IN_PHPBB'))
* @param array &$user_id_ary The user ids to check or empty if usernames used
* @param array &$username_ary The usernames to check or empty if user ids used
* @param mixed $user_type Array of user types to check, false if not restricting by user type
+* @param boolean $update_references If false, the supplied array is unset and appears unchanged from where it was called
+* @return boolean|string Returns false on success, error string on failure
*/
-function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false)
+function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false, $update_references = false)
{
global $db;
@@ -50,7 +52,13 @@ function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false)
}
$sql_in = ($which_ary == 'user_id_ary') ? array_map('intval', ${$which_ary}) : array_map('utf8_clean_string', ${$which_ary});
- unset(${$which_ary});
+
+ // By unsetting the array here, the values passed in at the point user_get_id_name() was called will be retained.
+ // Otherwise, if we don't unset (as the array was passed by reference) the original array will be updated below.
+ if ($update_references === false)
+ {
+ unset(${$which_ary});
+ }
$user_id_ary = $username_ary = array();
@@ -684,7 +692,8 @@ function user_delete($mode, $user_ids, $retain_username = true)
PRIVMSGS_RULES_TABLE,
$phpbb_container->getParameter('tables.auth_provider_oauth_token_storage'),
$phpbb_container->getParameter('tables.auth_provider_oauth_states'),
- $phpbb_container->getParameter('tables.auth_provider_oauth_account_assoc')
+ $phpbb_container->getParameter('tables.auth_provider_oauth_account_assoc'),
+ $phpbb_container->getParameter('tables.user_notifications')
];
// Ignore errors on deleting from non-existent tables, e.g. when migrating
@@ -1709,17 +1718,21 @@ function phpbb_validate_timezone($timezone)
return (in_array($timezone, phpbb_get_timezone_identifiers($timezone))) ? false : 'TIMEZONE_INVALID';
}
-/**
-* Check to see if the username has been taken, or if it is disallowed.
-* Also checks if it includes the " character, which we don't allow in usernames.
-* Used for registering, changing names, and posting anonymously with a username
-*
-* @param string $username The username to check
-* @param string $allowed_username An allowed username, default being $user->data['username']
-*
-* @return mixed Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
-*/
-function validate_username($username, $allowed_username = false)
+/***
+ * Validate Username
+ *
+ * Check to see if the username has been taken, or if it is disallowed.
+ * Also checks if it includes the " character or the 4-bytes Unicode ones
+ * (aka emojis) which we don't allow in usernames.
+ * Used for registering, changing names, and posting anonymously with a username
+ *
+ * @param string $username The username to check
+ * @param string $allowed_username An allowed username, default being $user->data['username']
+ *
+ * @return mixed Either false if validation succeeded or a string which will be
+ * used as the error message (with the variable name appended)
+ */
+function validate_username($username, $allowed_username = false, $allow_all_names = false)
{
global $config, $db, $user, $cache;
@@ -1731,6 +1744,14 @@ function validate_username($username, $allowed_username = false)
return false;
}
+ // The very first check is for
+ // out-of-bounds characters that are currently
+ // not supported by utf8_bin in MySQL
+ if (preg_match('/[\x{10000}-\x{10FFFF}]/u', $username))
+ {
+ return 'INVALID_EMOJIS';
+ }
+
// ... fast checks first.
if (strpos($username, '&quot;') !== false || strpos($username, '"') !== false || empty($clean_username))
{
@@ -1794,13 +1815,16 @@ function validate_username($username, $allowed_username = false)
return 'USERNAME_TAKEN';
}
- $bad_usernames = $cache->obtain_disallowed_usernames();
-
- foreach ($bad_usernames as $bad_username)
+ if (!$allow_all_names)
{
- if (preg_match('#^' . $bad_username . '$#', $clean_username))
+ $bad_usernames = $cache->obtain_disallowed_usernames();
+
+ foreach ($bad_usernames as $bad_username)
{
- return 'USERNAME_DISALLOWED';
+ if (preg_match('#^' . $bad_username . '$#', $clean_username))
+ {
+ return 'USERNAME_DISALLOWED';
+ }
}
}
@@ -1921,9 +1945,9 @@ function validate_user_email($email, $allowed_email = false)
return $validate_email;
}
- if (($ban_reason = $user->check_ban(false, false, $email, true)) !== false)
+ if (($ban = $user->check_ban(false, false, $email, true)) !== false)
{
- return ($ban_reason === true) ? 'EMAIL_BANNED' : $ban_reason;
+ return ($ban === true) ? 'EMAIL_BANNED' : (!empty($ban['ban_give_reason']) ? $ban['ban_give_reason'] : $ban);
}
if (!$config['allow_emailreuse'])
@@ -2698,6 +2722,13 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false,
return 'NO_USER';
}
+ // Because the item that gets passed into the previous function is unset, the reference is lost and our original
+ // array is retained - so we know there's a problem if there's a different number of ids to usernames now.
+ if (count($user_id_ary) != count($username_ary))
+ {
+ return 'GROUP_USERS_INVALID';
+ }
+
// Remove users who are already members of this group
$sql = 'SELECT user_id, group_leader
FROM ' . USER_GROUP_TABLE . '
diff --git a/phpBB/includes/mcp/mcp_ban.php b/phpBB/includes/mcp/mcp_ban.php
index b878b1af0a..6f748f5433 100644
--- a/phpBB/includes/mcp/mcp_ban.php
+++ b/phpBB/includes/mcp/mcp_ban.php
@@ -34,7 +34,10 @@ class mcp_ban
}
// Include the admin banning interface...
- include($phpbb_root_path . 'includes/acp/acp_ban.' . $phpEx);
+ if (!class_exists('acp_ban'))
+ {
+ include($phpbb_root_path . 'includes/acp/acp_ban.' . $phpEx);
+ }
$bansubmit = $request->is_set_post('bansubmit');
$unbansubmit = $request->is_set_post('unbansubmit');
@@ -266,7 +269,7 @@ class mcp_ban
}
else if ($post_id)
{
- $post_info = phpbb_get_post_data($post_id, 'm_ban');
+ $post_info = phpbb_get_post_data(array($post_id), 'm_ban');
if (count($post_info) && !empty($post_info[$post_id]))
{
diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php
index aeb716c1f9..918a98734b 100644
--- a/phpBB/includes/mcp/mcp_front.php
+++ b/phpBB/includes/mcp/mcp_front.php
@@ -290,7 +290,10 @@ function mcp_front_view($id, $mode, $action)
if ($total)
{
- include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
+ if (!function_exists('get_recipient_strings'))
+ {
+ include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
+ }
$sql_ary = array(
'SELECT' => 'r.report_id, r.report_time, p.msg_id, p.message_subject, p.message_time, p.to_address, p.bcc_address, p.message_attachment, u.username, u.username_clean, u.user_colour, u.user_id, u2.username as author_name, u2.username_clean as author_name_clean, u2.user_colour as author_colour, u2.user_id as author_id',
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index a4e3a74ba7..744eaebd7d 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -41,6 +41,22 @@ class mcp_main
$quickmod = ($mode == 'quickmod') ? true : false;
+ /**
+ * Event to perform additional actions before an MCP action is executed.
+ *
+ * @event core.mcp_main_before
+ * @var string action The action that is about to be performed
+ * @var string mode The mode in which the MCP is accessed, e.g. front, forum_view, topic_view, post_details, quickmod
+ * @var boolean quickmod Whether or not the action is performed via QuickMod
+ * @since 3.2.8-RC1
+ */
+ $vars = [
+ 'action',
+ 'mode',
+ 'quickmod',
+ ];
+ extract($phpbb_dispatcher->trigger_event('core.mcp_main_before', compact($vars)));
+
switch ($action)
{
case 'lock':
@@ -174,7 +190,10 @@ class mcp_main
switch ($mode)
{
case 'front':
- include($phpbb_root_path . 'includes/mcp/mcp_front.' . $phpEx);
+ if (!function_exists('mcp_front_view'))
+ {
+ include($phpbb_root_path . 'includes/mcp/mcp_front.' . $phpEx);
+ }
$user->add_lang('acp/common');
@@ -185,7 +204,10 @@ class mcp_main
break;
case 'forum_view':
- include($phpbb_root_path . 'includes/mcp/mcp_forum.' . $phpEx);
+ if (!function_exists('mcp_forum_view'))
+ {
+ include($phpbb_root_path . 'includes/mcp/mcp_forum.' . $phpEx);
+ }
$user->add_lang('viewforum');
@@ -208,7 +230,10 @@ class mcp_main
break;
case 'topic_view':
- include($phpbb_root_path . 'includes/mcp/mcp_topic.' . $phpEx);
+ if (!function_exists('mcp_topic_view'))
+ {
+ include($phpbb_root_path . 'includes/mcp/mcp_topic.' . $phpEx);
+ }
mcp_topic_view($id, $mode, $action);
@@ -217,7 +242,10 @@ class mcp_main
break;
case 'post_details':
- include($phpbb_root_path . 'includes/mcp/mcp_post.' . $phpEx);
+ if (!function_exists('mcp_post_details'))
+ {
+ include($phpbb_root_path . 'includes/mcp/mcp_post.' . $phpEx);
+ }
mcp_post_details($id, $mode, $action);
@@ -366,7 +394,7 @@ function lock_unlock($action, $ids)
*/
function change_topic_type($action, $topic_ids)
{
- global $user, $db, $request, $phpbb_log;
+ global $user, $db, $request, $phpbb_log, $phpbb_dispatcher;
switch ($action)
{
@@ -414,6 +442,25 @@ function change_topic_type($action, $topic_ids)
if (confirm_box(true))
{
+
+ /**
+ * Perform additional actions before changing topic(s) type
+ *
+ * @event core.mcp_change_topic_type_before
+ * @var int new_topic_type The candidated topic type.
+ * @var int forum_id The forum ID for the topic ID(s).
+ * @var array topic_ids Array containing the topic ID(s) that will be changed
+ * @since 3.2.6-RC1
+ */
+ $vars = array(
+ 'new_topic_type',
+ 'forum_id',
+ 'topic_ids',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_change_topic_type_before', compact($vars)));
+
+ $db->sql_transaction('begin');
+
$sql = 'UPDATE ' . TOPICS_TABLE . "
SET topic_type = $new_topic_type
WHERE " . $db->sql_in_set('topic_id', $topic_ids);
@@ -425,13 +472,10 @@ function change_topic_type($action, $topic_ids)
$sql = 'DELETE FROM ' . TOPICS_TABLE . '
WHERE ' . $db->sql_in_set('topic_moved_id', $topic_ids);
$db->sql_query($sql);
-
- $sql = 'UPDATE ' . TOPICS_TABLE . "
- SET topic_type = $new_topic_type
- WHERE " . $db->sql_in_set('topic_id', $topic_ids);
- $db->sql_query($sql);
}
+ $db->sql_transaction('commit');
+
$success_msg = (count($topic_ids) == 1) ? 'TOPIC_TYPE_CHANGED' : 'TOPICS_TYPE_CHANGED';
if (count($topic_ids))
@@ -448,6 +492,22 @@ function change_topic_type($action, $topic_ids)
}
}
+ /**
+ * Perform additional actions after changing topic types
+ *
+ * @event core.mcp_change_topic_type_after
+ * @var int new_topic_type The newly changed topic type.
+ * @var int forum_id The forum ID where the newly changed topic type belongs to.
+ * @var array topic_ids Array containing the topic IDs that have been changed
+ * @since 3.2.6-RC1
+ */
+ $vars = array(
+ 'new_topic_type',
+ 'forum_id',
+ 'topic_ids',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.mcp_change_topic_type_after', compact($vars)));
+
meta_refresh(2, $redirect);
$message = $user->lang[$success_msg];
@@ -930,10 +990,11 @@ function mcp_delete_topic($topic_ids, $is_soft = false, $soft_delete_reason = ''
'DELETE_TOPIC_PERMANENTLY_EXPLAIN' => $user->lang('DELETE_TOPIC_PERMANENTLY', count($topic_ids)),
));
- $l_confirm = (count($topic_ids) == 1) ? 'DELETE_TOPIC' : 'DELETE_TOPICS';
+ $count = count($topic_ids);
+ $l_confirm = $count === 1 ? 'DELETE_TOPIC' : 'DELETE_TOPICS';
if ($only_softdeleted)
{
- $l_confirm .= '_PERMANENTLY';
+ $l_confirm = array($l_confirm . '_PERMANENTLY', $count);
$s_hidden_fields['delete_permanent'] = '1';
}
else if ($only_shadow || !$auth->acl_get('m_softdelete', $forum_id))
@@ -1184,10 +1245,11 @@ function mcp_delete_post($post_ids, $is_soft = false, $soft_delete_reason = '',
'DELETE_POST_PERMANENTLY_EXPLAIN' => $user->lang('DELETE_POST_PERMANENTLY', count($post_ids)),
));
- $l_confirm = (count($post_ids) == 1) ? 'DELETE_POST' : 'DELETE_POSTS';
+ $count = count($post_ids);
+ $l_confirm = $count === 1 ? 'DELETE_POST' : 'DELETE_POSTS';
if ($only_softdeleted)
{
- $l_confirm .= '_PERMANENTLY';
+ $l_confirm = array($l_confirm . '_PERMANENTLY', $count);
$s_hidden_fields['delete_permanent'] = '1';
}
else if (!$auth->acl_get('m_softdelete', $forum_id))
diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php
index 9c63245982..68a65aafdd 100644
--- a/phpBB/includes/mcp/mcp_topic.php
+++ b/phpBB/includes/mcp/mcp_topic.php
@@ -93,7 +93,11 @@ function mcp_topic_view($id, $mode, $action)
// Restore or pprove posts?
if (($action == 'restore' || $action == 'approve') && $auth->acl_get('m_approve', $topic_info['forum_id']))
{
- include($phpbb_root_path . 'includes/mcp/mcp_queue.' . $phpEx);
+ if (!class_exists('mcp_queue'))
+ {
+ include($phpbb_root_path . 'includes/mcp/mcp_queue.' . $phpEx);
+ }
+
include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php
index c12f2ab1aa..0b79cca864 100644
--- a/phpBB/includes/message_parser.php
+++ b/phpBB/includes/message_parser.php
@@ -1587,6 +1587,16 @@ class parse_message extends bbcode_firstpass
'poster_id' => $user->data['user_id'],
);
+ /**
+ * Modify attachment sql array on submit
+ *
+ * @event core.modify_attachment_sql_ary_on_submit
+ * @var array sql_ary Array containing SQL data
+ * @since 3.2.6-RC1
+ */
+ $vars = array('sql_ary');
+ extract($phpbb_dispatcher->trigger_event('core.modify_attachment_sql_ary_on_submit', compact($vars)));
+
$db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
$new_entry = array(
@@ -1722,6 +1732,16 @@ class parse_message extends bbcode_firstpass
'poster_id' => $user->data['user_id'],
);
+ /**
+ * Modify attachment sql array on upload
+ *
+ * @event core.modify_attachment_sql_ary_on_upload
+ * @var array sql_ary Array containing SQL data
+ * @since 3.2.6-RC1
+ */
+ $vars = array('sql_ary');
+ extract($phpbb_dispatcher->trigger_event('core.modify_attachment_sql_ary_on_upload', compact($vars)));
+
$db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
$new_entry = array(
diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php
index c1b623cd71..7808fed325 100644
--- a/phpBB/includes/ucp/ucp_attachments.php
+++ b/phpBB/includes/ucp/ucp_attachments.php
@@ -29,7 +29,7 @@ class ucp_attachments
function main($id, $mode)
{
- global $template, $user, $db, $config, $phpEx, $phpbb_root_path, $phpbb_container, $request;
+ global $template, $user, $db, $config, $phpEx, $phpbb_root_path, $phpbb_container, $request, $auth;
$start = $request->variable('start', 0);
$sort_key = $request->variable('sk', 'a');
@@ -41,16 +41,27 @@ class ucp_attachments
if ($delete && count($delete_ids))
{
// Validate $delete_ids...
- $sql = 'SELECT attach_id
- FROM ' . ATTACHMENTS_TABLE . '
- WHERE poster_id = ' . $user->data['user_id'] . '
- AND is_orphan = 0
- AND ' . $db->sql_in_set('attach_id', $delete_ids);
+ $sql = 'SELECT a.attach_id, p.post_edit_locked, t.topic_status, f.forum_id, f.forum_status
+ FROM ' . ATTACHMENTS_TABLE . ' a
+ LEFT JOIN ' . POSTS_TABLE . ' p
+ ON (a.post_msg_id = p.post_id AND a.in_message = 0)
+ LEFT JOIN ' . TOPICS_TABLE . ' t
+ ON (t.topic_id = p.topic_id AND a.in_message = 0)
+ LEFT JOIN ' . FORUMS_TABLE . ' f
+ ON (f.forum_id = t.forum_id AND a.in_message = 0)
+ WHERE a.poster_id = ' . $user->data['user_id'] . '
+ AND a.is_orphan = 0
+ AND ' . $db->sql_in_set('a.attach_id', $delete_ids);
$result = $db->sql_query($sql);
$delete_ids = array();
while ($row = $db->sql_fetchrow($result))
{
+ if (!$auth->acl_get('m_edit', $row['forum_id']) && ($row['forum_status'] == ITEM_LOCKED || $row['topic_status'] == ITEM_LOCKED || $row['post_edit_locked']))
+ {
+ continue;
+ }
+
$delete_ids[] = $row['attach_id'];
}
$db->sql_freeresult($result);
@@ -124,10 +135,12 @@ class ucp_attachments
$pagination = $phpbb_container->get('pagination');
$start = $pagination->validate_start($start, $config['topics_per_page'], $num_attachments);
- $sql = 'SELECT a.*, t.topic_title, p.message_subject as message_title
+ $sql = 'SELECT a.*, t.topic_title, pr.message_subject as message_title, p.post_edit_locked, t.topic_status, f.forum_id, f.forum_status
FROM ' . ATTACHMENTS_TABLE . ' a
+ LEFT JOIN ' . POSTS_TABLE . ' p ON (a.post_msg_id = p.post_id AND a.in_message = 0)
LEFT JOIN ' . TOPICS_TABLE . ' t ON (a.topic_id = t.topic_id AND a.in_message = 0)
- LEFT JOIN ' . PRIVMSGS_TABLE . ' p ON (a.post_msg_id = p.msg_id AND a.in_message = 1)
+ LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = t.forum_id AND a.in_message = 0)
+ LEFT JOIN ' . PRIVMSGS_TABLE . ' pr ON (a.post_msg_id = pr.msg_id AND a.in_message = 1)
WHERE a.poster_id = ' . $user->data['user_id'] . "
AND a.is_orphan = 0
ORDER BY $order_by";
@@ -164,6 +177,7 @@ class ucp_attachments
'TOPIC_ID' => $row['topic_id'],
'S_IN_MESSAGE' => $row['in_message'],
+ 'S_LOCKED' => !$row['in_message'] && !$auth->acl_get('m_edit', $row['forum_id']) && ($row['forum_status'] == ITEM_LOCKED || $row['topic_status'] == ITEM_LOCKED || $row['post_edit_locked']),
'U_VIEW_ATTACHMENT' => append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $row['attach_id']),
'U_VIEW_TOPIC' => $view_topic)
diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php
index 1fb026167a..2423af86be 100644
--- a/phpBB/includes/ucp/ucp_groups.php
+++ b/phpBB/includes/ucp/ucp_groups.php
@@ -32,6 +32,9 @@ class ucp_groups
global $db, $user, $auth, $cache, $template;
global $request, $phpbb_container, $phpbb_log;
+ /** @var \phpbb\language\language $language Language object */
+ $language = $phpbb_container->get('language');
+
$user->add_lang('groups');
$return_page = '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $this->u_action . '">', '</a>');
@@ -396,7 +399,10 @@ class ucp_groups
$action = (isset($_POST['addusers'])) ? 'addusers' : $request->variable('action', '');
$group_id = $request->variable('g', 0);
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ if (!function_exists('phpbb_get_user_rank'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
add_form_key('ucp_groups');
@@ -1054,13 +1060,27 @@ class ucp_groups
if (confirm_box(true))
{
+ $return_manage_page = '<br /><br />' . $language->lang('RETURN_PAGE', '<a href="' . $this->u_action . '&amp;action=list&amp;g=' . $group_id . '">', '</a>');
+
// Add user/s to group
if ($error = group_user_add($group_id, false, $name_ary, $group_name, $default, 0, 0, $group_row))
{
- trigger_error($user->lang[$error] . $return_page);
+ $display_message = $language->lang($error);
+
+ if ($error == 'GROUP_USERS_INVALID')
+ {
+ // Find which users don't exist
+ $actual_name_ary = $name_ary;
+ $actual_user_id_ary = [];
+ user_get_id_name($actual_user_id_ary, $actual_name_ary, false, true);
+
+ $display_message = $language->lang('GROUP_USERS_INVALID', implode($language->lang('COMMA_SEPARATOR'), array_udiff($name_ary, $actual_name_ary, 'strcasecmp')));
+ }
+
+ trigger_error($display_message . $return_manage_page);
}
- trigger_error($user->lang['GROUP_USERS_ADDED'] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $this->u_action . '&amp;action=list&amp;g=' . $group_id . '">', '</a>'));
+ trigger_error($language->lang('GROUP_USERS_ADDED') . $return_manage_page);
}
else
{
diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php
index 5214de8c7c..36f45f3f46 100644
--- a/phpBB/includes/ucp/ucp_main.php
+++ b/phpBB/includes/ucp/ucp_main.php
@@ -245,7 +245,10 @@ class ucp_main
case 'subscribed':
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ if (!function_exists('topic_status'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
$user->add_lang('viewforum');
@@ -481,7 +484,10 @@ class ucp_main
break;
}
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ if (!function_exists('topic_status'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
$user->add_lang('viewforum');
diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php
index fa374c15c8..4d02620e89 100644
--- a/phpBB/includes/ucp/ucp_pm.php
+++ b/phpBB/includes/ucp/ucp_pm.php
@@ -82,7 +82,10 @@ class ucp_pm
$mode = 'view';
}
- include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
+ if (!function_exists('get_folder'))
+ {
+ include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
+ }
switch ($mode)
{
@@ -104,7 +107,10 @@ class ucp_pm
break;
}
- include($phpbb_root_path . 'includes/ucp/ucp_pm_compose.' . $phpEx);
+ if (!function_exists('compose_pm'))
+ {
+ include($phpbb_root_path . 'includes/ucp/ucp_pm_compose.' . $phpEx);
+ }
compose_pm($id, $mode, $action, $user_folders);
$tpl_file = 'posting_body';
@@ -114,7 +120,10 @@ class ucp_pm
set_user_message_limit();
get_folder($user->data['user_id']);
- include($phpbb_root_path . 'includes/ucp/ucp_pm_options.' . $phpEx);
+ if (!function_exists('message_options'))
+ {
+ include($phpbb_root_path . 'includes/ucp/ucp_pm_options.' . $phpEx);
+ }
message_options($id, $mode, $global_privmsgs_rules, $global_rule_conditions);
$tpl_file = 'ucp_pm_options';
@@ -125,8 +134,10 @@ class ucp_pm
get_folder($user->data['user_id']);
$this->p_name = 'pm';
- // Call another module... please do not try this at home... Hoochie Coochie Man
- include($phpbb_root_path . 'includes/ucp/ucp_main.' . $phpEx);
+ if (!class_exists('ucp_main'))
+ {
+ include($phpbb_root_path . 'includes/ucp/ucp_main.' . $phpEx);
+ }
$module = new ucp_main($this);
$module->u_action = $this->u_action;
@@ -375,7 +386,10 @@ class ucp_pm
if ($action == 'view_folder')
{
- include($phpbb_root_path . 'includes/ucp/ucp_pm_viewfolder.' . $phpEx);
+ if (!function_exists('view_folder'))
+ {
+ include($phpbb_root_path . 'includes/ucp/ucp_pm_viewfolder.' . $phpEx);
+ }
view_folder($id, $mode, $folder_id, $folder);
$tpl_file = 'ucp_pm_viewfolder';
@@ -393,7 +407,10 @@ class ucp_pm
trigger_error('NO_MESSAGE');
}
- include($phpbb_root_path . 'includes/ucp/ucp_pm_viewmessage.' . $phpEx);
+ if (!function_exists('view_message'))
+ {
+ include($phpbb_root_path . 'includes/ucp/ucp_pm_viewmessage.' . $phpEx);
+ }
view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row);
$tpl_file = ($view == 'print') ? 'ucp_pm_viewmessage_print' : 'ucp_pm_viewmessage';
diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php
index 621a945479..cb45112b01 100644
--- a/phpBB/includes/ucp/ucp_pm_compose.php
+++ b/phpBB/includes/ucp/ucp_pm_compose.php
@@ -33,9 +33,20 @@ function compose_pm($id, $mode, $action, $user_folders = array())
// Needed for handle_message_list_actions()
global $refresh, $submit, $preview;
- include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
- include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
+ if (!function_exists('generate_smilies'))
+ {
+ include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
+ }
+
+ if (!function_exists('display_custom_bbcodes'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
+
+ if (!class_exists('parse_message'))
+ {
+ include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
+ }
if (!$action)
{
@@ -996,6 +1007,16 @@ function compose_pm($id, $mode, $action, $user_folders = array())
if (($action == 'reply' || $action == 'quote' || $action == 'quotepost') && !$preview && !$refresh)
{
$message_subject = ((!preg_match('/^Re:/', $message_subject)) ? 'Re: ' : '') . censor_text($message_subject);
+
+ /**
+ * This event allows you to modify the PM subject of the PM being quoted
+ *
+ * @event core.pm_modify_message_subject
+ * @var string message_subject String with the PM subject already censored.
+ * @since 3.2.8-RC1
+ */
+ $vars = array('message_subject');
+ extract($phpbb_dispatcher->trigger_event('core.pm_modify_message_subject', compact($vars)));
}
if ($action == 'forward' && !$preview && !$refresh && !$submit)
diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php
index 2acc528b9f..09e7bf4d7c 100644
--- a/phpBB/includes/ucp/ucp_pm_viewfolder.php
+++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php
@@ -39,7 +39,7 @@ function view_folder($id, $mode, $folder_id, $folder)
// Grab icons
$icons = $cache->obtain_icons();
- $color_rows = array('marked', 'replied');
+ $color_rows = array('message_reported', 'marked', 'replied');
$_module = new p_master();
$_module->list_modules('ucp');
@@ -138,9 +138,9 @@ function view_folder($id, $mode, $folder_id, $folder)
$row_indicator = '';
foreach ($color_rows as $var)
{
- if (($var != 'friend' && $var != 'foe' && $row['pm_' . $var])
+ if (($var !== 'friend' && $var !== 'foe' && $row[($var === 'message_reported') ? $var : "pm_{$var}"])
||
- (($var == 'friend' || $var == 'foe') && isset(${$var}[$row['author_id']]) && ${$var}[$row['author_id']]))
+ (($var === 'friend' || $var === 'foe') && isset(${$var}[$row['author_id']]) && ${$var}[$row['author_id']]))
{
$row_indicator = $var;
break;
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index a36bf619f8..36ab3d0463 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -133,7 +133,6 @@ class ucp_profile
'user_email' => ($auth->acl_get('u_chgemail')) ? $data['email'] : $user->data['user_email'],
'user_email_hash' => ($auth->acl_get('u_chgemail')) ? phpbb_email_hash($data['email']) : $user->data['user_email_hash'],
'user_password' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? $passwords_manager->hash($data['new_password']) : $user->data['user_password'],
- 'user_passchg' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? time() : 0,
);
if ($auth->acl_get('u_chgname') && $config['allow_namechange'] && $data['username'] != $user->data['username'])
@@ -147,6 +146,8 @@ class ucp_profile
if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && !$passwords_manager->check($data['new_password'], $user->data['user_password']))
{
+ $sql_ary['user_passchg'] = time();
+
$user->reset_login_keys();
$phpbb_log->add('user', $user->data['user_id'], $user->ip, 'LOG_USER_NEW_PASSWORD', false, array(
'reportee_id' => $user->data['user_id'],
@@ -469,8 +470,15 @@ class ucp_profile
trigger_error('NO_AUTH_SIGNATURE');
}
- include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ if (!function_exists('generate_smilies'))
+ {
+ include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
+ }
+
+ if (!function_exists('display_custom_bbcodes'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
$preview = $request->is_set_post('preview');
diff --git a/phpBB/index.php b/phpBB/index.php
index 4e37782206..5eee7723a9 100644
--- a/phpBB/index.php
+++ b/phpBB/index.php
@@ -55,6 +55,17 @@ if (($mark_notification = $request->variable('mark_notification', 0)))
$notification->mark_read();
+ /**
+ * You can use this event to perform additional tasks or redirect user elsewhere.
+ *
+ * @event core.index_mark_notification_after
+ * @var int mark_notification Notification ID
+ * @var \phpbb\notification\type\type_interface notification Notification instance
+ * @since 3.2.6-RC1
+ */
+ $vars = array('mark_notification', 'notification');
+ extract($phpbb_dispatcher->trigger_event('core.index_mark_notification_after', compact($vars)));
+
if ($request->is_ajax())
{
$json_response = new \phpbb\json_response();
@@ -200,6 +211,9 @@ if ($show_birthdays)
$template->assign_block_vars_array('birthdays', $birthdays);
}
+// Add form token for login box
+add_form_key('login', '_LOGIN');
+
// Assign index specific vars
$template->assign_vars(array(
'TOTAL_POSTS' => $user->lang('TOTAL_POSTS_COUNT', (int) $config['num_posts']),
diff --git a/phpBB/install/app.php b/phpBB/install/app.php
index ef59689a65..710f49570b 100644
--- a/phpBB/install/app.php
+++ b/phpBB/install/app.php
@@ -20,9 +20,9 @@ define('PHPBB_ENVIRONMENT', 'production');
$phpbb_root_path = '../';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
-if (version_compare(PHP_VERSION, '5.4') < 0)
+if (version_compare(PHP_VERSION, '5.4.7', '<') || version_compare(PHP_VERSION, '7.3-dev', '>='))
{
- die('You are running an unsupported PHP version. Please upgrade to PHP 5.4.0 or higher before trying to install or update to phpBB 3.2');
+ die('You are running an unsupported PHP version. Please upgrade to PHP equal to or greater than 5.4.7 but less than 7.3-dev in order to install or update to phpBB 3.2');
}
$startup_new_path = $phpbb_root_path . 'install/update/update/new/install/startup.' . $phpEx;
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php
index 2b4da2bb7f..230b999c87 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.2.5',
+ 'phpbb_version' => '3.2.7',
'author' => '<a href="https://www.phpbb.com/">phpBB Limited</a>',
'dbms' => $dbms,
'dbhost' => $dbhost,
diff --git a/phpBB/install/phpbbcli.php b/phpBB/install/phpbbcli.php
index f6893f0944..217f1dfbd4 100755
--- a/phpBB/install/phpbbcli.php
+++ b/phpBB/install/phpbbcli.php
@@ -23,7 +23,7 @@ if (php_sapi_name() !== 'cli')
define('IN_PHPBB', true);
define('IN_INSTALL', true);
define('PHPBB_ENVIRONMENT', 'production');
-define('PHPBB_VERSION', '3.2.5');
+define('PHPBB_VERSION', '3.2.7');
$phpbb_root_path = __DIR__ . '/../';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index 2a032bb991..71000e64d7 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -269,9 +269,9 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('smilies_per_page',
INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_auth_method', 'PLAIN');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_delivery', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_host', '');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_password', '');
+INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('smtp_password', '', 1);
INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_port', '25');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_username', '');
+INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('smtp_username', '', 1);
INSERT INTO phpbb_config (config_name, config_value) VALUES ('teampage_memberships', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('teampage_forums', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('topics_per_page', '25');
@@ -279,7 +279,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.2.6-dev');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.2.8-dev');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400');
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index eb53ac0370..9b637ff9d3 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -44,7 +44,7 @@ $lang = array_merge($lang, array(
'BOARD_STYLE' => 'Board style',
'CUSTOM_DATEFORMAT' => 'Custom…',
'DEFAULT_DATE_FORMAT' => 'Date format',
- 'DEFAULT_DATE_FORMAT_EXPLAIN' => 'The date format is the same as the PHP <code>date</code> function.',
+ 'DEFAULT_DATE_FORMAT_EXPLAIN' => 'The date format is the same as the PHP <code><a href="https://secure.php.net/manual/function.date.php">date()</a></code> function.',
'DEFAULT_LANGUAGE' => 'Default language',
'DEFAULT_STYLE' => 'Default style',
'DEFAULT_STYLE_EXPLAIN' => 'The default style for new users.',
@@ -111,9 +111,9 @@ $lang = array_merge($lang, array(
'ALLOW_GRAVATAR' => 'Enable gravatar avatars',
'ALLOW_LOCAL' => 'Enable gallery avatars',
'ALLOW_REMOTE' => 'Enable remote avatars',
- 'ALLOW_REMOTE_EXPLAIN' => 'Avatars linked to from another website.',
+ 'ALLOW_REMOTE_EXPLAIN' => 'Avatars linked to from another website.<br><em><strong class="error">Warning:</strong> Enabling this feature might allow users to check for the existence of files and services that are only accessible on the local network.</em>',
'ALLOW_REMOTE_UPLOAD' => 'Enable remote avatar uploading',
- 'ALLOW_REMOTE_UPLOAD_EXPLAIN' => 'Allow uploading of avatars from another website.',
+ 'ALLOW_REMOTE_UPLOAD_EXPLAIN' => 'Allow uploading of avatars from another website.<br><em><strong class="error">Warning:</strong> Enabling this feature might allow users to check for the existence of files and services that are only accessible on the local network.</em>',
'ALLOW_UPLOAD' => 'Enable avatar uploading',
'AVATAR_GALLERY_PATH' => 'Avatar gallery path',
'AVATAR_GALLERY_PATH_EXPLAIN' => 'Path under your phpBB root directory for pre-loaded images, e.g. <samp>images/avatars/gallery</samp>.<br>Double dots like <samp>../</samp> will be stripped from the path for security reasons.',
@@ -587,8 +587,8 @@ $lang = array_merge($lang, array(
'SMTP_POP_BEFORE_SMTP' => 'POP-BEFORE-SMTP',
'SMTP_PORT' => 'SMTP server port',
'SMTP_PORT_EXPLAIN' => 'Only change this if you know your SMTP server is on a different port.',
- 'SMTP_SERVER' => 'SMTP server address and protocol',
- 'SMTP_SERVER_EXPLAIN' => 'Note that you have to provide the protocol that your server uses. If you are using SSL, this has to be "ssl://your.mailserver.com"',
+ 'SMTP_SERVER' => 'SMTP server address',
+ 'SMTP_SERVER_EXPLAIN' => 'Do not provide a protocol (<samp>ssl://</samp> or <samp>tsl://</samp>) unless your mail host tells you to do so.',
'SMTP_SETTINGS' => 'SMTP settings',
'SMTP_USERNAME' => 'SMTP username',
'SMTP_USERNAME_EXPLAIN' => 'Only enter a username if your SMTP server requires it.',
diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index 0d5f6fee25..1c2253542c 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -325,6 +325,7 @@ $lang = array_merge($lang, array(
'TOTAL_SIZE' => 'Total size',
'UCP' => 'User Control Panel',
+ 'URL_INVALID' => 'The provided URL for the setting “%1$s” is invalid.',
'USERNAMES_EXPLAIN' => 'Place each username on a separate line.',
'USER_CONTROL_PANEL' => 'User Control Panel',
diff --git a/phpBB/language/en/acp/database.php b/phpBB/language/en/acp/database.php
index ab85701eaa..302aaee570 100644
--- a/phpBB/language/en/acp/database.php
+++ b/phpBB/language/en/acp/database.php
@@ -38,14 +38,15 @@ if (empty($lang) || !is_array($lang))
// Database Backup/Restore
$lang = array_merge($lang, array(
- 'ACP_BACKUP_EXPLAIN' => 'Here you can backup all your phpBB related data. You may store the resulting archive in your <samp>store/</samp> folder or download it directly. Depending on your server configuration you may be able to compress the file in a number of formats.',
+ 'ACP_BACKUP_EXPLAIN' => 'Here you can backup all your phpBB related data. The resulting archive will be stored in your <samp>store/</samp> folder. Depending on your server configuration you may be able to compress the file in a number of formats.',
'ACP_RESTORE_EXPLAIN' => 'This will perform a full restore of all phpBB tables from a saved file. If your server supports it you may use a gzip or bzip2 compressed text file and it will automatically be decompressed. <strong>WARNING</strong> This will overwrite any existing data. The restore may take a long time to process please do not move from this page till it is complete. Backups are stored in the <samp>store/</samp> folder and are assumed to be generated by phpBB’s backup functionality. Restoring backups that were not created by the built in system may or may not work.',
- 'BACKUP_DELETE' => 'The backup file has been deleted successfully.',
- 'BACKUP_INVALID' => 'The selected file to backup is invalid.',
- 'BACKUP_OPTIONS' => 'Backup options',
- 'BACKUP_SUCCESS' => 'The backup file has been created successfully.',
- 'BACKUP_TYPE' => 'Backup type',
+ 'BACKUP_DELETE' => 'The backup file has been deleted successfully.',
+ 'BACKUP_INVALID' => 'The selected file to backup is invalid.',
+ 'BACKUP_NOT_SUPPORTED' => 'The selected backup is not supported',
+ 'BACKUP_OPTIONS' => 'Backup options',
+ 'BACKUP_SUCCESS' => 'The backup file has been created successfully.',
+ 'BACKUP_TYPE' => 'Backup type',
'DATABASE' => 'Database utilities',
'DATA_ONLY' => 'Data only',
diff --git a/phpBB/language/en/acp/forums.php b/phpBB/language/en/acp/forums.php
index 7a7176369f..d92d3f8c9e 100644
--- a/phpBB/language/en/acp/forums.php
+++ b/phpBB/language/en/acp/forums.php
@@ -97,6 +97,7 @@ $lang = array_merge($lang, array(
'FORUM_LINK_TRACK_EXPLAIN' => 'Records the number of times a forum link was clicked.',
'FORUM_NAME' => 'Forum name',
'FORUM_NAME_EMPTY' => 'You must enter a name for this forum.',
+ 'FORUM_NAME_EMOJI' => 'The forum name you entered is invalid.<br>It contains the following unsupported characters:<br>%s',
'FORUM_PARENT' => 'Parent forum',
'FORUM_PASSWORD' => 'Forum password',
'FORUM_PASSWORD_CONFIRM' => 'Confirm forum password',
diff --git a/phpBB/language/en/acp/groups.php b/phpBB/language/en/acp/groups.php
index c3a5ae9e44..5d68132a34 100644
--- a/phpBB/language/en/acp/groups.php
+++ b/phpBB/language/en/acp/groups.php
@@ -111,6 +111,7 @@ $lang = array_merge($lang, array(
'GROUP_USERS_ADDED' => 'New users added to group successfully.',
'GROUP_USERS_EXIST' => 'The selected users are already members.',
'GROUP_USERS_REMOVE' => 'Users removed from group and new defaults set successfully.',
+ 'GROUP_USERS_INVALID' => 'No users were added to the group as the following usernames do not exist: %s',
'LEGEND_EXPLAIN' => 'These are the groups which are displayed in the group legend:',
'LEGEND_SETTINGS' => 'Legend settings',
diff --git a/phpBB/language/en/acp/permissions_phpbb.php b/phpBB/language/en/acp/permissions_phpbb.php
index 64740b311b..2c7b3d3aee 100644
--- a/phpBB/language/en/acp/permissions_phpbb.php
+++ b/phpBB/language/en/acp/permissions_phpbb.php
@@ -81,8 +81,8 @@ $lang = array_merge($lang, array(
'ACL_U_SIG' => 'Can use signature',
'ACL_U_SENDPM' => 'Can send private messages',
- 'ACL_U_MASSPM' => 'Can send messages to multiple users',
- 'ACL_U_MASSPM_GROUP'=> 'Can send messages to groups',
+ 'ACL_U_MASSPM' => 'Can send private messages to multiple users',
+ 'ACL_U_MASSPM_GROUP'=> 'Can send private messages to groups',
'ACL_U_READPM' => 'Can read private messages',
'ACL_U_PM_EDIT' => 'Can edit own private messages',
'ACL_U_PM_DELETE' => 'Can remove private messages from own folder',
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index a037c5bfe8..835030762c 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -780,6 +780,10 @@ $lang = array_merge($lang, array(
'TOPIC_REVIEW' => 'Topic review',
'TOPIC_TITLE' => 'Topic title',
'TOPIC_UNAPPROVED' => 'This topic has not been approved.',
+ 'TOPIC_UNAPPROVED_FORUM' => array(
+ 1 => 'Topic awaiting approval',
+ 2 => 'Topics awaiting approval',
+ ),
'TOPIC_DELETED' => 'This topic has been deleted.',
'TOTAL_ATTACHMENTS' => 'Attachment(s)',
'TOTAL_LOGS' => array(
diff --git a/phpBB/language/en/email/admin_activate.txt b/phpBB/language/en/email/admin_activate.txt
index a53ab1269e..71faca70b2 100644
--- a/phpBB/language/en/email/admin_activate.txt
+++ b/phpBB/language/en/email/admin_activate.txt
@@ -7,7 +7,7 @@ The account owned by "{USERNAME}" has been deactivated or newly created, you sho
Use this link to view the user's profile:
{U_USER_DETAILS}
-Use this link to activate the account:
+You may activate the account immediately by clicking on this link:
{U_ACTIVATE}
{EMAIL_SIG}
diff --git a/phpBB/language/en/email/report_pm.txt b/phpBB/language/en/email/report_pm.txt
index a101a014ff..a6b8086a9a 100644
--- a/phpBB/language/en/email/report_pm.txt
+++ b/phpBB/language/en/email/report_pm.txt
@@ -1,4 +1,4 @@
-Subject: Private Message report - "{TOPIC_TITLE}"
+Subject: Private Message report - "{SUBJECT}"
Hello {USERNAME},
diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php
index 7c415b3457..11ea6483e1 100644
--- a/phpBB/language/en/posting.php
+++ b/phpBB/language/en/posting.php
@@ -145,6 +145,7 @@ $lang = array_merge($lang, array(
'LOAD_DRAFT_EXPLAIN' => 'Here you are able to select the draft you want to continue writing. Your current post will be cancelled, all current post contents will be deleted. View, edit and delete drafts within your User Control Panel.',
'LOGIN_EXPLAIN_BUMP' => 'You need to login in order to bump topics within this forum.',
'LOGIN_EXPLAIN_DELETE' => 'You need to login in order to delete posts within this forum.',
+ 'LOGIN_EXPLAIN_SOFT_DELETE' => 'You need to login in order to soft-delete posts within this forum.',
'LOGIN_EXPLAIN_POST' => 'You need to login in order to post within this forum.',
'LOGIN_EXPLAIN_QUOTE' => 'You need to login in order to quote posts within this forum.',
'LOGIN_EXPLAIN_REPLY' => 'You need to login in order to reply to topics within this forum.',
diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php
index 5875099fb8..8549230b9f 100644
--- a/phpBB/language/en/ucp.php
+++ b/phpBB/language/en/ucp.php
@@ -89,6 +89,7 @@ $lang = array_merge($lang, array(
'ATTACHMENTS_EXPLAIN' => 'This is a list of attachments you have made in posts to this board.',
'ATTACHMENTS_DELETED' => 'Attachments successfully deleted.',
'ATTACHMENT_DELETED' => 'Attachment successfully deleted.',
+ 'ATTACHMENT_LOCKED' => 'This topic is locked, you cannot delete the attachment.',
'AUTOLOGIN_SESSION_KEYS_DELETED'=> 'The selected "Remember Me" login keys were successfully deleted.',
'AVATAR_CATEGORY' => 'Category',
'AVATAR_DRIVER_GRAVATAR_TITLE' => 'Gravatar',
@@ -115,7 +116,7 @@ $lang = array_merge($lang, array(
'BIRTHDAY' => 'Birthday',
'BIRTHDAY_EXPLAIN' => 'Setting a year will list your age when it is your birthday.',
'BOARD_DATE_FORMAT' => 'My date format',
- 'BOARD_DATE_FORMAT_EXPLAIN' => 'The syntax used is identical to the PHP <a href="http://www.php.net/date">date()</a> function.',
+ 'BOARD_DATE_FORMAT_EXPLAIN' => 'The syntax used is identical to the PHP <a href="https://secure.php.net/manual/function.date.php">date()</a> function.',
'BOARD_LANGUAGE' => 'My language',
'BOARD_STYLE' => 'My board style',
'BOARD_TIMEZONE' => 'My timezone',
@@ -272,6 +273,7 @@ $lang = array_merge($lang, array(
'IMPORTANT_NEWS' => 'Important announcements',
'INVALID_USER_BIRTHDAY' => 'The entered birthday is not a valid date.',
'INVALID_CHARS_USERNAME' => 'The username contains forbidden characters.',
+ 'INVALID_EMOJIS_USERNAME' => 'The username contains forbidden characters (Emoji).',
'INVALID_CHARS_NEW_PASSWORD'=> 'The password does not contain the required characters.',
'ITEMS_REQUIRED' => 'The items marked with * are required profile fields and need to be filled out.',
@@ -302,6 +304,7 @@ $lang = array_merge($lang, array(
'MESSAGE_EDITED' => 'Message successfully edited.',
'MESSAGE_HISTORY' => 'Message history',
'MESSAGE_REMOVED_FROM_OUTBOX' => 'This message was deleted by its author.',
+ 'MESSAGE_REPORTED_MESSAGE' => 'Reported message',
'MESSAGE_SENT_ON' => 'on',
'MESSAGE_STORED' => 'This message has been sent successfully.',
'MESSAGE_TO' => 'To',
diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php
index ecc699f1c4..8f4d54b2c7 100644
--- a/phpBB/memberlist.php
+++ b/phpBB/memberlist.php
@@ -763,42 +763,58 @@ switch ($mode)
$member['posts_in_queue'] = 0;
}
- $template->assign_vars(array(
- 'L_POSTS_IN_QUEUE' => $user->lang('NUM_POSTS_IN_QUEUE', $member['posts_in_queue']),
-
- 'POSTS_DAY' => $user->lang('POST_DAY', $posts_per_day),
- 'POSTS_PCT' => $user->lang('POST_PCT', $percentage),
-
- 'SIGNATURE' => $member['user_sig'],
- 'POSTS_IN_QUEUE'=> $member['posts_in_queue'],
-
- 'PM_IMG' => $user->img('icon_contact_pm', $user->lang['SEND_PRIVATE_MESSAGE']),
- 'L_SEND_EMAIL_USER' => $user->lang('SEND_EMAIL_USER', $member['username']),
- 'EMAIL_IMG' => $user->img('icon_contact_email', $user->lang['EMAIL']),
- 'JABBER_IMG' => $user->img('icon_contact_jabber', $user->lang['JABBER']),
- 'SEARCH_IMG' => $user->img('icon_user_search', $user->lang['SEARCH']),
-
- 'S_PROFILE_ACTION' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group'),
- 'S_GROUP_OPTIONS' => $group_options,
- 'S_CUSTOM_FIELDS' => (isset($profile_fields['row']) && count($profile_fields['row'])) ? true : false,
-
- 'U_USER_ADMIN' => ($auth->acl_get('a_user')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&amp;mode=overview&amp;u=' . $user_id, true, $user->session_id) : '',
- 'U_USER_BAN' => ($auth->acl_get('m_ban') && $user_id != $user->data['user_id']) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=ban&amp;mode=user&amp;u=' . $user_id, true, $user->session_id) : '',
- 'U_MCP_QUEUE' => ($auth->acl_getf_global('m_approve')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue', true, $user->session_id) : '',
-
- 'U_SWITCH_PERMISSIONS' => ($auth->acl_get('a_switchperm') && $user->data['user_id'] != $user_id) ? append_sid("{$phpbb_root_path}ucp.$phpEx", "mode=switch_perm&amp;u={$user_id}&amp;hash=" . generate_link_hash('switchperm')) : '',
- 'U_EDIT_SELF' => ($user_id == $user->data['user_id'] && $auth->acl_get('u_chgprofileinfo')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_profile&amp;mode=profile_info') : '',
+ // Define the main array of vars to assign to memberlist_view.html
+ $template_ary = array(
+ 'L_POSTS_IN_QUEUE' => $user->lang('NUM_POSTS_IN_QUEUE', $member['posts_in_queue']),
+
+ 'POSTS_DAY' => $user->lang('POST_DAY', $posts_per_day),
+ 'POSTS_PCT' => $user->lang('POST_PCT', $percentage),
+
+ 'SIGNATURE' => $member['user_sig'],
+ 'POSTS_IN_QUEUE' => $member['posts_in_queue'],
+
+ 'PM_IMG' => $user->img('icon_contact_pm', $user->lang['SEND_PRIVATE_MESSAGE']),
+ 'L_SEND_EMAIL_USER' => $user->lang('SEND_EMAIL_USER', $member['username']),
+ 'EMAIL_IMG' => $user->img('icon_contact_email', $user->lang['EMAIL']),
+ 'JABBER_IMG' => $user->img('icon_contact_jabber', $user->lang['JABBER']),
+ 'SEARCH_IMG' => $user->img('icon_user_search', $user->lang['SEARCH']),
+
+ 'S_PROFILE_ACTION' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group'),
+ 'S_GROUP_OPTIONS' => $group_options,
+ 'S_CUSTOM_FIELDS' => (isset($profile_fields['row']) && count($profile_fields['row'])) ? true : false,
+
+ 'U_USER_ADMIN' => ($auth->acl_get('a_user')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&amp;mode=overview&amp;u=' . $user_id, true, $user->session_id) : '',
+ 'U_USER_BAN' => ($auth->acl_get('m_ban') && $user_id != $user->data['user_id']) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=ban&amp;mode=user&amp;u=' . $user_id, true, $user->session_id) : '',
+ 'U_MCP_QUEUE' => ($auth->acl_getf_global('m_approve')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue', true, $user->session_id) : '',
+
+ 'U_SWITCH_PERMISSIONS' => ($auth->acl_get('a_switchperm') && $user->data['user_id'] != $user_id) ? append_sid("{$phpbb_root_path}ucp.$phpEx", "mode=switch_perm&amp;u={$user_id}&amp;hash=" . generate_link_hash('switchperm')) : '',
+ 'U_EDIT_SELF' => ($user_id == $user->data['user_id'] && $auth->acl_get('u_chgprofileinfo')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_profile&amp;mode=profile_info') : '',
+
+ 'S_USER_NOTES' => ($user_notes_enabled) ? true : false,
+ 'S_WARN_USER' => ($warn_user_enabled) ? true : false,
+ 'S_ZEBRA' => ($user->data['user_id'] != $user_id && $user->data['is_registered'] && $zebra_enabled) ? true : false,
+ 'U_ADD_FRIEND' => (!$friend && !$foe && $friends_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;add=' . urlencode(htmlspecialchars_decode($member['username']))) : '',
+ 'U_ADD_FOE' => (!$friend && !$foe && $foes_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;mode=foes&amp;add=' . urlencode(htmlspecialchars_decode($member['username']))) : '',
+ 'U_REMOVE_FRIEND' => ($friend && $friends_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;remove=1&amp;usernames[]=' . $user_id) : '',
+ 'U_REMOVE_FOE' => ($foe && $foes_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;remove=1&amp;mode=foes&amp;usernames[]=' . $user_id) : '',
+
+ 'U_CANONICAL' => generate_board_url() . '/' . append_sid("memberlist.$phpEx", 'mode=viewprofile&amp;u=' . $user_id, true, ''),
+ );
- 'S_USER_NOTES' => ($user_notes_enabled) ? true : false,
- 'S_WARN_USER' => ($warn_user_enabled) ? true : false,
- 'S_ZEBRA' => ($user->data['user_id'] != $user_id && $user->data['is_registered'] && $zebra_enabled) ? true : false,
- 'U_ADD_FRIEND' => (!$friend && !$foe && $friends_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;add=' . urlencode(htmlspecialchars_decode($member['username']))) : '',
- 'U_ADD_FOE' => (!$friend && !$foe && $foes_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;mode=foes&amp;add=' . urlencode(htmlspecialchars_decode($member['username']))) : '',
- 'U_REMOVE_FRIEND' => ($friend && $friends_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;remove=1&amp;usernames[]=' . $user_id) : '',
- 'U_REMOVE_FOE' => ($foe && $foes_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;remove=1&amp;mode=foes&amp;usernames[]=' . $user_id) : '',
+ /**
+ * Modify user's template vars before we display the profile
+ *
+ * @event core.memberlist_modify_view_profile_template_vars
+ * @var array template_ary Array with user's template vars
+ * @since 3.2.6-RC1
+ */
+ $vars = array(
+ 'template_ary',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_view_profile_template_vars', compact($vars)));
- 'U_CANONICAL' => generate_board_url() . '/' . append_sid("memberlist.$phpEx", 'mode=viewprofile&amp;u=' . $user_id, true, ''),
- ));
+ // Assign vars to memberlist_view.html
+ $template->assign_vars($template_ary);
if (!empty($profile_fields['row']))
{
@@ -1369,11 +1385,6 @@ switch ($mode)
}
$sort_params[] = "mode=$mode";
- $pagination_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", implode('&amp;', $params));
- $sort_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", implode('&amp;', $sort_params));
-
- unset($search_params, $sort_params);
-
$u_first_char_params = implode('&amp;', $u_first_char_params);
$u_first_char_params .= ($u_first_char_params) ? '&amp;' : '';
@@ -1385,16 +1396,47 @@ switch ($mode)
}
$first_characters['other'] = $user->lang['OTHER'];
+ $first_char_block_vars = [];
+
foreach ($first_characters as $char => $desc)
{
- $template->assign_block_vars('first_char', array(
+ $first_char_block_vars[] = [
'DESC' => $desc,
'VALUE' => $char,
'S_SELECTED' => ($first_char == $char) ? true : false,
'U_SORT' => append_sid("{$phpbb_root_path}memberlist.$phpEx", $u_first_char_params . 'first_char=' . $char) . '#memberlist',
- ));
+ ];
}
+ /**
+ * Modify memberlist sort and pagination parameters
+ *
+ * @event core.memberlist_modify_sort_pagination_params
+ * @var array sort_params Array with URL parameters for sorting
+ * @var array params Array with URL parameters for pagination
+ * @var array first_characters Array that maps each letter in a-z, 'other' and the empty string to their display representation
+ * @var string u_first_char_params Concatenated URL parameters for first character search links
+ * @var array first_char_block_vars Template block variables for each first character
+ * @var int total_users Total number of users found in this search
+ * @since 3.2.6-RC1
+ */
+ $vars = [
+ 'sort_params',
+ 'params',
+ 'first_characters',
+ 'u_first_char_params',
+ 'first_char_block_vars',
+ 'total_users',
+ ];
+ extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_sort_pagination_params', compact($vars)));
+
+ $template->assign_block_vars_array('first_char', $first_char_block_vars);
+
+ $pagination_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", implode('&amp;', $params));
+ $sort_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", implode('&amp;', $sort_params));
+
+ unset($search_params, $sort_params);
+
// Some search user specific data
if (($mode == '' || $mode == 'searchuser') && ($config['load_search'] || $auth->acl_get('a_')))
{
@@ -1530,19 +1572,58 @@ switch ($mode)
// Do the SQL thang
if ($mode == 'group')
{
- $sql = "SELECT u.*
- $sql_select
- FROM " . USERS_TABLE . " u
- $sql_from
- WHERE " . $db->sql_in_set('u.user_id', $user_list) . "
- $sql_where_data";
+ $sql_from_ary = explode(',', $sql_from);
+ $extra_tables = [];
+ foreach ($sql_from_ary as $entry)
+ {
+ $table_data = explode(' ', trim($entry));
+
+ if (empty($table_data[0]) || empty($table_data[1]))
+ {
+ continue;
+ }
+
+ $extra_tables[$table_data[0]] = $table_data[1];
+ }
+
+ $sql_array = array(
+ 'SELECT' => 'u.*' . $sql_select,
+ 'FROM' => array_merge([USERS_TABLE => 'u'], $extra_tables),
+ 'WHERE' => $db->sql_in_set('u.user_id', $user_list) . $sql_where_data . '',
+ );
}
else
{
- $sql = 'SELECT *
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('user_id', $user_list);
+ $sql_array = array(
+ 'SELECT' => 'u.*',
+ 'FROM' => array(
+ USERS_TABLE => 'u'
+ ),
+ 'WHERE' => $db->sql_in_set('u.user_id', $user_list),
+ );
}
+
+ /**
+ * Modify user data SQL before member row is created
+ *
+ * @event core.memberlist_modify_memberrow_sql
+ * @var string mode Memberlist mode
+ * @var string sql_select Additional select statement
+ * @var string sql_from Additional from statement
+ * @var array sql_array Array containing the main query
+ * @var array user_list Array containing list of users
+ * @since 3.2.6-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'sql_select',
+ 'sql_from',
+ 'sql_array',
+ 'user_list',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_memberrow_sql', compact($vars)));
+
+ $sql = $db->sql_build_query('SELECT', $sql_array);
$result = $db->sql_query($sql);
$id_cache = array();
@@ -1553,9 +1634,10 @@ switch ($mode)
$id_cache[$row['user_id']] = $row;
}
+
$db->sql_freeresult($result);
- // Load custom profile fields
+ // Load custom profile fields if required
if ($config['load_cpf_memberlist'])
{
// Grab all profile fields from users in id cache for later use - similar to the poster cache
diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php
index 8809a0c6b4..1a3083d42e 100644
--- a/phpBB/phpbb/auth/provider/oauth/oauth.php
+++ b/phpBB/phpbb/auth/provider/oauth/oauth.php
@@ -191,7 +191,7 @@ class oauth extends \phpbb\auth\provider\base
return $provider->login($username, $password);
}
- // Requst the name of the OAuth service
+ // Request the name of the OAuth service
$service_name_original = $this->request->variable('oauth_service', '', false);
$service_name = 'auth.provider.oauth.service.' . strtolower($service_name_original);
if ($service_name_original === '' || !array_key_exists($service_name, $this->service_providers))
@@ -221,24 +221,33 @@ class oauth extends \phpbb\auth\provider\base
'provider' => $service_name_original,
'oauth_provider_id' => $unique_id
);
+
$sql = 'SELECT user_id FROM ' . $this->auth_provider_oauth_token_account_assoc . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
+ $redirect_data = array(
+ 'auth_provider' => 'oauth',
+ 'login_link_oauth_service' => $service_name_original,
+ );
+
/**
* Event is triggered before check if provider is already associated with an account
*
* @event core.oauth_login_after_check_if_provider_id_has_match
- * @var array row User row
- * @var array data Provider data
- * @var \OAuth\Common\Service\ServiceInterface service OAuth service
+ * @var array row User row
+ * @var array data Provider data
+ * @var array redirect_data Data to be appended to the redirect url
+ * @var \OAuth\Common\Service\ServiceInterface service OAuth service
* @since 3.2.3-RC1
+ * @changed 3.2.6-RC1 Added redirect_data
*/
$vars = array(
'row',
'data',
+ 'redirect_data',
'service',
);
extract($this->dispatcher->trigger_event('core.oauth_login_after_check_if_provider_id_has_match', compact($vars)));
@@ -250,15 +259,12 @@ class oauth extends \phpbb\auth\provider\base
'status' => LOGIN_SUCCESS_LINK_PROFILE,
'error_msg' => 'LOGIN_OAUTH_ACCOUNT_NOT_LINKED',
'user_row' => array(),
- 'redirect_data' => array(
- 'auth_provider' => 'oauth',
- 'login_link_oauth_service' => $service_name_original,
- ),
+ 'redirect_data' => $redirect_data,
);
}
// Retrieve the user's account
- $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type, user_login_attempts
+ $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_ip, user_type, user_login_attempts
FROM ' . $this->users_table . '
WHERE user_id = ' . (int) $row['user_id'];
$result = $this->db->sql_query($sql);
@@ -270,11 +276,36 @@ class oauth extends \phpbb\auth\provider\base
throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY');
}
+ /**
+ * Check if the user is banned.
+ * The fourth parameter, return, has to be true,
+ * otherwise the OAuth login is still called and
+ * an uncaught exception is thrown as there is no
+ * token stored in the database.
+ */
+ $ban = $this->user->check_ban($row['user_id'], $row['user_ip'], $row['user_email'], true);
+ if (!empty($ban))
+ {
+ $till_date = !empty($ban['ban_end']) ? $this->user->format_date($ban['ban_end']) : '';
+ $message = !empty($ban['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM';
+
+ $contact_link = phpbb_get_board_contact_link($this->config, $this->phpbb_root_path, $this->php_ext);
+ $message = $this->user->lang($message, $till_date, '<a href="' . $contact_link . '">', '</a>');
+ $message .= !empty($ban['ban_give_reason']) ? '<br /><br />' . $this->user->lang('BOARD_BAN_REASON', $ban['ban_give_reason']) : '';
+ $message .= !empty($ban['ban_triggered_by']) ? '<br /><br /><em>' . $this->user->lang('BAN_TRIGGERED_BY_' . strtoupper($ban['ban_triggered_by'])) . '</em>' : '';
+
+ return array(
+ 'status' => LOGIN_BREAK,
+ 'error_msg' => $message,
+ 'user_row' => $row,
+ );
+ }
+
// Update token storage to store the user_id
$storage->set_user_id($row['user_id']);
/**
- * Event is triggered after user is successfuly logged in via OAuth.
+ * Event is triggered after user is successfully logged in via OAuth.
*
* @event core.auth_oauth_login_after
* @var array row User row
@@ -392,7 +423,7 @@ class oauth extends \phpbb\auth\provider\base
if ($credentials['key'] && $credentials['secret'])
{
$actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
- $redirect_url = build_url(false) . '&login=external&oauth_service=' . $actual_name;
+ $redirect_url = generate_board_url() . '/ucp.' . $this->php_ext . '?mode=login&login=external&oauth_service=' . $actual_name;
$login_data['BLOCK_VARS'][$service_name] = array(
'REDIRECT_URL' => redirect($redirect_url, true),
'SERVICE_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
@@ -674,6 +705,7 @@ class oauth extends \phpbb\auth\provider\base
'oauth_service' => $actual_name,
),
+ 'SERVICE_ID' => $actual_name,
'SERVICE_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
'UNIQUE_ID' => (isset($oauth_user_ids[$actual_name])) ? $oauth_user_ids[$actual_name] : null,
);
@@ -707,7 +739,7 @@ class oauth extends \phpbb\auth\provider\base
AND user_id = " . (int) $user_id;
$this->db->sql_query($sql);
- // Clear all tokens belonging to the user on this servce
+ // Clear all tokens belonging to the user on this service
$service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']);
$storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
$storage->clearToken($service_name);
diff --git a/phpBB/phpbb/auth/provider/provider_interface.php b/phpBB/phpbb/auth/provider/provider_interface.php
index 35e0f559a1..463324ff46 100644
--- a/phpBB/phpbb/auth/provider/provider_interface.php
+++ b/phpBB/phpbb/auth/provider/provider_interface.php
@@ -71,9 +71,10 @@ interface provider_interface
* options with whatever configuraton values are passed to it as an array.
* It then returns the name of the acp file related to this authentication
* provider.
- * @param array $new_config Contains the new configuration values that
- * have been set in acp_board.
- * @return array|null Returns null if not implemented or an array with
+ *
+ * @param \phpbb\config\config $new_config Contains the new configuration values
+ * that have been set in acp_board.
+ * @return array|null Returns null if not implemented or an array with
* the template file name and an array of the vars
* that the template needs that must conform to the
* following example:
diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php
index 77b44754ac..a012bb15b6 100644
--- a/phpBB/phpbb/avatar/driver/upload.php
+++ b/phpBB/phpbb/avatar/driver/upload.php
@@ -148,7 +148,8 @@ class upload extends \phpbb\avatar\driver\driver
// Do not allow specifying the port (see RFC 3986) or IP addresses
// remote_upload() will do its own check for allowed filetypes
- if (preg_match('@^(http|https|ftp)://[^/:?#]+:[0-9]+[/:?#]@i', $url) ||
+ if (!preg_match('#^(http|https|ftp)://(?:(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}|(?:\d{1,3}\.){3,5}\d{1,3}):?([0-9]*?).*?\.('. implode('|', $this->allowed_extensions) . ')$#i', $url) ||
+ preg_match('@^(http|https|ftp)://[^/:?#]+:[0-9]+[/:?#]@i', $url) ||
preg_match('#^(http|https|ftp)://(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])#i', $url) ||
preg_match('#^(http|https|ftp)://(?:(?:(?:[\dA-F]{1,4}:){6}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:::(?:[\dA-F]{1,4}:){0,5}(?:[\dA-F]{1,4}(?::[\dA-F]{1,4})?|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:):(?:[\dA-F]{1,4}:){4}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,2}:(?:[\dA-F]{1,4}:){3}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,3}:(?:[\dA-F]{1,4}:){2}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,4}:(?:[\dA-F]{1,4}:)(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,5}:(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,6}:[\dA-F]{1,4})|(?:(?:[\dA-F]{1,4}:){1,7}:)|(?:::))#i', $url))
{
diff --git a/phpBB/phpbb/avatar/manager.php b/phpBB/phpbb/avatar/manager.php
index 6d9604db04..a909a91042 100644
--- a/phpBB/phpbb/avatar/manager.php
+++ b/phpBB/phpbb/avatar/manager.php
@@ -271,7 +271,7 @@ class manager
$config_name = $driver->get_config_name();
return array(
- 'allow_avatar_' . $config_name => array('lang' => 'ALLOW_' . strtoupper(str_replace('\\', '_', $config_name)), 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'allow_avatar_' . $config_name => array('lang' => 'ALLOW_' . strtoupper(str_replace('\\', '_', $config_name)), 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
);
}
diff --git a/phpBB/phpbb/captcha/plugins/qa.php b/phpBB/phpbb/captcha/plugins/qa.php
index 70b3f72cc3..966b8d32f2 100644
--- a/phpBB/phpbb/captcha/plugins/qa.php
+++ b/phpBB/phpbb/captcha/plugins/qa.php
@@ -21,7 +21,7 @@ class qa
{
var $confirm_id;
var $answer;
- var $question_ids;
+ var $question_ids = [];
var $question_text;
var $question_lang;
var $question_strict;
diff --git a/phpBB/phpbb/console/command/thumbnail/delete.php b/phpBB/phpbb/console/command/thumbnail/delete.php
index 9f2ee822be..7b95c20cf2 100644
--- a/phpBB/phpbb/console/command/thumbnail/delete.php
+++ b/phpBB/phpbb/console/command/thumbnail/delete.php
@@ -19,6 +19,11 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class delete extends \phpbb\console\command\command
{
/**
+ * @var \phpbb\config\config
+ */
+ protected $config;
+
+ /**
* @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -32,12 +37,14 @@ class delete extends \phpbb\console\command\command
/**
* Constructor
*
+ * @param \config\config $config The config
* @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)
+ public function __construct(\phpbb\config\config $config, \phpbb\user $user, \phpbb\db\driver\driver_interface $db, $phpbb_root_path)
{
+ $this->config = $config;
$this->db = $db;
$this->phpbb_root_path = $phpbb_root_path;
@@ -101,7 +108,7 @@ class delete extends \phpbb\console\command\command
$return = 0;
while ($row = $this->db->sql_fetchrow($result))
{
- $thumbnail_path = $this->phpbb_root_path . 'files/thumb_' . $row['physical_filename'];
+ $thumbnail_path = $this->phpbb_root_path . $this->config['upload_path'] . '/thumb_' . $row['physical_filename'];
if (@unlink($thumbnail_path))
{
diff --git a/phpBB/phpbb/console/command/thumbnail/generate.php b/phpBB/phpbb/console/command/thumbnail/generate.php
index 64f7555336..1f6582b17b 100644
--- a/phpBB/phpbb/console/command/thumbnail/generate.php
+++ b/phpBB/phpbb/console/command/thumbnail/generate.php
@@ -20,6 +20,11 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class generate extends \phpbb\console\command\command
{
/**
+ * @var \phpbb\config\config
+ */
+ protected $config;
+
+ /**
* @var \phpbb\db\driver\driver_interface
*/
protected $db;
@@ -45,14 +50,16 @@ class generate extends \phpbb\console\command\command
/**
* Constructor
*
+ * @param \config\config $config The config
* @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)
+ public function __construct(\phpbb\config\config $config, \phpbb\user $user, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, $phpbb_root_path, $php_ext)
{
+ $this->config = $config;
$this->db = $db;
$this->cache = $cache;
$this->phpbb_root_path = $phpbb_root_path;
@@ -126,8 +133,8 @@ class generate extends \phpbb\console\command\command
{
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'];
+ $source = $this->phpbb_root_path . $this->config['upload_path'] . '/' . $row['physical_filename'];
+ $destination = $this->phpbb_root_path . $this->config['upload_path'] . '/thumb_' . $row['physical_filename'];
if (create_thumbnail($source, $destination, $row['mimetype']))
{
diff --git a/phpBB/phpbb/db/migration/data/v32x/disable_remote_avatar.php b/phpBB/phpbb/db/migration/data/v32x/disable_remote_avatar.php
new file mode 100644
index 0000000000..b08833fad4
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v32x/disable_remote_avatar.php
@@ -0,0 +1,34 @@
+<?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\v32x;
+
+use phpbb\db\migration\migration;
+
+class disable_remote_avatar extends migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v32x\v325',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('allow_avatar_remote', '0')),
+ array('config.update', array('allow_avatar_remote_upload', '0')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v32x/smtp_dynamic_data.php b/phpBB/phpbb/db/migration/data/v32x/smtp_dynamic_data.php
new file mode 100644
index 0000000000..aeaa3e8979
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v32x/smtp_dynamic_data.php
@@ -0,0 +1,42 @@
+<?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\v32x;
+
+class smtp_dynamic_data extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v32x\v326rc1',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'set_smtp_dynamic'))),
+ );
+ }
+
+ public function set_smtp_dynamic()
+ {
+ $smtp_auth_entries = [
+ 'smtp_password',
+ 'smtp_username',
+ ];
+ $this->sql_query('UPDATE ' . CONFIG_TABLE . '
+ SET is_dynamic = 1
+ WHERE ' . $this->db->sql_in_set('config_name', $smtp_auth_entries));
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v32x/timezone_p3.php b/phpBB/phpbb/db/migration/data/v32x/timezone_p3.php
new file mode 100644
index 0000000000..433f62ace9
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v32x/timezone_p3.php
@@ -0,0 +1,29 @@
+<?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\v32x;
+
+class timezone_p3 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\timezone');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.remove', array('board_dst')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v32x/v326.php b/phpBB/phpbb/db/migration/data/v32x/v326.php
new file mode 100644
index 0000000000..2d511b9ed8
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v32x/v326.php
@@ -0,0 +1,39 @@
+<?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\v32x;
+
+class v326 extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return phpbb_version_compare($this->config['version'], '3.2.6', '>=');
+ }
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v32x\v326rc1',
+ '\phpbb\db\migration\data\v32x\disable_remote_avatar',
+ '\phpbb\db\migration\data\v32x\smtp_dynamic_data',
+ );
+
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.2.6')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v32x/v326rc1.php b/phpBB/phpbb/db/migration/data/v32x/v326rc1.php
new file mode 100644
index 0000000000..092700d3db
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v32x/v326rc1.php
@@ -0,0 +1,37 @@
+<?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\v32x;
+
+class v326rc1 extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return phpbb_version_compare($this->config['version'], '3.2.6-RC1', '>=');
+ }
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v32x\v325',
+ );
+
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.2.6-RC1')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v32x/v327.php b/phpBB/phpbb/db/migration/data/v32x/v327.php
new file mode 100644
index 0000000000..f9ea11f4b9
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v32x/v327.php
@@ -0,0 +1,37 @@
+<?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\v32x;
+
+class v327 extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return phpbb_version_compare($this->config['version'], '3.2.7', '>=');
+ }
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v32x\v327rc1',
+ );
+
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.2.7')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v32x/v327rc1.php b/phpBB/phpbb/db/migration/data/v32x/v327rc1.php
new file mode 100644
index 0000000000..c8169105af
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v32x/v327rc1.php
@@ -0,0 +1,36 @@
+<?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\v32x;
+
+class v327rc1 extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return phpbb_version_compare($this->config['version'], '3.2.7-RC1', '>=');
+ }
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v32x\v326',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.2.7-RC1')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php
index d21d34b8a9..c3352a1f66 100644
--- a/phpBB/phpbb/db/tools/tools.php
+++ b/phpBB/phpbb/db/tools/tools.php
@@ -576,7 +576,7 @@ class tools implements tools_interface
{
foreach ($indexes as $index_name)
{
- if (!$this->sql_index_exists($table, $index_name))
+ if (!$this->sql_index_exists($table, $index_name) && !$this->sql_unique_index_exists($table, $index_name))
{
continue;
}
diff --git a/phpBB/phpbb/event/md_exporter.php b/phpBB/phpbb/event/md_exporter.php
index 085b20c234..1a2d7c989e 100644
--- a/phpBB/phpbb/event/md_exporter.php
+++ b/phpBB/phpbb/event/md_exporter.php
@@ -143,6 +143,8 @@ class md_exporter
list($event_name, $details) = explode("\n===\n", $event, 2);
$this->validate_event_name($event_name);
+ $sorted_events = [$this->current_event, $event_name];
+ natsort($sorted_events);
$this->current_event = $event_name;
if (isset($this->events[$this->current_event]))
@@ -150,6 +152,12 @@ class md_exporter
throw new \LogicException("The event '{$this->current_event}' is defined multiple times");
}
+ // Use array_values() to get actual first element and check against natural order
+ if (array_values($sorted_events)[0] === $event_name)
+ {
+ throw new \LogicException("The event '{$sorted_events[1]}' should be defined before '{$sorted_events[0]}'");
+ }
+
if (($this->filter == 'adm' && strpos($this->current_event, 'acp_') !== 0)
|| ($this->filter == 'styles' && strpos($this->current_event, 'acp_') === 0))
{
@@ -381,9 +389,16 @@ class md_exporter
$files = explode("\n + ", $file_details);
foreach ($files as $file)
{
+ if (!preg_match('#^([^ ]+)( \([0-9]+\))?$#', $file))
+ {
+ throw new \LogicException("Invalid event instances for file '{$file}' found for event '{$this->current_event}'", 1);
+ }
+
+ list($file) = explode(" ", $file);
+
if (!file_exists($this->path . $file) || substr($file, -5) !== '.html')
{
- throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 1);
+ throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 2);
}
if (($this->filter !== 'adm') && strpos($file, 'styles/prosilver/template/') === 0)
@@ -396,7 +411,7 @@ class md_exporter
}
else
{
- throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 2);
+ throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 3);
}
$this->events_by_file[$file][] = $this->current_event;
@@ -416,7 +431,7 @@ class md_exporter
}
else
{
- throw new \LogicException("Invalid file list found for event '{$this->current_event}'", 2);
+ throw new \LogicException("Invalid file list found for event '{$this->current_event}'", 1);
}
return $files_list;
diff --git a/phpBB/phpbb/group/helper.php b/phpBB/phpbb/group/helper.php
index 5befddfc53..aa3876b325 100644
--- a/phpBB/phpbb/group/helper.php
+++ b/phpBB/phpbb/group/helper.php
@@ -13,19 +13,74 @@
namespace phpbb\group;
+use phpbb\auth\auth;
+use phpbb\cache\service as cache;
+use phpbb\config\config;
+use phpbb\language\language;
+use phpbb\event\dispatcher_interface;
+use phpbb\path_helper;
+use phpbb\user;
+
class helper
{
- /** @var \phpbb\language\language */
+ /** @var auth */
+ protected $auth;
+
+ /** @var cache */
+ protected $cache;
+
+ /** @var config */
+ protected $config;
+
+ /** @var language */
protected $language;
+ /** @var dispatcher_interface */
+ protected $dispatcher;
+
+ /** @var path_helper */
+ protected $path_helper;
+
+ /** @var user */
+ protected $user;
+
+ /** @var string phpBB root path */
+ protected $phpbb_root_path;
+
+ /** @var array Return templates for a group name string */
+ protected $name_strings;
+
/**
* Constructor
*
- * @param \phpbb\language\language $language Language object
+ * @param auth $auth Authentication object
+ * @param cache $cache Cache service object
+ * @param config $config Configuration object
+ * @param language $language Language object
+ * @param dispatcher_interface $dispatcher Event dispatcher object
+ * @param path_helper $path_helper Path helper object
+ * @param user $user User object
*/
- public function __construct(\phpbb\language\language $language)
+ public function __construct(auth $auth, cache $cache, config $config, language $language, dispatcher_interface $dispatcher, path_helper $path_helper, user $user)
{
+ $this->auth = $auth;
+ $this->cache = $cache;
+ $this->config = $config;
$this->language = $language;
+ $this->dispatcher = $dispatcher;
+ $this->path_helper = $path_helper;
+ $this->user = $user;
+
+ $this->phpbb_root_path = $path_helper->get_phpbb_root_path();
+
+ /** @html Group name spans and links for usage in the template */
+ $this->name_strings = array(
+ 'base_url' => "{$path_helper->get_phpbb_root_path()}memberlist.{$path_helper->get_php_ext()}?mode=group&amp;g={GROUP_ID}",
+ 'tpl_noprofile' => '<span class="username">{GROUP_NAME}</span>',
+ 'tpl_noprofile_colour' => '<span class="username-coloured" style="color: {GROUP_COLOUR};">{GROUP_NAME}</span>',
+ 'tpl_profile' => '<a class="username" href="{PROFILE_URL}">{GROUP_NAME}</a>',
+ 'tpl_profile_colour' => '<a class="username-coloured" href="{PROFILE_URL}" style="color: {GROUP_COLOUR};">{GROUP_NAME}</a>',
+ );
}
/**
@@ -37,4 +92,203 @@ class helper
{
return $this->language->is_set('G_' . utf8_strtoupper($group_name)) ? $this->language->lang('G_' . utf8_strtoupper($group_name)) : $group_name;
}
+
+ /**
+ * Get group name details for placing into templates.
+ *
+ * @html Group name spans and links
+ *
+ * @param string $mode Profile (for getting an url to the profile),
+ * group_name (for obtaining the group name),
+ * colour (for obtaining the group colour),
+ * full (for obtaining a coloured group name link to the group's profile),
+ * no_profile (the same as full but forcing no profile link)
+ * @param int $group_id The group id
+ * @param string $group_name The group name
+ * @param string $group_colour The group colour
+ * @param mixed $custom_profile_url optional parameter to specify a profile url. The group id gets appended to this url as &amp;g={group_id}
+ *
+ * @return string A string consisting of what is wanted based on $mode.
+ */
+ public function get_name_string($mode, $group_id, $group_name, $group_colour = '', $custom_profile_url = false)
+ {
+ $s_is_bots = ($group_name === 'BOTS');
+
+ // This switch makes sure we only run code required for the mode
+ switch ($mode)
+ {
+ case 'full':
+ case 'no_profile':
+ case 'colour':
+
+ // Build correct group colour
+ $group_colour = $group_colour ? '#' . $group_colour : '';
+
+ // Return colour
+ if ($mode === 'colour')
+ {
+ $group_name_string = $group_colour;
+ break;
+ }
+
+ // no break;
+
+ case 'group_name':
+
+ // Build correct group name
+ $group_name = $this->get_name($group_name);
+
+ // Return group name
+ if ($mode === 'group_name')
+ {
+ $group_name_string = $group_name;
+ break;
+ }
+
+ // no break;
+
+ case 'profile':
+
+ // Build correct profile url - only show if not anonymous and permission to view profile if registered user
+ // For anonymous the link leads to a login page.
+ if ($group_id && !$s_is_bots && ($this->user->data['user_id'] == ANONYMOUS || $this->auth->acl_get('u_viewprofile')))
+ {
+ $profile_url = ($custom_profile_url !== false) ? $custom_profile_url . '&amp;g=' . (int) $group_id : str_replace(array('={GROUP_ID}', '=%7BGROUP_ID%7D'), '=' . (int) $group_id, append_sid($this->name_strings['base_url']));
+ }
+ else
+ {
+ $profile_url = '';
+ }
+
+ // Return profile
+ if ($mode === 'profile')
+ {
+ $group_name_string = $profile_url;
+ break;
+ }
+
+ // no break;
+ }
+
+ if (!isset($group_name_string))
+ {
+ if (($mode === 'full' && empty($profile_url)) || $mode === 'no_profile' || $s_is_bots)
+ {
+ $group_name_string = str_replace(array('{GROUP_COLOUR}', '{GROUP_NAME}'), array($group_colour, $group_name), (!$group_colour) ? $this->name_strings['tpl_noprofile'] : $this->name_strings['tpl_noprofile_colour']);
+ }
+ else
+ {
+ $group_name_string = str_replace(array('{PROFILE_URL}', '{GROUP_COLOUR}', '{GROUP_NAME}'), array($profile_url, $group_colour, $group_name), (!$group_colour) ? $this->name_strings['tpl_profile'] : $this->name_strings['tpl_profile_colour']);
+ }
+ }
+
+ $name_strings = $this->name_strings;
+
+ /**
+ * Use this event to change the output of the group name
+ *
+ * @event core.modify_group_name_string
+ * @var string mode profile|group_name|colour|full|no_profile
+ * @var int group_id The group identifier
+ * @var string group_name The group name
+ * @var string group_colour The group colour
+ * @var string custom_profile_url Optional parameter to specify a profile url.
+ * @var string group_name_string The string that has been generated
+ * @var array name_strings Array of original return templates
+ * @since 3.2.8-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'group_id',
+ 'group_name',
+ 'group_colour',
+ 'custom_profile_url',
+ 'group_name_string',
+ 'name_strings',
+ );
+ extract($this->dispatcher->trigger_event('core.modify_group_name_string', compact($vars)));
+
+ return $group_name_string;
+ }
+
+ /**
+ * Get group rank title and image
+ *
+ * @html Group rank image element
+ *
+ * @param array $group_data The current stored group data
+ *
+ * @return array An associative array containing the rank title (title),
+ * the rank image as full img tag (img) and the rank image source (img_src)
+ */
+ public function get_rank($group_data)
+ {
+ $group_rank_data = array(
+ 'title' => null,
+ 'img' => null,
+ 'img_src' => null,
+ );
+
+ /**
+ * Preparing a group's rank before displaying
+ *
+ * @event core.get_group_rank_before
+ * @var array group_data Array with group's data
+ * @since 3.2.8-RC1
+ */
+
+ $vars = array('group_data');
+ extract($this->dispatcher->trigger_event('core.get_group_rank_before', compact($vars)));
+
+ if (!empty($group_data['group_rank']))
+ {
+ // Only obtain ranks if group rank is set
+ $ranks = $this->cache->obtain_ranks();
+
+ if (isset($ranks['special'][$group_data['group_rank']]))
+ {
+ $rank = $ranks['special'][$group_data['group_rank']];
+
+ $group_rank_data['title'] = $rank['rank_title'];
+
+ $group_rank_data['img_src'] = (!empty($rank['rank_image'])) ? $this->path_helper->update_web_root_path($this->phpbb_root_path . $this->config['ranks_path'] . '/' . $rank['rank_image']) : '';
+
+ /** @html Group rank image element for usage in the template */
+ $group_rank_data['img'] = (!empty($rank['rank_image'])) ? '<img src="' . $group_rank_data['img_src'] . '" alt="' . $rank['rank_title'] . '" title="' . $rank['rank_title'] . '" />' : '';
+ }
+ }
+
+ /**
+ * Modify a group's rank before displaying
+ *
+ * @event core.get_group_rank_after
+ * @var array group_data Array with group's data
+ * @var array group_rank_data Group rank data
+ * @since 3.2.8-RC1
+ */
+
+ $vars = array(
+ 'group_data',
+ 'group_rank_data',
+ );
+ extract($this->dispatcher->trigger_event('core.get_group_rank_after', compact($vars)));
+
+ return $group_rank_data;
+ }
+
+ /**
+ * Get group avatar.
+ * Wrapper function for phpbb_get_group_avatar()
+ *
+ * @param array $group_row Row from the groups table
+ * @param string $alt Optional language string for alt tag within image, can be a language key or text
+ * @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+ * @param bool $lazy If true, will be lazy loaded (requires JS)
+ *
+ * @return string Avatar html
+ */
+ function get_avatar($group_row, $alt = 'GROUP_AVATAR', $ignore_config = false, $lazy = false)
+ {
+ return phpbb_get_group_avatar($group_row, $alt, $ignore_config, $lazy);
+ }
}
diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php
index fad6749019..7eb0ae3b05 100644
--- a/phpBB/phpbb/install/helper/config.php
+++ b/phpBB/phpbb/install/helper/config.php
@@ -330,6 +330,8 @@ class config
fwrite($fp, $file_content);
fclose($fp);
+ // Enforce 0600 permission for install config
+ $this->filesystem->chmod([$this->install_config_file], 0600);
}
/**
diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php
index dc7b060746..6ec1e612b9 100644
--- a/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php
+++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php
@@ -78,10 +78,10 @@ class obtain_database_data extends \phpbb\install\task_base implements \phpbb\in
$dbms = $this->io_handler->get_input('dbms', '');
$dbhost = $this->io_handler->get_input('dbhost', '', true);
$dbport = $this->io_handler->get_input('dbport', '');
- $dbuser = $this->io_handler->get_input('dbuser', '');
- $dbpasswd = $this->io_handler->get_raw_input('dbpasswd', '');
- $dbname = $this->io_handler->get_input('dbname', '');
- $table_prefix = $this->io_handler->get_input('table_prefix', '');
+ $dbuser = $this->io_handler->get_input('dbuser', '', true);
+ $dbpasswd = $this->io_handler->get_raw_input('dbpasswd', '', true);
+ $dbname = $this->io_handler->get_input('dbname', '', true);
+ $table_prefix = $this->io_handler->get_input('table_prefix', '', true);
// Check database data
$user_data_vaild = $this->check_database_data($dbms, $dbhost, $dbport, $dbuser, $dbpasswd, $dbname, $table_prefix);
diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php
index e8a9c971b7..7cd0d7bf23 100644
--- a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php
+++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php
@@ -50,11 +50,11 @@ class obtain_email_data extends \phpbb\install\task_base implements \phpbb\insta
// E-mail data
$email_enable = $this->io_handler->get_input('email_enable', true);
$smtp_delivery = $this->io_handler->get_input('smtp_delivery', '');
- $smtp_host = $this->io_handler->get_input('smtp_host', '');
+ $smtp_host = $this->io_handler->get_input('smtp_host', '', true);
$smtp_port = $this->io_handler->get_input('smtp_port', '');
$smtp_auth = $this->io_handler->get_input('smtp_auth', '');
- $smtp_user = $this->io_handler->get_input('smtp_user', '');
- $smtp_passwd = $this->io_handler->get_input('smtp_pass', '');
+ $smtp_user = $this->io_handler->get_input('smtp_user', '', true);
+ $smtp_passwd = $this->io_handler->get_input('smtp_pass', '', true);
$auth_methods = array('PLAIN', 'LOGIN', 'CRAM-MD5', 'DIGEST-MD5', 'POP-BEFORE-SMTP');
diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php
index 1ef70eae08..5096ce284e 100644
--- a/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php
+++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php
@@ -79,9 +79,9 @@ class obtain_server_data extends \phpbb\install\task_base implements \phpbb\inst
$cookie_secure = $this->io_handler->get_input('cookie_secure', $cookie_secure);
$server_protocol = $this->io_handler->get_input('server_protocol', $server_protocol);
$force_server_vars = $this->io_handler->get_input('force_server_vars', 0);
- $server_name = $this->io_handler->get_input('server_name', $server_name);
+ $server_name = $this->io_handler->get_input('server_name', $server_name, true);
$server_port = $this->io_handler->get_input('server_port', $server_port);
- $script_path = $this->io_handler->get_input('script_path', $script_path);
+ $script_path = $this->io_handler->get_input('script_path', $script_path, true);
// Clean up script path
if ($script_path !== '/')
diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php
index f31472fc58..3c17576c13 100644
--- a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php
+++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php
@@ -85,10 +85,10 @@ class obtain_update_ftp_data extends task_base
$method = $methods[0];
}
- $ftp_host = $this->iohandler->get_input('ftp_host', '');
- $ftp_user = $this->iohandler->get_input('ftp_user', '');
- $ftp_pass = htmlspecialchars_decode($this->iohandler->get_input('ftp_pass', ''));
- $ftp_path = $this->iohandler->get_input('ftp_path', '');
+ $ftp_host = $this->iohandler->get_input('ftp_host', '', true);
+ $ftp_user = $this->iohandler->get_input('ftp_user', '', true);
+ $ftp_pass = htmlspecialchars_decode($this->iohandler->get_input('ftp_pass', '', true));
+ $ftp_path = $this->iohandler->get_input('ftp_path', '', true);
$ftp_port = $this->iohandler->get_input('ftp_port', 21);
$ftp_time = $this->iohandler->get_input('ftp_timeout', 10);
diff --git a/phpBB/phpbb/message/admin_form.php b/phpBB/phpbb/message/admin_form.php
index 96b8d3499e..ae1c1d8614 100644
--- a/phpBB/phpbb/message/admin_form.php
+++ b/phpBB/phpbb/message/admin_form.php
@@ -22,6 +22,9 @@ class admin_form extends form
/** @var \phpbb\config\db_text */
protected $config_text;
+ /** @var \phpbb\event\dispatcher_interface */
+ protected $dispatcher;
+
/** @var string */
protected $subject;
/** @var string */
@@ -37,13 +40,15 @@ class admin_form extends form
* @param \phpbb\config\db_text $config_text
* @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\user $user
+ * @param \phpbb\event\dispatcher_interface $dispatcher
* @param string $phpbb_root_path
* @param string $phpEx
*/
- public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\config\db_text $config_text, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $phpEx)
+ public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\config\db_text $config_text, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\event\dispatcher_interface $dispatcher, $phpbb_root_path, $phpEx)
{
parent::__construct($auth, $config, $db, $user, $phpbb_root_path, $phpEx);
$this->config_text = $config_text;
+ $this->dispatcher = $dispatcher;
}
/**
@@ -91,6 +96,29 @@ class admin_form extends form
$this->errors[] = $this->user->lang['EMPTY_MESSAGE_EMAIL'];
}
+ $subject = $this->subject;
+ $body = $this->body;
+ $errors = $this->errors;
+
+ /**
+ * You can use this event to modify subject and/or body and add new errors.
+ *
+ * @event core.message_admin_form_submit_before
+ * @var string subject Message subject
+ * @var string body Message body
+ * @var array errors Form errors
+ * @since 3.2.6-RC1
+ */
+ $vars = [
+ 'subject',
+ 'body',
+ 'errors',
+ ];
+ extract($this->dispatcher->trigger_event('core.message_admin_form_submit_before', compact($vars)));
+ $this->subject = $subject;
+ $this->body = $body;
+ $this->errors = $errors;
+
if ($this->user->data['is_registered'])
{
$this->message->set_sender_from_user($this->user);
diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php
index 7e53ffb3ca..444f98270d 100644
--- a/phpBB/phpbb/notification/type/report_pm.php
+++ b/phpBB/phpbb/notification/type/report_pm.php
@@ -142,13 +142,16 @@ class report_pm extends \phpbb\notification\type\pm
*/
public function get_email_template_variables()
{
- $user_data = $this->user_loader->get_user($this->get_data('reporter_id'));
+ $user_data = $this->user_loader->get_user($this->get_data('from_user_id'));
return array(
'AUTHOR_NAME' => htmlspecialchars_decode($user_data['username']),
'SUBJECT' => htmlspecialchars_decode(censor_text($this->get_data('message_subject'))),
- 'U_VIEW_REPORT' => generate_board_url() . "mcp.{$this->php_ext}?r={$this->item_parent_id}&amp;i=pm_reports&amp;mode=pm_report_details",
+ /** @deprecated 3.2.6-RC1 (to be removed in 4.0.0) use {SUBJECT} instead in report_pm.txt */
+ 'TOPIC_TITLE' => htmlspecialchars_decode(censor_text($this->get_data('message_subject'))),
+
+ 'U_VIEW_REPORT' => generate_board_url() . "/mcp.{$this->php_ext}?r={$this->item_parent_id}&amp;i=pm_reports&amp;mode=pm_report_details",
);
}
@@ -236,8 +239,10 @@ class report_pm extends \phpbb\notification\type\pm
*/
public function users_to_query()
{
- return array($this->get_data('reporter_id'));
- }
+ return array(
+ $this->get_data('from_user_id'),
+ $this->get_data('reporter_id'),
+ ); }
/**
* {@inheritdoc}
diff --git a/phpBB/phpbb/pagination.php b/phpBB/phpbb/pagination.php
index 40af5eda6b..a7086f6691 100644
--- a/phpBB/phpbb/pagination.php
+++ b/phpBB/phpbb/pagination.php
@@ -46,7 +46,7 @@ class pagination
/**
* Generate a pagination link based on the url and the page information
*
- * @param string $base_url is url prepended to all links generated within the function
+ * @param string|array $base_url is url prepended to all links generated within the function
* If you use page numbers inside your controller route, base_url should contains a placeholder (%d)
* for the page. Also be sure to specify the pagination path information into the start_name argument
* @param string $on_page is the page for which we want to generate the link
@@ -69,7 +69,7 @@ class pagination
* set $generate_page_link_override to the new URL value
*
* @event core.pagination_generate_page_link
- * @var string base_url is url prepended to all links generated within the function
+ * @var string|array base_url is url prepended to all links generated within the function
* If you use page numbers inside your controller route, base_url should contains a placeholder (%d)
* for the page. Also be sure to specify the pagination path information into the start_name argument
* @var string on_page is the page for which we want to generate the link
@@ -120,7 +120,7 @@ class pagination
* Generate template rendered pagination
* Allows full control of rendering of pagination with the template
*
- * @param string $base_url is url prepended to all links generated within the function
+ * @param string|array $base_url is url prepended to all links generated within the function
* If you use page numbers inside your controller route, base_url should contains a placeholder (%d)
* for the page. Also be sure to specify the pagination path information into the start_name argument
* @param string $block_var_name is the name assigned to the pagination data block within the template (example: <!-- BEGIN pagination -->)
@@ -132,7 +132,7 @@ class pagination
* @param int $start the item which should be considered currently active, used to determine the page we're on
* @param bool $reverse_count determines whether we weight display of the list towards the start (false) or end (true) of the list
* @param bool $ignore_on_page decides whether we enable an active (unlinked) item, used primarily for embedded lists
- * @return null
+ * @return void
*/
public function generate_template_pagination($base_url, $block_var_name, $start_name, $num_items, $per_page, $start = 1, $reverse_count = false, $ignore_on_page = false)
{
diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php
index 137ed7433d..1105d0892f 100644
--- a/phpBB/phpbb/search/fulltext_mysql.php
+++ b/phpBB/phpbb/search/fulltext_mysql.php
@@ -188,7 +188,7 @@ class fulltext_mysql extends \phpbb\search\base
}
$sql = 'SHOW VARIABLES
- LIKE \'ft\_%\'';
+ LIKE \'%ft\_%\'';
$result = $this->db->sql_query($sql);
$mysql_info = array();
@@ -198,8 +198,16 @@ class fulltext_mysql extends \phpbb\search\base
}
$this->db->sql_freeresult($result);
- $this->config->set('fulltext_mysql_max_word_len', $mysql_info['ft_max_word_len']);
- $this->config->set('fulltext_mysql_min_word_len', $mysql_info['ft_min_word_len']);
+ if ($engine === 'MyISAM')
+ {
+ $this->config->set('fulltext_mysql_max_word_len', $mysql_info['ft_max_word_len']);
+ $this->config->set('fulltext_mysql_min_word_len', $mysql_info['ft_min_word_len']);
+ }
+ else if ($engine === 'InnoDB')
+ {
+ $this->config->set('fulltext_mysql_max_word_len', $mysql_info['innodb_ft_max_token_size']);
+ $this->config->set('fulltext_mysql_min_word_len', $mysql_info['innodb_ft_min_token_size']);
+ }
return false;
}
diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php
index 4172e2cc4f..c83de75eed 100644
--- a/phpBB/phpbb/search/fulltext_native.php
+++ b/phpBB/phpbb/search/fulltext_native.php
@@ -190,7 +190,7 @@ class fulltext_native extends \phpbb\search\base
*/
public function split_keywords($keywords, $terms)
{
- $tokens = '+-|()*';
+ $tokens = '+-|()* ';
$keywords = trim($this->cleanup($keywords, $tokens));
@@ -224,12 +224,10 @@ class fulltext_native extends \phpbb\search\base
$keywords[$i] = '|';
break;
case '*':
- if ($i === 0 || ($keywords[$i - 1] !== '*' && strcspn($keywords[$i - 1], $tokens) === 0))
+ // $i can never be 0 here since $open_bracket is initialised to false
+ if (strpos($tokens, $keywords[$i - 1]) !== false && ($i + 1 === $n || strpos($tokens, $keywords[$i + 1]) !== false))
{
- if ($i === $n - 1 || ($keywords[$i + 1] !== '*' && strcspn($keywords[$i + 1], $tokens) === 0))
- {
- $keywords = substr($keywords, 0, $i) . substr($keywords, $i + 1);
- }
+ $keywords[$i] = '|';
}
break;
}
@@ -264,7 +262,7 @@ class fulltext_native extends \phpbb\search\base
}
}
- if ($open_bracket)
+ if ($open_bracket !== false)
{
$keywords .= ')';
}
@@ -307,6 +305,20 @@ class fulltext_native extends \phpbb\search\base
}
}
+ // Remove non trailing wildcards from each word to prevent a full table scan (it's now using the database index)
+ $match = '#\*(?!$|\s)#';
+ $replace = '$1';
+ $keywords = preg_replace($match, $replace, $keywords);
+
+ // Only allow one wildcard in the search query to limit the database load
+ $match = '#\*#';
+ $replace = '$1';
+ $count_wildcards = substr_count($keywords, '*');
+
+ // Reverse the string to remove all wildcards except the first one
+ $keywords = strrev(preg_replace($match, $replace, strrev($keywords), $count_wildcards - 1));
+ unset($count_wildcards);
+
// set the search_query which is shown to the user
$this->search_query = $keywords;
@@ -409,8 +421,16 @@ class fulltext_native extends \phpbb\search\base
{
if (strpos($word_part, '*') !== false)
{
- $id_words[] = '\'' . $this->db->sql_escape(str_replace('*', '%', $word_part)) . '\'';
- $non_common_words[] = $word_part;
+ $len = utf8_strlen(str_replace('*', '', $word_part));
+ if ($len >= $this->word_length['min'] && $len <= $this->word_length['max'])
+ {
+ $id_words[] = '\'' . $this->db->sql_escape(str_replace('*', '%', $word_part)) . '\'';
+ $non_common_words[] = $word_part;
+ }
+ else
+ {
+ $this->common_words[] = $word_part;
+ }
}
else if (isset($words[$word_part]))
{
diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php
index 80934dc411..31f32af7c4 100644
--- a/phpBB/phpbb/session.php
+++ b/phpBB/phpbb/session.php
@@ -1299,7 +1299,12 @@ class session
trigger_error($message);
}
- return ($banned && $ban_row['ban_give_reason']) ? $ban_row['ban_give_reason'] : $banned;
+ if (!empty($ban_row))
+ {
+ $ban_row['ban_triggered_by'] = $ban_triggered_by;
+ }
+
+ return ($banned && $ban_row) ? $ban_row : $banned;
}
/**
diff --git a/phpBB/phpbb/textformatter/s9e/link_helper.php b/phpBB/phpbb/textformatter/s9e/link_helper.php
index 1e113b6449..483794a83e 100644
--- a/phpBB/phpbb/textformatter/s9e/link_helper.php
+++ b/phpBB/phpbb/textformatter/s9e/link_helper.php
@@ -60,8 +60,10 @@ class link_helper
$length = $end - $start;
$text = substr($parser->getText(), $start, $length);
- // Create a tag that consumes the link's text
- $parser->addSelfClosingTag('LINK_TEXT', $start, $length)->setAttribute('text', $text);
+ // Create a tag that consumes the link's text and make it depends on this tag
+ $link_text_tag = $parser->addSelfClosingTag('LINK_TEXT', $start, $length);
+ $link_text_tag->setAttribute('text', $text);
+ $tag->cascadeInvalidationTo($link_text_tag);
}
/**
diff --git a/phpBB/posting.php b/phpBB/posting.php
index 59be983987..5089448483 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -222,6 +222,25 @@ if (!$post_data)
trigger_error(($mode == 'post' || $mode == 'bump' || $mode == 'reply') ? 'NO_TOPIC' : 'NO_POST');
}
+/**
+* This event allows you to bypass reply/quote test of an unapproved post.
+*
+* @event core.posting_modify_row_data
+* @var array post_data All post data from database
+* @var string mode What action to take if the form has been submitted
+* post|reply|quote|edit|delete|bump|smilies|popup
+* @var int topic_id ID of the topic
+* @var int forum_id ID of the forum
+* @since 3.2.8-RC1
+*/
+$vars = array(
+ 'post_data',
+ 'mode',
+ 'topic_id',
+ 'forum_id',
+);
+extract($phpbb_dispatcher->trigger_event('core.posting_modify_row_data', compact($vars)));
+
// Not able to reply to unapproved posts/topics
// TODO: add more descriptive language key
if ($auth->acl_get('m_approve', $forum_id) && ((($mode == 'reply' || $mode == 'bump') && $post_data['topic_visibility'] != ITEM_APPROVED) || ($mode == 'quote' && $post_data['post_visibility'] != ITEM_APPROVED)))
@@ -1649,6 +1668,20 @@ if ($generate_quote)
'user_id' => $post_data['poster_id'],
);
+ /**
+ * This event allows you to modify the quote attributes of the post being quoted
+ *
+ * @event core.posting_modify_quote_attributes
+ * @var array quote_attributes Array with quote attributes
+ * @var array post_data Array with post data
+ * @since 3.2.6-RC1
+ */
+ $vars = array(
+ 'quote_attributes',
+ 'post_data',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.posting_modify_quote_attributes', compact($vars)));
+
/** @var \phpbb\language\language $language */
$language = $phpbb_container->get('language');
phpbb_format_quote($language, $message_parser, $bbcode_utils, $bbcode_status, $quote_attributes);
@@ -1657,6 +1690,20 @@ if ($generate_quote)
if (($mode == 'reply' || $mode == 'quote') && !$submit && !$preview && !$refresh)
{
$post_data['post_subject'] = ((strpos($post_data['post_subject'], 'Re: ') !== 0) ? 'Re: ' : '') . censor_text($post_data['post_subject']);
+
+ $post_subject = $post_data['post_subject'];
+
+ /**
+ * This event allows you to modify the post subject of the post being quoted
+ *
+ * @event core.posting_modify_post_subject
+ * @var string post_subject String with the post subject already censored.
+ * @since 3.2.8-RC1
+ */
+ $vars = array('post_subject');
+ extract($phpbb_dispatcher->trigger_event('core.posting_modify_post_subject', compact($vars)));
+
+ $post_data['post_subject'] = $post_subject;
}
$attachment_data = $message_parser->attachment_data;
diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg
index a588f1e558..4485b17945 100644
--- a/phpBB/styles/prosilver/style.cfg
+++ b/phpBB/styles/prosilver/style.cfg
@@ -21,8 +21,8 @@
# General Information about this style
name = prosilver
copyright = © phpBB Limited, 2007
-style_version = 3.2.5
-phpbb_version = 3.2.5
+style_version = 3.2.7
+phpbb_version = 3.2.7
# Defining a different template bitfield
# template_bitfield = //g=
diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html
index eed27b5131..8250a1fd07 100644
--- a/phpBB/styles/prosilver/template/forumlist_body.html
+++ b/phpBB/styles/prosilver/template/forumlist_body.html
@@ -103,7 +103,11 @@
<!-- ENDIF -->
<br />{forumrow.LAST_POST_TIME}
<!-- ELSE -->
- {L_NO_POSTS}<br />&nbsp;
+ {% if forumrow.U_UNAPPROVED_TOPICS %}
+ {{ lang('TOPIC_UNAPPROVED_FORUM', forumrow.TOPICS) }}
+ {% else %}
+ {{ lang('NO_POSTS') }}
+ {% endif %}
<!-- ENDIF -->
</span>
</dd>
diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html
index b292c40eb2..239a91c580 100644
--- a/phpBB/styles/prosilver/template/index_body.html
+++ b/phpBB/styles/prosilver/template/index_body.html
@@ -29,6 +29,7 @@
<!-- ENDIF -->
<input type="submit" tabindex="5" name="login" value="{L_LOGIN}" class="button2" />
{S_LOGIN_REDIRECT}
+ {S_FORM_TOKEN_LOGIN}
</fieldset>
</form>
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/login_body.html b/phpBB/styles/prosilver/template/login_body.html
index ef08035717..dc597af51d 100644
--- a/phpBB/styles/prosilver/template/login_body.html
+++ b/phpBB/styles/prosilver/template/login_body.html
@@ -33,6 +33,7 @@
<!-- ENDIF -->
{S_LOGIN_REDIRECT}
+ {S_FORM_TOKEN_LOGIN}
<dl>
<dt>&nbsp;</dt>
<dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" tabindex="6" value="{L_LOGIN}" class="button1" /></dd>
diff --git a/phpBB/styles/prosilver/template/login_body_oauth.html b/phpBB/styles/prosilver/template/login_body_oauth.html
index 156485d211..1364d01ccb 100644
--- a/phpBB/styles/prosilver/template/login_body_oauth.html
+++ b/phpBB/styles/prosilver/template/login_body_oauth.html
@@ -1,8 +1,6 @@
+<br>
<div class="content">
- <!-- BEGIN oauth -->
- <dl>
- <dt>&nbsp;</dt>
- <dd><a href="{oauth.REDIRECT_URL}" class="button2">{oauth.SERVICE_NAME}</a></dd>
- </dl>
- <!-- END oauth -->
+ {% for oauth in oauth %}
+ <a href="{{ oauth.REDIRECT_URL }}" class="button2">{{ oauth.SERVICE_NAME }}</a>
+ {% endfor %}
</div>
diff --git a/phpBB/styles/prosilver/template/login_forum.html b/phpBB/styles/prosilver/template/login_forum.html
index 7fa9736a96..c5c36d4564 100644
--- a/phpBB/styles/prosilver/template/login_forum.html
+++ b/phpBB/styles/prosilver/template/login_forum.html
@@ -25,6 +25,7 @@
<dd><input type="password" tabindex="1" id="password" name="password" size="25" class="inputbox narrow" autocomplete="off" /></dd>
</dl>
{S_LOGIN_REDIRECT}
+ {S_FORM_TOKEN_LOGIN}
<dl>
<dt>&nbsp;</dt>
<dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" id="login" class="button1" value="{L_LOGIN}" tabindex="2" /></dd>
diff --git a/phpBB/styles/prosilver/template/mcp_ban.html b/phpBB/styles/prosilver/template/mcp_ban.html
index d953f1039f..86a322435d 100644
--- a/phpBB/styles/prosilver/template/mcp_ban.html
+++ b/phpBB/styles/prosilver/template/mcp_ban.html
@@ -9,12 +9,12 @@
ban_give_reason[-1] = '';
<!-- BEGIN bans -->
- ban_length['{bans.BAN_ID}'] = '{bans.A_LENGTH}';
+ ban_length['{bans.BAN_ID}'] = '{{ bans.A_LENGTH }}';
<!-- IF bans.A_REASON -->
- ban_reason['{bans.BAN_ID}'] = '{{ bans.A_REASON | e('js') }}';
+ ban_reason['{bans.BAN_ID}'] = '{{ bans.REASON | e('js') }}';
<!-- ENDIF -->
<!-- IF bans.A_GIVE_REASON -->
- ban_give_reason['{bans.BAN_ID}'] = '{{ bans.A_GIVE_REASON | e('js') }}';
+ ban_give_reason['{bans.BAN_ID}'] = '{{ bans.GIVE_REASON | e('js') }}';
<!-- ENDIF -->
<!-- END bans -->
diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html
index cedc5031c7..5f03ad99cc 100644
--- a/phpBB/styles/prosilver/template/memberlist_body.html
+++ b/phpBB/styles/prosilver/template/memberlist_body.html
@@ -12,19 +12,28 @@
<!-- ENDIF -->
+{% EVENT memberlist_body_page_header_after %}
+
<!-- IF S_SHOW_GROUP -->
+ {% EVENT memberlist_body_group_name_before %}
<h2 class="group-title"<!-- IF GROUP_COLOR --> style="color:#{GROUP_COLOR};"<!-- ENDIF -->>{GROUP_NAME}</h2>
+ {% EVENT memberlist_body_group_name_after %}
<!-- IF U_MANAGE -->
<p class="right responsive-center manage rightside"><a href="{U_MANAGE}">{L_MANAGE_GROUP}</a></p>
<!-- ENDIF -->
<p>{GROUP_DESC} {GROUP_TYPE}</p>
+ {% EVENT memberlist_body_group_desc_after %}
+
<p>
<!-- IF AVATAR_IMG -->{AVATAR_IMG}<!-- ENDIF -->
+ {% EVENT memberlist_body_group_rank_before %}
<!-- IF RANK_IMG -->{RANK_IMG}<!-- ENDIF -->
<!-- IF GROUP_RANK -->{GROUP_RANK}<!-- ENDIF -->
+ {% EVENT memberlist_body_group_rank_after %}
</p>
<!-- ELSE -->
+ {% EVENT memberlist_body_page_title_before %}
<h2 class="solo">{PAGE_TITLE}<!-- IF SEARCH_WORDS -->{L_COLON} <a href="{U_SEARCH_WORDS}">{SEARCH_WORDS}</a><!-- ENDIF --></h2>
<div class="action-bar bar-top">
@@ -60,6 +69,7 @@
<th class="info"><!-- BEGIN custom_fields --><!-- IF not custom_fields.S_FIRST_ROW -->{L_COMMA_SEPARATOR} <!-- ENDIF -->{custom_fields.PROFILE_FIELD_NAME}<!-- END custom_fields --></th>
<th class="joined"><a href="{U_SORT_JOINED}#memberlist">{L_JOINED}</a></th>
<!-- IF U_SORT_ACTIVE --><th class="active"><a href="{U_SORT_ACTIVE}#memberlist">{L_LAST_ACTIVE}</a></th><!-- ENDIF -->
+ {% EVENT memberlist_body_memberlist_after %}
</tr>
</thead>
<tbody>
@@ -91,12 +101,14 @@
<th class="info">{% for field in custom_fields %}{% if not loop.first %}{L_COMMA_SEPARATOR} {% endif %}{{ field.PROFILE_FIELD_NAME }}{% endfor %}</th>
<th class="joined"><a href="{U_SORT_JOINED}#memberlist">{L_JOINED}</a></th>
<!-- IF U_SORT_ACTIVE --><th class="active"><a href="{U_SORT_ACTIVE}#memberlist">{L_LAST_ACTIVE}</a></th><!-- ENDIF -->
+ {% EVENT memberlist_body_leaders_set_after %}
<!-- ELSEIF S_SHOW_GROUP -->
<th class="name">{L_GROUP_MEMBERS}</th>
<th class="posts">{L_POSTS}</th>
<th class="info"><!-- BEGIN custom_fields --><!-- IF not custom_fields.S_FIRST_ROW -->{L_COMMA_SEPARATOR} <!-- ENDIF -->{custom_fields.PROFILE_FIELD_NAME}<!-- END custom_fields --></th>
<th class="joined">{L_JOINED}</th>
<!-- IF U_SORT_ACTIVE --><th class="active">{L_LAST_ACTIVE}</th><!-- ENDIF -->
+ {% EVENT memberlist_body_show_group_after %}
<!-- ENDIF -->
</tr>
</thead>
@@ -111,6 +123,7 @@
<td class="info"><!-- BEGIN custom_fields --><div>{memberrow.custom_fields.PROFILE_FIELD_VALUE}</div><!-- BEGINELSE -->&nbsp;<!-- END custom_fields --></td>
<td>{memberrow.JOINED}</td>
<!-- IF S_VIEWONLINE --><td>{memberrow.LAST_ACTIVE}&nbsp;</td><!-- ENDIF -->
+ {% EVENT memberlist_body_memberrow_after %}
</tr>
<!-- BEGINELSE -->
<tr class="bg1">
@@ -156,6 +169,8 @@
</div>
</div>
+{% EVENT memberlist_body_page_footer_before %}
+
<!-- IF S_IN_SEARCH_POPUP -->
<!-- INCLUDE simple_footer.html -->
<!-- ELSE -->
diff --git a/phpBB/styles/prosilver/template/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html
index 2da14304c7..dc29285922 100644
--- a/phpBB/styles/prosilver/template/navbar_header.html
+++ b/phpBB/styles/prosilver/template/navbar_header.html
@@ -179,17 +179,18 @@
<ul id="nav-breadcrumbs" class="nav-breadcrumbs linklist navlinks" role="menubar">
<!-- DEFINE $MICRODATA = ' itemtype="http://schema.org/ListItem" itemprop="itemListElement" itemscope' -->
+ {% set navlink_position = 1 %}
<!-- EVENT overall_header_breadcrumbs_before -->
<li class="breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList">
<!-- IF U_SITE_HOME -->
- <span class="crumb" {$MICRODATA}><a href="{U_SITE_HOME}" itemprop="url" data-navbar-reference="home"><i class="icon fa-home fa-fw" aria-hidden="true"></i><span itemprop="title">{L_SITE_HOME}</span></a></span>
+ <span class="crumb" {$MICRODATA}><a href="{U_SITE_HOME}" itemtype="https://schema.org/Thing" itemprop="item" data-navbar-reference="home"><i class="icon fa-home fa-fw" aria-hidden="true"></i><span itemprop="name">{L_SITE_HOME}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span>
<!-- ENDIF -->
<!-- EVENT overall_header_breadcrumb_prepend -->
- <span class="crumb" {$MICRODATA}><a href="{U_INDEX}" itemprop="url" accesskey="h" data-navbar-reference="index"><!-- IF not U_SITE_HOME --><i class="icon fa-home fa-fw"></i><!-- ENDIF --><span itemprop="title">{L_INDEX}</span></a></span>
+ <span class="crumb" {$MICRODATA}><a href="{U_INDEX}" itemtype="https://schema.org/Thing" itemprop="item" accesskey="h" data-navbar-reference="index"><!-- IF not U_SITE_HOME --><i class="icon fa-home fa-fw"></i><!-- ENDIF --><span itemprop="name">{L_INDEX}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span>
<!-- BEGIN navlinks -->
<!-- EVENT overall_header_navlink_prepend -->
- <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>
+ <span class="crumb" {$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->><a href="{navlinks.U_VIEW_FORUM}" itemtype="https://schema.org/Thing" itemprop="item"><span itemprop="name">{navlinks.FORUM_NAME}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span>
<!-- EVENT overall_header_navlink_append -->
<!-- END navlinks -->
<!-- EVENT overall_header_breadcrumb_append -->
diff --git a/phpBB/styles/prosilver/template/posting_attach_body.html b/phpBB/styles/prosilver/template/posting_attach_body.html
index 444713d6e0..ff5bfe1b55 100644
--- a/phpBB/styles/prosilver/template/posting_attach_body.html
+++ b/phpBB/styles/prosilver/template/posting_attach_body.html
@@ -21,6 +21,7 @@
<input type="button" class="button2" value="{L_PLUPLOAD_ADD_FILES}" id="add_files" />
</div>
+ {% EVENT posting_attach_body_file_list_before %}
<div class="panel<!-- IF not .attach_row --> hidden<!-- ENDIF --> file-list-container" id="file-list-container">
<div class="inner">
<table class="table1 zebra-list fixed-width-table">
@@ -33,7 +34,7 @@
</tr>
</thead>
<tbody class="responsive-skip-empty file-list" id="file-list">
- <tr class="attach-row" id="attach-row-tpl">
+ <tr class="attach-row attach-row-tpl" id="attach-row-tpl">
<td class="attach-name">
<span class="file-name ellipsis-text"></span>
<span class="attach-controls">
@@ -55,16 +56,18 @@
<span class="file-status"></span>
</td>
</tr>
+ {% EVENT posting_attach_body_attach_row_before %}
<!-- BEGIN attach_row -->
+ {% EVENT posting_attach_body_attach_row_prepend %}
<tr class="attach-row" data-attach-id="{attach_row.ATTACH_ID}">
<td class="attach-name">
<span class="file-name ellipsis-text"><a href="{attach_row.U_VIEW_ATTACHMENT}">{attach_row.FILENAME}</a></span>
- <!-- EVENT posting_attach_body_attach_row_controls_prepend -->
+ {% EVENT posting_attach_body_attach_row_controls_prepend %}
<span class="attach-controls">
<!-- IF S_INLINE_ATTACHMENT_OPTIONS --><input type="button" value="{L_PLACE_INLINE}" class="button2 file-inline-bbcode" />&nbsp; <!-- ENDIF -->
<input type="submit" name="delete_file[{attach_row.ASSOC_INDEX}]" value="{L_DELETE_FILE}" class="button2 file-delete" />
</span>
- <!-- EVENT posting_attach_body_attach_row_controls_append -->
+ {% EVENT posting_attach_body_attach_row_controls_append %}
<span class="clear"></span>
</td>
<td class="attach-comment">
@@ -78,10 +81,13 @@
<span class="file-status file-uploaded"></span>
</td>
</tr>
+ {% EVENT posting_attach_body_attach_row_append %}
<!-- END attach_row -->
+ {% EVENT posting_attach_body_attach_row_after %}
</tbody>
</table>
</div>
</div>
+ {% EVENT posting_attach_body_file_list_after %}
</div>
</div>
diff --git a/phpBB/styles/prosilver/template/posting_review.html b/phpBB/styles/prosilver/template/posting_review.html
index 1304046b23..033a88485e 100644
--- a/phpBB/styles/prosilver/template/posting_review.html
+++ b/phpBB/styles/prosilver/template/posting_review.html
@@ -22,7 +22,7 @@
<i class="icon fa-file fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{post_review_row.MINI_POST}</span>
</a>
<!-- ENDIF -->
- {L_POST_BY_AUTHOR}<strong> {post_review_row.POST_AUTHOR_FULL}</strong> &raquo; {post_review_row.POST_DATE}
+ {L_POST_BY_AUTHOR} <!-- EVENT posting_review_row_post_author_username_prepend --><strong>{post_review_row.POST_AUTHOR_FULL}</strong><!-- EVENT posting_review_row_post_author_username_append --> &raquo; {post_review_row.POST_DATE}
</p>
<div class="content">{post_review_row.MESSAGE}</div>
diff --git a/phpBB/styles/prosilver/template/posting_topic_review.html b/phpBB/styles/prosilver/template/posting_topic_review.html
index 93c4484ff8..8faece3447 100644
--- a/phpBB/styles/prosilver/template/posting_topic_review.html
+++ b/phpBB/styles/prosilver/template/posting_topic_review.html
@@ -54,7 +54,7 @@
<i class="icon fa-file fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{topic_review_row.MINI_POST}</span>
</a>
<!-- ENDIF -->
- {L_POST_BY_AUTHOR} <strong>{topic_review_row.POST_AUTHOR_FULL}</strong> &raquo; {topic_review_row.POST_DATE}
+ {L_POST_BY_AUTHOR} <!-- EVENT posting_topic_review_row_post_author_username_prepend --><strong>{topic_review_row.POST_AUTHOR_FULL}</strong><!-- EVENT posting_topic_review_row_post_author_username_append --> &raquo; {topic_review_row.POST_DATE}
</p>
<!-- EVENT posting_topic_review_row_post_details_after -->
diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html
index ace65254d7..d4fef9f0a5 100644
--- a/phpBB/styles/prosilver/template/ucp_agreement.html
+++ b/phpBB/styles/prosilver/template/ucp_agreement.html
@@ -62,8 +62,6 @@
<div class="content">
<h2 class="sitename-title">{SITENAME} - {AGREEMENT_TITLE}</h2>
<p>{AGREEMENT_TEXT}</p>
- <hr class="dashed" />
- <p><a href="{U_BACK}" class="button2">{L_BACK}</a></p>
</div>
</div>
</div>
diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html
index 696f621116..cfdbf9c7ea 100644
--- a/phpBB/styles/prosilver/template/ucp_attachments.html
+++ b/phpBB/styles/prosilver/template/ucp_attachments.html
@@ -44,7 +44,7 @@
</dt>
<dd class="extra">{attachrow.DOWNLOAD_COUNT}</dd>
<dd class="time"><span>{attachrow.POST_TIME}</span></dd>
- <dd class="mark"><input type="checkbox" name="attachment[{attachrow.ATTACH_ID}]" value="1" /></dd>
+ <dd class="mark"><input type="checkbox" name="attachment[{attachrow.ATTACH_ID}]" value="1"{% if attachrow.S_LOCKED %} disabled title="{{ lang('ATTACHMENT_LOCKED') }}"{% endif %} /></dd>
</dl>
</li>
<!-- END attachrow -->
diff --git a/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html b/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html
index 18316613b0..60061a3139 100644
--- a/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html
+++ b/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html
@@ -1,5 +1,5 @@
<!-- BEGIN oauth -->
- <form id="ucp" method="post" action="{S_UCP_ACTION}">
+ <form id="ucp_oauth_{oauth.SERVICE_ID}" method="post" action="{S_UCP_ACTION}">
<h3>{oauth.SERVICE_NAME}</h3>
<fieldset class="fields2">
diff --git a/phpBB/styles/prosilver/template/ucp_pm_history.html b/phpBB/styles/prosilver/template/ucp_pm_history.html
index 6362a0b824..b53eb0c7ec 100644
--- a/phpBB/styles/prosilver/template/ucp_pm_history.html
+++ b/phpBB/styles/prosilver/template/ucp_pm_history.html
@@ -36,7 +36,7 @@
<p class="author">
<span><i class="icon fa-file fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{history_row.MINI_POST}</span></span> {L_SENT_AT}{L_COLON} <strong>{history_row.SENT_DATE}</strong>
<br />
- {L_MESSAGE_BY_AUTHOR} {history_row.MESSAGE_AUTHOR_FULL}
+ {L_MESSAGE_BY_AUTHOR} <!-- EVENT ucp_pm_history_row_message_author_username_prepend -->{history_row.MESSAGE_AUTHOR_FULL}<!-- EVENT ucp_pm_history_row_message_author_username_append -->
</p>
<div class="content"><!-- IF history_row.MESSAGE -->{history_row.MESSAGE}<!-- ELSE --><span class="error">{L_MESSAGE_REMOVED_FROM_OUTBOX}</span><!-- ENDIF --></div>
<div id="message_{history_row.MSG_ID}" style="display: none;">{history_row.DECODED_MESSAGE}</div>
@@ -54,4 +54,3 @@
<i class="icon fa-chevron-circle-up fa-fw icon-gray" aria-hidden="true"></i><span>{L_BACK_TO_TOP}</span>
</a>
</p>
-
diff --git a/phpBB/styles/prosilver/template/ucp_profile_signature.html b/phpBB/styles/prosilver/template/ucp_profile_signature.html
index 614f6f440d..ed28b7ab02 100644
--- a/phpBB/styles/prosilver/template/ucp_profile_signature.html
+++ b/phpBB/styles/prosilver/template/ucp_profile_signature.html
@@ -24,6 +24,7 @@
<!-- INCLUDE posting_editor.html -->
<h3>{L_OPTIONS}</h3>
<fieldset>
+ {% EVENT ucp_profile_signature_posting_editor_options_prepend %}
<!-- IF S_BBCODE_ALLOWED -->
<div><label for="disable_bbcode"><input type="checkbox" name="disable_bbcode" id="disable_bbcode"{S_BBCODE_CHECKED} /> {L_DISABLE_BBCODE}</label></div>
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html
index bf659bb663..d7099f387f 100644
--- a/phpBB/styles/prosilver/template/viewforum_body.html
+++ b/phpBB/styles/prosilver/template/viewforum_body.html
@@ -114,6 +114,7 @@
<dd><input type="submit" name="login" tabindex="5" value="{L_LOGIN}" class="button1" /></dd>
</dl>
{S_LOGIN_REDIRECT}
+ {S_FORM_TOKEN_LOGIN}
</fieldset>
</div>
@@ -197,7 +198,7 @@
<div class="topic-poster responsive-hide left-box">
<!-- IF topicrow.S_HAS_POLL --><i class="icon fa-bar-chart fa-fw" aria-hidden="true"></i><!-- ENDIF -->
<!-- IF topicrow.ATTACH_ICON_IMG --><i class="icon fa-paperclip fa-fw" aria-hidden="true"></i><!-- ENDIF -->
- {L_POST_BY_AUTHOR} <!-- EVENT viewforum_body_topic_author_username_prepend -->{topicrow.TOPIC_AUTHOR_FULL} &raquo; {topicrow.FIRST_POST_TIME}<!-- EVENT viewforum_body_topic_author_username_append -->
+ {L_POST_BY_AUTHOR} <!-- EVENT viewforum_body_topic_author_username_prepend -->{topicrow.TOPIC_AUTHOR_FULL}<!-- EVENT viewforum_body_topic_author_username_append --> &raquo; {topicrow.FIRST_POST_TIME}
<!-- IF topicrow.S_POST_GLOBAL and FORUM_ID != topicrow.FORUM_ID --> &raquo; {L_IN} <a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a><!-- ENDIF -->
</div>
diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css
index d54c948343..0041417022 100644
--- a/phpBB/styles/prosilver/theme/cp.css
+++ b/phpBB/styles/prosilver/theme/cp.css
@@ -300,11 +300,14 @@ ol.def-rules li {
padding: 0 3px;
}
+/* DEPRECATED 3.2.6
.pmlist li.pm_message_reported_colour, .pm_message_reported_colour {
border-left-color: transparent;
border-right-color: transparent;
}
+*/
+.pmlist li.pm_message_reported_colour, .pm_message_reported_colour,
.pmlist li.pm_marked_colour, .pm_marked_colour,
.pmlist li.pm_replied_colour, .pm_replied_colour,
.pmlist li.pm_friend_colour, .pm_friend_colour,
diff --git a/phpBB/styles/prosilver/theme/plupload.css b/phpBB/styles/prosilver/theme/plupload.css
index f466803964..b1f3ae2da8 100644
--- a/phpBB/styles/prosilver/theme/plupload.css
+++ b/phpBB/styles/prosilver/theme/plupload.css
@@ -3,6 +3,10 @@
margin-bottom: 1em;
}
+.attach-row-tpl {
+ display: none;
+}
+
.file-list td {
vertical-align: middle;
}
diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php
index 72c96e2d2d..5525a0d462 100644
--- a/phpBB/viewforum.php
+++ b/phpBB/viewforum.php
@@ -198,6 +198,9 @@ if (!($forum_data['forum_type'] == FORUM_POST || (($forum_data['forum_flags'] &
// We also make this circumstance available to the template in case we want to display a notice. ;)
if (!$auth->acl_gets('f_read', 'f_list_topics', $forum_id))
{
+ // Add form token for login box
+ add_form_key('login', '_LOGIN');
+
$template->assign_vars(array(
'S_NO_READ_ACCESS' => true,
));