aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xgit-tools/setup_github_network.php292
-rw-r--r--phpBB/adm/style/acp_ext_details.html1
-rw-r--r--phpBB/adm/style/acp_ext_list.html4
-rw-r--r--phpBB/adm/style/acp_main.html5
-rw-r--r--phpBB/adm/style/acp_styles.html4
-rw-r--r--phpBB/adm/style/acp_update.html5
-rw-r--r--phpBB/adm/style/ajax.js5
-rw-r--r--phpBB/adm/style/overall_header.html2
-rw-r--r--phpBB/adm/style/simple_header.html2
-rw-r--r--phpBB/assets/javascript/core.js21
-rw-r--r--phpBB/config/db.yml4
-rw-r--r--phpBB/docs/events.md34
-rw-r--r--phpBB/download/file.php2
-rw-r--r--phpBB/includes/acp/acp_board.php13
-rw-r--r--phpBB/includes/acp/acp_extensions.php207
-rw-r--r--phpBB/includes/acp/acp_main.php18
-rw-r--r--phpBB/includes/acp/acp_styles.php4
-rw-r--r--phpBB/includes/acp/acp_update.php16
-rw-r--r--phpBB/includes/acp/info/acp_logs.php27
-rw-r--r--phpBB/includes/functions_admin.php30
-rw-r--r--phpBB/includes/functions_display.php2
-rw-r--r--phpBB/includes/functions_download.php22
-rw-r--r--phpBB/includes/functions_messenger.php13
-rw-r--r--phpBB/includes/functions_posting.php2
-rw-r--r--phpBB/includes/functions_user.php28
-rw-r--r--phpBB/includes/mcp/mcp_forum.php2
-rw-r--r--phpBB/includes/mcp/mcp_main.php2
-rw-r--r--phpBB/includes/mcp/mcp_post.php114
-rw-r--r--phpBB/includes/message_parser.php2
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewfolder.php2
-rw-r--r--phpBB/language/en/acp/attachments.php2
-rw-r--r--phpBB/language/en/acp/board.php12
-rw-r--r--phpBB/language/en/acp/common.php2
-rw-r--r--phpBB/language/en/acp/styles.php1
-rw-r--r--phpBB/language/en/common.php1
-rw-r--r--phpBB/language/en/install.php1
-rw-r--r--phpBB/phpbb/auth/auth.php12
-rw-r--r--phpBB/phpbb/cache/driver/file.php2
-rw-r--r--phpBB/phpbb/cache/driver/memcached.php134
-rw-r--r--phpBB/phpbb/db/migration/data/v310/notification_options_reconvert.php1
-rw-r--r--phpBB/phpbb/db/migration/data/v31x/add_smtp_ssl_context_config_options.php32
-rw-r--r--phpBB/phpbb/db/migration/profilefield_base_migration.php1
-rw-r--r--phpBB/phpbb/di/container_builder.php14
-rw-r--r--phpBB/phpbb/di/extension/config.php6
-rw-r--r--phpBB/phpbb/event/php_exporter.php4
-rw-r--r--phpBB/phpbb/extension/manager.php32
-rw-r--r--phpBB/phpbb/extension/metadata_manager.php123
-rw-r--r--phpBB/phpbb/feed/attachments_base.php34
-rw-r--r--phpBB/phpbb/feed/forum.php2
-rw-r--r--phpBB/phpbb/feed/news.php2
-rw-r--r--phpBB/phpbb/feed/overall.php2
-rw-r--r--phpBB/phpbb/feed/topic.php2
-rw-r--r--phpBB/phpbb/feed/topics.php2
-rw-r--r--phpBB/phpbb/feed/topics_active.php2
-rw-r--r--phpBB/phpbb/profilefields/type/type_date.php2
-rw-r--r--phpBB/phpbb/request/request.php6
-rw-r--r--phpBB/phpbb/search/fulltext_mysql.php25
-rw-r--r--phpBB/phpbb/template/base.php8
-rw-r--r--phpBB/phpbb/template/context.php160
-rw-r--r--phpBB/phpbb/template/template.php17
-rw-r--r--phpBB/phpbb/template/twig/extension.php3
-rw-r--r--phpBB/phpbb/version_helper.php114
-rw-r--r--phpBB/posting.php15
-rw-r--r--phpBB/styles/prosilver/template/bbcode.html4
-rw-r--r--phpBB/styles/prosilver/template/forum_fn.js2
-rw-r--r--phpBB/styles/prosilver/template/mcp_post.html30
-rw-r--r--phpBB/styles/prosilver/template/memberlist_team.html2
-rw-r--r--phpBB/styles/prosilver/template/search_results.html2
-rw-r--r--phpBB/styles/prosilver/theme/common.css8
-rw-r--r--phpBB/styles/prosilver/theme/content.css2
-rw-r--r--phpBB/styles/prosilver/theme/forms.css2
-rw-r--r--phpBB/styles/subsilver2/template/memberlist_search.html2
-rw-r--r--phpBB/styles/subsilver2/template/memberlist_team.html2
-rw-r--r--phpBB/styles/subsilver2/template/overall_header.html2
-rw-r--r--phpBB/ucp.php25
-rw-r--r--phpBB/viewforum.php23
-rw-r--r--phpBB/viewonline.php4
-rw-r--r--phpBB/viewtopic.php14
-rw-r--r--tests/di/create_container_test.php2
-rw-r--r--tests/di/fixtures/config/services.yml3
-rw-r--r--tests/di/fixtures/other_config/services.yml3
-rw-r--r--tests/event/fixtures/trigger_many_vars.test2
-rw-r--r--tests/feed/attachments_base_test.php94
-rw-r--r--tests/feed/attachments_mock_feed.php31
-rw-r--r--tests/mcp/fixtures/post_ip.xml73
-rw-r--r--tests/mcp/post_ip_test.php67
-rw-r--r--tests/mock/extension_manager.php2
-rw-r--r--tests/template/template_test.php168
-rw-r--r--tests/version/version_test.php492
89 files changed, 2056 insertions, 666 deletions
diff --git a/git-tools/setup_github_network.php b/git-tools/setup_github_network.php
deleted file mode 100755
index 100ac53b33..0000000000
--- a/git-tools/setup_github_network.php
+++ /dev/null
@@ -1,292 +0,0 @@
-#!/usr/bin/env php
-<?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.
-*
-*/
-
-function show_usage()
-{
- $filename = basename(__FILE__);
-
- echo "$filename adds repositories of a github network as remotes to a local git repository.\n";
- echo "\n";
-
- echo "Usage: [php] $filename -s collaborators|organisation|contributors|forks [OPTIONS]\n";
- echo "\n";
-
- echo "Scopes:\n";
- echo " collaborators Repositories of people who have push access to the specified repository\n";
- echo " contributors Repositories of people who have contributed to the specified repository\n";
- echo " organisation Repositories of members of the organisation at github\n";
- echo " forks All repositories of the whole github network\n";
- echo "\n";
-
- echo "Options:\n";
- echo " -s scope See description above (mandatory)\n";
- echo " -u github_username Overwrites the github username (optional)\n";
- echo " -r repository_name Overwrites the repository name (optional)\n";
- echo " -m your_github_username Sets up ssh:// instead of git:// for pushable repositories (optional)\n";
- echo " -d Outputs the commands instead of running them (optional)\n";
- echo " -h This help text\n";
-
- exit(1);
-}
-
-// Handle arguments
-$opts = getopt('s:u:r:m:dh');
-
-if (empty($opts) || isset($opts['h']))
-{
- show_usage();
-}
-
-$scope = get_arg($opts, 's', '');
-$username = get_arg($opts, 'u', 'phpbb');
-$repository = get_arg($opts, 'r', 'phpbb3');
-$developer = get_arg($opts, 'm', '');
-$dry_run = !get_arg($opts, 'd', true);
-run(null, $dry_run);
-exit(work($scope, $username, $repository, $developer));
-
-function work($scope, $username, $repository, $developer)
-{
- // Get some basic data
- $forks = get_forks($username, $repository);
- $collaborators = get_collaborators($username, $repository);
-
- if ($forks === false || $collaborators === false)
- {
- echo "Error: failed to retrieve forks or collaborators\n";
- return 1;
- }
-
- switch ($scope)
- {
- case 'collaborators':
- $remotes = array_intersect_key($forks, $collaborators);
- break;
-
- case 'organisation':
- $remotes = array_intersect_key($forks, get_organisation_members($username));
- break;
-
- case 'contributors':
- $remotes = array_intersect_key($forks, get_contributors($username, $repository));
- break;
-
- case 'forks':
- $remotes = $forks;
- break;
-
- default:
- show_usage();
- }
-
- if (file_exists('.git'))
- {
- add_remote($username, $repository, isset($collaborators[$developer]));
- }
- else
- {
- clone_repository($username, $repository, isset($collaborators[$developer]));
- }
-
- // Add private security repository for developers
- if ($username == 'phpbb' && $repository == 'phpbb3' && isset($collaborators[$developer]))
- {
- run("git remote add $username-security " . get_repository_url($username, "$repository-security", true));
- }
-
- // Skip blessed repository.
- unset($remotes[$username]);
-
- foreach ($remotes as $remote)
- {
- add_remote($remote['username'], $remote['repository'], $remote['username'] == $developer);
- }
-
- run('git remote update');
-}
-
-function clone_repository($username, $repository, $pushable = false)
-{
- $url = get_repository_url($username, $repository, false);
- run("git clone $url ./ --origin $username");
-
- if ($pushable)
- {
- $ssh_url = get_repository_url($username, $repository, true);
- run("git remote set-url --push $username $ssh_url");
- }
-}
-
-function add_remote($username, $repository, $pushable = false)
-{
- $url = get_repository_url($username, $repository, false);
- run("git remote add $username $url");
-
- if ($pushable)
- {
- $ssh_url = get_repository_url($username, $repository, true);
- run("git remote set-url --push $username $ssh_url");
- }
-}
-
-function get_repository_url($username, $repository, $ssh = false)
-{
- $url_base = ($ssh) ? 'git@github.com:' : 'git://github.com/';
-
- return $url_base . $username . '/' . $repository . '.git';
-}
-
-function api_request($query)
-{
- return api_url_request("https://api.github.com/$query?per_page=100");
-}
-
-function api_url_request($url)
-{
- $contents = file_get_contents($url, false, stream_context_create(array(
- 'http' => array(
- 'header' => "User-Agent: phpBB/1.0\r\n",
- ),
- )));
-
- $sub_request_result = array();
- // Check headers for pagination links
- if (!empty($http_response_header))
- {
- foreach ($http_response_header as $header_element)
- {
- // Find Link Header which gives us a link to the next page
- if (strpos($header_element, 'Link: ') === 0)
- {
- list($head, $header_content) = explode(': ', $header_element);
- foreach (explode(', ', $header_content) as $links)
- {
- list($url, $rel) = explode('; ', $links);
- if ($rel == 'rel="next"')
- {
- // Found a next link, follow it and merge the results
- $sub_request_result = api_url_request(substr($url, 1, -1));
- }
- }
- }
- }
- }
-
- if ($contents === false)
- {
- return false;
- }
- $contents = json_decode($contents);
-
- if (isset($contents->message) && strpos($contents->message, 'API Rate Limit') === 0)
- {
- throw new RuntimeException('Reached github API Rate Limit. Please try again later' . "\n", 4);
- }
-
- return ($sub_request_result) ? array_merge($sub_request_result, $contents) : $contents;
-}
-
-function get_contributors($username, $repository)
-{
- $request = api_request("repos/$username/$repository/stats/contributors");
- if ($request === false)
- {
- return false;
- }
-
- $usernames = array();
- foreach ($request as $contribution)
- {
- $usernames[$contribution->author->login] = $contribution->author->login;
- }
-
- return $usernames;
-}
-
-function get_organisation_members($username)
-{
- $request = api_request("orgs/$username/public_members");
- if ($request === false)
- {
- return false;
- }
-
- $usernames = array();
- foreach ($request as $member)
- {
- $usernames[$member->login] = $member->login;
- }
-
- return $usernames;
-}
-
-function get_collaborators($username, $repository)
-{
- $request = api_request("repos/$username/$repository/collaborators");
- if ($request === false)
- {
- return false;
- }
-
- $usernames = array();
- foreach ($request as $collaborator)
- {
- $usernames[$collaborator->login] = $collaborator->login;
- }
-
- return $usernames;
-}
-
-function get_forks($username, $repository)
-{
- $request = api_request("repos/$username/$repository/forks");
- if ($request === false)
- {
- return false;
- }
-
- $usernames = array();
- foreach ($request as $fork)
- {
- $usernames[$fork->owner->login] = array(
- 'username' => $fork->owner->login,
- 'repository' => $fork->name,
- );
- }
-
- return $usernames;
-}
-
-function get_arg($array, $index, $default)
-{
- return isset($array[$index]) ? $array[$index] : $default;
-}
-
-function run($cmd, $dry = false)
-{
- static $dry_run;
-
- if (is_null($cmd))
- {
- $dry_run = $dry;
- }
- else if (!empty($dry_run))
- {
- echo "$cmd\n";
- }
- else
- {
- passthru(escapeshellcmd($cmd));
- }
-}
diff --git a/phpBB/adm/style/acp_ext_details.html b/phpBB/adm/style/acp_ext_details.html
index 830c2e3cb4..465a89e17a 100644
--- a/phpBB/adm/style/acp_ext_details.html
+++ b/phpBB/adm/style/acp_ext_details.html
@@ -136,4 +136,5 @@
<!-- END meta_authors -->
</fieldset>
+ <!-- EVENT acp_ext_details_end -->
<!-- INCLUDE overall_footer.html -->
diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html
index ccc39ea76d..af9e00a614 100644
--- a/phpBB/adm/style/acp_ext_list.html
+++ b/phpBB/adm/style/acp_ext_list.html
@@ -48,7 +48,7 @@
</tr>
<!-- BEGIN enabled -->
<tr class="ext_enabled row-highlight">
- <td><strong title="{enabled.NAME}">{enabled.META_DISPLAY_NAME}</strong></td>
+ <td><strong title="{enabled.NAME}">{enabled.META_DISPLAY_NAME}</strong><!-- EVENT acp_ext_list_enabled_name_after --></td>
<td style="text-align: center;">
<!-- IF enabled.S_VERSIONCHECK -->
<strong <!-- IF enabled.S_UP_TO_DATE -->style="color: #228822;"<!-- ELSE -->style="color: #BC2A4D;"<!-- ENDIF -->>{enabled.META_VERSION}</strong>
@@ -73,7 +73,7 @@
</tr>
<!-- BEGIN disabled -->
<tr class="ext_disabled row-highlight">
- <td><strong title="{disabled.NAME}">{disabled.META_DISPLAY_NAME}</strong></td>
+ <td><strong title="{disabled.NAME}">{disabled.META_DISPLAY_NAME}</strong><!-- EVENT acp_ext_list_disabled_name_after --></td>
<td style="text-align: center;">
<!-- IF disabled.S_VERSIONCHECK -->
<strong <!-- IF disabled.S_UP_TO_DATE -->style="color: #228822;"<!-- ELSE -->style="color: #BC2A4D;"<!-- ENDIF -->>{disabled.META_VERSION}</strong>
diff --git a/phpBB/adm/style/acp_main.html b/phpBB/adm/style/acp_main.html
index efcb25cb68..1bdb7b8d2a 100644
--- a/phpBB/adm/style/acp_main.html
+++ b/phpBB/adm/style/acp_main.html
@@ -30,6 +30,11 @@
<p><a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a> &middot; <a href="{U_VERSIONCHECK}">{L_MORE_INFORMATION}</a></p>
</div>
<!-- ENDIF -->
+ <!-- IF S_VERSION_UPGRADEABLE -->
+ <div class="errorbox notice">
+ <p>{UPGRADE_INSTRUCTIONS}</p>
+ </div>
+ <!-- ENDIF -->
<!-- IF S_SEARCH_INDEX_MISSING -->
<div class="errorbox">
diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html
index a36d15fe73..43c2f96a65 100644
--- a/phpBB/adm/style/acp_styles.html
+++ b/phpBB/adm/style/acp_styles.html
@@ -52,6 +52,10 @@
<dd><strong>{STYLE_PATH}</strong></dd>
</dl>
<dl>
+ <dt><label>{L_STYLE_VERSION}{L_COLON}</label></dt>
+ <dd><strong>{STYLE_VERSION}</strong></dd>
+ </dl>
+ <dl>
<dt><label for="name">{L_COPYRIGHT}{L_COLON}</label></dt>
<dd><strong>{STYLE_COPYRIGHT}</strong></dd>
</dl>
diff --git a/phpBB/adm/style/acp_update.html b/phpBB/adm/style/acp_update.html
index 351a3ba26c..5288833d05 100644
--- a/phpBB/adm/style/acp_update.html
+++ b/phpBB/adm/style/acp_update.html
@@ -20,6 +20,11 @@
<p>{L_VERSION_NOT_UP_TO_DATE_ACP} - <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a></p>
</div>
<!-- ENDIF -->
+<!-- IF S_VERSION_UPGRADEABLE -->
+ <div class="errorbox notice">
+ <p>{UPGRADE_INSTRUCTIONS}</p>
+ </div>
+<!-- ENDIF -->
<fieldset>
<legend></legend>
diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js
index a7ecf8ff7b..77fd28fbe6 100644
--- a/phpBB/adm/style/ajax.js
+++ b/phpBB/adm/style/ajax.js
@@ -173,10 +173,11 @@ function submitPermissions() {
$.ajax({
url: $form.action,
type: 'POST',
- data: formData + '&' + $submitAllButton.name + '=' + encodeURIComponent($submitAllButton.value) +
+ data: formData + '&' + $submitButton.name + '=' + encodeURIComponent($submitButton.value) +
'&creation_time=' + $form.find('input[type=hidden][name=creation_time]')[0].value +
'&form_token=' + $form.find('input[type=hidden][name=form_token]')[0].value +
- '&' + $form.children('input[type=hidden]').serialize(),
+ '&' + $form.children('input[type=hidden]').serialize() +
+ '&' + $form.find('input[type=checkbox][name^=inherit]').serialize(),
success: handlePermissionReturn,
error: handlePermissionReturn
});
diff --git a/phpBB/adm/style/overall_header.html b/phpBB/adm/style/overall_header.html
index d399c680ee..bd8caf1443 100644
--- a/phpBB/adm/style/overall_header.html
+++ b/phpBB/adm/style/overall_header.html
@@ -53,7 +53,7 @@ function marklist(id, name, state)
for (var r = 0; r < rb.length; r++)
{
- if (rb[r].name.substr(0, name.length) == name)
+ if (rb[r].name.substr(0, name.length) == name && rb[r].disabled !== true)
{
rb[r].checked = state;
}
diff --git a/phpBB/adm/style/simple_header.html b/phpBB/adm/style/simple_header.html
index 9f47b2052b..439645a211 100644
--- a/phpBB/adm/style/simple_header.html
+++ b/phpBB/adm/style/simple_header.html
@@ -66,7 +66,7 @@ function marklist(id, name, state)
for (var r = 0; r < rb.length; r++)
{
- if (rb[r].name.substr(0, name.length) == name)
+ if (rb[r].name.substr(0, name.length) == name && rb[r].disabled !== true)
{
rb[r].checked = state;
}
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index f7ace80705..b079043396 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -33,21 +33,28 @@ phpbb.loadingIndicator = function() {
if (!$loadingIndicator.is(':visible')) {
$loadingIndicator.fadeIn(phpbb.alertTime);
- // Wait fifteen seconds and display an error if nothing has been returned by then.
+ // Wait 60 seconds and display an error if nothing has been returned by then.
phpbb.clearLoadingTimeout();
phpbbAlertTimer = setTimeout(function() {
- var $alert = $('#phpbb_alert');
-
- if ($loadingIndicator.is(':visible')) {
- phpbb.alert($alert.attr('data-l-err'), $alert.attr('data-l-timeout-processing-req'));
- }
- }, 15000);
+ phpbb.showTimeoutMessage();
+ }, 60000);
}
return $loadingIndicator;
};
/**
+ * Show timeout message
+ */
+phpbb.showTimeoutMessage = function () {
+ var $alert = $('#phpbb_alert');
+
+ if ($loadingIndicator.is(':visible')) {
+ phpbb.alert($alert.attr('data-l-err'), $alert.attr('data-l-timeout-processing-req'));
+ }
+};
+
+/**
* Clear loading alert timeout
*/
phpbb.clearLoadingTimeout = function() {
diff --git a/phpBB/config/db.yml b/phpBB/config/db.yml
index d11669d8a3..4ab4401bbd 100644
--- a/phpBB/config/db.yml
+++ b/phpBB/config/db.yml
@@ -5,9 +5,7 @@ services:
- @service_container
dbal.conn.driver:
- class: %dbal.driver.class%
- calls:
- - [sql_connect, [%dbal.dbhost%, %dbal.dbuser%, %dbal.dbpasswd%, %dbal.dbname%, %dbal.dbport%, false, %dbal.new_link%]]
+ synthetic: true
dbal.tools:
class: phpbb\db\tools
diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md
index 12a8a3dfeb..2f28307c24 100644
--- a/phpBB/docs/events.md
+++ b/phpBB/docs/events.md
@@ -58,12 +58,30 @@ acp_email_options_after
* Since: 3.1.2-RC1
* Purpose: Add settings to mass email form
+acp_ext_details_end
+===
+* Location: adm/style/acp_ext_details.html
+* Since: 3.1.11-RC1
+* Purpose: Add more detailed information on extension after the available information.
+
+acp_ext_list_disabled_name_after
+===
+* Location: adm/style/acp_ext_list.html
+* Since: 3.1.11-RC1
+* Purpose: Add content after the name of disabled extensions in the list
+
acp_ext_list_disabled_title_after
===
* Location: adm/style/acp_ext_list.html
* Since: 3.1.11-RC1
* Purpose: Add text after disabled extensions section title.
+acp_ext_list_enabled_name_after
+===
+* Location: adm/style/acp_ext_list.html
+* Since: 3.1.11-RC1
+* Purpose: Add content after the name of enabled extensions in the list
+
acp_ext_list_enabled_title_after
===
* Location: adm/style/acp_ext_list.html
@@ -1057,6 +1075,22 @@ memberlist_search_sorting_options_before
* Since: 3.1.2-RC1
* Purpose: Add information before the search sorting options field.
+memberlist_team_username_append
+===
+* Locations:
+ + styles/prosilver/template/memberlist_team.html
+ + styles/subsilver2/template/memberlist_team.html
+* Since: 3.1.11-RC1
+* Purpose: Append information to username of team member
+
+memberlist_team_username_prepend
+===
+* Locations:
+ + styles/prosilver/template/memberlist_team.html
+ + styles/subsilver2/template/memberlist_team.html
+* Since: 3.1.11-RC1
+* Purpose: Add information before team user username
+
memberlist_view_contact_after
===
* Locations:
diff --git a/phpBB/download/file.php b/phpBB/download/file.php
index 56ea273d5c..e60ffad6b0 100644
--- a/phpBB/download/file.php
+++ b/phpBB/download/file.php
@@ -262,7 +262,7 @@ else
* @var string mode Download mode
* @var bool thumbnail Flag indicating if the file is a thumbnail
* @since 3.1.6-RC1
- * @change 3.1.7-RC1 Fixing wrong name of a variable (replacing "extension" by "extensions")
+ * @changed 3.1.7-RC1 Fixing wrong name of a variable (replacing "extension" by "extensions")
*/
$vars = array(
'attach_id',
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index c8f6f426c6..5c3c7f30aa 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -26,7 +26,7 @@ if (!defined('IN_PHPBB'))
class acp_board
{
var $u_action;
- var $new_config = array();
+ var $new_config;
function main($id, $mode)
{
@@ -318,9 +318,9 @@ class acp_board
'title' => 'ACP_COOKIE_SETTINGS',
'vars' => array(
'legend1' => 'ACP_COOKIE_SETTINGS',
- 'cookie_domain' => array('lang' => 'COOKIE_DOMAIN', 'validate' => 'string', 'type' => 'text::255', 'explain' => false),
- 'cookie_name' => array('lang' => 'COOKIE_NAME', 'validate' => 'string', 'type' => 'text::16', 'explain' => false),
- 'cookie_path' => array('lang' => 'COOKIE_PATH', 'validate' => 'string', 'type' => 'text::255', 'explain' => false),
+ 'cookie_domain' => array('lang' => 'COOKIE_DOMAIN', 'validate' => 'string', 'type' => 'text::255', 'explain' => true),
+ 'cookie_name' => array('lang' => 'COOKIE_NAME', 'validate' => 'string', 'type' => 'text::16', 'explain' => true),
+ 'cookie_path' => array('lang' => 'COOKIE_PATH', 'validate' => 'string', 'type' => 'text::255', 'explain' => true),
'cookie_secure' => array('lang' => 'COOKIE_SECURE', 'validate' => 'bool', 'type' => 'radio:disabled_enabled', 'explain' => true),
)
);
@@ -454,6 +454,9 @@ class acp_board
'smtp_auth_method' => array('lang' => 'SMTP_AUTH_METHOD', 'validate' => 'string', 'type' => 'select', 'method' => 'mail_auth_select', 'explain' => true),
'smtp_username' => array('lang' => 'SMTP_USERNAME', 'validate' => 'string', 'type' => 'text:25:255', 'explain' => true),
'smtp_password' => array('lang' => 'SMTP_PASSWORD', 'validate' => 'string', 'type' => 'password:25:255', 'explain' => true),
+ 'smtp_verify_peer' => array('lang' => 'SMTP_VERIFY_PEER', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'smtp_verify_peer_name' => array('lang' => 'SMTP_VERIFY_PEER_NAME', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'smtp_allow_self_signed'=> array('lang' => 'SMTP_ALLOW_SELF_SIGNED','validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend3' => 'ACP_SUBMIT_CHANGES',
)
@@ -482,7 +485,7 @@ class acp_board
$user->add_lang($display_vars['lang']);
}
- $this->new_config = $config;
+ $this->new_config = clone $config;
$cfg_array = (isset($_REQUEST['config'])) ? utf8_normalize_nfc(request_var('config', array('' => ''), true)) : $this->new_config;
$error = array();
diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php
index 5a2ded91e2..9e72ab83f8 100644
--- a/phpBB/includes/acp/acp_extensions.php
+++ b/phpBB/includes/acp/acp_extensions.php
@@ -22,21 +22,23 @@ if (!defined('IN_PHPBB'))
class acp_extensions
{
var $u_action;
+ var $tpl_name;
+ var $page_title;
- private $db;
private $config;
private $template;
private $user;
private $cache;
private $log;
private $request;
+ private $phpbb_dispatcher;
+ private $ext_manager;
function main()
{
// Start the page
- global $config, $user, $template, $request, $phpbb_extension_manager, $db, $phpbb_root_path, $phpEx, $phpbb_log, $cache, $phpbb_dispatcher;
+ global $config, $user, $template, $request, $phpbb_extension_manager, $phpbb_root_path, $phpEx, $phpbb_log, $cache, $phpbb_dispatcher;
- $this->db = $db;
$this->config = $config;
$this->template = $template;
$this->user = $user;
@@ -44,49 +46,57 @@ class acp_extensions
$this->request = $request;
$this->log = $phpbb_log;
$this->phpbb_dispatcher = $phpbb_dispatcher;
+ $this->ext_manager = $phpbb_extension_manager;
- $user->add_lang(array('install', 'acp/extensions', 'migrator'));
+ $this->user->add_lang(array('install', 'acp/extensions', 'migrator'));
$this->page_title = 'ACP_EXTENSIONS';
- $action = $request->variable('action', 'list');
- $ext_name = $request->variable('ext_name', '');
+ $action = $this->request->variable('action', 'list');
+ $ext_name = $this->request->variable('ext_name', '');
// What is a safe limit of execution time? Half the max execution time should be safe.
$safe_time_limit = (ini_get('max_execution_time') / 2);
$start_time = time();
+ // Cancel action
+ if ($this->request->is_set_post('cancel'))
+ {
+ $action = 'list';
+ $ext_name = '';
+ }
+
+ if (in_array($action, array('enable', 'disable', 'delete_data')) && !check_link_hash($this->request->variable('hash', ''), $action . '.' . $ext_name))
+ {
+ trigger_error('FORM_INVALID', E_USER_WARNING);
+ }
+
/**
* Event to run a specific action on extension
*
- * @event core.acp_extensions_run_action
- * @var string action Action to run
+ * @event core.acp_extensions_run_action_before
+ * @var string action Action to run; if the event completes execution of the action, should be set to 'none'
* @var string u_action Url we are at
* @var string ext_name Extension name from request
* @var int safe_time_limit Safe limit of execution time
* @var int start_time Start time
+ * @var string tpl_name Template file to load
* @since 3.1.11-RC1
+ * @changed 3.2.1-RC1 Renamed to core.acp_extensions_run_action_before, added tpl_name, added action 'none'
*/
$u_action = $this->u_action;
- $vars = array('action', 'u_action', 'ext_name', 'safe_time_limit', 'start_time');
- extract($this->phpbb_dispatcher->trigger_event('core.acp_extensions_run_action', compact($vars)));
+ $tpl_name = '';
+ $vars = array('action', 'u_action', 'ext_name', 'safe_time_limit', 'start_time', 'tpl_name');
+ extract($this->phpbb_dispatcher->trigger_event('core.acp_extensions_run_action_before', compact($vars)));
- // Cancel action
- if ($request->is_set_post('cancel'))
- {
- $action = 'list';
- $ext_name = '';
- }
-
- if (in_array($action, array('enable', 'disable', 'delete_data')) && !check_link_hash($request->variable('hash', ''), $action . '.' . $ext_name))
- {
- trigger_error('FORM_INVALID', E_USER_WARNING);
- }
+ // In case they have been updated by the event
+ $this->u_action = $u_action;
+ $this->tpl_name = $tpl_name;
// If they've specified an extension, let's load the metadata manager and validate it.
if ($ext_name)
{
- $md_manager = new \phpbb\extension\metadata_manager($ext_name, $config, $phpbb_extension_manager, $template, $user, $phpbb_root_path);
+ $md_manager = $this->ext_manager->create_extension_metadata_manager($ext_name, $this->template);
try
{
@@ -101,6 +111,10 @@ class acp_extensions
// What are we doing?
switch ($action)
{
+ case 'none':
+ // Intentionally empty, used by extensions that execute additional actions in the prior event
+ break;
+
case 'set_config_version_check_force_unstable':
$force_unstable = $this->request->variable('force_unstable', false);
@@ -110,12 +124,12 @@ class acp_extensions
'force_unstable' => $force_unstable,
));
- confirm_box(false, $user->lang('EXTENSION_FORCE_UNSTABLE_CONFIRM'), $s_hidden_fields);
+ confirm_box(false, $this->user->lang('EXTENSION_FORCE_UNSTABLE_CONFIRM'), $s_hidden_fields);
}
else
{
- $config->set('extension_force_unstable', false);
- trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
+ $this->config->set('extension_force_unstable', false);
+ trigger_error($this->user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
}
break;
@@ -123,17 +137,17 @@ class acp_extensions
default:
if (confirm_box(true))
{
- $config->set('extension_force_unstable', true);
- trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
+ $this->config->set('extension_force_unstable', true);
+ trigger_error($this->user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
}
- $this->list_enabled_exts($phpbb_extension_manager);
- $this->list_disabled_exts($phpbb_extension_manager);
- $this->list_available_exts($phpbb_extension_manager);
+ $this->list_enabled_exts();
+ $this->list_disabled_exts();
+ $this->list_available_exts();
$this->template->assign_vars(array(
'U_VERSIONCHECK_FORCE' => $this->u_action . '&amp;action=list&amp;versioncheck_force=1',
- 'FORCE_UNSTABLE' => $config['extension_force_unstable'],
+ 'FORCE_UNSTABLE' => $this->config['extension_force_unstable'],
'U_ACTION' => $this->u_action,
));
@@ -141,30 +155,29 @@ class acp_extensions
break;
case 'enable_pre':
- if (!$md_manager->validate_dir())
+ try
{
- trigger_error($user->lang['EXTENSION_DIR_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
+ $md_manager->validate_enable();
}
-
- if (!$md_manager->validate_enable())
+ catch (\phpbb\extension\exception $e)
{
- trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
+ trigger_error($e . adm_back_link($this->u_action), E_USER_WARNING);
}
- $extension = $phpbb_extension_manager->get_extension($ext_name);
+ $extension = $this->ext_manager->get_extension($ext_name);
if (!$extension->is_enableable())
{
- trigger_error($user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
+ trigger_error($this->user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
- if ($phpbb_extension_manager->is_enabled($ext_name))
+ if ($this->ext_manager->is_enabled($ext_name))
{
redirect($this->u_action);
}
$this->tpl_name = 'acp_ext_enable';
- $template->assign_vars(array(
+ $this->template->assign_vars(array(
'PRE' => true,
'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_ENABLE_CONFIRM', $md_manager->get_metadata('display-name')),
'U_ENABLE' => $this->u_action . '&amp;action=enable&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('enable.' . $ext_name),
@@ -172,57 +185,56 @@ class acp_extensions
break;
case 'enable':
- if (!$md_manager->validate_dir())
+ try
{
- trigger_error($user->lang['EXTENSION_DIR_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
+ $md_manager->validate_enable();
}
-
- if (!$md_manager->validate_enable())
+ catch (\phpbb\extension\exception $e)
{
- trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
+ trigger_error($e . adm_back_link($this->u_action), E_USER_WARNING);
}
- $extension = $phpbb_extension_manager->get_extension($ext_name);
+ $extension = $this->ext_manager->get_extension($ext_name);
if (!$extension->is_enableable())
{
- trigger_error($user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
+ trigger_error($this->user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
}
try
{
- while ($phpbb_extension_manager->enable_step($ext_name))
+ while ($this->ext_manager->enable_step($ext_name))
{
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{
- $template->assign_var('S_NEXT_STEP', true);
+ $this->template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=enable&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('enable.' . $ext_name));
}
}
- $this->log->add('admin', $user->data['user_id'], $user->ip, 'LOG_EXT_ENABLE', time(), array($ext_name));
+ $this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_ENABLE', time(), array($ext_name));
}
catch (\phpbb\db\migration\exception $e)
{
- $template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user));
+ $this->template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($this->user));
}
$this->tpl_name = 'acp_ext_enable';
- $template->assign_vars(array(
+ $this->template->assign_vars(array(
'U_RETURN' => $this->u_action . '&amp;action=list',
));
break;
case 'disable_pre':
- if (!$phpbb_extension_manager->is_enabled($ext_name))
+ if (!$this->ext_manager->is_enabled($ext_name))
{
redirect($this->u_action);
}
$this->tpl_name = 'acp_ext_disable';
- $template->assign_vars(array(
+ $this->template->assign_vars(array(
'PRE' => true,
'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_DISABLE_CONFIRM', $md_manager->get_metadata('display-name')),
'U_DISABLE' => $this->u_action . '&amp;action=disable&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('disable.' . $ext_name),
@@ -230,38 +242,38 @@ class acp_extensions
break;
case 'disable':
- if (!$phpbb_extension_manager->is_enabled($ext_name))
+ if (!$this->ext_manager->is_enabled($ext_name))
{
redirect($this->u_action);
}
- while ($phpbb_extension_manager->disable_step($ext_name))
+ while ($this->ext_manager->disable_step($ext_name))
{
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{
- $template->assign_var('S_NEXT_STEP', true);
+ $this->template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=disable&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('disable.' . $ext_name));
}
}
- $this->log->add('admin', $user->data['user_id'], $user->ip, 'LOG_EXT_DISABLE', time(), array($ext_name));
+ $this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_DISABLE', time(), array($ext_name));
$this->tpl_name = 'acp_ext_disable';
- $template->assign_vars(array(
+ $this->template->assign_vars(array(
'U_RETURN' => $this->u_action . '&amp;action=list',
));
break;
case 'delete_data_pre':
- if ($phpbb_extension_manager->is_enabled($ext_name))
+ if ($this->ext_manager->is_enabled($ext_name))
{
redirect($this->u_action);
}
$this->tpl_name = 'acp_ext_delete_data';
- $template->assign_vars(array(
+ $this->template->assign_vars(array(
'PRE' => true,
'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_DELETE_DATA_CONFIRM', $md_manager->get_metadata('display-name')),
'U_PURGE' => $this->u_action . '&amp;action=delete_data&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('delete_data.' . $ext_name),
@@ -269,33 +281,33 @@ class acp_extensions
break;
case 'delete_data':
- if ($phpbb_extension_manager->is_enabled($ext_name))
+ if ($this->ext_manager->is_enabled($ext_name))
{
redirect($this->u_action);
}
try
{
- while ($phpbb_extension_manager->purge_step($ext_name))
+ while ($this->ext_manager->purge_step($ext_name))
{
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{
- $template->assign_var('S_NEXT_STEP', true);
+ $this->template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=delete_data&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('delete_data.' . $ext_name));
}
}
- $this->log->add('admin', $user->data['user_id'], $user->ip, 'LOG_EXT_PURGE', time(), array($ext_name));
+ $this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_PURGE', time(), array($ext_name));
}
catch (\phpbb\db\migration\exception $e)
{
- $template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user));
+ $this->template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($this->user));
}
$this->tpl_name = 'acp_ext_delete_data';
- $template->assign_vars(array(
+ $this->template->assign_vars(array(
'U_RETURN' => $this->u_action . '&amp;action=list',
));
break;
@@ -306,28 +318,25 @@ class acp_extensions
try
{
- $updates_available = $this->version_check($md_manager, $request->variable('versioncheck_force', false));
+ $updates_available = $this->version_check($md_manager, $this->request->variable('versioncheck_force', false));
- $template->assign_vars(array(
+ $this->template->assign_vars(array(
'S_UP_TO_DATE' => empty($updates_available),
'S_VERSIONCHECK' => true,
'UP_TO_DATE_MSG' => $this->user->lang(empty($updates_available) ? 'UP_TO_DATE' : 'NOT_UP_TO_DATE', $md_manager->get_metadata('display-name')),
));
- foreach ($updates_available as $branch => $version_data)
- {
- $template->assign_block_vars('updates_available', $version_data);
- }
+ $this->template->assign_block_vars('updates_available', $updates_available);
}
catch (\RuntimeException $e)
{
- $template->assign_vars(array(
+ $this->template->assign_vars(array(
'S_VERSIONCHECK_STATUS' => $e->getCode(),
- 'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== $user->lang('VERSIONCHECK_FAIL')) ? $e->getMessage() : '',
+ 'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== $this->user->lang('VERSIONCHECK_FAIL')) ? $e->getMessage() : '',
));
}
- $template->assign_vars(array(
+ $this->template->assign_vars(array(
'U_BACK' => $this->u_action . '&amp;action=list',
'U_VERSIONCHECK_FORCE' => $this->u_action . '&amp;action=details&amp;versioncheck_force=1&amp;ext_name=' . urlencode($md_manager->get_metadata('name')),
));
@@ -335,21 +344,41 @@ class acp_extensions
$this->tpl_name = 'acp_ext_details';
break;
}
+
+ /**
+ * Event to run after a specific action on extension has completed
+ *
+ * @event core.acp_extensions_run_action_after
+ * @var string action Action that has run
+ * @var string u_action Url we are at
+ * @var string ext_name Extension name from request
+ * @var int safe_time_limit Safe limit of execution time
+ * @var int start_time Start time
+ * @var string tpl_name Template file to load
+ * @since 3.1.11-RC1
+ */
+ $u_action = $this->u_action;
+ $tpl_name = $this->tpl_name;
+ $vars = array('action', 'u_action', 'ext_name', 'safe_time_limit', 'start_time', 'tpl_name');
+ extract($this->phpbb_dispatcher->trigger_event('core.acp_extensions_run_action_after', compact($vars)));
+
+ // In case they have been updated by the event
+ $this->u_action = $u_action;
+ $this->tpl_name = $tpl_name;
}
/**
* Lists all the enabled extensions and dumps to the template
*
- * @param $phpbb_extension_manager An instance of the extension manager
* @return null
*/
- public function list_enabled_exts(\phpbb\extension\manager $phpbb_extension_manager)
+ public function list_enabled_exts()
{
$enabled_extension_meta_data = array();
- foreach ($phpbb_extension_manager->all_enabled() as $name => $location)
+ foreach ($this->ext_manager->all_enabled() as $name => $location)
{
- $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template);
+ $md_manager = $this->ext_manager->create_extension_metadata_manager($name, $this->template);
try
{
@@ -397,16 +426,15 @@ class acp_extensions
/**
* Lists all the disabled extensions and dumps to the template
*
- * @param $phpbb_extension_manager An instance of the extension manager
* @return null
*/
- public function list_disabled_exts(\phpbb\extension\manager $phpbb_extension_manager)
+ public function list_disabled_exts()
{
$disabled_extension_meta_data = array();
- foreach ($phpbb_extension_manager->all_disabled() as $name => $location)
+ foreach ($this->ext_manager->all_disabled() as $name => $location)
{
- $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template);
+ $md_manager = $this->ext_manager->create_extension_metadata_manager($name, $this->template);
try
{
@@ -455,18 +483,17 @@ class acp_extensions
/**
* Lists all the available extensions and dumps to the template
*
- * @param $phpbb_extension_manager An instance of the extension manager
* @return null
*/
- public function list_available_exts(\phpbb\extension\manager $phpbb_extension_manager)
+ public function list_available_exts()
{
- $uninstalled = array_diff_key($phpbb_extension_manager->all_available(), $phpbb_extension_manager->all_configured());
+ $uninstalled = array_diff_key($this->ext_manager->all_available(), $this->ext_manager->all_configured());
$available_extension_meta_data = array();
foreach ($uninstalled as $name => $location)
{
- $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template);
+ $md_manager = $this->ext_manager->create_extension_metadata_manager($name, $this->template);
try
{
@@ -535,7 +562,7 @@ class acp_extensions
* @param \phpbb\extension\metadata_manager $md_manager The metadata manager for the version to check.
* @param bool $force_update Ignores cached data. Defaults to false.
* @param bool $force_cache Force the use of the cache. Override $force_update.
- * @return string
+ * @return array
* @throws RuntimeException
*/
protected function version_check(\phpbb\extension\metadata_manager $md_manager, $force_update = false, $force_cache = false)
@@ -554,7 +581,7 @@ class acp_extensions
$version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename'], isset($version_check['ssl']) ? $version_check['ssl'] : false);
$version_helper->force_stability($this->config['extension_force_unstable'] ? 'unstable' : null);
- return $updates = $version_helper->get_suggested_updates($force_update, $force_cache);
+ return $version_helper->get_ext_update_on_branch($force_update, $force_cache);
}
/**
diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php
index 848cafeb67..6e7bd91a86 100644
--- a/phpBB/includes/acp/acp_main.php
+++ b/phpBB/includes/acp/acp_main.php
@@ -421,23 +421,33 @@ class acp_main
// Version check
$user->add_lang('install');
- if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.3.3', '<'))
+ if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.4.0', '<'))
{
$template->assign_vars(array(
'S_PHP_VERSION_OLD' => true,
- 'L_PHP_VERSION_OLD' => sprintf($user->lang['PHP_VERSION_OLD'], '<a href="https://www.phpbb.com/community/viewtopic.php?f=14&amp;t=2152375">', '</a>'),
+ 'L_PHP_VERSION_OLD' => sprintf($user->lang['PHP_VERSION_OLD'], PHP_VERSION, '5.4.0', '<a href="https://www.phpbb.com/support/docs/en/3.2/ug/quickstart/requirements">', '</a>'),
));
}
if ($auth->acl_get('a_board'))
{
+ /** @var \phpbb\version_helper $version_helper */
$version_helper = $phpbb_container->get('version_helper');
try
{
$recheck = $request->variable('versioncheck_force', false);
- $updates_available = $version_helper->get_suggested_updates($recheck);
+ $updates_available = $version_helper->get_update_on_branch($recheck);
+ $upgrades_available = $version_helper->get_suggested_updates();
+ if (!empty($upgrades_available))
+ {
+ $upgrades_available = array_pop($upgrades_available);
+ }
- $template->assign_var('S_VERSION_UP_TO_DATE', empty($updates_available));
+ $template->assign_vars(array(
+ 'S_VERSION_UP_TO_DATE' => empty($updates_available),
+ 'S_VERSION_UPGRADEABLE' => !empty($upgrades_available),
+ 'UPGRADE_INSTRUCTIONS' => !empty($upgrades_available) ? $user->lang('UPGRADE_INSTRUCTIONS', $upgrades_available['current'], $upgrades_available['announcement']) : false,
+ ));
}
catch (\RuntimeException $e)
{
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php
index 5181b87ecb..c29fb062d8 100644
--- a/phpBB/includes/acp/acp_styles.php
+++ b/phpBB/includes/acp/acp_styles.php
@@ -433,6 +433,9 @@ class acp_styles
trigger_error($this->user->lang['NO_MATCHING_STYLES_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING);
}
+ // Read style configuration file
+ $style_cfg = $this->read_style_cfg($style['style_path']);
+
// Find all available parent styles
$list = $this->find_possible_parents($styles, $id);
@@ -579,6 +582,7 @@ class acp_styles
'STYLE_ID' => $style['style_id'],
'STYLE_NAME' => htmlspecialchars($style['style_name']),
'STYLE_PATH' => htmlspecialchars($style['style_path']),
+ 'STYLE_VERSION' => htmlspecialchars($style_cfg['style_version']),
'STYLE_COPYRIGHT' => strip_tags($style['style_copyright']),
'STYLE_PARENT' => $style['style_parent_id'],
'S_STYLE_ACTIVE' => $style['style_active'],
diff --git a/phpBB/includes/acp/acp_update.php b/phpBB/includes/acp/acp_update.php
index 529f0f2185..cee2ce222e 100644
--- a/phpBB/includes/acp/acp_update.php
+++ b/phpBB/includes/acp/acp_update.php
@@ -37,7 +37,12 @@ class acp_update
try
{
$recheck = $request->variable('versioncheck_force', false);
- $updates_available = $version_helper->get_suggested_updates($recheck);
+ $updates_available = $version_helper->get_update_on_branch($recheck);
+ $upgrades_available = $version_helper->get_suggested_updates();
+ if (!empty($upgrades_available))
+ {
+ $upgrades_available = array_pop($upgrades_available);
+ }
}
catch (\RuntimeException $e)
{
@@ -46,12 +51,9 @@ class acp_update
$updates_available = array();
}
- foreach ($updates_available as $branch => $version_data)
- {
- $template->assign_block_vars('updates_available', $version_data);
- }
+ $template->assign_block_vars('updates_available', $updates_available);
- $update_link = append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=update');
+ $update_link = append_sid($phpbb_root_path . 'install/');
$template->assign_vars(array(
'S_UP_TO_DATE' => empty($updates_available),
@@ -61,6 +63,8 @@ class acp_update
'CURRENT_VERSION' => $config['version'],
'UPDATE_INSTRUCTIONS' => sprintf($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,
));
// Incomplete update?
diff --git a/phpBB/includes/acp/info/acp_logs.php b/phpBB/includes/acp/info/acp_logs.php
index e9e6034cd4..3b2764c4dc 100644
--- a/phpBB/includes/acp/info/acp_logs.php
+++ b/phpBB/includes/acp/info/acp_logs.php
@@ -15,16 +15,31 @@ class acp_logs_info
{
function module()
{
+ global $phpbb_dispatcher;
+
+ $modes = array(
+ 'admin' => array('title' => 'ACP_ADMIN_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')),
+ 'mod' => array('title' => 'ACP_MOD_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')),
+ 'users' => array('title' => 'ACP_USERS_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')),
+ 'critical' => array('title' => 'ACP_CRITICAL_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')),
+ );
+
+ /**
+ * Event to add or modify ACP log modulemodes
+ *
+ * @event core.acp_logs_info_modify_modes
+ * @var array modes Array with modes info
+ * @since 3.1.11-RC1
+ * @since 3.2.1-RC1
+ */
+ $vars = array('modes');
+ extract($phpbb_dispatcher->trigger_event('core.acp_logs_info_modify_modes', compact($vars)));
+
return array(
'filename' => 'acp_logs',
'title' => 'ACP_LOGGING',
'version' => '1.0.0',
- 'modes' => array(
- 'admin' => array('title' => 'ACP_ADMIN_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')),
- 'mod' => array('title' => 'ACP_MOD_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')),
- 'users' => array('title' => 'ACP_USERS_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')),
- 'critical' => array('title' => 'ACP_CRITICAL_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')),
- ),
+ 'modes' => $modes,
);
}
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index 1dc246ec33..4bac718999 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -641,8 +641,8 @@ function move_posts($post_ids, $topic_id, $auto_sync = true)
*
* @event core.move_posts_before
* @var array post_ids Array of post ids to move
- * @var string topic_id The topic id the posts are moved to
- * @var bool auto_sync Whether or not to perform auto sync
+ * @var int topic_id The topic id the posts are moved to
+ * @var bool auto_sync Whether or not to perform auto sync
* @var array forum_ids Array of the forum ids the posts are moved from
* @var array topic_ids Array of the topic ids the posts are moved from
* @var array forum_row Array with the forum id of the topic the posts are moved to
@@ -673,8 +673,8 @@ function move_posts($post_ids, $topic_id, $auto_sync = true)
*
* @event core.move_posts_after
* @var array post_ids Array of the moved post ids
- * @var string topic_id The topic id the posts are moved to
- * @var bool auto_sync Whether or not to perform auto sync
+ * @var int topic_id The topic id the posts are moved to
+ * @var bool auto_sync Whether or not to perform auto sync
* @var array forum_ids Array of the forum ids the posts are moved from
* @var array topic_ids Array of the topic ids the posts are moved from
* @var array forum_row Array with the forum id of the topic the posts are moved to
@@ -698,6 +698,28 @@ function move_posts($post_ids, $topic_id, $auto_sync = true)
sync('topic_attachment', 'topic_id', $topic_ids);
sync('topic', 'topic_id', $topic_ids, true);
sync('forum', 'forum_id', $forum_ids, true, true);
+
+ /**
+ * Perform additional actions after move post sync
+ *
+ * @event core.move_posts_sync_after
+ * @var array post_ids Array of the moved post ids
+ * @var int topic_id The topic id the posts are moved to
+ * @var bool auto_sync Whether or not to perform auto sync
+ * @var array forum_ids Array of the forum ids the posts are moved from
+ * @var array topic_ids Array of the topic ids the posts are moved from
+ * @var array forum_row Array with the forum id of the topic the posts are moved to
+ * @since 3.1.11-RC1
+ */
+ $vars = array(
+ 'post_ids',
+ 'topic_id',
+ 'auto_sync',
+ 'forum_ids',
+ 'topic_ids',
+ 'forum_row',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.move_posts_sync_after', compact($vars)));
}
// Update posted information
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index b49a8b80c0..3b2d66c2d3 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -646,7 +646,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
* @var array row The data of the forum
* @var array subforums_row Template data of subforums
* @since 3.1.0-a1
- * @change 3.1.0-b5 Added var subforums_row
+ * @changed 3.1.0-b5 Added var subforums_row
*/
$vars = array('forum_row', 'row', 'subforums_row');
extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_template_vars', compact($vars)));
diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php
index 86c60c31ff..053e362682 100644
--- a/phpBB/includes/functions_download.php
+++ b/phpBB/includes/functions_download.php
@@ -124,7 +124,7 @@ function wrap_img_in_html($src, $title)
*/
function send_file_to_browser($attachment, $upload_dir, $category)
{
- global $user, $db, $config, $phpbb_root_path;
+ global $user, $db, $config, $phpbb_dispatcher, $phpbb_root_path;
$filename = $phpbb_root_path . $upload_dir . '/' . $attachment['physical_filename'];
@@ -149,6 +149,26 @@ function send_file_to_browser($attachment, $upload_dir, $category)
// Now send the File Contents to the Browser
$size = @filesize($filename);
+ /**
+ * Event to alter attachment before it is sent to browser.
+ *
+ * @event core.send_file_to_browser_before
+ * @var array attachment Attachment data
+ * @var string upload_dir Relative path of upload directory
+ * @var int category Attachment category
+ * @var string filename Path to file, including filename
+ * @var int size File size
+ * @since 3.1.11-RC1
+ */
+ $vars = array(
+ 'attachment',
+ 'upload_dir',
+ 'category',
+ 'filename',
+ 'size',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.send_file_to_browser_before', compact($vars)));
+
// To correctly display further errors we need to make sure we are using the correct headers for both (unsetting content-length may not work)
// Check if headers already sent or not able to get the file contents.
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index f141637fb9..a6e4cb0679 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -1046,7 +1046,18 @@ function smtpmail($addresses, $subject, $message, &$err_msg, $headers = false)
}
$collector = new \phpbb\error_collector;
$collector->install();
- $smtp->socket = fsockopen($config['smtp_host'], $config['smtp_port'], $errno, $errstr, 20);
+
+ $options = array();
+ $verify_peer = (bool) $config['smtp_verify_peer'];
+ $verify_peer_name = (bool) $config['smtp_verify_peer_name'];
+ $allow_self_signed = (bool) $config['smtp_allow_self_signed'];
+ $remote_socket = $config['smtp_host'] . ':' . $config['smtp_port'];
+
+ // Set ssl context options, see http://php.net/manual/en/context.ssl.php
+ $options['ssl'] = array('verify_peer' => $verify_peer, 'verify_peer_name' => $verify_peer_name, 'allow_self_signed' => $allow_self_signed);
+ $socket_context = stream_context_create($options);
+
+ $smtp->socket = stream_socket_client($remote_socket, $errno, $errstr, 20, STREAM_CLIENT_CONNECT, $socket_context);
$collector->uninstall();
$error_contents = $collector->format_errors();
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 30f5ba91ef..ba367e5eeb 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -2514,7 +2514,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
* @var string url The "Return to topic" URL
*
* @since 3.1.0-a3
- * @change 3.1.0-RC3 Added vars mode, subject, username, topic_type,
+ * @changed 3.1.0-RC3 Added vars mode, subject, username, topic_type,
* poll, update_message, update_search_index
*/
$vars = array(
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 0b39339c7f..4aecbff6ba 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -272,13 +272,15 @@ function user_add($user_row, $cp_data = false, $notifications_data = null)
* Use this event to modify the values to be inserted when a user is added
*
* @event core.user_add_modify_data
- * @var array user_row Array of user details submited to user_add
- * @var array cp_data Array of Custom profile fields submited to user_add
- * @var array sql_ary Array of data to be inserted when a user is added
+ * @var array user_row Array of user details submited to user_add
+ * @var array cp_data Array of Custom profile fields submited to user_add
+ * @var array sql_ary Array of data to be inserted when a user is added
+ * @var array notifications_data Array of notification data to be inserted when a user is added
* @since 3.1.0-a1
- * @change 3.1.0-b5
+ * @changed 3.1.0-b5 Added user_row and cp_data
+ * @changed 3.1.11-RC1 Added notifications_data
*/
- $vars = array('user_row', 'cp_data', 'sql_ary');
+ $vars = array('user_row', 'cp_data', 'sql_ary', 'notifications_data');
extract($phpbb_dispatcher->trigger_event('core.user_add_modify_data', compact($vars)));
$sql = 'INSERT INTO ' . USERS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
@@ -1291,7 +1293,7 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas
*/
function user_unban($mode, $ban)
{
- global $db, $user, $auth, $cache;
+ global $db, $user, $auth, $cache, $phpbb_dispatcher;
// Delete stale bans
$sql = 'DELETE FROM ' . BANLIST_TABLE . '
@@ -1358,6 +1360,20 @@ function user_unban($mode, $ban)
add_log('user', $user_id, 'LOG_UNBAN_' . strtoupper($mode), $l_unban_list);
}
}
+
+ /**
+ * Use this event to perform actions after the unban has been performed
+ *
+ * @event core.user_unban
+ * @var string mode One of the following: user, ip, email
+ * @var array user_ids_ary Array with user_ids
+ * @since 3.1.11-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'user_ids_ary',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.user_unban', compact($vars)));
}
$cache->destroy('sql', BANLIST_TABLE);
diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php
index e4c0640ec7..3deb58b96a 100644
--- a/phpBB/includes/mcp/mcp_forum.php
+++ b/phpBB/includes/mcp/mcp_forum.php
@@ -458,7 +458,7 @@ function merge_topics($forum_id, $topic_ids, $to_topic_id)
return;
}
- $redirect = request_var('redirect', build_url(array('quickmod')));
+ $redirect = request_var('redirect', "{$phpbb_root_path}mcp.$phpEx?f=$forum_id&amp;i=main&amp;mode=forum_view");
$s_hidden_fields = build_hidden_fields(array(
'i' => 'main',
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index 599bd5d918..491697d2e9 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -164,7 +164,7 @@ class mcp_main
* @var string action Topic quick moderation action name
* @var bool quickmod Flag indicating whether MCP is in quick moderation mode
* @since 3.1.0-a4
- * @change 3.1.0-RC4 Added variables: action, quickmod
+ * @changed 3.1.0-RC4 Added variables: action, quickmod
*/
$vars = array('action', 'quickmod');
extract($phpbb_dispatcher->trigger_event('core.modify_quickmod_actions', compact($vars)));
diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php
index 2dcfcd608b..b5f2bf4f02 100644
--- a/phpBB/includes/mcp/mcp_post.php
+++ b/phpBB/includes/mcp/mcp_post.php
@@ -24,8 +24,8 @@ if (!defined('IN_PHPBB'))
*/
function mcp_post_details($id, $mode, $action)
{
- global $phpEx, $phpbb_root_path, $config;
- global $template, $db, $user, $auth, $cache;
+ global $phpEx, $phpbb_root_path, $config, $request;
+ global $template, $db, $user, $auth, $cache, $phpbb_container;
global $phpbb_dispatcher;
$user->add_lang('posting');
@@ -355,7 +355,11 @@ function mcp_post_details($id, $mode, $action)
// Get IP
if ($auth->acl_get('m_info', $post_info['forum_id']))
{
- $rdns_ip_num = request_var('rdns', '');
+ /** @var \phpbb\pagination $pagination */
+ $pagination = $phpbb_container->get('pagination');
+
+ $rdns_ip_num = $request->variable('rdns', '');
+ $start_users = $request->variable('start_users', 0);
if ($rdns_ip_num != 'all')
{
@@ -364,23 +368,46 @@ function mcp_post_details($id, $mode, $action)
);
}
+ $num_users = false;
+ if ($start_users)
+ {
+ $num_users = phpbb_get_num_posters_for_ip($db, $post_info['poster_ip']);
+ $start_users = $pagination->validate_start($start_users, $config['posts_per_page'], $num_users);
+ }
+
// Get other users who've posted under this IP
$sql = 'SELECT poster_id, COUNT(poster_id) as postings
FROM ' . POSTS_TABLE . "
WHERE poster_ip = '" . $db->sql_escape($post_info['poster_ip']) . "'
+ AND poster_id <> " . (int) $post_info['poster_id'] . "
GROUP BY poster_id
- ORDER BY postings DESC";
- $result = $db->sql_query($sql);
+ ORDER BY postings DESC, poster_id ASC";
+ $result = $db->sql_query_limit($sql, $config['posts_per_page'], $start_users);
+ $page_users = 0;
while ($row = $db->sql_fetchrow($result))
{
- // Fill the user select list with users who have posted under this IP
- if ($row['poster_id'] != $post_info['poster_id'])
+ $page_users++;
+ $users_ary[$row['poster_id']] = $row;
+ }
+ $db->sql_freeresult($result);
+
+ if ($page_users == $config['posts_per_page'] || $start_users)
+ {
+ if ($num_users === false)
{
- $users_ary[$row['poster_id']] = $row;
+ $num_users = phpbb_get_num_posters_for_ip($db, $post_info['poster_ip']);
}
+
+ $pagination->generate_template_pagination(
+ $url . '&amp;i=main&amp;mode=post_details',
+ 'pagination',
+ 'start_users',
+ $num_users,
+ $config['posts_per_page'],
+ $start_users
+ );
}
- $db->sql_freeresult($result);
if (sizeof($users_ary))
{
@@ -415,16 +442,26 @@ function mcp_post_details($id, $mode, $action)
// A compound index on poster_id, poster_ip (posts table) would help speed up this query a lot,
// but the extra size is only valuable if there are persons having more than a thousands posts.
// This is better left to the really really big forums.
+ $start_ips = $request->variable('start_ips', 0);
+
+ $num_ips = false;
+ if ($start_ips)
+ {
+ $num_ips = phpbb_get_num_ips_for_poster($db, $post_info['poster_id']);
+ $start_ips = $pagination->validate_start($start_ips, $config['posts_per_page'], $num_ips);
+ }
$sql = 'SELECT poster_ip, COUNT(poster_ip) AS postings
FROM ' . POSTS_TABLE . '
WHERE poster_id = ' . $post_info['poster_id'] . "
GROUP BY poster_ip
- ORDER BY postings DESC";
- $result = $db->sql_query($sql);
+ ORDER BY postings DESC, poster_ip ASC";
+ $result = $db->sql_query_limit($sql, $config['posts_per_page'], $start_ips);
+ $page_ips = 0;
while ($row = $db->sql_fetchrow($result))
{
+ $page_ips++;
$hostname = (($rdns_ip_num == $row['poster_ip'] || $rdns_ip_num == 'all') && $row['poster_ip']) ? @gethostbyaddr($row['poster_ip']) : '';
$template->assign_block_vars('iprow', array(
@@ -439,6 +476,23 @@ function mcp_post_details($id, $mode, $action)
}
$db->sql_freeresult($result);
+ if ($page_ips == $config['posts_per_page'] || $start_ips)
+ {
+ if ($num_ips === false)
+ {
+ $num_ips = phpbb_get_num_ips_for_poster($db, $post_info['poster_id']);
+ }
+
+ $pagination->generate_template_pagination(
+ $url . '&amp;i=main&amp;mode=post_details',
+ 'pagination_ips',
+ 'start_ips',
+ $num_ips,
+ $config['posts_per_page'],
+ $start_ips
+ );
+ }
+
$user_select = '';
if (sizeof($usernames_ary))
@@ -457,6 +511,44 @@ function mcp_post_details($id, $mode, $action)
}
/**
+ * Get the number of posters for a given ip
+ *
+ * @param \phpbb\db\driver\driver_interface $db DBAL interface
+ * @param string $poster_ip IP
+ * @return int Number of posters
+ */
+function phpbb_get_num_posters_for_ip(\phpbb\db\driver\driver_interface $db, $poster_ip)
+{
+ $sql = 'SELECT COUNT(DISTINCT poster_id) as num_users
+ FROM ' . POSTS_TABLE . "
+ WHERE poster_ip = '" . $db->sql_escape($poster_ip) . "'";
+ $result = $db->sql_query($sql);
+ $num_users = (int) $db->sql_fetchfield('num_users');
+ $db->sql_freeresult($result);
+
+ return $num_users;
+}
+
+/**
+ * Get the number of ips for a given poster
+ *
+ * @param \phpbb\db\driver\driver_interface $db
+ * @param int $poster_id Poster user ID
+ * @return int Number of IPs for given poster
+ */
+function phpbb_get_num_ips_for_poster(\phpbb\db\driver\driver_interface $db, $poster_id)
+{
+ $sql = 'SELECT COUNT(DISTINCT poster_ip) as num_ips
+ FROM ' . POSTS_TABLE . '
+ WHERE poster_id = ' . (int) $poster_id;
+ $result = $db->sql_query($sql);
+ $num_ips = (int) $db->sql_fetchfield('num_ips');
+ $db->sql_freeresult($result);
+
+ return $num_ips;
+}
+
+/**
* Change a post's poster
*/
function change_poster(&$post_info, $userdata)
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php
index 16b65fb83e..bbd5e84233 100644
--- a/phpBB/includes/message_parser.php
+++ b/phpBB/includes/message_parser.php
@@ -1171,7 +1171,7 @@ class parse_message extends bbcode_firstpass
* @var bool return Do we return after the event is triggered if $warn_msg is not empty
* @var array warn_msg Array of the warning messages
* @since 3.1.2-RC1
- * @change 3.1.3-RC1 Added vars $bbcode_bitfield and $bbcode_uid
+ * @changed 3.1.3-RC1 Added vars $bbcode_bitfield and $bbcode_uid
*/
$message = $this->message;
$warn_msg = $this->warn_msg;
diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php
index 3ae7876a72..3364206680 100644
--- a/phpBB/includes/ucp/ucp_pm_viewfolder.php
+++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php
@@ -547,7 +547,7 @@ function get_pm_from($folder_id, $folder, $user_id)
AND $folder_sql
AND t.msg_id = p.msg_id
$sql_limit_time",
- 'ORDER' => $sql_sort_order,
+ 'ORDER_BY' => $sql_sort_order,
);
/**
diff --git a/phpBB/language/en/acp/attachments.php b/phpBB/language/en/acp/attachments.php
index 7d3d93d693..750f2f8d61 100644
--- a/phpBB/language/en/acp/attachments.php
+++ b/phpBB/language/en/acp/attachments.php
@@ -125,7 +125,7 @@ $lang = array_merge($lang, array(
'MAX_EXTGROUP_FILESIZE' => 'Maximum file size',
'MAX_IMAGE_SIZE' => 'Maximum image dimensions',
'MAX_IMAGE_SIZE_EXPLAIN' => 'Maximum size of image attachments. Set both values to 0px by 0px to disable dimension checking.',
- 'MAX_THUMB_WIDTH' => 'Maximum thumbnail width in pixel',
+ 'MAX_THUMB_WIDTH' => 'Maximum thumbnail width/height in pixel',
'MAX_THUMB_WIDTH_EXPLAIN' => 'A generated thumbnail will not exceed the width set here.',
'MIN_THUMB_FILESIZE' => 'Minimum thumbnail file size',
'MIN_THUMB_FILESIZE_EXPLAIN' => 'Do not create a thumbnail for images smaller than this.',
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index 8b4db6a061..1e77af14b1 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -345,11 +345,14 @@ $lang = array_merge($lang, array(
// Cookie Settings
$lang = array_merge($lang, array(
- 'ACP_COOKIE_SETTINGS_EXPLAIN' => 'These details define the data used to send cookies to your users browsers. In most cases the default values for the cookie settings should be sufficient. If you do need to change any do so with care, incorrect settings can prevent users logging in.',
+ 'ACP_COOKIE_SETTINGS_EXPLAIN' => 'These details define the data used to send cookies to your users browsers. In most cases the default values for the cookie settings should be sufficient. If you do need to change any do so with care, incorrect settings can prevent users logging in. If you have problems with users staying logging in to your board, visit the <b><a href="https://www.phpbb.com/support/go/cookie-settings/">phpBB.com Knowledge Base - Fixing incorrect cookie settings</a></b>.',
'COOKIE_DOMAIN' => 'Cookie domain',
+ 'COOKIE_DOMAIN_EXPLAIN' => 'In most cases the cookie domain is optional. Leave it blank if you are unsure.<br /><br /> In the case where you have a board integrated with other software or have multiple domains, then to determine the cookie domain you need to do the following. If you have something like <i>example.com</i> and <i>forums.example.com</i>, or perhaps <i>forums.example.com</i> and <i>blog.example.com</i>. Remove the subdomains until you find the common domain, <i>example.com</i>. Now add a dot in front of the common domain and you would enter .example.com (note the dot at the beginning).',
'COOKIE_NAME' => 'Cookie name',
+ 'COOKIE_NAME_EXPLAIN' => 'This can be anything what you want, make it original. Whenever the cookie settings are changed the name of the cookie should be changed.',
'COOKIE_PATH' => 'Cookie path',
+ 'COOKIE_PATH_EXPLAIN' => 'Note that this is always a slash, it does not matter what your board URL is.',
'COOKIE_SECURE' => 'Cookie secure',
'COOKIE_SECURE_EXPLAIN' => 'If your server is running via SSL set this to enabled else leave as disabled. Having this enabled and not running via SSL will result in server errors during redirects.',
'ONLINE_LENGTH' => 'View online time span',
@@ -558,6 +561,8 @@ $lang = array_merge($lang, array(
'EMAIL_SIG_EXPLAIN' => 'This text will be attached to all emails the board sends.',
'ENABLE_EMAIL' => 'Enable board-wide emails',
'ENABLE_EMAIL_EXPLAIN' => 'If this is set to disabled no emails will be sent by the board at all. <em>Note the user and admin account activation settings require this setting to be enabled. If currently using “user” or “admin” activation in the activation settings, disabling this setting will disable registration.</em>',
+ 'SMTP_ALLOW_SELF_SIGNED' => 'Allow self-signed SSL certificates',
+ 'SMTP_ALLOW_SELF_SIGNED_EXPLAIN'=> 'Allow connections to SMTP server with self-signed SSL certificate.<em><strong>Warning:</strong> Allowing self-signed SSL certificates may cause security implications.</em>',
'SMTP_AUTH_METHOD' => 'Authentication method for SMTP',
'SMTP_AUTH_METHOD_EXPLAIN' => 'Only used if a username/password is set, ask your provider if you are unsure which method to use.',
'SMTP_CRAM_MD5' => 'CRAM-MD5',
@@ -574,6 +579,11 @@ $lang = array_merge($lang, array(
'SMTP_SETTINGS' => 'SMTP settings',
'SMTP_USERNAME' => 'SMTP username',
'SMTP_USERNAME_EXPLAIN' => 'Only enter a username if your SMTP server requires it.',
+ 'SMTP_VERIFY_PEER' => 'Verify SSL certificate',
+ 'SMTP_VERIFY_PEER_EXPLAIN' => 'Require verification of SSL certificate used by SMTP server.<em><strong>Warning:</strong> Connecting peers with unverified SSL certificates may cause security implications.</em>',
+ 'SMTP_VERIFY_PEER_NAME' => 'Verify SMTP peer name',
+ 'SMTP_VERIFY_PEER_NAME_EXPLAIN' => 'Require verification of peer name for SMTP servers using SSL / TLS connections.<em><strong>Warning:</strong> Connecting to unverified peers may cause security implications.</em>',
+
'USE_SMTP' => 'Use SMTP server for email',
'USE_SMTP_EXPLAIN' => 'Select “Yes” if you want or have to send email via a named server instead of the local mail function.',
));
diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index 88e60d00a3..562b446f8a 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -373,7 +373,7 @@ $lang = array_merge($lang, array(
'NUMBER_USERS' => 'Number of users',
'NUMBER_ORPHAN' => 'Orphan attachments',
- 'PHP_VERSION_OLD' => 'The version of PHP on this server will no longer be supported by future versions of phpBB. %sDetails%s',
+ 'PHP_VERSION_OLD' => 'The version of PHP on this server (%1$s) will no longer be supported by future versions of phpBB. The minimum required version will be PHP %2$s. %3$sDetails%4$s',
'POSTS_PER_DAY' => 'Posts per day',
diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php
index 0d91eb3704..9293d67ecc 100644
--- a/phpBB/language/en/acp/styles.php
+++ b/phpBB/language/en/acp/styles.php
@@ -81,6 +81,7 @@ $lang = array_merge($lang, array(
'STYLE_UNINSTALL_DEPENDENT' => 'Style "%s" cannot be uninstalled because it has one or more child styles.',
'STYLE_UNINSTALLED' => 'Style "%s" uninstalled successfully.',
'STYLE_USED_BY' => 'Used by (including robots)',
+ 'STYLE_VERSION' => 'Style version',
'UNINSTALL_DEFAULT' => 'You cannot uninstall the default style.',
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index a2cfd958aa..b4b328e90d 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -336,6 +336,7 @@ $lang = array_merge($lang, array(
'INTERESTS' => 'Interests',
'INVALID_DIGEST_CHALLENGE' => 'Invalid digest challenge.',
'INVALID_EMAIL_LOG' => '<strong>%s</strong> possibly an invalid email address?',
+ 'INVALID_FEED_ATTACHMENTS' => 'The selected feed tried fetching attachments with invalid constraints.',
'INVALID_PLURAL_RULE' => 'The chosen plural rule is invalid. Valid values are integers between 0 and 15.',
'IP' => 'IP',
'IP_BLACKLISTED' => 'Your IP %1$s has been blocked because it is blacklisted. For details please see <a href="%2$s">%2$s</a>.',
diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php
index 6477a929e9..0460c0613e 100644
--- a/phpBB/language/en/install.php
+++ b/phpBB/language/en/install.php
@@ -574,6 +574,7 @@ $lang = array_merge($lang, array(
'UPDATING_DATA' => 'Updating data',
'UPDATING_TO_LATEST_STABLE' => 'Updating database to latest stable release',
'UPDATED_VERSION' => 'Updated version',
+ 'UPGRADE_INSTRUCTIONS' => 'A new feature release <strong>%1$s</strong> is available. Please read <a href="%2$s" title="%2$s"><strong>the release announcement</strong></a> to learn about what it has to offer, and how to upgrade.',
'UPLOAD_METHOD' => 'Upload method',
'UPDATE_DB_SUCCESS' => 'Database update was successful.',
diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php
index b7634e04ce..37d4352c10 100644
--- a/phpBB/phpbb/auth/auth.php
+++ b/phpBB/phpbb/auth/auth.php
@@ -514,7 +514,7 @@ class auth
*/
function acl_clear_prefetch($user_id = false)
{
- global $db, $cache;
+ global $db, $cache, $phpbb_dispatcher;
// Rebuild options cache
$cache->destroy('_role_cache');
@@ -553,6 +553,16 @@ class auth
$where_sql";
$db->sql_query($sql);
+ /**
+ * Event is triggered after user(s) permission settings cache has been cleared
+ *
+ * @event core.acl_clear_prefetch_after
+ * @var mixed user_id User ID(s)
+ * @since 3.1.11-RC1
+ */
+ $vars = array('user_id');
+ extract($phpbb_dispatcher->trigger_event('core.acl_clear_prefetch_after', compact($vars)));
+
return;
}
diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php
index fae4614039..1e9ee960dc 100644
--- a/phpBB/phpbb/cache/driver/file.php
+++ b/phpBB/phpbb/cache/driver/file.php
@@ -601,6 +601,6 @@ class file extends \phpbb\cache\driver\base
*/
protected function clean_varname($varname)
{
- return str_replace('/', '-', $varname);
+ return str_replace(array('/', '\\'), '-', $varname);
}
}
diff --git a/phpBB/phpbb/cache/driver/memcached.php b/phpBB/phpbb/cache/driver/memcached.php
new file mode 100644
index 0000000000..105e763af4
--- /dev/null
+++ b/phpBB/phpbb/cache/driver/memcached.php
@@ -0,0 +1,134 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\cache\driver;
+
+if (!defined('PHPBB_ACM_MEMCACHED_PORT'))
+{
+ define('PHPBB_ACM_MEMCACHED_PORT', 11211);
+}
+
+if (!defined('PHPBB_ACM_MEMCACHED_COMPRESS'))
+{
+ define('PHPBB_ACM_MEMCACHED_COMPRESS', true);
+}
+
+if (!defined('PHPBB_ACM_MEMCACHED_HOST'))
+{
+ define('PHPBB_ACM_MEMCACHED_HOST', 'localhost');
+}
+
+if (!defined('PHPBB_ACM_MEMCACHED'))
+{
+ //can define multiple servers with host1/port1,host2/port2 format
+ define('PHPBB_ACM_MEMCACHED', PHPBB_ACM_MEMCACHED_HOST . '/' . PHPBB_ACM_MEMCACHED_PORT);
+}
+
+/**
+* ACM for Memcached
+*/
+class memcached extends \phpbb\cache\driver\memory
+{
+ /** @var string Extension to use */
+ protected $extension = 'memcached';
+
+ /** @var \Memcached Memcached class */
+ protected $memcached;
+
+ /** @var int Flags */
+ protected $flags = 0;
+
+ /**
+ * Memcached constructor
+ */
+ public function __construct()
+ {
+ // Call the parent constructor
+ parent::__construct();
+
+ $this->memcached = new \Memcached();
+ $this->memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
+ // Memcached defaults to using compression, disable if we don't want
+ // to use it
+ if (!PHPBB_ACM_MEMCACHED_COMPRESS)
+ {
+ $this->memcached->setOption(\Memcached::OPT_COMPRESSION, false);
+ }
+
+ foreach (explode(',', PHPBB_ACM_MEMCACHE) as $u)
+ {
+ $parts = explode('/', $u);
+ $this->memcached->addServer(trim($parts[0]), trim($parts[1]));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function unload()
+ {
+ parent::unload();
+
+ unset($this->memcached);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function purge()
+ {
+ $this->memcached->flush();
+
+ parent::purge();
+ }
+
+ /**
+ * Fetch an item from the cache
+ *
+ * @param string $var Cache key
+ *
+ * @return mixed Cached data
+ */
+ protected function _read($var)
+ {
+ return $this->memcached->get($this->key_prefix . $var);
+ }
+
+ /**
+ * Store data in the cache
+ *
+ * @param string $var Cache key
+ * @param mixed $data Data to store
+ * @param int $ttl Time-to-live of cached data
+ * @return bool True if the operation succeeded
+ */
+ protected function _write($var, $data, $ttl = 2592000)
+ {
+ if (!$this->memcached->replace($this->key_prefix . $var, $data, $ttl))
+ {
+ return $this->memcached->set($this->key_prefix . $var, $data, $ttl);
+ }
+ return true;
+ }
+
+ /**
+ * Remove an item from the cache
+ *
+ * @param string $var Cache key
+ * @return bool True if the operation succeeded
+ */
+ protected function _delete($var)
+ {
+ return $this->memcached->delete($this->key_prefix . $var);
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/notification_options_reconvert.php b/phpBB/phpbb/db/migration/data/v310/notification_options_reconvert.php
index 2d4d26ae61..d43d432dd9 100644
--- a/phpBB/phpbb/db/migration/data/v310/notification_options_reconvert.php
+++ b/phpBB/phpbb/db/migration/data/v310/notification_options_reconvert.php
@@ -52,6 +52,7 @@ class notification_options_reconvert extends \phpbb\db\migration\migration
{
$limit = 250;
$converted_users = 0;
+ $start = $start ?: 0;
$sql = 'SELECT user_id, user_notify_type, user_notify_pm
FROM ' . $this->table_prefix . 'users
diff --git a/phpBB/phpbb/db/migration/data/v31x/add_smtp_ssl_context_config_options.php b/phpBB/phpbb/db/migration/data/v31x/add_smtp_ssl_context_config_options.php
new file mode 100644
index 0000000000..92051dc3ca
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v31x/add_smtp_ssl_context_config_options.php
@@ -0,0 +1,32 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v31x;
+
+class add_smtp_ssl_context_config_options extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v31x\v3110');
+ }
+
+ public function update_data()
+ {
+ return array(
+ // See http://php.net/manual/en/context.ssl.php
+ array('config.add', array('smtp_verify_peer', 1)),
+ array('config.add', array('smtp_verify_peer_name', 1)),
+ array('config.add', array('smtp_allow_self_signed', 0)),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/profilefield_base_migration.php b/phpBB/phpbb/db/migration/profilefield_base_migration.php
index da1a38e2fa..b20ca874be 100644
--- a/phpBB/phpbb/db/migration/profilefield_base_migration.php
+++ b/phpBB/phpbb/db/migration/profilefield_base_migration.php
@@ -191,6 +191,7 @@ abstract class profilefield_base_migration extends container_aware_migration
$insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, $this->table_prefix . 'profile_fields_data');
$limit = 250;
$converted_users = 0;
+ $start = $start ?: 0;
$sql = 'SELECT user_id, ' . $this->user_column_name . '
FROM ' . $this->table_prefix . 'users
diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php
index a214356ac3..5f3aa685bf 100644
--- a/phpBB/phpbb/di/container_builder.php
+++ b/phpBB/phpbb/di/container_builder.php
@@ -185,6 +185,7 @@ class container_builder
}
$this->container->set('config.php', $this->config_php_file);
+ $this->inject_dbal_driver();
if ($this->compile_container)
{
@@ -304,6 +305,18 @@ class container_builder
}
/**
+ * Inject the dbal connection driver into container
+ */
+ protected function inject_dbal_driver()
+ {
+ $config_data = $this->config_php_file->get_all();
+ if (!empty($config_data))
+ {
+ $this->container->set('dbal.conn.driver', $this->get_dbal_connection());
+ }
+ }
+
+ /**
* Get DB connection.
*
* @return \phpbb\db\driver\driver_interface
@@ -320,6 +333,7 @@ class container_builder
$this->config_php_file->get('dbpasswd'),
$this->config_php_file->get('dbname'),
$this->config_php_file->get('dbport'),
+ false,
defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK
);
}
diff --git a/phpBB/phpbb/di/extension/config.php b/phpBB/phpbb/di/extension/config.php
index 7984a783df..8c9de48823 100644
--- a/phpBB/phpbb/di/extension/config.php
+++ b/phpBB/phpbb/di/extension/config.php
@@ -43,12 +43,6 @@ class config extends Extension
'core.adm_relative_path' => $this->config_php->get('phpbb_adm_relative_path') ? $this->config_php->get('phpbb_adm_relative_path') : 'adm/',
'core.table_prefix' => $this->config_php->get('table_prefix'),
'cache.driver.class' => $this->convert_30_acm_type($this->config_php->get('acm_type')),
- 'dbal.driver.class' => $this->config_php->convert_30_dbms_to_31($this->config_php->get('dbms')),
- 'dbal.dbhost' => $this->config_php->get('dbhost'),
- 'dbal.dbuser' => $this->config_php->get('dbuser'),
- 'dbal.dbpasswd' => $this->config_php->get('dbpasswd'),
- 'dbal.dbname' => $this->config_php->get('dbname'),
- 'dbal.dbport' => $this->config_php->get('dbport'),
'dbal.new_link' => defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK,
);
$parameter_bag = $container->getParameterBag();
diff --git a/phpBB/phpbb/event/php_exporter.php b/phpBB/phpbb/event/php_exporter.php
index d2ab0595c0..ae3553c558 100644
--- a/phpBB/phpbb/event/php_exporter.php
+++ b/phpBB/phpbb/event/php_exporter.php
@@ -510,7 +510,7 @@ class php_exporter
/**
* Find the "@changed" Information lines
*
- * @param string $tag_name Should be 'changed' or 'change'
+ * @param string $tag_name Should be 'change', not 'changed'
* @return array Absolute line numbers
* @throws \LogicException
*/
@@ -658,7 +658,7 @@ class php_exporter
{
$match = array();
$line = str_replace("\t", ' ', ltrim($line, "\t "));
- preg_match('#^\* @change(d)? (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)( (?:.*))?$#', $line, $match);
+ preg_match('#^\* @changed (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)( (?:.*))?$#', $line, $match);
if (!isset($match[2]))
{
throw new \LogicException("Invalid '@changed' information for event "
diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php
index 76f0e3558e..e7e5f83c23 100644
--- a/phpBB/phpbb/extension/manager.php
+++ b/phpBB/phpbb/extension/manager.php
@@ -149,10 +149,10 @@ class manager
* Instantiates the metadata manager for the extension with the given name
*
* @param string $name The extension name
- * @param \phpbb\template\template $template The template manager
+ * @param \phpbb\template\template $template The template manager or null
* @return \phpbb\extension\metadata_manager Instance of the metadata manager
*/
- public function create_extension_metadata_manager($name, \phpbb\template\template $template)
+ public function create_extension_metadata_manager($name, \phpbb\template\template $template = null)
{
return new \phpbb\extension\metadata_manager($name, $this->config, $this, $template, $this->user, $this->phpbb_root_path);
}
@@ -433,25 +433,11 @@ class manager
if ($file_info->isFile() && $file_info->getFilename() == 'composer.json')
{
$ext_name = $iterator->getInnerIterator()->getSubPath();
- $composer_file = $iterator->getPath() . '/composer.json';
-
- // Ignore the extension if there is no composer.json.
- if (!is_readable($composer_file) || !($ext_info = file_get_contents($composer_file)))
- {
- continue;
- }
-
- $ext_info = json_decode($ext_info, true);
$ext_name = str_replace(DIRECTORY_SEPARATOR, '/', $ext_name);
-
- // Ignore the extension if directory depth is not correct or if the directory structure
- // does not match the name value specified in composer.json.
- if (substr_count($ext_name, '/') !== 1 || !isset($ext_info['name']) || $ext_name != $ext_info['name'])
+ if ($this->is_available($ext_name))
{
- continue;
+ $available[$ext_name] = $this->phpbb_root_path . 'ext/' . $ext_name . '/';
}
-
- $available[$ext_name] = $this->phpbb_root_path . 'ext/' . $ext_name . '/';
}
}
ksort($available);
@@ -524,7 +510,15 @@ class manager
*/
public function is_available($name)
{
- return file_exists($this->get_extension_path($name, true));
+ $md_manager = $this->create_extension_metadata_manager($name);
+ try
+ {
+ return $md_manager->get_metadata('all') && $md_manager->validate_enable();
+ }
+ catch (\phpbb\extension\exception $e)
+ {
+ return false;
+ }
}
/**
diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php
index 34e2910a33..a09f07bed2 100644
--- a/phpBB/phpbb/extension/metadata_manager.php
+++ b/phpBB/phpbb/extension/metadata_manager.php
@@ -66,17 +66,18 @@ class metadata_manager
*/
protected $metadata_file;
+ // @codingStandardsIgnoreStart
/**
* Creates the metadata manager
*
* @param string $ext_name Name (including vendor) of the extension
* @param \phpbb\config\config $config phpBB Config instance
* @param \phpbb\extension\manager $extension_manager An instance of the phpBB extension manager
- * @param \phpbb\template\template $template phpBB Template instance
+ * @param \phpbb\template\template $template phpBB Template instance or null
* @param \phpbb\user $user User instance
* @param string $phpbb_root_path Path to the phpbb includes directory.
*/
- public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, \phpbb\user $user, $phpbb_root_path)
+ public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template = null, \phpbb\user $user, $phpbb_root_path)
{
$this->config = $config;
$this->extension_manager = $extension_manager;
@@ -88,6 +89,7 @@ class metadata_manager
$this->metadata = array();
$this->metadata_file = '';
}
+ // @codingStandardsIgnoreEnd
/**
* Processes and gets the metadata requested
@@ -97,51 +99,38 @@ class metadata_manager
*/
public function get_metadata($element = 'all')
{
- $this->set_metadata_file();
-
- // Fetch the metadata
- $this->fetch_metadata();
-
- // Clean the metadata
- $this->clean_metadata_array();
+ // Fetch and clean the metadata if not done yet
+ if ($this->metadata_file === '')
+ {
+ $this->fetch_metadata_from_file();
+ }
switch ($element)
{
case 'all':
default:
- // Validate the metadata
- if (!$this->validate())
- {
- return false;
- }
-
+ $this->validate();
return $this->metadata;
break;
case 'version':
case 'name':
- return ($this->validate($element)) ? $this->metadata[$element] : false;
+ $this->validate($element);
+ return $this->metadata[$element];
break;
case 'display-name':
- if (isset($this->metadata['extra']['display-name']))
- {
- return $this->metadata['extra']['display-name'];
- }
- else
- {
- return ($this->validate('name')) ? $this->metadata['name'] : false;
- }
+ return (isset($this->metadata['extra']['display-name'])) ? $this->metadata['extra']['display-name'] : $this->get_metadata('name');
break;
}
}
/**
- * Sets the filepath of the metadata file
+ * Sets the path of the metadata file, gets its contents and cleans loaded file
*
* @throws \phpbb\extension\exception
*/
- private function set_metadata_file()
+ private function fetch_metadata_from_file()
{
$ext_filepath = $this->extension_manager->get_extension_path($this->ext_name);
$metadata_filepath = $this->phpbb_root_path . $ext_filepath . 'composer.json';
@@ -152,37 +141,19 @@ class metadata_manager
{
throw new \phpbb\extension\exception($this->user->lang('FILE_NOT_FOUND', $this->metadata_file));
}
- }
- /**
- * Gets the contents of the composer.json file
- *
- * @return bool True if success, throws an exception on failure
- * @throws \phpbb\extension\exception
- */
- private function fetch_metadata()
- {
- if (!file_exists($this->metadata_file))
+ if (!($file_contents = file_get_contents($this->metadata_file)))
{
- throw new \phpbb\extension\exception($this->user->lang('FILE_NOT_FOUND', $this->metadata_file));
+ throw new \phpbb\extension\exception($this->user->lang('FILE_CONTENT_ERR', $this->metadata_file));
}
- else
- {
- if (!($file_contents = file_get_contents($this->metadata_file)))
- {
- throw new \phpbb\extension\exception($this->user->lang('FILE_CONTENT_ERR', $this->metadata_file));
- }
-
- if (($metadata = json_decode($file_contents, true)) === null)
- {
- throw new \phpbb\extension\exception($this->user->lang('FILE_JSON_DECODE_ERR', $this->metadata_file));
- }
-
- array_walk_recursive($metadata, array($this, 'sanitize_json'));
- $this->metadata = $metadata;
- return true;
+ if (($metadata = json_decode($file_contents, true)) === null)
+ {
+ throw new \phpbb\extension\exception($this->user->lang('FILE_JSON_DECODE_ERR', $this->metadata_file));
}
+
+ array_walk_recursive($metadata, array($this, 'sanitize_json'));
+ $this->metadata = $metadata;
}
/**
@@ -197,16 +168,6 @@ class metadata_manager
}
/**
- * This array handles the cleaning of the array
- *
- * @return array Contains the cleaned metadata array
- */
- private function clean_metadata_array()
- {
- return $this->metadata;
- }
-
- /**
* Validate fields
*
* @param string $name ("all" for display and enable validation
@@ -228,10 +189,8 @@ class metadata_manager
switch ($name)
{
case 'all':
- $this->validate('display');
-
$this->validate_enable();
- break;
+ // no break
case 'display':
foreach ($fields as $field => $data)
@@ -288,40 +247,43 @@ class metadata_manager
/**
* This array handles the verification that this extension can be enabled on this board
*
- * @return bool True if validation succeeded, False if failed
+ * @return bool True if validation succeeded, throws an exception if invalid
+ * @throws \phpbb\extension\exception
*/
public function validate_enable()
{
// Check for valid directory & phpBB, PHP versions
- if (!$this->validate_dir() || !$this->validate_require_phpbb() || !$this->validate_require_php())
- {
- return false;
- }
-
- return true;
+ return $this->validate_dir() && $this->validate_require_phpbb() && $this->validate_require_php();
}
/**
* Validates the most basic directory structure to ensure it follows <vendor>/<ext> convention.
*
- * @return boolean True when passes validation
+ * @return boolean True when passes validation, throws an exception if invalid
+ * @throws \phpbb\extension\exception
*/
public function validate_dir()
{
- return (substr_count($this->ext_name, '/') === 1 && $this->ext_name == $this->get_metadata('name'));
+ if (substr_count($this->ext_name, '/') !== 1 || $this->ext_name != $this->get_metadata('name'))
+ {
+ throw new \phpbb\extension\exception($this->user->lang('EXTENSION_DIR_INVALID'));
+ }
+
+ return true;
}
/**
* Validates the contents of the phpbb requirement field
*
- * @return boolean True when passes validation
+ * @return boolean True when passes validation, throws an exception if invalid
+ * @throws \phpbb\extension\exception
*/
public function validate_require_phpbb()
{
if (!isset($this->metadata['extra']['soft-require']['phpbb/phpbb']))
{
- return false;
+ throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'soft-require'));
}
return true;
@@ -330,13 +292,14 @@ class metadata_manager
/**
* Validates the contents of the php requirement field
*
- * @return boolean True when passes validation
+ * @return boolean True when passes validation, throws an exception if invalid
+ * @throws \phpbb\extension\exception
*/
public function validate_require_php()
{
if (!isset($this->metadata['require']['php']))
{
- return false;
+ throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'require php'));
}
return true;
@@ -359,10 +322,10 @@ class metadata_manager
'META_LICENSE' => $this->metadata['license'],
'META_REQUIRE_PHP' => (isset($this->metadata['require']['php'])) ? $this->metadata['require']['php'] : '',
- 'META_REQUIRE_PHP_FAIL' => !$this->validate_require_php(),
+ 'META_REQUIRE_PHP_FAIL' => (isset($this->metadata['require']['php'])) ? false : true,
'META_REQUIRE_PHPBB' => (isset($this->metadata['extra']['soft-require']['phpbb/phpbb'])) ? $this->metadata['extra']['soft-require']['phpbb/phpbb'] : '',
- 'META_REQUIRE_PHPBB_FAIL' => !$this->validate_require_phpbb(),
+ 'META_REQUIRE_PHPBB_FAIL' => (isset($this->metadata['extra']['soft-require']['phpbb/phpbb'])) ? false : true,
'META_DISPLAY_NAME' => (isset($this->metadata['extra']['display-name'])) ? $this->metadata['extra']['display-name'] : '',
));
diff --git a/phpBB/phpbb/feed/attachments_base.php b/phpBB/phpbb/feed/attachments_base.php
index 04812f1570..df8f29a626 100644
--- a/phpBB/phpbb/feed/attachments_base.php
+++ b/phpBB/phpbb/feed/attachments_base.php
@@ -25,8 +25,11 @@ abstract class attachments_base extends \phpbb\feed\base
/**
* Retrieve the list of attachments that may be displayed
+ *
+ * @param array $post_ids Specify for which post IDs to fetch the attachments (optional)
+ * @param array $topic_ids Specify for which topic IDs to fetch the attachments (optional)
*/
- protected function fetch_attachments()
+ protected function fetch_attachments($post_ids = array(), $topic_ids = array())
{
$sql_array = array(
'SELECT' => 'a.*',
@@ -37,7 +40,20 @@ abstract class attachments_base extends \phpbb\feed\base
'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC',
);
- if (isset($this->topic_id))
+ if (!empty($post_ids))
+ {
+ $sql_array['WHERE'] .= 'AND ' . $this->db->sql_in_set('a.post_msg_id', $post_ids);
+ }
+ else if (!empty($topic_ids))
+ {
+ if (isset($this->topic_id))
+ {
+ $topic_ids[] = $this->topic_id;
+ }
+
+ $sql_array['WHERE'] .= 'AND ' . $this->db->sql_in_set('a.topic_id', $topic_ids);
+ }
+ else if (isset($this->topic_id))
{
$sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id;
}
@@ -51,6 +67,11 @@ abstract class attachments_base extends \phpbb\feed\base
);
$sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id;
}
+ else
+ {
+ // Do not allow querying the full attachments table
+ throw new \RuntimeException($this->user->lang('INVALID_FEED_ATTACHMENTS'));
+ }
$sql = $this->db->sql_build_query('SELECT', $sql_array);
$result = $this->db->sql_query($sql);
@@ -64,15 +85,6 @@ abstract class attachments_base extends \phpbb\feed\base
}
/**
- * {@inheritDoc}
- */
- public function open()
- {
- parent::open();
- $this->fetch_attachments();
- }
-
- /**
* Get attachments related to a given post
*
* @param $post_id int Post id
diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php
index 7a2087c1cd..6aba12a147 100644
--- a/phpBB/phpbb/feed/forum.php
+++ b/phpBB/phpbb/feed/forum.php
@@ -112,6 +112,8 @@ class forum extends \phpbb\feed\post_base
return false;
}
+ parent::fetch_attachments(array(), $topic_ids);
+
$this->sql = array(
'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' .
'u.username, u.user_id',
diff --git a/phpBB/phpbb/feed/news.php b/phpBB/phpbb/feed/news.php
index a02c199d85..5d4786518b 100644
--- a/phpBB/phpbb/feed/news.php
+++ b/phpBB/phpbb/feed/news.php
@@ -83,6 +83,8 @@ class news extends \phpbb\feed\topic_base
return false;
}
+ parent::fetch_attachments($post_ids);
+
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time,
diff --git a/phpBB/phpbb/feed/overall.php b/phpBB/phpbb/feed/overall.php
index ab452f5386..1176a9c182 100644
--- a/phpBB/phpbb/feed/overall.php
+++ b/phpBB/phpbb/feed/overall.php
@@ -52,6 +52,8 @@ class overall extends \phpbb\feed\post_base
return false;
}
+ parent::fetch_attachments(array(), $topic_ids);
+
// Get the actual data
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name, ' .
diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php
index 66c49e55cf..295bf3f795 100644
--- a/phpBB/phpbb/feed/topic.php
+++ b/phpBB/phpbb/feed/topic.php
@@ -91,6 +91,8 @@ class topic extends \phpbb\feed\post_base
function get_sql()
{
+ parent::fetch_attachments();
+
$this->sql = array(
'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' .
'u.username, u.user_id',
diff --git a/phpBB/phpbb/feed/topics.php b/phpBB/phpbb/feed/topics.php
index 2b9cb3501a..e6416bc064 100644
--- a/phpBB/phpbb/feed/topics.php
+++ b/phpBB/phpbb/feed/topics.php
@@ -55,6 +55,8 @@ class topics extends \phpbb\feed\topic_base
return false;
}
+ parent::fetch_attachments($post_ids);
+
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time,
diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php
index 6d5eddfc16..3b751f3233 100644
--- a/phpBB/phpbb/feed/topics_active.php
+++ b/phpBB/phpbb/feed/topics_active.php
@@ -71,6 +71,8 @@ class topics_active extends \phpbb\feed\topic_base
return false;
}
+ parent::fetch_attachments($post_ids);
+
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views,
diff --git a/phpBB/phpbb/profilefields/type/type_date.php b/phpBB/phpbb/profilefields/type/type_date.php
index 90ac9a6703..63a0c79a3d 100644
--- a/phpBB/phpbb/profilefields/type/type_date.php
+++ b/phpBB/phpbb/profilefields/type/type_date.php
@@ -264,7 +264,7 @@ class type_date extends type_base
}
$profile_row['s_year_options'] = '<option value="0"' . ((!$year) ? ' selected="selected"' : '') . '>--</option>';
- for ($i = $now['year'] - 100; $i <= $now['year'] + 100; $i++)
+ for ($i = 1901; $i <= $now['year'] + 50; $i++)
{
$profile_row['s_year_options'] .= '<option value="' . $i . '"' . (($i == $year) ? ' selected="selected"' : '') . ">$i</option>";
}
diff --git a/phpBB/phpbb/request/request.php b/phpBB/phpbb/request/request.php
index 4cac6fbaea..00ff9064cb 100644
--- a/phpBB/phpbb/request/request.php
+++ b/phpBB/phpbb/request/request.php
@@ -169,12 +169,6 @@ class request implements \phpbb\request\request_interface
$GLOBALS[$this->super_globals[$super_global]][$var_name] = $value;
}
}
-
- if (!$this->super_globals_disabled())
- {
- unset($GLOBALS[$this->super_globals[$super_global]][$var_name]);
- $GLOBALS[$this->super_globals[$super_global]][$var_name] = $value;
- }
}
/**
diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php
index 9faf5ca08b..f8bda9ae81 100644
--- a/phpBB/phpbb/search/fulltext_mysql.php
+++ b/phpBB/phpbb/search/fulltext_mysql.php
@@ -942,38 +942,45 @@ class fulltext_mysql extends \phpbb\search\base
$this->get_stats();
}
- $alter = array();
+ $alter_list = array();
if (!isset($this->stats['post_subject']))
{
+ $alter_entry = array();
if ($this->db->get_sql_layer() == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
{
- $alter[] = 'MODIFY post_subject varchar(255) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL';
+ $alter_entry[] = 'MODIFY post_subject varchar(255) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL';
}
else
{
- $alter[] = 'MODIFY post_subject text NOT NULL';
+ $alter_entry[] = 'MODIFY post_subject text NOT NULL';
}
- $alter[] = 'ADD FULLTEXT (post_subject)';
+ $alter_entry[] = 'ADD FULLTEXT (post_subject)';
+ $alter_list[] = $alter_entry;
}
if (!isset($this->stats['post_content']))
{
+ $alter_entry = array();
if ($this->db->get_sql_layer() == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
{
- $alter[] = 'MODIFY post_text mediumtext COLLATE utf8_unicode_ci NOT NULL';
+ $alter_entry[] = 'MODIFY post_text mediumtext COLLATE utf8_unicode_ci NOT NULL';
}
else
{
- $alter[] = 'MODIFY post_text mediumtext NOT NULL';
+ $alter_entry[] = 'MODIFY post_text mediumtext NOT NULL';
}
- $alter[] = 'ADD FULLTEXT post_content (post_text, post_subject)';
+ $alter_entry[] = 'ADD FULLTEXT post_content (post_text, post_subject)';
+ $alter_list[] = $alter_entry;
}
- if (sizeof($alter))
+ if (sizeof($alter_list))
{
- $this->db->sql_query('ALTER TABLE ' . POSTS_TABLE . ' ' . implode(', ', $alter));
+ foreach ($alter_list as $alter)
+ {
+ $this->db->sql_query('ALTER TABLE ' . POSTS_TABLE . ' ' . implode(', ', $alter));
+ }
}
$this->db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE);
diff --git a/phpBB/phpbb/template/base.php b/phpBB/phpbb/template/base.php
index 9a40702ba8..41c0a01ba8 100644
--- a/phpBB/phpbb/template/base.php
+++ b/phpBB/phpbb/template/base.php
@@ -133,6 +133,14 @@ abstract class base implements template
}
/**
+ * {@inheritdoc}
+ */
+ public function find_key_index($blockname, $key)
+ {
+ return $this->context->find_key_index($blockname, $key);
+ }
+
+ /**
* Calls hook if any is defined.
*
* @param string $handle Template handle being displayed.
diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php
index 4ee48205c8..5d04a09865 100644
--- a/phpBB/phpbb/template/context.php
+++ b/phpBB/phpbb/template/context.php
@@ -264,6 +264,89 @@ class context
}
/**
+ * Find the index for a specified key in the innermost specified block
+ *
+ * @param string $blockname the blockname, for example 'loop'
+ * @param mixed $key Key to search for
+ *
+ * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position]
+ *
+ * int: Position [the position to search for]
+ *
+ * If key is false the position is set to 0
+ * If key is true the position is set to the last entry
+ *
+ * @return mixed false if not found, index position otherwise; be sure to test with ===
+ */
+ public function find_key_index($blockname, $key)
+ {
+ // For nested block, $blockcount > 0, for top-level block, $blockcount == 0
+ $blocks = explode('.', $blockname);
+ $blockcount = sizeof($blocks) - 1;
+
+ $block = $this->tpldata;
+ for ($i = 0; $i < $blockcount; $i++)
+ {
+ if (($pos = strpos($blocks[$i], '[')) !== false)
+ {
+ $name = substr($blocks[$i], 0, $pos);
+
+ if (strpos($blocks[$i], '[]') === $pos)
+ {
+ $index = sizeof($block[$name]) - 1;
+ }
+ else
+ {
+ $index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1);
+ }
+ }
+ else
+ {
+ $name = $blocks[$i];
+ $index = sizeof($block[$name]) - 1;
+ }
+ if (!isset($block[$name]))
+ {
+ return false;
+ }
+ $block = $block[$name];
+ if (!isset($block[$index]))
+ {
+ return false;
+ }
+ $block = $block[$index];
+ }
+
+ if (!isset($block[$blocks[$i]]))
+ {
+ return false;
+ }
+ $block = $block[$blocks[$i]]; // Traverse the last block
+
+ // Change key to zero (change first position) if false and to last position if true
+ if ($key === false || $key === true)
+ {
+ return ($key === false) ? 0 : sizeof($block) - 1;
+ }
+
+ // Get correct position if array given
+ if (is_array($key))
+ {
+ // Search array to get correct position
+ list($search_key, $search_value) = @each($key);
+ foreach ($block as $i => $val_ary)
+ {
+ if ($val_ary[$search_key] === $search_value)
+ {
+ return $i;
+ }
+ }
+ }
+
+ return (is_int($key) && ((0 <= $key) && ($key < sizeof($block)))) ? $key : false;
+ }
+
+ /**
* Change already assigned key variable pair (one-dimensional - single loop entry)
*
* An example of how to use this function:
@@ -293,45 +376,49 @@ class context
public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert')
{
$this->num_rows_is_set = false;
- if (strpos($blockname, '.') !== false)
- {
- // Nested block.
- $blocks = explode('.', $blockname);
- $blockcount = sizeof($blocks) - 1;
- $block = &$this->tpldata;
- for ($i = 0; $i < $blockcount; $i++)
+ // For nested block, $blockcount > 0, for top-level block, $blockcount == 0
+ $blocks = explode('.', $blockname);
+ $blockcount = sizeof($blocks) - 1;
+
+ $block = &$this->tpldata;
+ for ($i = 0; $i < $blockcount; $i++)
+ {
+ if (($pos = strpos($blocks[$i], '[')) !== false)
{
- if (($pos = strpos($blocks[$i], '[')) !== false)
+ $name = substr($blocks[$i], 0, $pos);
+
+ if (strpos($blocks[$i], '[]') === $pos)
{
- $name = substr($blocks[$i], 0, $pos);
-
- if (strpos($blocks[$i], '[]') === $pos)
- {
- $index = sizeof($block[$name]) - 1;
- }
- else
- {
- $index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1);
- }
+ $index = sizeof($block[$name]) - 1;
}
else
{
- $name = $blocks[$i];
- $index = sizeof($block[$name]) - 1;
+ $index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1);
}
- $block = &$block[$name];
- $block = &$block[$index];
}
-
- $block = &$block[$blocks[$i]]; // Traverse the last block
+ else
+ {
+ $name = $blocks[$i];
+ $index = sizeof($block[$name]) - 1;
+ }
+ $block = &$block[$name];
+ $block = &$block[$index];
}
- else
+ $name = $blocks[$i];
+
+ // If last block does not exist and we are inserting, and not searching for key, we create it empty; otherwise, nothing to do
+ if (!isset($block[$name]))
{
- // Top-level block.
- $block = &$this->tpldata[$blockname];
+ if ($mode != 'insert' || is_array($key))
+ {
+ return false;
+ }
+ $block[$name] = array();
}
+ $block = &$block[$name]; // Now we can traverse the last block
+
// Change key to zero (change first position) if false and to last position if true
if ($key === false || $key === true)
{
@@ -365,20 +452,21 @@ class context
if ($mode == 'insert')
{
// Make sure we are not exceeding the last iteration
- if ($key >= sizeof($this->tpldata[$blockname]))
+ if ($key >= sizeof($block))
{
- $key = sizeof($this->tpldata[$blockname]);
- unset($this->tpldata[$blockname][($key - 1)]['S_LAST_ROW']);
+ $key = sizeof($block);
+ unset($block[($key - 1)]['S_LAST_ROW']);
$vararray['S_LAST_ROW'] = true;
}
- else if ($key === 0)
+ if ($key <= 0)
{
- unset($this->tpldata[$blockname][0]['S_FIRST_ROW']);
+ $key = 0;
+ unset($block[0]['S_FIRST_ROW']);
$vararray['S_FIRST_ROW'] = true;
}
// Assign S_BLOCK_NAME
- $vararray['S_BLOCK_NAME'] = $blockname;
+ $vararray['S_BLOCK_NAME'] = $name;
// Re-position template blocks
for ($i = sizeof($block); $i > $key; $i--)
@@ -398,6 +486,12 @@ class context
// Which block to change?
if ($mode == 'change')
{
+ // If key is out of bounds, do not change anything
+ if ($key > sizeof($block) || $key < 0)
+ {
+ return false;
+ }
+
if ($key == sizeof($block))
{
$key--;
diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php
index 041ecb12e4..9e3d658ca8 100644
--- a/phpBB/phpbb/template/template.php
+++ b/phpBB/phpbb/template/template.php
@@ -173,6 +173,23 @@ interface template
public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert');
/**
+ * Find the index for a specified key in the innermost specified block
+ *
+ * @param string $blockname the blockname, for example 'loop'
+ * @param mixed $key Key to search for
+ *
+ * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position]
+ *
+ * int: Position [the position to search for]
+ *
+ * If key is false the position is set to 0
+ * If key is true the position is set to the last entry
+ *
+ * @return mixed false if not found, index position otherwise; be sure to test with ===
+ */
+ public function find_key_index($blockname, $key);
+
+ /**
* Get path to template for handle (required for BBCode parser)
*
* @param string $handle Handle to retrieve the source file
diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php
index 3a983491b9..d5b14129b5 100644
--- a/phpBB/phpbb/template/twig/extension.php
+++ b/phpBB/phpbb/template/twig/extension.php
@@ -169,8 +169,7 @@ class extension extends \Twig_Extension
$args = func_get_args();
$key = $args[0];
- $context = $this->context->get_data_ref();
- $context_vars = $context['.'][0];
+ $context_vars = $this->context->get_root_ref();
if (isset($context_vars['L_' . $key]))
{
diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php
index a1e66ba8fe..9dc5a2e7c9 100644
--- a/phpBB/phpbb/version_helper.php
+++ b/phpBB/phpbb/version_helper.php
@@ -184,7 +184,7 @@ class version_helper
$self = $this;
$current_version = $this->current_version;
- // Filter out any versions less than to the current version
+ // Filter out any versions less than the current version
$versions = array_filter($versions, function($data) use ($self, $current_version) {
return $self->compare($data['current'], $current_version, '>=');
});
@@ -201,11 +201,117 @@ class version_helper
}
/**
+ * Gets the latest update for the current branch the user is on
+ * Will suggest versions from newer branches when EoL has been reached
+ * and/or version from newer branch is needed for having all known security
+ * issues fixed.
+ *
+ * @param bool $force_update Ignores cached data. Defaults to false.
+ * @param bool $force_cache Force the use of the cache. Override $force_update.
+ * @return array Version info or empty array if there are no updates
+ * @throws \RuntimeException
+ */
+ public function get_update_on_branch($force_update = false, $force_cache = false)
+ {
+ $versions = $this->get_versions_matching_stability($force_update, $force_cache);
+
+ $self = $this;
+ $current_version = $this->current_version;
+
+ // Filter out any versions less than the current version
+ $versions = array_filter($versions, function($data) use ($self, $current_version) {
+ return $self->compare($data['current'], $current_version, '>=');
+ });
+
+ // Get the lowest version from the previous list.
+ $update_info = array_reduce($versions, function($value, $data) use ($self, $current_version) {
+ if ($value === null && $self->compare($data['current'], $current_version, '>='))
+ {
+ if (!$data['eol'] && (!$data['security'] || $self->compare($data['security'], $data['current'], '<=')))
+ {
+ return ($self->compare($data['current'], $current_version, '>')) ? $data : array();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ return $value;
+ });
+
+ return $update_info === null ? array() : $update_info;
+ }
+
+ /**
+ * Gets the latest extension update for the current phpBB branch the user is on
+ * Will suggest versions from newer branches when EoL has been reached
+ * and/or version from newer branch is needed for having all known security
+ * issues fixed.
+ *
+ * @param bool $force_update Ignores cached data. Defaults to false.
+ * @param bool $force_cache Force the use of the cache. Override $force_update.
+ * @return array Version info or empty array if there are no updates
+ * @throws \RuntimeException
+ */
+ public function get_ext_update_on_branch($force_update = false, $force_cache = false)
+ {
+ $versions = $this->get_versions_matching_stability($force_update, $force_cache);
+
+ $self = $this;
+ $current_version = $this->current_version;
+
+ // Get current phpBB branch from version, e.g.: 3.2
+ preg_match('/^(\d+\.\d+).*$/', $this->config['version'], $matches);
+ $current_branch = $matches[1];
+
+ // Filter out any versions less than the current version
+ $versions = array_filter($versions, function($data) use ($self, $current_version) {
+ return $self->compare($data['current'], $current_version, '>=');
+ });
+
+ // Filter out any phpbb branches less than the current version
+ $branches = array_filter(array_keys($versions), function($branch) use ($self, $current_branch) {
+ return $self->compare($branch, $current_branch, '>=');
+ });
+ if (!empty($branches))
+ {
+ $versions = array_intersect_key($versions, array_flip($branches));
+ }
+ else
+ {
+ // If branches are empty, it means the current phpBB branch is newer than any branch the
+ // extension was validated against. Reverse sort the versions array so we get the newest
+ // validated release available.
+ krsort($versions);
+ }
+
+ // Get the first available version from the previous list.
+ $update_info = array_reduce($versions, function($value, $data) use ($self, $current_version) {
+ if ($value === null && $self->compare($data['current'], $current_version, '>='))
+ {
+ if (!$data['eol'] && (!$data['security'] || $self->compare($data['security'], $data['current'], '<=')))
+ {
+ return $self->compare($data['current'], $current_version, '>') ? $data : array();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ return $value;
+ });
+
+ return $update_info === null ? array() : $update_info;
+ }
+
+ /**
* Obtains the latest version information
*
* @param bool $force_update Ignores cached data. Defaults to false.
* @param bool $force_cache Force the use of the cache. Override $force_update.
- * @return string
+ * @return array
* @throws \RuntimeException
*/
public function get_suggested_updates($force_update = false, $force_cache = false)
@@ -226,7 +332,7 @@ class version_helper
*
* @param bool $force_update Ignores cached data. Defaults to false.
* @param bool $force_cache Force the use of the cache. Override $force_update.
- * @return string Version info
+ * @return array Version info
* @throws \RuntimeException
*/
public function get_versions_matching_stability($force_update = false, $force_cache = false)
@@ -246,7 +352,7 @@ class version_helper
*
* @param bool $force_update Ignores cached data. Defaults to false.
* @param bool $force_cache Force the use of the cache. Override $force_update.
- * @return string Version info, includes stable and unstable data
+ * @return array Version info, includes stable and unstable data
* @throws \RuntimeException
*/
public function get_versions($force_update = false, $force_cache = false)
diff --git a/phpBB/posting.php b/phpBB/posting.php
index db580d926b..4651a1fd2c 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -84,7 +84,7 @@ $current_time = time();
* NOTE: Should be actual language strings, NOT
* language keys.
* @since 3.1.0-a1
-* @change 3.1.2-RC1 Removed 'delete' var as it does not exist
+* @changed 3.1.2-RC1 Removed 'delete' var as it does not exist
*/
$vars = array(
'post_id',
@@ -941,7 +941,9 @@ if ($submit || $preview || $refresh)
* is posting a new topic or editing a post)
* @var bool refresh Whether or not to retain previously submitted data
* @var object message_parser The message parser object
+ * @var array error Array of errors
* @since 3.1.2-RC1
+ * @changed 3.1.11-RC1 Added error
*/
$vars = array(
'post_data',
@@ -956,6 +958,7 @@ if ($submit || $preview || $refresh)
'cancel',
'refresh',
'message_parser',
+ 'error',
);
extract($phpbb_dispatcher->trigger_event('core.posting_modify_message_text', compact($vars)));
@@ -1261,7 +1264,7 @@ if ($submit || $preview || $refresh)
* @var array error Any error strings; a non-empty array aborts form submission.
* NOTE: Should be actual language strings, NOT language keys.
* @since 3.1.0-RC5
- * @change 3.1.5-RC1 Added poll array to the event
+ * @changed 3.1.5-RC1 Added poll array to the event
*/
$vars = array(
'post_data',
@@ -1869,13 +1872,13 @@ if (($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_
* posting page via $template->assign_vars()
* @var object message_parser The message parser object
* @since 3.1.0-a1
-* @change 3.1.0-b3 Added vars post_data, moderators, mode, page_title,
+* @changed 3.1.0-b3 Added vars post_data, moderators, mode, page_title,
* s_topic_icons, form_enctype, s_action, s_hidden_fields,
* post_id, topic_id, forum_id, submit, preview, save, load,
* delete, cancel, refresh, error, page_data, message_parser
-* @change 3.1.2-RC1 Removed 'delete' var as it does not exist
-* @change 3.1.5-RC1 Added poll variables to the page_data array
-* @change 3.1.6-RC1 Added 'draft_id' var
+* @changed 3.1.2-RC1 Removed 'delete' var as it does not exist
+* @changed 3.1.5-RC1 Added poll variables to the page_data array
+* @changed 3.1.6-RC1 Added 'draft_id' var
*/
$vars = array(
'post_data',
diff --git a/phpBB/styles/prosilver/template/bbcode.html b/phpBB/styles/prosilver/template/bbcode.html
index 3e38d13a32..49bcd56945 100644
--- a/phpBB/styles/prosilver/template/bbcode.html
+++ b/phpBB/styles/prosilver/template/bbcode.html
@@ -18,13 +18,13 @@
<!-- BEGIN inline_attachment_open --><div class="inline-attachment"><!-- END inline_attachment_open -->
<!-- BEGIN inline_attachment_close --></div><!-- END inline_attachment_close -->
-<!-- BEGIN b_open --><strong><!-- END b_open -->
+<!-- BEGIN b_open --><strong class="text-strong"><!-- END b_open -->
<!-- BEGIN b_close --></strong><!-- END b_close -->
<!-- BEGIN u_open --><span style="text-decoration: underline"><!-- END u_open -->
<!-- BEGIN u_close --></span><!-- END u_close -->
-<!-- BEGIN i_open --><em><!-- END i_open -->
+<!-- BEGIN i_open --><em class="text-italics"><!-- END i_open -->
<!-- BEGIN i_close --></em><!-- END i_close -->
<!-- BEGIN color --><span style="color: {COLOR}">{TEXT}</span><!-- END color -->
diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js
index 99f3108fad..d779008f80 100644
--- a/phpBB/styles/prosilver/template/forum_fn.js
+++ b/phpBB/styles/prosilver/template/forum_fn.js
@@ -57,7 +57,7 @@ function marklist(id, name, state) {
jQuery('#' + id + ' input[type=checkbox][name]').each(function() {
var $this = jQuery(this);
- if ($this.attr('name').substr(0, name.length) === name) {
+ if ($this.attr('name').substr(0, name.length) === name && !$this.prop('disabled')) {
$this.prop('checked', state);
}
});
diff --git a/phpBB/styles/prosilver/template/mcp_post.html b/phpBB/styles/prosilver/template/mcp_post.html
index e5777d206a..5acdcef859 100644
--- a/phpBB/styles/prosilver/template/mcp_post.html
+++ b/phpBB/styles/prosilver/template/mcp_post.html
@@ -294,6 +294,14 @@
</tbody>
</table>
+ <div class="pagination">
+ <!-- INCLUDE pagination.html -->
+ </div>
+ </div>
+ </div>
+
+ <div class="panel">
+ <div class="inner">
<table class="table1">
<thead>
<tr>
@@ -315,7 +323,27 @@
</tbody>
</table>
- <p><a href="{U_LOOKUP_ALL}#ip">{L_LOOKUP_ALL}</a></p>
+ <div class="buttons">
+ <p><a href="{U_LOOKUP_ALL}#ip">{L_LOOKUP_ALL}</a></p>
+ </div>
+
+ <div class="pagination">
+ <ul>
+ <!-- BEGIN pagination_ips -->
+ <!-- IF pagination_ips.S_IS_PREV -->
+ <li class="previous"><a href="{pagination_ips.PAGE_URL}" rel="prev" role="button">{L_PREVIOUS}</a></li>
+ <!-- ELSEIF pagination_ips.S_IS_CURRENT -->
+ <li class="active"><span>{pagination_ips.PAGE_NUMBER}</span></li>
+ <!-- ELSEIF pagination_ips.S_IS_ELLIPSIS -->
+ <li class="ellipsis" role="separator"><span>{L_ELLIPSIS}</span></li>
+ <!-- ELSEIF pagination_ips.S_IS_NEXT -->
+ <li class="next"><a href="{pagination_ips.PAGE_URL}" rel="next" role="button">{L_NEXT}</a></li>
+ <!-- ELSE -->
+ <li><a href="{pagination_ips.PAGE_URL}" role="button">{pagination_ips.PAGE_NUMBER}</a></li>
+ <!-- ENDIF -->
+ <!-- END pagination_ips -->
+ </ul>
+ </div>
</div>
</div>
diff --git a/phpBB/styles/prosilver/template/memberlist_team.html b/phpBB/styles/prosilver/template/memberlist_team.html
index b7f2d66d94..327dde412e 100644
--- a/phpBB/styles/prosilver/template/memberlist_team.html
+++ b/phpBB/styles/prosilver/template/memberlist_team.html
@@ -19,7 +19,7 @@
<tbody>
<!-- BEGIN user -->
<tr class="<!-- IF group.user.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF group.user.S_INACTIVE --> inactive<!-- ENDIF -->">
- <td><!-- IF group.user.RANK_IMG --><span class="rank-img">{group.user.RANK_IMG}</span><!-- ELSE --><span class="rank-img">{group.user.RANK_TITLE}</span><!-- ENDIF -->{group.user.USERNAME_FULL}<!-- IF group.user.S_INACTIVE --> ({L_INACTIVE})<!-- ENDIF --></td>
+ <td><!-- IF group.user.RANK_IMG --><span class="rank-img">{group.user.RANK_IMG}</span><!-- ELSE --><span class="rank-img">{group.user.RANK_TITLE}</span><!-- ENDIF --><!-- EVENT memberlist_team_username_prepend -->{group.user.USERNAME_FULL}<!-- IF group.user.S_INACTIVE --> ({L_INACTIVE})<!-- ENDIF --><!-- EVENT memberlist_team_username_append --></td>
<td class="info"><!-- IF group.user.U_GROUP -->
<a<!-- IF group.user.GROUP_COLOR --> style="font-weight: bold; color: #{group.user.GROUP_COLOR}"<!-- ENDIF --> href="{group.user.U_GROUP}">{group.user.GROUP_NAME}</a>
<!-- ELSE -->
diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html
index b6c454bf05..4365482314 100644
--- a/phpBB/styles/prosilver/template/search_results.html
+++ b/phpBB/styles/prosilver/template/search_results.html
@@ -76,6 +76,7 @@
<!-- IF searchresults.S_TOPIC_UNAPPROVED or searchresults.S_POSTS_UNAPPROVED --><a href="{searchresults.U_MCP_QUEUE}">{searchresults.UNAPPROVED_IMG}</a> <!-- ENDIF -->
<!-- IF searchresults.S_TOPIC_DELETED --><a href="{searchresults.U_MCP_QUEUE}">{DELETED_IMG}</a> <!-- ENDIF -->
<!-- IF searchresults.S_TOPIC_REPORTED --><a href="{searchresults.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF --><br />
+ <!-- EVENT topiclist_row_topic_title_after -->
<!-- IF .searchresults.pagination -->
<div class="pagination">
<ul>
@@ -91,7 +92,6 @@
</div>
<!-- ENDIF -->
<!-- IF searchresults.S_HAS_POLL -->{POLL_IMG} <!-- ENDIF -->
- <!-- EVENT topiclist_row_topic_title_after -->
{L_POST_BY_AUTHOR} {searchresults.TOPIC_AUTHOR_FULL} &raquo; {searchresults.FIRST_POST_TIME} &raquo; {L_IN} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a>
<!-- EVENT topiclist_row_append -->
diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css
index 0ac7a45a23..df923aa948 100644
--- a/phpBB/styles/prosilver/theme/common.css
+++ b/phpBB/styles/prosilver/theme/common.css
@@ -146,10 +146,18 @@ b, strong {
font-weight: bold;
}
+.text-strong {
+ font-weight: bold;
+}
+
i, em {
font-style: italic;
}
+.text-italics {
+ font-style: italic;
+}
+
u {
text-decoration: underline;
}
diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css
index e7c0e177a6..dfb91891fa 100644
--- a/phpBB/styles/prosilver/theme/content.css
+++ b/phpBB/styles/prosilver/theme/content.css
@@ -493,6 +493,8 @@ blockquote.uncited {
padding: 3px;
border: 1px solid transparent;
font-size: 1em;
+ overflow-x: scroll;
+ word-wrap: normal;
}
.codebox p {
diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css
index 777f011c35..235c230ed4 100644
--- a/phpBB/styles/prosilver/theme/forms.css
+++ b/phpBB/styles/prosilver/theme/forms.css
@@ -288,7 +288,7 @@ textarea.inputbox {
}
input[type="number"] {
- -moz-padding-end: inherit;
+ -moz-padding-end: 0;
}
input[type="search"] {
diff --git a/phpBB/styles/subsilver2/template/memberlist_search.html b/phpBB/styles/subsilver2/template/memberlist_search.html
index 2096062607..5a4c430cd2 100644
--- a/phpBB/styles/subsilver2/template/memberlist_search.html
+++ b/phpBB/styles/subsilver2/template/memberlist_search.html
@@ -54,7 +54,7 @@
for (var r = 0; r < rb.length; r++)
{
- if (rb[r].name.substr(0, name.length) == name)
+ if (rb[r].name.substr(0, name.length) == name && rb[r].disabled !== true)
{
rb[r].checked = state;
}
diff --git a/phpBB/styles/subsilver2/template/memberlist_team.html b/phpBB/styles/subsilver2/template/memberlist_team.html
index 18995b6e50..75fade184c 100644
--- a/phpBB/styles/subsilver2/template/memberlist_team.html
+++ b/phpBB/styles/subsilver2/template/memberlist_team.html
@@ -17,7 +17,7 @@
<!-- BEGIN user -->
<!-- IF group.user.S_ROW_COUNT is even --><tr class="row2"><!-- ELSE --><tr class="row1"><!-- ENDIF -->
- <td class="gen" align="center"><strong>{group.user.USERNAME_FULL}</strong><!-- IF group.user.S_INACTIVE --> <em>({L_INACTIVE})</em><!-- ENDIF --></td>
+ <td class="gen" align="center"><!-- EVENT memberlist_team_username_prepend --><strong>{group.user.USERNAME_FULL}</strong><!-- IF group.user.S_INACTIVE --> <em>({L_INACTIVE})</em><!-- ENDIF --><!-- EVENT memberlist_team_username_append --></td>
<!-- IF S_DISPLAY_MODERATOR_FORUMS --><td class="gensmall" align="center"><!-- IF group.user.FORUM_OPTIONS --><select style="width: 100%;">{group.user.FORUMS}</select><!-- ELSEIF group.user.FORUMS -->{group.user.FORUMS}<!-- ELSE -->-<!-- ENDIF --></td><!-- ENDIF -->
<td class="gensmall" align="center" nowrap="nowrap">&nbsp;
<!-- IF group.user.U_GROUP -->
diff --git a/phpBB/styles/subsilver2/template/overall_header.html b/phpBB/styles/subsilver2/template/overall_header.html
index a4185785e3..ae3d48215e 100644
--- a/phpBB/styles/subsilver2/template/overall_header.html
+++ b/phpBB/styles/subsilver2/template/overall_header.html
@@ -83,7 +83,7 @@ function marklist(id, name, state)
for (var r = 0; r < rb.length; r++)
{
- if (rb[r].name.substr(0, name.length) == name)
+ if (rb[r].name.substr(0, name.length) == name && rb[r].disabled !== true)
{
rb[r].checked = state;
}
diff --git a/phpBB/ucp.php b/phpBB/ucp.php
index 8c74ca1f3c..5cd602bab5 100644
--- a/phpBB/ucp.php
+++ b/phpBB/ucp.php
@@ -237,6 +237,19 @@ switch ($mode)
add_log('admin', 'LOG_ACL_TRANSFER_PERMISSIONS', $user_row['username']);
$message = sprintf($user->lang['PERMISSIONS_TRANSFERRED'], $user_row['username']) . '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>');
+
+ /**
+ * Event to run code after permissions are switched
+ *
+ * @event core.ucp_switch_permissions
+ * @var int user_id User ID to switch permission to
+ * @var array user_row User data
+ * @var string message Success message
+ * @since 3.1.11-RC1
+ */
+ $vars = array('user_id', 'user_row', 'message');
+ extract($phpbb_dispatcher->trigger_event('core.ucp_switch_permissions', compact($vars)));
+
trigger_error($message);
break;
@@ -260,6 +273,18 @@ switch ($mode)
add_log('admin', 'LOG_ACL_RESTORE_PERMISSIONS', $username);
$message = $user->lang['PERMISSIONS_RESTORED'] . '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>');
+
+ /**
+ * Event to run code after permissions are restored
+ *
+ * @event core.ucp_restore_permissions
+ * @var string username User name
+ * @var string message Success message
+ * @since 3.1.11-RC1
+ */
+ $vars = array('username', 'message');
+ extract($phpbb_dispatcher->trigger_event('core.ucp_restore_permissions', compact($vars)));
+
trigger_error($message);
break;
diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php
index e0cc9ba512..5c51975150 100644
--- a/phpBB/viewforum.php
+++ b/phpBB/viewforum.php
@@ -146,6 +146,13 @@ else
}
}
+// Is a forum specific topic count required?
+if ($forum_data['forum_topics_per_page'])
+{
+ $config['topics_per_page'] = $forum_data['forum_topics_per_page'];
+}
+
+/* @var $phpbb_content_visibility \phpbb\content_visibility */
$phpbb_content_visibility = $phpbb_container->get('content.visibility');
// Dump out the page header and load viewforum template
@@ -209,12 +216,6 @@ if ($mark_read == 'topics')
trigger_error($user->lang['TOPICS_MARKED'] . '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . $redirect_url . '">', '</a>'));
}
-// Is a forum specific topic count required?
-if ($forum_data['forum_topics_per_page'])
-{
- $config['topics_per_page'] = $forum_data['forum_topics_per_page'];
-}
-
// Do the forum Prune thang - cron type job ...
if (!$config['use_system_cron'])
{
@@ -431,9 +432,9 @@ $sql_array = array(
* Author, Post time, Replies, Subject, Views
* @var string sort_dir Either "a" for ascending or "d" for descending
* @since 3.1.0-a1
-* @change 3.1.0-RC4 Added forum_data var
-* @change 3.1.4-RC1 Added forum_id, topics_count, sort_days, sort_key and sort_dir vars
-* @change 3.1.9-RC1 Fix types of properties
+* @changed 3.1.0-RC4 Added forum_data var
+* @changed 3.1.4-RC1 Added forum_id, topics_count, sort_days, sort_key and sort_dir vars
+* @changed 3.1.9-RC1 Fix types of properties
*/
$vars = array(
'forum_data',
@@ -782,9 +783,11 @@ $topic_tracking_info = $tracking_topics = array();
* @var array topic_list Array with current viewforum page topic ids
* @var array rowset Array with topics data (in topic_id => topic_data format)
* @var int total_topic_count Forum's total topic count
+* @var int forum_id Forum identifier
* @since 3.1.0-b3
+* @changed 3.1.11-RC1 Added forum_id
*/
-$vars = array('topic_list', 'rowset', 'total_topic_count');
+$vars = array('topic_list', 'rowset', 'total_topic_count', 'forum_id');
extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topics_data', compact($vars)));
// Okay, lets dump out the page ...
diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php
index 8bfa422e26..5cb1175528 100644
--- a/phpBB/viewonline.php
+++ b/phpBB/viewonline.php
@@ -168,7 +168,7 @@ $sql_ary = array(
* @var int guest_counter Number of guests displayed
* @var array forum_data Array with forum data
* @since 3.1.0-a1
-* @change 3.1.0-a2 Added vars guest_counter and forum_data
+* @changed 3.1.0-a2 Added vars guest_counter and forum_data
*/
$vars = array('sql_ary', 'show_guests', 'guest_counter', 'forum_data');
extract($phpbb_dispatcher->trigger_event('core.viewonline_modify_sql', compact($vars)));
@@ -385,7 +385,7 @@ while ($row = $db->sql_fetchrow($result))
* @var string location_url Page url to displayed in the list
* @var array forum_data Array with forum data
* @since 3.1.0-a1
- * @change 3.1.0-a2 Added var forum_data
+ * @changed 3.1.0-a2 Added var forum_data
*/
$vars = array('on_page', 'row', 'location', 'location_url', 'forum_data');
extract($phpbb_dispatcher->trigger_event('core.viewonline_overwrite_location', compact($vars)));
diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index dc656b8fad..378e2d8f97 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -700,7 +700,7 @@ $base_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=
* @var int total_posts Topic total posts count
* @var string viewtopic_url URL to the topic page
* @since 3.1.0-RC4
-* @change 3.1.2-RC1 Added viewtopic_url
+* @changed 3.1.2-RC1 Added viewtopic_url
*/
$vars = array(
'base_url',
@@ -1200,7 +1200,7 @@ $sql_ary = array(
* @var int start Pagination information
* @var array sql_ary The SQL array to get the data of posts and posters
* @since 3.1.0-a1
-* @change 3.1.0-a2 Added vars forum_id, topic_id, topic_data, post_list, sort_days, sort_key, sort_dir, start
+* @changed 3.1.0-a2 Added vars forum_id, topic_id, topic_data, post_list, sort_days, sort_key, sort_dir, start
*/
$vars = array(
'forum_id',
@@ -2007,9 +2007,9 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
* @var array post_row Template block array of the post
* @var array topic_data Array with topic data
* @since 3.1.0-a1
- * @change 3.1.0-a3 Added vars start, current_row_number, end, attachments
- * @change 3.1.0-b3 Added topic_data array, total_posts
- * @change 3.1.0-RC3 Added poster_id
+ * @changed 3.1.0-a3 Added vars start, current_row_number, end, attachments
+ * @changed 3.1.0-b3 Added topic_data array, total_posts
+ * @changed 3.1.0-RC3 Added poster_id
*/
$vars = array(
'start',
@@ -2107,7 +2107,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
* @var array post_row Template block array of the post
* @var array topic_data Array with topic data
* @since 3.1.0-a3
- * @change 3.1.0-b3 Added topic_data array, total_posts
+ * @changed 3.1.0-b3 Added topic_data array, total_posts
*/
$vars = array(
'start',
@@ -2270,7 +2270,7 @@ $page_title = $topic_data['topic_title'] . ($start ? ' - ' . sprintf($user->lang
* @var int start Start offset used to calculate the page
* @var array post_list Array with post_ids we are going to display
* @since 3.1.0-a1
-* @change 3.1.0-RC4 Added post_list var
+* @changed 3.1.0-RC4 Added post_list var
*/
$vars = array('page_title', 'topic_data', 'forum_id', 'start', 'post_list');
extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_page_title', compact($vars)));
diff --git a/tests/di/create_container_test.php b/tests/di/create_container_test.php
index 4ae6017989..1a7eb4698c 100644
--- a/tests/di/create_container_test.php
+++ b/tests/di/create_container_test.php
@@ -53,7 +53,7 @@ namespace
$this->assertTrue($container->isFrozen());
// Checks inject_config
- $this->assertTrue($container->hasParameter('dbal.dbhost'));
+ $this->assertTrue($container->hasParameter('core.table_prefix'));
// Checks use_extensions
$this->assertTrue($container->hasParameter('enabled'));
diff --git a/tests/di/fixtures/config/services.yml b/tests/di/fixtures/config/services.yml
index f2a22ae109..913a2603c9 100644
--- a/tests/di/fixtures/config/services.yml
+++ b/tests/di/fixtures/config/services.yml
@@ -10,5 +10,8 @@ services:
arguments:
- @service_container
+ dbal.conn.driver:
+ synthetic: true
+
dispatcher:
class: phpbb\db\driver\container_mock
diff --git a/tests/di/fixtures/other_config/services.yml b/tests/di/fixtures/other_config/services.yml
index c299bfc648..d6246d3bc0 100644
--- a/tests/di/fixtures/other_config/services.yml
+++ b/tests/di/fixtures/other_config/services.yml
@@ -10,5 +10,8 @@ services:
arguments:
- @service_container
+ dbal.conn.driver:
+ synthetic: true
+
dispatcher:
class: phpbb\db\driver\container_mock
diff --git a/tests/event/fixtures/trigger_many_vars.test b/tests/event/fixtures/trigger_many_vars.test
index a624138588..5e0720d13b 100644
--- a/tests/event/fixtures/trigger_many_vars.test
+++ b/tests/event/fixtures/trigger_many_vars.test
@@ -34,7 +34,7 @@
* posting page via $template->assign_vars()
* @var object message_parser The message parser object
* @since 3.1.0-a1
- * @change 3.1.0-b3 Added vars post_data, moderators, mode, page_title,
+ * @changed 3.1.0-b3 Added vars post_data, moderators, mode, page_title,
* s_topic_icons, form_enctype, s_action, s_hidden_fields,
* post_id, topic_id, forum_id, submit, preview, save, load,
* delete, cancel, refresh, error, page_data, message_parser
diff --git a/tests/feed/attachments_base_test.php b/tests/feed/attachments_base_test.php
new file mode 100644
index 0000000000..c980dfd3d7
--- /dev/null
+++ b/tests/feed/attachments_base_test.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+require_once(dirname(__FILE__) . '/attachments_mock_feed.php');
+
+class phpbb_feed_attachments_base_test extends phpbb_database_test_case
+{
+ protected $filesystem;
+
+ /** @var \phpbb_feed_attachments_mock_feed */
+ protected $attachments_mocks_feed;
+
+ public function getDataSet()
+ {
+ return $this->createXMLDataSet(dirname(__FILE__) . '/../extension/fixtures/extensions.xml');
+ }
+
+ public function setUp()
+ {
+ global $phpbb_root_path, $phpEx;
+
+ $this->filesystem = new \phpbb\filesystem();
+ $config = new \phpbb\config\config(array());
+ $user = new \phpbb\user('\phpbb\datetime');
+ $feed_helper = new \phpbb\feed\helper($config, $user, $phpbb_root_path, $phpEx);
+ $db = $this->new_dbal();
+ $cache = new \phpbb_mock_cache();
+ $auth = new \phpbb\auth\auth();
+ $content_visibility = new \phpbb\content_visibility(
+ $auth,
+ $config,
+ new \phpbb_mock_event_dispatcher(),
+ $db,
+ $user,
+ $phpbb_root_path,
+ $phpEx,
+ FORUMS_TABLE,
+ POSTS_TABLE,
+ TOPICS_TABLE,
+ USERS_TABLE
+ );
+
+ $this->attachments_mocks_feed = new \phpbb_feed_attachments_mock_feed(
+ $feed_helper,
+ $config,
+ $db,
+ $cache,
+ $user,
+ $auth,
+ $content_visibility,
+ new \phpbb_mock_event_dispatcher(),
+ $phpEx
+ );
+ }
+
+ public function data_fetch_attachments()
+ {
+ return array(
+ array(array(0), array(0)),
+ array(array(), array(1)),
+ array(array(), array(), 'RuntimeException')
+ );
+ }
+
+ /**
+ * @dataProvider data_fetch_attachments
+ */
+ public function test_fetch_attachments($post_ids, $topic_ids, $expected_exception = false)
+ {
+ $this->attachments_mocks_feed->post_ids = $post_ids;
+ $this->attachments_mocks_feed->topic_ids = $topic_ids;
+
+ if ($expected_exception !== false)
+ {
+ $this->setExpectedException($expected_exception);
+
+ $this->attachments_mocks_feed->get_sql();
+ }
+ else
+ {
+ $this->assertTrue($this->attachments_mocks_feed->get_sql());
+ }
+ }
+}
diff --git a/tests/feed/attachments_mock_feed.php b/tests/feed/attachments_mock_feed.php
new file mode 100644
index 0000000000..0e623fed24
--- /dev/null
+++ b/tests/feed/attachments_mock_feed.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+/**
+ * Board wide feed (aka overall feed)
+ *
+ * This will give you the newest {$this->num_items} posts
+ * from the whole board.
+ */
+class phpbb_feed_attachments_mock_feed extends \phpbb\feed\attachments_base
+{
+ public $topic_ids = array();
+ public $post_ids = array();
+
+ function get_sql()
+ {
+ parent::fetch_attachments($this->post_ids, $this->topic_ids);
+
+ return true;
+ }
+}
diff --git a/tests/mcp/fixtures/post_ip.xml b/tests/mcp/fixtures/post_ip.xml
new file mode 100644
index 0000000000..fad2193396
--- /dev/null
+++ b/tests/mcp/fixtures/post_ip.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<dataset>
+ <table name="phpbb_posts">
+ <column>post_id</column>
+ <column>poster_id</column>
+ <column>post_edit_user</column>
+ <column>post_delete_user</column>
+ <column>post_username</column>
+ <column>topic_id</column>
+ <column>forum_id</column>
+ <column>post_visibility</column>
+ <column>post_time</column>
+ <column>post_text</column>
+ <column>post_reported</column>
+ <column>poster_ip</column>
+ <row>
+ <value>1</value>
+ <value>2</value>
+ <value>2</value>
+ <value>2</value>
+ <value></value>
+ <value>1</value>
+ <value>1</value>
+ <value>1</value>
+ <value>1</value>
+ <value></value>
+ <value>1</value>
+ <value>127.0.0.1</value>
+ </row>
+ <row>
+ <value>2</value>
+ <value>1</value>
+ <value>1</value>
+ <value>1</value>
+ <value>Other</value>
+ <value>2</value>
+ <value>2</value>
+ <value>1</value>
+ <value>1</value>
+ <value></value>
+ <value>1</value>
+ <value>127.0.0.2</value>
+ </row>
+ <row>
+ <value>3</value>
+ <value>2</value>
+ <value>2</value>
+ <value>2</value>
+ <value></value>
+ <value>3</value>
+ <value>3</value>
+ <value>1</value>
+ <value>1</value>
+ <value></value>
+ <value>1</value>
+ <value>127.0.0.3</value>
+ </row>
+ <row>
+ <value>4</value>
+ <value>1</value>
+ <value>1</value>
+ <value>1</value>
+ <value>Other</value>
+ <value>4</value>
+ <value>4</value>
+ <value>1</value>
+ <value>1</value>
+ <value></value>
+ <value>1</value>
+ <value>127.0.0.1</value>
+ </row>
+ </table>
+</dataset>
diff --git a/tests/mcp/post_ip_test.php b/tests/mcp/post_ip_test.php
new file mode 100644
index 0000000000..72a9f62774
--- /dev/null
+++ b/tests/mcp/post_ip_test.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+require_once dirname(__FILE__) . '/../../phpBB/includes/mcp/mcp_post.php';
+
+class phpbb_mcp_post_ip_test extends phpbb_database_test_case
+{
+ /** @var \phpbb\db\driver\driver_interface */
+ protected $db;
+
+ public function getDataSet()
+ {
+ return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/post_ip.xml');
+ }
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->db = $this->new_dbal();
+ }
+
+ public function data_get_num_ips()
+ {
+ return array(
+ array(2, 1),
+ array(2, 2),
+ array(0, 3),
+ );
+ }
+
+ /**
+ * @dataProvider data_get_num_ips
+ */
+ public function test_get_num_ips($expected, $poster_id)
+ {
+ $this->assertSame($expected, phpbb_get_num_ips_for_poster($this->db, $poster_id));
+ }
+
+ public function data_get_num_posters()
+ {
+ return array(
+ array(2, '127.0.0.1'),
+ array(1, '127.0.0.2'),
+ array(1, '127.0.0.3'),
+ array(0, '127.0.0.4'),
+ );
+ }
+
+ /**
+ * @dataProvider data_get_num_posters
+ */
+ public function test_get_num_posters($expected, $ip)
+ {
+ $this->assertSame($expected, phpbb_get_num_posters_for_ip($this->db, $ip));
+ }
+}
diff --git a/tests/mock/extension_manager.php b/tests/mock/extension_manager.php
index 3b759fbbc2..94268159a8 100644
--- a/tests/mock/extension_manager.php
+++ b/tests/mock/extension_manager.php
@@ -20,5 +20,7 @@ class phpbb_mock_extension_manager extends \phpbb\extension\manager
$this->extensions = $extensions;
$this->filesystem = new \phpbb\filesystem();
$this->container = $container;
+ $this->config = new \phpbb\config\config(array());
+ $this->user = new \phpbb\user('\phpbb\datetime');
}
}
diff --git a/tests/template/template_test.php b/tests/template/template_test.php
index 0bbfe3848d..69546cc227 100644
--- a/tests/template/template_test.php
+++ b/tests/template/template_test.php
@@ -528,22 +528,139 @@ EOT
),
array(
'outer',
+ array('VARIABLE' => 'changed'),
+ 0,
+ 'change',
+ <<<EOT
+outer - 0 - changed
+middle - 0
+middle - 1
+outer - 1
+middle - 0
+middle - 1
+outer - 2
+middle - 0
+middle - 1
+EOT
+,
+ 'Test changing at 0 on top level block',
+ ),
+ array(
+ 'outer',
+ array('VARIABLE' => 'changed'),
+ array('S_ROW_NUM' => 2),
+ 'change',
+ <<<EOT
+outer - 0
+middle - 0
+middle - 1
+outer - 1
+middle - 0
+middle - 1
+outer - 2 - changed
+middle - 0
+middle - 1
+EOT
+,
+ 'Test changing at KEY on top level block',
+ ),
+ array(
+ 'outer.middle',
+ array('VARIABLE' => 'before'),
+ false,
+ 'insert',
+ <<<EOT
+outer - 0
+middle - 0
+middle - 1
+outer - 1
+middle - 0
+middle - 1
+outer - 2
+middle - 0 - before
+middle - 1
+middle - 2
+EOT
+,
+ 'Test inserting before on middle level block',
+ ),
+ array(
+ 'outer.middle',
+ array('VARIABLE' => 'after'),
+ true,
+ 'insert',
+ <<<EOT
+outer - 0
+middle - 0
+middle - 1
+outer - 1
+middle - 0
+middle - 1
+outer - 2
+middle - 0
+middle - 1
+middle - 2 - after
+EOT
+,
+ 'Test inserting after on middle level block',
+ ),
+ array(
+ 'outer[1].middle',
array('VARIABLE' => 'pos #1'),
+ 1,
+ 'insert',
+ <<<EOT
+outer - 0
+middle - 0
+middle - 1
+outer - 1
+middle - 0
+middle - 1 - pos #1
+middle - 2
+outer - 2
+middle - 0
+middle - 1
+EOT
+,
+ 'Test inserting at 1 on middle level block',
+ ),
+ array(
+ 'outer[].middle',
+ array('VARIABLE' => 'changed'),
0,
'change',
<<<EOT
-outer - 0 - pos #1
+outer - 0
middle - 0
middle - 1
outer - 1
middle - 0
middle - 1
outer - 2
+middle - 0 - changed
+middle - 1
+EOT
+,
+ 'Test changing at beginning of last top level block',
+ ),
+ array(
+ 'outer.middle',
+ array('VARIABLE' => 'changed'),
+ array('S_ROW_NUM' => 1),
+ 'change',
+ <<<EOT
+outer - 0
+middle - 0
+middle - 1
+outer - 1
middle - 0
middle - 1
+outer - 2
+middle - 0
+middle - 1 - changed
EOT
,
- 'Test inserting at 1 on top level block',
+ 'Test changing at beginning of last top level block',
),
);
}
@@ -601,8 +718,55 @@ EOT
$expect = 'outer - 0[outer|4]outer - 1[outer|4]middle - 0[middle|1]outer - 2 - test[outer|4]middle - 0[middle|2]middle - 1[middle|2]outer - 3[outer|4]middle - 0[middle|3]middle - 1[middle|3]middle - 2[middle|3]';
$this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring S_NUM_ROWS is correct after modification');
+
+ $this->template->alter_block_array('outer.middle', array());
+
+ $expect = 'outer - 0[outer|4]outer - 1[outer|4]middle - 0[middle|1]outer - 2 - test[outer|4]middle - 0[middle|2]middle - 1[middle|2]outer - 3[outer|4]middle - 0[middle|4]middle - 1[middle|4]middle - 2[middle|4]middle - 3[middle|4]';
+ $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring S_NUM_ROWS is correct after insertion at middle level');
+
+ $this->template->alter_block_array('outer.middle', array('VARIABLE' => 'test'), 2, 'change');
+
+ $expect = 'outer - 0[outer|4]outer - 1[outer|4]middle - 0[middle|1]outer - 2 - test[outer|4]middle - 0[middle|2]middle - 1[middle|2]outer - 3[outer|4]middle - 0[middle|4]middle - 1[middle|4]middle - 2 - test[middle|4]middle - 3[middle|4]';
+ $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring S_NUM_ROWS is correct after modification at middle level');
}
+ public function test_find_key_index()
+ {
+ $this->template->set_filenames(array('test' => 'loop_nested.html'));
+
+ $this->template->assign_var('TEST_MORE', true);
+
+ // @todo Change this
+ $this->template->assign_block_vars('outer', array('VARIABLE' => 'zero'));
+ $this->template->assign_block_vars('outer', array('VARIABLE' => 'one'));
+ $this->template->assign_block_vars('outer.middle', array('VARIABLE' => '1A'));
+ $this->template->assign_block_vars('outer', array('VARIABLE' => 'two'));
+ $this->template->assign_block_vars('outer.middle', array('VARIABLE' => '2A'));
+ $this->template->assign_block_vars('outer.middle', array('VARIABLE' => '2B'));
+ $this->template->assign_block_vars('outer', array('VARIABLE' => 'three'));
+ $this->template->assign_block_vars('outer.middle', array('VARIABLE' => '3A'));
+ $this->template->assign_block_vars('outer.middle', array('VARIABLE' => '3B'));
+ $this->template->assign_block_vars('outer.middle', array('VARIABLE' => '3C'));
+
+ $expect = 'outer - 0 - zero[outer|4]outer - 1 - one[outer|4]middle - 0 - 1A[middle|1]outer - 2 - two[outer|4]middle - 0 - 2A[middle|2]middle - 1 - 2B[middle|2]outer - 3 - three[outer|4]middle - 0 - 3A[middle|3]middle - 1 - 3B[middle|3]middle - 2 - 3C[middle|3]';
+ $this->assertEquals($expect, str_replace(array("\n", "\r", "\t"), '', $this->display('test')), 'Ensuring template is built correctly before modification');
+
+ $this->template->find_key_index('outer', false);
+
+ $this->assertEquals(0, $this->template->find_key_index('outer', false), 'Find index at the beginning of outer loop');
+ $this->assertEquals(1, $this->template->find_key_index('outer', 1), 'Find index by index in outer loop');
+ $this->assertEquals(2, $this->template->find_key_index('outer', array('VARIABLE' => 'two')), 'Find index by key in outer loop');
+ $this->assertEquals(3, $this->template->find_key_index('outer', true), 'Find index at the end of outer loop');
+ $this->assertEquals(false, $this->template->find_key_index('outer', 7), 'Find index out of bounds of outer loop');
+
+ $this->assertEquals(false, $this->template->find_key_index('outer[0].middle', false), 'Find index at the beginning of middle loop, no middle block');
+ $this->assertEquals(false, $this->template->find_key_index('outer[1].middle', 1), 'Find index by index in inner loop, out of bounds');
+ $this->assertEquals(1, $this->template->find_key_index('outer[2].middle', array('VARIABLE' => '2B')), 'Find index by key in middle loop');
+ $this->assertEquals(2, $this->template->find_key_index('outer.middle', true), 'Find index at the end of middle loop');
+
+ $this->assertEquals(false, $this->template->find_key_index('outer.wrong', true), 'Wrong middle block name');
+ $this->assertEquals(false, $this->template->find_key_index('wrong.middle', false), 'Wrong outer block name');
+ }
public function assign_block_vars_array_data()
{
return array(
diff --git a/tests/version/version_test.php b/tests/version/version_test.php
index 528f1602d6..0ed0fcb589 100644
--- a/tests/version/version_test.php
+++ b/tests/version/version_test.php
@@ -332,4 +332,496 @@ class phpbb_version_helper_test extends phpbb_test_case
$this->assertSame($expected, $version_helper->get_latest_on_current_branch());
}
+
+ public function get_update_on_branch_data()
+ {
+ return array(
+ array(
+ '1.0.0',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1',
+ ),
+ '1.1' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.0.1',
+ ),
+ ),
+ array(
+ '1.0.1',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1',
+ ),
+ '1.1' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(),
+ ),
+ array(
+ '1.0.1-a1',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1-a2',
+ ),
+ '1.1' => array(
+ 'current' => '1.1.0',
+ ),
+ ),
+ array(
+ 'current' => '1.0.1-a2',
+ ),
+ ),
+ array(
+ '1.1.0',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1',
+ ),
+ '1.1' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ '1.1.1',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1',
+ ),
+ '1.1' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(),
+ ),
+ array(
+ '1.1.0-a1',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1',
+ ),
+ '1.1' => array(
+ 'current' => '1.1.0-a2',
+ ),
+ ),
+ array(
+ 'current' => '1.1.0-a2',
+ ),
+ ),
+ array(
+ '1.1.0',
+ array(),
+ array(),
+ ),
+ // Latest safe release is 1.0.1
+ array(
+ '1.0.0',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1',
+ 'security' => '1.0.1',
+ ),
+ '1.1' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.0.1',
+ 'security' => '1.0.1',
+ ),
+ ),
+ // Latest safe release is 1.0.0
+ array(
+ '1.0.0',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1',
+ 'security' => '1.0.0',
+ ),
+ '1.1' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.0.1',
+ 'security' => '1.0.0',
+ ),
+ ),
+ // Latest safe release is 1.1.0
+ array(
+ '1.0.0',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1',
+ 'security' => '1.1.0',
+ ),
+ '1.1' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ // Latest 1.0 release is EOL
+ array(
+ '1.0.0',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1',
+ 'eol' => true,
+ ),
+ '1.1' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ // All are EOL -- somewhat undefined behavior
+ array(
+ '1.0.0',
+ array(
+ '1.0' => array(
+ 'current' => '1.0.1',
+ 'eol' => true,
+ ),
+ '1.1' => array(
+ 'current' => '1.1.1',
+ 'eol' => true,
+ ),
+ ),
+ array(),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider get_update_on_branch_data
+ */
+ public function test_get_update_on_branch($current_version, $versions, $expected)
+ {
+ $version_helper = $this
+ ->getMockBuilder('\phpbb\version_helper')
+ ->setMethods(array(
+ 'get_versions_matching_stability',
+ ))
+ ->setConstructorArgs(array(
+ $this->cache,
+ new \phpbb\config\config(array(
+ 'version' => $current_version,
+ )),
+ new \phpbb\file_downloader(),
+ new \phpbb\user('\phpbb\datetime'),
+ ))
+ ->getMock()
+ ;
+
+ $version_helper->expects($this->any())
+ ->method('get_versions_matching_stability')
+ ->will($this->returnValue($versions));
+
+ $this->assertSame($expected, $version_helper->get_update_on_branch());
+ }
+
+ public function get_ext_update_on_branch_data()
+ {
+ return array(
+ // Single branch, check version for current branch
+ array(
+ '3.1.0',
+ '1.0.0',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ ),
+ array(
+ 'current' => '1.0.1',
+ ),
+ ),
+ array(
+ '3.1.0',
+ '1.0.1',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ ),
+ array(),
+ ),
+ array(
+ '3.2.0',
+ '1.0.0',
+ array(
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ '3.2.0',
+ '1.1.1',
+ array(
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(),
+ ),
+ // Single branch, check for newest version when branches don't match up
+ array(
+ '3.1.0',
+ '1.0.0',
+ array(
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ '3.1.0',
+ '1.1.1',
+ array(
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(),
+ ),
+ array(
+ '3.2.0',
+ '1.0.0',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ ),
+ array(
+ 'current' => '1.0.1',
+ ),
+ ),
+ array(
+ '3.2.0',
+ '1.0.1',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ ),
+ array(),
+ ),
+ array(
+ '3.3.0',
+ '1.0.0',
+ array(
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ '3.3.0',
+ '1.1.1',
+ array(
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(),
+ ),
+ // Multiple branches, check version for current branch
+ array(
+ '3.1.0',
+ '1.0.0',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.0.1',
+ ),
+ ),
+ array(
+ '3.1.0',
+ '1.0.1',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(),
+ ),
+ array(
+ '3.1.0',
+ '1.1.1',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(),
+ ),
+ array(
+ '3.2.0',
+ '1.0.0',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ '3.2.0',
+ '1.0.1',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ '3.2.0',
+ '1.1.1',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(),
+ ),
+ // Multiple branches, check for newest version when branches don't match up
+ array(
+ '3.3.0',
+ '1.0.0',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ '3.3.0',
+ '1.0.1',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ '3.3.0',
+ '1.1.0',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(
+ '3.3.0',
+ '1.1.1',
+ array(
+ '3.1' => array(
+ 'current' => '1.0.1',
+ ),
+ '3.2' => array(
+ 'current' => '1.1.1',
+ ),
+ ),
+ array(),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider get_ext_update_on_branch_data
+ */
+ public function test_get_ext_update_on_branch($phpbb_version, $ext_version, $versions, $expected)
+ {
+ $version_helper = $this
+ ->getMockBuilder('\phpbb\version_helper')
+ ->setMethods(array(
+ 'get_versions_matching_stability',
+ ))
+ ->setConstructorArgs(array(
+ $this->cache,
+ new \phpbb\config\config(array(
+ 'version' => $phpbb_version,
+ )),
+ new \phpbb\file_downloader(),
+ new \phpbb\user('\phpbb\datetime'),
+ ))
+ ->getMock()
+ ;
+
+ $version_helper->expects($this->any())
+ ->method('get_versions_matching_stability')
+ ->will($this->returnValue($versions));
+
+ $version_helper->set_current_version($ext_version);
+
+ $this->assertSame($expected, $version_helper->get_ext_update_on_branch());
+ }
}