diff options
-rwxr-xr-x | git-tools/setup_github_network.php | 292 | ||||
-rw-r--r-- | phpBB/adm/style/acp_main.html | 5 | ||||
-rw-r--r-- | phpBB/adm/style/acp_update.html | 5 | ||||
-rw-r--r-- | phpBB/adm/style/ajax.js | 5 | ||||
-rw-r--r-- | phpBB/includes/acp/acp_main.php | 18 | ||||
-rw-r--r-- | phpBB/includes/acp/acp_update.php | 11 | ||||
-rw-r--r-- | phpBB/language/en/acp/common.php | 2 | ||||
-rw-r--r-- | phpBB/language/en/install.php | 1 | ||||
-rw-r--r-- | phpBB/phpbb/extension/metadata_manager.php | 14 | ||||
-rw-r--r-- | phpBB/phpbb/version_helper.php | 43 | ||||
-rw-r--r-- | phpBB/styles/prosilver/template/search_results.html | 2 | ||||
-rw-r--r-- | tests/version/version_test.php | 200 |
12 files changed, 294 insertions, 304 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_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_update.html b/phpBB/adm/style/acp_update.html index 351a3ba26c..5288833d05 100644 --- a/phpBB/adm/style/acp_update.html +++ b/phpBB/adm/style/acp_update.html @@ -20,6 +20,11 @@ <p>{L_VERSION_NOT_UP_TO_DATE_ACP} - <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a></p> </div> <!-- ENDIF --> +<!-- IF S_VERSION_UPGRADEABLE --> + <div class="errorbox notice"> + <p>{UPGRADE_INSTRUCTIONS}</p> + </div> +<!-- ENDIF --> <fieldset> <legend></legend> diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index a7ecf8ff7b..77fd28fbe6 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -173,10 +173,11 @@ function submitPermissions() { $.ajax({ url: $form.action, type: 'POST', - data: formData + '&' + $submitAllButton.name + '=' + encodeURIComponent($submitAllButton.value) + + data: formData + '&' + $submitButton.name + '=' + encodeURIComponent($submitButton.value) + '&creation_time=' + $form.find('input[type=hidden][name=creation_time]')[0].value + '&form_token=' + $form.find('input[type=hidden][name=form_token]')[0].value + - '&' + $form.children('input[type=hidden]').serialize(), + '&' + $form.children('input[type=hidden]').serialize() + + '&' + $form.find('input[type=checkbox][name^=inherit]').serialize(), success: handlePermissionReturn, error: handlePermissionReturn }); diff --git a/phpBB/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_update.php b/phpBB/includes/acp/acp_update.php index 529f0f2185..51ff4870f2 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) { @@ -51,7 +56,7 @@ class acp_update $template->assign_block_vars('updates_available', $version_data); } - $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 +66,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/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/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/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index 35a88d6991..107907609b 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -230,9 +230,19 @@ class metadata_manager case 'all': $this->validate('display'); - if (!$this->validate_enable()) + if (!$this->validate_dir()) { - throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', $name)); + throw new \phpbb\extension\exception($this->user->lang('EXTENSION_DIR_INVALID')); + } + + if (!$this->validate_require_phpbb()) + { + throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'soft-require')); + } + + if (!$this->validate_require_php()) + { + throw new \phpbb\extension\exception($this->user->lang('META_FIELD_NOT_SET', 'require php')); } break; diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index a1e66ba8fe..135d390584 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -201,6 +201,49 @@ 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 to 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; + } + + /** * Obtains the latest version information * * @param bool $force_update Ignores cached data. Defaults to false. 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/tests/version/version_test.php b/tests/version/version_test.php index 528f1602d6..54237f2059 100644 --- a/tests/version/version_test.php +++ b/tests/version/version_test.php @@ -332,4 +332,204 @@ 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()); + } } |