aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB')
-rw-r--r--phpBB/.htaccess7
-rw-r--r--phpBB/adm/style/acp_forums.html5
-rw-r--r--phpBB/assets/javascript/core.js109
-rw-r--r--phpBB/composer.lock513
-rw-r--r--phpBB/config/default/container/services_auth.yml22
-rw-r--r--phpBB/config/default/container/services_console.yml8
-rw-r--r--phpBB/develop/calc_email_hash.php74
-rw-r--r--phpBB/develop/update_email_hash.php56
-rw-r--r--phpBB/docs/CHANGELOG.html25
-rw-r--r--phpBB/docs/INSTALL.html2
-rw-r--r--phpBB/docs/coding-guidelines.html6
-rw-r--r--phpBB/docs/nginx.sample.conf4
-rw-r--r--phpBB/includes/acp/acp_board.php1
-rw-r--r--phpBB/includes/acp/acp_forums.php3
-rw-r--r--phpBB/includes/acp/acp_users.php5
-rw-r--r--phpBB/includes/constants.php2
-rw-r--r--phpBB/includes/functions.php15
-rw-r--r--phpBB/includes/functions_compatibility.php14
-rw-r--r--phpBB/includes/functions_convert.php10
-rw-r--r--phpBB/includes/functions_display.php4
-rw-r--r--phpBB/includes/functions_messenger.php25
-rw-r--r--phpBB/includes/functions_user.php5
-rw-r--r--phpBB/includes/ucp/ucp_pm_compose.php5
-rw-r--r--phpBB/includes/ucp/ucp_profile.php1
-rw-r--r--phpBB/includes/ucp/ucp_register.php29
-rw-r--r--phpBB/includes/ucp/ucp_resend.php2
-rw-r--r--phpBB/install/convertors/convert_phpbb20.php3
-rwxr-xr-xphpBB/install/phpbbcli.php2
-rw-r--r--phpBB/install/schemas/schema_data.sql2
-rw-r--r--phpBB/language/en/acp/board.php2
-rw-r--r--phpBB/language/en/acp/forums.php2
-rw-r--r--phpBB/language/en/cli.php3
-rw-r--r--phpBB/language/en/common.php2
-rw-r--r--phpBB/phpbb/auth/provider/apache.php75
-rw-r--r--phpBB/phpbb/auth/provider/base.php2
-rw-r--r--phpBB/phpbb/auth/provider/db.php61
-rw-r--r--phpBB/phpbb/auth/provider/ldap.php53
-rw-r--r--phpBB/phpbb/auth/provider/oauth/oauth.php966
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/base.php62
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/bitly.php107
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/facebook.php99
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/google.php107
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/service_interface.php114
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/twitter.php113
-rw-r--r--phpBB/phpbb/auth/provider/oauth/token_storage.php346
-rw-r--r--phpBB/phpbb/auth/provider/provider_interface.php4
-rw-r--r--phpBB/phpbb/cache/driver/memcache.php122
-rw-r--r--phpBB/phpbb/cache/driver/memcached.php22
-rw-r--r--phpBB/phpbb/captcha/non_gd.php6
-rw-r--r--phpBB/phpbb/console/command/fixup/recalculate_email_hash.php76
-rw-r--r--phpBB/phpbb/content_visibility.php20
-rw-r--r--phpBB/phpbb/db/migration/data/v330/add_display_unapproved_posts_config.php (renamed from phpBB/phpbb/db/tools.php)13
-rw-r--r--phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php49
-rw-r--r--phpBB/phpbb/db/migration/data/v330/remove_email_hash.php57
-rw-r--r--phpBB/phpbb/db/migration/data/v330/v330b2.php38
-rw-r--r--phpBB/phpbb/di/service_collection.php19
-rw-r--r--phpBB/phpbb/install/module/install_database/task/add_config_settings.php1
-rw-r--r--phpBB/phpbb/textformatter/s9e/bbcode_merger.php26
-rw-r--r--phpBB/phpbb/textformatter/s9e/factory.php2
-rw-r--r--phpBB/phpbb/textformatter/s9e/link_helper.php2
-rw-r--r--phpBB/phpbb/textformatter/s9e/parser.php20
-rw-r--r--phpBB/phpbb/textformatter/s9e/quote_helper.php22
-rw-r--r--phpBB/phpbb/ucp/controller/reset_password.php2
-rw-r--r--phpBB/posting.php12
-rw-r--r--phpBB/search.php3
-rw-r--r--phpBB/styles/prosilver/style.cfg4
-rw-r--r--phpBB/styles/prosilver/template/bbcode.html4
-rw-r--r--phpBB/styles/prosilver/template/memberlist_search.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_agreement.html3
-rw-r--r--phpBB/styles/prosilver/template/viewtopic_body.html7
-rw-r--r--phpBB/styles/prosilver/theme/colours.css5
-rw-r--r--phpBB/styles/prosilver/theme/forms.css2
-rw-r--r--phpBB/viewforum.php5
-rw-r--r--phpBB/viewtopic.php1
74 files changed, 2004 insertions, 1618 deletions
diff --git a/phpBB/.htaccess b/phpBB/.htaccess
index 53bce762ea..0be28ab670 100644
--- a/phpBB/.htaccess
+++ b/phpBB/.htaccess
@@ -36,6 +36,13 @@ RewriteRule ^(.*)$ app.php [QSA,L]
#Options +FollowSymLinks
</IfModule>
+# Apache content negotation tries to interpret non-existent paths as files if
+# MultiViews is enabled. This will however cause issues with paths containg
+# dots, e.g. for the cron tasks
+<IfModule mod_negotiation.c>
+ Options -MultiViews
+</IfModule>
+
# With Apache 2.4 the "Order, Deny" syntax has been deprecated and moved from
# module mod_authz_host to a new module called mod_access_compat (which may be
# disabled) and a new "Require" syntax has been introduced to mod_authz_host.
diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html
index 20bcd2e9f9..f51ce98776 100644
--- a/phpBB/adm/style/acp_forums.html
+++ b/phpBB/adm/style/acp_forums.html
@@ -211,6 +211,11 @@
<label><input type="radio" class="radio" name="display_subforum_list" value="0"<!-- IF not S_DISPLAY_SUBFORUM_LIST --> id="display_subforum_list" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
</dl>
<dl>
+ <dt><label for="display_subforum_limit">{L_LIMIT_SUBFORUMS}{L_COLON}</label><br /><span>{L_LIMIT_SUBFORUMS_EXPLAIN}</span></dt>
+ <dd><label><input type="radio" class="radio" name="display_subforum_limit" value="1"<!-- IF S_DISPLAY_SUBFORUM_LIMIT --> id="display_subforum_limit" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
+ <label><input type="radio" class="radio" name="display_subforum_limit" value="0"<!-- IF not S_DISPLAY_SUBFORUM_LIMIT --> id="display_subforum_limit" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
+ </dl>
+ <dl>
<dt><label for="display_on_index">{L_LIST_INDEX}{L_COLON}</label><br /><span>{L_LIST_INDEX_EXPLAIN}</span></dt>
<dd><label><input type="radio" class="radio" name="display_on_index" value="1"<!-- IF S_DISPLAY_ON_INDEX --> id="display_on_index" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input type="radio" class="radio" name="display_on_index" value="0"<!-- IF not S_DISPLAY_ON_INDEX --> id="display_on_index" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index bb38441622..bedbd23532 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -11,7 +11,9 @@ phpbb.alertTime = 100;
var keymap = {
TAB: 9,
ENTER: 13,
- ESC: 27
+ ESC: 27,
+ ARROW_UP: 38,
+ ARROW_DOWN: 40
};
var $dark = $('#darkenwrapper');
@@ -561,7 +563,7 @@ phpbb.search.setValue = function($input, value, multiline) {
phpbb.search.setValueOnClick = function($input, value, $row, $container) {
$row.click(function() {
phpbb.search.setValue($input, value.result, $input.attr('data-multiline'));
- $container.hide();
+ phpbb.search.closeResults($input, $container);
});
};
@@ -575,7 +577,7 @@ phpbb.search.setValueOnClick = function($input, value, $row, $container) {
* @param {object} event Onkeyup event object.
* @param {function} sendRequest Function to execute AJAX request.
*
- * @returns {bool} Returns false.
+ * @returns {boolean} Returns false.
*/
phpbb.search.filter = function(data, event, sendRequest) {
var $this = $(this),
@@ -584,9 +586,16 @@ phpbb.search.filter = function(data, event, sendRequest) {
searchID = $this.attr('data-results'),
keyword = phpbb.search.getKeyword($this, data[dataName], $this.attr('data-multiline')),
cache = phpbb.search.cache.get(searchID),
+ key = event.keyCode || event.which,
proceed = true;
data[dataName] = keyword;
+ // No need to search if enter was pressed
+ // for selecting a value from the results.
+ if (key === keymap.ENTER) {
+ return false;
+ }
+
if (cache.timeout) {
clearTimeout(cache.timeout);
}
@@ -697,22 +706,108 @@ phpbb.search.showResults = function(results, $input, $container, callback) {
row.appendTo($resultContainer).show();
});
$container.show();
+
+ phpbb.search.navigateResults($input, $container, $resultContainer);
};
/**
* Clear search results.
*
- * @param {jQuery} $container Search results container.
+ * @param {jQuery} $container Search results container.
*/
phpbb.search.clearResults = function($container) {
$container.children(':not(.search-result-tpl)').remove();
};
+/**
+ * Close search results.
+ *
+ * @param {jQuery} $input Search input|textarea.
+ * @param {jQuery} $container Search results container.
+ */
+phpbb.search.closeResults = function($input, $container) {
+ $input.off('.phpbb.search');
+ $container.hide();
+};
+
+/**
+ * Navigate search results.
+ *
+ * @param {jQuery} $input Search input|textarea.
+ * @param {jQuery} $container Search results container.
+ * @param {jQuery} $resultContainer Search results list container.
+ */
+phpbb.search.navigateResults = function($input, $container, $resultContainer) {
+ // Add a namespace to the event (.phpbb.search),
+ // so it can be unbound specifically later on.
+ // Rebind it, to ensure the event is 'dynamic'.
+ $input.off('.phpbb.search');
+ $input.on('keydown.phpbb.search', function(event) {
+ var key = event.keyCode || event.which,
+ $active = $resultContainer.children('.active');
+
+ switch (key) {
+ // Close the results
+ case keymap.ESC:
+ phpbb.search.closeResults($input, $container);
+ break;
+
+ // Set the value for the selected result
+ case keymap.ENTER:
+ if ($active.length) {
+ var value = $active.find('.search-result > span').text();
+
+ phpbb.search.setValue($input, value, $input.attr('data-multiline'));
+ }
+
+ phpbb.search.closeResults($input, $container);
+
+ // Do not submit the form
+ event.preventDefault();
+ break;
+
+ // Navigate the results
+ case keymap.ARROW_DOWN:
+ case keymap.ARROW_UP:
+ var up = key === keymap.ARROW_UP,
+ $children = $resultContainer.children();
+
+ if (!$active.length) {
+ if (up) {
+ $children.last().addClass('active');
+ } else {
+ $children.first().addClass('active');
+ }
+ } else if ($children.length > 1) {
+ if (up) {
+ if ($active.is(':first-child')) {
+ $children.last().addClass('active');
+ } else {
+ $active.prev().addClass('active');
+ }
+ } else {
+ if ($active.is(':last-child')) {
+ $children.first().addClass('active');
+ } else {
+ $active.next().addClass('active');
+ }
+ }
+
+ $active.removeClass('active');
+ }
+
+ // Do not change cursor position in the input element
+ event.preventDefault();
+ break;
+ }
+ });
+};
+
$('#phpbb').click(function() {
var $this = $(this);
if (!$this.is('.live-search') && !$this.parents().is('.live-search')) {
- $('.live-search').hide();
+ phpbb.search.closeResults($('input, textarea'), $('.live-search'));
}
});
@@ -1492,7 +1587,7 @@ phpbb.colorPalette = function(dir, width, height) {
* @param {jQuery} el jQuery object for the palette container.
*/
phpbb.registerPalette = function(el) {
- var orientation = el.attr('data-color-palette'),
+ var orientation = el.attr('data-color-palette') || el.attr('data-orientation'), // data-orientation kept for backwards compat.
height = el.attr('data-height'),
width = el.attr('data-width'),
target = el.attr('data-target'),
@@ -1706,7 +1801,7 @@ $(function() {
phpbb.registerPageDropdowns();
- $('[data-color-palette]').each(function() {
+ $('[data-color-palette], [data-orientation]').each(function() {
phpbb.registerPalette($(this));
});
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index e39d0ec865..7529a9e883 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -85,44 +85,46 @@
},
{
"name": "guzzlehttp/guzzle",
- "version": "6.3.3",
+ "version": "6.5.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
- "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
+ "reference": "dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
- "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5",
+ "reference": "dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5",
"shasum": ""
},
"require": {
+ "ext-json": "*",
"guzzlehttp/promises": "^1.0",
- "guzzlehttp/psr7": "^1.4",
+ "guzzlehttp/psr7": "^1.6.1",
"php": ">=5.5"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
- "psr/log": "^1.0"
+ "psr/log": "^1.1"
},
"suggest": {
+ "ext-intl": "Required for Internationalized Domain Name (IDN) support",
"psr/log": "Required for using the Log middleware"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "6.3-dev"
+ "dev-master": "6.5-dev"
}
},
"autoload": {
- "files": [
- "src/functions_include.php"
- ],
"psr-4": {
"GuzzleHttp\\": "src/"
- }
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -146,7 +148,7 @@
"rest",
"web service"
],
- "time": "2018-04-22T15:46:56+00:00"
+ "time": "2019-12-07T18:20:45+00:00"
},
{
"name": "guzzlehttp/promises",
@@ -335,20 +337,20 @@
"oauth",
"security"
],
- "time": "2018-02-14T22:37:14+00:00"
+ "time": "2016-07-12T22:15:00+00:00"
},
{
"name": "marc1706/fast-image-size",
- "version": "v1.1.5",
+ "version": "v1.1.6",
"source": {
"type": "git",
"url": "https://github.com/marc1706/fast-image-size.git",
- "reference": "519b90abdba7e3d54b4dc710d72a2e070fca0984"
+ "reference": "3a3a2b036be20f43fa06ce00dfa754df503e6684"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/marc1706/fast-image-size/zipball/519b90abdba7e3d54b4dc710d72a2e070fca0984",
- "reference": "519b90abdba7e3d54b4dc710d72a2e070fca0984",
+ "url": "https://api.github.com/repos/marc1706/fast-image-size/zipball/3a3a2b036be20f43fa06ce00dfa754df503e6684",
+ "reference": "3a3a2b036be20f43fa06ce00dfa754df503e6684",
"shasum": ""
},
"require": {
@@ -392,20 +394,20 @@
"php",
"size"
],
- "time": "2019-10-03T15:00:04+00:00"
+ "time": "2019-12-07T08:02:07+00:00"
},
{
"name": "ocramius/package-versions",
- "version": "1.4.0",
+ "version": "1.4.2",
"source": {
"type": "git",
"url": "https://github.com/Ocramius/PackageVersions.git",
- "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb"
+ "reference": "44af6f3a2e2e04f2af46bcb302ad9600cba41c7d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb",
- "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb",
+ "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/44af6f3a2e2e04f2af46bcb302ad9600cba41c7d",
+ "reference": "44af6f3a2e2e04f2af46bcb302ad9600cba41c7d",
"shasum": ""
},
"require": {
@@ -417,7 +419,7 @@
"doctrine/coding-standard": "^5.0.1",
"ext-zip": "*",
"infection/infection": "^0.7.1",
- "phpunit/phpunit": "^7.0.0"
+ "phpunit/phpunit": "^7.5.17"
},
"type": "composer-plugin",
"extra": {
@@ -442,7 +444,7 @@
}
],
"description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
- "time": "2019-02-21T12:16:21+00:00"
+ "time": "2019-11-15T16:17:10+00:00"
},
{
"name": "ocramius/proxy-manager",
@@ -560,22 +562,25 @@
},
{
"name": "patchwork/utf8",
- "version": "v1.3.1",
+ "version": "v1.3.2",
"source": {
"type": "git",
"url": "https://github.com/tchwork/utf8.git",
- "reference": "30ec6451aec7d2536f0af8fe535f70c764f2c47a"
+ "reference": "d296e0026e7ce10b2a9fe594feca9628ef00e9e8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/tchwork/utf8/zipball/30ec6451aec7d2536f0af8fe535f70c764f2c47a",
- "reference": "30ec6451aec7d2536f0af8fe535f70c764f2c47a",
+ "url": "https://api.github.com/repos/tchwork/utf8/zipball/d296e0026e7ce10b2a9fe594feca9628ef00e9e8",
+ "reference": "d296e0026e7ce10b2a9fe594feca9628ef00e9e8",
"shasum": ""
},
"require": {
"lib-pcre": ">=7.3",
"php": ">=5.3.0"
},
+ "require-dev": {
+ "symfony/phpunit-bridge": "^3.4|^4.4"
+ },
"suggest": {
"ext-iconv": "Use iconv for best performance",
"ext-intl": "Use Intl for best performance",
@@ -615,7 +620,7 @@
"utf-8",
"utf8"
],
- "time": "2016-05-18T13:57:10+00:00"
+ "time": "2019-12-03T14:44:12+00:00"
},
{
"name": "psr/container",
@@ -718,16 +723,16 @@
},
{
"name": "psr/log",
- "version": "1.1.0",
+ "version": "1.1.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
- "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
+ "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
- "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801",
+ "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801",
"shasum": ""
},
"require": {
@@ -736,7 +741,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "1.1.x-dev"
}
},
"autoload": {
@@ -761,7 +766,7 @@
"psr",
"psr-3"
],
- "time": "2018-11-20T15:27:04+00:00"
+ "time": "2019-11-01T11:05:21+00:00"
},
{
"name": "ralouphie/getallheaders",
@@ -843,16 +848,16 @@
},
{
"name": "s9e/text-formatter",
- "version": "2.1.2",
+ "version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/s9e/TextFormatter.git",
- "reference": "de2752a252047ef8899dab0ac0880be306bca474"
+ "reference": "26d6ee3a931a25acfea3096f62f0cc42172f3859"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/de2752a252047ef8899dab0ac0880be306bca474",
- "reference": "de2752a252047ef8899dab0ac0880be306bca474",
+ "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/26d6ee3a931a25acfea3096f62f0cc42172f3859",
+ "reference": "26d6ee3a931a25acfea3096f62f0cc42172f3859",
"shasum": ""
},
"require": {
@@ -877,7 +882,7 @@
},
"type": "library",
"extra": {
- "version": "2.1.2"
+ "version": "2.3.0"
},
"autoload": {
"psr-4": {
@@ -907,20 +912,20 @@
"parser",
"shortcodes"
],
- "time": "2019-08-22T21:47:11+00:00"
+ "time": "2019-11-17T16:03:56+00:00"
},
{
"name": "symfony/config",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "24a60c0d7ad98a0fa5d1f892e9286095a389404f"
+ "reference": "a599a867d0e4a07c342b5f1e656b3915a540ddbe"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/24a60c0d7ad98a0fa5d1f892e9286095a389404f",
- "reference": "24a60c0d7ad98a0fa5d1f892e9286095a389404f",
+ "url": "https://api.github.com/repos/symfony/config/zipball/a599a867d0e4a07c342b5f1e656b3915a540ddbe",
+ "reference": "a599a867d0e4a07c342b5f1e656b3915a540ddbe",
"shasum": ""
},
"require": {
@@ -971,20 +976,20 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
- "time": "2019-08-26T07:52:57+00:00"
+ "time": "2019-12-01T10:45:41+00:00"
},
{
"name": "symfony/console",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "4510f04e70344d70952566e4262a0b11df39cb10"
+ "reference": "1ee23b3b659b06c622f2bd2492a229e416eb4586"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/4510f04e70344d70952566e4262a0b11df39cb10",
- "reference": "4510f04e70344d70952566e4262a0b11df39cb10",
+ "url": "https://api.github.com/repos/symfony/console/zipball/1ee23b3b659b06c622f2bd2492a229e416eb4586",
+ "reference": "1ee23b3b659b06c622f2bd2492a229e416eb4586",
"shasum": ""
},
"require": {
@@ -1043,20 +1048,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2019-08-26T07:52:58+00:00"
+ "time": "2019-12-01T10:04:45+00:00"
},
{
"name": "symfony/debug",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "0b600300918780001e2821db77bc28b677794486"
+ "reference": "f72e33fdb1170b326e72c3157f0cd456351dd086"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/0b600300918780001e2821db77bc28b677794486",
- "reference": "0b600300918780001e2821db77bc28b677794486",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/f72e33fdb1170b326e72c3157f0cd456351dd086",
+ "reference": "f72e33fdb1170b326e72c3157f0cd456351dd086",
"shasum": ""
},
"require": {
@@ -1099,20 +1104,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2019-08-20T13:31:17+00:00"
+ "time": "2019-10-24T15:33:53+00:00"
},
{
"name": "symfony/dependency-injection",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
- "reference": "2709bc2978ceb90f5180181f777f8a09125f2d89"
+ "reference": "0d201916bfb3af939fec3c0c8815ea16c60ac1a2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2709bc2978ceb90f5180181f777f8a09125f2d89",
- "reference": "2709bc2978ceb90f5180181f777f8a09125f2d89",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/0d201916bfb3af939fec3c0c8815ea16c60ac1a2",
+ "reference": "0d201916bfb3af939fec3c0c8815ea16c60ac1a2",
"shasum": ""
},
"require": {
@@ -1170,20 +1175,20 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
- "time": "2019-08-26T16:07:57+00:00"
+ "time": "2019-12-01T08:33:36+00:00"
},
{
"name": "symfony/event-dispatcher",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "3e922c4c3430b9de624e8a285dada5e61e230959"
+ "reference": "f9031c22ec127d4a2450760f81a8677fe8a10177"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3e922c4c3430b9de624e8a285dada5e61e230959",
- "reference": "3e922c4c3430b9de624e8a285dada5e61e230959",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f9031c22ec127d4a2450760f81a8677fe8a10177",
+ "reference": "f9031c22ec127d4a2450760f81a8677fe8a10177",
"shasum": ""
},
"require": {
@@ -1233,20 +1238,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2019-08-23T08:05:57+00:00"
+ "time": "2019-10-24T15:33:53+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "00e3a6ddd723b8bcfe4f2a1b6f82b98eeeb51516"
+ "reference": "00cdad0936d06fab136944bc2342b762b1c3a4a2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/00e3a6ddd723b8bcfe4f2a1b6f82b98eeeb51516",
- "reference": "00e3a6ddd723b8bcfe4f2a1b6f82b98eeeb51516",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/00cdad0936d06fab136944bc2342b762b1c3a4a2",
+ "reference": "00cdad0936d06fab136944bc2342b762b1c3a4a2",
"shasum": ""
},
"require": {
@@ -1283,20 +1288,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2019-08-20T13:31:17+00:00"
+ "time": "2019-11-25T16:36:22+00:00"
},
{
"name": "symfony/finder",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "1fcad80b440abcd1451767349906b6f9d3961d37"
+ "reference": "290ae21279b37bfd287cdcce640d51204e84afdf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/1fcad80b440abcd1451767349906b6f9d3961d37",
- "reference": "1fcad80b440abcd1451767349906b6f9d3961d37",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/290ae21279b37bfd287cdcce640d51204e84afdf",
+ "reference": "290ae21279b37bfd287cdcce640d51204e84afdf",
"shasum": ""
},
"require": {
@@ -1332,20 +1337,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2019-08-14T09:39:58+00:00"
+ "time": "2019-11-17T21:55:15+00:00"
},
{
"name": "symfony/http-foundation",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "b3d57a1c325f39f703b249bed7998ce8c64236b4"
+ "reference": "d2d0cfe8e319d9df44c4cca570710fcf221d4593"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b3d57a1c325f39f703b249bed7998ce8c64236b4",
- "reference": "b3d57a1c325f39f703b249bed7998ce8c64236b4",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d2d0cfe8e319d9df44c4cca570710fcf221d4593",
+ "reference": "d2d0cfe8e319d9df44c4cca570710fcf221d4593",
"shasum": ""
},
"require": {
@@ -1386,20 +1391,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "time": "2019-08-26T07:50:50+00:00"
+ "time": "2019-11-28T12:52:59+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "f6d35bb306b26812df007525f5757a8b0e95857e"
+ "reference": "c42c8339acb28cfff0fb1786948db4d23d609ff7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f6d35bb306b26812df007525f5757a8b0e95857e",
- "reference": "f6d35bb306b26812df007525f5757a8b0e95857e",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/c42c8339acb28cfff0fb1786948db4d23d609ff7",
+ "reference": "c42c8339acb28cfff0fb1786948db4d23d609ff7",
"shasum": ""
},
"require": {
@@ -1408,7 +1413,8 @@
"symfony/debug": "^3.3.3|~4.0",
"symfony/event-dispatcher": "~2.8|~3.0|~4.0",
"symfony/http-foundation": "~3.4.12|~4.0.12|^4.1.1",
- "symfony/polyfill-ctype": "~1.8"
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-php56": "~1.8"
},
"conflict": {
"symfony/config": "<2.8",
@@ -1475,20 +1481,20 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
- "time": "2019-08-26T16:36:29+00:00"
+ "time": "2019-12-01T13:50:37+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.12.0",
+ "version": "v1.13.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "550ebaac289296ce228a706d0867afc34687e3f4"
+ "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4",
- "reference": "550ebaac289296ce228a706d0867afc34687e3f4",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
+ "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
"shasum": ""
},
"require": {
@@ -1500,7 +1506,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.12-dev"
+ "dev-master": "1.13-dev"
}
},
"autoload": {
@@ -1533,20 +1539,20 @@
"polyfill",
"portable"
],
- "time": "2019-08-06T08:03:45+00:00"
+ "time": "2019-11-27T13:56:44+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.12.0",
+ "version": "v1.13.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17"
+ "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17",
- "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f",
+ "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f",
"shasum": ""
},
"require": {
@@ -1558,7 +1564,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.12-dev"
+ "dev-master": "1.13-dev"
}
},
"autoload": {
@@ -1592,20 +1598,76 @@
"portable",
"shim"
],
- "time": "2019-08-06T08:03:45+00:00"
+ "time": "2019-11-27T14:18:11+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php56",
+ "version": "v1.13.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php56.git",
+ "reference": "53dd1cdf3cb986893ccf2b96665b25b3abb384f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/53dd1cdf3cb986893ccf2b96665b25b3abb384f4",
+ "reference": "53dd1cdf3cb986893ccf2b96665b25b3abb384f4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/polyfill-util": "~1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.13-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php56\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2019-11-27T13:56:44+00:00"
},
{
"name": "symfony/polyfill-php70",
- "version": "v1.12.0",
+ "version": "v1.13.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php70.git",
- "reference": "54b4c428a0054e254223797d2713c31e08610831"
+ "reference": "af23c7bb26a73b850840823662dda371484926c4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/54b4c428a0054e254223797d2713c31e08610831",
- "reference": "54b4c428a0054e254223797d2713c31e08610831",
+ "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/af23c7bb26a73b850840823662dda371484926c4",
+ "reference": "af23c7bb26a73b850840823662dda371484926c4",
"shasum": ""
},
"require": {
@@ -1615,7 +1677,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.12-dev"
+ "dev-master": "1.13-dev"
}
},
"autoload": {
@@ -1651,20 +1713,72 @@
"portable",
"shim"
],
- "time": "2019-08-06T08:03:45+00:00"
+ "time": "2019-11-27T13:56:44+00:00"
+ },
+ {
+ "name": "symfony/polyfill-util",
+ "version": "v1.13.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-util.git",
+ "reference": "964a67f293b66b95883a5ed918a65354fcd2258f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/964a67f293b66b95883a5ed918a65354fcd2258f",
+ "reference": "964a67f293b66b95883a5ed918a65354fcd2258f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.13-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Util\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony utilities for portability of PHP codes",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compat",
+ "compatibility",
+ "polyfill",
+ "shim"
+ ],
+ "time": "2019-11-27T13:56:44+00:00"
},
{
"name": "symfony/proxy-manager-bridge",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/proxy-manager-bridge.git",
- "reference": "40d174ac695f74d468a0d63e87d1b65c57b47232"
+ "reference": "3c185a0e45ea13334aaf7b0fa9726922816ebec6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/40d174ac695f74d468a0d63e87d1b65c57b47232",
- "reference": "40d174ac695f74d468a0d63e87d1b65c57b47232",
+ "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/3c185a0e45ea13334aaf7b0fa9726922816ebec6",
+ "reference": "3c185a0e45ea13334aaf7b0fa9726922816ebec6",
"shasum": ""
},
"require": {
@@ -1685,9 +1799,6 @@
"psr-4": {
"Symfony\\Bridge\\ProxyManager\\": ""
},
- "classmap": [
- "Legacy/ProxiedMethodReturnExpression.php"
- ],
"exclude-from-classmap": [
"/Tests/"
]
@@ -1708,20 +1819,20 @@
],
"description": "Symfony ProxyManager Bridge",
"homepage": "https://symfony.com",
- "time": "2019-08-20T13:34:30+00:00"
+ "time": "2019-08-29T14:54:55+00:00"
},
{
"name": "symfony/routing",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "8b0faa681c4ee14701e76a7056fef15ac5384163"
+ "reference": "b689ccd48e234ea404806d94b07eeb45f9f6f06a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/8b0faa681c4ee14701e76a7056fef15ac5384163",
- "reference": "8b0faa681c4ee14701e76a7056fef15ac5384163",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/b689ccd48e234ea404806d94b07eeb45f9f6f06a",
+ "reference": "b689ccd48e234ea404806d94b07eeb45f9f6f06a",
"shasum": ""
},
"require": {
@@ -1784,20 +1895,20 @@
"uri",
"url"
],
- "time": "2019-08-26T07:50:50+00:00"
+ "time": "2019-12-01T08:33:36+00:00"
},
{
"name": "symfony/twig-bridge",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/twig-bridge.git",
- "reference": "b3ee7d17bb002129d94504fb27463f7e0b4185bd"
+ "reference": "49b824ddc7f2d250a1f172349cd9a111d63287c0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/b3ee7d17bb002129d94504fb27463f7e0b4185bd",
- "reference": "b3ee7d17bb002129d94504fb27463f7e0b4185bd",
+ "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/49b824ddc7f2d250a1f172349cd9a111d63287c0",
+ "reference": "49b824ddc7f2d250a1f172349cd9a111d63287c0",
"shasum": ""
},
"require": {
@@ -1875,20 +1986,20 @@
],
"description": "Symfony Twig Bridge",
"homepage": "https://symfony.com",
- "time": "2019-08-26T07:52:58+00:00"
+ "time": "2019-11-30T08:19:08+00:00"
},
{
"name": "symfony/yaml",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "3dc414b7db30695bae671a1d86013d03f4ae9834"
+ "reference": "dab657db15207879217fc81df4f875947bf68804"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/3dc414b7db30695bae671a1d86013d03f4ae9834",
- "reference": "3dc414b7db30695bae671a1d86013d03f4ae9834",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/dab657db15207879217fc81df4f875947bf68804",
+ "reference": "dab657db15207879217fc81df4f875947bf68804",
"shasum": ""
},
"require": {
@@ -1934,20 +2045,20 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2019-08-20T13:31:17+00:00"
+ "time": "2019-10-24T15:33:53+00:00"
},
{
"name": "twig/twig",
- "version": "v2.11.3",
+ "version": "v2.12.2",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "699ed2342557c88789a15402de5eb834dedd6792"
+ "reference": "d761fd1f1c6b867ae09a7d8119a6d95d06dc44ed"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/699ed2342557c88789a15402de5eb834dedd6792",
- "reference": "699ed2342557c88789a15402de5eb834dedd6792",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/d761fd1f1c6b867ae09a7d8119a6d95d06dc44ed",
+ "reference": "d761fd1f1c6b867ae09a7d8119a6d95d06dc44ed",
"shasum": ""
},
"require": {
@@ -1957,13 +2068,13 @@
},
"require-dev": {
"psr/container": "^1.0",
- "symfony/debug": "^2.7",
- "symfony/phpunit-bridge": "^3.4.19|^4.1.8|^5.0"
+ "symfony/debug": "^3.4|^4.2",
+ "symfony/phpunit-bridge": "^4.4@dev|^5.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.11-dev"
+ "dev-master": "2.12-dev"
}
},
"autoload": {
@@ -1986,14 +2097,14 @@
"role": "Lead Developer"
},
{
- "name": "Armin Ronacher",
- "email": "armin.ronacher@active-4.com",
- "role": "Project Founder"
- },
- {
"name": "Twig Team",
"homepage": "https://twig.symfony.com/contributors",
"role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
@@ -2001,30 +2112,33 @@
"keywords": [
"templating"
],
- "time": "2019-06-18T15:37:11+00:00"
+ "time": "2019-11-11T16:52:09+00:00"
},
{
"name": "zendframework/zend-code",
- "version": "3.3.2",
+ "version": "3.4.1",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-code.git",
- "reference": "936fa7ad4d53897ea3e3eb41b5b760828246a20b"
+ "reference": "268040548f92c2bfcba164421c1add2ba43abaaa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/zendframework/zend-code/zipball/936fa7ad4d53897ea3e3eb41b5b760828246a20b",
- "reference": "936fa7ad4d53897ea3e3eb41b5b760828246a20b",
+ "url": "https://api.github.com/repos/zendframework/zend-code/zipball/268040548f92c2bfcba164421c1add2ba43abaaa",
+ "reference": "268040548f92c2bfcba164421c1add2ba43abaaa",
"shasum": ""
},
"require": {
"php": "^7.1",
"zendframework/zend-eventmanager": "^2.6 || ^3.0"
},
+ "conflict": {
+ "phpspec/prophecy": "<1.9.0"
+ },
"require-dev": {
- "doctrine/annotations": "^1.0",
+ "doctrine/annotations": "^1.7",
"ext-phar": "*",
- "phpunit/phpunit": "^7.5.15",
+ "phpunit/phpunit": "^7.5.16 || ^8.4",
"zendframework/zend-coding-standard": "^1.0",
"zendframework/zend-stdlib": "^2.7 || ^3.0"
},
@@ -2035,8 +2149,9 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.3.x-dev",
- "dev-develop": "3.4.x-dev"
+ "dev-master": "3.4.x-dev",
+ "dev-develop": "3.5.x-dev",
+ "dev-dev-4.0": "4.0.x-dev"
}
},
"autoload": {
@@ -2054,7 +2169,7 @@
"code",
"zf"
],
- "time": "2019-08-31T14:14:34+00:00"
+ "time": "2019-12-10T19:21:15+00:00"
},
{
"name": "zendframework/zend-eventmanager",
@@ -2114,16 +2229,16 @@
"packages-dev": [
{
"name": "doctrine/instantiator",
- "version": "1.2.0",
+ "version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
- "reference": "a2c590166b2133a4633738648b6b064edae0814a"
+ "reference": "ae466f726242e637cebdd526a7d991b9433bacf1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a",
- "reference": "a2c590166b2133a4633738648b6b064edae0814a",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1",
+ "reference": "ae466f726242e637cebdd526a7d991b9433bacf1",
"shasum": ""
},
"require": {
@@ -2166,7 +2281,7 @@
"constructor",
"instantiate"
],
- "time": "2019-03-17T17:37:11+00:00"
+ "time": "2019-10-21T16:45:58+00:00"
},
{
"name": "fabpot/goutte",
@@ -3097,16 +3212,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "7.5.16",
+ "version": "7.5.18",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "316afa6888d2562e04aeb67ea7f2017a0eb41661"
+ "reference": "fcf6c4bfafaadc07785528b06385cce88935474d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/316afa6888d2562e04aeb67ea7f2017a0eb41661",
- "reference": "316afa6888d2562e04aeb67ea7f2017a0eb41661",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fcf6c4bfafaadc07785528b06385cce88935474d",
+ "reference": "fcf6c4bfafaadc07785528b06385cce88935474d",
"shasum": ""
},
"require": {
@@ -3177,7 +3292,7 @@
"testing",
"xunit"
],
- "time": "2019-09-14T09:08:39+00:00"
+ "time": "2019-12-06T05:14:37+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
@@ -3346,16 +3461,16 @@
},
{
"name": "sebastian/environment",
- "version": "4.2.2",
+ "version": "4.2.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404"
+ "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404",
- "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
+ "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
"shasum": ""
},
"require": {
@@ -3395,7 +3510,7 @@
"environment",
"hhvm"
],
- "time": "2019-05-05T09:05:15+00:00"
+ "time": "2019-11-20T08:46:58+00:00"
},
{
"name": "sebastian/exporter",
@@ -3747,16 +3862,16 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "3.5.0",
+ "version": "3.5.3",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "0afebf16a2e7f1e434920fa976253576151effe9"
+ "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/0afebf16a2e7f1e434920fa976253576151effe9",
- "reference": "0afebf16a2e7f1e434920fa976253576151effe9",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/557a1fc7ac702c66b0bbfe16ab3d55839ef724cb",
+ "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb",
"shasum": ""
},
"require": {
@@ -3794,20 +3909,20 @@
"phpcs",
"standards"
],
- "time": "2019-09-26T23:12:26+00:00"
+ "time": "2019-12-04T04:46:47+00:00"
},
{
"name": "symfony/browser-kit",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
- "reference": "1a3406a6b9b61b492592a816ca056afcc9e976c0"
+ "reference": "2e4c991e27a97a8c27745720b030ff85a5cebdf6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/browser-kit/zipball/1a3406a6b9b61b492592a816ca056afcc9e976c0",
- "reference": "1a3406a6b9b61b492592a816ca056afcc9e976c0",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/2e4c991e27a97a8c27745720b030ff85a5cebdf6",
+ "reference": "2e4c991e27a97a8c27745720b030ff85a5cebdf6",
"shasum": ""
},
"require": {
@@ -3851,20 +3966,20 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
- "time": "2019-08-26T07:52:58+00:00"
+ "time": "2019-10-24T15:33:53+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "e18c5c4b35e7f17513448a25d02f7af34a4bdb41"
+ "reference": "f819f71ae3ba6f396b4c015bd5895de7d2f1f85f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/e18c5c4b35e7f17513448a25d02f7af34a4bdb41",
- "reference": "e18c5c4b35e7f17513448a25d02f7af34a4bdb41",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/f819f71ae3ba6f396b4c015bd5895de7d2f1f85f",
+ "reference": "f819f71ae3ba6f396b4c015bd5895de7d2f1f85f",
"shasum": ""
},
"require": {
@@ -3904,20 +4019,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2019-08-20T13:31:17+00:00"
+ "time": "2019-10-01T11:57:37+00:00"
},
{
"name": "symfony/dom-crawler",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
- "reference": "8558d1bc4554f5cb0b66e50377457967a8969263"
+ "reference": "6bcffd2eabc4ca087faaaf54e26c8ff3a40284f3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/8558d1bc4554f5cb0b66e50377457967a8969263",
- "reference": "8558d1bc4554f5cb0b66e50377457967a8969263",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/6bcffd2eabc4ca087faaaf54e26c8ff3a40284f3",
+ "reference": "6bcffd2eabc4ca087faaaf54e26c8ff3a40284f3",
"shasum": ""
},
"require": {
@@ -3961,20 +4076,20 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
- "time": "2019-08-26T07:52:58+00:00"
+ "time": "2019-10-24T15:33:53+00:00"
},
{
"name": "symfony/process",
- "version": "v3.4.31",
+ "version": "v3.4.36",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "d822cb654000a95b7855362c0d5b127f6a6d8baa"
+ "reference": "9a4545c01e1e4f473492bd52b71e574dcc401ca2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/d822cb654000a95b7855362c0d5b127f6a6d8baa",
- "reference": "d822cb654000a95b7855362c0d5b127f6a6d8baa",
+ "url": "https://api.github.com/repos/symfony/process/zipball/9a4545c01e1e4f473492bd52b71e574dcc401ca2",
+ "reference": "9a4545c01e1e4f473492bd52b71e574dcc401ca2",
"shasum": ""
},
"require": {
@@ -4010,7 +4125,7 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2019-08-26T07:52:58+00:00"
+ "time": "2019-11-28T10:05:51+00:00"
},
{
"name": "theseer/tokenizer",
@@ -4054,31 +4169,29 @@
},
{
"name": "webmozart/assert",
- "version": "1.5.0",
+ "version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
- "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4"
+ "reference": "573381c0a64f155a0d9a23f4b0c797194805b925"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4",
- "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925",
+ "reference": "573381c0a64f155a0d9a23f4b0c797194805b925",
"shasum": ""
},
"require": {
"php": "^5.3.3 || ^7.0",
"symfony/polyfill-ctype": "^1.8"
},
+ "conflict": {
+ "vimeo/psalm": "<3.6.0"
+ },
"require-dev": {
"phpunit/phpunit": "^4.8.36 || ^7.5.13"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.3-dev"
- }
- },
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
@@ -4100,7 +4213,7 @@
"check",
"validate"
],
- "time": "2019-08-24T08:43:50+00:00"
+ "time": "2019-11-24T13:36:37+00:00"
}
],
"aliases": [],
diff --git a/phpBB/config/default/container/services_auth.yml b/phpBB/config/default/container/services_auth.yml
index ed8dc90a74..1540bea97f 100644
--- a/phpBB/config/default/container/services_auth.yml
+++ b/phpBB/config/default/container/services_auth.yml
@@ -15,12 +15,12 @@ services:
auth.provider.db:
class: phpbb\auth\provider\db
arguments:
- - '@dbal.conn'
+ - '@captcha.factory'
- '@config'
+ - '@dbal.conn'
- '@passwords.manager'
- '@request'
- '@user'
- - '@service_container'
- '%core.root_path%'
- '%core.php_ext%'
tags:
@@ -29,9 +29,9 @@ services:
auth.provider.apache:
class: phpbb\auth\provider\apache
arguments:
- - '@dbal.conn'
- '@config'
- - '@passwords.manager'
+ - '@dbal.conn'
+ - '@language'
- '@request'
- '@user'
- '%core.root_path%'
@@ -42,9 +42,9 @@ services:
auth.provider.ldap:
class: phpbb\auth\provider\ldap
arguments:
- - '@dbal.conn'
- '@config'
- - '@passwords.manager'
+ - '@dbal.conn'
+ - '@language'
- '@user'
tags:
- { name: auth.provider }
@@ -52,18 +52,18 @@ services:
auth.provider.oauth:
class: phpbb\auth\provider\oauth\oauth
arguments:
- - '@dbal.conn'
- '@config'
- - '@passwords.manager'
+ - '@dbal.conn'
+ - '@auth.provider.db'
+ - '@dispatcher'
+ - '@language'
- '@request'
+ - '@auth.provider.oauth.service_collection'
- '@user'
- '%tables.auth_provider_oauth_token_storage%'
- '%tables.auth_provider_oauth_states%'
- '%tables.auth_provider_oauth_account_assoc%'
- - '@auth.provider.oauth.service_collection'
- '%tables.users%'
- - '@service_container'
- - '@dispatcher'
- '%core.root_path%'
- '%core.php_ext%'
tags:
diff --git a/phpBB/config/default/container/services_console.yml b/phpBB/config/default/container/services_console.yml
index 05e467ff8d..b662102b35 100644
--- a/phpBB/config/default/container/services_console.yml
+++ b/phpBB/config/default/container/services_console.yml
@@ -158,14 +158,6 @@ services:
tags:
- { name: console.command }
- console.command.fixup.recalculate_email_hash:
- class: phpbb\console\command\fixup\recalculate_email_hash
- arguments:
- - '@user'
- - '@dbal.conn'
- tags:
- - { name: console.command }
-
console.command.fixup.update_hashes:
class: phpbb\console\command\fixup\update_hashes
arguments:
diff --git a/phpBB/develop/calc_email_hash.php b/phpBB/develop/calc_email_hash.php
deleted file mode 100644
index 740f9158cf..0000000000
--- a/phpBB/develop/calc_email_hash.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?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.
-*
-*/
-
-//
-// Security message:
-//
-// This script is potentially dangerous.
-// Remove or comment the next line (die(".... ) to enable this script.
-// Do NOT FORGET to either remove this script or disable it after you have used it.
-//
-die("Please read the first lines of this script for instructions on how to enable it");
-@set_time_limit(300);
-
-$db = $dbhost = $dbuser = $dbpasswd = $dbport = $dbname = '';
-
-define('IN_PHPBB', 1);
-define('ANONYMOUS', 1);
-$phpEx = substr(strrchr(__FILE__, '.'), 1);
-$phpbb_root_path='./../';
-include($phpbb_root_path . 'config.'.$phpEx);
-require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.'.$phpEx);
-require($phpbb_root_path . 'includes/db/' . $dbms . '.'.$phpEx);
-include($phpbb_root_path . 'includes/functions.'.$phpEx);
-
-$cache = new acm();
-$db = new sql_db();
-
-// Connect to DB
-$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false);
-
-$start = 0;
-do
-{
- // Batch query for group members, call group_user_del
- $sql = "SELECT user_id, user_email
- FROM {$table_prefix}users
- LIMIT $start, 100";
- $result = $db->sql_query($sql);
-
- if ($row = $db->sql_fetchrow($result))
- {
- do
- {
- $sql = "UPDATE {$table_prefix}users
- SET user_email_hash = " . (crc32(strtolower($row['user_email'])) . strlen($row['user_email'])) . '
- WHERE user_id = ' . $row['user_id'];
- $db->sql_query($sql);
-
- $start++;
- }
- while ($row = $db->sql_fetchrow($result));
-
- echo "<br />Batch -> $start\n";
- flush();
- }
- else
- {
- $start = 0;
- }
- $db->sql_freeresult($result);
-}
-while ($start);
-
-echo "<p><b>Done</b></p>\n";
diff --git a/phpBB/develop/update_email_hash.php b/phpBB/develop/update_email_hash.php
deleted file mode 100644
index c149900d64..0000000000
--- a/phpBB/develop/update_email_hash.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/**
-* Corrects user_email_hash values if DB moved from 32-bit system to 64-bit system or vice versa.
-* The CRC32 function in PHP generates different results for both systems.
-* @PHP dev team: no, a hexdec() applied to it does not solve the issue. And please document it.
-*
-*/
-die("Please read the first lines of this script for instructions on how to enable it");
-
-set_time_limit(0);
-
-define('IN_PHPBB', true);
-$phpbb_root_path = './../';
-$phpEx = substr(strrchr(__FILE__, '.'), 1);
-include($phpbb_root_path . 'common.' . $phpEx);
-
-// Start session management
-$user->session_begin();
-$auth->acl($user->data);
-$user->setup();
-
-$start = $request->variable('start', 0);
-$num_items = 1000;
-
-echo '<br />Updating user email hashes' . "\n";
-
-$sql = 'SELECT user_id, user_email
- FROM ' . USERS_TABLE . '
- ORDER BY user_id ASC';
-$result = $db->sql_query($sql);
-
-$echos = 0;
-while ($row = $db->sql_fetchrow($result))
-{
- $echos++;
-
- $sql = 'UPDATE ' . USERS_TABLE . "
- SET user_email_hash = '" . $db->sql_escape(phpbb_email_hash($row['user_email'])) . "'
- WHERE user_id = " . (int) $row['user_id'];
- $db->sql_query($sql);
-
- if ($echos == 200)
- {
- echo '<br />';
- $echos = 0;
- }
-
- echo '.';
- flush();
-}
-$db->sql_freeresult($result);
-
-echo 'FINISHED';
-
-// Done
-$db->sql_close();
diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html
index 08804e5ce5..d229b91bd6 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -50,6 +50,7 @@
<ol>
<li><a href="#changelog">Changelog</a>
<ul>
+ <li><a href="#v330b1">Changes since 3.3.0-b1</a></li>
<li><a href="#v32x">Changes since 3.2.x</a></li>
<li><a href="#v328rc1">Changes since 3.2.8-RC1</a></li>
<li><a href="#v327">Changes since 3.2.7</a></li>
@@ -141,6 +142,30 @@
<div class="inner">
<div class="content">
+ <a name="v330b1"></a><h3>Changes since 3.3.0-b1</h3>
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16008">PHPBB3-16008</a>] - oAuth does not respect custom server settings</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16167">PHPBB3-16167</a>] - phpbb_email_hash creates false duplicates</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16188">PHPBB3-16188</a>] - Statistics Panel in ACP</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16192">PHPBB3-16192</a>] - Installing Extensions Via CLI Broken</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16205">PHPBB3-16205</a>] - Undefined variable 'zebra' in search.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16210">PHPBB3-16210</a>] - Terms of use should not be skippable</li>
+ </ul>
+ <h4>Improvement</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12539">PHPBB3-12539</a>] - Live Member Search Improvements</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12559">PHPBB3-12559</a>] - Add forum setting to limit subforums legend to direct children only</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12574">PHPBB3-12574</a>] - Don't require the passwords_manager in the constructor of the auth plugins</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15958">PHPBB3-15958</a>] - Created forums and default forum created during install have diferent options</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16187">PHPBB3-16187</a>] - Correctly display registration using external services</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16189">PHPBB3-16189</a>] - Deprecate inet_ntop and inet_pton wrappers</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16190">PHPBB3-16190</a>] - Deprecate phpbb's checkdnsrr wrapper</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16195">PHPBB3-16195</a>] - Copy forum permissions missing paragraph</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16196">PHPBB3-16196</a>] - Remove random_compat</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16206">PHPBB3-16206</a>] - Remove offsetExists reimplementation in service_collection</li>
+ </ul>
+
<a name="v32x"></a><h3>Changes since 3.2.x</h3>
<h4>Bug</h4>
<ul>
diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html
index 33609837eb..fbc701a2ca 100644
--- a/phpBB/docs/INSTALL.html
+++ b/phpBB/docs/INSTALL.html
@@ -147,7 +147,7 @@
<li>Oracle</li>
</ul>
</li>
- <li><strong>PHP 7.1.0+</strong> but less than <strong>PHP 7.4</strong> with support for the database you intend to use.</li>
+ <li><strong>PHP 7.1.0+</strong> up to and including <strong>PHP 7.4</strong> with support for the database you intend to use.</li>
<li>The following PHP modules are required:
<ul>
<li>json</li>
diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html
index 6cf647c55f..ffa2112771 100644
--- a/phpBB/docs/coding-guidelines.html
+++ b/phpBB/docs/coding-guidelines.html
@@ -234,9 +234,9 @@ PHPBB_USE_BOARD_URL_PATH (use generate_board_url() for image paths instead of
PHPBB_DISABLE_ACP_EDITOR (disable ACP style editor for templates)
PHPBB_DISABLE_CONFIG_CHECK (disable ACP config.php writeable check)
-PHPBB_ACM_MEMCACHE_PORT (overwrite memcached port, default is 11211)
-PHPBB_ACM_MEMCACHE_COMPRESS (overwrite memcached compress setting, default is disabled)
-PHPBB_ACM_MEMCACHE_HOST (overwrite memcached host name, default is localhost)
+PHPBB_ACM_MEMCACHED_PORT (overwrite memcached port, default is 11211)
+PHPBB_ACM_MEMCACHED_COMPRESS (overwrite memcached compress setting, default is disabled)
+PHPBB_ACM_MEMCACHED_HOST (overwrite memcached host name, default is localhost)
PHPBB_ACM_REDIS_HOST (overwrite redis host name, default is localhost)
PHPBB_ACM_REDIS_PORT (overwrite redis port, default is 6379)
diff --git a/phpBB/docs/nginx.sample.conf b/phpBB/docs/nginx.sample.conf
index 55c01a1fc9..848998cfeb 100644
--- a/phpBB/docs/nginx.sample.conf
+++ b/phpBB/docs/nginx.sample.conf
@@ -93,7 +93,7 @@ http {
# Correctly pass scripts for installer
location /install/ {
# phpBB uses index.htm
- try_files $uri $uri/ @rewrite_installapp;
+ try_files $uri $uri/ @rewrite_installapp =404;
# Pass the php scripts to fastcgi server specified in upstream declaration.
location ~ \.php(/|$) {
@@ -104,7 +104,7 @@ http {
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
- try_files $uri $uri/ /install/app.php$is_args$args;
+ try_files $uri $uri/ /install/app.php$is_args$args =404;
fastcgi_pass php;
}
}
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 05871e4157..2441a37edc 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -101,6 +101,7 @@ class acp_board
'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'allow_birthdays' => array('lang' => 'ALLOW_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'display_last_subject' => array('lang' => 'DISPLAY_LAST_SUBJECT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'display_unapproved_posts' => array('lang' => 'DISPLAY_UNAPPROVED_POSTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'allow_quick_reply' => array('lang' => 'ALLOW_QUICK_REPLY', 'validate' => 'bool', 'type' => 'custom', 'method' => 'quick_reply', 'explain' => true),
'legend2' => 'ACP_SUBMIT_CHANGES',
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index 572ae3692a..ba3901f67a 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -132,6 +132,7 @@ class acp_forums
'forum_image' => $request->variable('forum_image', ''),
'forum_style' => $request->variable('forum_style', 0),
'display_subforum_list' => $request->variable('display_subforum_list', true),
+ 'display_subforum_limit'=> $request->variable('display_subforum_limit', false),
'display_on_index' => $request->variable('display_on_index', true),
'forum_topics_per_page' => $request->variable('topics_per_page', 0),
'enable_indexing' => $request->variable('enable_indexing', true),
@@ -454,6 +455,7 @@ class acp_forums
'forum_image' => '',
'forum_style' => 0,
'display_subforum_list' => true,
+ 'display_subforum_limit' => false,
'display_on_index' => true,
'forum_topics_per_page' => 0,
'enable_indexing' => true,
@@ -676,6 +678,7 @@ class acp_forums
'S_ENABLE_INDEXING' => ($forum_data['enable_indexing']) ? true : false,
'S_TOPIC_ICONS' => ($forum_data['enable_icons']) ? true : false,
'S_DISPLAY_SUBFORUM_LIST' => ($forum_data['display_subforum_list']) ? true : false,
+ 'S_DISPLAY_SUBFORUM_LIMIT' => ($forum_data['display_subforum_limit']) ? true : false,
'S_DISPLAY_ON_INDEX' => ($forum_data['display_on_index']) ? true : false,
'S_PRUNE_ENABLE' => ($forum_data['enable_prune']) ? true : false,
'S_PRUNE_SHADOW_ENABLE' => ($forum_data['enable_shadow_prune']) ? true : false,
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 1b66943490..6993c86279 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -966,10 +966,7 @@ class acp_users
if ($update_email !== false)
{
- $sql_ary += array(
- 'user_email' => $update_email,
- 'user_email_hash' => phpbb_email_hash($update_email),
- );
+ $sql_ary += ['user_email' => $update_email];
$phpbb_log->add('user', $user->data['user_id'], $user->ip, 'LOG_USER_UPDATE_EMAIL', false, array(
'reportee_id' => $user_id,
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index 759bc94520..493399bd71 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))
*/
// phpBB Version
-@define('PHPBB_VERSION', '3.3.0-b2-dev');
+@define('PHPBB_VERSION', '3.3.0-RC1-dev');
// QA-related
// define('PHPBB_QA', 1);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index d2d5b503a2..9759eabb5a 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -264,18 +264,6 @@ function still_on_time($extra_time = 15)
}
/**
-* Hashes an email address to a big integer
-*
-* @param string $email Email address
-*
-* @return string Unsigned Big Integer
-*/
-function phpbb_email_hash($email)
-{
- return sprintf('%u', crc32(strtolower($email))) . strlen($email);
-}
-
-/**
* Wrapper for version_compare() that allows using uppercase A and B
* for alpha and beta releases.
*
@@ -2276,6 +2264,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
$err = '';
$form_name = 'login';
+ $username = $autologin = false;
// Make sure user->setup() has been called
if (!$user->is_setup())
@@ -4130,7 +4119,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
/**
* Workaround for missing template variable in pre phpBB 3.2.6 styles.
- * @deprecated 3.2.7 (To be removed: 3.3.0-a1)
+ * @deprecated 3.2.7 (To be removed: 4.0.0-a1)
*/
$form_token_login = $template->retrieve_var('S_FORM_TOKEN_LOGIN');
if (!empty($form_token_login))
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
index 2578290875..92e24c055c 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -659,3 +659,17 @@ function phpbb_inet_pton($address)
{
return inet_pton($address);
}
+
+/**
+ * Hashes an email address to a big integer
+ *
+ * @param string $email Email address
+ *
+ * @return string Unsigned Big Integer
+ *
+ * @deprecated 3.3.0-b2 (To be removed: 4.0.0)
+ */
+function phpbb_email_hash($email)
+{
+ return sprintf('%u', crc32(strtolower($email))) . strlen($email);
+}
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index 13e01afe51..df4c9b1875 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -207,16 +207,6 @@ function get_group_id($group_name)
}
/**
-* Generate the email hash stored in the users table
-*
-* Note: Deprecated, calls should directly go to phpbb_email_hash()
-*/
-function gen_email_hash($email)
-{
- return phpbb_email_hash($email);
-}
-
-/**
* Convert a boolean into the appropriate phpBB constant indicating whether the topic is locked
*/
function is_topic_locked($bool)
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index 9be1ff950b..44478dbe49 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -30,6 +30,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$forum_rows = $subforums = $forum_ids = $forum_ids_moderator = $forum_moderators = $active_forum_ary = array();
$parent_id = $visible_forums = 0;
+ $parent_subforum_limit = false;
// Mark forums read?
$mark_read = $request->variable('mark', '');
@@ -266,6 +267,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
// Direct child of current branch
$parent_id = $forum_id;
+ $parent_subforum_limit = $row['display_subforum_limit'];
$forum_rows[$forum_id] = $row;
if ($row['forum_type'] == FORUM_CAT && $row['parent_id'] == $root_data['forum_id'])
@@ -278,7 +280,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
}
else if ($row['forum_type'] != FORUM_CAT)
{
- $subforums[$parent_id][$forum_id]['display'] = ($row['display_on_index']) ? true : false;
+ $subforums[$parent_id][$forum_id]['display'] = ($row['display_on_index'] && (!$parent_subforum_limit || $parent_id == $row['parent_id']));
$subforums[$parent_id][$forum_id]['name'] = $row['forum_name'];
$subforums[$parent_id][$forum_id]['orig_forum_last_post_time'] = $row['forum_last_post_time'];
$subforums[$parent_id][$forum_id]['children'] = array();
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index 7f8238e1bf..ec297b536a 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -1893,14 +1893,21 @@ function mail_encode($str, $eol = "\r\n")
}
/**
-* Wrapper for sending out emails with the PHP's mail function
-*/
+ * Wrapper for sending out emails with the PHP's mail function
+ */
function phpbb_mail($to, $subject, $msg, $headers, $eol, &$err_msg)
{
global $config, $phpbb_root_path, $phpEx;
- // We use the EOL character for the OS here because the PHP mail function does not correctly transform line endings. On Windows SMTP is used (SMTP is \r\n), on UNIX a command is used...
- // Reference: http://bugs.php.net/bug.php?id=15841
+ // Convert Numeric Character References to UTF-8 chars (ie. Emojis)
+ $subject = utf8_decode_ncr($subject);
+ $msg = utf8_decode_ncr($msg);
+
+ /**
+ * We use the EOL character for the OS here because the PHP mail function does not correctly transform line endings.
+ * On Windows SMTP is used (SMTP is \r\n), on UNIX a command is used...
+ * Reference: http://bugs.php.net/bug.php?id=15841
+ */
$headers = implode($eol, $headers);
if (!class_exists('\phpbb\error_collector'))
@@ -1911,10 +1918,14 @@ function phpbb_mail($to, $subject, $msg, $headers, $eol, &$err_msg)
$collector = new \phpbb\error_collector;
$collector->install();
- // On some PHP Versions mail() *may* fail if there are newlines within the subject.
- // Newlines are used as a delimiter for lines in mail_encode() according to RFC 2045 section 6.8.
- // Because PHP can't decide what is wanted we revert back to the non-RFC-compliant way of separating by one space (Use '' as parameter to mail_encode() results in SPACE used)
+ /**
+ * On some PHP Versions mail() *may* fail if there are newlines within the subject.
+ * Newlines are used as a delimiter for lines in mail_encode() according to RFC 2045 section 6.8.
+ * Because PHP can't decide what is wanted we revert back to the non-RFC-compliant way of separating by one space
+ * (Use '' as parameter to mail_encode() results in SPACE used)
+ */
$additional_parameters = $config['email_force_sender'] ? '-f' . $config['board_email'] : '';
+
$result = mail($to, mail_encode($subject, ''), wordwrap(utf8_wordwrap($msg), 997, "\n", true), $headers, $additional_parameters);
$collector->uninstall();
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 5c94a90d9d..dc6e09268a 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -204,7 +204,6 @@ function user_add($user_row, $cp_data = false, $notifications_data = null)
'username_clean' => $username_clean,
'user_password' => (isset($user_row['user_password'])) ? $user_row['user_password'] : '',
'user_email' => strtolower($user_row['user_email']),
- 'user_email_hash' => phpbb_email_hash($user_row['user_email']),
'group_id' => $user_row['group_id'],
'user_type' => $user_row['user_type'],
);
@@ -1948,9 +1947,9 @@ function validate_user_email($email, $allowed_email = false)
if (!$config['allow_emailreuse'])
{
- $sql = 'SELECT user_email_hash
+ $sql = 'SELECT user_email
FROM ' . USERS_TABLE . "
- WHERE user_email_hash = " . $db->sql_escape(phpbb_email_hash($email));
+ WHERE user_email = '" . $db->sql_escape($email) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php
index 06baa279a5..87a8c91fd2 100644
--- a/phpBB/includes/ucp/ucp_pm_compose.php
+++ b/phpBB/includes/ucp/ucp_pm_compose.php
@@ -999,7 +999,10 @@ function compose_pm($id, $mode, $action, $user_folders = array())
{
$quote_attributes['post_id'] = $post['msg_id'];
}
-
+ if ($action === 'quote')
+ {
+ $quote_attributes['msg_id'] = $post['msg_id'];
+ }
/** @var \phpbb\language\language $language */
$language = $phpbb_container->get('language');
/** @var \phpbb\textformatter\utils_interface $text_formatter_utils */
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index 6d98362e08..dca7e7eeb7 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -131,7 +131,6 @@ class ucp_profile
'username' => ($auth->acl_get('u_chgname') && $config['allow_namechange']) ? $data['username'] : $user->data['username'],
'username_clean' => ($auth->acl_get('u_chgname') && $config['allow_namechange']) ? utf8_clean_string($data['username']) : $user->data['username_clean'],
'user_email' => ($auth->acl_get('u_chgemail')) ? $data['email'] : $user->data['user_email'],
- 'user_email_hash' => ($auth->acl_get('u_chgemail')) ? phpbb_email_hash($data['email']) : $user->data['user_email_hash'],
'user_password' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? $passwords_manager->hash($data['new_password']) : $user->data['user_password'],
);
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 97d2631224..00fa8034f9 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -39,12 +39,23 @@ class ucp_register
trigger_error('UCP_REGISTER_DISABLE');
}
- $coppa = $request->is_set('coppa') ? (int) $request->variable('coppa', false) : false;
+ $coppa = $request->is_set('coppa_yes') ? 1 : ($request->is_set('coppa_no') ? 0 : false);
+ $coppa = $request->is_set('coppa') ? $request->variable('coppa', 0) : $coppa;
$agreed = $request->variable('agreed', false);
$submit = $request->is_set_post('submit');
$change_lang = $request->variable('change_lang', '');
$user_lang = $request->variable('lang', $user->lang_name);
+ if ($agreed && !check_form_key('ucp_register'))
+ {
+ $agreed = false;
+ }
+
+ if ($coppa !== false && !check_form_key('ucp_register'))
+ {
+ $coppa = false;
+ }
+
/**
* Add UCP register data before they are assigned to the template or submitted
*
@@ -67,14 +78,7 @@ class ucp_register
);
extract($phpbb_dispatcher->trigger_event('core.ucp_register_requests_after', compact($vars)));
- if ($agreed)
- {
- add_form_key('ucp_register');
- }
- else
- {
- add_form_key('ucp_register_terms');
- }
+ add_form_key('ucp_register');
if ($change_lang || $user_lang != $config['default_lang'])
{
@@ -168,11 +172,8 @@ class ucp_register
$template_vars = array(
'S_LANG_OPTIONS' => (count($lang_row) > 1) ? language_select($user_lang) : '',
- 'L_COPPA_NO' => sprintf($user->lang['UCP_COPPA_BEFORE'], $coppa_birthday),
- 'L_COPPA_YES' => sprintf($user->lang['UCP_COPPA_ON_AFTER'], $coppa_birthday),
-
- 'U_COPPA_NO' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register&amp;coppa=0'),
- 'U_COPPA_YES' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register&amp;coppa=1'),
+ 'L_COPPA_NO' => $user->lang('UCP_COPPA_BEFORE', $coppa_birthday),
+ 'L_COPPA_YES' => $user->lang('UCP_COPPA_ON_AFTER', $coppa_birthday),
'S_SHOW_COPPA' => true,
'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields),
diff --git a/phpBB/includes/ucp/ucp_resend.php b/phpBB/includes/ucp/ucp_resend.php
index 44c54100cd..55923668d4 100644
--- a/phpBB/includes/ucp/ucp_resend.php
+++ b/phpBB/includes/ucp/ucp_resend.php
@@ -47,7 +47,7 @@ class ucp_resend
$sql = 'SELECT user_id, group_id, username, user_email, user_type, user_lang, user_actkey, user_inactive_reason
FROM ' . USERS_TABLE . "
- WHERE user_email_hash = '" . $db->sql_escape(phpbb_email_hash($email)) . "'
+ WHERE user_email = '" . $db->sql_escape($email) . "'
AND username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
$result = $db->sql_query($sql);
$user_row = $db->sql_fetchrow($result);
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php
index c4d2be5a28..cefb33fe3c 100644
--- a/phpBB/install/convertors/convert_phpbb20.php
+++ b/phpBB/install/convertors/convert_phpbb20.php
@@ -38,7 +38,7 @@ $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
$convertor_data = array(
'forum_name' => 'phpBB 2.0.x',
'version' => '1.0.3',
- 'phpbb_version' => '3.3.0',
+ 'phpbb_version' => '3.3.0-b2',
'author' => '<a href="https://www.phpbb.com/">phpBB Limited</a>',
'dbms' => $dbms,
'dbhost' => $dbhost,
@@ -899,7 +899,6 @@ if (!$get_info)
array('user_password', 'users.user_password', 'phpbb_convert_password_hash'),
array('user_posts', 'users.user_posts', 'intval'),
array('user_email', 'users.user_email', 'strtolower'),
- array('user_email_hash', 'users.user_email', 'gen_email_hash'),
array('user_birthday', ((defined('MOD_BIRTHDAY')) ? 'users.user_birthday' : ''), 'phpbb_get_birthday'),
array('user_lastvisit', 'users.user_lastvisit', 'intval'),
array('user_lastmark', 'users.user_lastvisit', 'intval'),
diff --git a/phpBB/install/phpbbcli.php b/phpBB/install/phpbbcli.php
index b7a07488ac..6ac261aa13 100755
--- a/phpBB/install/phpbbcli.php
+++ b/phpBB/install/phpbbcli.php
@@ -23,7 +23,7 @@ if (php_sapi_name() !== 'cli')
define('IN_PHPBB', true);
define('IN_INSTALL', true);
define('PHPBB_ENVIRONMENT', 'production');
-define('PHPBB_VERSION', '3.3.0-b2-dev');
+define('PHPBB_VERSION', '3.3.0-b2');
$phpbb_root_path = __DIR__ . '/../';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index 97fc23f0bf..8e7b26d60c 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -278,7 +278,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.3.0-b2-dev');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.3.0-RC1-dev');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400');
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index fdc02d9ae8..cb9013805d 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -52,6 +52,8 @@ $lang = array_merge($lang, array(
'DISABLE_BOARD_EXPLAIN' => 'This will make the board unavailable to users who are neither administrators nor moderators. You can also enter a short (255 character) message to display if you wish.',
'DISPLAY_LAST_SUBJECT' => 'Display subject of last added post on forum list',
'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'The subject of the last added post will be displayed in the forum list with a hyperlink to the post. Subjects from password protected forums and forums in which user doesn’t have read access are not shown.',
+ 'DISPLAY_UNAPPROVED_POSTS' => 'Display unapproved posts to the author',
+ 'DISPLAY_UNAPPROVED_POSTS_EXPLAIN' => 'Unapproved posts can be viewed by the author. Does not apply to Guest posts.',
'GUEST_STYLE' => 'Guest style',
'GUEST_STYLE_EXPLAIN' => 'The board style for guests.',
'OVERRIDE_STYLE' => 'Override user style',
diff --git a/phpBB/language/en/acp/forums.php b/phpBB/language/en/acp/forums.php
index d92d3f8c9e..3ab152345c 100644
--- a/phpBB/language/en/acp/forums.php
+++ b/phpBB/language/en/acp/forums.php
@@ -129,6 +129,8 @@ $lang = array_merge($lang, array(
'GENERAL_FORUM_SETTINGS' => 'General forum settings',
'LINK' => 'Link',
+ 'LIMIT_SUBFORUMS' => 'Limit legend to direct child-subforums',
+ 'LIMIT_SUBFORUMS_EXPLAIN' => 'Limits the subforums to be displayed to subforums that are direct descendants (children) of the current forum. Disabling this will display all subforums with the “List subforums in legend” option enabled, regardless of depth.',
'LIST_INDEX' => 'List subforum in parent-forum’s legend',
'LIST_INDEX_EXPLAIN' => 'Displays this forum on the index and elsewhere as a link within the legend of its parent-forum if the parent-forum’s “List subforums in legend” option is enabled.',
'LIST_SUBFORUMS' => 'List subforums in legend',
diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php
index 505d12e8ff..122010d2cf 100644
--- a/phpBB/language/en/cli.php
+++ b/phpBB/language/en/cli.php
@@ -78,8 +78,6 @@ $lang = array_merge($lang, array(
'CLI_DESCRIPTION_REPARSER_REPARSE_OPT_RANGE_SIZE' => 'Approximate number of records to process at a time',
'CLI_DESCRIPTION_REPARSER_REPARSE_OPT_RESUME' => 'Start reparsing where the last execution stopped',
- 'CLI_DESCRIPTION_RECALCULATE_EMAIL_HASH' => 'Recalculates the user_email_hash column of the users table.',
-
'CLI_DESCRIPTION_SET_ATOMIC_CONFIG' => 'Sets a configuration option’s value only if the old matches the current value',
'CLI_DESCRIPTION_SET_CONFIG' => 'Sets a configuration option’s value',
@@ -130,7 +128,6 @@ $lang = array_merge($lang, array(
'CLI_EXTENSIONS_ENABLED' => 'Enabled',
'CLI_FIXUP_FIX_LEFT_RIGHT_IDS_SUCCESS' => 'Successfully repaired the tree structure of the forums and modules.',
- 'CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS' => 'Successfully recalculated all email hashes.',
'CLI_FIXUP_UPDATE_HASH_BCRYPT_SUCCESS' => 'Successfully updated outdated password hashes to bcrypt.',
'CLI_MIGRATION_NAME' => 'Migration name, including the namespace (use forward slashes instead of backslashes to avoid problems).',
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index d050c1b109..609ae4fe53 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -94,6 +94,7 @@ $lang = array_merge($lang, array(
'AUTH_PROVIDER_OAUTH_ERROR_ALREADY_LINKED' => 'This external service is already associated with another board account.',
'AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY' => 'Invalid database entry.',
'AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE' => 'Invalid service type provided to OAuth service handler.',
+ 'AUTH_PROVIDER_OAUTH_ERROR_REQUEST' => 'Something went wrong when processing your OAuth request.',
'AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED' => 'OAuth service not created',
'AUTH_PROVIDER_OAUTH_SERVICE_BITLY' => 'Bitly',
'AUTH_PROVIDER_OAUTH_SERVICE_FACEBOOK' => 'Facebook',
@@ -615,6 +616,7 @@ $lang = array_merge($lang, array(
'POST_TOPIC' => 'Post a new topic',
'POST_UNAPPROVED_ACTION' => 'Post awaiting approval:',
'POST_UNAPPROVED' => 'This post has not been approved.',
+ 'POST_UNAPPROVED_EXPLAIN' => 'This post is not visible to other users until it has been approved by a moderator.',
'POWERED_BY' => 'Powered by %s',
'PREVIEW' => 'Preview',
'PREVIOUS' => 'Previous', // Used in pagination
diff --git a/phpBB/phpbb/auth/provider/apache.php b/phpBB/phpbb/auth/provider/apache.php
index aa5bf64335..a713674657 100644
--- a/phpBB/phpbb/auth/provider/apache.php
+++ b/phpBB/phpbb/auth/provider/apache.php
@@ -13,34 +13,55 @@
namespace phpbb\auth\provider;
+use phpbb\config\config;
+use phpbb\db\driver\driver_interface;
+use phpbb\language\language;
+use phpbb\request\request_interface;
+use phpbb\request\type_cast_helper;
+use phpbb\user;
+
/**
* Apache authentication provider for phpBB3
*/
-class apache extends \phpbb\auth\provider\base
+class apache extends base
{
- /**
- * phpBB passwords manager
- *
- * @var \phpbb\passwords\manager
- */
- protected $passwords_manager;
+ /** @var config phpBB config */
+ protected $config;
+
+ /** @var driver_interface Database object */
+ protected $db;
+
+ /** @var language Language object */
+ protected $language;
+
+ /** @var request_interface Request object */
+ protected $request;
+
+ /** @var user User object */
+ protected $user;
+
+ /** @var string Relative path to phpBB root */
+ protected $phpbb_root_path;
+
+ /** @var string PHP file extension */
+ protected $php_ext;
/**
* Apache Authentication Constructor
*
- * @param \phpbb\db\driver\driver_interface $db Database object
- * @param \phpbb\config\config $config Config object
- * @param \phpbb\passwords\manager $passwords_manager Passwords Manager object
- * @param \phpbb\request\request $request Request object
- * @param \phpbb\user $user User object
+ * @param config $config Config object
+ * @param driver_interface $db Database object
+ * @param language $language Language object
+ * @param request_interface $request Request object
+ * @param user $user User object
* @param string $phpbb_root_path Relative path to phpBB root
* @param string $php_ext PHP file extension
*/
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext)
+ public function __construct(config $config, driver_interface $db, language $language, request_interface $request, user $user, $phpbb_root_path, $php_ext)
{
- $this->db = $db;
$this->config = $config;
- $this->passwords_manager = $passwords_manager;
+ $this->db = $db;
+ $this->language = $language;
$this->request = $request;
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
@@ -52,9 +73,9 @@ class apache extends \phpbb\auth\provider\base
*/
public function init()
{
- if (!$this->request->is_set('PHP_AUTH_USER', \phpbb\request\request_interface::SERVER) || $this->user->data['username'] !== htmlspecialchars_decode($this->request->server('PHP_AUTH_USER')))
+ if (!$this->request->is_set('PHP_AUTH_USER', request_interface::SERVER) || $this->user->data['username'] !== htmlspecialchars_decode($this->request->server('PHP_AUTH_USER')))
{
- return $this->user->lang['APACHE_SETUP_BEFORE_USE'];
+ return $this->language->lang('APACHE_SETUP_BEFORE_USE');
}
return false;
}
@@ -83,7 +104,7 @@ class apache extends \phpbb\auth\provider\base
);
}
- if (!$this->request->is_set('PHP_AUTH_USER', \phpbb\request\request_interface::SERVER))
+ if (!$this->request->is_set('PHP_AUTH_USER', request_interface::SERVER))
{
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
@@ -137,7 +158,7 @@ class apache extends \phpbb\auth\provider\base
return array(
'status' => LOGIN_SUCCESS_CREATE_PROFILE,
'error_msg' => false,
- 'user_row' => $this->user_row($php_auth_user, $php_auth_pw),
+ 'user_row' => $this->user_row($php_auth_user),
);
}
@@ -154,7 +175,7 @@ class apache extends \phpbb\auth\provider\base
*/
public function autologin()
{
- if (!$this->request->is_set('PHP_AUTH_USER', \phpbb\request\request_interface::SERVER))
+ if (!$this->request->is_set('PHP_AUTH_USER', request_interface::SERVER))
{
return array();
}
@@ -164,8 +185,8 @@ class apache extends \phpbb\auth\provider\base
if (!empty($php_auth_user) && !empty($php_auth_pw))
{
- set_var($php_auth_user, $php_auth_user, 'string', true);
- set_var($php_auth_pw, $php_auth_pw, 'string', true);
+ $type_cast_helper = new type_cast_helper();
+ $type_cast_helper->set_var($php_auth_user, $php_auth_user, 'string', true);
$sql = 'SELECT *
FROM ' . USERS_TABLE . "
@@ -185,7 +206,7 @@ class apache extends \phpbb\auth\provider\base
}
// create the user if he does not exist yet
- user_add($this->user_row($php_auth_user, $php_auth_pw));
+ user_add($this->user_row($php_auth_user));
$sql = 'SELECT *
FROM ' . USERS_TABLE . "
@@ -208,11 +229,11 @@ class apache extends \phpbb\auth\provider\base
* function in order to create a user
*
* @param string $username The username of the new user.
- * @param string $password The password of the new user.
+ *
* @return array Contains data that can be passed directly to
* the user_add function.
*/
- private function user_row($username, $password)
+ private function user_row($username)
{
// first retrieve default group id
$sql = 'SELECT group_id
@@ -231,7 +252,7 @@ class apache extends \phpbb\auth\provider\base
// generate user account data
return array(
'username' => $username,
- 'user_password' => $this->passwords_manager->hash($password),
+ 'user_password' => '',
'user_email' => '',
'group_id' => (int) $row['group_id'],
'user_type' => USER_NORMAL,
@@ -246,7 +267,7 @@ class apache extends \phpbb\auth\provider\base
public function validate_session($user)
{
// Check if PHP_AUTH_USER is set and handle this case
- if ($this->request->is_set('PHP_AUTH_USER', \phpbb\request\request_interface::SERVER))
+ if ($this->request->is_set('PHP_AUTH_USER', request_interface::SERVER))
{
$php_auth_user = $this->request->server('PHP_AUTH_USER');
diff --git a/phpBB/phpbb/auth/provider/base.php b/phpBB/phpbb/auth/provider/base.php
index dea27ccc25..30e0a0fe2d 100644
--- a/phpBB/phpbb/auth/provider/base.php
+++ b/phpBB/phpbb/auth/provider/base.php
@@ -16,7 +16,7 @@ namespace phpbb\auth\provider;
/**
* Base authentication provider class that all other providers should implement
*/
-abstract class base implements \phpbb\auth\provider\provider_interface
+abstract class base implements provider_interface
{
/**
* {@inheritdoc}
diff --git a/phpBB/phpbb/auth/provider/db.php b/phpBB/phpbb/auth/provider/db.php
index 1adf85ee05..a70734fcbe 100644
--- a/phpBB/phpbb/auth/provider/db.php
+++ b/phpBB/phpbb/auth/provider/db.php
@@ -13,48 +13,69 @@
namespace phpbb\auth\provider;
+use phpbb\captcha\factory;
+use phpbb\config\config;
+use phpbb\db\driver\driver_interface;
+use phpbb\passwords\manager;
+use phpbb\request\request_interface;
+use phpbb\user;
+
/**
* Database authentication provider for phpBB3
* This is for authentication via the integrated user table
*/
-class db extends \phpbb\auth\provider\base
+class db extends base
{
+ /** @var factory CAPTCHA factory */
+ protected $captcha_factory;
+
+ /** @var config phpBB config */
+ protected $config;
+
+ /** @var driver_interface DBAL driver instance */
+ protected $db;
+
+ /** @var request_interface Request object */
+ protected $request;
+
+ /** @var user User object */
+ protected $user;
+
+ /** @var string phpBB root path */
+ protected $phpbb_root_path;
+
+ /** @var string PHP file extension */
+ protected $php_ext;
+
/**
* phpBB passwords manager
*
- * @var \phpbb\passwords\manager
+ * @var manager
*/
protected $passwords_manager;
/**
- * DI container
- *
- * @var \Symfony\Component\DependencyInjection\ContainerInterface
- */
- protected $phpbb_container;
-
- /**
* Database Authentication Constructor
*
- * @param \phpbb\db\driver\driver_interface $db
- * @param \phpbb\config\config $config
- * @param \phpbb\passwords\manager $passwords_manager
- * @param \phpbb\request\request $request
- * @param \phpbb\user $user
- * @param \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container DI container
+ * @param factory $captcha_factory
+ * @param config $config
+ * @param driver_interface $db
+ * @param manager $passwords_manager
+ * @param request_interface $request
+ * @param user $user
* @param string $phpbb_root_path
* @param string $php_ext
*/
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, $phpbb_root_path, $php_ext)
+ public function __construct(factory $captcha_factory, config $config, driver_interface $db, manager $passwords_manager, request_interface $request, user $user, $phpbb_root_path, $php_ext)
{
- $this->db = $db;
+ $this->captcha_factory = $captcha_factory;
$this->config = $config;
+ $this->db = $db;
$this->passwords_manager = $passwords_manager;
$this->request = $request;
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
- $this->phpbb_container = $phpbb_container;
}
/**
@@ -155,9 +176,7 @@ class db extends \phpbb\auth\provider\base
// Every auth module is able to define what to do by itself...
if ($show_captcha)
{
- /* @var $captcha_factory \phpbb\captcha\factory */
- $captcha_factory = $this->phpbb_container->get('captcha.factory');
- $captcha = $captcha_factory->get_instance($this->config['captcha_plugin']);
+ $captcha = $this->captcha_factory->get_instance($this->config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
$vc_response = $captcha->validate($row);
if ($vc_response)
diff --git a/phpBB/phpbb/auth/provider/ldap.php b/phpBB/phpbb/auth/provider/ldap.php
index 0789a6234d..6a78136e5f 100644
--- a/phpBB/phpbb/auth/provider/ldap.php
+++ b/phpBB/phpbb/auth/provider/ldap.php
@@ -1,4 +1,5 @@
<?php
+
/**
*
* This file is part of the phpBB Forum Software package.
@@ -13,32 +14,42 @@
namespace phpbb\auth\provider;
+use phpbb\config\config;
+use phpbb\db\driver\driver_interface;
+use phpbb\language\language;
+use phpbb\user;
+
/**
* Database authentication provider for phpBB3
* This is for authentication via the integrated user table
*/
-class ldap extends \phpbb\auth\provider\base
+class ldap extends base
{
- /**
- * phpBB passwords manager
- *
- * @var \phpbb\passwords\manager
- */
- protected $passwords_manager;
+ /** @var config phpBB config */
+ protected $config;
+
+ /** @var driver_interface DBAL driver interface */
+ protected $db;
+
+ /** @var language phpBB language class */
+ protected $language;
+
+ /** @var user phpBB user */
+ protected $user;
/**
* LDAP Authentication Constructor
*
- * @param \phpbb\db\driver\driver_interface $db Database object
- * @param \phpbb\config\config $config Config object
- * @param \phpbb\passwords\manager $passwords_manager Passwords manager object
- * @param \phpbb\user $user User object
+ * @param driver_interface $db DBAL driver interface
+ * @param config $config Config object
+ * @param language $language Language object
+ * @param user $user User object
*/
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\user $user)
+ public function __construct(config $config, driver_interface $db, language $language, user $user)
{
- $this->db = $db;
$this->config = $config;
- $this->passwords_manager = $passwords_manager;
+ $this->db = $db;
+ $this->language = $language;
$this->user = $user;
}
@@ -49,7 +60,7 @@ class ldap extends \phpbb\auth\provider\base
{
if (!@extension_loaded('ldap'))
{
- return $this->user->lang['LDAP_NO_LDAP_EXTENSION'];
+ return $this->language->lang('LDAP_NO_LDAP_EXTENSION');
}
$this->config['ldap_port'] = (int) $this->config['ldap_port'];
@@ -64,7 +75,7 @@ class ldap extends \phpbb\auth\provider\base
if (!$ldap)
{
- return $this->user->lang['LDAP_NO_SERVER_CONNECTION'];
+ return $this->language->lang('LDAP_NO_SERVER_CONNECTION');
}
@ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
@@ -74,7 +85,7 @@ class ldap extends \phpbb\auth\provider\base
{
if (!@ldap_bind($ldap, htmlspecialchars_decode($this->config['ldap_user']), htmlspecialchars_decode($this->config['ldap_password'])))
{
- return $this->user->lang['LDAP_INCORRECT_USER_PASSWORD'];
+ return $this->language->lang('LDAP_INCORRECT_USER_PASSWORD');
}
}
@@ -92,7 +103,7 @@ class ldap extends \phpbb\auth\provider\base
if ($search === false)
{
- return $this->user->lang['LDAP_SEARCH_FAILED'];
+ return $this->language->lang('LDAP_SEARCH_FAILED');
}
$result = @ldap_get_entries($ldap, $search);
@@ -101,12 +112,12 @@ class ldap extends \phpbb\auth\provider\base
if (!is_array($result) || count($result) < 2)
{
- return sprintf($this->user->lang['LDAP_NO_IDENTITY'], $this->user->data['username']);
+ return $this->language->lang('LDAP_NO_IDENTITY', $this->user->data['username']);
}
if (!empty($this->config['ldap_email']) && !isset($result[0][htmlspecialchars_decode($this->config['ldap_email'])]))
{
- return $this->user->lang['LDAP_NO_EMAIL'];
+ return $this->language->lang('LDAP_NO_EMAIL');
}
return false;
@@ -245,7 +256,7 @@ class ldap extends \phpbb\auth\provider\base
// generate user account data
$ldap_user_row = array(
'username' => $username,
- 'user_password' => $this->passwords_manager->hash($password),
+ 'user_password' => '',
'user_email' => (!empty($this->config['ldap_email'])) ? utf8_htmlspecialchars($ldap_result[0][htmlspecialchars_decode($this->config['ldap_email'])][0]) : '',
'group_id' => (int) $row['group_id'],
'user_type' => USER_NORMAL,
diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php
index e3f8394bba..29ffe6d591 100644
--- a/phpBB/phpbb/auth/provider/oauth/oauth.php
+++ b/phpBB/phpbb/auth/provider/oauth/oauth.php
@@ -1,169 +1,137 @@
<?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.
-*
-*/
+ *
+ * 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\auth\provider\oauth;
+use OAuth\Common\Http\Exception\TokenResponseException;
+use OAuth\ServiceFactory;
use OAuth\Common\Consumer\Credentials;
+use OAuth\Common\Service\ServiceInterface;
+use OAuth\OAuth1\Service\AbstractService as OAuth1Service;
+use OAuth\OAuth2\Service\AbstractService as OAuth2Service;
+use phpbb\auth\provider\base;
+use phpbb\auth\provider\db;
+use phpbb\auth\provider\oauth\service\exception;
+use phpbb\config\config;
+use phpbb\db\driver\driver_interface;
+use phpbb\di\service_collection;
+use phpbb\event\dispatcher;
+use phpbb\language\language;
+use phpbb\request\request_interface;
+use phpbb\user;
/**
-* OAuth authentication provider for phpBB3
-*/
-class oauth extends \phpbb\auth\provider\base
+ * OAuth authentication provider for phpBB3
+ */
+class oauth extends base
{
- /**
- * Database driver
- *
- * @var \phpbb\db\driver\driver_interface
- */
- protected $db;
-
- /**
- * phpBB config
- *
- * @var \phpbb\config\config
- */
+ /** @var config */
protected $config;
- /**
- * phpBB passwords manager
- *
- * @var \phpbb\passwords\manager
- */
- protected $passwords_manager;
-
- /**
- * phpBB request object
- *
- * @var \phpbb\request\request_interface
- */
- protected $request;
+ /** @var driver_interface */
+ protected $db;
- /**
- * phpBB user
- *
- * @var \phpbb\user
- */
- protected $user;
+ /** @var db */
+ protected $db_auth;
- /**
- * OAuth token table
- *
- * @var string
- */
- protected $auth_provider_oauth_token_storage_table;
+ /** @var dispatcher */
+ protected $dispatcher;
- /**
- * OAuth state table
- *
- * @var string
- */
- protected $auth_provider_oauth_state_table;
+ /** @var language */
+ protected $language;
- /**
- * OAuth account association table
- *
- * @var string
- */
- protected $auth_provider_oauth_token_account_assoc;
+ /** @var request_interface */
+ protected $request;
- /**
- * All OAuth service providers
- *
- * @var \phpbb\di\service_collection Contains \phpbb\auth\provider\oauth\service_interface
- */
+ /** @var service_collection */
protected $service_providers;
- /**
- * Users table
- *
- * @var string
- */
- protected $users_table;
+ /** @var user */
+ protected $user;
- /**
- * Cached current uri object
- *
- * @var \OAuth\Common\Http\Uri\UriInterface|null
- */
- protected $current_uri;
+ /** @var string OAuth table: token storage */
+ protected $oauth_token_table;
- /**
- * DI container
- *
- * @var \Symfony\Component\DependencyInjection\ContainerInterface
- */
- protected $phpbb_container;
+ /** @var string OAuth table: state */
+ protected $oauth_state_table;
- /**
- * phpBB event dispatcher
- *
- * @var \phpbb\event\dispatcher_interface
- */
- protected $dispatcher;
+ /** @var string OAuth table: account association */
+ protected $oauth_account_table;
- /**
- * phpBB root path
- *
- * @var string
- */
- protected $phpbb_root_path;
+ /** @var string Users table */
+ protected $users_table;
- /**
- * PHP file extension
- *
- * @var string
- */
+ /** @var string phpBB root path */
+ protected $root_path;
+
+ /** @var string php File extension */
protected $php_ext;
/**
- * OAuth Authentication Constructor
- *
- * @param \phpbb\db\driver\driver_interface $db
- * @param \phpbb\config\config $config
- * @param \phpbb\passwords\manager $passwords_manager
- * @param \phpbb\request\request_interface $request
- * @param \phpbb\user $user
- * @param string $auth_provider_oauth_token_storage_table
- * @param string $auth_provider_oauth_state_table
- * @param string $auth_provider_oauth_token_account_assoc
- * @param \phpbb\di\service_collection $service_providers Contains \phpbb\auth\provider\oauth\service_interface
- * @param string $users_table
- * @param \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container DI container
- * @param \phpbb\event\dispatcher_interface $dispatcher phpBB event dispatcher
- * @param string $phpbb_root_path
- * @param string $php_ext
- */
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_state_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, \phpbb\event\dispatcher_interface $dispatcher, $phpbb_root_path, $php_ext)
+ * Constructor.
+ *
+ * @param config $config Config object
+ * @param driver_interface $db Database object
+ * @param db $db_auth DB auth provider
+ * @param dispatcher $dispatcher Event dispatcher object
+ * @param language $language Language object
+ * @param request_interface $request Request object
+ * @param service_collection $service_providers OAuth providers service collection
+ * @param user $user User object
+ * @param string $oauth_token_table OAuth table: token storage
+ * @param string $oauth_state_table OAuth table: state
+ * @param string $oauth_account_table OAuth table: account association
+ * @param string $users_table User table
+ * @param string $root_path phpBB root path
+ * @param string $php_ext php File extension
+ */
+ public function __construct(
+ config $config,
+ driver_interface $db,
+ db $db_auth,
+ dispatcher $dispatcher,
+ language $language,
+ request_interface $request,
+ service_collection $service_providers,
+ user $user,
+ $oauth_token_table,
+ $oauth_state_table,
+ $oauth_account_table,
+ $users_table,
+ $root_path,
+ $php_ext
+ )
{
- $this->db = $db;
- $this->config = $config;
- $this->passwords_manager = $passwords_manager;
- $this->request = $request;
- $this->user = $user;
- $this->auth_provider_oauth_token_storage_table = $auth_provider_oauth_token_storage_table;
- $this->auth_provider_oauth_state_table = $auth_provider_oauth_state_table;
- $this->auth_provider_oauth_token_account_assoc = $auth_provider_oauth_token_account_assoc;
- $this->service_providers = $service_providers;
- $this->users_table = $users_table;
- $this->phpbb_container = $phpbb_container;
- $this->dispatcher = $dispatcher;
- $this->phpbb_root_path = $phpbb_root_path;
- $this->php_ext = $php_ext;
+ $this->config = $config;
+ $this->db = $db;
+ $this->db_auth = $db_auth;
+ $this->dispatcher = $dispatcher;
+ $this->language = $language;
+ $this->service_providers = $service_providers;
+ $this->request = $request;
+ $this->user = $user;
+
+ $this->oauth_token_table = $oauth_token_table;
+ $this->oauth_state_table = $oauth_state_table;
+ $this->oauth_account_table = $oauth_account_table;
+ $this->users_table = $users_table;
+ $this->root_path = $root_path;
+ $this->php_ext = $php_ext;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function init()
{
// This does not test whether or not the key and secret provided are valid.
@@ -173,61 +141,85 @@ class oauth extends \phpbb\auth\provider\base
if (($credentials['key'] && !$credentials['secret']) || (!$credentials['key'] && $credentials['secret']))
{
- return $this->user->lang['AUTH_PROVIDER_OAUTH_ERROR_ELEMENT_MISSING'];
+ return $this->language->lang('AUTH_PROVIDER_OAUTH_ERROR_ELEMENT_MISSING');
}
}
+
return false;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function login($username, $password)
{
// Temporary workaround for only having one authentication provider available
if (!$this->request->is_set('oauth_service'))
{
- $provider = new \phpbb\auth\provider\db($this->db, $this->config, $this->passwords_manager, $this->request, $this->user, $this->phpbb_container, $this->phpbb_root_path, $this->php_ext);
- return $provider->login($username, $password);
+ return $this->db_auth->login($username, $password);
}
// Request the name of the OAuth service
- $service_name_original = $this->request->variable('oauth_service', '', false);
- $service_name = 'auth.provider.oauth.service.' . strtolower($service_name_original);
- if ($service_name_original === '' || !array_key_exists($service_name, $this->service_providers))
+ $provider = $this->request->variable('oauth_service', '', false);
+ $service_name = $this->get_service_name($provider);
+
+ if ($provider === '' || !array_key_exists($service_name, $this->service_providers))
{
- return array(
+ return [
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LOGIN_ERROR_OAUTH_SERVICE_DOES_NOT_EXIST',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
+ 'user_row' => ['user_id' => ANONYMOUS],
+ ];
}
// Get the service credentials for the given service
- $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
+ $storage = new token_storage($this->db, $this->user, $this->oauth_token_table, $this->oauth_state_table);
+ $query = 'mode=login&login=external&oauth_service=' . $provider;
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
- $query = 'mode=login&login=external&oauth_service=' . $service_name_original;
- $service = $this->get_service($service_name_original, $storage, $service_credentials, $query, $this->service_providers[$service_name]->get_auth_scope());
+ try
+ {
+ /** @var OAuth1Service|OAuth2Service $service */
+ $service = $this->get_service($provider, $storage, $query);
+ }
+ catch (\Exception $e)
+ {
+ return [
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => $e->getMessage(),
+ 'user_row' => ['user_id' => ANONYMOUS],
+ ];
+ }
- if (($service::OAUTH_VERSION === 2 && $this->request->is_set('code', \phpbb\request\request_interface::GET))
- || ($service::OAUTH_VERSION === 1 && $this->request->is_set('oauth_token', \phpbb\request\request_interface::GET)))
+ if ($this->is_set_code($service))
{
$this->service_providers[$service_name]->set_external_service_provider($service);
- $unique_id = $this->service_providers[$service_name]->perform_auth_login();
+
+ try
+ {
+ $unique_id = $this->service_providers[$service_name]->perform_auth_login();
+ }
+ catch (exception $e)
+ {
+ return [
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => $e->getMessage(),
+ 'user_row' => ['user_id' => ANONYMOUS],
+ ];
+ }
/**
* Check to see if this provider is already associated with an account.
*
- * Enforcing a data type to make data contains strings and not integers,
+ * Enforcing a data type to make sure it are strings and not integers,
* so values are quoted in the SQL WHERE statement.
*/
- $data = array(
- 'provider' => (string) $service_name_original,
+ $data = [
+ 'provider' => (string) utf8_strtolower($provider),
'oauth_provider_id' => (string) $unique_id
- );
+ ];
- $sql = 'SELECT user_id FROM ' . $this->auth_provider_oauth_token_account_assoc . '
+ $sql = 'SELECT user_id
+ FROM ' . $this->oauth_account_table . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
@@ -235,204 +227,134 @@ class oauth extends \phpbb\auth\provider\base
$redirect_data = array(
'auth_provider' => 'oauth',
- 'login_link_oauth_service' => $service_name_original,
+ 'login_link_oauth_service' => $provider,
);
/**
- * Event is triggered before check if provider is already associated with an account
- *
- * @event core.oauth_login_after_check_if_provider_id_has_match
- * @var array row User row
- * @var array data Provider data
- * @var array redirect_data Data to be appended to the redirect url
- * @var \OAuth\Common\Service\ServiceInterface service OAuth service
- * @since 3.2.3-RC1
- * @changed 3.2.6-RC1 Added redirect_data
- */
- $vars = array(
+ * Event is triggered before check if provider is already associated with an account
+ *
+ * @event core.oauth_login_after_check_if_provider_id_has_match
+ * @var array row User row
+ * @var array data Provider data
+ * @var array redirect_data Data to be appended to the redirect url
+ * @var ServiceInterface service OAuth service
+ * @since 3.2.3-RC1
+ * @changed 3.2.6-RC1 Added redirect_data
+ */
+ $vars = [
'row',
'data',
'redirect_data',
'service',
- );
+ ];
extract($this->dispatcher->trigger_event('core.oauth_login_after_check_if_provider_id_has_match', compact($vars)));
if (!$row)
{
// The user does not yet exist, ask to link or create profile
- return array(
+ return [
'status' => LOGIN_SUCCESS_LINK_PROFILE,
'error_msg' => 'LOGIN_OAUTH_ACCOUNT_NOT_LINKED',
- 'user_row' => array(),
+ 'user_row' => [],
'redirect_data' => $redirect_data,
- );
+ ];
}
// Retrieve the user's account
$sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_ip, user_type, user_login_attempts
FROM ' . $this->users_table . '
- WHERE user_id = ' . (int) $row['user_id'];
+ WHERE user_id = ' . (int) $row['user_id'];
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if (!$row)
{
- throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY');
+ return [
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => 'AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY',
+ 'user_row' => ['user_id' => ANONYMOUS],
+ ];
}
/**
* Check if the user is banned.
- * The fourth parameter, return, has to be true,
- * otherwise the OAuth login is still called and
- * an uncaught exception is thrown as there is no
- * token stored in the database.
+ * The fourth parameter (return) has to be true, otherwise the OAuth login is still called and
+ * an uncaught exception is thrown as there is no token stored in the database.
*/
$ban = $this->user->check_ban($row['user_id'], $row['user_ip'], $row['user_email'], true);
+
if (!empty($ban))
{
$till_date = !empty($ban['ban_end']) ? $this->user->format_date($ban['ban_end']) : '';
$message = !empty($ban['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM';
- $contact_link = phpbb_get_board_contact_link($this->config, $this->phpbb_root_path, $this->php_ext);
- $message = $this->user->lang($message, $till_date, '<a href="' . $contact_link . '">', '</a>');
- $message .= !empty($ban['ban_give_reason']) ? '<br /><br />' . $this->user->lang('BOARD_BAN_REASON', $ban['ban_give_reason']) : '';
- $message .= !empty($ban['ban_triggered_by']) ? '<br /><br /><em>' . $this->user->lang('BAN_TRIGGERED_BY_' . strtoupper($ban['ban_triggered_by'])) . '</em>' : '';
+ $contact_link = phpbb_get_board_contact_link($this->config, $this->root_path, $this->php_ext);
+
+ $message = $this->language->lang($message, $till_date, '<a href="' . $contact_link . '">', '</a>');
+ $message .= !empty($ban['ban_give_reason']) ? '<br /><br />' . $this->language->lang('BOARD_BAN_REASON', $ban['ban_give_reason']) : '';
+ $message .= !empty($ban['ban_triggered_by']) ? '<br /><br /><em>' . $this->language->lang('BAN_TRIGGERED_BY_' . utf8_strtoupper($ban['ban_triggered_by'])) . '</em>' : '';
- return array(
+ return [
'status' => LOGIN_BREAK,
'error_msg' => $message,
'user_row' => $row,
- );
+ ];
}
// Update token storage to store the user_id
$storage->set_user_id($row['user_id']);
/**
- * Event is triggered after user is successfully logged in via OAuth.
- *
- * @event core.auth_oauth_login_after
- * @var array row User row
- * @since 3.1.11-RC1
- */
- $vars = array(
+ * Event is triggered after user is successfully logged in via OAuth.
+ *
+ * @event core.auth_oauth_login_after
+ * @var array row User row
+ * @since 3.1.11-RC1
+ */
+ $vars = [
'row',
- );
+ ];
extract($this->dispatcher->trigger_event('core.auth_oauth_login_after', compact($vars)));
// The user is now authenticated and can be logged in
- return array(
+ return [
'status' => LOGIN_SUCCESS,
'error_msg' => false,
'user_row' => $row,
- );
+ ];
}
else
{
- if ($service::OAUTH_VERSION === 1)
- {
- $token = $service->requestRequestToken();
- $url = $service->getAuthorizationUri(array('oauth_token' => $token->getRequestToken()));
- }
- else
- {
- $url = $service->getAuthorizationUri();
- }
- header('Location: ' . $url);
- }
- }
-
- /**
- * Returns the cached current_uri object or creates and caches it if it is
- * not already created. In each case the query string is updated based on
- * the $query parameter.
- *
- * @param string $service_name The name of the service
- * @param string $query The query string of the current_uri
- * used in redirects
- * @return \OAuth\Common\Http\Uri\UriInterface
- */
- protected function get_current_uri($service_name, $query)
- {
- if ($this->current_uri)
- {
- $this->current_uri->setQuery($query);
- return $this->current_uri;
- }
-
- $uri_factory = new \OAuth\Common\Http\Uri\UriFactory();
- $super_globals = $this->request->get_super_global(\phpbb\request\request_interface::SERVER);
- if (!empty($super_globals['HTTP_X_FORWARDED_PROTO']) && $super_globals['HTTP_X_FORWARDED_PROTO'] === 'https')
- {
- $super_globals['HTTPS'] = 'on';
- $super_globals['SERVER_PORT'] = 443;
- }
- $current_uri = $uri_factory->createFromSuperGlobalArray($super_globals);
- $current_uri->setQuery($query);
-
- $this->current_uri = $current_uri;
- return $current_uri;
- }
-
- /**
- * Returns a new service object
- *
- * @param string $service_name The name of the service
- * @param \phpbb\auth\provider\oauth\token_storage $storage
- * @param array $service_credentials {@see \phpbb\auth\provider\oauth\oauth::get_service_credentials}
- * @param string $query The query string of the
- * current_uri used in redirection
- * @param array $scopes The scope of the request against
- * the api.
- * @return \OAuth\Common\Service\ServiceInterface
- * @throws \Exception
- */
- protected function get_service($service_name, \phpbb\auth\provider\oauth\token_storage $storage, array $service_credentials, $query, array $scopes = array())
- {
- $current_uri = $this->get_current_uri($service_name, $query);
-
- // Setup the credentials for the requests
- $credentials = new Credentials(
- $service_credentials['key'],
- $service_credentials['secret'],
- $current_uri->getAbsoluteUri()
- );
-
- $service_factory = new \OAuth\ServiceFactory();
- $service = $service_factory->createService($service_name, $credentials, $storage, $scopes);
-
- if (!$service)
- {
- throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED');
+ return $this->set_redirect($service);
}
-
- return $service;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_login_data()
{
- $login_data = array(
+ $login_data = [
'TEMPLATE_FILE' => 'login_body_oauth.html',
'BLOCK_VAR_NAME' => 'oauth',
- 'BLOCK_VARS' => array(),
- );
+ 'BLOCK_VARS' => [],
+ ];
foreach ($this->service_providers as $service_name => $service_provider)
{
// Only include data if the credentials are set
$credentials = $service_provider->get_service_credentials();
+
if ($credentials['key'] && $credentials['secret'])
{
- $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
- $redirect_url = generate_board_url() . '/ucp.' . $this->php_ext . '?mode=login&login=external&oauth_service=' . $actual_name;
- $login_data['BLOCK_VARS'][$service_name] = array(
+ $provider = $this->get_provider($service_name);
+ $redirect_url = generate_board_url() . '/ucp.' . $this->php_ext . '?mode=login&login=external&oauth_service=' . $provider;
+
+ $login_data['BLOCK_VARS'][$service_name] = [
'REDIRECT_URL' => redirect($redirect_url, true),
- 'SERVICE_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
- );
+ 'SERVICE_NAME' => $this->get_provider_title($provider),
+ ];
}
}
@@ -440,51 +362,55 @@ class oauth extends \phpbb\auth\provider\base
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function acp()
{
- $ret = array();
+ $ret = [];
foreach ($this->service_providers as $service_name => $service_provider)
{
- $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
- $ret[] = 'auth_oauth_' . $actual_name . '_key';
- $ret[] = 'auth_oauth_' . $actual_name . '_secret';
+ $provider = $this->get_provider($service_name);
+
+ $provider = utf8_strtolower($provider);
+
+ $ret[] = 'auth_oauth_' . $provider . '_key';
+ $ret[] = 'auth_oauth_' . $provider . '_secret';
}
return $ret;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_acp_template($new_config)
{
- $ret = array(
+ $ret = [
'BLOCK_VAR_NAME' => 'oauth_services',
- 'BLOCK_VARS' => array(),
+ 'BLOCK_VARS' => [],
'TEMPLATE_FILE' => 'auth_provider_oauth.html',
- 'TEMPLATE_VARS' => array(),
- );
+ 'TEMPLATE_VARS' => [],
+ ];
foreach ($this->service_providers as $service_name => $service_provider)
{
- $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
- $ret['BLOCK_VARS'][$actual_name] = array(
- 'ACTUAL_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
- 'KEY' => $new_config['auth_oauth_' . $actual_name . '_key'],
- 'NAME' => $actual_name,
- 'SECRET' => $new_config['auth_oauth_' . $actual_name . '_secret'],
- );
+ $provider = $this->get_provider($service_name);
+
+ $ret['BLOCK_VARS'][$provider] = [
+ 'NAME' => $provider,
+ 'ACTUAL_NAME' => $this->get_provider_title($provider),
+ 'KEY' => $new_config['auth_oauth_' . utf8_strtolower($provider) . '_key'],
+ 'SECRET' => $new_config['auth_oauth_' . utf8_strtolower($provider) . '_secret'],
+ ];
}
return $ret;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function login_link_has_necessary_data($login_link_data)
{
if (empty($login_link_data))
@@ -502,16 +428,13 @@ class oauth extends \phpbb\auth\provider\base
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function link_account(array $link_data)
{
// Check for a valid link method (auth_link or login_link)
if (!array_key_exists('link_method', $link_data) ||
- !in_array($link_data['link_method'], array(
- 'auth_link',
- 'login_link',
- )))
+ !in_array($link_data['link_method'], ['auth_link', 'login_link']))
{
return 'LOGIN_LINK_MISSING_DATA';
}
@@ -527,7 +450,8 @@ class oauth extends \phpbb\auth\provider\base
}
}
- $service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']);
+ $service_name = $this->get_service_name($link_data['oauth_service']);
+
if (!array_key_exists($service_name, $this->service_providers))
{
return 'LOGIN_ERROR_OAUTH_SERVICE_DOES_NOT_EXIST';
@@ -539,21 +463,109 @@ class oauth extends \phpbb\auth\provider\base
return $this->link_account_auth_link($link_data, $service_name);
case 'login_link':
return $this->link_account_login_link($link_data, $service_name);
+ default:
+ return 'LOGIN_LINK_MISSING_DATA';
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function logout($data, $new_session)
+ {
+ // Clear all tokens belonging to the user
+ $storage = new token_storage($this->db, $this->user, $this->oauth_token_table, $this->oauth_state_table);
+ $storage->clearAllTokens();
+
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_auth_link_data($user_id = 0)
+ {
+ $user_ids = [];
+ $block_vars = [];
+
+ $sql = 'SELECT oauth_provider_id, provider
+ FROM ' . $this->oauth_account_table . '
+ WHERE user_id = ' . ($user_id > 0 ? (int) $user_id : (int) $this->user->data['user_id']);
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $user_ids[$row['provider']] = $row['oauth_provider_id'];
+ }
+ $this->db->sql_freeresult($result);
+
+ foreach ($this->service_providers as $service_name => $service_provider)
+ {
+ // Only include data if the credentials are set
+ $credentials = $service_provider->get_service_credentials();
+
+ if ($credentials['key'] && $credentials['secret'])
+ {
+ $provider = $this->get_provider($service_name);
+
+ $block_vars[$service_name] = [
+ 'SERVICE_NAME' => $this->get_provider_title($provider),
+ 'UNIQUE_ID' => isset($user_ids[$provider]) ? $user_ids[$provider] : null,
+ 'HIDDEN_FIELDS' => [
+ 'link' => !isset($user_ids[$provider]),
+ 'oauth_service' => $provider,
+ ],
+ ];
+ }
+ }
+
+ return [
+ 'BLOCK_VAR_NAME' => 'oauth',
+ 'BLOCK_VARS' => $block_vars,
+
+ 'TEMPLATE_FILE' => 'ucp_auth_link_oauth.html',
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unlink_account(array $link_data)
+ {
+ if (!array_key_exists('oauth_service', $link_data) || !$link_data['oauth_service'])
+ {
+ return 'LOGIN_LINK_MISSING_DATA';
}
+
+ // Remove user specified in $link_data if possible
+ $user_id = isset($link_data['user_id']) ? $link_data['user_id'] : $this->user->data['user_id'];
+
+ // Remove the link
+ $sql = 'DELETE FROM ' . $this->oauth_account_table . "
+ WHERE provider = '" . $this->db->sql_escape($link_data['oauth_service']) . "'
+ AND user_id = " . (int) $user_id;
+ $this->db->sql_query($sql);
+
+ $service_name = $this->get_service_name($link_data['oauth_service']);
+
+ // Clear all tokens belonging to the user on this service
+ $storage = new token_storage($this->db, $this->user, $this->oauth_token_table, $this->oauth_state_table);
+ $storage->clearToken($service_name);
+
+ return false;
}
/**
- * Performs the account linking for login_link
- *
- * @param array $link_data The same variable given to {@see \phpbb\auth\provider\provider_interface::link_account}
- * @param string $service_name The name of the service being used in
- * linking.
- * @return string|null Returns a language constant (string) if an error is
- * encountered, or null on success.
- */
+ * Performs the account linking for login_link.
+ *
+ * @param array $link_data The same variable given to
+ * {@see \phpbb\auth\provider\provider_interface::link_account}
+ * @param string $service_name The name of the service being used in linking.
+ * @return string|false Returns a language key (string) if an error is encountered,
+ * or false on success.
+ */
protected function link_account_login_link(array $link_data, $service_name)
{
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
+ $storage = new token_storage($this->db, $this->user, $this->oauth_token_table, $this->oauth_state_table);
// Check for an access token, they should have one
if (!$storage->has_access_token_by_session($service_name))
@@ -561,87 +573,109 @@ class oauth extends \phpbb\auth\provider\base
return 'LOGIN_LINK_ERROR_OAUTH_NO_ACCESS_TOKEN';
}
- // Prepare the query string
- $query = 'mode=login_link&login_link_oauth_service=' . strtolower($link_data['oauth_service']);
-
// Prepare for an authentication request
- $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
- $scopes = $this->service_providers[$service_name]->get_auth_scope();
- $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $query, $scopes);
+ $query = 'mode=login_link&login_link_oauth_service=' . $link_data['oauth_service'];
+
+ try
+ {
+ $service = $this->get_service($link_data['oauth_service'], $storage, $query);
+ }
+ catch (\Exception $e)
+ {
+ return $e->getMessage();
+ }
+
$this->service_providers[$service_name]->set_external_service_provider($service);
- // The user has already authenticated successfully, request to authenticate again
- $unique_id = $this->service_providers[$service_name]->perform_token_auth();
+ try
+ {
+ // The user has already authenticated successfully, request to authenticate again
+ $unique_id = $this->service_providers[$service_name]->perform_token_auth();
+ }
+ catch (exception $e)
+ {
+ return $e->getMessage();
+ }
// Insert into table, they will be able to log in after this
- $data = array(
+ $data = [
'user_id' => $link_data['user_id'],
- 'provider' => strtolower($link_data['oauth_service']),
+ 'provider' => utf8_strtolower($link_data['oauth_service']),
'oauth_provider_id' => $unique_id,
- );
+ ];
$this->link_account_perform_link($data);
+
// Update token storage to store the user_id
$storage->set_user_id($link_data['user_id']);
+
+ return false;
}
/**
- * Performs the account linking for auth_link
- *
- * @param array $link_data The same variable given to {@see \phpbb\auth\provider\provider_interface::link_account}
- * @param string $service_name The name of the service being used in
- * linking.
- * @return string|null Returns a language constant (string) if an error is
- * encountered, or null on success.
- */
+ * Performs the account linking for auth_link.
+ *
+ * @param array $link_data The same variable given to
+ * {@see \phpbb\auth\provider\provider_interface::link_account}
+ * @param string $service_name The name of the service being used in linking.
+ * @return string|false Returns a language constant (string) if an error is encountered,
+ * or false on success.
+ */
protected function link_account_auth_link(array $link_data, $service_name)
{
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
- $query = 'i=ucp_auth_link&mode=auth_link&link=1&oauth_service=' . strtolower($link_data['oauth_service']);
- $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
- $scopes = $this->service_providers[$service_name]->get_auth_scope();
- $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $query, $scopes);
+ $storage = new token_storage($this->db, $this->user, $this->oauth_token_table, $this->oauth_state_table);
+ $query = 'i=ucp_auth_link&mode=auth_link&link=1&oauth_service=' . $link_data['oauth_service'];
- if (($service::OAUTH_VERSION === 2 && $this->request->is_set('code', \phpbb\request\request_interface::GET))
- || ($service::OAUTH_VERSION === 1 && $this->request->is_set('oauth_token', \phpbb\request\request_interface::GET)))
+ try
+ {
+ /** @var OAuth1Service|OAuth2Service $service */
+ $service = $this->get_service($link_data['oauth_service'], $storage, $query);
+ }
+ catch (\Exception $e)
+ {
+ return $e->getMessage();
+ }
+
+ if ($this->is_set_code($service))
{
$this->service_providers[$service_name]->set_external_service_provider($service);
- $unique_id = $this->service_providers[$service_name]->perform_auth_login();
+
+ try
+ {
+ $unique_id = $this->service_providers[$service_name]->perform_auth_login();
+ }
+ catch (exception $e)
+ {
+ return $e->getMessage();
+ }
// Insert into table, they will be able to log in after this
- $data = array(
+ $data = [
'user_id' => $this->user->data['user_id'],
- 'provider' => strtolower($link_data['oauth_service']),
+ 'provider' => utf8_strtolower($link_data['oauth_service']),
'oauth_provider_id' => $unique_id,
- );
+ ];
$this->link_account_perform_link($data);
+
+ return false;
}
else
{
- if ($service::OAUTH_VERSION === 1)
- {
- $token = $service->requestRequestToken();
- $url = $service->getAuthorizationUri(array('oauth_token' => $token->getRequestToken()));
- }
- else
- {
- $url = $service->getAuthorizationUri();
- }
- header('Location: ' . $url);
+ return $this->set_redirect($service);
}
}
/**
- * Performs the query that inserts an account link
- *
- * @param array $data This array is passed to db->sql_build_array
- */
+ * Performs the query that inserts an account link
+ *
+ * @param array $data This array is passed to db->sql_build_array
+ */
protected function link_account_perform_link(array $data)
{
// Check if the external account is already associated with other user
$sql = 'SELECT user_id
- FROM ' . $this->auth_provider_oauth_token_account_assoc . "
+ FROM ' . $this->oauth_account_table . "
WHERE provider = '" . $this->db->sql_escape($data['provider']) . "'
AND oauth_provider_id = '" . $this->db->sql_escape($data['oauth_provider_id']) . "'";
$result = $this->db->sql_query($sql);
@@ -654,114 +688,172 @@ class oauth extends \phpbb\auth\provider\base
}
// Link account
- $sql = 'INSERT INTO ' . $this->auth_provider_oauth_token_account_assoc . '
- ' . $this->db->sql_build_array('INSERT', $data);
+ $sql = 'INSERT INTO ' . $this->oauth_account_table . ' ' . $this->db->sql_build_array('INSERT', $data);
$this->db->sql_query($sql);
/**
* Event is triggered after user links account.
*
* @event core.auth_oauth_link_after
- * @var array data User row
+ * @var array data User row
* @since 3.1.11-RC1
*/
- $vars = array(
+ $vars = [
'data',
- );
+ ];
extract($this->dispatcher->trigger_event('core.auth_oauth_link_after', compact($vars)));
}
/**
- * {@inheritdoc}
- */
- public function logout($data, $new_session)
+ * Returns a new service object.
+ *
+ * @param string $provider The name of the provider
+ * @param token_storage $storage Token storage object
+ * @param string $query The query string used for the redirect uri
+ * @return ServiceInterface
+ * @throws exception When OAuth service was not created
+ */
+ protected function get_service($provider, token_storage $storage, $query)
{
- // Clear all tokens belonging to the user
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
- $storage->clearAllTokens();
+ $service_name = $this->get_service_name($provider);
- return;
- }
+ /** @see \phpbb\auth\provider\oauth\service\service_interface::get_service_credentials */
+ $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
- /**
- * {@inheritdoc}
- */
- public function get_auth_link_data($user_id = 0)
- {
- $block_vars = array();
+ /** @see \phpbb\auth\provider\oauth\service\service_interface::get_auth_scope */
+ $scopes = $this->service_providers[$service_name]->get_auth_scope();
- // Get all external accounts tied to the current user
- $data = array(
- 'user_id' => ($user_id <= 0) ? (int) $this->user->data['user_id'] : (int) $user_id,
+ $callback = generate_board_url() . "/ucp.{$this->php_ext}?{$query}";
+
+ // Setup the credentials for the requests
+ $credentials = new Credentials(
+ $service_credentials['key'],
+ $service_credentials['secret'],
+ $callback
);
- $sql = 'SELECT oauth_provider_id, provider FROM ' . $this->auth_provider_oauth_token_account_assoc . '
- WHERE ' . $this->db->sql_build_array('SELECT', $data);
- $result = $this->db->sql_query($sql);
- $rows = $this->db->sql_fetchrowset($result);
- $this->db->sql_freeresult($result);
- $oauth_user_ids = array();
+ $service_factory = new ServiceFactory;
- if ($rows !== false && count($rows))
+ // Allow providers to register a custom class or override the provider name
+ if ($class = $this->service_providers[$service_name]->get_external_service_class())
{
- foreach ($rows as $row)
+ if (class_exists($class))
+ {
+ try
+ {
+ $service_factory->registerService($provider, $class);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ }
+ }
+ else
{
- $oauth_user_ids[$row['provider']] = $row['oauth_provider_id'];
+ $provider = $class;
}
}
- unset($rows);
- foreach ($this->service_providers as $service_name => $service_provider)
+ $service = $service_factory->createService($provider, $credentials, $storage, $scopes);
+
+ if (!$service)
{
- // Only include data if the credentials are set
- $credentials = $service_provider->get_service_credentials();
- if ($credentials['key'] && $credentials['secret'])
- {
- $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
-
- $block_vars[$service_name] = array(
- 'HIDDEN_FIELDS' => array(
- 'link' => (!isset($oauth_user_ids[$actual_name])),
- 'oauth_service' => $actual_name,
- ),
-
- 'SERVICE_ID' => $actual_name,
- 'SERVICE_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
- 'UNIQUE_ID' => (isset($oauth_user_ids[$actual_name])) ? $oauth_user_ids[$actual_name] : null,
- );
- }
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED');
}
- return array(
- 'BLOCK_VAR_NAME' => 'oauth',
- 'BLOCK_VARS' => $block_vars,
+ return $service;
+ }
- 'TEMPLATE_FILE' => 'ucp_auth_link_oauth.html',
- );
+ /**
+ * Returns the service name for an OAuth provider name.
+ *
+ * @param string $provider The OAuth provider name
+ * @return string The service name
+ */
+ protected function get_service_name($provider)
+ {
+ if (strpos($provider, 'auth.provider.oauth.service.') !== 0)
+ {
+ $provider = 'auth.provider.oauth.service.' . utf8_strtolower($provider);
+ }
+
+ return $provider;
}
/**
- * {@inheritdoc}
- */
- public function unlink_account(array $link_data)
+ * Returns the OAuth provider name from a service name.
+ *
+ * @param string $service_name The service name
+ * @return string The OAuth provider name
+ */
+ protected function get_provider($service_name)
{
- if (!array_key_exists('oauth_service', $link_data) || !$link_data['oauth_service'])
+ return str_replace('auth.provider.oauth.service.', '', $service_name);
+ }
+
+ /**
+ * Returns the localized title for the OAuth provider.
+ *
+ * @param string $provider The OAuth provider name
+ * @return string The OAuth provider title
+ */
+ protected function get_provider_title($provider)
+ {
+ return $this->language->lang('AUTH_PROVIDER_OAUTH_SERVICE_' . utf8_strtoupper($provider));
+ }
+
+ /**
+ * Returns whether or not the authorization code is set.
+ *
+ * @param OAuth1Service|OAuth2Service $service The external OAuth service
+ * @return bool Whether or not the authorization code is set in the URL
+ * for the respective OAuth service's version
+ */
+ protected function is_set_code($service)
+ {
+ switch ($service::OAUTH_VERSION)
{
- return 'LOGIN_LINK_MISSING_DATA';
+ case 1:
+ return $this->request->is_set('oauth_token', request_interface::GET);
+
+ case 2:
+ return $this->request->is_set('code', request_interface::GET);
+
+ default:
+ return false;
}
+ }
- // Remove user specified in $link_data if possible
- $user_id = isset($link_data['user_id']) ? $link_data['user_id'] : $this->user->data['user_id'];
+ /**
+ * Sets a redirect to the authorization uri.
+ *
+ * @param OAuth1Service|OAuth2Service $service The external OAuth service
+ * @return array|false Array if an error occurred,
+ * false on success
+ */
+ protected function set_redirect($service)
+ {
+ $parameters = [];
- // Remove the link
- $sql = 'DELETE FROM ' . $this->auth_provider_oauth_token_account_assoc . "
- WHERE provider = '" . $this->db->sql_escape($link_data['oauth_service']) . "'
- AND user_id = " . (int) $user_id;
- $this->db->sql_query($sql);
+ if ($service::OAUTH_VERSION === 1)
+ {
+ try
+ {
+ $token = $service->requestRequestToken();
+ $parameters = ['oauth_token' => $token->getRequestToken()];
+ }
+ catch (TokenResponseException $e)
+ {
+ return [
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => $e->getMessage(),
+ 'user_row' => ['user_id' => ANONYMOUS],
+ ];
+ }
+ }
- // Clear all tokens belonging to the user on this service
- $service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']);
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
- $storage->clearToken($service_name);
+ redirect($service->getAuthorizationUri($parameters), false, true);
+
+ return false;
}
}
diff --git a/phpBB/phpbb/auth/provider/oauth/service/base.php b/phpBB/phpbb/auth/provider/oauth/service/base.php
index 6adf64aa30..5ab426a0aa 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/base.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/base.php
@@ -1,49 +1,57 @@
<?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.
-*
-*/
+ *
+ * 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\auth\provider\oauth\service;
/**
-* Base OAuth abstract class that all OAuth services should implement
-*/
-abstract class base implements \phpbb\auth\provider\oauth\service\service_interface
+ * Base OAuth abstract class that all OAuth services should implement
+ */
+abstract class base implements service_interface
{
/**
- * External OAuth service provider
- *
- * @var \OAuth\Common\Service\ServiceInterface
- */
+ * External OAuth service provider
+ *
+ * @var \OAuth\Common\Service\ServiceInterface
+ */
protected $service_provider;
/**
- * {@inheritdoc}
- */
- public function get_external_service_provider()
+ * {@inheritdoc}
+ */
+ public function get_auth_scope()
{
- return $this->service_provider;
+ return [];
}
/**
- * {@inheritdoc}
- */
- public function get_auth_scope()
+ * {@inheritdoc}
+ */
+ public function get_external_service_class()
+ {
+ return '';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_external_service_provider()
{
- return array();
+ return $this->service_provider;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function set_external_service_provider(\OAuth\Common\Service\ServiceInterface $service_provider)
{
$this->service_provider = $service_provider;
diff --git a/phpBB/phpbb/auth/provider/oauth/service/bitly.php b/phpBB/phpbb/auth/provider/oauth/service/bitly.php
index 25e731a02c..ca131b2019 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/bitly.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/bitly.php
@@ -1,94 +1,107 @@
<?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.
-*
-*/
+ *
+ * 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\auth\provider\oauth\service;
/**
-* Bitly OAuth service
-*/
-class bitly extends \phpbb\auth\provider\oauth\service\base
+ * Bitly OAuth service
+ */
+class bitly extends base
{
- /**
- * phpBB config
- *
- * @var \phpbb\config\config
- */
+ /** @var \phpbb\config\config */
protected $config;
- /**
- * phpBB request
- *
- * @var \phpbb\request\request_interface
- */
+ /** @var \phpbb\request\request_interface */
protected $request;
/**
- * Constructor
- *
- * @param \phpbb\config\config $config
- * @param \phpbb\request\request_interface $request
- */
+ * Constructor.
+ *
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\request\request_interface $request Request object
+ */
public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
{
- $this->config = $config;
- $this->request = $request;
+ $this->config = $config;
+ $this->request = $request;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_service_credentials()
{
- return array(
+ return [
'key' => $this->config['auth_oauth_bitly_key'],
'secret' => $this->config['auth_oauth_bitly_secret'],
- );
+ ];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_auth_login()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Bitly))
{
- throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // This was a callback request from bitly, get the token
- $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ try
+ {
+ // This was a callback request, get the token
+ $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ }
+ catch (\OAuth\Common\Http\Exception\TokenResponseException $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
- // Send a request with it
- $result = json_decode($this->service_provider->request('user/info'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('user/info'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Return the unique identifier returned from bitly
return $result['data']['login'];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_token_auth()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Bitly))
{
- throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // Send a request with it
- $result = json_decode($this->service_provider->request('user/info'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('user/info'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
- // Return the unique identifier returned from bitly
+ // Return the unique identifier
return $result['data']['login'];
}
}
diff --git a/phpBB/phpbb/auth/provider/oauth/service/facebook.php b/phpBB/phpbb/auth/provider/oauth/service/facebook.php
index bb98835e07..f7dbe307eb 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/facebook.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/facebook.php
@@ -1,63 +1,55 @@
<?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.
-*
-*/
+ *
+ * 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\auth\provider\oauth\service;
/**
-* Facebook OAuth service
-*/
+ * Facebook OAuth service
+ */
class facebook extends base
{
- /**
- * phpBB config
- *
- * @var \phpbb\config\config
- */
+ /** @var \phpbb\config\config */
protected $config;
- /**
- * phpBB request
- *
- * @var \phpbb\request\request_interface
- */
+ /** @var \phpbb\request\request_interface */
protected $request;
/**
- * Constructor
- *
- * @param \phpbb\config\config $config
- * @param \phpbb\request\request_interface $request
- */
+ * Constructor.
+ *
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\request\request_interface $request Request object
+ */
public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
{
- $this->config = $config;
- $this->request = $request;
+ $this->config = $config;
+ $this->request = $request;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_service_credentials()
{
- return array(
+ return [
'key' => $this->config['auth_oauth_facebook_key'],
'secret' => $this->config['auth_oauth_facebook_secret'],
- );
+ ];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_auth_login()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Facebook))
@@ -65,19 +57,33 @@ class facebook extends base
throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // This was a callback request, get the token
- $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ try
+ {
+ // This was a callback request, get the token
+ $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ }
+ catch (\OAuth\Common\Http\Exception\TokenResponseException $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
- // Send a request with it
- $result = json_decode($this->service_provider->request('/me'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('/me'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Return the unique identifier
return $result['id'];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_token_auth()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Facebook))
@@ -85,8 +91,15 @@ class facebook extends base
throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // Send a request with it
- $result = json_decode($this->service_provider->request('/me'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('/me'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Return the unique identifier
return $result['id'];
diff --git a/phpBB/phpbb/auth/provider/oauth/service/google.php b/phpBB/phpbb/auth/provider/oauth/service/google.php
index cb9f83a94f..6e671ab13e 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/google.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/google.php
@@ -1,74 +1,66 @@
<?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.
-*
-*/
+ *
+ * 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\auth\provider\oauth\service;
/**
-* Google OAuth service
-*/
+ * Google OAuth service
+ */
class google extends base
{
- /**
- * phpBB config
- *
- * @var \phpbb\config\config
- */
+ /** @var \phpbb\config\config */
protected $config;
- /**
- * phpBB request
- *
- * @var \phpbb\request\request_interface
- */
+ /** @var \phpbb\request\request_interface */
protected $request;
/**
- * Constructor
- *
- * @param \phpbb\config\config $config
- * @param \phpbb\request\request_interface $request
- */
+ * Constructor.
+ *
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\request\request_interface $request Request object
+ */
public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
{
- $this->config = $config;
- $this->request = $request;
+ $this->config = $config;
+ $this->request = $request;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_auth_scope()
{
- return array(
+ return [
'userinfo_email',
'userinfo_profile',
- );
+ ];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_service_credentials()
{
- return array(
+ return [
'key' => $this->config['auth_oauth_google_key'],
'secret' => $this->config['auth_oauth_google_secret'],
- );
+ ];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_auth_login()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Google))
@@ -76,19 +68,33 @@ class google extends base
throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // This was a callback request, get the token
- $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ try
+ {
+ // This was a callback request, get the token
+ $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ }
+ catch (\OAuth\Common\Http\Exception\TokenResponseException $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
- // Send a request with it
- $result = json_decode($this->service_provider->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Return the unique identifier
return $result['id'];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_token_auth()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Google))
@@ -96,8 +102,15 @@ class google extends base
throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // Send a request with it
- $result = json_decode($this->service_provider->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Return the unique identifier
return $result['id'];
diff --git a/phpBB/phpbb/auth/provider/oauth/service/service_interface.php b/phpBB/phpbb/auth/provider/oauth/service/service_interface.php
index e84eb247b6..ea9ef43788 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/service_interface.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/service_interface.php
@@ -1,73 +1,87 @@
<?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.
-*
-*/
+ *
+ * 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\auth\provider\oauth\service;
/**
-* OAuth service interface
-*/
+ * OAuth service interface
+ */
interface service_interface
{
/**
- * Returns an array of the scopes necessary for auth
- *
- * @return array An array of the required scopes
- */
+ * Returns an array of the scopes necessary for auth
+ *
+ * @return array An array of the required scopes
+ */
public function get_auth_scope();
/**
- * Returns the external library service provider once it has been set
- *
- * @param \OAuth\Common\Service\ServiceInterface|null
- */
- public function get_external_service_provider();
-
- /**
- * Returns an array containing the service credentials belonging to requested
- * service.
- *
- * @return array An array containing the 'key' and the 'secret' of the
- * service in the form:
- * array(
- * 'key' => string
- * 'secret' => string
- * )
- */
+ * Returns an array containing the service credentials belonging to requested
+ * service.
+ *
+ * @return array An array containing the 'key' and the 'secret' of the
+ * service in the form:
+ * array(
+ * 'key' => string
+ * 'secret' => string
+ * )
+ */
public function get_service_credentials();
/**
- * Returns the results of the authentication in json format
- *
- * @throws \phpbb\auth\provider\oauth\service\exception
- * @return string The unique identifier returned by the service provider
- * that is used to authenticate the user with phpBB.
- */
+ * Returns the results of the authentication in json format
+ *
+ * @throws \phpbb\auth\provider\oauth\service\exception
+ * @return string The unique identifier returned by the service provider
+ * that is used to authenticate the user with phpBB.
+ */
public function perform_auth_login();
/**
- * Returns the results of the authentication in json format
- * Use this function when the user already has an access token
- *
- * @throws \phpbb\auth\provider\oauth\service\exception
- * @return string The unique identifier returned by the service provider
- * that is used to authenticate the user with phpBB.
- */
+ * Returns the results of the authentication in json format
+ * Use this function when the user already has an access token
+ *
+ * @throws \phpbb\auth\provider\oauth\service\exception
+ * @return string The unique identifier returned by the service provider
+ * that is used to authenticate the user with phpBB.
+ */
public function perform_token_auth();
/**
- * Sets the external library service provider
- *
- * @param \OAuth\Common\Service\ServiceInterface $service_provider
- */
+ * Returns the class of external library service provider that has to be used.
+ *
+ * @return string If the string is a class, it will register the provided string as a class,
+ * which later will be generated as the OAuth external service provider.
+ * If the string is not a class, it will use this string,
+ * trying to generate a service for the version 2 and 1 respectively:
+ * \OAuth\OAuth2\Service\<string>
+ * If the string is empty, it will default to OAuth's standard service classes,
+ * trying to generate a service for the version 2 and 1 respectively:
+ * \OAuth\OAuth2\Service\Facebook
+ */
+ public function get_external_service_class();
+
+ /**
+ * Returns the external library service provider once it has been set
+ *
+ * @param \OAuth\Common\Service\ServiceInterface|null
+ */
+ public function get_external_service_provider();
+
+ /**
+ * Sets the external library service provider
+ *
+ * @param \OAuth\Common\Service\ServiceInterface $service_provider
+ */
public function set_external_service_provider(\OAuth\Common\Service\ServiceInterface $service_provider);
}
diff --git a/phpBB/phpbb/auth/provider/oauth/service/twitter.php b/phpBB/phpbb/auth/provider/oauth/service/twitter.php
index 06beac51e2..35cbc9e4f7 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/twitter.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/twitter.php
@@ -1,102 +1,111 @@
<?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.
-*
-*/
+ *
+ * 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\auth\provider\oauth\service;
/**
-* Twitter OAuth service
-*/
-class twitter extends \phpbb\auth\provider\oauth\service\base
+ * Twitter OAuth service
+ */
+class twitter extends base
{
- /**
- * phpBB config
- *
- * @var \phpbb\config\config
- */
+ /** @var \phpbb\config\config */
protected $config;
- /**
- * phpBB request
- *
- * @var \phpbb\request\request_interface
- */
+ /** @var \phpbb\request\request_interface */
protected $request;
/**
- * Constructor
- *
- * @param \phpbb\config\config $config
- * @param \phpbb\request\request_interface $request
- */
+ * Constructor.
+ *
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\request\request_interface $request Request object
+ */
public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
{
- $this->config = $config;
- $this->request = $request;
+ $this->config = $config;
+ $this->request = $request;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_service_credentials()
{
- return array(
+ return [
'key' => $this->config['auth_oauth_twitter_key'],
'secret' => $this->config['auth_oauth_twitter_secret'],
- );
+ ];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_auth_login()
{
if (!($this->service_provider instanceof \OAuth\OAuth1\Service\Twitter))
{
- throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
$storage = $this->service_provider->getStorage();
- $token = $storage->retrieveAccessToken('Twitter');
- $tokensecret = $token->getRequestTokenSecret();
- // This was a callback request from twitter, get the token
- $this->service_provider->requestAccessToken(
- $this->request->variable('oauth_token', ''),
- $this->request->variable('oauth_verifier', ''),
- $tokensecret
- );
+ try
+ {
+ /** @var \OAuth\OAuth1\Token\TokenInterface $token */
+ $token = $storage->retrieveAccessToken('Twitter');
+ }
+ catch (\OAuth\Common\Storage\Exception\TokenNotFoundException $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
+
+ $secret = $token->getRequestTokenSecret();
+
+ try
+ {
+ // This was a callback request, get the token
+ $this->service_provider->requestAccessToken(
+ $this->request->variable('oauth_token', ''),
+ $this->request->variable('oauth_verifier', ''),
+ $secret
+ );
+ }
+ catch (\OAuth\Common\Http\Exception\TokenResponseException $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Send a request with it
- $result = json_decode($this->service_provider->request('account/verify_credentials.json'), true);
+ $result = (array) json_decode($this->service_provider->request('account/verify_credentials.json'), true);
- // Return the unique identifier returned from twitter
+ // Return the unique identifier
return $result['id'];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_token_auth()
{
if (!($this->service_provider instanceof \OAuth\OAuth1\Service\Twitter))
{
- throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
// Send a request with it
- $result = json_decode($this->service_provider->request('account/verify_credentials.json'), true);
+ $result = (array) json_decode($this->service_provider->request('account/verify_credentials.json'), true);
- // Return the unique identifier returned from twitter
+ // Return the unique identifier
return $result['id'];
}
}
diff --git a/phpBB/phpbb/auth/provider/oauth/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php
index b0c2fd0d62..c0f585d7bb 100644
--- a/phpBB/phpbb/auth/provider/oauth/token_storage.php
+++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php
@@ -1,15 +1,15 @@
<?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.
-*
-*/
+ *
+ * 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\auth\provider\oauth;
@@ -20,67 +20,48 @@ use OAuth\Common\Storage\Exception\TokenNotFoundException;
use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
/**
-* OAuth storage wrapper for phpbb's cache
-*/
+ * OAuth storage wrapper for phpBB's cache
+ */
class token_storage implements TokenStorageInterface
{
- /**
- * Cache driver.
- *
- * @var \phpbb\db\driver\driver_interface
- */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
- /**
- * phpBB user
- *
- * @var \phpbb\user
- */
+ /** @var \phpbb\user */
protected $user;
- /**
- * OAuth token table
- *
- * @var string
- */
+ /** @var string OAuth table: token storage */
protected $oauth_token_table;
- /**
- * OAuth state table
- *
- * @var string
- */
+ /** @var string OAuth table: state */
protected $oauth_state_table;
- /**
- * @var object|TokenInterface
- */
+ /** @var TokenInterface OAuth token */
protected $cachedToken;
- /**
- * @var string
- */
+ /** @var string OAuth state */
protected $cachedState;
/**
- * Creates token storage for phpBB.
- *
- * @param \phpbb\db\driver\driver_interface $db
- * @param \phpbb\user $user
- * @param string $oauth_token_table
- * @param string $oauth_state_table
- */
+ * Constructor.
+ *
+ * @param \phpbb\db\driver\driver_interface $db Database object
+ * @param \phpbb\user $user User object
+ * @param string $oauth_token_table OAuth table: token storage
+ * @param string $oauth_state_table OAuth table: state
+ */
public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $oauth_token_table, $oauth_state_table)
{
- $this->db = $db;
- $this->user = $user;
+ $this->db = $db;
+ $this->user = $user;
+
$this->oauth_token_table = $oauth_token_table;
$this->oauth_state_table = $oauth_state_table;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function retrieveAccessToken($service)
{
$service = $this->get_service_name_for_db($service);
@@ -90,10 +71,10 @@ class token_storage implements TokenStorageInterface
return $this->cachedToken;
}
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
- );
+ ];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
{
@@ -104,33 +85,38 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function storeAccessToken($service, TokenInterface $token)
{
$service = $this->get_service_name_for_db($service);
$this->cachedToken = $token;
- $data = array(
+ $data = [
'oauth_token' => $this->json_encode_token($token),
- );
+ ];
$sql = 'UPDATE ' . $this->oauth_token_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $data) . '
- WHERE user_id = ' . (int) $this->user->data['user_id'] . '
- ' . ((int) $this->user->data['user_id'] === ANONYMOUS ? "AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'" : '') . "
- AND provider = '" . $this->db->sql_escape($service) . "'";
+ SET ' . $this->db->sql_build_array('UPDATE', $data) . '
+ WHERE user_id = ' . (int) $this->user->data['user_id'] . "
+ AND provider = '" . $this->db->sql_escape($service) . "'";
+
+ if ((int) $this->user->data['user_id'] === ANONYMOUS)
+ {
+ $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
+ }
+
$this->db->sql_query($sql);
if (!$this->db->sql_affectedrows())
{
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
'oauth_token' => $this->json_encode_token($token),
'session_id' => $this->user->data['session_id'],
- );
+ ];
$sql = 'INSERT INTO ' . $this->oauth_token_table . $this->db->sql_build_array('INSERT', $data);
@@ -141,8 +127,8 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function hasAccessToken($service)
{
$service = $this->get_service_name_for_db($service);
@@ -152,22 +138,22 @@ class token_storage implements TokenStorageInterface
return true;
}
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
- );
+ ];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
{
$data['session_id'] = $this->user->data['session_id'];
}
- return $this->_has_acess_token($data);
+ return $this->has_access_token($data);
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function clearToken($service)
{
$service = $this->get_service_name_for_db($service);
@@ -189,13 +175,13 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function clearAllTokens()
{
$this->cachedToken = null;
- $sql = 'DELETE FROM ' . $this->oauth_token_table . '
+ $sql = 'DELETE FROM ' . $this->oauth_token_table . '
WHERE user_id = ' . (int) $this->user->data['user_id'];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
@@ -209,31 +195,30 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function storeAuthorizationState($service, $state)
{
$service = $this->get_service_name_for_db($service);
$this->cachedState = $state;
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
'oauth_state' => $state,
'session_id' => $this->user->data['session_id'],
- );
+ ];
- $sql = 'INSERT INTO ' . $this->oauth_state_table . '
- ' . $this->db->sql_build_array('INSERT', $data);
+ $sql = 'INSERT INTO ' . $this->oauth_state_table . ' ' . $this->db->sql_build_array('INSERT', $data);
$this->db->sql_query($sql);
return $this;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function hasAuthorizationState($service)
{
$service = $this->get_service_name_for_db($service);
@@ -243,10 +228,10 @@ class token_storage implements TokenStorageInterface
return true;
}
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
- );
+ ];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
{
@@ -257,8 +242,8 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function retrieveAuthorizationState($service)
{
$service = $this->get_service_name_for_db($service);
@@ -268,10 +253,10 @@ class token_storage implements TokenStorageInterface
return $this->cachedState;
}
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
- );
+ ];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
{
@@ -282,8 +267,8 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function clearAuthorizationState($service)
{
$service = $this->get_service_name_for_db($service);
@@ -305,8 +290,8 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function clearAllAuthorizationStates()
{
$this->cachedState = null;
@@ -325,10 +310,11 @@ class token_storage implements TokenStorageInterface
}
/**
- * Updates the user_id field in the database assosciated with the token
- *
- * @param int $user_id
- */
+ * Updates the user_id field in the database associated with the token.
+ *
+ * @param int $user_id The user identifier
+ * @return void
+ */
public function set_user_id($user_id)
{
if (!$this->cachedToken)
@@ -336,21 +322,24 @@ class token_storage implements TokenStorageInterface
return;
}
+ $data = [
+ 'user_id' => (int) $user_id,
+ ];
+
$sql = 'UPDATE ' . $this->oauth_token_table . '
- SET ' . $this->db->sql_build_array('UPDATE', array(
- 'user_id' => (int) $user_id
- )) . '
- WHERE user_id = ' . (int) $this->user->data['user_id'] . "
- AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
+ SET ' . $this->db->sql_build_array('UPDATE', $data) . '
+ WHERE user_id = ' . (int) $this->user->data['user_id'] . "
+ AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
$this->db->sql_query($sql);
}
/**
- * Checks to see if an access token exists solely by the session_id of the user
- *
- * @param string $service The name of the OAuth service
- * @return bool true if they have token, false if they don't
- */
+ * Checks to see if an access token exists solely by the session_id of the user.
+ *
+ * @param string $service The OAuth service name
+ * @return bool true if the user's access token exists,
+ * false if the user's access token does not exist
+ */
public function has_access_token_by_session($service)
{
$service = $this->get_service_name_for_db($service);
@@ -360,20 +349,21 @@ class token_storage implements TokenStorageInterface
return true;
}
- $data = array(
+ $data = [
'session_id' => $this->user->data['session_id'],
'provider' => $service,
- );
+ ];
- return $this->_has_acess_token($data);
+ return $this->has_access_token($data);
}
/**
- * Checks to see if a state exists solely by the session_id of the user
- *
- * @param string $service The name of the OAuth service
- * @return bool true if they have state, false if they don't
- */
+ * Checks to see if a state exists solely by the session_id of the user.
+ *
+ * @param string $service The OAuth service name
+ * @return bool true if the user's state exists,
+ * false if the user's state does not exist
+ */
public function has_state_by_session($service)
{
$service = $this->get_service_name_for_db($service);
@@ -383,25 +373,34 @@ class token_storage implements TokenStorageInterface
return true;
}
- $data = array(
+ $data = [
'session_id' => $this->user->data['session_id'],
'provider' => $service,
- );
+ ];
return (bool) $this->get_state_row($data);
}
/**
- * A helper function that performs the query for has access token functions
- *
- * @param array $data
- * @return bool
- */
- protected function _has_acess_token($data)
+ * A helper function that performs the query for has access token functions.
+ *
+ * @param array $data The SQL WHERE data
+ * @return bool true if the user's access token exists,
+ * false if the user's access token does not exist
+ */
+ protected function has_access_token($data)
{
return (bool) $this->get_access_token_row($data);
}
+ /**
+ * A helper function that performs the query for retrieving access token functions by session.
+ * Also checks if the token is a valid token.
+ *
+ * @param string $service The OAuth service provider name
+ * @return TokenInterface
+ * @throws TokenNotFoundException
+ */
public function retrieve_access_token_by_session($service)
{
$service = $this->get_service_name_for_db($service);
@@ -411,14 +410,21 @@ class token_storage implements TokenStorageInterface
return $this->cachedToken;
}
- $data = array(
+ $data = [
'session_id' => $this->user->data['session_id'],
- 'provider' => $service,
- );
+ 'provider' => $service,
+ ];
return $this->_retrieve_access_token($data);
}
+ /**
+ * A helper function that performs the query for retrieving state functions by session.
+ *
+ * @param string $service The OAuth service provider name
+ * @return string The OAuth state
+ * @throws AuthorizationStateNotFoundException
+ */
public function retrieve_state_by_session($service)
{
$service = $this->get_service_name_for_db($service);
@@ -428,22 +434,22 @@ class token_storage implements TokenStorageInterface
return $this->cachedState;
}
- $data = array(
+ $data = [
'session_id' => $this->user->data['session_id'],
- 'provider' => $service,
- );
+ 'provider' => $service,
+ ];
return $this->_retrieve_state($data);
}
/**
- * A helper function that performs the query for retrieve access token functions
- * Also checks if the token is a valid token
- *
- * @param array $data
- * @return mixed
- * @throws \OAuth\Common\Storage\Exception\TokenNotFoundException
- */
+ * A helper function that performs the query for retrieve access token functions.
+ * Also checks if the token is a valid token.
+ *
+ * @param array $data The SQL WHERE data
+ * @return TokenInterface
+ * @throws TokenNotFoundException
+ */
protected function _retrieve_access_token($data)
{
$row = $this->get_access_token_row($data);
@@ -459,19 +465,21 @@ class token_storage implements TokenStorageInterface
if (!($token instanceof TokenInterface))
{
$this->clearToken($data['provider']);
+
throw new TokenNotFoundException('AUTH_PROVIDER_OAUTH_TOKEN_ERROR_INCORRECTLY_STORED');
}
$this->cachedToken = $token;
+
return $token;
}
/**
- * A helper function that performs the query for retrieve state functions
+ * A helper function that performs the query for retrieve state functions.
*
- * @param array $data
- * @return mixed
- * @throws \OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException
+ * @param array $data The SQL WHERE data
+ * @return string The OAuth state
+ * @throws AuthorizationStateNotFoundException
*/
protected function _retrieve_state($data)
{
@@ -483,18 +491,21 @@ class token_storage implements TokenStorageInterface
}
$this->cachedState = $row['oauth_state'];
+
return $this->cachedState;
}
/**
- * A helper function that performs the query for retrieving an access token
- *
- * @param array $data
- * @return mixed
- */
+ * A helper function that performs the query for retrieving an access token.
+ *
+ * @param array $data The SQL WHERE data
+ * @return array|false array with the OAuth token row,
+ * false if the token does not exist
+ */
protected function get_access_token_row($data)
{
- $sql = 'SELECT oauth_token FROM ' . $this->oauth_token_table . '
+ $sql = 'SELECT oauth_token
+ FROM ' . $this->oauth_token_table . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
@@ -504,14 +515,16 @@ class token_storage implements TokenStorageInterface
}
/**
- * A helper function that performs the query for retrieving a state
+ * A helper function that performs the query for retrieving a state.
*
- * @param array $data
- * @return mixed
+ * @param array $data The SQL WHERE data
+ * @return array|false array with the OAuth state row,
+ * false if the state does not exist
*/
protected function get_state_row($data)
{
- $sql = 'SELECT oauth_state FROM ' . $this->oauth_state_table . '
+ $sql = 'SELECT oauth_state
+ FROM ' . $this->oauth_state_table . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
@@ -520,16 +533,22 @@ class token_storage implements TokenStorageInterface
return $row;
}
+ /**
+ * A helper function that JSON encodes a TokenInterface's data.
+ *
+ * @param TokenInterface $token
+ * @return string The json encoded TokenInterface's data
+ */
public function json_encode_token(TokenInterface $token)
{
- $members = array(
+ $members = [
'accessToken' => $token->getAccessToken(),
'endOfLife' => $token->getEndOfLife(),
'extraParams' => $token->getExtraParams(),
'refreshToken' => $token->getRefreshToken(),
'token_class' => get_class($token),
- );
+ ];
// Handle additional data needed for OAuth1 tokens
if ($token instanceof StdOAuth1Token)
@@ -542,6 +561,13 @@ class token_storage implements TokenStorageInterface
return json_encode($members);
}
+ /**
+ * A helper function that JSON decodes a data string and creates a TokenInterface.
+ *
+ * @param string $json The json encoded TokenInterface's data
+ * @return TokenInterface
+ * @throws TokenNotFoundException
+ */
public function json_decode_token($json)
{
$token_data = json_decode($json, true);
@@ -557,7 +583,10 @@ class token_storage implements TokenStorageInterface
$endOfLife = $token_data['endOfLife'];
$extra_params = $token_data['extraParams'];
- // Create the token
+ /**
+ * Create the token
+ * @var TokenInterface $token
+ */
$token = new $token_class($access_token, $refresh_token, TokenInterface::EOL_NEVER_EXPIRES, $extra_params);
$token->setEndOfLife($endOfLife);
@@ -573,20 +602,19 @@ class token_storage implements TokenStorageInterface
}
/**
- * Returns the name of the service as it must be stored in the database.
- *
- * @param string $service The name of the OAuth service
- * @return string The name of the OAuth service as it needs to be stored
- * in the database.
- */
- protected function get_service_name_for_db($service)
+ * Returns the service name as it must be stored in the database.
+ *
+ * @param string $provider The OAuth provider name
+ * @return string The OAuth service name
+ */
+ protected function get_service_name_for_db($provider)
{
// Enforce the naming convention for oauth services
- if (strpos($service, 'auth.provider.oauth.service.') !== 0)
+ if (strpos($provider, 'auth.provider.oauth.service.') !== 0)
{
- $service = 'auth.provider.oauth.service.' . strtolower($service);
+ $provider = 'auth.provider.oauth.service.' . strtolower($provider);
}
- return $service;
+ return $provider;
}
}
diff --git a/phpBB/phpbb/auth/provider/provider_interface.php b/phpBB/phpbb/auth/provider/provider_interface.php
index 463324ff46..21c73a33c5 100644
--- a/phpBB/phpbb/auth/provider/provider_interface.php
+++ b/phpBB/phpbb/auth/provider/provider_interface.php
@@ -53,7 +53,7 @@ interface provider_interface
* Autologin function
*
* @return array|null containing the user row, empty if no auto login
- * should take place, or null if not impletmented.
+ * should take place, or null if not implemented.
*/
public function autologin();
@@ -68,7 +68,7 @@ interface provider_interface
/**
* This function updates the template with variables related to the acp
- * options with whatever configuraton values are passed to it as an array.
+ * options with whatever configuration values are passed to it as an array.
* It then returns the name of the acp file related to this authentication
* provider.
*
diff --git a/phpBB/phpbb/cache/driver/memcache.php b/phpBB/phpbb/cache/driver/memcache.php
deleted file mode 100644
index 57f138f574..0000000000
--- a/phpBB/phpbb/cache/driver/memcache.php
+++ /dev/null
@@ -1,122 +0,0 @@
-<?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_MEMCACHE_PORT'))
-{
- define('PHPBB_ACM_MEMCACHE_PORT', 11211);
-}
-
-if (!defined('PHPBB_ACM_MEMCACHE_COMPRESS'))
-{
- define('PHPBB_ACM_MEMCACHE_COMPRESS', false);
-}
-
-if (!defined('PHPBB_ACM_MEMCACHE_HOST'))
-{
- define('PHPBB_ACM_MEMCACHE_HOST', 'localhost');
-}
-
-if (!defined('PHPBB_ACM_MEMCACHE'))
-{
- //can define multiple servers with host1/port1,host2/port2 format
- define('PHPBB_ACM_MEMCACHE', PHPBB_ACM_MEMCACHE_HOST . '/' . PHPBB_ACM_MEMCACHE_PORT);
-}
-
-/**
-* ACM for Memcached
-*/
-class memcache extends \phpbb\cache\driver\memory
-{
- var $extension = 'memcache';
-
- var $memcache;
- var $flags = 0;
-
- function __construct()
- {
- // Call the parent constructor
- parent::__construct();
-
- $this->memcache = new \Memcache;
- foreach (explode(',', PHPBB_ACM_MEMCACHE) as $u)
- {
- preg_match('#(.*)/(\d+)#', $u, $parts);
- $this->memcache->addServer(trim($parts[1]), (int) trim($parts[2]));
- }
- $this->flags = (PHPBB_ACM_MEMCACHE_COMPRESS) ? MEMCACHE_COMPRESSED : 0;
- }
-
- /**
- * {@inheritDoc}
- */
- function unload()
- {
- parent::unload();
-
- $this->memcache->close();
- }
-
- /**
- * {@inheritDoc}
- */
- function purge()
- {
- $this->memcache->flush();
-
- parent::purge();
- }
-
- /**
- * Fetch an item from the cache
- *
- * @access protected
- * @param string $var Cache key
- * @return mixed Cached data
- */
- function _read($var)
- {
- return $this->memcache->get($this->key_prefix . $var);
- }
-
- /**
- * Store data in the cache
- *
- * @access protected
- * @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
- */
- function _write($var, $data, $ttl = 2592000)
- {
- if (!$this->memcache->replace($this->key_prefix . $var, $data, $this->flags, $ttl))
- {
- return $this->memcache->set($this->key_prefix . $var, $data, $this->flags, $ttl);
- }
- return true;
- }
-
- /**
- * Remove an item from the cache
- *
- * @access protected
- * @param string $var Cache key
- * @return bool True if the operation succeeded
- */
- function _delete($var)
- {
- return $this->memcache->delete($this->key_prefix . $var);
- }
-}
diff --git a/phpBB/phpbb/cache/driver/memcached.php b/phpBB/phpbb/cache/driver/memcached.php
index 7d66759ec2..fbb587a369 100644
--- a/phpBB/phpbb/cache/driver/memcached.php
+++ b/phpBB/phpbb/cache/driver/memcached.php
@@ -50,12 +50,16 @@ class memcached extends \phpbb\cache\driver\memory
/**
* Memcached constructor
+ *
+ * @param string $memcached_servers Memcached servers string (optional)
*/
- public function __construct()
+ public function __construct($memcached_servers = '')
{
// Call the parent constructor
parent::__construct();
+ $memcached_servers = $memcached_servers ?: PHPBB_ACM_MEMCACHED;
+
$this->memcached = new \Memcached();
$this->memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
// Memcached defaults to using compression, disable if we don't want
@@ -65,10 +69,20 @@ class memcached extends \phpbb\cache\driver\memory
$this->memcached->setOption(\Memcached::OPT_COMPRESSION, false);
}
- foreach (explode(',', PHPBB_ACM_MEMCACHED) as $u)
+ $server_list = [];
+ foreach (explode(',', $memcached_servers) as $u)
+ {
+ if (preg_match('#(.*)/(\d+)#', $u, $parts))
+ {
+ $server_list[] = [trim($parts[1]), (int) trim($parts[2])];
+ }
+ }
+
+ $this->memcached->addServers($server_list);
+
+ if (empty($server_list) || empty($this->memcached->getStats()))
{
- preg_match('#(.*)/(\d+)#', $u, $parts);
- $this->memcached->addServer(trim($parts[1]), (int) trim($parts[2]));
+ trigger_error('Could not connect to memcached server(s).');
}
}
diff --git a/phpBB/phpbb/captcha/non_gd.php b/phpBB/phpbb/captcha/non_gd.php
index 3818672f17..8105187ed9 100644
--- a/phpBB/phpbb/captcha/non_gd.php
+++ b/phpBB/phpbb/captcha/non_gd.php
@@ -78,7 +78,7 @@ class non_gd
for ($j = 0; $j < $code_len; $j++)
{
- $image .= $this->randomise(substr($hold_chars[$code{$j}][$i - $offset_y - 1], 1), $char_widths[$j]);
+ $image .= $this->randomise(substr($hold_chars[$code[$j]][$i - $offset_y - 1], 1), $char_widths[$j]);
}
for ($j = $offset_x + $img_width; $j < $this->width; $j++)
@@ -117,7 +117,7 @@ class non_gd
$end = strlen($scanline) - ceil($width/2);
for ($i = (int) floor($width / 2); $i < $end; $i++)
{
- $pixel = ord($scanline{$i});
+ $pixel = ord($scanline[$i]);
if ($pixel < 190)
{
@@ -129,7 +129,7 @@ class non_gd
}
else
{
- $new_line .= $scanline{$i};
+ $new_line .= $scanline[$i];
}
}
diff --git a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
deleted file mode 100644
index 6f7096296d..0000000000
--- a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-namespace phpbb\console\command\fixup;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Style\SymfonyStyle;
-
-class recalculate_email_hash extends \phpbb\console\command\command
-{
- /** @var \phpbb\db\driver\driver_interface */
- protected $db;
-
- public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db)
- {
- $this->db = $db;
-
- parent::__construct($user);
- }
-
- protected function configure()
- {
- $this
- ->setName('fixup:recalculate-email-hash')
- ->setDescription($this->user->lang('CLI_DESCRIPTION_RECALCULATE_EMAIL_HASH'))
- ;
- }
-
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- $io = new SymfonyStyle($input, $output);
-
- $sql = 'SELECT user_id, user_email, user_email_hash
- FROM ' . USERS_TABLE . '
- WHERE user_type <> ' . USER_IGNORE . "
- AND user_email <> ''";
- $result = $this->db->sql_query($sql);
-
- while ($row = $this->db->sql_fetchrow($result))
- {
- $user_email_hash = phpbb_email_hash($row['user_email']);
- if ($user_email_hash !== $row['user_email_hash'])
- {
- $sql_ary = array(
- 'user_email_hash' => $user_email_hash,
- );
-
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . '
- WHERE user_id = ' . (int) $row['user_id'];
- $this->db->sql_query($sql);
-
- if ($output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG)
- {
- $io->table(
- array('user_id', 'user_email', 'user_email_hash'),
- array(array($row['user_id'], $row['user_email'], $user_email_hash))
- );
- }
- }
- }
- $this->db->sql_freeresult($result);
-
- $io->success($this->user->lang('CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS'));
- }
-}
diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php
index 704ec6badb..fbc56f3db2 100644
--- a/phpBB/phpbb/content_visibility.php
+++ b/phpBB/phpbb/content_visibility.php
@@ -144,7 +144,14 @@ class content_visibility
*/
public function is_visible($mode, $forum_id, $data)
{
- $is_visible = $this->auth->acl_get('m_approve', $forum_id) || $data[$mode . '_visibility'] == ITEM_APPROVED;
+ $visibility = $data[$mode . '_visibility'];
+ $poster_key = ($mode === 'topic') ? 'topic_poster' : 'poster_id';
+ $is_visible = ($visibility == ITEM_APPROVED) ||
+ ($this->config['display_unapproved_posts'] &&
+ ($this->user->data['user_id'] != ANONYMOUS) &&
+ ($visibility == ITEM_UNAPPROVED || $visibility == ITEM_REAPPROVE) &&
+ ($this->user->data['user_id'] == $data[$poster_key])) ||
+ $this->auth->acl_get('m_approve', $forum_id);
/**
* Allow changing the result of calling is_visible
@@ -216,9 +223,16 @@ class content_visibility
}
else
{
- $where_sql .= $table_alias . $mode . '_visibility = ' . ITEM_APPROVED;
- }
+ $visibility_query = $table_alias . $mode . '_visibility = ';
+ $where_sql .= '(' . $visibility_query . ITEM_APPROVED . ')';
+ if ($this->config['display_unapproved_posts'] && ($this->user->data['user_id'] != ANONYMOUS))
+ {
+ $poster_key = ($mode === 'topic') ? 'topic_poster' : 'poster_id';
+ $where_sql .= ' OR ((' . $visibility_query . ITEM_UNAPPROVED . ' OR ' . $visibility_query . ITEM_REAPPROVE .')';
+ $where_sql .= ' AND ' . $table_alias . $poster_key . ' = ' . ((int) $this->user->data['user_id']) . ')';
+ }
+ }
return '(' . $where_sql . ')';
}
diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/migration/data/v330/add_display_unapproved_posts_config.php
index 4d1b91f7b4..b429270827 100644
--- a/phpBB/phpbb/db/tools.php
+++ b/phpBB/phpbb/db/migration/data/v330/add_display_unapproved_posts_config.php
@@ -11,11 +11,14 @@
*
*/
-namespace phpbb\db;
+namespace phpbb\db\migration\data\v330;
-/**
- * @deprecated 3.2.0-dev (To be removed 3.3.0) use \phpbb\db\tools\tools instead
- */
-class tools extends \phpbb\db\tools\tools
+class add_display_unapproved_posts_config extends \phpbb\db\migration\migration
{
+ public function update_data()
+ {
+ return [
+ ['config.add', ['display_unapproved_posts', 1]],
+ ];
+ }
}
diff --git a/phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php b/phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php
new file mode 100644
index 0000000000..c5a4beef38
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php
@@ -0,0 +1,49 @@
+<?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\v330;
+
+class forums_legend_limit extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return $this->db_tools->sql_column_exists($this->table_prefix . 'forums', 'display_subforum_limit');
+ }
+
+ static public function depends_on()
+ {
+ return ['\phpbb\db\migration\data\v330\v330b1'];
+ }
+
+ public function update_schema()
+ {
+ return [
+ 'add_columns' => [
+ $this->table_prefix . 'forums' => [
+ 'display_subforum_limit' => ['BOOL', 0, 'after' => 'display_subforum_list'],
+ ],
+ ],
+ ];
+ }
+
+ public function revert_schema()
+ {
+ return [
+ 'drop_columns' => [
+ $this->table_prefix . 'forums' => [
+ 'display_subforum_limit',
+ ],
+ ],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v330/remove_email_hash.php b/phpBB/phpbb/db/migration/data/v330/remove_email_hash.php
new file mode 100644
index 0000000000..dc43678625
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/remove_email_hash.php
@@ -0,0 +1,57 @@
+<?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\v330;
+
+class remove_email_hash extends \phpbb\db\migration\migration
+{
+ public function update_schema()
+ {
+ return [
+ 'add_index' => [
+ $this->table_prefix . 'users' => [
+ 'user_email' => ['user_email'],
+ ],
+ ],
+ 'drop_keys' => [
+ $this->table_prefix . 'users' => [
+ 'user_email_hash',
+ ],
+ ],
+ 'drop_columns' => [
+ $this->table_prefix . 'users' => ['user_email_hash'],
+ ],
+ ];
+ }
+
+ public function revert_schema()
+ {
+ return [
+ 'add_columns' => [
+ $this->table_prefix . 'users' => [
+ 'user_email_hash' => ['BINT', 0],
+ ],
+ ],
+ 'add_index' => [
+ $this->table_prefix . 'users' => [
+ 'user_email_hash',
+ ],
+ ],
+ 'drop_keys' => [
+ $this->table_prefix . 'users' => [
+ 'user_email' => ['user_email'],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v330/v330b2.php b/phpBB/phpbb/db/migration/data/v330/v330b2.php
new file mode 100644
index 0000000000..1badc1387a
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/v330b2.php
@@ -0,0 +1,38 @@
+<?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\v330;
+
+class v330b2 extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return version_compare($this->config['version'], '3.3.0-b2', '>=');
+ }
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v330\add_display_unapproved_posts_config',
+ '\phpbb\db\migration\data\v330\forums_legend_limit',
+ '\phpbb\db\migration\data\v330\remove_email_hash',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.3.0-b2')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/di/service_collection.php b/phpBB/phpbb/di/service_collection.php
index 8c1c172e36..6298670c42 100644
--- a/phpBB/phpbb/di/service_collection.php
+++ b/phpBB/phpbb/di/service_collection.php
@@ -49,21 +49,6 @@ class service_collection extends \ArrayObject
return new service_collection_iterator($this);
}
- // Because of a PHP issue we have to redefine offsetExists
- // (even with a call to the parent):
- // https://bugs.php.net/bug.php?id=66834
- // https://bugs.php.net/bug.php?id=67067
- // But it triggers a sniffer issue that we have to skip
- // @codingStandardsIgnoreStart
- /**
- * {@inheritdoc}
- */
- public function offsetExists($index)
- {
- return parent::offsetExists($index);
- }
- // @codingStandardsIgnoreEnd
-
/**
* {@inheritdoc}
*/
@@ -76,11 +61,11 @@ class service_collection extends \ArrayObject
* Add a service to the collection
*
* @param string $name The service name
- * @return null
+ * @return void
*/
public function add($name)
{
- $this->offsetSet($name, null);
+ $this->offsetSet($name, false);
}
/**
diff --git a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php
index ba439609ff..91d7884aa4 100644
--- a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php
+++ b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php
@@ -245,7 +245,6 @@ class add_config_settings extends \phpbb\install\task_base
user_lang = '" . $this->db->sql_escape($this->install_config->get('user_language', 'en')) . "',
user_email='" . $this->db->sql_escape($this->install_config->get('board_email')) . "',
user_dateformat='" . $this->db->sql_escape($this->language->lang('default_dateformat')) . "',
- user_email_hash = " . $this->db->sql_escape(phpbb_email_hash($this->install_config->get('board_email'))) . ",
username_clean = '" . $this->db->sql_escape(utf8_clean_string($this->install_config->get('admin_name'))) . "'
WHERE username = 'Admin'",
diff --git a/phpBB/phpbb/textformatter/s9e/bbcode_merger.php b/phpBB/phpbb/textformatter/s9e/bbcode_merger.php
index af644192d8..d1bedb0b72 100644
--- a/phpBB/phpbb/textformatter/s9e/bbcode_merger.php
+++ b/phpBB/phpbb/textformatter/s9e/bbcode_merger.php
@@ -50,7 +50,7 @@ class bbcode_merger
$with = $this->create_bbcode($with);
// Select the appropriate strategy for merging this BBCode
- if ($this->is_content_bbcode($without, $with))
+ if (!$this->is_optional_bbcode($without, $with) && $this->is_content_bbcode($without, $with))
{
$merged = $this->merge_content_bbcode($without, $with);
}
@@ -107,12 +107,12 @@ class bbcode_merger
/**
* Test whether the two definitions form a "content"-style BBCode
*
- * Such BBCodes include the [URL] BBCode, which uses its text content as
+ * Such BBCodes include the [url] BBCode, which uses its text content as
* attribute if none is provided
*
* @param array $without BBCode definition without an attribute
* @param array $with BBCode definition with an attribute
- * @return array Merged definition
+ * @return bool
*/
protected function is_content_bbcode(array $without, array $with)
{
@@ -123,6 +123,22 @@ class bbcode_merger
}
/**
+ * Test whether the two definitions form BBCode with an optional attribute
+ *
+ * @param array $without BBCode definition without an attribute
+ * @param array $with BBCode definition with an attribute
+ * @return bool
+ */
+ protected function is_optional_bbcode(array $without, array $with)
+ {
+ // Remove the default attribute from the definition
+ $with['usage'] = preg_replace('(=[^\\]]++)', '', $with['usage']);
+
+ // Test whether both definitions are the same, regardless of case
+ return strcasecmp($without['usage'], $with['usage']) === 0;
+ }
+
+ /**
* Merge the two BBCode definitions of a "content"-style BBCode
*
* @param array $without BBCode definition without an attribute
@@ -131,7 +147,7 @@ class bbcode_merger
*/
protected function merge_content_bbcode(array $without, array $with)
{
- // Convert [X={X}] into [X={X;useContent}]
+ // Convert [x={X}] into [x={X;useContent}]
$usage = preg_replace('(\\})', ';useContent}', $with['usage'], 1);
// Use the template from the definition that uses an attribute
@@ -143,7 +159,7 @@ class bbcode_merger
/**
* Merge the two BBCode definitions of a BBCode with an optional argument
*
- * Such BBCodes include the [QUOTE] BBCode, which takes an optional argument
+ * Such BBCodes include the [quote] BBCode, which takes an optional argument
* but otherwise does not behave differently
*
* @param array $without BBCode definition without an attribute
diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php
index dca1c78d40..f82c7b0771 100644
--- a/phpBB/phpbb/textformatter/s9e/factory.php
+++ b/phpBB/phpbb/textformatter/s9e/factory.php
@@ -89,6 +89,8 @@ class factory implements \phpbb\textformatter\cache_interface
author={TEXT1;optional}
post_id={UINT;optional}
post_url={URL;optional;postFilter=#false}
+ msg_id={UINT;optional}
+ msg_url={URL;optional;postFilter=#false}
profile_url={URL;optional;postFilter=#false}
time={UINT;optional}
url={URL;optional}
diff --git a/phpBB/phpbb/textformatter/s9e/link_helper.php b/phpBB/phpbb/textformatter/s9e/link_helper.php
index 483794a83e..1cd5dd2fa7 100644
--- a/phpBB/phpbb/textformatter/s9e/link_helper.php
+++ b/phpBB/phpbb/textformatter/s9e/link_helper.php
@@ -61,7 +61,7 @@ class link_helper
$text = substr($parser->getText(), $start, $length);
// Create a tag that consumes the link's text and make it depends on this tag
- $link_text_tag = $parser->addSelfClosingTag('LINK_TEXT', $start, $length);
+ $link_text_tag = $parser->addSelfClosingTag('LINK_TEXT', $start, $length, 10);
$link_text_tag->setAttribute('text', $text);
$tag->cascadeInvalidationTo($link_text_tag);
}
diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php
index a36fc63141..f7e4668980 100644
--- a/phpBB/phpbb/textformatter/s9e/parser.php
+++ b/phpBB/phpbb/textformatter/s9e/parser.php
@@ -15,6 +15,7 @@ namespace phpbb\textformatter\s9e;
use s9e\TextFormatter\Parser\AttributeFilters\UrlFilter;
use s9e\TextFormatter\Parser\Logger;
+use s9e\TextFormatter\Parser\Tag;
/**
* s9e\TextFormatter\Parser adapter
@@ -219,7 +220,7 @@ class parser implements \phpbb\textformatter\parser_interface
{
$errors[] = array($msg, $context['max_' . strtolower($m[1])]);
}
- else if ($msg === 'Tag is disabled')
+ else if ($msg === 'Tag is disabled' && $this->is_a_bbcode($context['tag']))
{
$name = strtolower($context['tag']->getName());
$errors[] = array('UNAUTHORISED_BBCODE', '[' . $name . ']');
@@ -396,4 +397,21 @@ class parser implements \phpbb\textformatter\parser_interface
return $url;
}
+
+ /**
+ * Test whether given tag consumes text that looks like BBCode-styled markup
+ *
+ * @param Tag $tag Original tag
+ * @return bool
+ */
+ protected function is_a_bbcode(Tag $tag)
+ {
+ if ($tag->getLen() < 3)
+ {
+ return false;
+ }
+ $markup = substr($this->parser->getText(), $tag->getPos(), $tag->getLen());
+
+ return (bool) preg_match('(^\\[\\w++.*?\\]$)s', $markup);
+ }
}
diff --git a/phpBB/phpbb/textformatter/s9e/quote_helper.php b/phpBB/phpbb/textformatter/s9e/quote_helper.php
index 86c33c7591..3011ec88dc 100644
--- a/phpBB/phpbb/textformatter/s9e/quote_helper.php
+++ b/phpBB/phpbb/textformatter/s9e/quote_helper.php
@@ -21,6 +21,11 @@ class quote_helper
protected $post_url;
/**
+ * @var string Base URL for a private message link, uses {MSG_ID} as placeholder
+ */
+ protected $msg_url;
+
+ /**
* @var string Base URL for a profile link, uses {USER_ID} as placeholder
*/
protected $profile_url;
@@ -40,6 +45,7 @@ class quote_helper
public function __construct(\phpbb\user $user, $root_path, $php_ext)
{
$this->post_url = append_sid($root_path . 'viewtopic.' . $php_ext, 'p={POST_ID}#p{POST_ID}', false);
+ $this->msg_url = append_sid($root_path . 'ucp.' . $php_ext, 'i=pm&mode=view&p={MSG_ID}', false);
$this->profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=viewprofile&u={USER_ID}', false);
$this->user = $user;
}
@@ -52,26 +58,26 @@ class quote_helper
*/
public function inject_metadata($xml)
{
- $post_url = $this->post_url;
- $profile_url = $this->profile_url;
- $user = $this->user;
-
return \s9e\TextFormatter\Utils::replaceAttributes(
$xml,
'QUOTE',
- function ($attributes) use ($post_url, $profile_url, $user)
+ function ($attributes)
{
if (isset($attributes['post_id']))
{
- $attributes['post_url'] = str_replace('{POST_ID}', $attributes['post_id'], $post_url);
+ $attributes['post_url'] = str_replace('{POST_ID}', $attributes['post_id'], $this->post_url);
+ }
+ if (isset($attributes['msg_id']))
+ {
+ $attributes['msg_url'] = str_replace('{MSG_ID}', $attributes['msg_id'], $this->msg_url);
}
if (isset($attributes['time']))
{
- $attributes['date'] = $user->format_date($attributes['time']);
+ $attributes['date'] = $this->user->format_date($attributes['time']);
}
if (isset($attributes['user_id']))
{
- $attributes['profile_url'] = str_replace('{USER_ID}', $attributes['user_id'], $profile_url);
+ $attributes['profile_url'] = str_replace('{USER_ID}', $attributes['user_id'], $this->profile_url);
}
return $attributes;
diff --git a/phpBB/phpbb/ucp/controller/reset_password.php b/phpBB/phpbb/ucp/controller/reset_password.php
index 7bd1b20cb3..5c27c4f414 100644
--- a/phpBB/phpbb/ucp/controller/reset_password.php
+++ b/phpBB/phpbb/ucp/controller/reset_password.php
@@ -173,7 +173,7 @@ class reset_password
'SELECT' => 'user_id, username, user_permissions, user_email, user_jabber, user_notify_type, user_type,'
. ' user_lang, user_inactive_reason, reset_token, reset_token_expiration',
'FROM' => [$this->users_table => 'u'],
- 'WHERE' => "user_email_hash = '" . $this->db->sql_escape(phpbb_email_hash($email)) . "'" .
+ 'WHERE' => "user_email = '" . $this->db->sql_escape($email) . "'" .
(!empty($username) ? " AND username_clean = '" . $this->db->sql_escape(utf8_clean_string($username)) . "'" : ''),
];
diff --git a/phpBB/posting.php b/phpBB/posting.php
index da70e64877..c5d0693f35 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -256,12 +256,6 @@ if ($mode == 'popup')
$user->setup(array('posting', 'mcp', 'viewtopic'), $post_data['forum_style']);
-if ($config['enable_post_confirm'] && !$user->data['is_registered'])
-{
- $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
- $captcha->init(CONFIRM_POST);
-}
-
// Use post_row values in favor of submitted ones...
$forum_id = (!empty($post_data['forum_id'])) ? (int) $post_data['forum_id'] : (int) $forum_id;
$topic_id = (!empty($post_data['topic_id'])) ? (int) $post_data['topic_id'] : (int) $topic_id;
@@ -427,6 +421,12 @@ if (!$is_authed || !empty($error))
login_box('', $message);
}
+if ($config['enable_post_confirm'] && !$user->data['is_registered'])
+{
+ $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
+ $captcha->init(CONFIRM_POST);
+}
+
// Is the user able to post within this forum?
if ($post_data['forum_type'] != FORUM_POST && in_array($mode, array('post', 'bump', 'quote', 'reply')))
{
diff --git a/phpBB/search.php b/phpBB/search.php
index 8dde46f999..bd8025dae5 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -720,6 +720,8 @@ if ($keywords || $author || $author_id || $search_id || $submit)
if ($sql_where)
{
+ $zebra = [];
+
if ($show_results == 'posts')
{
// @todo Joining this query to the one below?
@@ -728,7 +730,6 @@ if ($keywords || $author || $author_id || $search_id || $submit)
WHERE user_id = ' . $user->data['user_id'];
$result = $db->sql_query($sql);
- $zebra = array();
while ($row = $db->sql_fetchrow($result))
{
$zebra[($row['friend']) ? 'friend' : 'foe'][] = $row['zebra_id'];
diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg
index cdf67d5a0c..9b9a02c1fb 100644
--- a/phpBB/styles/prosilver/style.cfg
+++ b/phpBB/styles/prosilver/style.cfg
@@ -21,8 +21,8 @@
# General Information about this style
name = prosilver
copyright = © phpBB Limited, 2007
-style_version = 3.3.0-b1
-phpbb_version = 3.3.0-b1
+style_version = 3.3.0-b2
+phpbb_version = 3.3.0-b2
# Defining a different template bitfield
# template_bitfield = //g=
diff --git a/phpBB/styles/prosilver/template/bbcode.html b/phpBB/styles/prosilver/template/bbcode.html
index 940c0ace29..b37ba238d2 100644
--- a/phpBB/styles/prosilver/template/bbcode.html
+++ b/phpBB/styles/prosilver/template/bbcode.html
@@ -37,6 +37,10 @@
<xsl:text> </xsl:text>
<a href="{@post_url}" data-post-id="{@post_id}" onclick="if(document.getElementById(hash.substr(1)))href=hash">&#8593;</a>
</xsl:if>
+ <xsl:if test="@msg_url">
+ <xsl:text> </xsl:text>
+ <a href="{@msg_url}" data-msg-id="{@msg_id}">&#8593;</a>
+ </xsl:if>
<xsl:if test="@date">
<div class="responsive-hide"><xsl:value-of select="@date"/></div>
</xsl:if>
diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html
index b1c7a81709..34915ebc41 100644
--- a/phpBB/styles/prosilver/template/memberlist_search.html
+++ b/phpBB/styles/prosilver/template/memberlist_search.html
@@ -12,7 +12,7 @@
<dt><label for="username">{L_USERNAME}{L_COLON}</label></dt>
<dd>
<!-- IF U_LIVE_SEARCH --><div class="dropdown-container dropdown-{S_CONTENT_FLOW_END}"><!-- ENDIF -->
- <input type="text" name="username" id="username" value="{USERNAME}" class="inputbox"<!-- IF U_LIVE_SEARCH --> autocomplete="off" data-filter="phpbb.search.filter" data-ajax="member_search" data-min-length="3" data-url="{U_LIVE_SEARCH}" data-results="#user-search" data-overlay="false"<!-- ENDIF --> />
+ <input type="text" name="username" id="username" value="{USERNAME}" class="inputbox"<!-- IF U_LIVE_SEARCH --> autocomplete="off" data-filter="phpbb.search.filter" data-ajax="member_search" data-min-length="3" data-url="{U_LIVE_SEARCH}" data-results="#user-search"<!-- ENDIF --> />
<!-- IF U_LIVE_SEARCH -->
<div class="dropdown live-search hidden" id="user-search">
<div class="pointer"><div class="pointer-inner"></div></div>
diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html
index d4fef9f0a5..7959925d30 100644
--- a/phpBB/styles/prosilver/template/ucp_agreement.html
+++ b/phpBB/styles/prosilver/template/ucp_agreement.html
@@ -43,7 +43,8 @@
<div class="inner">
<fieldset class="submit-buttons">
<!-- IF S_SHOW_COPPA -->
- <strong><a href="{U_COPPA_NO}" class="button1">{L_COPPA_NO}</a></strong>&nbsp; <a href="{U_COPPA_YES}" class="button2">{L_COPPA_YES}</a>
+ <input type="submit" name="coppa_no" id="coppa_no" value="{{ L_COPPA_NO }}" class="button1" />
+ <input type="submit" name="coppa_yes" id="coppa_yes" value="{{ L_COPPA_YES }}" class="button2" />
<!-- ELSE -->
<input type="submit" name="agreed" id="agreed" value="{L_AGREE}" class="button1" />&nbsp;
<input type="submit" name="not_agreed" value="{L_NOT_AGREE}" class="button2" />
diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html
index 9bfa07e52b..6af33f2f87 100644
--- a/phpBB/styles/prosilver/template/viewtopic_body.html
+++ b/phpBB/styles/prosilver/template/viewtopic_body.html
@@ -294,6 +294,7 @@
<!-- EVENT viewtopic_body_postrow_post_details_after -->
<!-- IF postrow.S_POST_UNAPPROVED -->
+ <!-- IF postrow.S_CAN_APPROVE -->
<form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}">
<p class="post-notice unapproved">
<span><i class="icon fa-question icon-red fa-fw" aria-hidden="true"></i></span>
@@ -304,6 +305,12 @@
{S_FORM_TOKEN}
</p>
</form>
+ <!-- ELSE -->
+ <p class="post-notice unapproved">
+ <span><i class="icon fa-exclamation icon-red fa-fw" aria-hidden="true"></i></span>
+ <strong>{L_POST_UNAPPROVED_EXPLAIN}</strong>
+ </p>
+ <!-- ENDIF -->
<!-- ELSEIF postrow.S_POST_DELETED -->
<form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}">
<p class="post-notice deleted">
diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css
index ffaa71034f..1ead493926 100644
--- a/phpBB/styles/prosilver/theme/colours.css
+++ b/phpBB/styles/prosilver/theme/colours.css
@@ -672,6 +672,11 @@ Colours and backgrounds for buttons.css
box-shadow: 0 0 10px #0075B0;
}
+.search-results li:hover,
+.search-results li.active {
+ background-color: #CFE1F6;
+}
+
/* Icon images
---------------------------------------- */
diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css
index 5646a7d6c7..99c898f41e 100644
--- a/phpBB/styles/prosilver/theme/forms.css
+++ b/phpBB/styles/prosilver/theme/forms.css
@@ -355,7 +355,7 @@ input.button3 {
font-variant: small-caps;
}
-input[type="button"], input[type="submit"], input[type="reset"], input[type="checkbox"], input[type="radio"] {
+input[type="button"], input[type="submit"], input[type="reset"], input[type="checkbox"], input[type="radio"], .search-results li {
cursor: pointer;
}
diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php
index 4691512cbd..eb6b37ada8 100644
--- a/phpBB/viewforum.php
+++ b/phpBB/viewforum.php
@@ -899,6 +899,11 @@ if (count($topic_list))
// Replies
$replies = $phpbb_content_visibility->get_count('topic_posts', $row, $topic_forum_id) - 1;
+ // Correction for case of unapproved topic visible to poster
+ if ($replies < 0)
+ {
+ $replies = 0;
+ }
if ($row['topic_status'] == ITEM_MOVED)
{
diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index 4e502538c8..df241a5e8b 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -2092,6 +2092,7 @@ for ($i = 0, $end = count($post_list); $i < $end; ++$i)
'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false,
'S_MULTIPLE_ATTACHMENTS' => !empty($attachments[$row['post_id']]) && count($attachments[$row['post_id']]) > 1,
'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) ? true : false,
+ 'S_CAN_APPROVE' => $auth->acl_get('m_approve', $forum_id),
'S_POST_DELETED' => ($row['post_visibility'] == ITEM_DELETED) ? true : false,
'L_POST_DELETED_MESSAGE' => $l_deleted_message,
'S_POST_REPORTED' => ($row['post_reported'] && $auth->acl_get('m_report', $forum_id)) ? true : false,