diff options
99 files changed, 2007 insertions, 616 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> · <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_profile.html b/phpBB/adm/style/acp_profile.html index 07718846cc..cebd2e9632 100644 --- a/phpBB/adm/style/acp_profile.html +++ b/phpBB/adm/style/acp_profile.html @@ -127,6 +127,7 @@ <!-- ENDIF --> </dl> <!-- ENDIF --> + <!-- EVENT acp_profile_step_one_lang_after --> </fieldset> <fieldset class="quick"> 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 7ddd2d3742..77fd28fbe6 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -173,9 +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_token=' + $form.find('input[type=hidden][name=form_token]')[0].value + + '&' + $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/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 0ebaf8f3e0..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 @@ -369,6 +387,13 @@ acp_profile_contact_before * Since: 3.1.6-RC1 * Purpose: Add extra options to custom profile field configuration in the ACP +acp_profile_step_one_lang_after +=== +* Locations: + + adm/style/acp_profile.html +* Since: 3.1.11-RC1 +* Purpose: Add extra lang specific options to custom profile field step one configuration in the ACP + acp_prune_forums_append === * Locations: @@ -814,6 +839,14 @@ mcp_forum_actions_after * Since: 3.1.11-RC1 * Purpose: Add some information after actions fieldset +mcp_forum_actions_append +=== +* Locations: + + styles/prosilver/template/mcp_forum.html + + styles/subsilver2/template/mcp_forum.html +* Since: 3.1.11-RC1 +* Purpose: Add additional options to actions select + mcp_forum_actions_before === * Locations: @@ -1042,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: @@ -2009,6 +2058,14 @@ ucp_main_front_user_activity_after * Since: 3.1.6-RC1 * Purpose: Add content right after the user activity info viewing UCP front page +ucp_main_front_user_activity_append +=== +* Locations: + + styles/prosilver/template/ucp_main_front.html + + styles/subsilver2/template/ucp_main_front.html +* Since: 3.1.11-RC1 +* Purpose: Add content after last user activity info viewing UCP front page + ucp_main_front_user_activity_before === * Locations: @@ -2017,6 +2074,14 @@ ucp_main_front_user_activity_before * Since: 3.1.6-RC1 * Purpose: Add content right before the user activity info viewing UCP front page +ucp_main_front_user_activity_prepend +=== +* Locations: + + styles/prosilver/template/ucp_main_front.html + + styles/subsilver2/template/ucp_main_front.html +* Since: 3.1.11-RC1 +* Purpose: Add content before first user activity info viewing UCP front page + ucp_pm_history_post_buttons_after === * Locations: @@ -2113,6 +2178,13 @@ ucp_pm_viewmessage_custom_fields_before * Purpose: Add data before the custom fields on the user profile when viewing a private message +ucp_pm_viewmessage_options_before +=== +* Locations: + + styles/prosilver/template/ucp_pm_viewmessage.html +* Since: 3.1.11-RC1 +* Purpose: Add content right before display options + ucp_pm_viewmessage_post_buttons_after === * Locations: @@ -2271,6 +2343,14 @@ ucp_profile_register_details_after * Since: 3.1.4-RC1 * Purpose: Add options in profile page fieldset - after confirm password field. +ucp_register_buttons_before +=== +* Locations: + + styles/prosilver/template/ucp_register.html + + styles/subsilver2/template/ucp_register.html +* Since: 3.1.11-RC1 +* Purpose: Add content before buttons in registration form. + ucp_register_credentials_before === * 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..bcecb2f300 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) { @@ -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 . '&action=list&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 . '&action=enable&ext_name=' . urlencode($ext_name) . '&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 . '&action=enable&ext_name=' . urlencode($ext_name) . '&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 . '&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 . '&action=disable&ext_name=' . urlencode($ext_name) . '&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 . '&action=disable&ext_name=' . urlencode($ext_name) . '&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 . '&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 . '&action=delete_data&ext_name=' . urlencode($ext_name) . '&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 . '&action=delete_data&ext_name=' . urlencode($ext_name) . '&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 . '&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 . '&action=list', 'U_VERSIONCHECK_FORCE' => $this->u_action . '&action=details&versioncheck_force=1&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&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 4881dde6f5..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))); @@ -1554,6 +1554,23 @@ function phpbb_get_user_rank($user_data, $user_posts) } } + /** + * Modify a user's rank before displaying + * + * @event core.get_user_rank_after + * @var array user_data Array with user's data + * @var int user_posts User_posts to change + * @var array user_rank_data User rank data + * @since 3.1.11-RC1 + */ + + $vars = array( + 'user_data', + 'user_posts', + 'user_rank_data', + ); + extract($phpbb_dispatcher->trigger_event('core.get_user_rank_after', compact($vars))); + return $user_rank_data; } 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&i=main&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 b2441aed1b..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))); @@ -463,7 +463,7 @@ function change_topic_type($action, $topic_ids) */ function mcp_move_topic($topic_ids) { - global $auth, $user, $db, $template, $phpbb_log, $request; + global $auth, $user, $db, $template, $phpbb_log, $request, $phpbb_dispatcher; global $phpEx, $phpbb_root_path; // Here we limit the operation to one forum only @@ -625,6 +625,18 @@ function mcp_move_topic($topic_ids) 'poll_last_vote' => (int) $row['poll_last_vote'] ); + /** + * Perform actions before shadow topic is created. + * + * @event core.mcp_main_modify_shadow_sql + * @var array shadow SQL array to be used by $db->sql_build_array + * @since 3.1.11-RC1 + */ + $vars = array( + 'shadow', + ); + extract($phpbb_dispatcher->trigger_event('core.mcp_main_modify_shadow_sql', compact($vars))); + $db->sql_query('INSERT INTO ' . TOPICS_TABLE . $db->sql_build_array('INSERT', $shadow)); // Shadow topics only count on new "topics" and not posts... a shadow topic alone has 0 posts @@ -1281,6 +1293,18 @@ function mcp_fork_topic($topic_ids) 'poll_vote_change' => (int) $topic_row['poll_vote_change'], ); + /** + * Perform actions before forked topic is created. + * + * @event core.mcp_main_modify_fork_sql + * @var array sql_ary SQL array to be used by $db->sql_build_array + * @since 3.1.11-RC1 + */ + $vars = array( + 'sql_ary', + ); + extract($phpbb_dispatcher->trigger_event('core.mcp_main_modify_fork_sql', compact($vars))); + $db->sql_query('INSERT INTO ' . TOPICS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $new_topic_id = $db->sql_nextid(); $new_topic_id_list[$topic_id] = $new_topic_id; 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 19acd9ecb9..3364206680 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -397,7 +397,7 @@ function view_folder($id, $mode, $folder_id, $folder) */ function get_pm_from($folder_id, $folder, $user_id) { - global $user, $db, $template, $config, $auth, $phpbb_container, $phpbb_root_path, $phpEx; + global $user, $db, $template, $config, $auth, $phpbb_container, $phpbb_root_path, $phpEx, $phpbb_dispatcher; $start = request_var('start', 0); @@ -461,7 +461,7 @@ function get_pm_from($folder_id, $folder, $user_id) $start = $pagination->validate_start($start, $config['topics_per_page'], $pm_count); $pagination->generate_template_pagination($base_url, 'pagination', 'start', $pm_count, $config['topics_per_page'], $start); - $template->assign_vars(array( + $template_vars = array( 'TOTAL_MESSAGES' => $user->lang('VIEW_PM_MESSAGES', (int) $pm_count), 'POST_IMG' => (!$auth->acl_get('u_sendpm')) ? $user->img('button_topic_locked', 'POST_PM_LOCKED') : $user->img('button_pm_new', 'POST_NEW_PM'), @@ -475,7 +475,33 @@ function get_pm_from($folder_id, $folder, $user_id) 'U_POST_NEW_TOPIC' => ($auth->acl_get('u_sendpm')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose') : '', 'S_PM_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=view&action=view_folder&f=$folder_id" . (($start !== 0) ? "&start=$start" : '')), - )); + ); + + /** + * Modify template variables before they are assigned + * + * @event core.ucp_pm_view_folder_get_pm_from_template + * @var int folder_id Folder ID + * @var array folder Folder data + * @var int user_id User ID + * @var string base_url Pagination base URL + * @var int start Pagination start + * @var int pm_count Count of PMs + * @var array template_vars Template variables to be assigned + * @since 3.1.11-RC1 + */ + $vars = array( + 'folder_id', + 'folder', + 'user_id', + 'base_url', + 'start', + 'pm_count', + 'template_vars', + ); + extract($phpbb_dispatcher->trigger_event('core.ucp_pm_view_folder_get_pm_from_template', compact($vars))); + + $template->assign_vars($template_vars); // Grab all pm data $rowset = $pm_list = array(); @@ -509,15 +535,38 @@ function get_pm_from($folder_id, $folder, $user_id) $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . $direction; } - $sql = 'SELECT t.*, p.root_level, p.message_time, p.message_subject, p.icon_id, p.to_address, p.message_attachment, p.bcc_address, u.username, u.username_clean, u.user_colour, p.message_reported - FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p, ' . USERS_TABLE . " u - WHERE t.user_id = $user_id + $sql_ary = array( + 'SELECT' => 't.*, p.root_level, p.message_time, p.message_subject, p.icon_id, p.to_address, p.message_attachment, p.bcc_address, u.username, u.username_clean, u.user_colour, p.message_reported', + 'FROM' => array( + PRIVMSGS_TO_TABLE => 't', + PRIVMSGS_TABLE => 'p', + USERS_TABLE => 'u', + ), + 'WHERE' => "t.user_id = $user_id AND p.author_id = u.user_id AND $folder_sql AND t.msg_id = p.msg_id - $sql_limit_time - ORDER BY $sql_sort_order"; - $result = $db->sql_query_limit($sql, $sql_limit, $sql_start); + $sql_limit_time", + 'ORDER_BY' => $sql_sort_order, + ); + + /** + * Modify SQL before it is executed + * + * @event core.ucp_pm_view_folder_get_pm_from_sql + * @var array sql_ary SQL array + * @var int sql_limit SQL limit + * @var int sql_start SQL start + * @since 3.1.11-RC1 + */ + $vars = array( + 'sql_ary', + 'sql_limit', + 'sql_start', + ); + extract($phpbb_dispatcher->trigger_event('core.ucp_pm_view_folder_get_pm_from_sql', compact($vars))); + + $result = $db->sql_query_limit($db->sql_build_query('SELECT', $sql_ary), $sql_limit, $sql_start); $pm_reported = array(); while ($row = $db->sql_fetchrow($result)) diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 0be1930f1a..4a3d8133b3 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -633,10 +633,19 @@ class ucp_profile 'user_avatar_height' => $result['avatar_height'], ); + /** + * Trigger events on successfull avatar change + * + * @event core.ucp_profile_avatar_sql + * @var array result Array with data to be stored in DB + * @since 3.1.11-RC1 + */ + $vars = array('result'); + extract($phpbb_dispatcher->trigger_event('core.ucp_profile_avatar_sql', compact($vars))); + $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $result) . ' WHERE user_id = ' . (int) $user->data['user_id']; - $db->sql_query($sql); meta_refresh(3, $this->u_action); diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 3426af95d0..52ed410b04 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -45,6 +45,28 @@ class ucp_register $change_lang = request_var('change_lang', ''); $user_lang = request_var('lang', $user->lang_name); + /** + * Add UCP register data before they are assigned to the template or submitted + * + * To assign data to the template, use $template->assign_vars() + * + * @event core.ucp_register_requests_after + * @var bool coppa Is set coppa + * @var bool agreed Did user agree to coppa? + * @var bool submit Is set post submit? + * @var string change_lang Change language request + * @var string user_lang User language request + * @since 3.1.11-RC1 + */ + $vars = array( + 'coppa', + 'agreed', + 'submit', + 'change_lang', + 'user_lang', + ); + extract($phpbb_dispatcher->trigger_event('core.ucp_register_requests_after', compact($vars))); + if ($agreed) { add_form_key('ucp_register'); diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index 415bf0e84d..29d4199528 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -30,7 +30,7 @@ class ucp_remind function main($id, $mode) { global $config, $phpbb_root_path, $phpEx; - global $db, $user, $auth, $template, $phpbb_container; + global $db, $user, $auth, $template, $phpbb_container, $phpbb_dispatcher; if (!$config['allow_password_reset']) { @@ -43,10 +43,30 @@ class ucp_remind if ($submit) { - $sql = 'SELECT user_id, username, user_permissions, user_email, user_jabber, user_notify_type, user_type, user_lang, user_inactive_reason - FROM ' . USERS_TABLE . " - WHERE user_email_hash = '" . $db->sql_escape(phpbb_email_hash($email)) . "' - AND username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'"; + $sql_array = array( + 'SELECT' => 'user_id, username, user_permissions, user_email, user_jabber, user_notify_type, user_type, user_lang, user_inactive_reason', + 'FROM' => array(USERS_TABLE => 'u'), + 'WHERE' => "user_email_hash = '" . $db->sql_escape(phpbb_email_hash($email)) . "' + AND username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'" + ); + + /** + * Change SQL query for fetching user data + * + * @event core.ucp_remind_modify_select_sql + * @var string email User's email from the form + * @var string username User's username from the form + * @var array sql_array Fully assembled SQL query with keys SELECT, FROM, WHERE + * @since 3.1.11-RC1 + */ + $vars = array( + 'email', + 'username', + 'sql_array', + ); + extract($phpbb_dispatcher->trigger_event('core.ucp_remind_modify_select_sql', compact($vars))); + + $sql = $db->sql_build_query('SELECT', $sql_array); $result = $db->sql_query($sql); $user_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); 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..8b5e113b16 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -558,6 +558,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 +576,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/data/v31x/increase_size_of_emotion.php b/phpBB/phpbb/db/migration/data/v31x/increase_size_of_emotion.php new file mode 100644 index 0000000000..7e486aca7c --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/increase_size_of_emotion.php @@ -0,0 +1,46 @@ +<?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 increase_size_of_emotion extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v3110', + ); + } + + public function update_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'smilies' => array( + 'emotion' => array('VCHAR_UNI', ''), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'smilies' => array( + 'emotion' => array('VCHAR_UNI:50', ''), + ), + ), + ); + } +} 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 759f15ee5c..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 @@ -107,28 +109,18 @@ class metadata_manager { case 'all': default: - // Validate the metadata - if (!$this->validate()) - { - return false; - } - + $this->validate(); return $this->metadata; break; + case 'version': case 'name': - return ($this->validate('name')) ? $this->metadata['name'] : 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; } } @@ -197,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) @@ -257,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; @@ -299,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; @@ -328,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/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php index cc32984ac6..fc39623c5c 100644 --- a/phpBB/phpbb/notification/type/report_pm.php +++ b/phpBB/phpbb/notification/type/report_pm.php @@ -141,6 +141,8 @@ class report_pm extends \phpbb\notification\type\pm */ public function get_email_template_variables() { + $user_data = $this->user_loader->get_user($this->get_data('reporter_id')); + return array( 'AUTHOR_NAME' => htmlspecialchars_decode($user_data['username']), 'SUBJECT' => htmlspecialchars_decode(censor_text($this->get_data('message_subject'))), diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index 7f6267ed32..04d681cea6 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -266,7 +266,7 @@ class plupload if ($this->config['img_max_height'] > 0 && $this->config['img_max_width'] > 0) { $resize = sprintf( - 'resize: {width: %d, height: %d, quality: 100},', + 'resize: {width: %d, height: %d, quality: 85},', (int) $this->config['img_max_width'], (int) $this->config['img_max_height'] ); diff --git a/phpBB/phpbb/profilefields/type/type_interface.php b/phpBB/phpbb/profilefields/type/type_interface.php index ec770f9467..93b9e4b893 100644 --- a/phpBB/phpbb/profilefields/type/type_interface.php +++ b/phpBB/phpbb/profilefields/type/type_interface.php @@ -134,6 +134,14 @@ interface type_interface public function get_field_ident($field_data); /** + * Get the localized name of the field + * + * @param string $field_name Unlocalized name of this field + * @return string Localized name of the field + */ + public function get_field_name($field_name); + + /** * Get the column type for the database * * @return string Returns the database column type 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/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 311da92a95..ec9b53328f 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -132,9 +132,10 @@ phpbb.markNotifications = function($popup, unreadCount) { // Update the unread count. $('strong', '#notification_list_button').html(unreadCount); - // Remove the Mark all read link & notification count if there are no unread notifications. + // Remove the Mark all read link and hide notification count if there are no unread notifications. if (!unreadCount) { - $('#mark_all_notifications, #notification_list_button > strong').remove(); + $('#mark_all_notifications').remove(); + $('#notification_list_button > strong').addClass('hidden'); } // Update page title 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_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html index 5858a2c801..4c037f56ae 100644 --- a/phpBB/styles/prosilver/template/mcp_forum.html +++ b/phpBB/styles/prosilver/template/mcp_forum.html @@ -138,6 +138,7 @@ <option value="make_announce">{L_MAKE_ANNOUNCE}</option> <option value="make_global">{L_MAKE_GLOBAL}</option> <!-- ENDIF --> + <!-- EVENT mcp_forum_actions_append --> </select> <input class="button2" type="submit" value="{L_SUBMIT}" /> <div><a href="#" onclick="marklist('mcp', 'topic_id_list', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'topic_id_list', false); return false;">{L_UNMARK_ALL}</a></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/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html index e5f354a943..bdfb5fb87d 100644 --- a/phpBB/styles/prosilver/template/navbar_header.html +++ b/phpBB/styles/prosilver/template/navbar_header.html @@ -72,12 +72,12 @@ </li> <!-- IF S_DISPLAY_PM --> <li class="small-icon icon-pm rightside" data-skip-responsive="true"> - <a href="{U_PRIVATEMSGS}" role="menuitem"><span>{L_PRIVATE_MESSAGES} </span><!-- IF PRIVATE_MESSAGE_COUNT --><strong class="badge">{PRIVATE_MESSAGE_COUNT}</strong><!-- ENDIF --></a> + <a href="{U_PRIVATEMSGS}" role="menuitem"><span>{L_PRIVATE_MESSAGES} </span><strong class="badge<!-- IF not PRIVATE_MESSAGE_COUNT --> hidden<!-- ENDIF -->">{PRIVATE_MESSAGE_COUNT}</strong></a> </li> <!-- ENDIF --> <!-- IF S_NOTIFICATIONS_DISPLAY --> <li class="small-icon icon-notification dropdown-container dropdown-{S_CONTENT_FLOW_END} rightside" data-skip-responsive="true"> - <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button" class="dropdown-trigger"><span>{L_NOTIFICATIONS} </span><!-- IF NOTIFICATIONS_COUNT --><strong class="badge">{NOTIFICATIONS_COUNT}</strong><!-- ENDIF --></a> + <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button" class="dropdown-trigger"><span>{L_NOTIFICATIONS} </span><strong class="badge<!-- IF not NOTIFICATIONS_COUNT --> hidden<!-- ENDIF -->">{NOTIFICATIONS_COUNT}</strong></a> <!-- INCLUDE notification_dropdown.html --> </li> <!-- ENDIF --> 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} » {searchresults.FIRST_POST_TIME} » {L_IN} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a> <!-- EVENT topiclist_row_append --> diff --git a/phpBB/styles/prosilver/template/ucp_main_front.html b/phpBB/styles/prosilver/template/ucp_main_front.html index 7bc8d40078..056ea300d8 100644 --- a/phpBB/styles/prosilver/template/ucp_main_front.html +++ b/phpBB/styles/prosilver/template/ucp_main_front.html @@ -55,12 +55,14 @@ <!-- EVENT ucp_main_front_user_activity_before --> <dl class="details"> + <!-- EVENT ucp_main_front_user_activity_prepend --> <dt>{L_JOINED}{L_COLON}</dt> <dd>{JOINED}</dd> <dt>{L_LAST_ACTIVE}{L_COLON}</dt> <dd>{LAST_VISIT_YOU}</dd> <dt>{L_TOTAL_POSTS}{L_COLON}</dt> <dd><!-- IF POSTS_PCT -->{POSTS}<!-- IF S_DISPLAY_SEARCH --> | <strong><a href="{U_SEARCH_USER}">{L_SEARCH_YOUR_POSTS}</a></strong><!-- ENDIF --><br />({POSTS_DAY} / {POSTS_PCT})<!-- ELSE -->{POSTS}<!-- ENDIF --></dd> <!-- IF ACTIVE_FORUM != '' --><dt>{L_ACTIVE_IN_FORUM}{L_COLON}</dt> <dd><strong><a href="{U_ACTIVE_FORUM}">{ACTIVE_FORUM}</a></strong><br />({ACTIVE_FORUM_POSTS} / {ACTIVE_FORUM_PCT})</dd><!-- ENDIF --> <!-- IF ACTIVE_TOPIC != '' --><dt>{L_ACTIVE_IN_TOPIC}{L_COLON}</dt> <dd><strong><a href="{U_ACTIVE_TOPIC}">{ACTIVE_TOPIC}</a></strong><br />({ACTIVE_TOPIC_POSTS} / {ACTIVE_TOPIC_PCT})</dd><!-- ENDIF --> <!-- IF WARNINGS --><dt>{L_YOUR_WARNINGS}{L_COLON}</dt> <dd class="error">{WARNING_IMG} [{WARNINGS}]</dd><!-- ENDIF --> + <!-- EVENT ucp_main_front_user_activity_append --> </dl> <!-- EVENT ucp_main_front_user_activity_after --> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index d92b90a045..009a9bf975 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -146,6 +146,7 @@ </div> </div> +<!-- EVENT ucp_pm_viewmessage_options_before --> <!-- IF S_VIEW_MESSAGE --> <fieldset class="display-options"> <!-- IF U_PREVIOUS_PM --><a href="{U_PREVIOUS_PM}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}">{L_VIEW_PREVIOUS_PM}</a><!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html index 655c0fc48c..38413addba 100644 --- a/phpBB/styles/prosilver/template/ucp_register.html +++ b/phpBB/styles/prosilver/template/ucp_register.html @@ -79,8 +79,6 @@ <!-- ENDIF --> <!-- IF S_COPPA --> - - <div class="panel"> <div class="inner"> @@ -91,6 +89,8 @@ </div> <!-- ENDIF --> +<!-- EVENT ucp_register_buttons_before --> + <div class="panel"> <div class="inner"> diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index cf6d14e6ab..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; } @@ -1269,6 +1277,10 @@ ul.linklist:after, padding: 4px 6px; } +.badge.hidden { + display: none; +} + /* Navbar specific list items ----------------------------------------*/ diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index 92a7db81d9..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 { @@ -515,7 +517,7 @@ blockquote .codebox { max-height: 200px; white-space: normal; padding-top: 5px; - font: 0.9em Monaco, "Andale Mono","Courier New", Courier, mono; + font: 0.9em Monaco, "Andale Mono","Courier New", Courier, monospace; line-height: 1.3em; margin: 2px 0; } diff --git a/phpBB/styles/subsilver2/template/mcp_forum.html b/phpBB/styles/subsilver2/template/mcp_forum.html index d905910c22..12447b2b1e 100644 --- a/phpBB/styles/subsilver2/template/mcp_forum.html +++ b/phpBB/styles/subsilver2/template/mcp_forum.html @@ -77,6 +77,7 @@ <option value="make_announce">{L_MAKE_ANNOUNCE}</option> <option value="make_global">{L_MAKE_GLOBAL}</option> <!-- ENDIF --> + <!-- EVENT mcp_forum_actions_append --> </select> <input class="btnmain" type="submit" value="{L_SUBMIT}" /> </td> 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"> <!-- 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/styles/subsilver2/template/ucp_main_front.html b/phpBB/styles/subsilver2/template/ucp_main_front.html index 7fc906a126..485a58b7ab 100644 --- a/phpBB/styles/subsilver2/template/ucp_main_front.html +++ b/phpBB/styles/subsilver2/template/ucp_main_front.html @@ -38,6 +38,7 @@ <!-- EVENT ucp_main_front_user_activity_before --> <td class="row1" colspan="3"> <table width="100%" cellspacing="1" cellpadding="4"> + <!-- EVENT ucp_main_front_user_activity_prepend --> <tr> <td align="{S_CONTENT_FLOW_END}" valign="top" nowrap="nowrap"><b class="genmed">{L_JOINED}{L_COLON} </b></td> <td width="100%"><b class="gen">{JOINED}</b></td> @@ -62,6 +63,7 @@ <td class="genmed">{WARNING_IMG} [ <b>{WARNINGS}</b> ]</td> </tr> <!-- ENDIF --> + <!-- EVENT ucp_main_front_user_activity_append --> </table> </td> <!-- EVENT ucp_main_front_user_activity_after --> diff --git a/phpBB/styles/subsilver2/template/ucp_register.html b/phpBB/styles/subsilver2/template/ucp_register.html index 9b9e164df4..db26f51ebd 100644 --- a/phpBB/styles/subsilver2/template/ucp_register.html +++ b/phpBB/styles/subsilver2/template/ucp_register.html @@ -91,6 +91,8 @@ </tr> <!-- ENDIF --> +<!-- EVENT ucp_register_buttons_before --> + <tr> <td class="cat" colspan="2" align="center">{S_HIDDEN_FIELDS}<input class="btnmain" type="submit" name="submit" id="submit" value="{L_SUBMIT}" /> <input class="btnlite" type="reset" value="{L_RESET}" name="reset" /></td> </tr> 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 5c98a9c931..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&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', @@ -1316,7 +1316,6 @@ while ($row = $db->sql_fetchrow($result)) 'rank_title' => '', 'rank_image' => '', 'rank_image_src' => '', - 'sig' => '', 'pm' => '', 'email' => '', 'jabber' => '', @@ -2008,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', @@ -2108,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', @@ -2271,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/functional/notification_test.php b/tests/functional/notification_test.php index d4c61cc062..f21d73817a 100644 --- a/tests/functional/notification_test.php +++ b/tests/functional/notification_test.php @@ -82,6 +82,7 @@ class phpbb_functional_notification_test extends phpbb_functional_test_case // Get form token $link = $crawler->selectLink($this->lang('NOTIFICATIONS_MARK_ALL_READ'))->link()->getUri(); $crawler = self::request('GET', substr($link, strpos($link, 'ucp.'))); - $this->assertCount(0, $crawler->filter('#notification_list_button strong')); + $this->assertCount(1, $crawler->filter('#notification_list_button strong.badge.hidden')); + $this->assertEquals("0", $crawler->filter('#notification_list_button strong.badge.hidden')->text()); } } 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/plupload/plupload_test.php b/tests/plupload/plupload_test.php index 2f47bf2b39..c3fa2b9bad 100644 --- a/tests/plupload/plupload_test.php +++ b/tests/plupload/plupload_test.php @@ -24,7 +24,7 @@ class phpbb_plupload_test extends phpbb_test_case array( 130, 150, - 'resize: {width: 130, height: 150, quality: 100},' + 'resize: {width: 130, height: 150, quality: 85},' ), ); } 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()); + } } |