aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB')
-rw-r--r--phpBB/.htaccess7
-rw-r--r--phpBB/adm/index.php1
-rw-r--r--phpBB/adm/style/acp_avatar_options_upload.html2
-rw-r--r--phpBB/adm/style/acp_contact.html2
-rw-r--r--phpBB/adm/style/acp_ext_actions.html6
-rw-r--r--phpBB/adm/style/acp_ext_delete_data.html40
-rw-r--r--phpBB/adm/style/acp_ext_disable.html34
-rw-r--r--phpBB/adm/style/acp_ext_enable.html40
-rw-r--r--phpBB/adm/style/acp_ext_list.html21
-rw-r--r--phpBB/adm/style/acp_forums.html5
-rw-r--r--phpBB/adm/style/acp_groups.html2
-rw-r--r--phpBB/adm/style/acp_language.html2
-rw-r--r--phpBB/adm/style/acp_main.html191
-rw-r--r--phpBB/adm/style/acp_styles.html2
-rw-r--r--phpBB/adm/style/acp_users_signature.html2
-rw-r--r--phpBB/adm/style/admin.css10
-rw-r--r--phpBB/adm/style/admin.js58
-rw-r--r--phpBB/adm/style/ajax.js28
-rw-r--r--phpBB/adm/style/captcha_recaptcha.html3
-rw-r--r--phpBB/adm/style/installer_footer.html2
-rw-r--r--phpBB/adm/style/overall_footer.html2
-rw-r--r--phpBB/adm/style/permission_forum_copy.html2
-rw-r--r--phpBB/adm/style/simple_footer.html2
-rw-r--r--phpBB/assets/cookieconsent/cookieconsent.min.css12
-rw-r--r--phpBB/assets/cookieconsent/cookieconsent.min.js2
-rw-r--r--phpBB/assets/javascript/core.js153
-rw-r--r--phpBB/assets/javascript/jquery-3.4.1.min.js2
-rw-r--r--phpBB/assets/javascript/jquery.min.js5
-rw-r--r--phpBB/common.php4
-rw-r--r--phpBB/composer.json63
-rw-r--r--phpBB/composer.lock2392
-rw-r--r--phpBB/config/default/container/parameters.yml2
-rw-r--r--phpBB/config/default/container/services.yml1
-rw-r--r--phpBB/config/default/container/services_auth.yml22
-rw-r--r--phpBB/config/default/container/services_console.yml8
-rw-r--r--phpBB/config/default/container/services_cron.yml13
-rw-r--r--phpBB/config/default/container/services_password.yml20
-rw-r--r--phpBB/config/default/container/services_routing.yml2
-rw-r--r--phpBB/config/default/container/services_twig.yml18
-rw-r--r--phpBB/config/default/container/services_ucp.yml17
-rw-r--r--phpBB/config/default/routing/cron.yml3
-rw-r--r--phpBB/config/default/routing/routing.yml8
-rw-r--r--phpBB/config/default/routing/ucp.yml7
-rw-r--r--phpBB/config/development/config.yml8
-rw-r--r--phpBB/config/test/config.yml1
-rw-r--r--phpBB/cron.php67
-rw-r--r--phpBB/develop/add_permissions.php9
-rw-r--r--phpBB/develop/calc_email_hash.php74
-rw-r--r--phpBB/develop/create_schema_files.php1
-rw-r--r--phpBB/develop/mysql_upgrader.php212
-rw-r--r--phpBB/develop/regex.php40
-rw-r--r--phpBB/develop/regex_idn.php41
-rw-r--r--phpBB/develop/update_email_hash.php56
-rw-r--r--phpBB/docs/CHANGELOG.html140
-rw-r--r--phpBB/docs/CREDITS.txt6
-rw-r--r--phpBB/docs/FAQ.html10
-rw-r--r--phpBB/docs/INSTALL.html40
-rw-r--r--phpBB/docs/README.html24
-rw-r--r--phpBB/docs/coding-guidelines.html24
-rw-r--r--phpBB/download/file.php5
-rw-r--r--phpBB/feed.php6
-rw-r--r--phpBB/images/upload_icons/flash.gifbin254 -> 0 bytes
-rw-r--r--phpBB/includes/acp/acp_attachments.php2
-rw-r--r--phpBB/includes/acp/acp_bbcodes.php159
-rw-r--r--phpBB/includes/acp/acp_board.php52
-rw-r--r--phpBB/includes/acp/acp_database.php2
-rw-r--r--phpBB/includes/acp/acp_extensions.php187
-rw-r--r--phpBB/includes/acp/acp_forums.php14
-rw-r--r--phpBB/includes/acp/acp_main.php2
-rw-r--r--phpBB/includes/acp/acp_reasons.php2
-rw-r--r--phpBB/includes/acp/acp_users.php11
-rw-r--r--phpBB/includes/compatibility_globals.php8
-rw-r--r--phpBB/includes/constants.php6
-rw-r--r--phpBB/includes/functions.php389
-rw-r--r--phpBB/includes/functions_acp.php2
-rw-r--r--phpBB/includes/functions_admin.php45
-rw-r--r--phpBB/includes/functions_compatibility.php190
-rw-r--r--phpBB/includes/functions_compress.php4
-rw-r--r--phpBB/includes/functions_content.php20
-rw-r--r--phpBB/includes/functions_convert.php15
-rw-r--r--phpBB/includes/functions_display.php44
-rw-r--r--phpBB/includes/functions_download.php26
-rw-r--r--phpBB/includes/functions_module.php10
-rw-r--r--phpBB/includes/functions_posting.php34
-rw-r--r--phpBB/includes/functions_transfer.php4
-rw-r--r--phpBB/includes/functions_user.php14
-rw-r--r--phpBB/includes/questionnaire/questionnaire.php4
-rw-r--r--phpBB/includes/startup.php6
-rw-r--r--phpBB/includes/ucp/ucp_profile.php7
-rw-r--r--phpBB/includes/ucp/ucp_register.php34
-rw-r--r--phpBB/includes/ucp/ucp_remind.php174
-rw-r--r--phpBB/includes/ucp/ucp_resend.php2
-rw-r--r--phpBB/index.php5
-rw-r--r--phpBB/install/app.php4
-rw-r--r--phpBB/install/convert/convertor.php23
-rw-r--r--phpBB/install/convertors/convert_phpbb20.php3
-rw-r--r--phpBB/install/convertors/functions_phpbb20.php26
-rwxr-xr-xphpBB/install/phpbbcli.php2
-rw-r--r--phpBB/install/schemas/schema_data.sql18
-rw-r--r--phpBB/install/startup.php1
-rw-r--r--phpBB/language/en/acp/attachments.php2
-rw-r--r--phpBB/language/en/acp/board.php4
-rw-r--r--phpBB/language/en/acp/common.php12
-rw-r--r--phpBB/language/en/acp/forums.php2
-rw-r--r--phpBB/language/en/acp/permissions.php2
-rw-r--r--phpBB/language/en/captcha_recaptcha.php10
-rw-r--r--phpBB/language/en/cli.php3
-rw-r--r--phpBB/language/en/common.php17
-rw-r--r--phpBB/language/en/email/user_activate_passwd.txt17
-rw-r--r--phpBB/language/en/email/user_forgot_password.txt13
-rw-r--r--phpBB/language/en/install.php11
-rw-r--r--phpBB/language/en/migrator.php2
-rw-r--r--phpBB/language/en/posting.php1
-rw-r--r--phpBB/language/en/ucp.php19
-rw-r--r--phpBB/mcp.php5
-rw-r--r--phpBB/memberlist.php64
-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/avatar/driver/upload.php1
-rw-r--r--phpBB/phpbb/cache/driver/apc.php70
-rw-r--r--phpBB/phpbb/cache/driver/eaccelerator.php107
-rw-r--r--phpBB/phpbb/cache/driver/memcache.php122
-rw-r--r--phpBB/phpbb/cache/driver/memcached.php22
-rw-r--r--phpBB/phpbb/cache/driver/memory.php2
-rw-r--r--phpBB/phpbb/cache/driver/xcache.php107
-rw-r--r--phpBB/phpbb/class_loader.php2
-rw-r--r--phpBB/phpbb/config/config.php19
-rw-r--r--phpBB/phpbb/config_php_file.php6
-rw-r--r--phpBB/phpbb/console/command/cron/run.php2
-rw-r--r--phpBB/phpbb/console/command/extension/enable.php6
-rw-r--r--phpBB/phpbb/console/command/fixup/recalculate_email_hash.php76
-rw-r--r--phpBB/phpbb/console/command/update/check.php2
-rw-r--r--phpBB/phpbb/console/command/user/add.php2
-rw-r--r--phpBB/phpbb/content_visibility.php22
-rw-r--r--phpBB/phpbb/controller/helper.php2
-rw-r--r--phpBB/phpbb/cron/controller/cron.php40
-rw-r--r--phpBB/phpbb/cron/event/cron_runner_listener.php103
-rw-r--r--phpBB/phpbb/cron/manager.php21
-rw-r--r--phpBB/phpbb/cron/task/wrapper.php47
-rw-r--r--phpBB/phpbb/db/driver/driver.php28
-rw-r--r--phpBB/phpbb/db/driver/driver_interface.php14
-rw-r--r--phpBB/phpbb/db/driver/factory.php16
-rw-r--r--phpBB/phpbb/db/driver/mssql_odbc.php11
-rw-r--r--phpBB/phpbb/db/driver/mssqlnative.php11
-rw-r--r--phpBB/phpbb/db/driver/mysql.php503
-rw-r--r--phpBB/phpbb/db/driver/mysqli.php13
-rw-r--r--phpBB/phpbb/db/driver/oracle.php11
-rw-r--r--phpBB/phpbb/db/driver/postgres.php11
-rw-r--r--phpBB/phpbb/db/driver/sqlite3.php11
-rw-r--r--phpBB/phpbb/db/extractor/mysql_extractor.php106
-rw-r--r--phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php2
-rw-r--r--phpBB/phpbb/db/migration/data/v310/softdelete_p1.php2
-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/dev.php36
-rw-r--r--phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php49
-rw-r--r--phpBB/phpbb/db/migration/data/v330/jquery_update.php37
-rw-r--r--phpBB/phpbb/db/migration/data/v330/remove_attachment_flash.php84
-rw-r--r--phpBB/phpbb/db/migration/data/v330/remove_email_hash.php57
-rw-r--r--phpBB/phpbb/db/migration/data/v330/remove_max_pass_chars.php43
-rw-r--r--phpBB/phpbb/db/migration/data/v330/reset_password.php48
-rw-r--r--phpBB/phpbb/db/migration/data/v330/v330b1.php41
-rw-r--r--phpBB/phpbb/db/migration/data/v330/v330b2.php38
-rw-r--r--phpBB/phpbb/db/migration/tool/module.php2
-rw-r--r--phpBB/phpbb/db/migrator.php2
-rw-r--r--phpBB/phpbb/db/tools/mssql.php2
-rw-r--r--phpBB/phpbb/db/tools/postgres.php2
-rw-r--r--phpBB/phpbb/db/tools/tools.php87
-rw-r--r--phpBB/phpbb/di/container_builder.php9
-rw-r--r--phpBB/phpbb/di/extension/container_configuration.php11
-rw-r--r--phpBB/phpbb/di/extension/core.php8
-rw-r--r--phpBB/phpbb/di/extension/tables.php59
-rw-r--r--phpBB/phpbb/di/service_collection.php50
-rw-r--r--phpBB/phpbb/extension/extension_interface.php3
-rw-r--r--phpBB/phpbb/extension/manager.php150
-rw-r--r--phpBB/phpbb/feed/topics_active.php2
-rw-r--r--phpBB/phpbb/files/filespec.php2
-rw-r--r--phpBB/phpbb/filesystem.php2
-rw-r--r--phpBB/phpbb/filesystem/filesystem.php24
-rw-r--r--phpBB/phpbb/filesystem/filesystem_interface.php2
-rw-r--r--phpBB/phpbb/finder.php4
-rw-r--r--phpBB/phpbb/help/controller/bbcode.php5
-rw-r--r--phpBB/phpbb/help/controller/faq.php5
-rw-r--r--phpBB/phpbb/install/controller/helper.php2
-rw-r--r--phpBB/phpbb/install/helper/container_factory.php2
-rw-r--r--phpBB/phpbb/install/helper/database.php18
-rw-r--r--phpBB/phpbb/install/helper/iohandler/iohandler_interface.php2
-rw-r--r--phpBB/phpbb/install/installer_configuration.php9
-rw-r--r--phpBB/phpbb/install/module/install_database/task/add_config_settings.php1
-rw-r--r--phpBB/phpbb/install/module/install_database/task/create_schema.php9
-rw-r--r--phpBB/phpbb/install/module/install_database/task/set_up_database.php9
-rw-r--r--phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php3
-rw-r--r--phpBB/phpbb/install/module/requirements/task/check_server_environment.php2
-rw-r--r--phpBB/phpbb/lock/db.php7
-rw-r--r--phpBB/phpbb/lock/flock.php5
-rw-r--r--phpBB/phpbb/mimetype/guesser.php2
-rw-r--r--phpBB/phpbb/notification/type/approve_post.php7
-rw-r--r--phpBB/phpbb/notification/type/approve_topic.php7
-rw-r--r--phpBB/phpbb/notification/type/base.php4
-rw-r--r--phpBB/phpbb/notification/type/post.php2
-rw-r--r--phpBB/phpbb/notification/type/topic.php2
-rw-r--r--phpBB/phpbb/notification/type/type_interface.php2
-rw-r--r--phpBB/phpbb/passwords/driver/argon2i.php73
-rw-r--r--phpBB/phpbb/passwords/driver/argon2id.php33
-rw-r--r--phpBB/phpbb/passwords/driver/base_native.php75
-rw-r--r--phpBB/phpbb/passwords/manager.php2
-rw-r--r--phpBB/phpbb/report/report_handler.php2
-rw-r--r--phpBB/phpbb/request/request.php6
-rw-r--r--phpBB/phpbb/request/request_interface.php2
-rw-r--r--phpBB/phpbb/search/fulltext_mysql.php23
-rw-r--r--phpBB/phpbb/search/fulltext_native.php4
-rw-r--r--phpBB/phpbb/search/fulltext_postgres.php2
-rw-r--r--phpBB/phpbb/search/fulltext_sphinx.php8
-rw-r--r--phpBB/phpbb/session.php61
-rw-r--r--phpBB/phpbb/template/asset.php7
-rw-r--r--phpBB/phpbb/template/context.php4
-rw-r--r--phpBB/phpbb/template/template.php2
-rw-r--r--phpBB/phpbb/template/twig/extension.php30
-rw-r--r--phpBB/phpbb/template/twig/extension/avatar.php80
-rw-r--r--phpBB/phpbb/template/twig/extension/config.php64
-rw-r--r--phpBB/phpbb/template/twig/extension/username.php84
-rw-r--r--phpBB/phpbb/template/twig/lexer.php16
-rw-r--r--phpBB/phpbb/template/twig/loader.php8
-rw-r--r--phpBB/phpbb/template/twig/node/definenode.php2
-rw-r--r--phpBB/phpbb/template/twig/node/includeasset.php20
-rw-r--r--phpBB/phpbb/template/twig/node/includephp.php6
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/defineparser.php4
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/event.php17
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includecss.php4
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includejs.php4
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includeparser.php2
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/includephp.php17
-rw-r--r--phpBB/phpbb/template/twig/tokenparser/php.php17
-rw-r--r--phpBB/phpbb/textformatter/s9e/bbcode_merger.php6
-rw-r--r--phpBB/phpbb/ucp/controller/reset_password.php443
-rw-r--r--phpBB/phpbb/user.php20
-rw-r--r--phpBB/phpbb/user_loader.php6
-rw-r--r--phpBB/posting.php2
-rw-r--r--phpBB/report.php2
-rw-r--r--phpBB/search.php13
-rw-r--r--phpBB/styles/prosilver/style.cfg4
-rw-r--r--phpBB/styles/prosilver/template/attachment.html13
-rw-r--r--phpBB/styles/prosilver/template/captcha_recaptcha.html31
-rw-r--r--phpBB/styles/prosilver/template/forum_fn.js2
-rw-r--r--phpBB/styles/prosilver/template/memberlist_search.html2
-rw-r--r--phpBB/styles/prosilver/template/navbar_header.html4
-rw-r--r--phpBB/styles/prosilver/template/overall_footer.html2
-rw-r--r--phpBB/styles/prosilver/template/posting_buttons.html2
-rw-r--r--phpBB/styles/prosilver/template/posting_layout.html21
-rw-r--r--phpBB/styles/prosilver/template/simple_footer.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_avatar_options_upload.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_groups_manage.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_register.html11
-rw-r--r--phpBB/styles/prosilver/template/ucp_remind.html37
-rw-r--r--phpBB/styles/prosilver/template/ucp_reset_password.html49
-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/styles/prosilver/theme/icons.css2
-rw-r--r--phpBB/styles/prosilver/theme/print.css2
-rw-r--r--phpBB/styles/prosilver/theme/stylesheet.css26
-rw-r--r--phpBB/ucp.php11
-rw-r--r--phpBB/viewforum.php5
-rw-r--r--phpBB/viewonline.php5
-rw-r--r--phpBB/viewtopic.php1
275 files changed, 6142 insertions, 5597 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/index.php b/phpBB/adm/index.php
index d27f56f28b..c648fdf100 100644
--- a/phpBB/adm/index.php
+++ b/phpBB/adm/index.php
@@ -49,7 +49,6 @@ if (!$auth->acl_get('a_'))
define('IN_ADMIN', true);
// Some oft used variables
-$safe_mode = (@ini_get('safe_mode') == '1' || strtolower(@ini_get('safe_mode')) === 'on') ? true : false;
$file_uploads = (@ini_get('file_uploads') == '1' || strtolower(@ini_get('file_uploads')) === 'on') ? true : false;
$module_id = $request->variable('i', '');
$mode = $request->variable('mode', '');
diff --git a/phpBB/adm/style/acp_avatar_options_upload.html b/phpBB/adm/style/acp_avatar_options_upload.html
index 63a734ea7d..666950e0ae 100644
--- a/phpBB/adm/style/acp_avatar_options_upload.html
+++ b/phpBB/adm/style/acp_avatar_options_upload.html
@@ -1,6 +1,6 @@
<dl>
<dt><label for="avatar_upload_file">{L_UPLOAD_AVATAR_FILE}{L_COLON}</label></dt>
- <dd><input type="hidden" name="MAX_FILE_SIZE" value="{AVATAR_UPLOAD_SIZE}" /><input type="file" name="avatar_upload_file" id="avatar_upload_file" class="inputbox autowidth" /></dd>
+ <dd><input type="hidden" name="MAX_FILE_SIZE" value="{AVATAR_UPLOAD_SIZE}" /><input type="file" name="avatar_upload_file" id="avatar_upload_file" class="inputbox autowidth" accept="{{ AVATAR_ALLOWED_EXTENSIONS }}" /></dd>
</dl>
<!-- IF S_UPLOAD_AVATAR_URL -->
diff --git a/phpBB/adm/style/acp_contact.html b/phpBB/adm/style/acp_contact.html
index d63fd08a3a..c46a2d7fed 100644
--- a/phpBB/adm/style/acp_contact.html
+++ b/phpBB/adm/style/acp_contact.html
@@ -44,7 +44,7 @@
<!-- INCLUDE acp_posting_buttons.html -->
<dl class="responsive-columns">
- <dt style="width: 90px;" id="color_palette_placeholder" data-orientation="v" data-height="12" data-width="15" data-bbcode="true">
+ <dt style="width: 90px;" id="color_palette_placeholder" data-color-palette="v" data-height="12" data-width="15" data-bbcode="true">
</dt>
<dd style="margin-{S_CONTENT_FLOW_BEGIN}: 90px;">
diff --git a/phpBB/adm/style/acp_ext_actions.html b/phpBB/adm/style/acp_ext_actions.html
new file mode 100644
index 0000000000..6f2341f381
--- /dev/null
+++ b/phpBB/adm/style/acp_ext_actions.html
@@ -0,0 +1,6 @@
+{% for action in enabled.actions %}
+<a href="{{ action.U_ACTION }}"{% if action.L_ACTION_EXPLAIN %} title="{{ action.L_ACTION_EXPLAIN }}"{% endif %}{% if action.COLOR %} style="color: {{ action.COLOR }};"{% endif %} data-ajax="{{ action.ACTION_AJAX }}" data-refresh="true">{{ action.L_ACTION }}</a>{% if not action.S_LAST_ROW %}&nbsp;|&nbsp;{% endif %}
+{% endfor %}
+{% for action in disabled.actions %}
+<a href="{{ action.U_ACTION }}"{% if action.L_ACTION_EXPLAIN %} title="{{ action.L_ACTION_EXPLAIN }}"{% endif %}{% if action.COLOR %} style="color: {{ action.COLOR }};"{% endif %} data-ajax="{{ action.ACTION_AJAX }}" data-refresh="true">{{ action.L_ACTION }}</a>{% if not action.S_LAST_ROW %}&nbsp;|&nbsp;{% endif %}
+{% endfor %} \ No newline at end of file
diff --git a/phpBB/adm/style/acp_ext_delete_data.html b/phpBB/adm/style/acp_ext_delete_data.html
deleted file mode 100644
index 0f3adb7cfe..0000000000
--- a/phpBB/adm/style/acp_ext_delete_data.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!-- INCLUDE overall_header.html -->
-
- <a id="maincontent"></a>
-
- <h1>{L_EXTENSIONS_ADMIN}</h1>
-
- <p>{L_EXTENSIONS_EXPLAIN}</p>
- <p>{L_EXTENSION_DELETE_DATA_EXPLAIN}</p>
-
- <!-- IF MIGRATOR_ERROR -->
- <div class="errorbox">
- <p><strong>{L_MIGRATION_EXCEPTION_ERROR}</strong></p>
- <p>{MIGRATOR_ERROR}</p>
- <p><a href="{U_RETURN}">{L_RETURN_TO_EXTENSION_LIST}</a></p>
- </div>
- <!-- ELSEIF PRE -->
- <div class="errorbox">
- <p>{L_CONFIRM_MESSAGE}</p>
- </div>
-
- <form id="acp_extensions" method="post" action="{U_PURGE}">
- <fieldset class="submit-buttons">
- <legend>{L_EXTENSION_DELETE_DATA}</legend>
- <input class="button1" type="submit" name="delete_data" value="{L_EXTENSION_DELETE_DATA}" />
- <input class="button2" type="submit" name="cancel" value="{L_CANCEL}" />
- </fieldset>
- </form>
- <!-- ELSEIF S_NEXT_STEP -->
- <div class="errorbox">
- <p>{L_EXTENSION_DELETE_DATA_IN_PROGRESS}</p>
- </div>
- <!-- ELSE -->
- <div class="successbox">
- <p>{L_EXTENSION_DELETE_DATA_SUCCESS}</p>
- <br />
- <p><a href="{U_RETURN}">{L_RETURN_TO_EXTENSION_LIST}</a></p>
- </div>
- <!-- ENDIF -->
-
-<!-- INCLUDE overall_footer.html -->
diff --git a/phpBB/adm/style/acp_ext_disable.html b/phpBB/adm/style/acp_ext_disable.html
deleted file mode 100644
index d2b5c46fe8..0000000000
--- a/phpBB/adm/style/acp_ext_disable.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!-- INCLUDE overall_header.html -->
-
- <a id="maincontent"></a>
-
- <h1>{L_EXTENSIONS_ADMIN}</h1>
-
- <p>{L_EXTENSIONS_EXPLAIN}</p>
- <p>{L_EXTENSION_DISABLE_EXPLAIN}</p>
-
- <!-- IF PRE -->
- <fieldset>
- <h2>{L_CONFIRM}</h2>
- <p>{L_CONFIRM_MESSAGE}</p>
- </fieldset>
-
- <form id="acp_extensions" method="post" action="{U_DISABLE}">
- <fieldset class="submit-buttons">
- <input class="button1" type="submit" name="disable" value="{L_EXTENSION_DISABLE}" />
- <input class="button2" type="submit" name="cancel" value="{L_CANCEL}" />
- </fieldset>
- </form>
- <!-- ELSEIF S_NEXT_STEP -->
- <div class="successbox notice">
- <p>{L_EXTENSION_DISABLE_IN_PROGRESS}</p>
- </div>
- <!-- ELSE -->
- <div class="successbox">
- <p>{L_EXTENSION_DISABLE_SUCCESS}</p>
- <br />
- <p><a href="{U_RETURN}">{L_RETURN_TO_EXTENSION_LIST}</a></p>
- </div>
- <!-- ENDIF -->
-
-<!-- INCLUDE overall_footer.html -->
diff --git a/phpBB/adm/style/acp_ext_enable.html b/phpBB/adm/style/acp_ext_enable.html
deleted file mode 100644
index 8a4a35359e..0000000000
--- a/phpBB/adm/style/acp_ext_enable.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!-- INCLUDE overall_header.html -->
-
- <a id="maincontent"></a>
-
- <h1>{L_EXTENSIONS_ADMIN}</h1>
-
- <p>{L_EXTENSIONS_EXPLAIN}</p>
- <p>{L_EXTENSION_ENABLE_EXPLAIN}</p>
-
- <!-- IF MIGRATOR_ERROR -->
- <div class="errorbox">
- <p><strong>{L_MIGRATION_EXCEPTION_ERROR}</strong></p>
- <p>{MIGRATOR_ERROR}</p>
- <p><a href="{U_RETURN}">{L_RETURN_TO_EXTENSION_LIST}</a></p>
- </div>
- <!-- ELSEIF PRE -->
- <fieldset>
- <h2>{L_CONFIRM}</h2>
- <p>{L_CONFIRM_MESSAGE}</p>
- </fieldset>
-
- <form id="acp_extensions" method="post" action="{U_ENABLE}">
- <fieldset class="submit-buttons">
- <input class="button1" type="submit" name="enable" value="{L_EXTENSION_ENABLE}" />
- <input class="button2" type="submit" name="cancel" value="{L_CANCEL}" />
- </fieldset>
- </form>
- <!-- ELSEIF S_NEXT_STEP -->
- <div class="successbox notice">
- <p>{L_EXTENSION_ENABLE_IN_PROGRESS}</p>
- </div>
- <!-- ELSE -->
- <div class="successbox">
- <p>{L_EXTENSION_ENABLE_SUCCESS}</p>
- <br />
- <p><a href="{U_RETURN}">{L_RETURN_TO_EXTENSION_LIST}</a></p>
- </div>
- <!-- ENDIF -->
-
-<!-- INCLUDE overall_footer.html -->
diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html
index 8e2c7452a3..e5783124c6 100644
--- a/phpBB/adm/style/acp_ext_list.html
+++ b/phpBB/adm/style/acp_ext_list.html
@@ -7,7 +7,7 @@
<p>{L_EXTENSIONS_EXPLAIN}</p>
<fieldset class="quick">
- <span class="small"><a href="https://www.phpbb.com/go/customise/extensions/3.2" target="_blank">{L_BROWSE_EXTENSIONS_DATABASE}</a> &bull; <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE_ALL}</a> &bull; <a href="javascript:phpbb.toggleDisplay('version_check_settings');">{L_SETTINGS}</a></span>
+ <span class="small"><a href="https://www.phpbb.com/go/customise/extensions/3.3" target="_blank">{L_BROWSE_EXTENSIONS_DATABASE}</a> &bull; <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE_ALL}</a> &bull; <a href="javascript:phpbb.toggleDisplay('version_check_settings');">{L_SETTINGS}</a></span>
</fieldset>
<form id="version_check_settings" method="post" action="{U_ACTION}" style="display:none">
@@ -42,8 +42,8 @@
</tr>
</thead>
<tbody>
- <!-- IF .enabled -->
- <tr>
+
+ <tr id="ext_enabled_header"<!-- IF not .enabled --> class="hidden"<!-- ENDIF -->>
<td class="row3" colspan="4"><strong>{L_EXTENSIONS_ENABLED}</strong><!-- EVENT acp_ext_list_enabled_title_after --></td>
</tr>
<!-- BEGIN enabled -->
@@ -59,17 +59,12 @@
</td>
<td style="text-align: center;"><a href="{enabled.U_DETAILS}">{L_DETAILS}</a></td>
<td style="text-align: center;">
- <!-- BEGIN actions -->
- <a href="{enabled.actions.U_ACTION}"<!-- IF enabled.actions.L_ACTION_EXPLAIN --> title="{enabled.actions.L_ACTION_EXPLAIN}"<!-- ENDIF -->>{enabled.actions.L_ACTION}</a>
- <!-- IF not enabled.actions.S_LAST_ROW -->&nbsp;|&nbsp;<!-- ENDIF -->
- <!-- END actions -->
+ <!-- INCLUDE acp_ext_actions.html -->
</td>
</tr>
<!-- END enabled -->
- <!-- ENDIF -->
- <!-- IF .disabled -->
- <tr>
+ <tr id="ext_disabled_header"<!-- IF not .disabled --> class="hidden"<!-- ENDIF -->>
<td class="row3" colspan="4"><strong>{L_EXTENSIONS_DISABLED}</strong><!-- EVENT acp_ext_list_disabled_title_after --></td>
</tr>
<!-- BEGIN disabled -->
@@ -87,14 +82,10 @@
<!-- IF disabled.U_DETAILS --><a href="{disabled.U_DETAILS}">{L_DETAILS}</a><!-- ENDIF -->
</td>
<td style="text-align: center;">
- <!-- BEGIN actions -->
- <a href="{disabled.actions.U_ACTION}"<!-- IF disabled.actions.L_ACTION_EXPLAIN --> title="{disabled.actions.L_ACTION_EXPLAIN}"<!-- ENDIF -->>{disabled.actions.L_ACTION}</a>
- <!-- IF not disabled.actions.S_LAST_ROW -->&nbsp;|&nbsp;<!-- ENDIF -->
- <!-- END actions -->
+ <!-- INCLUDE acp_ext_actions.html -->
</td>
</tr>
<!-- END disabled -->
- <!-- ENDIF -->
</tbody>
</table>
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/adm/style/acp_groups.html b/phpBB/adm/style/acp_groups.html
index 723a190899..8651b63b7f 100644
--- a/phpBB/adm/style/acp_groups.html
+++ b/phpBB/adm/style/acp_groups.html
@@ -100,7 +100,7 @@
<input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="6" maxlength="6" />
<!-- IF GROUP_COLOUR -->&nbsp;<span style="background-color: #{GROUP_COLOUR}">&nbsp; &nbsp;</span><!-- ENDIF -->&nbsp;&nbsp;<span>
[ <a href="#" id="color_palette_toggle">{L_COLOUR_SWATCH}</a> ]</span>
- <div id="color_palette_placeholder" style="display: none;" data-orientation="h" data-height="12" data-width="15" data-target="#group_colour"></div>
+ <div id="color_palette_placeholder" style="display: none;" data-color-palette="h" data-height="12" data-width="15" data-target="#group_colour"></div>
</dd>
</dl>
<dl>
diff --git a/phpBB/adm/style/acp_language.html b/phpBB/adm/style/acp_language.html
index 79fef94207..5e3ac9532a 100644
--- a/phpBB/adm/style/acp_language.html
+++ b/phpBB/adm/style/acp_language.html
@@ -69,7 +69,7 @@
<p>{L_ACP_LANGUAGE_PACKS_EXPLAIN}</p>
<fieldset class="quick">
- <span class="small"><a href="https://www.phpbb.com/go/customise/language-packs/3.2" target="_blank">{L_BROWSE_LANGUAGE_PACKS_DATABASE}</a></span>
+ <span class="small"><a href="https://www.phpbb.com/go/customise/language-packs/3.3" target="_blank">{L_BROWSE_LANGUAGE_PACKS_DATABASE}</a></span>
</fieldset>
<table class="table1 zebra-table">
diff --git a/phpBB/adm/style/acp_main.html b/phpBB/adm/style/acp_main.html
index 12477a4b77..ce55d81375 100644
--- a/phpBB/adm/style/acp_main.html
+++ b/phpBB/adm/style/acp_main.html
@@ -94,90 +94,113 @@
<!-- EVENT acp_main_notice_after -->
- <table class="table1 two-columns no-header" data-no-responsive-header="true">
- <caption>{L_FORUM_STATS}</caption>
- <col class="col1" /><col class="col2" /><col class="col1" /><col class="col2" />
- <thead>
- <tr>
- <th>{L_STATISTIC}</th>
- <th>{L_VALUE}</th>
- <th>{L_STATISTIC}</th>
- <th>{L_VALUE}</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>{L_NUMBER_POSTS}{L_COLON} </td>
- <td><strong>{TOTAL_POSTS}</strong></td>
- <td>{L_POSTS_PER_DAY}{L_COLON} </td>
- <td><strong>{POSTS_PER_DAY}</strong></td>
- </tr>
- <tr>
- <td>{L_NUMBER_TOPICS}{L_COLON} </td>
- <td><strong>{TOTAL_TOPICS}</strong></td>
- <td>{L_TOPICS_PER_DAY}{L_COLON} </td>
- <td><strong>{TOPICS_PER_DAY}</strong></td>
- </tr>
- <tr>
- <td>{L_NUMBER_USERS}{L_COLON} </td>
- <td><strong>{TOTAL_USERS}</strong></td>
- <td>{L_USERS_PER_DAY}{L_COLON} </td>
- <td><strong>{USERS_PER_DAY}</strong></td>
- </tr>
- <tr>
- <td>{L_NUMBER_FILES}{L_COLON} </td>
- <td><strong>{TOTAL_FILES}</strong></td>
- <td>{L_FILES_PER_DAY}{L_COLON} </td>
- <td><strong>{FILES_PER_DAY}</strong></td>
- </tr>
- <tr>
- <td>{L_BOARD_STARTED}{L_COLON} </td>
- <td><strong>{START_DATE}</strong></td>
- <td>{L_AVATAR_DIR_SIZE}{L_COLON} </td>
- <td><strong>{AVATAR_DIR_SIZE}</strong></td>
- </tr>
- <tr>
- <td>{L_DATABASE_SIZE}{L_COLON} </td>
- <td><strong>{DBSIZE}</strong></td>
- <td>{L_UPLOAD_DIR_SIZE}{L_COLON} </td>
- <td><strong>{UPLOAD_DIR_SIZE}</strong></td>
- </tr>
- <tr>
- <td>{L_DATABASE_SERVER_INFO}{L_COLON} </td>
- <td><strong>{DATABASE_INFO}</strong></td>
- <td>{L_GZIP_COMPRESSION}{L_COLON} </td>
- <td><strong>{GZIP_COMPRESSION}</strong></td>
- </tr>
- <tr>
- <td>{L_PHP_VERSION}{L_COLON} </td>
- <td><strong>{PHP_VERSION_INFO}</strong></td>
- <!-- IF S_TOTAL_ORPHAN -->
- <td>{L_NUMBER_ORPHAN}{L_COLON} </td>
- <td>
- <!-- IF TOTAL_ORPHAN > 0 -->
- <a href="{U_ATTACH_ORPHAN}" title="{L_MORE_INFORMATION}"><strong>{TOTAL_ORPHAN}</strong></a>
- <!-- ELSE -->
- <strong>{TOTAL_ORPHAN}</strong>
- <!-- ENDIF -->
- </td>
- <!-- ELSE -->
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <!-- ENDIF -->
- </tr>
- <!-- IF S_VERSIONCHECK -->
- <tr>
- <td>{L_BOARD_VERSION}{L_COLON} </td>
- <td>
- <strong><a href="{U_VERSIONCHECK}" <!-- IF S_VERSION_UP_TO_DATE -->style="color: #228822;" <!-- ELSEIF not S_VERSIONCHECK_FAIL -->style="color: #BC2A4D;" <!-- ENDIF -->title="{L_MORE_INFORMATION}">{BOARD_VERSION}</a></strong> [&nbsp;<a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a>&nbsp;]
- </td>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- </tr>
- <!-- ENDIF -->
- </tbody>
- </table>
-
+ <div class="lside">
+ <table class="table1 zebra-table no-header" data-no-responsive-header="true">
+ <thead>
+ <tr>
+ <th>{L_STATISTIC}</th>
+ <th>{L_VALUE}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="tabled">{L_NUMBER_POSTS}{L_COLON}</td>
+ <td class="tabled"><strong>{TOTAL_POSTS}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_POSTS_PER_DAY}{L_COLON}</td>
+ <td class="tabled"><strong>{POSTS_PER_DAY}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_NUMBER_TOPICS}{L_COLON}</td>
+ <td class="tabled"><strong>{TOTAL_TOPICS}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_TOPICS_PER_DAY}{L_COLON}</td>
+ <td class="tabled"><strong>{TOPICS_PER_DAY}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_NUMBER_USERS}{L_COLON}</td>
+ <td class="tabled"><strong>{TOTAL_USERS}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_USERS_PER_DAY}{L_COLON}</td>
+ <td class="tabled"><strong>{USERS_PER_DAY}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_NUMBER_FILES}{L_COLON}</td>
+ <td class="tabled"><strong>{TOTAL_FILES}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_FILES_PER_DAY}{L_COLON}</td>
+ <td class="tabled"><strong>{FILES_PER_DAY}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">&nbsp;</td>
+ <td class="tabled">&nbsp;</td>
+ </tr>
+ </tbody>
+ </table>
+ <table class="table1 zebra-table no-header" data-no-responsive-header="true">
+ <thead>
+ <tr>
+ <th>{L_STATISTIC}</th>
+ <th>{L_VALUE}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="tabled">{L_BOARD_STARTED}{L_COLON}</td>
+ <td class="tabled"><strong>{START_DATE}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_AVATAR_DIR_SIZE}{L_COLON}</td>
+ <td class="tabled"><strong>{AVATAR_DIR_SIZE}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_DATABASE_SIZE}{L_COLON}</td>
+ <td class="tabled"><strong>{DBSIZE}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_UPLOAD_DIR_SIZE}{L_COLON}</td>
+ <td class="tabled"><strong>{UPLOAD_DIR_SIZE}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_DATABASE_SERVER_INFO}{L_COLON}</td>
+ <td class="tabled"><strong>{DATABASE_INFO}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_GZIP_COMPRESSION}{L_COLON}</td>
+ <td class="tabled"><strong>{GZIP_COMPRESSION}</strong></td>
+ </tr>
+ <tr>
+ <td class="tabled">{L_PHP_VERSION}{L_COLON}</td>
+ <td class="tabled"><strong>{PHP_VERSION_INFO}</strong></td>
+ </tr>
+ <tr>
+ <!-- IF S_TOTAL_ORPHAN -->
+ <td class="tabled">{L_NUMBER_ORPHAN}{L_COLON}</td>
+ <td class="tabled">
+ <!-- IF TOTAL_ORPHAN > 0 -->
+ <a href="{U_ATTACH_ORPHAN}" title="{L_MORE_INFORMATION}"><strong>{TOTAL_ORPHAN}</strong></a>
+ <!-- ELSE -->
+ <strong>{TOTAL_ORPHAN}</strong>
+ <!-- ENDIF -->
+ </td>
+ <!-- ELSE -->
+ <!-- ENDIF -->
+ </tr>
+ <!-- IF S_VERSIONCHECK -->
+ <tr>
+ <td class="tabled">{L_BOARD_VERSION}{L_COLON}</td>
+ <td class="tabled">
+ <strong><a href="{U_VERSIONCHECK}" <!-- IF S_VERSION_UP_TO_DATE -->style="color: #228822;" <!-- ELSEIF not S_VERSIONCHECK_FAIL -->style="color: #BC2A4D;" <!-- ENDIF -->title="{L_MORE_INFORMATION}">{BOARD_VERSION}</a></strong> [&nbsp;<a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a>&nbsp;]
+ </td>
+ </tr>
+ <!-- ENDIF -->
+ </tbody>
+ </table>
+ </div>
<!-- IF S_ACTION_OPTIONS -->
<fieldset>
<legend>{L_STATISTIC_RESYNC_OPTIONS}</legend>
diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html
index cfa804090f..c09294beaf 100644
--- a/phpBB/adm/style/acp_styles.html
+++ b/phpBB/adm/style/acp_styles.html
@@ -33,7 +33,7 @@
<!-- IF L_EXPLAIN --><p>{L_EXPLAIN}</p><!-- ENDIF -->
<fieldset class="quick">
- <span class="small"><a href="https://www.phpbb.com/go/customise/styles/3.2" target="_blank">{L_BROWSE_STYLES_DATABASE}</a></span>
+ <span class="small"><a href="https://www.phpbb.com/go/customise/styles/3.3" target="_blank">{L_BROWSE_STYLES_DATABASE}</a></span>
</fieldset>
<form id="acp_styles" method="post" action="{U_ACTION}">
diff --git a/phpBB/adm/style/acp_users_signature.html b/phpBB/adm/style/acp_users_signature.html
index 180c24c96d..40f0fc25d9 100644
--- a/phpBB/adm/style/acp_users_signature.html
+++ b/phpBB/adm/style/acp_users_signature.html
@@ -26,7 +26,7 @@
<!-- INCLUDE acp_posting_buttons.html -->
<dl class="responsive-columns">
- <dt style="width: 90px;" id="color_palette_placeholder" data-orientation="v" data-height="12" data-width="15" data-bbcode="true">
+ <dt style="width: 90px;" id="color_palette_placeholder" data-color-palette="v" data-height="12" data-width="15" data-bbcode="true">
</dt>
<dd style="margin-{S_CONTENT_FLOW_BEGIN}: 90px;"><textarea name="signature" rows="10" cols="60" style="width: 95%;" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" onfocus="initInsertions();" data-bbcode="true">{SIGNATURE}</textarea></dd>
<dd style="margin-{S_CONTENT_FLOW_BEGIN}: 90px; margin-top: 5px;">
diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css
index 7cf6c22236..d0f6583ce2 100644
--- a/phpBB/adm/style/admin.css
+++ b/phpBB/adm/style/admin.css
@@ -1,4 +1,4 @@
-/* phpBB 3.2 Admin Style Sheet
+/* phpBB 3.3 Admin Style Sheet
------------------------------------------------------------------------
Original author: subBlue ( http://www.subblue.com/ )
Copyright (c) phpBB Limited <https://www.phpbb.com>
@@ -723,9 +723,13 @@ td {
}
.table1 {
- border-collapse: separate;
- border-spacing: 1px;
clear: both;
+ border-spacing: 1px;
+ border-collapse: separate;
+}
+
+.tabled {
+ width: 25%;
}
dt#color_palette_placeholder table {
diff --git a/phpBB/adm/style/admin.js b/phpBB/adm/style/admin.js
index 551c78a4a3..5fdd07356c 100644
--- a/phpBB/adm/style/admin.js
+++ b/phpBB/adm/style/admin.js
@@ -229,6 +229,64 @@ function parse_document(container)
}
/**
+ * Extension actions helper functions
+ */
+function move_to_enabled(element)
+{
+ var disabled_header = document.querySelector('#ext_disabled_header');
+ disabled_header.parentNode.insertBefore(element, disabled_header);
+ element.classList.remove('ext_disabled');
+ element.classList.add('ext_enabled');
+}
+function move_to_disabled(element)
+{
+ var table_body = document.querySelector('#ext_disabled_header').parentNode;
+ table_body.appendChild(element);
+ element.classList.remove('ext_enabled');
+ element.classList.add('ext_disabled');
+}
+function set_actions(container, actions) {
+ container.innerHTML = '';
+ for (var i = 0; i < actions.length; i++) {
+ var a = document.createElement('a');
+ a.href = actions[i].U_ACTION.split('&amp;').join('&'); // replace all occurances
+ a.title = actions[i].L_ACTION_EXPLAIN;
+ if (actions[i].COLOR) {
+ a.style = actions[i].COLOR;
+ }
+ a.innerHTML = actions[i].L_ACTION;
+ // ajaxify this action as well
+ phpbb.ajaxify({
+ selector: a,
+ refresh: true,
+ callback: actions[i].ACTION_AJAX
+ });
+
+ container.appendChild(a);
+
+ if (i < actions.length - 1) {
+ container.innerHTML += '&nbsp;|&nbsp;';
+ }
+ }
+}
+function show_enabled_header() {
+ document.querySelector('#ext_enabled_header').classList.remove('hidden');
+}
+function show_disabled_header() {
+ document.querySelector('#ext_disabled_header').classList.remove('hidden');
+}
+function hide_disabled_header_if_empty() {
+ if (!document.querySelector('.ext_disabled')) {
+ document.querySelector('#ext_disabled_header').classList.add('hidden');
+ }
+}
+function hide_enabled_header_if_empty() {
+ if (!document.querySelector('.ext_enabled')) {
+ document.querySelector('#ext_enabled_header').classList.add('hidden');
+ }
+}
+
+/**
* Run onload functions
*/
(function($) {
diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js
index 895bb056e5..644e74bef7 100644
--- a/phpBB/adm/style/ajax.js
+++ b/phpBB/adm/style/ajax.js
@@ -158,6 +158,34 @@ phpbb.addAjaxCallback('row_delete', function(res) {
});
/**
+ * Callbacks for extension actions
+ */
+phpbb.addAjaxCallback('ext_enable', function(res) {
+ if (res.EXT_ENABLE_SUCCESS) {
+ move_to_enabled(this.parentNode.parentNode);
+ set_actions(this.parentNode, res.ACTIONS);
+ show_enabled_header();
+ hide_disabled_header_if_empty();
+ }
+});
+phpbb.addAjaxCallback('ext_delete_data', function(res) {
+ if (res.EXT_DELETE_DATA_SUCCESS) {
+ move_to_disabled(this.parentNode.parentNode);
+ set_actions(this.parentNode, res.ACTIONS);
+ show_disabled_header();
+ hide_enabled_header_if_empty();
+ }
+});
+phpbb.addAjaxCallback('ext_disable', function(res) {
+ if (res.EXT_DISABLE_SUCCESS) {
+ move_to_disabled(this.parentNode.parentNode);
+ set_actions(this.parentNode, res.ACTIONS);
+ show_disabled_header();
+ hide_enabled_header_if_empty();
+ }
+});
+
+/**
* Handler for submitting permissions form in chunks
* This call will submit permissions forms in chunks of 5 fieldsets.
*/
diff --git a/phpBB/adm/style/captcha_recaptcha.html b/phpBB/adm/style/captcha_recaptcha.html
index 3f61c76cb1..563bd98835 100644
--- a/phpBB/adm/style/captcha_recaptcha.html
+++ b/phpBB/adm/style/captcha_recaptcha.html
@@ -5,8 +5,9 @@
<div>{L_RECAPTCHA_NOSCRIPT}</div>
</noscript>
+ {L_RECAPTCHA_INVISIBLE}
<script src="{RECAPTCHA_SERVER}.js?hl={LA_RECAPTCHA_LANG}" async defer></script>
- <div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}"></div>
+ <div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}" data-size="invisible"></div>
</dd>
</dl>
<!-- ELSE -->
diff --git a/phpBB/adm/style/installer_footer.html b/phpBB/adm/style/installer_footer.html
index 8b3b04d8a5..81a85d1b01 100644
--- a/phpBB/adm/style/installer_footer.html
+++ b/phpBB/adm/style/installer_footer.html
@@ -23,7 +23,7 @@ installLang = {
</script>
<script src="{T_JQUERY_LINK}"></script>
-<!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js">\x3C/script>');</script><!-- ENDIF -->
+<!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery-3.4.1.min.js">\x3C/script>');</script><!-- ENDIF -->
<script src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- INCLUDEJS admin.js -->
{$SCRIPTS}
diff --git a/phpBB/adm/style/overall_footer.html b/phpBB/adm/style/overall_footer.html
index 3ab633e04b..7a5b620f48 100644
--- a/phpBB/adm/style/overall_footer.html
+++ b/phpBB/adm/style/overall_footer.html
@@ -34,7 +34,7 @@
</div>
<script src="{T_JQUERY_LINK}"></script>
-<!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF -->
+<!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery-3.4.1.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF -->
<script src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- INCLUDEJS ajax.js -->
<!-- INCLUDEJS admin.js -->
diff --git a/phpBB/adm/style/permission_forum_copy.html b/phpBB/adm/style/permission_forum_copy.html
index b1539aff12..0560648baf 100644
--- a/phpBB/adm/style/permission_forum_copy.html
+++ b/phpBB/adm/style/permission_forum_copy.html
@@ -4,7 +4,7 @@
<h1>{L_ACP_FORUM_PERMISSIONS_COPY}</h1>
- {L_ACP_FORUM_PERMISSIONS_COPY_EXPLAIN}
+ <p>{L_ACP_FORUM_PERMISSIONS_COPY_EXPLAIN}</p>
<form id="forum_perm_copy" method="post" action="{U_ACTION}">
diff --git a/phpBB/adm/style/simple_footer.html b/phpBB/adm/style/simple_footer.html
index 4b54b83373..dd9dc90fd0 100644
--- a/phpBB/adm/style/simple_footer.html
+++ b/phpBB/adm/style/simple_footer.html
@@ -17,7 +17,7 @@
</div>
<script src="{T_JQUERY_LINK}"></script>
-<!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF -->
+<!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery-3.4.1.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF -->
<script src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- EVENT acp_simple_footer_after -->
diff --git a/phpBB/assets/cookieconsent/cookieconsent.min.css b/phpBB/assets/cookieconsent/cookieconsent.min.css
index 03c69fe82f..d4d439025b 100644
--- a/phpBB/assets/cookieconsent/cookieconsent.min.css
+++ b/phpBB/assets/cookieconsent/cookieconsent.min.css
@@ -1,6 +1,6 @@
-.cc-window{opacity:1;transition:opacity 1s ease}.cc-window.cc-invisible{opacity:0}.cc-animate.cc-revoke{transition:transform 1s ease}.cc-animate.cc-revoke.cc-top{transform:translateY(-2em)}.cc-animate.cc-revoke.cc-bottom{transform:translateY(2em)}.cc-animate.cc-revoke.cc-active.cc-bottom,.cc-animate.cc-revoke.cc-active.cc-top,.cc-revoke:hover{transform:translateY(0)}.cc-grower{max-height:0;overflow:hidden;transition:max-height 1s}
-.cc-link,.cc-revoke:hover{text-decoration:underline}.cc-revoke,.cc-window{position:fixed;overflow:hidden;box-sizing:border-box;font-family:Helvetica,Calibri,Arial,sans-serif;font-size:16px;line-height:1.5em;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;z-index:9999}.cc-window.cc-static{position:static}.cc-window.cc-floating{padding:2em;max-width:24em;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner{padding:1em 1.8em;width:100%;-ms-flex-direction:row;flex-direction:row}.cc-revoke{padding:.5em}.cc-header{font-size:18px;font-weight:700}.cc-btn,.cc-close,.cc-link,.cc-revoke{cursor:pointer}.cc-link{opacity:.8;display:inline-block;padding:.2em}.cc-link:hover{opacity:1}.cc-link:active,.cc-link:visited{color:initial}.cc-btn{display:block;padding:.4em .8em;font-size:.9em;font-weight:700;border-width:2px;border-style:solid;text-align:center;white-space:nowrap}.cc-banner .cc-btn:last-child{min-width:140px}.cc-highlight .cc-btn:first-child{background-color:transparent;border-color:transparent}.cc-highlight .cc-btn:first-child:focus,.cc-highlight .cc-btn:first-child:hover{background-color:transparent;text-decoration:underline}.cc-close{display:block;position:absolute;top:.5em;right:.5em;font-size:1.6em;opacity:.9;line-height:.75}.cc-close:focus,.cc-close:hover{opacity:1}
-.cc-revoke.cc-top{top:0;left:3em;border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}.cc-revoke.cc-bottom{bottom:0;left:3em;border-top-left-radius:.5em;border-top-right-radius:.5em}.cc-revoke.cc-left{left:3em;right:unset}.cc-revoke.cc-right{right:3em;left:unset}.cc-top{top:1em}.cc-left{left:1em}.cc-right{right:1em}.cc-bottom{bottom:1em}.cc-floating>.cc-link{margin-bottom:1em}.cc-floating .cc-message{display:block;margin-bottom:1em}.cc-window.cc-floating .cc-compliance{-ms-flex:1;flex:1}.cc-window.cc-banner{-ms-flex-align:center;align-items:center}.cc-banner.cc-top{left:0;right:0;top:0}.cc-banner.cc-bottom{left:0;right:0;bottom:0}.cc-banner .cc-message{-ms-flex:1;flex:1}.cc-compliance{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:justify;align-content:space-between}.cc-compliance>.cc-btn{-ms-flex:1;flex:1}.cc-btn+.cc-btn{margin-left:.5em}
-@media print{.cc-revoke,.cc-window{display:none}}@media screen and (max-width:900px){.cc-btn{white-space:normal}}@media screen and (max-width:414px) and (orientation:portrait),screen and (max-width:736px) and (orientation:landscape){.cc-window.cc-top{top:0}.cc-window.cc-bottom{bottom:0}.cc-window.cc-banner,.cc-window.cc-left,.cc-window.cc-right{left:0;right:0}.cc-window.cc-banner{-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner .cc-compliance{-ms-flex:1;flex:1}.cc-window.cc-floating{max-width:none}.cc-window .cc-message{margin-bottom:1em}.cc-window.cc-banner{-ms-flex-align:unset;align-items:unset}}
-.cc-floating.cc-theme-classic{padding:1.2em;border-radius:5px}.cc-floating.cc-type-info.cc-theme-classic .cc-compliance{text-align:center;display:inline;-ms-flex:none;flex:none}.cc-theme-classic .cc-btn{border-radius:5px}.cc-theme-classic .cc-btn:last-child{min-width:140px}.cc-floating.cc-type-info.cc-theme-classic .cc-btn{display:inline-block}
-.cc-theme-edgeless.cc-window{padding:0}.cc-floating.cc-theme-edgeless .cc-message{margin:2em 2em 1.5em}.cc-banner.cc-theme-edgeless .cc-btn{margin:0;padding:.8em 1.8em;height:100%}.cc-banner.cc-theme-edgeless .cc-message{margin-left:1em}.cc-floating.cc-theme-edgeless .cc-btn+.cc-btn{margin-left:0} \ No newline at end of file
+.cc-window{opacity:1;-webkit-transition:opacity 1s ease;transition:opacity 1s ease}.cc-window.cc-invisible{opacity:0}.cc-animate.cc-revoke{-webkit-transition:transform 1s ease;-webkit-transition:-webkit-transform 1s ease;transition:-webkit-transform 1s ease;transition:transform 1s ease;transition:transform 1s ease,-webkit-transform 1s ease}.cc-animate.cc-revoke.cc-top{-webkit-transform:translateY(-2em);transform:translateY(-2em)}.cc-animate.cc-revoke.cc-bottom{-webkit-transform:translateY(2em);transform:translateY(2em)}.cc-animate.cc-revoke.cc-active.cc-top{-webkit-transform:translateY(0);transform:translateY(0)}.cc-animate.cc-revoke.cc-active.cc-bottom{-webkit-transform:translateY(0);transform:translateY(0)}.cc-revoke:hover{-webkit-transform:translateY(0);transform:translateY(0)}.cc-grower{max-height:0;overflow:hidden;-webkit-transition:max-height 1s;transition:max-height 1s}
+.cc-revoke,.cc-window{position:fixed;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:Helvetica,Calibri,Arial,sans-serif;font-size:16px;line-height:1.5em;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;z-index:9999}.cc-window.cc-static{position:static}.cc-window.cc-floating{padding:2em;max-width:24em;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner{padding:1em 1.8em;width:100%;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.cc-revoke{padding:.5em}.cc-revoke:hover{text-decoration:underline}.cc-header{font-size:18px;font-weight:700}.cc-btn,.cc-close,.cc-link,.cc-revoke{cursor:pointer}.cc-link{opacity:.8;display:inline-block;padding:.2em;text-decoration:underline}.cc-link:hover{opacity:1}.cc-link:active,.cc-link:visited{color:initial}.cc-btn{display:block;padding:.4em .8em;font-size:.9em;font-weight:700;border-width:2px;border-style:solid;text-align:center;white-space:nowrap}.cc-highlight .cc-btn:first-child{background-color:transparent;border-color:transparent}.cc-highlight .cc-btn:first-child:focus,.cc-highlight .cc-btn:first-child:hover{background-color:transparent;text-decoration:underline}.cc-close{display:block;position:absolute;top:.5em;right:.5em;font-size:1.6em;opacity:.9;line-height:.75}.cc-close:focus,.cc-close:hover{opacity:1}
+.cc-revoke.cc-top{top:0;left:3em;border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}.cc-revoke.cc-bottom{bottom:0;left:3em;border-top-left-radius:.5em;border-top-right-radius:.5em}.cc-revoke.cc-left{left:3em;right:unset}.cc-revoke.cc-right{right:3em;left:unset}.cc-top{top:1em}.cc-left{left:1em}.cc-right{right:1em}.cc-bottom{bottom:1em}.cc-floating>.cc-link{margin-bottom:1em}.cc-floating .cc-message{display:block;margin-bottom:1em}.cc-window.cc-floating .cc-compliance{-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto}.cc-window.cc-banner{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.cc-banner.cc-top{left:0;right:0;top:0}.cc-banner.cc-bottom{left:0;right:0;bottom:0}.cc-banner .cc-message{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;max-width:100%;margin-right:1em}.cc-compliance{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:justify;align-content:space-between}.cc-floating .cc-compliance>.cc-btn{-webkit-box-flex:1;-ms-flex:1;flex:1}.cc-btn+.cc-btn{margin-left:.5em}
+@media print{.cc-revoke,.cc-window{display:none}}@media screen and (max-width:900px){.cc-btn{white-space:normal}}@media screen and (max-width:414px) and (orientation:portrait),screen and (max-width:736px) and (orientation:landscape){.cc-window.cc-top{top:0}.cc-window.cc-bottom{bottom:0}.cc-window.cc-banner,.cc-window.cc-floating,.cc-window.cc-left,.cc-window.cc-right{left:0;right:0}.cc-window.cc-banner{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner .cc-compliance{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.cc-window.cc-floating{max-width:none}.cc-window .cc-message{margin-bottom:1em}.cc-window.cc-banner{-webkit-box-align:unset;-ms-flex-align:unset;align-items:unset}.cc-window.cc-banner .cc-message{margin-right:0}}
+.cc-floating.cc-theme-classic{padding:1.2em;border-radius:5px}.cc-floating.cc-type-info.cc-theme-classic .cc-compliance{text-align:center;display:inline;-webkit-box-flex:0;-ms-flex:none;flex:none}.cc-theme-classic .cc-btn{border-radius:5px}.cc-theme-classic .cc-btn:last-child{min-width:140px}.cc-floating.cc-type-info.cc-theme-classic .cc-btn{display:inline-block}
+.cc-theme-edgeless.cc-window{padding:0}.cc-floating.cc-theme-edgeless .cc-message{margin:2em;margin-bottom:1.5em}.cc-banner.cc-theme-edgeless .cc-btn{margin:0;padding:.8em 1.8em;height:100%}.cc-banner.cc-theme-edgeless .cc-message{margin-left:1em}.cc-floating.cc-theme-edgeless .cc-btn+.cc-btn{margin-left:0} \ No newline at end of file
diff --git a/phpBB/assets/cookieconsent/cookieconsent.min.js b/phpBB/assets/cookieconsent/cookieconsent.min.js
index 8e44bdde90..1e3dccf1a7 100644
--- a/phpBB/assets/cookieconsent/cookieconsent.min.js
+++ b/phpBB/assets/cookieconsent/cookieconsent.min.js
@@ -1 +1 @@
-!function(e){if(!e.hasInitialised){var t={escapeRegExp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},hasClass:function(e,t){var i=" ";return 1===e.nodeType&&(i+e.className+i).replace(/[\n\t]/g,i).indexOf(i+t+i)>=0},addClass:function(e,t){e.className+=" "+t},removeClass:function(e,t){var i=new RegExp("\\b"+this.escapeRegExp(t)+"\\b");e.className=e.className.replace(i,"")},interpolateString:function(e,t){var i=/{{([a-z][a-z0-9\-_]*)}}/gi;return e.replace(i,function(e){return t(arguments[1])||""})},getCookie:function(e){var t="; "+document.cookie,i=t.split("; "+e+"=");return 2!=i.length?void 0:i.pop().split(";").shift()},setCookie:function(e,t,i,n,o){var s=new Date;s.setDate(s.getDate()+(i||365));var r=[e+"="+t,"expires="+s.toUTCString(),"path="+(o||"/")];n&&r.push("domain="+n),document.cookie=r.join(";")},deepExtend:function(e,t){for(var i in t)t.hasOwnProperty(i)&&(i in e&&this.isPlainObject(e[i])&&this.isPlainObject(t[i])?this.deepExtend(e[i],t[i]):e[i]=t[i]);return e},throttle:function(e,t){var i=!1;return function(){i||(e.apply(this,arguments),i=!0,setTimeout(function(){i=!1},t))}},hash:function(e){var t,i,n,o=0;if(0===e.length)return o;for(t=0,n=e.length;t<n;++t)i=e.charCodeAt(t),o=(o<<5)-o+i,o|=0;return o},normaliseHex:function(e){return"#"==e[0]&&(e=e.substr(1)),3==e.length&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),e},getContrast:function(e){e=this.normaliseHex(e);var t=parseInt(e.substr(0,2),16),i=parseInt(e.substr(2,2),16),n=parseInt(e.substr(4,2),16),o=(299*t+587*i+114*n)/1e3;return o>=128?"#000":"#fff"},getLuminance:function(e){var t=parseInt(this.normaliseHex(e),16),i=38,n=(t>>16)+i,o=(t>>8&255)+i,s=(255&t)+i,r=(16777216+65536*(n<255?n<1?0:n:255)+256*(o<255?o<1?0:o:255)+(s<255?s<1?0:s:255)).toString(16).slice(1);return"#"+r},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object}};e.status={deny:"deny",allow:"allow",dismiss:"dismiss"},e.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var i in t)if(t.hasOwnProperty(i)&&"undefined"!=typeof e.style[i+"ransition"])return t[i];return""}(),e.hasTransition=!!e.transitionEnd;var i=Object.keys(e.status).map(t.escapeRegExp);e.customStyles={},e.Popup=function(){function n(){this.initialise.apply(this,arguments)}function o(e){this.openingTimeout=null,t.removeClass(e,"cc-invisible")}function s(t){t.style.display="none",t.removeEventListener(e.transitionEnd,this.afterTransition),this.afterTransition=null}function r(){var t=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return t(e.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return t(e.status.allow),!0;var i=Object.keys(e.status),n=this.getStatus(),o=i.indexOf(n)>=0;return o&&t(n),o}function a(){var e=this.options.position.split("-"),t=[];return e.forEach(function(e){t.push("cc-"+e)}),t}function c(){var e=this.options,i="top"==e.position||"bottom"==e.position?"banner":"floating";t.isMobile()&&(i="floating");var n=["cc-"+i,"cc-type-"+e.type,"cc-theme-"+e.theme];e["static"]&&n.push("cc-static"),n.push.apply(n,a.call(this));p.call(this,this.options.palette);return this.customStyleSelector&&n.push(this.customStyleSelector),n}function l(){var e={},i=this.options;i.showLink||(i.elements.link="",i.elements.messagelink=i.elements.message),Object.keys(i.elements).forEach(function(n){e[n]=t.interpolateString(i.elements[n],function(e){var t=i.content[e];return e&&"string"==typeof t&&t.length?t:""})});var n=i.compliance[i.type];n||(n=i.compliance.info),e.compliance=t.interpolateString(n,function(t){return e[t]});var o=i.layouts[i.layout];return o||(o=i.layouts.basic),t.interpolateString(o,function(t){return e[t]})}function u(i){var n=this.options,o=document.createElement("div"),s=n.container&&1===n.container.nodeType?n.container:document.body;o.innerHTML=i;var r=o.children[0];return r.style.display="none",t.hasClass(r,"cc-window")&&e.hasTransition&&t.addClass(r,"cc-invisible"),this.onButtonClick=h.bind(this),r.addEventListener("click",this.onButtonClick),n.autoAttach&&(s.firstChild?s.insertBefore(r,s.firstChild):s.appendChild(r)),r}function h(n){var o=n.target;if(t.hasClass(o,"cc-btn")){var s=o.className.match(new RegExp("\\bcc-("+i.join("|")+")\\b")),r=s&&s[1]||!1;r&&(this.setStatus(r),this.close(!0))}t.hasClass(o,"cc-close")&&(this.setStatus(e.status.dismiss),this.close(!0)),t.hasClass(o,"cc-revoke")&&this.revokeChoice()}function p(e){var i=t.hash(JSON.stringify(e)),n="cc-color-override-"+i,o=t.isPlainObject(e);return this.customStyleSelector=o?n:null,o&&d(i,e,"."+n),o}function d(i,n,o){if(e.customStyles[i])return void++e.customStyles[i].references;var s={},r=n.popup,a=n.button,c=n.highlight;r&&(r.text=r.text?r.text:t.getContrast(r.background),r.link=r.link?r.link:r.text,s[o+".cc-window"]=["color: "+r.text,"background-color: "+r.background],s[o+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],s[o+" .cc-link,"+o+" .cc-link:active,"+o+" .cc-link:visited"]=["color: "+r.link],a&&(a.text=a.text?a.text:t.getContrast(a.background),a.border=a.border?a.border:"transparent",s[o+" .cc-btn"]=["color: "+a.text,"border-color: "+a.border,"background-color: "+a.background],"transparent"!=a.background&&(s[o+" .cc-btn:hover, "+o+" .cc-btn:focus"]=["background-color: "+v(a.background)]),c?(c.text=c.text?c.text:t.getContrast(c.background),c.border=c.border?c.border:"transparent",s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+c.text,"border-color: "+c.border,"background-color: "+c.background]):s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var l=document.createElement("style");document.head.appendChild(l),e.customStyles[i]={references:1,element:l.sheet};var u=-1;for(var h in s)s.hasOwnProperty(h)&&l.sheet.insertRule(h+"{"+s[h].join(";")+"}",++u)}function v(e){return e=t.normaliseHex(e),"000000"==e?"#222":t.getLuminance(e)}function f(i){if(t.isPlainObject(i)){var n=t.hash(JSON.stringify(i)),o=e.customStyles[n];if(o&&!--o.references){var s=o.element.ownerNode;s&&s.parentNode&&s.parentNode.removeChild(s),e.customStyles[n]=null}}}function m(e,t){for(var i=0,n=e.length;i<n;++i){var o=e[i];if(o instanceof RegExp&&o.test(t)||"string"==typeof o&&o.length&&o===t)return!0}return!1}function b(){var t=this.setStatus.bind(this),i=this.options.dismissOnTimeout;"number"==typeof i&&i>=0&&(this.dismissTimeout=window.setTimeout(function(){t(e.status.dismiss)},Math.floor(i)));var n=this.options.dismissOnScroll;if("number"==typeof n&&n>=0){var o=function(i){window.pageYOffset>Math.floor(n)&&(t(e.status.dismiss),window.removeEventListener("scroll",o),this.onWindowScroll=null)};this.onWindowScroll=o,window.addEventListener("scroll",o)}}function y(){if("info"!=this.options.type&&(this.options.revokable=!0),t.isMobile()&&(this.options.animateRevokable=!1),this.options.revokable){var e=a.call(this);this.options.animateRevokable&&e.push("cc-animate"),this.customStyleSelector&&e.push(this.customStyleSelector);var i=this.options.revokeBtn.replace("{{classes}}",e.join(" "));this.revokeBtn=u.call(this,i);var n=this.revokeBtn;if(this.options.animateRevokable){var o=t.throttle(function(e){var i=!1,o=20,s=window.innerHeight-20;t.hasClass(n,"cc-top")&&e.clientY<o&&(i=!0),t.hasClass(n,"cc-bottom")&&e.clientY>s&&(i=!0),i?t.hasClass(n,"cc-active")||t.addClass(n,"cc-active"):t.hasClass(n,"cc-active")&&t.removeClass(n,"cc-active")},200);this.onMouseMove=o,window.addEventListener("mousemove",o)}}}var g={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"http://cookiesandyou.com",close:"&#x274c;"},elements:{header:'<span class="cc-header">{{header}}</span>&nbsp;',message:'<span id="cookieconsent:desc" class="cc-message">{{message}}</span>',messagelink:'<span id="cookieconsent:desc" class="cc-message">{{message}} <a aria-label="learn more about cookies" role=button tabindex="0" class="cc-link" href="{{href}}" target="_blank">{{link}}</a></span>',dismiss:'<a aria-label="dismiss cookie message" role=button tabindex="0" class="cc-btn cc-dismiss">{{dismiss}}</a>',allow:'<a aria-label="allow cookies" role=button tabindex="0" class="cc-btn cc-allow">{{allow}}</a>',deny:'<a aria-label="deny cookies" role=button tabindex="0" class="cc-btn cc-deny">{{deny}}</a>',link:'<a aria-label="learn more about cookies" role=button tabindex="0" class="cc-link" href="{{href}}" target="_blank">{{link}}</a>',close:'<span aria-label="dismiss cookie message" role=button tabindex="0" class="cc-close">{{close}}</span>'},window:'<div role="dialog" aria-live="polite" aria-label="cookieconsent" aria-describedby="cookieconsent:desc" class="cc-window {{classes}}"><!--googleoff: all-->{{children}}<!--googleon: all--></div>',revokeBtn:'<div class="cc-revoke {{classes}}">Cookie Policy</div>',compliance:{info:'<div class="cc-compliance">{{dismiss}}</div>',"opt-in":'<div class="cc-compliance cc-highlight">{{dismiss}}{{allow}}</div>',"opt-out":'<div class="cc-compliance cc-highlight">{{deny}}{{dismiss}}</div>'},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block","static":!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null};return n.prototype.initialise=function(e){this.options&&this.destroy(),t.deepExtend(this.options={},g),t.isPlainObject(e)&&t.deepExtend(this.options,e),r.call(this)&&(this.options.enabled=!1),m(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),m(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var i=this.options.window.replace("{{classes}}",c.call(this).join(" ")).replace("{{children}}",l.call(this)),n=this.options.overrideHTML;if("string"==typeof n&&n.length&&(i=n),this.options["static"]){var o=u.call(this,'<div class="cc-grower">'+i+"</div>");o.style.display="",this.element=o.firstChild,this.element.style.display="none",t.addClass(this.element,"cc-invisible")}else this.element=u.call(this,i);b.call(this),y.call(this),this.options.autoOpen&&this.autoOpen()},n.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,f(this.options.palette),this.options=null},n.prototype.open=function(t){if(this.element)return this.isOpen()||(e.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},n.prototype.close=function(t){if(this.element)return this.isOpen()&&(e.hasTransition?this.fadeOut():this.element.style.display="none",t&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},n.prototype.fadeIn=function(){var i=this.element;if(e.hasTransition&&i&&(this.afterTransition&&s.call(this,i),t.hasClass(i,"cc-invisible"))){if(i.style.display="",this.options["static"]){var n=this.element.clientHeight;this.element.parentNode.style.maxHeight=n+"px"}var r=20;this.openingTimeout=setTimeout(o.bind(this,i),r)}},n.prototype.fadeOut=function(){var i=this.element;e.hasTransition&&i&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),o.bind(this,i)),t.hasClass(i,"cc-invisible")||(this.options["static"]&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=s.bind(this,i),i.addEventListener(e.transitionEnd,this.afterTransition),t.addClass(i,"cc-invisible")))},n.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!e.hasTransition||!t.hasClass(this.element,"cc-invisible"))},n.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},n.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},n.prototype.hasAnswered=function(t){return Object.keys(e.status).indexOf(this.getStatus())>=0},n.prototype.hasConsented=function(t){var i=this.getStatus();return i==e.status.allow||i==e.status.dismiss},n.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled&&this.open()},n.prototype.setStatus=function(i){var n=this.options.cookie,o=t.getCookie(n.name),s=Object.keys(e.status).indexOf(o)>=0;Object.keys(e.status).indexOf(i)>=0?(t.setCookie(n.name,i,n.expiryDays,n.domain,n.path),this.options.onStatusChange.call(this,i,s)):this.clearStatus()},n.prototype.getStatus=function(){return t.getCookie(this.options.cookie.name)},n.prototype.clearStatus=function(){var e=this.options.cookie;t.setCookie(e.name,"",-1,e.domain,e.path)},n}(),e.Location=function(){function e(e){t.deepExtend(this.options={},s),t.isPlainObject(e)&&t.deepExtend(this.options,e),this.currentServiceIndex=-1}function i(e,t,i){var n,o=document.createElement("script");o.type="text/"+(e.type||"javascript"),o.src=e.src||e,o.async=!1,o.onreadystatechange=o.onload=function(){var e=o.readyState;clearTimeout(n),t.done||e&&!/loaded|complete/.test(e)||(t.done=!0,t(),o.onreadystatechange=o.onload=null)},document.body.appendChild(o),n=setTimeout(function(){t.done=!0,t(),o.onreadystatechange=o.onload=null},i)}function n(e,t,i,n,o){var s=new(window.XMLHttpRequest||window.ActiveXObject)("MSXML2.XMLHTTP.3.0");if(s.open(n?"POST":"GET",e,1),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-type","application/x-www-form-urlencoded"),Array.isArray(o))for(var r=0,a=o.length;r<a;++r){var c=o[r].split(":",2);s.setRequestHeader(c[0].replace(/^\s+|\s+$/g,""),c[1].replace(/^\s+|\s+$/g,""))}"function"==typeof t&&(s.onreadystatechange=function(){s.readyState>3&&t(s)}),s.send(n)}function o(e){return new Error("Error ["+(e.code||"UNKNOWN")+"]: "+e.error)}var s={timeout:5e3,services:["freegeoip","ipinfo","maxmind"],serviceDefinitions:{freegeoip:function(){return{url:"//freegeoip.net/json/?callback={callback}",isScript:!0,callback:function(e,t){try{var i=JSON.parse(t);return i.error?o(i):{code:i.country_code}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var i=JSON.parse(t);return i.error?o(i):{code:i.country}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var i=JSON.parse(t);return"ERROR"==i.statusCode?o({error:i.statusMessage}):{code:i.countryCode}}catch(n){return o({error:"Invalid response ("+n+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(e){return window.geoip2?void geoip2.country(function(t){try{e({code:t.country.iso_code})}catch(i){e(o(i))}},function(t){e(o(t))}):void e(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}};return e.prototype.getNextService=function(){var e;do e=this.getServiceByIdx(++this.currentServiceIndex);while(this.currentServiceIndex<this.options.services.length&&!e);return e},e.prototype.getServiceByIdx=function(e){var i=this.options.services[e];if("function"==typeof i){var n=i();return n.name&&t.deepExtend(n,this.options.serviceDefinitions[n.name](n)),n}return"string"==typeof i?this.options.serviceDefinitions[i]():t.isPlainObject(i)?this.options.serviceDefinitions[i.name](i):null},e.prototype.locate=function(e,t){var i=this.getNextService();return i?(this.callbackComplete=e,this.callbackError=t,void this.runService(i,this.runNextServiceOnError.bind(this))):void t(new Error("No services to run"))},e.prototype.setupUrl=function(e){var t=this.getCurrentServiceOpts();return e.url.replace(/\{(.*?)\}/g,function(i,n){if("callback"===n){var o="callback"+Date.now();return window[o]=function(t){e.__JSONP_DATA=JSON.stringify(t)},o}if(n in t.interpolateUrl)return t.interpolateUrl[n]})},e.prototype.runService=function(e,t){var o=this;if(e&&e.url&&e.callback){var s=e.isScript?i:n,r=this.setupUrl(e);s(r,function(i){var n=i?i.responseText:"";e.__JSONP_DATA&&(n=e.__JSONP_DATA,delete e.__JSONP_DATA),o.runServiceCallback.call(o,t,e,n)},this.options.timeout,e.data,e.headers)}},e.prototype.runServiceCallback=function(e,t,i){var n=this,o=function(t){s||n.onServiceResult.call(n,e,t)},s=t.callback(o,i);s&&this.onServiceResult.call(this,e,s)},e.prototype.onServiceResult=function(e,t){t instanceof Error||t&&t.error?e.call(this,t,null):e.call(this,null,t)},e.prototype.runNextServiceOnError=function(e,t){if(e){this.logError(e);var i=this.getNextService();i?this.runService(i,this.runNextServiceOnError.bind(this)):this.completeService.call(this,this.callbackError,new Error("All services failed"))}else this.completeService.call(this,this.callbackComplete,t)},e.prototype.getCurrentServiceOpts=function(){var e=this.options.services[this.currentServiceIndex];return"string"==typeof e?{name:e}:"function"==typeof e?e():t.isPlainObject(e)?e:{}},e.prototype.completeService=function(e,t){this.currentServiceIndex=-1,e&&e(t)},e.prototype.logError=function(e){var t=this.currentServiceIndex,i=this.getServiceByIdx(t);console.error("The service["+t+"] ("+i.url+") responded with the following error",e)},e}(),e.Law=function(){function e(e){this.initialise.apply(this,arguments)}var i={regionalLaw:!0,hasLaw:["AT","BE","BG","HR","CZ","CY","DK","EE","FI","FR","DE","EL","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","SK","SI","ES","SE","GB","UK"],revokable:["HR","CY","DK","EE","FR","DE","LV","LT","NL","PT","ES"],explicitAction:["HR","IT","ES"]};return e.prototype.initialise=function(e){t.deepExtend(this.options={},i),t.isPlainObject(e)&&t.deepExtend(this.options,e)},e.prototype.get=function(e){var t=this.options;return{hasLaw:t.hasLaw.indexOf(e)>=0,revokable:t.revokable.indexOf(e)>=0,explicitAction:t.explicitAction.indexOf(e)>=0}},e.prototype.applyLaw=function(e,t){var i=this.get(t);return i.hasLaw||(e.enabled=!1),this.options.regionalLaw&&(i.revokable&&(e.revokable=!0),i.explicitAction&&(e.dismissOnScroll=!1,e.dismissOnTimeout=!1)),e},e}(),e.initialise=function(t,i,n){var o=new e.Law(t.law);i||(i=function(){}),n||(n=function(){}),e.getCountryCode(t,function(n){delete t.law,delete t.location,n.code&&(t=o.applyLaw(t,n.code)),i(new e.Popup(t))},function(i){delete t.law,delete t.location,n(i,new e.Popup(t))})},e.getCountryCode=function(t,i,n){if(t.law&&t.law.countryCode)return void i({code:t.law.countryCode});if(t.location){var o=new e.Location(t.location);return void o.locate(function(e){i(e||{})},n)}i({})},e.utils=t,e.hasInitialised=!0,window.cookieconsent=e}}(window.cookieconsent||{}); \ No newline at end of file
+!function(e){if(!e.hasInitialised){var t={escapeRegExp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},hasClass:function(e,t){var i=" ";return 1===e.nodeType&&(i+e.className+i).replace(/[\n\t]/g,i).indexOf(i+t+i)>=0},addClass:function(e,t){e.className+=" "+t},removeClass:function(e,t){var i=new RegExp("\\b"+this.escapeRegExp(t)+"\\b");e.className=e.className.replace(i,"")},interpolateString:function(e,t){return e.replace(/{{([a-z][a-z0-9\-_]*)}}/gi,function(e){return t(arguments[1])||""})},getCookie:function(e){var t=("; "+document.cookie).split("; "+e+"=");return t.length<2?void 0:t.pop().split(";").shift()},setCookie:function(e,t,i,n,o,s){var r=new Date;r.setHours(r.getHours()+24*(i||365));var a=[e+"="+t,"expires="+r.toUTCString(),"path="+(o||"/")];n&&a.push("domain="+n),s&&a.push("secure"),document.cookie=a.join(";")},deepExtend:function(e,t){for(var i in t)t.hasOwnProperty(i)&&(i in e&&this.isPlainObject(e[i])&&this.isPlainObject(t[i])?this.deepExtend(e[i],t[i]):e[i]=t[i]);return e},throttle:function(e,t){var i=!1;return function(){i||(e.apply(this,arguments),i=!0,setTimeout(function(){i=!1},t))}},hash:function(e){var t,i,n=0;if(0===e.length)return n;for(t=0,i=e.length;t<i;++t)n=(n<<5)-n+e.charCodeAt(t),n|=0;return n},normaliseHex:function(e){return"#"==e[0]&&(e=e.substr(1)),3==e.length&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),e},getContrast:function(e){return e=this.normaliseHex(e),(299*parseInt(e.substr(0,2),16)+587*parseInt(e.substr(2,2),16)+114*parseInt(e.substr(4,2),16))/1e3>=128?"#000":"#fff"},getLuminance:function(e){var t=parseInt(this.normaliseHex(e),16),i=38+(t>>16),n=38+(t>>8&255),o=38+(255&t);return"#"+(16777216+65536*(i<255?i<1?0:i:255)+256*(n<255?n<1?0:n:255)+(o<255?o<1?0:o:255)).toString(16).slice(1)},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object},traverseDOMPath:function(e,i){return e&&e.parentNode?t.hasClass(e,i)?e:this.traverseDOMPath(e.parentNode,i):null}};e.status={deny:"deny",allow:"allow",dismiss:"dismiss"},e.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var i in t)if(t.hasOwnProperty(i)&&void 0!==e.style[i+"ransition"])return t[i];return""}(),e.hasTransition=!!e.transitionEnd;var i=Object.keys(e.status).map(t.escapeRegExp);e.customStyles={},e.Popup=function(){var n={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365,secure:!1},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},onNoCookieLaw:function(e,t){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"https://www.cookiesandyou.com",close:"&#x274c;",target:"_blank",policy:"Cookie Policy"},elements:{header:'<span class="cc-header">{{header}}</span>&nbsp;',message:'<span id="cookieconsent:desc" class="cc-message">{{message}}</span>',messagelink:'<span id="cookieconsent:desc" class="cc-message">{{message}} <a aria-label="learn more about cookies" role=button tabindex="0" class="cc-link" href="{{href}}" rel="noopener noreferrer nofollow" target="{{target}}">{{link}}</a></span>',dismiss:'<a aria-label="dismiss cookie message" role=button tabindex="0" class="cc-btn cc-dismiss">{{dismiss}}</a>',allow:'<a aria-label="allow cookies" role=button tabindex="0" class="cc-btn cc-allow">{{allow}}</a>',deny:'<a aria-label="deny cookies" role=button tabindex="0" class="cc-btn cc-deny">{{deny}}</a>',link:'<a aria-label="learn more about cookies" role=button tabindex="0" class="cc-link" href="{{href}}" rel="noopener noreferrer nofollow" target="{{target}}">{{link}}</a>',close:'<span aria-label="dismiss cookie message" role=button tabindex="0" class="cc-close">{{close}}</span>'},window:'<div role="dialog" aria-live="polite" aria-label="cookieconsent" aria-describedby="cookieconsent:desc" class="cc-window {{classes}}">\x3c!--googleoff: all--\x3e{{children}}\x3c!--googleon: all--\x3e</div>',revokeBtn:'<div class="cc-revoke {{classes}}">{{policy}}</div>',compliance:{info:'<div class="cc-compliance">{{dismiss}}</div>',"opt-in":'<div class="cc-compliance cc-highlight">{{deny}}{{allow}}</div>',"opt-out":'<div class="cc-compliance cc-highlight">{{deny}}{{allow}}</div>'},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block",static:!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,dismissOnWindowClick:!1,ignoreClicksFrom:["cc-revoke","cc-btn"],autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null};function o(){this.initialise.apply(this,arguments)}function s(e){this.openingTimeout=null,t.removeClass(e,"cc-invisible")}function r(t){t.style.display="none",t.removeEventListener(e.transitionEnd,this.afterTransition),this.afterTransition=null}function a(){var e=this.options.position.split("-"),t=[];return e.forEach(function(e){t.push("cc-"+e)}),t}function c(n){var o=this.options,s=document.createElement("div"),r=o.container&&1===o.container.nodeType?o.container:document.body;s.innerHTML=n;var a=s.children[0];return a.style.display="none",t.hasClass(a,"cc-window")&&e.hasTransition&&t.addClass(a,"cc-invisible"),this.onButtonClick=function(n){var o=t.traverseDOMPath(n.target,"cc-btn")||n.target;if(t.hasClass(o,"cc-btn")){var s=o.className.match(new RegExp("\\bcc-("+i.join("|")+")\\b")),r=s&&s[1]||!1;r&&(this.setStatus(r),this.close(!0))}t.hasClass(o,"cc-close")&&(this.setStatus(e.status.dismiss),this.close(!0));t.hasClass(o,"cc-revoke")&&this.revokeChoice()}.bind(this),a.addEventListener("click",this.onButtonClick),o.autoAttach&&(r.firstChild?r.insertBefore(a,r.firstChild):r.appendChild(a)),a}function l(e){return"000000"==(e=t.normaliseHex(e))?"#222":t.getLuminance(e)}function u(e,t){for(var i=0,n=e.length;i<n;++i){var o=e[i];if(o instanceof RegExp&&o.test(t)||"string"==typeof o&&o.length&&o===t)return!0}return!1}return o.prototype.initialise=function(i){this.options&&this.destroy(),t.deepExtend(this.options={},n),t.isPlainObject(i)&&t.deepExtend(this.options,i),function(){var t=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return t(e.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return t(e.status.allow),!0;var i=Object.keys(e.status),n=this.getStatus(),o=i.indexOf(n)>=0;o&&t(n);return o}.call(this)&&(this.options.enabled=!1),u(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),u(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var o=this.options.window.replace("{{classes}}",function(){var i=this.options,n="top"==i.position||"bottom"==i.position?"banner":"floating";t.isMobile()&&(n="floating");var o=["cc-"+n,"cc-type-"+i.type,"cc-theme-"+i.theme];i.static&&o.push("cc-static");o.push.apply(o,a.call(this));(function(i){var n=t.hash(JSON.stringify(i)),o="cc-color-override-"+n,s=t.isPlainObject(i);this.customStyleSelector=s?o:null,s&&function(i,n,o){if(e.customStyles[i])return void++e.customStyles[i].references;var s={},r=n.popup,a=n.button,c=n.highlight;r&&(r.text=r.text?r.text:t.getContrast(r.background),r.link=r.link?r.link:r.text,s[o+".cc-window"]=["color: "+r.text,"background-color: "+r.background],s[o+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],s[o+" .cc-link,"+o+" .cc-link:active,"+o+" .cc-link:visited"]=["color: "+r.link],a&&(a.text=a.text?a.text:t.getContrast(a.background),a.border=a.border?a.border:"transparent",s[o+" .cc-btn"]=["color: "+a.text,"border-color: "+a.border,"background-color: "+a.background],a.padding&&s[o+" .cc-btn"].push("padding: "+a.padding),"transparent"!=a.background&&(s[o+" .cc-btn:hover, "+o+" .cc-btn:focus"]=["background-color: "+(a.hover||l(a.background))]),c?(c.text=c.text?c.text:t.getContrast(c.background),c.border=c.border?c.border:"transparent",s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+c.text,"border-color: "+c.border,"background-color: "+c.background]):s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var u=document.createElement("style");document.head.appendChild(u),e.customStyles[i]={references:1,element:u.sheet};var h=-1;for(var p in s)s.hasOwnProperty(p)&&u.sheet.insertRule(p+"{"+s[p].join(";")+"}",++h)}(n,i,"."+o);return s}).call(this,this.options.palette);this.customStyleSelector&&o.push(this.customStyleSelector);return o}.call(this).join(" ")).replace("{{children}}",function(){var e={},i=this.options;i.showLink||(i.elements.link="",i.elements.messagelink=i.elements.message);Object.keys(i.elements).forEach(function(n){e[n]=t.interpolateString(i.elements[n],function(e){var t=i.content[e];return e&&"string"==typeof t&&t.length?t:""})});var n=i.compliance[i.type];n||(n=i.compliance.info);e.compliance=t.interpolateString(n,function(t){return e[t]});var o=i.layouts[i.layout];o||(o=i.layouts.basic);return t.interpolateString(o,function(t){return e[t]})}.call(this)),s=this.options.overrideHTML;if("string"==typeof s&&s.length&&(o=s),this.options.static){var r=c.call(this,'<div class="cc-grower">'+o+"</div>");r.style.display="",this.element=r.firstChild,this.element.style.display="none",t.addClass(this.element,"cc-invisible")}else this.element=c.call(this,o);(function(){var i=this.setStatus.bind(this),n=this.close.bind(this),o=this.options.dismissOnTimeout;"number"==typeof o&&o>=0&&(this.dismissTimeout=window.setTimeout(function(){i(e.status.dismiss),n(!0)},Math.floor(o)));var s=this.options.dismissOnScroll;if("number"==typeof s&&s>=0){var r=function(t){window.pageYOffset>Math.floor(s)&&(i(e.status.dismiss),n(!0),window.removeEventListener("scroll",r),this.onWindowScroll=null)};this.options.enabled&&(this.onWindowScroll=r,window.addEventListener("scroll",r))}var a=this.options.dismissOnWindowClick,c=this.options.ignoreClicksFrom;if(a){var l=function(o){for(var s=!1,r=o.path.length,a=c.length,u=0;u<r;u++)if(!s)for(var h=0;h<a;h++)s||(s=t.hasClass(o.path[u],c[h]));s||(i(e.status.dismiss),n(!0),window.removeEventListener("click",l),window.removeEventListener("touchend",l),this.onWindowClick=null)}.bind(this);this.options.enabled&&(this.onWindowClick=l,window.addEventListener("click",l),window.addEventListener("touchend",l))}}).call(this),function(){"info"!=this.options.type&&(this.options.revokable=!0);t.isMobile()&&(this.options.animateRevokable=!1);if(this.options.revokable){var e=a.call(this);this.options.animateRevokable&&e.push("cc-animate"),this.customStyleSelector&&e.push(this.customStyleSelector);var i=this.options.revokeBtn.replace("{{classes}}",e.join(" ")).replace("{{policy}}",this.options.content.policy);this.revokeBtn=c.call(this,i);var n=this.revokeBtn;if(this.options.animateRevokable){var o=t.throttle(function(e){var i=!1,o=window.innerHeight-20;t.hasClass(n,"cc-top")&&e.clientY<20&&(i=!0),t.hasClass(n,"cc-bottom")&&e.clientY>o&&(i=!0),i?t.hasClass(n,"cc-active")||t.addClass(n,"cc-active"):t.hasClass(n,"cc-active")&&t.removeClass(n,"cc-active")},200);this.onMouseMove=o,window.addEventListener("mousemove",o)}}}.call(this),this.options.autoOpen&&this.autoOpen()},o.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onWindowClick&&(window.removeEventListener("click",this.onWindowClick),this.onWindowClick=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,function(i){if(t.isPlainObject(i)){var n=t.hash(JSON.stringify(i)),o=e.customStyles[n];if(o&&!--o.references){var s=o.element.ownerNode;s&&s.parentNode&&s.parentNode.removeChild(s),e.customStyles[n]=null}}}(this.options.palette),this.options=null},o.prototype.open=function(t){if(this.element)return this.isOpen()||(e.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},o.prototype.close=function(t){if(this.element)return this.isOpen()&&(e.hasTransition?this.fadeOut():this.element.style.display="none",t&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},o.prototype.fadeIn=function(){var i=this.element;if(e.hasTransition&&i&&(this.afterTransition&&r.call(this,i),t.hasClass(i,"cc-invisible"))){if(i.style.display="",this.options.static){var n=this.element.clientHeight;this.element.parentNode.style.maxHeight=n+"px"}this.openingTimeout=setTimeout(s.bind(this,i),20)}},o.prototype.fadeOut=function(){var i=this.element;e.hasTransition&&i&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),s.bind(this,i)),t.hasClass(i,"cc-invisible")||(this.options.static&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=r.bind(this,i),i.addEventListener(e.transitionEnd,this.afterTransition),t.addClass(i,"cc-invisible")))},o.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!e.hasTransition||!t.hasClass(this.element,"cc-invisible"))},o.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},o.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},o.prototype.hasAnswered=function(t){return Object.keys(e.status).indexOf(this.getStatus())>=0},o.prototype.hasConsented=function(t){var i=this.getStatus();return i==e.status.allow||i==e.status.dismiss},o.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled?this.open():this.hasAnswered()&&this.options.revokable&&this.toggleRevokeButton(!0)},o.prototype.setStatus=function(i){var n=this.options.cookie,o=t.getCookie(n.name),s=Object.keys(e.status).indexOf(o)>=0;Object.keys(e.status).indexOf(i)>=0?(t.setCookie(n.name,i,n.expiryDays,n.domain,n.path,n.secure),this.options.onStatusChange.call(this,i,s)):this.clearStatus()},o.prototype.getStatus=function(){return t.getCookie(this.options.cookie.name)},o.prototype.clearStatus=function(){var e=this.options.cookie;t.setCookie(e.name,"",-1,e.domain,e.path)},o}(),e.Location=function(){var e={timeout:5e3,services:["ipinfo"],serviceDefinitions:{ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var i=JSON.parse(t);return i.error?s(i):{code:i.country}}catch(e){return s({error:"Invalid response ("+e+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var i=JSON.parse(t);return"ERROR"==i.statusCode?s({error:i.statusMessage}):{code:i.countryCode}}catch(e){return s({error:"Invalid response ("+e+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(e){window.geoip2?geoip2.country(function(t){try{e({code:t.country.iso_code})}catch(t){e(s(t))}},function(t){e(s(t))}):e(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}};function i(i){t.deepExtend(this.options={},e),t.isPlainObject(i)&&t.deepExtend(this.options,i),this.currentServiceIndex=-1}function n(e,t,i){var n,o=document.createElement("script");o.type="text/"+(e.type||"javascript"),o.src=e.src||e,o.async=!1,o.onreadystatechange=o.onload=function(){var e=o.readyState;clearTimeout(n),t.done||e&&!/loaded|complete/.test(e)||(t.done=!0,t(),o.onreadystatechange=o.onload=null)},document.body.appendChild(o),n=setTimeout(function(){t.done=!0,t(),o.onreadystatechange=o.onload=null},i)}function o(e,t,i,n,o){var s=new(window.XMLHttpRequest||window.ActiveXObject)("MSXML2.XMLHTTP.3.0");if(s.open(n?"POST":"GET",e,1),s.setRequestHeader("Content-type","application/x-www-form-urlencoded"),Array.isArray(o))for(var r=0,a=o.length;r<a;++r){var c=o[r].split(":",2);s.setRequestHeader(c[0].replace(/^\s+|\s+$/g,""),c[1].replace(/^\s+|\s+$/g,""))}"function"==typeof t&&(s.onreadystatechange=function(){s.readyState>3&&t(s)}),s.send(n)}function s(e){return new Error("Error ["+(e.code||"UNKNOWN")+"]: "+e.error)}return i.prototype.getNextService=function(){var e;do{e=this.getServiceByIdx(++this.currentServiceIndex)}while(this.currentServiceIndex<this.options.services.length&&!e);return e},i.prototype.getServiceByIdx=function(e){var i=this.options.services[e];if("function"==typeof i){var n=i();return n.name&&t.deepExtend(n,this.options.serviceDefinitions[n.name](n)),n}return"string"==typeof i?this.options.serviceDefinitions[i]():t.isPlainObject(i)?this.options.serviceDefinitions[i.name](i):null},i.prototype.locate=function(e,t){var i=this.getNextService();i?(this.callbackComplete=e,this.callbackError=t,this.runService(i,this.runNextServiceOnError.bind(this))):t(new Error("No services to run"))},i.prototype.setupUrl=function(e){var t=this.getCurrentServiceOpts();return e.url.replace(/\{(.*?)\}/g,function(i,n){if("callback"===n){var o="callback"+Date.now();return window[o]=function(t){e.__JSONP_DATA=JSON.stringify(t)},o}if(n in t.interpolateUrl)return t.interpolateUrl[n]})},i.prototype.runService=function(e,t){var i=this;e&&e.url&&e.callback&&(e.isScript?n:o)(this.setupUrl(e),function(n){var o=n?n.responseText:"";e.__JSONP_DATA&&(o=e.__JSONP_DATA,delete e.__JSONP_DATA),i.runServiceCallback.call(i,t,e,o)},this.options.timeout,e.data,e.headers)},i.prototype.runServiceCallback=function(e,t,i){var n=this,o=t.callback(function(t){o||n.onServiceResult.call(n,e,t)},i);o&&this.onServiceResult.call(this,e,o)},i.prototype.onServiceResult=function(e,t){t instanceof Error||t&&t.error?e.call(this,t,null):e.call(this,null,t)},i.prototype.runNextServiceOnError=function(e,t){if(e){this.logError(e);var i=this.getNextService();i?this.runService(i,this.runNextServiceOnError.bind(this)):this.completeService.call(this,this.callbackError,new Error("All services failed"))}else this.completeService.call(this,this.callbackComplete,t)},i.prototype.getCurrentServiceOpts=function(){var e=this.options.services[this.currentServiceIndex];return"string"==typeof e?{name:e}:"function"==typeof e?e():t.isPlainObject(e)?e:{}},i.prototype.completeService=function(e,t){this.currentServiceIndex=-1,e&&e(t)},i.prototype.logError=function(e){var t=this.currentServiceIndex,i=this.getServiceByIdx(t);console.warn("The service["+t+"] ("+i.url+") responded with the following error",e)},i}(),e.Law=function(){var e={regionalLaw:!0,hasLaw:["AT","BE","BG","HR","CZ","CY","DK","EE","FI","FR","DE","EL","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","SK","ES","SE","GB","UK","GR","EU"],revokable:["HR","CY","DK","EE","FR","DE","LV","LT","NL","PT","ES"],explicitAction:["HR","IT","ES"]};function i(e){this.initialise.apply(this,arguments)}return i.prototype.initialise=function(i){t.deepExtend(this.options={},e),t.isPlainObject(i)&&t.deepExtend(this.options,i)},i.prototype.get=function(e){var t=this.options;return{hasLaw:t.hasLaw.indexOf(e)>=0,revokable:t.revokable.indexOf(e)>=0,explicitAction:t.explicitAction.indexOf(e)>=0}},i.prototype.applyLaw=function(e,t){var i=this.get(t);return i.hasLaw||(e.enabled=!1,"function"==typeof e.onNoCookieLaw&&e.onNoCookieLaw(t,i)),this.options.regionalLaw&&(i.revokable&&(e.revokable=!0),i.explicitAction&&(e.dismissOnScroll=!1,e.dismissOnTimeout=!1)),e},i}(),e.initialise=function(i,n,o){var s=new e.Law(i.law);n||(n=function(){}),o||(o=function(){});var r=Object.keys(e.status),a=t.getCookie("cookieconsent_status");r.indexOf(a)>=0?n(new e.Popup(i)):e.getCountryCode(i,function(t){delete i.law,delete i.location,t.code&&(i=s.applyLaw(i,t.code)),n(new e.Popup(i))},function(t){delete i.law,delete i.location,o(t,new e.Popup(i))})},e.getCountryCode=function(t,i,n){t.law&&t.law.countryCode?i({code:t.law.countryCode}):t.location?new e.Location(t.location).locate(function(e){i(e||{})},n):i({})},e.utils=t,e.hasInitialised=!0,window.cookieconsent=e}}(window.cookieconsent||{}); \ No newline at end of file
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index 5218a8c1be..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-orientation'),
+ 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'),
@@ -1650,6 +1745,50 @@ phpbb.lazyLoadAvatars = function loadAvatars() {
});
};
+var recaptchaForm = $('.g-recaptcha').parents('form');
+var submitButton = null;
+var programaticallySubmitted = false;
+
+phpbb.recaptchaOnLoad = function () {
+ // Listen to submit buttons in order to know which one was pressed
+ $('input[type="submit"]').each(function () {
+ $(this).on('click', function () {
+ submitButton = this;
+ });
+ });
+
+ recaptchaForm.on('submit', function (e) {
+ if (!programaticallySubmitted) {
+ grecaptcha.execute();
+ e.preventDefault();
+ }
+ });
+}
+
+phpbb.recaptchaOnSubmit = function () {
+ programaticallySubmitted = true;
+ // If concrete button was clicked (e.g. preview instead of submit),
+ // let's trigger the same action
+ if (submitButton) {
+ submitButton.click();
+ } else {
+ // Rename input[name="submit"] so that we can submit the form
+ if (typeof recaptchaForm.submit !== 'function') {
+ recaptchaForm.submit.name = 'submit_btn';
+ }
+ recaptchaForm.submit();
+ }
+}
+
+// reCAPTCHA doesn't accept callback functions nested inside objects
+// so we need to make this helper functions here
+window.phpbbRecaptchaOnLoad = function() {
+ phpbb.recaptchaOnLoad();
+}
+window.phpbbRecaptchaOnSubmit = function() {
+ phpbb.recaptchaOnSubmit();
+}
+
$(window).on('load', phpbb.lazyLoadAvatars);
/**
@@ -1662,7 +1801,7 @@ $(function() {
phpbb.registerPageDropdowns();
- $('[data-orientation]').each(function() {
+ $('[data-color-palette], [data-orientation]').each(function() {
phpbb.registerPalette($(this));
});
diff --git a/phpBB/assets/javascript/jquery-3.4.1.min.js b/phpBB/assets/javascript/jquery-3.4.1.min.js
new file mode 100644
index 0000000000..a1c07fd803
--- /dev/null
+++ b/phpBB/assets/javascript/jquery-3.4.1.min.js
@@ -0,0 +1,2 @@
+/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}k.fn=k.prototype={jquery:f,constructor:k,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=k.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return k.each(this,e)},map:function(n){return this.pushStack(k.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},k.extend=k.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(k.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||k.isPlainObject(n)?n:{},i=!1,a[t]=k.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},k.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t){b(e,{nonce:t&&t.nonce})},each:function(e,t){var n,r=0;if(d(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(p,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?k.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g.apply([],a)},guid:1,support:y}),"function"==typeof Symbol&&(k.fn[Symbol.iterator]=t[Symbol.iterator]),k.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var h=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,k="sizzle"+1*new Date,m=n.document,S=0,r=0,p=ue(),x=ue(),N=ue(),A=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",$=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",F=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="<a id='"+k+"'></a><select id='"+k+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!==C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!==C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(F," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[S,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[S,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[k]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace(B,"$1"));return s[k]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[S,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[k]||(e[k]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===S&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[k]&&(v=Ce(v)),y&&!y[k]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[k]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(B,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(B," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=N[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[k]?i.push(a):o.push(a);(a=N(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=S+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t===C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument===C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(S=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(S=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=k.split("").sort(D).join("")===k,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);k.find=h,k.expr=h.selectors,k.expr[":"]=k.expr.pseudos,k.uniqueSort=k.unique=h.uniqueSort,k.text=h.getText,k.isXMLDoc=h.isXML,k.contains=h.contains,k.escapeSelector=h.escape;var T=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&k(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},N=k.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var D=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1<i.call(n,e)!==r}):k.filter(n,e,r)}k.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?k.find.matchesSelector(r,e)?[r]:[]:k.find.matches(e,k.grep(t,function(e){return 1===e.nodeType}))},k.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(k(e).filter(function(){for(t=0;t<r;t++)if(k.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)k.find(e,i[t],n);return 1<r?k.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&N.test(e)?k(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(k.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&k(e);if(!N.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&k.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?k.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(k(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(k.uniqueSort(k.merge(this.get(),k(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),k.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return T(e,"parentNode")},parentsUntil:function(e,t,n){return T(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return T(e,"nextSibling")},prevAll:function(e){return T(e,"previousSibling")},nextUntil:function(e,t,n){return T(e,"nextSibling",n)},prevUntil:function(e,t,n){return T(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return"undefined"!=typeof e.contentDocument?e.contentDocument:(A(e,"template")&&(e=e.content||e),k.merge([],e.childNodes))}},function(r,i){k.fn[r]=function(e,t){var n=k.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=k.filter(t,n)),1<this.length&&(O[r]||k.uniqueSort(n),H.test(r)&&n.reverse()),this.pushStack(n)}});var R=/[^\x20\t\r\n\f]+/g;function M(e){return e}function I(e){throw e}function W(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}k.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},k.each(e.match(R)||[],function(e,t){n[t]=!0}),n):k.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){k.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return k.each(arguments,function(e,t){var n;while(-1<(n=k.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<k.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},k.extend({Deferred:function(e){var o=[["notify","progress",k.Callbacks("memory"),k.Callbacks("memory"),2],["resolve","done",k.Callbacks("once memory"),k.Callbacks("once memory"),0,"resolved"],["reject","fail",k.Callbacks("once memory"),k.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return k.Deferred(function(r){k.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,M,s),l(u,o,I,s)):(u++,t.call(e,l(u,o,M,s),l(u,o,I,s),l(u,o,M,o.notifyWith))):(a!==M&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){k.Deferred.exceptionHook&&k.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==I&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(k.Deferred.getStackHook&&(t.stackTrace=k.Deferred.getStackHook()),C.setTimeout(t))}}return k.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:M,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:M)),o[2][3].add(l(0,e,m(n)?n:I))}).promise()},promise:function(e){return null!=e?k.extend(e,a):a}},s={};return k.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=k.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(W(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)W(i[t],a(t),o.reject);return o.promise()}});var $=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;k.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&$.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},k.readyException=function(e){C.setTimeout(function(){throw e})};var F=k.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),k.ready()}k.fn.ready=function(e){return F.then(e)["catch"](function(e){k.readyException(e)}),this},k.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--k.readyWait:k.isReady)||(k.isReady=!0)!==e&&0<--k.readyWait||F.resolveWith(E,[k])}}),k.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(k.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var _=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)_(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(k(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},z=/^-ms-/,U=/-([a-z])/g;function X(e,t){return t.toUpperCase()}function V(e){return e.replace(z,"ms-").replace(U,X)}var G=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Y(){this.expando=k.expando+Y.uid++}Y.uid=1,Y.prototype={cache:function(e){var t=e[this.expando];return t||(t={},G(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[V(t)]=n;else for(r in t)i[V(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][V(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(V):(t=V(t))in r?[t]:t.match(R)||[]).length;while(n--)delete r[t[n]]}(void 0===t||k.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!k.isEmptyObject(t)}};var Q=new Y,J=new Y,K=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function ee(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Z,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:K.test(i)?JSON.parse(i):i)}catch(e){}J.set(e,t,n)}else n=void 0;return n}k.extend({hasData:function(e){return J.hasData(e)||Q.hasData(e)},data:function(e,t,n){return J.access(e,t,n)},removeData:function(e,t){J.remove(e,t)},_data:function(e,t,n){return Q.access(e,t,n)},_removeData:function(e,t){Q.remove(e,t)}}),k.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=J.get(o),1===o.nodeType&&!Q.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=V(r.slice(5)),ee(o,r,i[r]));Q.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){J.set(this,n)}):_(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=J.get(o,n))?t:void 0!==(t=ee(o,n))?t:void 0;this.each(function(){J.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){J.remove(this,e)})}}),k.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Q.get(e,t),n&&(!r||Array.isArray(n)?r=Q.access(e,t,k.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=k.queue(e,t),r=n.length,i=n.shift(),o=k._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){k.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Q.get(e,n)||Q.access(e,n,{empty:k.Callbacks("once memory").add(function(){Q.remove(e,[t+"queue",n])})})}}),k.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?k.queue(this[0],t):void 0===n?this:this.each(function(){var e=k.queue(this,t,n);k._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&k.dequeue(this,t)})},dequeue:function(e){return this.each(function(){k.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=k.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Q.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var te=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ne=new RegExp("^(?:([+-])=|)("+te+")([a-z%]*)$","i"),re=["Top","Right","Bottom","Left"],ie=E.documentElement,oe=function(e){return k.contains(e.ownerDocument,e)},ae={composed:!0};ie.getRootNode&&(oe=function(e){return k.contains(e.ownerDocument,e)||e.getRootNode(ae)===e.ownerDocument});var se=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&oe(e)&&"none"===k.css(e,"display")},ue=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];for(o in i=n.apply(e,r||[]),t)e.style[o]=a[o];return i};function le(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return k.css(e,t,"")},u=s(),l=n&&n[3]||(k.cssNumber[t]?"":"px"),c=e.nodeType&&(k.cssNumber[t]||"px"!==l&&+u)&&ne.exec(k.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)k.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,k.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ce={};function fe(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Q.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&se(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ce[s])||(o=a.body.appendChild(a.createElement(s)),u=k.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ce[s]=u)))):"none"!==n&&(l[c]="none",Q.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}k.fn.extend({show:function(){return fe(this,!0)},hide:function(){return fe(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){se(this)?k(this).show():k(this).hide()})}});var pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Q.set(e[n],"globalEval",!t||Q.get(t[n],"globalEval"))}ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;var me,xe,be=/<|&#?\w+;/;function we(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))k.merge(p,o.nodeType?[o]:o);else if(be.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+k.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;k.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<k.inArray(o,r))i&&i.push(o);else if(l=oe(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}me=E.createDocumentFragment().appendChild(E.createElement("div")),(xe=E.createElement("input")).setAttribute("type","radio"),xe.setAttribute("checked","checked"),xe.setAttribute("name","t"),me.appendChild(xe),y.checkClone=me.cloneNode(!0).cloneNode(!0).lastChild.checked,me.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,s)){a=k.event.handlers.call(this,s,l),t=0;while((i=a[t++])&&!s.isPropagationStopped()){s.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!s.isImmediatePropagationStopped())s.rnamespace&&!1!==o.namespace&&!s.rnamespace.test(o.namespace)||(s.handleObj=o,s.data=o.data,void 0!==(r=((k.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,u))&&!1===(s.result=r)&&(s.preventDefault(),s.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<k(i,this).index(l):k.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(k.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[k.expando]?e:new k.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&De(t,"click",ke),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&De(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Q.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},k.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},k.Event=function(e,t){if(!(this instanceof k.Event))return new k.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?ke:Se,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&k.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[k.expando]=!0},k.Event.prototype={constructor:k.Event,isDefaultPrevented:Se,isPropagationStopped:Se,isImmediatePropagationStopped:Se,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=ke,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=ke,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=ke,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},k.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&Te.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Ce.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},k.event.addProp),k.each({focus:"focusin",blur:"focusout"},function(e,t){k.event.special[e]={setup:function(){return De(this,e,Ne),!1},trigger:function(){return De(this,e),!0},delegateType:t}}),k.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){k.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||k.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),k.fn.extend({on:function(e,t,n,r){return Ae(this,e,t,n,r)},one:function(e,t,n,r){return Ae(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,k(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Se),this.each(function(){k.event.remove(this,e,n,t)})}});var je=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/<script|<style|<link/i,Le=/checked\s*(?:[^=]|=\s*.checked.)/i,He=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n<r;n++)k.event.add(t,i,l[i][n]);J.hasData(e)&&(s=J.access(e),u=k.extend({},s),J.set(t,u))}}function Ie(n,r,i,o){r=g.apply([],r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&Le.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Ie(t,r,i,o)});if(f&&(t=(e=we(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=k.map(ve(e,"script"),Pe)).length;c<f;c++)u=e,c!==p&&(u=k.clone(u,!0,!0),s&&k.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,k.map(a,Re),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Q.access(u,"globalEval")&&k.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?k._evalUrl&&!u.noModule&&k._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")}):b(u.textContent.replace(He,""),u,l))}return n}function We(e,t,n){for(var r,i=t?k.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||k.cleanData(ve(r)),r.parentNode&&(n&&oe(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}k.extend({htmlPrefilter:function(e){return e.replace(je,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Me(o[r],a[r]);else Me(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=k.event.special,o=0;void 0!==(n=e[o]);o++)if(G(n)){if(t=n[Q.expando]){if(t.events)for(r in t.events)i[r]?k.event.remove(n,r):k.removeEvent(n,r,t.handle);n[Q.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),k.fn.extend({detach:function(e){return We(this,e,!0)},remove:function(e){return We(this,e)},text:function(e){return _(this,function(e){return void 0===e?k.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Ie(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Oe(this,e).appendChild(e)})},prepend:function(){return Ie(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Oe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(k.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return k.clone(this,e,t)})},html:function(e){return _(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!qe.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=k.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(k.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Ie(this,arguments,function(e){var t=this.parentNode;k.inArray(this,n)<0&&(k.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),k.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){k.fn[e]=function(e){for(var t,n=[],r=k(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),k(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var $e=new RegExp("^("+te+")(?!px)[a-z%]+$","i"),Fe=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Be=new RegExp(re.join("|"),"i");function _e(e,t,n){var r,i,o,a,s=e.style;return(n=n||Fe(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||oe(e)||(a=k.style(e,t)),!y.pixelBoxStyles()&&$e.test(a)&&Be.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function ze(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(u){s.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",u.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",ie.appendChild(s).appendChild(u);var e=C.getComputedStyle(u);n="1%"!==e.top,a=12===t(e.marginLeft),u.style.right="60%",o=36===t(e.right),r=36===t(e.width),u.style.position="absolute",i=12===t(u.offsetWidth/3),ie.removeChild(s),u=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s=E.createElement("div"),u=E.createElement("div");u.style&&(u.style.backgroundClip="content-box",u.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===u.style.backgroundClip,k.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),a},scrollboxSize:function(){return e(),i}}))}();var Ue=["Webkit","Moz","ms"],Xe=E.createElement("div").style,Ve={};function Ge(e){var t=k.cssProps[e]||Ve[e];return t||(e in Xe?e:Ve[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Ue.length;while(n--)if((e=Ue[n]+t)in Xe)return e}(e)||e)}var Ye=/^(none|table(?!-c[ea]).+)/,Qe=/^--/,Je={position:"absolute",visibility:"hidden",display:"block"},Ke={letterSpacing:"0",fontWeight:"400"};function Ze(e,t,n){var r=ne.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function et(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=k.css(e,n+re[a],!0,i)),r?("content"===n&&(u-=k.css(e,"padding"+re[a],!0,i)),"margin"!==n&&(u-=k.css(e,"border"+re[a]+"Width",!0,i))):(u+=k.css(e,"padding"+re[a],!0,i),"padding"!==n?u+=k.css(e,"border"+re[a]+"Width",!0,i):s+=k.css(e,"border"+re[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function tt(e,t,n){var r=Fe(e),i=(!y.boxSizingReliable()||n)&&"border-box"===k.css(e,"boxSizing",!1,r),o=i,a=_e(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if($e.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||"auto"===a||!parseFloat(a)&&"inline"===k.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===k.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+et(e,t,n||(i?"border":"content"),o,r,a)+"px"}function nt(e,t,n,r,i){return new nt.prototype.init(e,t,n,r,i)}k.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=_e(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=V(t),u=Qe.test(t),l=e.style;if(u||(t=Ge(s)),a=k.cssHooks[t]||k.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=ne.exec(n))&&i[1]&&(n=le(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(k.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=V(t);return Qe.test(t)||(t=Ge(s)),(a=k.cssHooks[t]||k.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=_e(e,t,r)),"normal"===i&&t in Ke&&(i=Ke[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),k.each(["height","width"],function(e,u){k.cssHooks[u]={get:function(e,t,n){if(t)return!Ye.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?tt(e,u,n):ue(e,Je,function(){return tt(e,u,n)})},set:function(e,t,n){var r,i=Fe(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===k.css(e,"boxSizing",!1,i),s=n?et(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-et(e,u,"border",!1,i)-.5)),s&&(r=ne.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=k.css(e,u)),Ze(0,t,s)}}}),k.cssHooks.marginLeft=ze(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(_e(e,"marginLeft"))||e.getBoundingClientRect().left-ue(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),k.each({margin:"",padding:"",border:"Width"},function(i,o){k.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+re[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(k.cssHooks[i+o].set=Ze)}),k.fn.extend({css:function(e,t){return _(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Fe(e),i=t.length;a<i;a++)o[t[a]]=k.css(e,t[a],!1,r);return o}return void 0!==n?k.style(e,t,n):k.css(e,t)},e,t,1<arguments.length)}}),((k.Tween=nt).prototype={constructor:nt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||k.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(k.cssNumber[n]?"":"px")},cur:function(){var e=nt.propHooks[this.prop];return e&&e.get?e.get(this):nt.propHooks._default.get(this)},run:function(e){var t,n=nt.propHooks[this.prop];return this.options.duration?this.pos=t=k.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):nt.propHooks._default.set(this),this}}).init.prototype=nt.prototype,(nt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=k.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){k.fx.step[e.prop]?k.fx.step[e.prop](e):1!==e.elem.nodeType||!k.cssHooks[e.prop]&&null==e.elem.style[Ge(e.prop)]?e.elem[e.prop]=e.now:k.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=nt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},k.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},k.fx=nt.prototype.init,k.fx.step={};var rt,it,ot,at,st=/^(?:toggle|show|hide)$/,ut=/queueHooks$/;function lt(){it&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(lt):C.setTimeout(lt,k.fx.interval),k.fx.tick())}function ct(){return C.setTimeout(function(){rt=void 0}),rt=Date.now()}function ft(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=re[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function pt(e,t,n){for(var r,i=(dt.tweeners[t]||[]).concat(dt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function dt(o,e,t){var n,a,r=0,i=dt.prefilters.length,s=k.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=rt||ct(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:k.extend({},e),opts:k.extend(!0,{specialEasing:{},easing:k.easing._default},t),originalProperties:e,originalOptions:t,startTime:rt||ct(),duration:t.duration,tweens:[],createTween:function(e,t){var n=k.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=V(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=k.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=dt.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(k._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return k.map(c,pt,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),k.fx.timer(k.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}k.Animation=k.extend(dt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return le(n.elem,e,ne.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(R);for(var n,r=0,i=e.length;r<i;r++)n=e[r],dt.tweeners[n]=dt.tweeners[n]||[],dt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&se(e),v=Q.get(e,"fxshow");for(r in n.queue||(null==(a=k._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,k.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],st.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||k.style(e,r)}if((u=!k.isEmptyObject(t))||!k.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Q.get(e,"display")),"none"===(c=k.css(e,"display"))&&(l?c=l:(fe([e],!0),l=e.style.display||l,c=k.css(e,"display"),fe([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===k.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Q.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&fe([e],!0),p.done(function(){for(r in g||fe([e]),Q.remove(e,"fxshow"),d)k.style(e,r,d[r])})),u=pt(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?dt.prefilters.unshift(e):dt.prefilters.push(e)}}),k.speed=function(e,t,n){var r=e&&"object"==typeof e?k.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return k.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in k.fx.speeds?r.duration=k.fx.speeds[r.duration]:r.duration=k.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&k.dequeue(this,r.queue)},r},k.fn.extend({fadeTo:function(e,t,n,r){return this.filter(se).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=k.isEmptyObject(t),o=k.speed(e,n,r),a=function(){var e=dt(this,k.extend({},t),o);(i||Q.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&!1!==i&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=k.timers,r=Q.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&ut.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||k.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Q.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=k.timers,o=n?n.length:0;for(t.finish=!0,k.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),k.each(["toggle","show","hide"],function(e,r){var i=k.fn[r];k.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(ft(r,!0),e,t,n)}}),k.each({slideDown:ft("show"),slideUp:ft("hide"),slideToggle:ft("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){k.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),k.timers=[],k.fx.tick=function(){var e,t=0,n=k.timers;for(rt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||k.fx.stop(),rt=void 0},k.fx.timer=function(e){k.timers.push(e),k.fx.start()},k.fx.interval=13,k.fx.start=function(){it||(it=!0,lt())},k.fx.stop=function(){it=null},k.fx.speeds={slow:600,fast:200,_default:400},k.fn.delay=function(r,e){return r=k.fx&&k.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},ot=E.createElement("input"),at=E.createElement("select").appendChild(E.createElement("option")),ot.type="checkbox",y.checkOn=""!==ot.value,y.optSelected=at.selected,(ot=E.createElement("input")).value="t",ot.type="radio",y.radioValue="t"===ot.value;var ht,gt=k.expr.attrHandle;k.fn.extend({attr:function(e,t){return _(this,k.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){k.removeAttr(this,e)})}}),k.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?k.prop(e,t,n):(1===o&&k.isXMLDoc(e)||(i=k.attrHooks[t.toLowerCase()]||(k.expr.match.bool.test(t)?ht:void 0)),void 0!==n?null===n?void k.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=k.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(R);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),ht={set:function(e,t,n){return!1===t?k.removeAttr(e,n):e.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),function(e,t){var a=gt[t]||k.find.attr;gt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=gt[o],gt[o]=r,r=null!=a(e,t,n)?o:null,gt[o]=i),r}});var vt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;function mt(e){return(e.match(R)||[]).join(" ")}function xt(e){return e.getAttribute&&e.getAttribute("class")||""}function bt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(R)||[]}k.fn.extend({prop:function(e,t){return _(this,k.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[k.propFix[e]||e]})}}),k.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&k.isXMLDoc(e)||(t=k.propFix[t]||t,i=k.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=k.find.attr(e,"tabindex");return t?parseInt(t,10):vt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(k.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){k.propFix[this.toLowerCase()]=this}),k.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){k(this).addClass(t.call(this,e,xt(this)))});if((e=bt(t)).length)while(n=this[u++])if(i=xt(n),r=1===n.nodeType&&" "+mt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=mt(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){k(this).removeClass(t.call(this,e,xt(this)))});if(!arguments.length)return this.attr("class","");if((e=bt(t)).length)while(n=this[u++])if(i=xt(n),r=1===n.nodeType&&" "+mt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=mt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){k(this).toggleClass(i.call(this,e,xt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=k(this),r=bt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=xt(this))&&Q.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Q.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+mt(xt(n))+" ").indexOf(t))return!0;return!1}});var wt=/\r/g;k.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,k(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=k.map(t,function(e){return null==e?"":e+""})),(r=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=k.valHooks[t.type]||k.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(wt,""):null==e?"":e:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:mt(k.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=k(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=k.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<k.inArray(k.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k.each(["radio","checkbox"],function(){k.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<k.inArray(k(e).val(),t)}},y.checkOn||(k.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var Tt=/^(?:focusinfocus|focusoutblur)$/,Ct=function(e){e.stopPropagation()};k.extend(k.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!Tt.test(d+k.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[k.expando]?e:new k.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:k.makeArray(t,[e]),c=k.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,Tt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Q.get(o,"events")||{})[e.type]&&Q.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&G(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!G(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),k.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,Ct),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,Ct),k.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=k.extend(new k.Event,n,{type:e,isSimulated:!0});k.event.trigger(r,null,t)}}),k.fn.extend({trigger:function(e,t){return this.each(function(){k.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return k.event.trigger(e,t,n,!0)}}),y.focusin||k.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){k.event.simulate(r,e.target,k.event.fix(e))};k.event.special[r]={setup:function(){var e=this.ownerDocument||this,t=Q.access(e,r);t||e.addEventListener(n,i,!0),Q.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this,t=Q.access(e,r)-1;t?Q.access(e,r,t):(e.removeEventListener(n,i,!0),Q.remove(e,r))}}});var Et=C.location,kt=Date.now(),St=/\?/;k.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||k.error("Invalid XML: "+e),t};var Nt=/\[\]$/,At=/\r?\n/g,Dt=/^(?:submit|button|image|reset|file)$/i,jt=/^(?:input|select|textarea|keygen)/i;function qt(n,e,r,i){var t;if(Array.isArray(e))k.each(e,function(e,t){r||Nt.test(n)?i(n,t):qt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)qt(n+"["+t+"]",e[t],r,i)}k.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!k.isPlainObject(e))k.each(e,function(){i(this.name,this.value)});else for(n in e)qt(n,e[n],t,i);return r.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=k.prop(this,"elements");return e?k.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!k(this).is(":disabled")&&jt.test(this.nodeName)&&!Dt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,function(e){return{name:t.name,value:e.replace(At,"\r\n")}}):{name:t.name,value:n.replace(At,"\r\n")}}).get()}});var Lt=/%20/g,Ht=/#.*$/,Ot=/([?&])_=[^&]*/,Pt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Rt=/^(?:GET|HEAD)$/,Mt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Ft=E.createElement("a");function Bt(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(R)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function _t(t,i,o,a){var s={},u=t===Wt;function l(e){var r;return s[e]=!0,k.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function zt(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&k.extend(!0,e,r),e}Ft.href=Et.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,k.ajaxSettings),t):zt(k.ajaxSettings,e)},ajaxPrefilter:Bt(It),ajaxTransport:Bt(Wt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=k.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?k(y):k.event,x=k.Deferred(),b=k.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Pt.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Et.href)+"").replace(Mt,Et.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(R)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Ft.protocol+"//"+Ft.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=k.param(v.data,v.traditional)),_t(It,v,t,T),h)return T;for(i in(g=k.event&&v.global)&&0==k.active++&&k.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Rt.test(v.type),f=v.url.replace(Ht,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Lt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(St.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Ot,"$1"),o=(St.test(f)?"&":"?")+"_="+kt+++o),v.url=f+o),v.ifModified&&(k.lastModified[f]&&T.setRequestHeader("If-Modified-Since",k.lastModified[f]),k.etag[f]&&T.setRequestHeader("If-None-Match",k.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+$t+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=_t(Wt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(k.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(k.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--k.active||k.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return k.get(e,t,n,"json")},getScript:function(e,t){return k.get(e,void 0,t,"script")}}),k.each(["get","post"],function(e,i){k[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),k.ajax(k.extend({url:e,type:i,dataType:r,data:t,success:n},k.isPlainObject(e)&&e))}}),k._evalUrl=function(e,t){return k.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){k.globalEval(e,t)}})},k.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=k(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){k(this).wrapInner(n.call(this,e))}):this.each(function(){var e=k(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){k(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){k(this).replaceWith(this.childNodes)}),this}}),k.expr.pseudos.hidden=function(e){return!k.expr.pseudos.visible(e)},k.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Ut={0:200,1223:204},Xt=k.ajaxSettings.xhr();y.cors=!!Xt&&"withCredentials"in Xt,y.ajax=Xt=!!Xt,k.ajaxTransport(function(i){var o,a;if(y.cors||Xt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Ut[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),k.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),k.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return k.globalEval(e),e}}}),k.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),k.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=k("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=mt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&k.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?k("<div>").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}}),k.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),k.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),k.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||k.guid++,i},k.holdReady=function(e){e?k.readyWait++:k.ready(!0)},k.isArray=Array.isArray,k.parseJSON=JSON.parse,k.nodeName=A,k.isFunction=m,k.isWindow=x,k.camelCase=V,k.type=w,k.now=Date.now,k.isNumeric=function(e){var t=k.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return k});var Qt=C.jQuery,Jt=C.$;return k.noConflict=function(e){return C.$===k&&(C.$=Jt),e&&C.jQuery===k&&(C.jQuery=Qt),k},e||(C.jQuery=C.$=k),k});
diff --git a/phpBB/assets/javascript/jquery.min.js b/phpBB/assets/javascript/jquery.min.js
deleted file mode 100644
index e836475870..0000000000
--- a/phpBB/assets/javascript/jquery.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */
-!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0;
-}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?"<table>"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d="on"+b;a.detachEvent&&("undefined"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?n.prop(b,"form"):void 0;c&&!n._data(c,"submit")&&(n.event.add(c,"submit._submit",function(a){a._submitBubble=!0}),n._data(c,"submit",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,"click._change",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate("change",this,a)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,"change")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a)}),n._data(b,"change",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\d+="(?:null|\d+)"/g,ua=new RegExp("<(?:"+ba+")[\\s/>]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/<script|<style|<link/i,xa=/checked\s*(?:[^=]|=\s*.checked.)/i,ya=/^true\/(.*)/,za=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Pa=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement("div"),j=d.createElement("div");if(j.style){j.style.cssText="float:left;opacity:.5",l.opacity="0.5"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip="content-box",j.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===j.style.backgroundClip,i=d.createElement("div"),i.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",j.innerHTML="",i.appendChild(j),l.boxSizing=""===j.style.boxSizing||""===j.style.MozBoxSizing||""===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b="1%"!==(l||{}).top,h="2px"===(l||{}).marginLeft,e="4px"===(l||{width:"4px"}).width,j.style.marginRight="50%",c="4px"===(l||{marginRight:"4px"}).marginRight,k=j.appendChild(d.createElement("div")),k.style.cssText=j.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",k.style.marginRight=k.style.width="0",j.style.width="1px",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display="none",f=0===j.getClientRects().length,f&&(j.style.display="",j.innerHTML="<table><tr><td></td><td>t</td></tr></table>",j.childNodes[0].style.borderCollapse="separate",k=j.getElementsByTagName("td"),k[0].style.cssText="margin:0;border:0;padding:0;display:none",f=0===k[0].offsetHeight,f&&(k[0].style.display="",k[1].style.display="none",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Oa.test(g)&&Na.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0===g?g:g+""}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\([^)]*\)/i,Wa=/opacity\s*=\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp("^("+T+")(.*)$","i"),Za={position:"absolute",visibility:"hidden",display:"block"},$a={letterSpacing:"0",fontWeight:"400"},_a=["Webkit","O","Moz","ms"],ab=d.createElement("div").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&W(d)&&(f[g]=n._data(d,"olddisplay",Ma(d.nodeName)))):(e=W(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function eb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+V[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+V[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+V[f]+"Width",!0,e))):(g+=n.css(a,"padding"+V[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+V[f]+"Width",!0,e)));return g}function fb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ra(a),g=l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Sa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Oa.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+eb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),"normal"===f&&b in $a&&(f=$a[b]),""===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,"display"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Va,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+" "+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:"inline-block"},Sa,[a,"marginRight"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,"marginLeft"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{
-marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(qb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb("show"),slideUp:mb("hide"),slideToggle:mb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a,b=d.createElement("input"),c=d.createElement("div"),e=d.createElement("select"),f=e.appendChild(d.createElement("option"));c=d.createElement("div"),c.setAttribute("className","t"),c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],b.setAttribute("type","checkbox"),c.appendChild(b),a=c.getElementsByTagName("a")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==c.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement("form").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value}();var rb=/\r/g,sb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(sb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ub:tb)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var Bb=/[\t\r\n\f]/g;function Cb(a){return n.attr(a,"class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Cb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Cb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Cb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=Cb(this),b&&n._data(this,"__className__",b),n.attr(this,"class",b||a===!1?"":n._data(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+Cb(c)+" ").replace(Bb," ").indexOf(b)>-1)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Db=a.location,Eb=n.now(),Fb=/\?/,Gb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,"text/xml")):(c=new a.ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\/\//,Nb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ob={},Pb={},Qb="*/".concat("*"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Rb,type:"GET",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Qb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks("once memory"),r=l.statusCode||{},s={},t={},u=0,v="canceled",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+"").replace(Hb,"").replace(Mb,Sb[1]+"//"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||"*").toLowerCase().match(G)||[""],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||("http:"===d[1]?"80":"443"))===(Sb[3]||("http:"===Sb[1]?"80":"443")))),l.data&&l.processData&&"string"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,"$1_="+Eb++):f+(Fb.test(f)?"&":"?")+"_="+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&w.setRequestHeader("If-None-Match",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader("Content-Type",l.contentType),w.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+("*"!==l.dataTypes[0]?", "+Qb+"; q=0.01":""):l.accepts["*"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v="abort";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger("ajaxSend",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort("timeout")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,"No Transport");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||"",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader("Last-Modified"),x&&(n.lastModified[f]=x),x=w.getResponseHeader("etag"),x&&(n.etag[f]=x)),204===b||"HEAD"===l.type?y="nocontent":304===b?y="notmodified":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+"",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?"ajaxSuccess":"ajaxError",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger("ajaxComplete",[w,l]),--n.active||n.event.trigger("ajaxStop")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}});function Yb(a){return a.style&&a.style.display||n.css(a,"display")}function Zb(a){if(!n.contains(a.ownerDocument||d,a))return!0;while(a&&1===a.nodeType){if("none"===Yb(a)||"hidden"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\[\]$/,ac=/\r?\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)dc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)dc(c,a[c],b,e);return d.join("&").replace($b,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(ac,"\r\n")}}):{name:b.name,value:c.replace(ac,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&"withCredentials"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d["X-Requested-With"]||(d["X-Requested-With"]="XMLHttpRequest");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+"");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,"string"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=""}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=d.head||n("head")[0]||d.documentElement;return{send:function(e,f){b=d.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=jc.pop()||n.expando+"_"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&kc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(kc,"$1"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,jc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?("undefined"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({
-padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});
diff --git a/phpBB/common.php b/phpBB/common.php
index 172503f078..fc009dd8c4 100644
--- a/phpBB/common.php
+++ b/phpBB/common.php
@@ -12,7 +12,7 @@
*/
/**
-* Minimum Requirement: PHP 5.4.0
+* Minimum Requirement: PHP 7.1.0
*/
if (!defined('IN_PHPBB'))
@@ -132,6 +132,8 @@ catch (InvalidArgumentException $e)
$phpbb_class_loader->set_cache($phpbb_container->get('cache.driver'));
$phpbb_class_loader_ext->set_cache($phpbb_container->get('cache.driver'));
+$phpbb_container->get('dbal.conn')->set_debug_sql_explain($phpbb_container->getParameter('debug.sql_explain'));
+$phpbb_container->get('dbal.conn')->set_debug_load_time($phpbb_container->getParameter('debug.load_time'));
require($phpbb_root_path . 'includes/compatibility_globals.' . $phpEx);
register_compatibility_globals();
diff --git a/phpBB/composer.json b/phpBB/composer.json
index 33655b865f..c047c225a2 100644
--- a/phpBB/composer.json
+++ b/phpBB/composer.json
@@ -25,51 +25,50 @@
"phpbb/phpbb-core": "self.version"
},
"require": {
- "php": ">=5.4",
- "bantu/ini-get-wrapper": "1.0.*",
+ "php": ">=7.1",
+ "ext-json": "*",
+ "bantu/ini-get-wrapper": "~1.0",
"google/recaptcha": "~1.1",
- "guzzlehttp/guzzle": "~5.3",
+ "guzzlehttp/guzzle": "~6.3",
"lusitanian/oauth": "^0.8.1",
"marc1706/fast-image-size": "^1.1",
- "paragonie/random_compat": "^2.0",
"patchwork/utf8": "^1.1",
- "s9e/text-formatter": "^1.3",
- "symfony/config": "^2.8",
- "symfony/console": "^2.8",
- "symfony/debug": "^2.8",
- "symfony/dependency-injection": "^2.8",
- "symfony/event-dispatcher": "^2.8",
- "symfony/filesystem": "^2.8",
- "symfony/finder": "^2.8",
- "symfony/http-foundation": "^2.8",
- "symfony/http-kernel": "^2.8",
- "symfony/proxy-manager-bridge": "^2.8",
- "symfony/routing": "^2.8",
- "symfony/twig-bridge": "^2.8",
- "symfony/yaml": "^2.8",
- "twig/twig": "^1.0"
+ "s9e/text-formatter": "^2.0",
+ "symfony/config": "~3.4",
+ "symfony/console": "~3.4",
+ "symfony/debug": "~3.4",
+ "symfony/dependency-injection": "~3.4",
+ "symfony/event-dispatcher": "~3.4",
+ "symfony/filesystem": "~3.4",
+ "symfony/finder": "~3.4",
+ "symfony/http-foundation": "~3.4",
+ "symfony/http-kernel": "~3.4",
+ "symfony/proxy-manager-bridge": "~3.4",
+ "symfony/routing": "~3.4",
+ "symfony/twig-bridge": "~3.4",
+ "symfony/yaml": "~3.4",
+ "twig/twig": "^1.0 || ^2.0"
},
"require-dev": {
- "fabpot/goutte": "~2.0",
- "facebook/webdriver": "~1.1",
- "laravel/homestead": "~2.2",
- "phing/phing": "2.4.*",
- "phpunit/dbunit": "1.3.*",
- "phpunit/phpunit": "^4.1",
- "sami/sami": "1.*",
- "squizlabs/php_codesniffer": "2.*",
- "symfony/browser-kit": "^2.8",
- "symfony/css-selector": "^2.8",
- "symfony/dom-crawler": "^2.8"
+ "fabpot/goutte": "~3.2",
+ "facebook/webdriver": "~1.6",
+ "laravel/homestead": "~7.0",
+ "phing/phing": "~2.4",
+ "phpunit/dbunit": "~4.0",
+ "phpunit/phpunit": "^7.0",
+ "squizlabs/php_codesniffer": "~3.4",
+ "symfony/browser-kit": "~3.4",
+ "symfony/css-selector": "~3.4",
+ "symfony/dom-crawler": "~3.4"
},
"extra": {
"branch-alias": {
- "dev-master": "3.2.x-dev"
+ "dev-master": "3.3.x-dev"
}
},
"config": {
"platform": {
- "php": "5.4.7"
+ "php": "7.1"
}
}
}
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index d2a95fd8a3..e39d0ec865 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "cd42964227d699a6923798e33eab3dd5",
+ "content-hash": "b31f688c19bfc55c9a6f4c388c885301",
"packages": [
{
"name": "bantu/ini-get-wrapper",
@@ -38,28 +38,30 @@
},
{
"name": "google/recaptcha",
- "version": "1.1.2",
+ "version": "1.2.3",
"source": {
"type": "git",
"url": "https://github.com/google/recaptcha.git",
- "reference": "2b7e00566afca82a38a1d3adb8e42c118006296e"
+ "reference": "98c4a6573b27e8b0990ea8789c74ea378795134c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/google/recaptcha/zipball/2b7e00566afca82a38a1d3adb8e42c118006296e",
- "reference": "2b7e00566afca82a38a1d3adb8e42c118006296e",
+ "url": "https://api.github.com/repos/google/recaptcha/zipball/98c4a6573b27e8b0990ea8789c74ea378795134c",
+ "reference": "98c4a6573b27e8b0990ea8789c74ea378795134c",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
+ "php": ">=5.5"
},
"require-dev": {
- "phpunit/phpunit": "4.5.*"
+ "friendsofphp/php-cs-fixer": "^2.2.20|^2.15",
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^4.8.36|^5.7.27|^6.59|^7.5.11"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.1.x-dev"
+ "dev-master": "1.2.x-dev"
}
},
"autoload": {
@@ -71,41 +73,53 @@
"license": [
"BSD-3-Clause"
],
- "description": "Client library for reCAPTCHA, a free service that protect websites from spam and abuse.",
- "homepage": "http://www.google.com/recaptcha/",
+ "description": "Client library for reCAPTCHA, a free service that protects websites from spam and abuse.",
+ "homepage": "https://www.google.com/recaptcha/",
"keywords": [
"Abuse",
"captcha",
"recaptcha",
"spam"
],
- "time": "2015-09-02T17:23:59+00:00"
+ "time": "2019-08-16T15:48:25+00:00"
},
{
"name": "guzzlehttp/guzzle",
- "version": "5.3.3",
+ "version": "6.3.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
- "reference": "93bbdb30d59be6cd9839495306c65f2907370eb9"
+ "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/93bbdb30d59be6cd9839495306c65f2907370eb9",
- "reference": "93bbdb30d59be6cd9839495306c65f2907370eb9",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
+ "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
"shasum": ""
},
"require": {
- "guzzlehttp/ringphp": "^1.1",
- "php": ">=5.4.0",
- "react/promise": "^2.2"
+ "guzzlehttp/promises": "^1.0",
+ "guzzlehttp/psr7": "^1.4",
+ "php": ">=5.5"
},
"require-dev": {
"ext-curl": "*",
- "phpunit/phpunit": "^4.0"
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
+ "psr/log": "^1.0"
+ },
+ "suggest": {
+ "psr/log": "Required for using the Log middleware"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.3-dev"
+ }
+ },
"autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
"psr-4": {
"GuzzleHttp\\": "src/"
}
@@ -121,7 +135,7 @@
"homepage": "https://github.com/mtdowling"
}
],
- "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
+ "description": "Guzzle is a PHP HTTP client library",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
@@ -132,44 +146,41 @@
"rest",
"web service"
],
- "time": "2018-07-31T13:33:10+00:00"
+ "time": "2018-04-22T15:46:56+00:00"
},
{
- "name": "guzzlehttp/ringphp",
- "version": "1.1.1",
+ "name": "guzzlehttp/promises",
+ "version": "v1.3.1",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/RingPHP.git",
- "reference": "5e2a174052995663dd68e6b5ad838afd47dd615b"
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/5e2a174052995663dd68e6b5ad838afd47dd615b",
- "reference": "5e2a174052995663dd68e6b5ad838afd47dd615b",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
"shasum": ""
},
"require": {
- "guzzlehttp/streams": "~3.0",
- "php": ">=5.4.0",
- "react/promise": "~2.0"
+ "php": ">=5.5.0"
},
"require-dev": {
- "ext-curl": "*",
- "phpunit/phpunit": "~4.0"
- },
- "suggest": {
- "ext-curl": "Guzzle will use specific adapters if cURL is present"
+ "phpunit/phpunit": "^4.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.1-dev"
+ "dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
- "GuzzleHttp\\Ring\\": "src/"
- }
+ "GuzzleHttp\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -182,39 +193,54 @@
"homepage": "https://github.com/mtdowling"
}
],
- "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
- "time": "2018-07-31T13:22:33+00:00"
+ "description": "Guzzle promises library",
+ "keywords": [
+ "promise"
+ ],
+ "time": "2016-12-20T10:07:11+00:00"
},
{
- "name": "guzzlehttp/streams",
- "version": "3.0.0",
+ "name": "guzzlehttp/psr7",
+ "version": "1.6.1",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/streams.git",
- "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5"
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "239400de7a173fe9901b9ac7c06497751f00727a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
- "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
+ "reference": "239400de7a173fe9901b9ac7c06497751f00727a",
"shasum": ""
},
"require": {
- "php": ">=5.4.0"
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0",
+ "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.0"
+ "ext-zlib": "*",
+ "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
+ },
+ "suggest": {
+ "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "1.6-dev"
}
},
"autoload": {
"psr-4": {
- "GuzzleHttp\\Stream\\": "src/"
- }
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -225,57 +251,24 @@
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
- }
- ],
- "description": "Provides a simple abstraction over streams of data",
- "homepage": "http://guzzlephp.org/",
- "keywords": [
- "Guzzle",
- "stream"
- ],
- "time": "2014-10-12T19:18:40+00:00"
- },
- {
- "name": "ircmaxell/password-compat",
- "version": "v1.0.4",
- "source": {
- "type": "git",
- "url": "https://github.com/ircmaxell/password_compat.git",
- "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c",
- "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c",
- "shasum": ""
- },
- "require-dev": {
- "phpunit/phpunit": "4.*"
- },
- "type": "library",
- "autoload": {
- "files": [
- "lib/password.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
+ },
{
- "name": "Anthony Ferrara",
- "email": "ircmaxell@php.net",
- "homepage": "http://blog.ircmaxell.com"
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
}
],
- "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
- "homepage": "https://github.com/ircmaxell/password_compat",
+ "description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
- "hashing",
- "password"
+ "http",
+ "message",
+ "psr-7",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
],
- "time": "2014-11-20T16:49:30+00:00"
+ "time": "2019-07-01T23:21:34+00:00"
},
{
"name": "lusitanian/oauth",
@@ -342,20 +335,20 @@
"oauth",
"security"
],
- "time": "2016-07-12T22:15:00+00:00"
+ "time": "2018-02-14T22:37:14+00:00"
},
{
"name": "marc1706/fast-image-size",
- "version": "v1.1.4",
+ "version": "v1.1.5",
"source": {
"type": "git",
"url": "https://github.com/marc1706/fast-image-size.git",
- "reference": "c4ded0223a4e49ae45a2183a69f6afac5baf7250"
+ "reference": "519b90abdba7e3d54b4dc710d72a2e070fca0984"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/marc1706/fast-image-size/zipball/c4ded0223a4e49ae45a2183a69f6afac5baf7250",
- "reference": "c4ded0223a4e49ae45a2183a69f6afac5baf7250",
+ "url": "https://api.github.com/repos/marc1706/fast-image-size/zipball/519b90abdba7e3d54b4dc710d72a2e070fca0984",
+ "reference": "519b90abdba7e3d54b4dc710d72a2e070fca0984",
"shasum": ""
},
"require": {
@@ -363,9 +356,14 @@
"php": ">=5.3.0"
},
"require-dev": {
- "phpunit/phpunit": "4.*"
+ "phpunit/phpunit": "^4.8"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
"FastImageSize\\": "lib",
@@ -394,42 +392,98 @@
"php",
"size"
],
- "time": "2017-10-23T18:52:01+00:00"
+ "time": "2019-10-03T15:00:04+00:00"
+ },
+ {
+ "name": "ocramius/package-versions",
+ "version": "1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Ocramius/PackageVersions.git",
+ "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb",
+ "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0.0",
+ "php": "^7.1.0"
+ },
+ "require-dev": {
+ "composer/composer": "^1.6.3",
+ "doctrine/coding-standard": "^5.0.1",
+ "ext-zip": "*",
+ "infection/infection": "^0.7.1",
+ "phpunit/phpunit": "^7.0.0"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "PackageVersions\\Installer",
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PackageVersions\\": "src/PackageVersions"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com"
+ }
+ ],
+ "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
+ "time": "2019-02-21T12:16:21+00:00"
},
{
"name": "ocramius/proxy-manager",
- "version": "1.0.2",
+ "version": "2.1.1",
"source": {
"type": "git",
"url": "https://github.com/Ocramius/ProxyManager.git",
- "reference": "57e9272ec0e8deccf09421596e0e2252df440e11"
+ "reference": "e18ac876b2e4819c76349de8f78ccc8ef1554cd7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/57e9272ec0e8deccf09421596e0e2252df440e11",
- "reference": "57e9272ec0e8deccf09421596e0e2252df440e11",
+ "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/e18ac876b2e4819c76349de8f78ccc8ef1554cd7",
+ "reference": "e18ac876b2e4819c76349de8f78ccc8ef1554cd7",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "zendframework/zend-code": ">2.2.5,<3.0"
+ "ocramius/package-versions": "^1.1.1",
+ "php": "^7.1.0",
+ "zendframework/zend-code": "^3.1.0"
},
"require-dev": {
+ "couscous/couscous": "^1.5.2",
"ext-phar": "*",
- "phpunit/phpunit": "~4.0",
- "squizlabs/php_codesniffer": "1.5.*"
+ "humbug/humbug": "dev-master@DEV",
+ "nikic/php-parser": "^3.0.4",
+ "phpbench/phpbench": "^0.12.2",
+ "phpstan/phpstan": "^0.6.4",
+ "phpunit/phpunit": "^5.6.4",
+ "phpunit/phpunit-mock-objects": "^3.4.1",
+ "squizlabs/php_codesniffer": "^2.7.0"
},
"suggest": {
"ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects",
"zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)",
"zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)",
- "zendframework/zend-stdlib": "To use the hydrator proxy",
"zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0.x-dev"
+ "dev-master": "3.0.x-dev"
}
},
"autoload": {
@@ -445,7 +499,7 @@
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
- "homepage": "http://ocramius.github.com/"
+ "homepage": "http://ocramius.github.io/"
}
],
"description": "A library providing utilities to generate, instantiate and generally operate with Object Proxies",
@@ -457,37 +511,33 @@
"proxy pattern",
"service proxies"
],
- "time": "2015-08-09T04:28:19+00:00"
+ "time": "2017-05-04T11:12:50+00:00"
},
{
"name": "paragonie/random_compat",
- "version": "v2.0.18",
+ "version": "v9.99.99",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
- "reference": "0a58ef6e3146256cc3dc7cc393927bcc7d1b72db"
+ "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/paragonie/random_compat/zipball/0a58ef6e3146256cc3dc7cc393927bcc7d1b72db",
- "reference": "0a58ef6e3146256cc3dc7cc393927bcc7d1b72db",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
+ "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
"shasum": ""
},
"require": {
- "php": ">=5.2.0"
+ "php": "^7"
},
"require-dev": {
- "phpunit/phpunit": "4.*|5.*"
+ "phpunit/phpunit": "4.*|5.*",
+ "vimeo/psalm": "^1"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
- "autoload": {
- "files": [
- "lib/random.php"
- ]
- },
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
@@ -506,7 +556,7 @@
"pseudorandom",
"random"
],
- "time": "2019-01-03T20:59:08+00:00"
+ "time": "2018-07-02T15:55:56+00:00"
},
{
"name": "patchwork/utf8",
@@ -568,6 +618,105 @@
"time": "2016-05-18T13:57:10+00:00"
},
{
+ "name": "psr/container",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "time": "2017-02-14T16:28:37+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "time": "2016-08-06T14:39:51+00:00"
+ },
+ {
"name": "psr/log",
"version": "1.1.0",
"source": {
@@ -615,32 +764,30 @@
"time": "2018-11-20T15:27:04+00:00"
},
{
- "name": "react/promise",
- "version": "v2.7.1",
+ "name": "ralouphie/getallheaders",
+ "version": "3.0.3",
"source": {
"type": "git",
- "url": "https://github.com/reactphp/promise.git",
- "reference": "31ffa96f8d2ed0341a57848cbb84d88b89dd664d"
+ "url": "https://github.com/ralouphie/getallheaders.git",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/reactphp/promise/zipball/31ffa96f8d2ed0341a57848cbb84d88b89dd664d",
- "reference": "31ffa96f8d2ed0341a57848cbb84d88b89dd664d",
+ "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
- "php": ">=5.4.0"
+ "php": ">=5.6"
},
"require-dev": {
- "phpunit/phpunit": "~4.8"
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^5 || ^6.5"
},
"type": "library",
"autoload": {
- "psr-4": {
- "React\\Promise\\": "src/"
- },
"files": [
- "src/functions_include.php"
+ "src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -649,42 +796,75 @@
],
"authors": [
{
- "name": "Jan Sorgalla",
- "email": "jsorgalla@gmail.com"
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
}
],
- "description": "A lightweight implementation of CommonJS Promises/A for PHP",
+ "description": "A polyfill for getallheaders.",
+ "time": "2019-03-08T08:55:37+00:00"
+ },
+ {
+ "name": "s9e/regexp-builder",
+ "version": "1.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/s9e/RegexpBuilder.git",
+ "reference": "59d0167a909659d718f53964f7653d2c83a5f8fe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/s9e/RegexpBuilder/zipball/59d0167a909659d718f53964f7653d2c83a5f8fe",
+ "reference": "59d0167a909659d718f53964f7653d2c83a5f8fe",
+ "shasum": ""
+ },
+ "require": {
+ "lib-pcre": ">=7.2",
+ "php": ">=5.5.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "<5.8"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "s9e\\RegexpBuilder\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Single-purpose library that generates regular expressions that match a list of strings.",
+ "homepage": "https://github.com/s9e/RegexpBuilder/",
"keywords": [
- "promise",
- "promises"
+ "regexp"
],
- "time": "2019-01-07T21:25:54+00:00"
+ "time": "2019-04-26T17:55:23+00:00"
},
{
"name": "s9e/text-formatter",
- "version": "1.4.5",
+ "version": "2.1.2",
"source": {
"type": "git",
"url": "https://github.com/s9e/TextFormatter.git",
- "reference": "6857c53658929b66dc0d92daece17f211c64ea61"
+ "reference": "de2752a252047ef8899dab0ac0880be306bca474"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/6857c53658929b66dc0d92daece17f211c64ea61",
- "reference": "6857c53658929b66dc0d92daece17f211c64ea61",
+ "url": "https://api.github.com/repos/s9e/TextFormatter/zipball/de2752a252047ef8899dab0ac0880be306bca474",
+ "reference": "de2752a252047ef8899dab0ac0880be306bca474",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-filter": "*",
- "lib-pcre": ">=7.2",
- "php": ">=5.4.7"
+ "lib-pcre": ">=8.13",
+ "php": ">=7.1",
+ "s9e/regexp-builder": "^1.4"
},
"require-dev": {
"matthiasmullie/minify": "*",
- "php-coveralls/php-coveralls": "*",
- "phpunit/phpunit": "<6",
- "s9e/regexp-builder": "1.*"
+ "phpunit/phpunit": "^7 || 8.2.*"
},
"suggest": {
"ext-curl": "Improves the performance of the MediaEmbed plugin and some JavaScript minifiers",
@@ -696,6 +876,9 @@
"ext-zlib": "Enables gzip compression when scraping content via the MediaEmbed plugin"
},
"type": "library",
+ "extra": {
+ "version": "2.1.2"
+ },
"autoload": {
"psr-4": {
"s9e\\TextFormatter\\": "src"
@@ -724,29 +907,36 @@
"parser",
"shortcodes"
],
- "time": "2019-06-04T15:47:55+00:00"
+ "time": "2019-08-22T21:47:11+00:00"
},
{
"name": "symfony/config",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "7dd5f5040dc04c118d057fb5886563963eb70011"
+ "reference": "24a60c0d7ad98a0fa5d1f892e9286095a389404f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/7dd5f5040dc04c118d057fb5886563963eb70011",
- "reference": "7dd5f5040dc04c118d057fb5886563963eb70011",
+ "url": "https://api.github.com/repos/symfony/config/zipball/24a60c0d7ad98a0fa5d1f892e9286095a389404f",
+ "reference": "24a60c0d7ad98a0fa5d1f892e9286095a389404f",
"shasum": ""
},
"require": {
- "php": ">=5.3.9",
- "symfony/filesystem": "~2.3|~3.0.0",
+ "php": "^5.5.9|>=7.0.8",
+ "symfony/filesystem": "~2.8|~3.0|~4.0",
"symfony/polyfill-ctype": "~1.8"
},
+ "conflict": {
+ "symfony/dependency-injection": "<3.3",
+ "symfony/finder": "<3.3"
+ },
"require-dev": {
- "symfony/yaml": "~2.7|~3.0.0"
+ "symfony/dependency-injection": "~3.3|~4.0",
+ "symfony/event-dispatcher": "~3.3|~4.0",
+ "symfony/finder": "~3.3|~4.0",
+ "symfony/yaml": "~3.0|~4.0"
},
"suggest": {
"symfony/yaml": "To use the yaml reference dumper"
@@ -754,7 +944,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -781,41 +971,52 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
- "time": "2018-11-26T09:38:12+00:00"
+ "time": "2019-08-26T07:52:57+00:00"
},
{
"name": "symfony/console",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12"
+ "reference": "4510f04e70344d70952566e4262a0b11df39cb10"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12",
- "reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12",
+ "url": "https://api.github.com/repos/symfony/console/zipball/4510f04e70344d70952566e4262a0b11df39cb10",
+ "reference": "4510f04e70344d70952566e4262a0b11df39cb10",
"shasum": ""
},
"require": {
- "php": ">=5.3.9",
- "symfony/debug": "^2.7.2|~3.0.0",
+ "php": "^5.5.9|>=7.0.8",
+ "symfony/debug": "~2.8|~3.0|~4.0",
"symfony/polyfill-mbstring": "~1.0"
},
+ "conflict": {
+ "symfony/dependency-injection": "<3.4",
+ "symfony/process": "<3.3"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0"
+ },
"require-dev": {
"psr/log": "~1.0",
- "symfony/event-dispatcher": "~2.1|~3.0.0",
- "symfony/process": "~2.1|~3.0.0"
+ "symfony/config": "~3.3|~4.0",
+ "symfony/dependency-injection": "~3.4|~4.0",
+ "symfony/event-dispatcher": "~2.8|~3.0|~4.0",
+ "symfony/lock": "~3.4|~4.0",
+ "symfony/process": "~3.3|~4.0"
},
"suggest": {
- "psr/log-implementation": "For using the console logger",
+ "psr/log": "For using the console logger",
"symfony/event-dispatcher": "",
+ "symfony/lock": "",
"symfony/process": ""
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -842,37 +1043,36 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2018-11-20T15:55:20+00:00"
+ "time": "2019-08-26T07:52:58+00:00"
},
{
"name": "symfony/debug",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "74251c8d50dd3be7c4ce0c7b862497cdc641a5d0"
+ "reference": "0b600300918780001e2821db77bc28b677794486"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/74251c8d50dd3be7c4ce0c7b862497cdc641a5d0",
- "reference": "74251c8d50dd3be7c4ce0c7b862497cdc641a5d0",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/0b600300918780001e2821db77bc28b677794486",
+ "reference": "0b600300918780001e2821db77bc28b677794486",
"shasum": ""
},
"require": {
- "php": ">=5.3.9",
+ "php": "^5.5.9|>=7.0.8",
"psr/log": "~1.0"
},
"conflict": {
"symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
},
"require-dev": {
- "symfony/class-loader": "~2.2|~3.0.0",
- "symfony/http-kernel": "~2.3.24|~2.5.9|^2.6.2|~3.0.0"
+ "symfony/http-kernel": "~2.8|~3.0|~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -899,43 +1099,51 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2018-11-11T11:18:13+00:00"
+ "time": "2019-08-20T13:31:17+00:00"
},
{
"name": "symfony/dependency-injection",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
- "reference": "c306198fee8f872a8f5f031e6e4f6f83086992d8"
+ "reference": "2709bc2978ceb90f5180181f777f8a09125f2d89"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/c306198fee8f872a8f5f031e6e4f6f83086992d8",
- "reference": "c306198fee8f872a8f5f031e6e4f6f83086992d8",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2709bc2978ceb90f5180181f777f8a09125f2d89",
+ "reference": "2709bc2978ceb90f5180181f777f8a09125f2d89",
"shasum": ""
},
"require": {
- "php": ">=5.3.9"
+ "php": "^5.5.9|>=7.0.8",
+ "psr/container": "^1.0"
},
"conflict": {
- "symfony/expression-language": "<2.6"
+ "symfony/config": "<3.3.7",
+ "symfony/finder": "<3.3",
+ "symfony/proxy-manager-bridge": "<3.4",
+ "symfony/yaml": "<3.4"
+ },
+ "provide": {
+ "psr/container-implementation": "1.0"
},
"require-dev": {
- "symfony/config": "~2.2|~3.0.0",
- "symfony/expression-language": "~2.6|~3.0.0",
- "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7"
+ "symfony/config": "~3.3|~4.0",
+ "symfony/expression-language": "~2.8|~3.0|~4.0",
+ "symfony/yaml": "~3.4|~4.0"
},
"suggest": {
"symfony/config": "",
"symfony/expression-language": "For using expressions in service container configuration",
+ "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required",
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -962,31 +1170,34 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
- "time": "2019-04-16T11:33:46+00:00"
+ "time": "2019-08-26T16:07:57+00:00"
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0"
+ "reference": "3e922c4c3430b9de624e8a285dada5e61e230959"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a77e974a5fecb4398833b0709210e3d5e334ffb0",
- "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3e922c4c3430b9de624e8a285dada5e61e230959",
+ "reference": "3e922c4c3430b9de624e8a285dada5e61e230959",
"shasum": ""
},
"require": {
- "php": ">=5.3.9"
+ "php": "^5.5.9|>=7.0.8"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<3.3"
},
"require-dev": {
"psr/log": "~1.0",
- "symfony/config": "^2.0.5|~3.0.0",
- "symfony/dependency-injection": "~2.6|~3.0.0",
- "symfony/expression-language": "~2.6|~3.0.0",
- "symfony/stopwatch": "~2.3|~3.0.0"
+ "symfony/config": "~2.8|~3.0|~4.0",
+ "symfony/dependency-injection": "~3.3|~4.0",
+ "symfony/expression-language": "~2.8|~3.0|~4.0",
+ "symfony/stopwatch": "~2.8|~3.0|~4.0"
},
"suggest": {
"symfony/dependency-injection": "",
@@ -995,7 +1206,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -1022,30 +1233,30 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2018-11-21T14:20:20+00:00"
+ "time": "2019-08-23T08:05:57+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "7ae46872dad09dffb7fe1e93a0937097339d0080"
+ "reference": "00e3a6ddd723b8bcfe4f2a1b6f82b98eeeb51516"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/7ae46872dad09dffb7fe1e93a0937097339d0080",
- "reference": "7ae46872dad09dffb7fe1e93a0937097339d0080",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/00e3a6ddd723b8bcfe4f2a1b6f82b98eeeb51516",
+ "reference": "00e3a6ddd723b8bcfe4f2a1b6f82b98eeeb51516",
"shasum": ""
},
"require": {
- "php": ">=5.3.9",
+ "php": "^5.5.9|>=7.0.8",
"symfony/polyfill-ctype": "~1.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -1072,29 +1283,29 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2018-11-11T11:18:13+00:00"
+ "time": "2019-08-20T13:31:17+00:00"
},
{
"name": "symfony/finder",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "1444eac52273e345d9b95129bf914639305a9ba4"
+ "reference": "1fcad80b440abcd1451767349906b6f9d3961d37"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/1444eac52273e345d9b95129bf914639305a9ba4",
- "reference": "1444eac52273e345d9b95129bf914639305a9ba4",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/1fcad80b440abcd1451767349906b6f9d3961d37",
+ "reference": "1fcad80b440abcd1451767349906b6f9d3961d37",
"shasum": ""
},
"require": {
- "php": ">=5.3.9"
+ "php": "^5.5.9|>=7.0.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -1121,35 +1332,34 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2018-11-11T11:18:13+00:00"
+ "time": "2019-08-14T09:39:58+00:00"
},
{
"name": "symfony/http-foundation",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "746f8d3638bf46ee8b202e62f2b214c3d61fb06a"
+ "reference": "b3d57a1c325f39f703b249bed7998ce8c64236b4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/746f8d3638bf46ee8b202e62f2b214c3d61fb06a",
- "reference": "746f8d3638bf46ee8b202e62f2b214c3d61fb06a",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b3d57a1c325f39f703b249bed7998ce8c64236b4",
+ "reference": "b3d57a1c325f39f703b249bed7998ce8c64236b4",
"shasum": ""
},
"require": {
- "php": ">=5.3.9",
+ "php": "^5.5.9|>=7.0.8",
"symfony/polyfill-mbstring": "~1.1",
- "symfony/polyfill-php54": "~1.0",
- "symfony/polyfill-php55": "~1.0"
+ "symfony/polyfill-php70": "~1.6"
},
"require-dev": {
- "symfony/expression-language": "~2.4|~3.0.0"
+ "symfony/expression-language": "~2.8|~3.0|~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -1176,54 +1386,59 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "time": "2019-04-16T10:00:53+00:00"
+ "time": "2019-08-26T07:50:50+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v2.8.51",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "a01e2b4b267fda24dba9b06cd1c575ca87a51ad2"
+ "reference": "f6d35bb306b26812df007525f5757a8b0e95857e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a01e2b4b267fda24dba9b06cd1c575ca87a51ad2",
- "reference": "a01e2b4b267fda24dba9b06cd1c575ca87a51ad2",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f6d35bb306b26812df007525f5757a8b0e95857e",
+ "reference": "f6d35bb306b26812df007525f5757a8b0e95857e",
"shasum": ""
},
"require": {
- "php": ">=5.3.9",
+ "php": "^5.5.9|>=7.0.8",
"psr/log": "~1.0",
- "symfony/debug": "^2.6.2",
- "symfony/event-dispatcher": "^2.6.7|~3.0.0",
- "symfony/http-foundation": "~2.7.36|~2.8.29|~3.1.6",
+ "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"
},
"conflict": {
- "symfony/config": "<2.7",
+ "symfony/config": "<2.8",
+ "symfony/dependency-injection": "<3.4.10|<4.0.10,>=4",
+ "symfony/var-dumper": "<3.3",
"twig/twig": "<1.34|<2.4,>=2"
},
+ "provide": {
+ "psr/log-implementation": "1.0"
+ },
"require-dev": {
- "symfony/browser-kit": "~2.3|~3.0.0",
- "symfony/class-loader": "~2.1|~3.0.0",
- "symfony/config": "~2.8",
- "symfony/console": "~2.3|~3.0.0",
- "symfony/css-selector": "^2.0.5|~3.0.0",
- "symfony/dependency-injection": "~2.8|~3.0.0",
- "symfony/dom-crawler": "^2.0.5|~3.0.0",
- "symfony/expression-language": "~2.4|~3.0.0",
- "symfony/finder": "^2.0.5|~3.0.0",
- "symfony/process": "^2.0.5|~3.0.0",
- "symfony/routing": "~2.8|~3.0.0",
- "symfony/stopwatch": "~2.3|~3.0.0",
- "symfony/templating": "~2.2|~3.0.0",
- "symfony/translation": "^2.0.5|~3.0.0",
- "symfony/var-dumper": "~2.6|~3.0.0"
+ "psr/cache": "~1.0",
+ "symfony/browser-kit": "~2.8|~3.0|~4.0",
+ "symfony/class-loader": "~2.8|~3.0",
+ "symfony/config": "~2.8|~3.0|~4.0",
+ "symfony/console": "~2.8|~3.0|~4.0",
+ "symfony/css-selector": "~2.8|~3.0|~4.0",
+ "symfony/dependency-injection": "^3.4.10|^4.0.10",
+ "symfony/dom-crawler": "~2.8|~3.0|~4.0",
+ "symfony/expression-language": "~2.8|~3.0|~4.0",
+ "symfony/finder": "~2.8|~3.0|~4.0",
+ "symfony/process": "~2.8|~3.0|~4.0",
+ "symfony/routing": "~3.4|~4.0",
+ "symfony/stopwatch": "~2.8|~3.0|~4.0",
+ "symfony/templating": "~2.8|~3.0|~4.0",
+ "symfony/translation": "~2.8|~3.0|~4.0",
+ "symfony/var-dumper": "~3.3|~4.0"
},
"suggest": {
"symfony/browser-kit": "",
- "symfony/class-loader": "",
"symfony/config": "",
"symfony/console": "",
"symfony/dependency-injection": "",
@@ -1233,7 +1448,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -1260,20 +1475,20 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
- "time": "2019-04-17T16:42:28+00:00"
+ "time": "2019-08-26T16:36:29+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.11.0",
+ "version": "v1.12.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "82ebae02209c21113908c229e9883c419720738a"
+ "reference": "550ebaac289296ce228a706d0867afc34687e3f4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a",
- "reference": "82ebae02209c21113908c229e9883c419720738a",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4",
+ "reference": "550ebaac289296ce228a706d0867afc34687e3f4",
"shasum": ""
},
"require": {
@@ -1285,7 +1500,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.11-dev"
+ "dev-master": "1.12-dev"
}
},
"autoload": {
@@ -1302,12 +1517,12 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
},
{
- "name": "Gert de Pagter",
- "email": "backendtea@gmail.com"
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
@@ -1318,20 +1533,20 @@
"polyfill",
"portable"
],
- "time": "2019-02-06T07:57:58+00:00"
+ "time": "2019-08-06T08:03:45+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.11.0",
+ "version": "v1.12.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "fe5e94c604826c35a32fa832f35bd036b6799609"
+ "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fe5e94c604826c35a32fa832f35bd036b6799609",
- "reference": "fe5e94c604826c35a32fa832f35bd036b6799609",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17",
+ "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17",
"shasum": ""
},
"require": {
@@ -1343,7 +1558,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.11-dev"
+ "dev-master": "1.12-dev"
}
},
"autoload": {
@@ -1377,34 +1592,35 @@
"portable",
"shim"
],
- "time": "2019-02-06T07:57:58+00:00"
+ "time": "2019-08-06T08:03:45+00:00"
},
{
- "name": "symfony/polyfill-php54",
- "version": "v1.11.0",
+ "name": "symfony/polyfill-php70",
+ "version": "v1.12.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-php54.git",
- "reference": "2964b17ddc32dba7bcba009d5501c84d3fba1452"
+ "url": "https://github.com/symfony/polyfill-php70.git",
+ "reference": "54b4c428a0054e254223797d2713c31e08610831"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/2964b17ddc32dba7bcba009d5501c84d3fba1452",
- "reference": "2964b17ddc32dba7bcba009d5501c84d3fba1452",
+ "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/54b4c428a0054e254223797d2713c31e08610831",
+ "reference": "54b4c428a0054e254223797d2713c31e08610831",
"shasum": ""
},
"require": {
+ "paragonie/random_compat": "~1.0|~2.0|~9.99",
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.11-dev"
+ "dev-master": "1.12-dev"
}
},
"autoload": {
"psr-4": {
- "Symfony\\Polyfill\\Php54\\": ""
+ "Symfony\\Polyfill\\Php70\\": ""
},
"files": [
"bootstrap.php"
@@ -1427,7 +1643,7 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions",
+ "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
@@ -1435,96 +1651,43 @@
"portable",
"shim"
],
- "time": "2019-02-06T07:57:58+00:00"
- },
- {
- "name": "symfony/polyfill-php55",
- "version": "v1.11.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php55.git",
- "reference": "96fa25cef405ea452919559a0025d5dc16e30e4c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/96fa25cef405ea452919559a0025d5dc16e30e4c",
- "reference": "96fa25cef405ea452919559a0025d5dc16e30e4c",
- "shasum": ""
- },
- "require": {
- "ircmaxell/password-compat": "~1.0",
- "php": ">=5.3.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.11-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Php55\\": ""
- },
- "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.5+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "time": "2019-02-06T07:57:58+00:00"
+ "time": "2019-08-06T08:03:45+00:00"
},
{
"name": "symfony/proxy-manager-bridge",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/proxy-manager-bridge.git",
- "reference": "40802595fea26ada845ed58124d8000a13dd4c6f"
+ "reference": "40d174ac695f74d468a0d63e87d1b65c57b47232"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/40802595fea26ada845ed58124d8000a13dd4c6f",
- "reference": "40802595fea26ada845ed58124d8000a13dd4c6f",
+ "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/40d174ac695f74d468a0d63e87d1b65c57b47232",
+ "reference": "40d174ac695f74d468a0d63e87d1b65c57b47232",
"shasum": ""
},
"require": {
"ocramius/proxy-manager": "~0.4|~1.0|~2.0",
- "php": ">=5.3.9",
- "symfony/dependency-injection": "~2.8|~3.0.0"
+ "php": "^5.5.9|>=7.0.8",
+ "symfony/dependency-injection": "~3.4|~4.0"
},
"require-dev": {
- "symfony/config": "~2.3|~3.0.0"
+ "symfony/config": "~2.8|~3.0|~4.0"
},
"type": "symfony-bridge",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Bridge\\ProxyManager\\": ""
},
+ "classmap": [
+ "Legacy/ProxiedMethodReturnExpression.php"
+ ],
"exclude-from-classmap": [
"/Tests/"
]
@@ -1545,40 +1708,42 @@
],
"description": "Symfony ProxyManager Bridge",
"homepage": "https://symfony.com",
- "time": "2019-04-16T11:33:46+00:00"
+ "time": "2019-08-20T13:34:30+00:00"
},
{
"name": "symfony/routing",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "8b0df6869d1997baafff6a1541826eac5a03d067"
+ "reference": "8b0faa681c4ee14701e76a7056fef15ac5384163"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/8b0df6869d1997baafff6a1541826eac5a03d067",
- "reference": "8b0df6869d1997baafff6a1541826eac5a03d067",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/8b0faa681c4ee14701e76a7056fef15ac5384163",
+ "reference": "8b0faa681c4ee14701e76a7056fef15ac5384163",
"shasum": ""
},
"require": {
- "php": ">=5.3.9"
+ "php": "^5.5.9|>=7.0.8"
},
"conflict": {
- "symfony/config": "<2.7"
+ "symfony/config": "<3.3.1",
+ "symfony/dependency-injection": "<3.3",
+ "symfony/yaml": "<3.4"
},
"require-dev": {
"doctrine/annotations": "~1.0",
"psr/log": "~1.0",
- "symfony/config": "~2.7|~3.0.0",
- "symfony/expression-language": "~2.4|~3.0.0",
- "symfony/http-foundation": "~2.3|~3.0.0",
- "symfony/yaml": "^2.0.5|~3.0.0"
+ "symfony/config": "^3.3.1|~4.0",
+ "symfony/dependency-injection": "~3.3|~4.0",
+ "symfony/expression-language": "~2.8|~3.0|~4.0",
+ "symfony/http-foundation": "~2.8|~3.0|~4.0",
+ "symfony/yaml": "~3.4|~4.0"
},
"suggest": {
"doctrine/annotations": "For using the annotation loader",
"symfony/config": "For using the all-in-one router or any loader",
- "symfony/dependency-injection": "For loading routes from a service",
"symfony/expression-language": "For using expression matching",
"symfony/http-foundation": "For using a Symfony Request object",
"symfony/yaml": "For using the YAML loader"
@@ -1586,7 +1751,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -1619,46 +1784,51 @@
"uri",
"url"
],
- "time": "2018-11-20T15:55:20+00:00"
+ "time": "2019-08-26T07:50:50+00:00"
},
{
"name": "symfony/twig-bridge",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/twig-bridge.git",
- "reference": "ecc1e30d05fa99f25b504e2d6a8684555ae39f7c"
+ "reference": "b3ee7d17bb002129d94504fb27463f7e0b4185bd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/ecc1e30d05fa99f25b504e2d6a8684555ae39f7c",
- "reference": "ecc1e30d05fa99f25b504e2d6a8684555ae39f7c",
+ "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/b3ee7d17bb002129d94504fb27463f7e0b4185bd",
+ "reference": "b3ee7d17bb002129d94504fb27463f7e0b4185bd",
"shasum": ""
},
"require": {
- "php": ">=5.3.9",
- "twig/twig": "~1.34|~2.4"
+ "php": "^5.5.9|>=7.0.8",
+ "twig/twig": "^1.41|^2.10"
},
"conflict": {
- "symfony/form": "<2.8.23"
+ "symfony/console": "<3.4",
+ "symfony/form": "<3.4.31|>=4.0,<4.3.4"
},
"require-dev": {
- "symfony/asset": "~2.7|~3.0.0",
- "symfony/console": "~2.8|~3.0.0",
- "symfony/expression-language": "~2.4|~3.0.0",
- "symfony/finder": "~2.3|~3.0.0",
- "symfony/form": "^2.8.23",
- "symfony/http-foundation": "^2.8.29|~3.0.0",
- "symfony/http-kernel": "~2.8|~3.0.0",
+ "fig/link-util": "^1.0",
+ "symfony/asset": "~2.8|~3.0|~4.0",
+ "symfony/console": "~3.4|~4.0",
+ "symfony/dependency-injection": "~2.8|~3.0|~4.0",
+ "symfony/expression-language": "~2.8|~3.0|~4.0",
+ "symfony/finder": "~2.8|~3.0|~4.0",
+ "symfony/form": "^3.4.31|^4.3.4",
+ "symfony/http-foundation": "^3.3.11|~4.0",
+ "symfony/http-kernel": "~3.2|~4.0",
"symfony/polyfill-intl-icu": "~1.0",
- "symfony/routing": "~2.2|~3.0.0",
- "symfony/security": "^2.8.31|^3.3.13",
- "symfony/security-acl": "~2.6|~3.0.0",
- "symfony/stopwatch": "~2.2|~3.0.0",
- "symfony/templating": "~2.1|~3.0.0",
- "symfony/translation": "~2.7|~3.0.0",
- "symfony/var-dumper": "~2.7.16|~2.8.9|~3.0.9",
- "symfony/yaml": "^2.0.5|~3.0.0"
+ "symfony/routing": "~2.8|~3.0|~4.0",
+ "symfony/security": "^2.8.31|^3.3.13|~4.0",
+ "symfony/security-acl": "~2.8|~3.0",
+ "symfony/stopwatch": "~2.8|~3.0|~4.0",
+ "symfony/templating": "~2.8|~3.0|~4.0",
+ "symfony/translation": "~2.8|~3.0|~4.0",
+ "symfony/var-dumper": "~2.8.10|~3.1.4|~3.2|~4.0",
+ "symfony/web-link": "~3.3|~4.0",
+ "symfony/workflow": "~3.3|~4.0",
+ "symfony/yaml": "~2.8|~3.0|~4.0"
},
"suggest": {
"symfony/asset": "For using the AssetExtension",
@@ -1672,12 +1842,13 @@
"symfony/templating": "For using the TwigEngine",
"symfony/translation": "For using the TranslationExtension",
"symfony/var-dumper": "For using the DumpExtension",
+ "symfony/web-link": "For using the WebLinkExtension",
"symfony/yaml": "For using the YamlExtension"
},
"type": "symfony-bridge",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -1704,30 +1875,39 @@
],
"description": "Symfony Twig Bridge",
"homepage": "https://symfony.com",
- "time": "2018-11-11T11:18:13+00:00"
+ "time": "2019-08-26T07:52:58+00:00"
},
{
"name": "symfony/yaml",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "02c1859112aa779d9ab394ae4f3381911d84052b"
+ "reference": "3dc414b7db30695bae671a1d86013d03f4ae9834"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/02c1859112aa779d9ab394ae4f3381911d84052b",
- "reference": "02c1859112aa779d9ab394ae4f3381911d84052b",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/3dc414b7db30695bae671a1d86013d03f4ae9834",
+ "reference": "3dc414b7db30695bae671a1d86013d03f4ae9834",
"shasum": ""
},
"require": {
- "php": ">=5.3.9",
+ "php": "^5.5.9|>=7.0.8",
"symfony/polyfill-ctype": "~1.8"
},
+ "conflict": {
+ "symfony/console": "<3.4"
+ },
+ "require-dev": {
+ "symfony/console": "~3.4|~4.0"
+ },
+ "suggest": {
+ "symfony/console": "For validating YAML files using the lint command"
+ },
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -1754,25 +1934,26 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2018-11-11T11:18:13+00:00"
+ "time": "2019-08-20T13:31:17+00:00"
},
{
"name": "twig/twig",
- "version": "v1.42.2",
+ "version": "v2.11.3",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "21707d6ebd05476854805e4f91b836531941bcd4"
+ "reference": "699ed2342557c88789a15402de5eb834dedd6792"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/21707d6ebd05476854805e4f91b836531941bcd4",
- "reference": "21707d6ebd05476854805e4f91b836531941bcd4",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/699ed2342557c88789a15402de5eb834dedd6792",
+ "reference": "699ed2342557c88789a15402de5eb834dedd6792",
"shasum": ""
},
"require": {
- "php": ">=5.4.0",
- "symfony/polyfill-ctype": "^1.8"
+ "php": "^7.0",
+ "symfony/polyfill-ctype": "^1.8",
+ "symfony/polyfill-mbstring": "^1.3"
},
"require-dev": {
"psr/container": "^1.0",
@@ -1782,7 +1963,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.42-dev"
+ "dev-master": "2.11-dev"
}
},
"autoload": {
@@ -1820,42 +2001,42 @@
"keywords": [
"templating"
],
- "time": "2019-06-18T15:35:16+00:00"
+ "time": "2019-06-18T15:37:11+00:00"
},
{
"name": "zendframework/zend-code",
- "version": "2.5.1",
+ "version": "3.3.2",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-code.git",
- "reference": "5d998f261ec2a55171c71da57a11622745680153"
+ "reference": "936fa7ad4d53897ea3e3eb41b5b760828246a20b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/zendframework/zend-code/zipball/5d998f261ec2a55171c71da57a11622745680153",
- "reference": "5d998f261ec2a55171c71da57a11622745680153",
+ "url": "https://api.github.com/repos/zendframework/zend-code/zipball/936fa7ad4d53897ea3e3eb41b5b760828246a20b",
+ "reference": "936fa7ad4d53897ea3e3eb41b5b760828246a20b",
"shasum": ""
},
"require": {
- "php": ">=5.3.23",
- "zendframework/zend-eventmanager": "~2.5"
+ "php": "^7.1",
+ "zendframework/zend-eventmanager": "^2.6 || ^3.0"
},
"require-dev": {
- "doctrine/common": ">=2.1",
- "fabpot/php-cs-fixer": "1.7.*",
- "phpunit/phpunit": "~4.0",
- "zendframework/zend-stdlib": "~2.5",
- "zendframework/zend-version": "~2.5"
+ "doctrine/annotations": "^1.0",
+ "ext-phar": "*",
+ "phpunit/phpunit": "^7.5.15",
+ "zendframework/zend-coding-standard": "^1.0",
+ "zendframework/zend-stdlib": "^2.7 || ^3.0"
},
"suggest": {
- "doctrine/common": "Doctrine\\Common >=2.1 for annotation features",
+ "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features",
"zendframework/zend-stdlib": "Zend\\Stdlib component"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.5-dev",
- "dev-develop": "2.6-dev"
+ "dev-master": "3.3.x-dev",
+ "dev-develop": "3.4.x-dev"
}
},
"autoload": {
@@ -1867,41 +2048,47 @@
"license": [
"BSD-3-Clause"
],
- "description": "provides facilities to generate arbitrary code using an object oriented interface",
- "homepage": "https://github.com/zendframework/zend-code",
+ "description": "Extensions to the PHP Reflection API, static code scanning, and code generation",
"keywords": [
+ "ZendFramework",
"code",
- "zf2"
+ "zf"
],
- "time": "2015-06-03T15:31:59+00:00"
+ "time": "2019-08-31T14:14:34+00:00"
},
{
"name": "zendframework/zend-eventmanager",
- "version": "2.5.1",
+ "version": "3.2.1",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-eventmanager.git",
- "reference": "d94a16039144936f107f906896349900fd634443"
+ "reference": "a5e2583a211f73604691586b8406ff7296a946dd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/d94a16039144936f107f906896349900fd634443",
- "reference": "d94a16039144936f107f906896349900fd634443",
+ "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/a5e2583a211f73604691586b8406ff7296a946dd",
+ "reference": "a5e2583a211f73604691586b8406ff7296a946dd",
"shasum": ""
},
"require": {
- "php": ">=5.3.23",
- "zendframework/zend-stdlib": "~2.5"
+ "php": "^5.6 || ^7.0"
},
"require-dev": {
- "fabpot/php-cs-fixer": "1.7.*",
- "phpunit/phpunit": "~4.0"
+ "athletic/athletic": "^0.1",
+ "container-interop/container-interop": "^1.1.0",
+ "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2",
+ "zendframework/zend-coding-standard": "~1.0.0",
+ "zendframework/zend-stdlib": "^2.7.3 || ^3.0"
+ },
+ "suggest": {
+ "container-interop/container-interop": "^1.1.0, to use the lazy listeners feature",
+ "zendframework/zend-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.5-dev",
- "dev-develop": "2.6-dev"
+ "dev-master": "3.2-dev",
+ "dev-develop": "3.3-dev"
}
},
"autoload": {
@@ -1913,99 +2100,48 @@
"license": [
"BSD-3-Clause"
],
+ "description": "Trigger and listen to events within a PHP application",
"homepage": "https://github.com/zendframework/zend-eventmanager",
"keywords": [
+ "event",
"eventmanager",
+ "events",
"zf2"
],
- "time": "2015-06-03T15:32:01+00:00"
- },
- {
- "name": "zendframework/zend-stdlib",
- "version": "2.5.1",
- "source": {
- "type": "git",
- "url": "https://github.com/zendframework/zend-stdlib.git",
- "reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/cc8e90a60dd5d44b9730b77d07b97550091da1ae",
- "reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.23"
- },
- "require-dev": {
- "fabpot/php-cs-fixer": "1.7.*",
- "phpunit/phpunit": "~4.0",
- "zendframework/zend-config": "~2.5",
- "zendframework/zend-eventmanager": "~2.5",
- "zendframework/zend-filter": "~2.5",
- "zendframework/zend-inputfilter": "~2.5",
- "zendframework/zend-serializer": "~2.5",
- "zendframework/zend-servicemanager": "~2.5"
- },
- "suggest": {
- "zendframework/zend-eventmanager": "To support aggregate hydrator usage",
- "zendframework/zend-filter": "To support naming strategy hydrator usage",
- "zendframework/zend-serializer": "Zend\\Serializer component",
- "zendframework/zend-servicemanager": "To support hydrator plugin manager usage"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.5-dev",
- "dev-develop": "2.6-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Zend\\Stdlib\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "homepage": "https://github.com/zendframework/zend-stdlib",
- "keywords": [
- "stdlib",
- "zf2"
- ],
- "time": "2015-06-03T15:32:03+00:00"
+ "time": "2018-04-25T15:33:34+00:00"
}
],
"packages-dev": [
{
"name": "doctrine/instantiator",
- "version": "1.0.5",
+ "version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
- "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
+ "reference": "a2c590166b2133a4633738648b6b064edae0814a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
- "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a",
+ "reference": "a2c590166b2133a4633738648b6b064edae0814a",
"shasum": ""
},
"require": {
- "php": ">=5.3,<8.0-DEV"
+ "php": "^7.1"
},
"require-dev": {
- "athletic/athletic": "~0.1.8",
+ "doctrine/coding-standard": "^6.0",
"ext-pdo": "*",
"ext-phar": "*",
- "phpunit/phpunit": "~4.0",
- "squizlabs/php_codesniffer": "~2.0"
+ "phpbench/phpbench": "^0.13",
+ "phpstan/phpstan-phpunit": "^0.11",
+ "phpstan/phpstan-shim": "^0.11",
+ "phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "1.2.x-dev"
}
},
"autoload": {
@@ -2025,44 +2161,50 @@
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
- "homepage": "https://github.com/doctrine/instantiator",
+ "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
"keywords": [
"constructor",
"instantiate"
],
- "time": "2015-06-14T21:17:01+00:00"
+ "time": "2019-03-17T17:37:11+00:00"
},
{
"name": "fabpot/goutte",
- "version": "v2.0.4",
+ "version": "v3.2.3",
"source": {
"type": "git",
"url": "https://github.com/FriendsOfPHP/Goutte.git",
- "reference": "0ad3ee6dc2d0aaa832a80041a1e09bf394e99802"
+ "reference": "3f0eaf0a40181359470651f1565b3e07e3dd31b8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/0ad3ee6dc2d0aaa832a80041a1e09bf394e99802",
- "reference": "0ad3ee6dc2d0aaa832a80041a1e09bf394e99802",
+ "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/3f0eaf0a40181359470651f1565b3e07e3dd31b8",
+ "reference": "3f0eaf0a40181359470651f1565b3e07e3dd31b8",
"shasum": ""
},
"require": {
- "guzzlehttp/guzzle": ">=4,<6",
- "php": ">=5.4.0",
- "symfony/browser-kit": "~2.1",
- "symfony/css-selector": "~2.1",
- "symfony/dom-crawler": "~2.1"
+ "guzzlehttp/guzzle": "^6.0",
+ "php": ">=5.5.0",
+ "symfony/browser-kit": "~2.1|~3.0|~4.0",
+ "symfony/css-selector": "~2.1|~3.0|~4.0",
+ "symfony/dom-crawler": "~2.1|~3.0|~4.0"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^3.3 || ^4"
},
"type": "application",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-master": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Goutte\\": "Goutte"
- }
+ },
+ "exclude-from-classmap": [
+ "Goutte/Tests"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2079,35 +2221,49 @@
"keywords": [
"scraper"
],
- "time": "2015-05-05T21:14:57+00:00"
+ "time": "2018-06-29T15:13:57+00:00"
},
{
"name": "facebook/webdriver",
- "version": "1.1.3",
+ "version": "1.7.1",
"source": {
"type": "git",
"url": "https://github.com/facebook/php-webdriver.git",
- "reference": "b7186fb1bcfda956d237f59face250d06ef47253"
+ "reference": "e43de70f3c7166169d0f14a374505392734160e5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/b7186fb1bcfda956d237f59face250d06ef47253",
- "reference": "b7186fb1bcfda956d237f59face250d06ef47253",
+ "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/e43de70f3c7166169d0f14a374505392734160e5",
+ "reference": "e43de70f3c7166169d0f14a374505392734160e5",
"shasum": ""
},
"require": {
"ext-curl": "*",
- "php": ">=5.3.19"
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "ext-zip": "*",
+ "php": "^5.6 || ~7.0",
+ "symfony/process": "^2.8 || ^3.1 || ^4.0"
},
"require-dev": {
- "friendsofphp/php-cs-fixer": "^1.11",
- "phpunit/phpunit": "4.6.* || ~5.0",
- "squizlabs/php_codesniffer": "^2.6"
+ "friendsofphp/php-cs-fixer": "^2.0",
+ "jakub-onderka/php-parallel-lint": "^0.9.2",
+ "php-coveralls/php-coveralls": "^2.0",
+ "php-mock/php-mock-phpunit": "^1.1",
+ "phpunit/phpunit": "^5.7",
+ "sebastian/environment": "^1.3.4 || ^2.0 || ^3.0",
+ "squizlabs/php_codesniffer": "^2.6",
+ "symfony/var-dumper": "^3.3 || ^4.0"
},
"suggest": {
- "phpdocumentor/phpdocumentor": "2.*"
+ "ext-SimpleXML": "For Firefox profile creation"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-community": "1.5-dev"
+ }
+ },
"autoload": {
"psr-4": {
"Facebook\\WebDriver\\": "lib/"
@@ -2117,7 +2273,7 @@
"license": [
"Apache-2.0"
],
- "description": "A PHP client for WebDriver",
+ "description": "A PHP client for Selenium WebDriver",
"homepage": "https://github.com/facebook/php-webdriver",
"keywords": [
"facebook",
@@ -2125,31 +2281,41 @@
"selenium",
"webdriver"
],
- "time": "2016-08-10T00:44:08+00:00"
+ "time": "2019-06-13T08:02:18+00:00"
},
{
"name": "laravel/homestead",
- "version": "v2.2.2",
+ "version": "v7.20.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/homestead.git",
- "reference": "f4e45f895d8707042c2d0698627d33c484e7c6ba"
+ "reference": "cae38adcfdde1de1c4581e7a33872adaf9fbf926"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/homestead/zipball/f4e45f895d8707042c2d0698627d33c484e7c6ba",
- "reference": "f4e45f895d8707042c2d0698627d33c484e7c6ba",
+ "url": "https://api.github.com/repos/laravel/homestead/zipball/cae38adcfdde1de1c4581e7a33872adaf9fbf926",
+ "reference": "cae38adcfdde1de1c4581e7a33872adaf9fbf926",
"shasum": ""
},
"require": {
- "php": ">=5.4",
- "symfony/console": "~2.0 || ~3.0",
- "symfony/process": "~2.0 || ~3.0"
+ "php": "^5.6 || ^7.0",
+ "symfony/console": "~3.3|~4.0",
+ "symfony/process": "~3.3|~4.0",
+ "symfony/yaml": "~3.3|~4.0"
+ },
+ "require-dev": {
+ "phly/changelog-generator": "^2.2",
+ "phpunit/phpunit": "^5.7 || ^6.0"
},
"bin": [
- "homestead"
+ "bin/homestead"
],
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
"autoload": {
"psr-4": {
"Laravel\\Homestead\\": "src/"
@@ -2166,82 +2332,133 @@
}
],
"description": "A virtual machine for web artisans.",
- "time": "2016-09-17T04:42:33+00:00"
+ "time": "2018-12-11T02:04:35+00:00"
},
{
- "name": "michelf/php-markdown",
- "version": "1.8.0",
+ "name": "myclabs/deep-copy",
+ "version": "1.9.3",
"source": {
"type": "git",
- "url": "https://github.com/michelf/php-markdown.git",
- "reference": "01ab082b355bf188d907b9929cd99b2923053495"
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/michelf/php-markdown/zipball/01ab082b355bf188d907b9929cd99b2923053495",
- "reference": "01ab082b355bf188d907b9929cd99b2923053495",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea",
+ "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": "^7.1"
+ },
+ "replace": {
+ "myclabs/deep-copy": "self.version"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.0",
+ "doctrine/common": "^2.6",
+ "phpunit/phpunit": "^7.1"
},
"type": "library",
"autoload": {
"psr-4": {
- "Michelf\\": "Michelf/"
+ "DeepCopy\\": "src/DeepCopy/"
+ },
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "time": "2019-08-09T12:45:53+00:00"
+ },
+ {
+ "name": "phar-io/manifest",
+ "version": "1.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/manifest.git",
+ "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+ "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-phar": "*",
+ "phar-io/version": "^2.0",
+ "php": "^5.6 || ^7.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
}
},
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
- "name": "Michel Fortin",
- "email": "michel.fortin@michelf.ca",
- "homepage": "https://michelf.ca/",
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
"role": "Developer"
},
{
- "name": "John Gruber",
- "homepage": "https://daringfireball.net/"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
}
],
- "description": "PHP Markdown",
- "homepage": "https://michelf.ca/projects/php-markdown/",
- "keywords": [
- "markdown"
- ],
- "time": "2018-01-15T00:49:33+00:00"
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+ "time": "2018-07-08T19:23:20+00:00"
},
{
- "name": "nikic/php-parser",
- "version": "v0.9.5",
+ "name": "phar-io/version",
+ "version": "2.0.1",
"source": {
"type": "git",
- "url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb"
+ "url": "https://github.com/phar-io/version.git",
+ "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ef70767475434bdb3615b43c327e2cae17ef12eb",
- "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+ "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
"shasum": ""
},
"require": {
- "ext-tokenizer": "*",
- "php": ">=5.2"
+ "php": "^5.6 || ^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "0.9-dev"
- }
- },
"autoload": {
- "psr-0": {
- "PHPParser": "lib/"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2249,37 +2466,85 @@
],
"authors": [
{
- "name": "Nikita Popov"
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
}
],
- "description": "A PHP parser written in PHP",
- "keywords": [
- "parser",
- "php"
- ],
- "time": "2014-07-23T18:24:17+00:00"
+ "description": "Library for handling version information and constraints",
+ "time": "2018-07-08T19:19:57+00:00"
},
{
"name": "phing/phing",
- "version": "2.4.14",
+ "version": "2.16.1",
"source": {
"type": "git",
"url": "https://github.com/phingofficial/phing.git",
- "reference": "41075d93ca254f1c90c79ec7ce81be2b2629e138"
+ "reference": "cbe0f969e434e269af91b4160b86fe899c6e07c7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phingofficial/phing/zipball/41075d93ca254f1c90c79ec7ce81be2b2629e138",
- "reference": "41075d93ca254f1c90c79ec7ce81be2b2629e138",
+ "url": "https://api.github.com/repos/phingofficial/phing/zipball/cbe0f969e434e269af91b4160b86fe899c6e07c7",
+ "reference": "cbe0f969e434e269af91b4160b86fe899c6e07c7",
"shasum": ""
},
"require": {
- "php": ">=5.2.0"
+ "php": ">=5.2.0",
+ "symfony/yaml": "^3.1 || ^4.0"
+ },
+ "require-dev": {
+ "ext-pdo_sqlite": "*",
+ "mikey179/vfsstream": "^1.6",
+ "pdepend/pdepend": "2.x",
+ "pear/archive_tar": "1.4.x",
+ "pear/http_request2": "dev-trunk",
+ "pear/net_growl": "dev-trunk",
+ "pear/pear-core-minimal": "1.10.1",
+ "pear/versioncontrol_git": "@dev",
+ "pear/versioncontrol_svn": "~0.5",
+ "phpdocumentor/phpdocumentor": "2.x",
+ "phploc/phploc": "~2.0.6",
+ "phpmd/phpmd": "~2.2",
+ "phpunit/phpunit": ">=3.7",
+ "sebastian/git": "~1.0",
+ "sebastian/phpcpd": "2.x",
+ "siad007/versioncontrol_hg": "^1.0",
+ "simpletest/simpletest": "^1.1",
+ "squizlabs/php_codesniffer": "~2.2"
+ },
+ "suggest": {
+ "pdepend/pdepend": "PHP version of JDepend",
+ "pear/archive_tar": "Tar file management class",
+ "pear/versioncontrol_git": "A library that provides OO interface to handle Git repository",
+ "pear/versioncontrol_svn": "A simple OO-style interface for Subversion, the free/open-source version control system",
+ "phpdocumentor/phpdocumentor": "Documentation Generator for PHP",
+ "phploc/phploc": "A tool for quickly measuring the size of a PHP project",
+ "phpmd/phpmd": "PHP version of PMD tool",
+ "phpunit/php-code-coverage": "Library that provides collection, processing, and rendering functionality for PHP code coverage information",
+ "phpunit/phpunit": "The PHP Unit Testing Framework",
+ "sebastian/phpcpd": "Copy/Paste Detector (CPD) for PHP code",
+ "siad007/versioncontrol_hg": "A library for interfacing with Mercurial repositories.",
+ "tedivm/jshrink": "Javascript Minifier built in PHP"
},
"bin": [
"bin/phing"
],
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.16.x-dev"
+ }
+ },
"autoload": {
"classmap": [
"classes/phing/"
@@ -2290,61 +2555,114 @@
"classes"
],
"license": [
- "LGPL3"
+ "LGPL-3.0"
],
"authors": [
{
"name": "Michiel Rook",
- "email": "mrook@php.net",
- "role": "Lead"
+ "email": "mrook@php.net"
},
{
"name": "Phing Community",
- "homepage": "http://www.phing.info/trac/wiki/Development/Contributors"
+ "homepage": "https://www.phing.info/trac/wiki/Development/Contributors"
}
],
"description": "PHing Is Not GNU make; it's a PHP project build system or build tool based on Apache Ant.",
- "homepage": "http://www.phing.info/",
+ "homepage": "https://www.phing.info/",
"keywords": [
"build",
+ "phing",
"task",
"tool"
],
- "time": "2012-11-29T21:23:47+00:00"
+ "time": "2018-01-25T13:18:09+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a",
+ "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ],
+ "time": "2018-08-07T13:53:10+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
- "version": "2.0.5",
+ "version": "4.3.2",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b"
+ "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b",
- "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e",
+ "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": "^7.0",
+ "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0",
+ "phpdocumentor/type-resolver": "~0.4 || ^1.0.0",
+ "webmozart/assert": "^1.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.0"
- },
- "suggest": {
- "dflydev/markdown": "~1.0",
- "erusev/parsedown": "~1.0"
+ "doctrine/instantiator": "^1.0.5",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.4"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0.x-dev"
+ "dev-master": "4.x-dev"
}
},
"autoload": {
- "psr-0": {
- "phpDocumentor": [
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
"src/"
]
}
@@ -2356,29 +2674,77 @@
"authors": [
{
"name": "Mike van Riel",
- "email": "mike.vanriel@naenius.com"
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "time": "2019-09-12T14:27:41+00:00"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
+ "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1",
+ "phpdocumentor/reflection-common": "^2.0"
+ },
+ "require-dev": {
+ "ext-tokenizer": "^7.1",
+ "mockery/mockery": "~1",
+ "phpunit/phpunit": "^7.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
}
],
- "time": "2016-01-25T08:17:30+00:00"
+ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+ "time": "2019-08-22T18:11:29+00:00"
},
{
"name": "phpspec/prophecy",
- "version": "1.8.1",
+ "version": "1.9.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
- "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76"
+ "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
- "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203",
+ "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.3|^7.0",
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
"sebastian/comparator": "^1.1|^2.0|^3.0",
"sebastian/recursion-context": "^1.0|^2.0|^3.0"
},
@@ -2422,59 +2788,52 @@
"spy",
"stub"
],
- "time": "2019-06-13T12:50:23+00:00"
+ "time": "2019-10-03T11:07:50+00:00"
},
{
"name": "phpunit/dbunit",
- "version": "1.3.2",
+ "version": "4.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/dbunit.git",
- "reference": "1507040c2541bdffd7fbd71fc792cecdea6a7c61"
+ "reference": "e77b469c3962b5a563f09a2a989f1c9bd38b8615"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/1507040c2541bdffd7fbd71fc792cecdea6a7c61",
- "reference": "1507040c2541bdffd7fbd71fc792cecdea6a7c61",
+ "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/e77b469c3962b5a563f09a2a989f1c9bd38b8615",
+ "reference": "e77b469c3962b5a563f09a2a989f1c9bd38b8615",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"ext-simplexml": "*",
- "php": ">=5.3.3",
- "phpunit/phpunit": "~3.7|~4.0",
- "symfony/yaml": "~2.1"
+ "php": "^7.1",
+ "phpunit/phpunit": "^7.0",
+ "symfony/yaml": "^3.0 || ^4.0"
},
- "bin": [
- "composer/bin/dbunit"
- ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.3.x-dev"
+ "dev-master": "4.0-dev"
}
},
"autoload": {
"classmap": [
- "PHPUnit/"
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
- "include-path": [
- "",
- "../../symfony/yaml/"
- ],
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
+ "email": "sebastian@phpunit.de",
"role": "lead"
}
],
- "description": "DbUnit port for PHP/PHPUnit to support database interaction testing.",
+ "description": "PHPUnit extension for database interaction testing",
"homepage": "https://github.com/sebastianbergmann/dbunit/",
"keywords": [
"database",
@@ -2482,43 +2841,44 @@
"xunit"
],
"abandoned": true,
- "time": "2015-03-29T14:23:04+00:00"
+ "time": "2018-02-07T06:47:59+00:00"
},
{
"name": "phpunit/php-code-coverage",
- "version": "2.2.4",
+ "version": "6.1.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
+ "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
- "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
+ "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "phpunit/php-file-iterator": "~1.3",
- "phpunit/php-text-template": "~1.2",
- "phpunit/php-token-stream": "~1.3",
- "sebastian/environment": "^1.3.2",
- "sebastian/version": "~1.0"
+ "ext-dom": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.1",
+ "phpunit/php-file-iterator": "^2.0",
+ "phpunit/php-text-template": "^1.2.1",
+ "phpunit/php-token-stream": "^3.0",
+ "sebastian/code-unit-reverse-lookup": "^1.0.1",
+ "sebastian/environment": "^3.1 || ^4.0",
+ "sebastian/version": "^2.0.1",
+ "theseer/tokenizer": "^1.1"
},
"require-dev": {
- "ext-xdebug": ">=2.1.4",
- "phpunit/phpunit": "~4"
+ "phpunit/phpunit": "^7.0"
},
"suggest": {
- "ext-dom": "*",
- "ext-xdebug": ">=2.2.1",
- "ext-xmlwriter": "*"
+ "ext-xdebug": "^2.6.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.2.x-dev"
+ "dev-master": "6.1-dev"
}
},
"autoload": {
@@ -2533,7 +2893,7 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
+ "email": "sebastian@phpunit.de",
"role": "lead"
}
],
@@ -2544,29 +2904,32 @@
"testing",
"xunit"
],
- "time": "2015-10-06T15:47:00+00:00"
+ "time": "2018-10-31T16:06:48+00:00"
},
{
"name": "phpunit/php-file-iterator",
- "version": "1.4.5",
+ "version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
+ "reference": "050bedf145a257b1ff02746c31894800e5122946"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
- "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
+ "reference": "050bedf145a257b1ff02746c31894800e5122946",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4.x-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
@@ -2581,7 +2944,7 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
+ "email": "sebastian@phpunit.de",
"role": "lead"
}
],
@@ -2591,7 +2954,7 @@
"filesystem",
"iterator"
],
- "time": "2017-11-27T13:52:08+00:00"
+ "time": "2018-09-13T20:33:42+00:00"
},
{
"name": "phpunit/php-text-template",
@@ -2636,28 +2999,28 @@
},
{
"name": "phpunit/php-timer",
- "version": "1.0.9",
+ "version": "2.1.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
+ "reference": "1038454804406b0b5f5f520358e78c1c2f71501e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
- "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e",
+ "reference": "1038454804406b0b5f5f520358e78c1c2f71501e",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0"
+ "php": "^7.1"
},
"require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ "phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "2.1-dev"
}
},
"autoload": {
@@ -2672,7 +3035,7 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
+ "email": "sebastian@phpunit.de",
"role": "lead"
}
],
@@ -2681,33 +3044,33 @@
"keywords": [
"timer"
],
- "time": "2017-02-26T11:10:40+00:00"
+ "time": "2019-06-07T04:22:29+00:00"
},
{
"name": "phpunit/php-token-stream",
- "version": "1.4.12",
+ "version": "3.1.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16"
+ "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16",
- "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff",
+ "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
- "php": ">=5.3.3"
+ "php": "^7.1"
},
"require-dev": {
- "phpunit/phpunit": "~4.2"
+ "phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4-dev"
+ "dev-master": "3.1-dev"
}
},
"autoload": {
@@ -2730,45 +3093,57 @@
"keywords": [
"tokenizer"
],
- "time": "2017-12-04T08:55:13+00:00"
+ "time": "2019-09-17T06:23:10+00:00"
},
{
"name": "phpunit/phpunit",
- "version": "4.8.36",
+ "version": "7.5.16",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "46023de9a91eec7dfb06cc56cb4e260017298517"
+ "reference": "316afa6888d2562e04aeb67ea7f2017a0eb41661"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517",
- "reference": "46023de9a91eec7dfb06cc56cb4e260017298517",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/316afa6888d2562e04aeb67ea7f2017a0eb41661",
+ "reference": "316afa6888d2562e04aeb67ea7f2017a0eb41661",
"shasum": ""
},
"require": {
+ "doctrine/instantiator": "^1.1",
"ext-dom": "*",
"ext-json": "*",
- "ext-pcre": "*",
- "ext-reflection": "*",
- "ext-spl": "*",
- "php": ">=5.3.3",
- "phpspec/prophecy": "^1.3.1",
- "phpunit/php-code-coverage": "~2.1",
- "phpunit/php-file-iterator": "~1.4",
- "phpunit/php-text-template": "~1.2",
- "phpunit/php-timer": "^1.0.6",
- "phpunit/phpunit-mock-objects": "~2.3",
- "sebastian/comparator": "~1.2.2",
- "sebastian/diff": "~1.2",
- "sebastian/environment": "~1.3",
- "sebastian/exporter": "~1.2",
- "sebastian/global-state": "~1.0",
- "sebastian/version": "~1.0",
- "symfony/yaml": "~2.1|~3.0"
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "myclabs/deep-copy": "^1.7",
+ "phar-io/manifest": "^1.0.2",
+ "phar-io/version": "^2.0",
+ "php": "^7.1",
+ "phpspec/prophecy": "^1.7",
+ "phpunit/php-code-coverage": "^6.0.7",
+ "phpunit/php-file-iterator": "^2.0.1",
+ "phpunit/php-text-template": "^1.2.1",
+ "phpunit/php-timer": "^2.1",
+ "sebastian/comparator": "^3.0",
+ "sebastian/diff": "^3.0",
+ "sebastian/environment": "^4.0",
+ "sebastian/exporter": "^3.1",
+ "sebastian/global-state": "^2.0",
+ "sebastian/object-enumerator": "^3.0.3",
+ "sebastian/resource-operations": "^2.0",
+ "sebastian/version": "^2.0.1"
+ },
+ "conflict": {
+ "phpunit/phpunit-mock-objects": "*"
+ },
+ "require-dev": {
+ "ext-pdo": "*"
},
"suggest": {
- "phpunit/php-invoker": "~1.1"
+ "ext-soap": "*",
+ "ext-xdebug": "*",
+ "phpunit/php-invoker": "^2.0"
},
"bin": [
"phpunit"
@@ -2776,7 +3151,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.8.x-dev"
+ "dev-master": "7.5-dev"
}
},
"autoload": {
@@ -2802,38 +3177,32 @@
"testing",
"xunit"
],
- "time": "2017-06-21T08:07:12+00:00"
+ "time": "2019-09-14T09:08:39+00:00"
},
{
- "name": "phpunit/phpunit-mock-objects",
- "version": "2.3.8",
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "1.0.1",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
- "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
- "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.0.2",
- "php": ">=5.3.3",
- "phpunit/php-text-template": "~1.2",
- "sebastian/exporter": "~1.2"
+ "php": "^5.6 || ^7.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.4"
- },
- "suggest": {
- "ext-soap": "*"
+ "phpunit/phpunit": "^5.7 || ^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.3.x-dev"
+ "dev-master": "1.0.x-dev"
}
},
"autoload": {
@@ -2848,149 +3217,39 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
- "role": "lead"
- }
- ],
- "description": "Mock Object library for PHPUnit",
- "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
- "keywords": [
- "mock",
- "xunit"
- ],
- "abandoned": true,
- "time": "2015-10-02T06:51:40+00:00"
- },
- {
- "name": "pimple/pimple",
- "version": "v1.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/silexphp/Pimple.git",
- "reference": "ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/silexphp/Pimple/zipball/ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94",
- "reference": "ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Pimple": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- }
- ],
- "description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
- "homepage": "http://pimple.sensiolabs.org",
- "keywords": [
- "container",
- "dependency injection"
- ],
- "time": "2013-03-08T08:21:40+00:00"
- },
- {
- "name": "sami/sami",
- "version": "v1.4.1",
- "source": {
- "type": "git",
- "url": "https://github.com/FriendsOfPHP/Sami.git",
- "reference": "160018bfefffa730dc35a2c606691a45acbf41a1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/FriendsOfPHP/Sami/zipball/160018bfefffa730dc35a2c606691a45acbf41a1",
- "reference": "160018bfefffa730dc35a2c606691a45acbf41a1",
- "shasum": ""
- },
- "require": {
- "michelf/php-markdown": "~1.3",
- "nikic/php-parser": "0.9.*",
- "php": ">=5.3.0",
- "pimple/pimple": "1.0.*",
- "symfony/console": "~2.1",
- "symfony/filesystem": "~2.1",
- "symfony/finder": "~2.1",
- "symfony/process": "~2.1",
- "symfony/yaml": "~2.1",
- "twig/twig": "1.*"
- },
- "bin": [
- "sami.php"
- ],
- "type": "application",
- "extra": {
- "branch-alias": {
- "dev-master": "1.4-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Sami": "."
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "sebastian@phpunit.de"
}
],
- "description": "Sami, an API documentation generator",
- "homepage": "http://sami.sensiolabs.org",
- "keywords": [
- "phpdoc"
- ],
- "abandoned": true,
- "time": "2015-06-05T03:36:34+00:00"
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "time": "2017-03-04T06:30:41+00:00"
},
{
"name": "sebastian/comparator",
- "version": "1.2.4",
+ "version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
+ "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
- "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
+ "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "sebastian/diff": "~1.2",
- "sebastian/exporter": "~1.2 || ~2.0"
+ "php": "^7.1",
+ "sebastian/diff": "^3.0",
+ "sebastian/exporter": "^3.1"
},
"require-dev": {
- "phpunit/phpunit": "~4.4"
+ "phpunit/phpunit": "^7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2.x-dev"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
@@ -3021,38 +3280,39 @@
}
],
"description": "Provides the functionality to compare PHP values for equality",
- "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "homepage": "https://github.com/sebastianbergmann/comparator",
"keywords": [
"comparator",
"compare",
"equality"
],
- "time": "2017-01-29T09:50:25+00:00"
+ "time": "2018-07-12T15:12:46+00:00"
},
{
"name": "sebastian/diff",
- "version": "1.4.3",
+ "version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4"
+ "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4",
- "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
+ "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0"
+ "php": "^7.1"
},
"require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ "phpunit/phpunit": "^7.5 || ^8.0",
+ "symfony/process": "^2 || ^3.3 || ^4"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4-dev"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
@@ -3077,34 +3337,40 @@
"description": "Diff implementation",
"homepage": "https://github.com/sebastianbergmann/diff",
"keywords": [
- "diff"
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
],
- "time": "2017-05-22T07:24:03+00:00"
+ "time": "2019-02-04T06:01:07+00:00"
},
{
"name": "sebastian/environment",
- "version": "1.3.8",
+ "version": "4.2.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
+ "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
- "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404",
+ "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0"
+ "php": "^7.1"
},
"require-dev": {
- "phpunit/phpunit": "^4.8 || ^5.0"
+ "phpunit/phpunit": "^7.5"
+ },
+ "suggest": {
+ "ext-posix": "*"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.3.x-dev"
+ "dev-master": "4.2-dev"
}
},
"autoload": {
@@ -3129,34 +3395,34 @@
"environment",
"hhvm"
],
- "time": "2016-08-18T05:49:44+00:00"
+ "time": "2019-05-05T09:05:15+00:00"
},
{
"name": "sebastian/exporter",
- "version": "1.2.2",
+ "version": "3.1.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
+ "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
- "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e",
+ "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "sebastian/recursion-context": "~1.0"
+ "php": "^7.0",
+ "sebastian/recursion-context": "^3.0"
},
"require-dev": {
"ext-mbstring": "*",
- "phpunit/phpunit": "~4.4"
+ "phpunit/phpunit": "^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.3.x-dev"
+ "dev-master": "3.1.x-dev"
}
},
"autoload": {
@@ -3170,6 +3436,10 @@
],
"authors": [
{
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
@@ -3178,16 +3448,12 @@
"email": "github@wallbash.com"
},
{
- "name": "Bernhard Schussek",
- "email": "bschussek@2bepublished.at"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
"name": "Adam Harvey",
"email": "aharvey@php.net"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
}
],
"description": "Provides the functionality to export PHP variables for visualization",
@@ -3196,27 +3462,27 @@
"export",
"exporter"
],
- "time": "2016-06-17T09:04:28+00:00"
+ "time": "2019-09-14T09:02:43+00:00"
},
{
"name": "sebastian/global-state",
- "version": "1.1.1",
+ "version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
+ "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
- "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+ "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": "^7.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.2"
+ "phpunit/phpunit": "^6.0"
},
"suggest": {
"ext-uopz": "*"
@@ -3224,7 +3490,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "2.0-dev"
}
},
"autoload": {
@@ -3247,32 +3513,124 @@
"keywords": [
"global state"
],
- "time": "2015-10-12T03:26:01+00:00"
+ "time": "2017-04-27T15:39:26+00:00"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5",
+ "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "sebastian/object-reflector": "^1.1.1",
+ "sebastian/recursion-context": "^3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "time": "2017-08-03T12:35:26+00:00"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "773f97c67f28de00d397be301821b06708fca0be"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be",
+ "reference": "773f97c67f28de00d397be301821b06708fca0be",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+ "time": "2017-03-29T09:07:27+00:00"
},
{
"name": "sebastian/recursion-context",
- "version": "1.0.5",
+ "version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
+ "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
- "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
+ "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": "^7.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.4"
+ "phpunit/phpunit": "^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "3.0.x-dev"
}
},
"autoload": {
@@ -3300,23 +3658,73 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2016-10-03T07:41:43+00:00"
+ "time": "2017-03-03T06:23:57+00:00"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
+ "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "time": "2018-10-04T04:07:39+00:00"
},
{
"name": "sebastian/version",
- "version": "1.0.6",
+ "version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/version.git",
- "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
- "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
"shasum": ""
},
+ "require": {
+ "php": ">=5.6"
+ },
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
"autoload": {
"classmap": [
"src/"
@@ -3335,68 +3743,41 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
- "time": "2015-06-21T13:59:46+00:00"
+ "time": "2016-10-03T07:35:21+00:00"
},
{
"name": "squizlabs/php_codesniffer",
- "version": "2.9.2",
+ "version": "3.5.0",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "2acf168de78487db620ab4bc524135a13cfe6745"
+ "reference": "0afebf16a2e7f1e434920fa976253576151effe9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745",
- "reference": "2acf168de78487db620ab4bc524135a13cfe6745",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/0afebf16a2e7f1e434920fa976253576151effe9",
+ "reference": "0afebf16a2e7f1e434920fa976253576151effe9",
"shasum": ""
},
"require": {
"ext-simplexml": "*",
"ext-tokenizer": "*",
"ext-xmlwriter": "*",
- "php": ">=5.1.2"
+ "php": ">=5.4.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.0"
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
},
"bin": [
- "scripts/phpcs",
- "scripts/phpcbf"
+ "bin/phpcs",
+ "bin/phpcbf"
],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.x-dev"
+ "dev-master": "3.x-dev"
}
},
- "autoload": {
- "classmap": [
- "CodeSniffer.php",
- "CodeSniffer/CLI.php",
- "CodeSniffer/Exception.php",
- "CodeSniffer/File.php",
- "CodeSniffer/Fixer.php",
- "CodeSniffer/Report.php",
- "CodeSniffer/Reporting.php",
- "CodeSniffer/Sniff.php",
- "CodeSniffer/Tokens.php",
- "CodeSniffer/Reports/",
- "CodeSniffer/Tokenizers/",
- "CodeSniffer/DocGenerators/",
- "CodeSniffer/Standards/AbstractPatternSniff.php",
- "CodeSniffer/Standards/AbstractScopeSniff.php",
- "CodeSniffer/Standards/AbstractVariableSniff.php",
- "CodeSniffer/Standards/IncorrectPatternException.php",
- "CodeSniffer/Standards/Generic/Sniffs/",
- "CodeSniffer/Standards/MySource/Sniffs/",
- "CodeSniffer/Standards/PEAR/Sniffs/",
- "CodeSniffer/Standards/PSR1/Sniffs/",
- "CodeSniffer/Standards/PSR2/Sniffs/",
- "CodeSniffer/Standards/Squiz/Sniffs/",
- "CodeSniffer/Standards/Zend/Sniffs/"
- ]
- },
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
@@ -3408,34 +3789,34 @@
}
],
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
- "homepage": "http://www.squizlabs.com/php-codesniffer",
+ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
"keywords": [
"phpcs",
"standards"
],
- "time": "2018-11-07T22:31:41+00:00"
+ "time": "2019-09-26T23:12:26+00:00"
},
{
"name": "symfony/browser-kit",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
- "reference": "b507697225f32a76a9d333d0766fb46353e9d00d"
+ "reference": "1a3406a6b9b61b492592a816ca056afcc9e976c0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/browser-kit/zipball/b507697225f32a76a9d333d0766fb46353e9d00d",
- "reference": "b507697225f32a76a9d333d0766fb46353e9d00d",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/1a3406a6b9b61b492592a816ca056afcc9e976c0",
+ "reference": "1a3406a6b9b61b492592a816ca056afcc9e976c0",
"shasum": ""
},
"require": {
- "php": ">=5.3.9",
- "symfony/dom-crawler": "~2.1|~3.0.0"
+ "php": "^5.5.9|>=7.0.8",
+ "symfony/dom-crawler": "~2.8|~3.0|~4.0"
},
"require-dev": {
- "symfony/css-selector": "^2.0.5|~3.0.0",
- "symfony/process": "~2.3.34|^2.7.6|~3.0.0"
+ "symfony/css-selector": "~2.8|~3.0|~4.0",
+ "symfony/process": "~2.8|~3.0|~4.0"
},
"suggest": {
"symfony/process": ""
@@ -3443,7 +3824,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -3470,29 +3851,29 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
- "time": "2018-11-26T06:55:10+00:00"
+ "time": "2019-08-26T07:52:58+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "7b1692e418d7ccac24c373528453bc90e42797de"
+ "reference": "e18c5c4b35e7f17513448a25d02f7af34a4bdb41"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/7b1692e418d7ccac24c373528453bc90e42797de",
- "reference": "7b1692e418d7ccac24c373528453bc90e42797de",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/e18c5c4b35e7f17513448a25d02f7af34a4bdb41",
+ "reference": "e18c5c4b35e7f17513448a25d02f7af34a4bdb41",
"shasum": ""
},
"require": {
- "php": ">=5.3.9"
+ "php": "^5.5.9|>=7.0.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -3509,43 +3890,43 @@
],
"authors": [
{
- "name": "Jean-François Simon",
- "email": "jeanfrancois.simon@sensiolabs.com"
- },
- {
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
+ "name": "Jean-François Simon",
+ "email": "jeanfrancois.simon@sensiolabs.com"
+ },
+ {
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2018-11-11T11:18:13+00:00"
+ "time": "2019-08-20T13:31:17+00:00"
},
{
"name": "symfony/dom-crawler",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
- "reference": "2cdc7d3909eea6f982a6298d2e9ab7db01b6403c"
+ "reference": "8558d1bc4554f5cb0b66e50377457967a8969263"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/2cdc7d3909eea6f982a6298d2e9ab7db01b6403c",
- "reference": "2cdc7d3909eea6f982a6298d2e9ab7db01b6403c",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/8558d1bc4554f5cb0b66e50377457967a8969263",
+ "reference": "8558d1bc4554f5cb0b66e50377457967a8969263",
"shasum": ""
},
"require": {
- "php": ">=5.3.9",
+ "php": "^5.5.9|>=7.0.8",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
- "symfony/css-selector": "~2.8|~3.0.0"
+ "symfony/css-selector": "~2.8|~3.0|~4.0"
},
"suggest": {
"symfony/css-selector": ""
@@ -3553,7 +3934,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -3580,29 +3961,29 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
- "time": "2018-11-24T22:30:19+00:00"
+ "time": "2019-08-26T07:52:58+00:00"
},
{
"name": "symfony/process",
- "version": "v2.8.50",
+ "version": "v3.4.31",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "c3591a09c78639822b0b290d44edb69bf9f05dc8"
+ "reference": "d822cb654000a95b7855362c0d5b127f6a6d8baa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/c3591a09c78639822b0b290d44edb69bf9f05dc8",
- "reference": "c3591a09c78639822b0b290d44edb69bf9f05dc8",
+ "url": "https://api.github.com/repos/symfony/process/zipball/d822cb654000a95b7855362c0d5b127f6a6d8baa",
+ "reference": "d822cb654000a95b7855362c0d5b127f6a6d8baa",
"shasum": ""
},
"require": {
- "php": ">=5.3.9"
+ "php": "^5.5.9|>=7.0.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.8-dev"
+ "dev-master": "3.4-dev"
}
},
"autoload": {
@@ -3629,7 +4010,97 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2018-11-11T11:18:13+00:00"
+ "time": "2019-08-26T07:52:58+00:00"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
+ "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "time": "2019-06-13T22:48:21+00:00"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozart/assert.git",
+ "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4",
+ "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "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/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ],
+ "time": "2019-08-24T08:43:50+00:00"
}
],
"aliases": [],
@@ -3638,10 +4109,11 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": ">=5.4"
+ "php": ">=7.1",
+ "ext-json": "*"
},
"platform-dev": [],
"platform-overrides": {
- "php": "5.4.7"
+ "php": "7.1"
}
}
diff --git a/phpBB/config/default/container/parameters.yml b/phpBB/config/default/container/parameters.yml
index 8ecc1428f4..8fcb401914 100644
--- a/phpBB/config/default/container/parameters.yml
+++ b/phpBB/config/default/container/parameters.yml
@@ -14,6 +14,8 @@ parameters:
# List of default password driver types
passwords.algorithms:
+ - passwords.driver.argon2id
+ - passwords.driver.argon2i
- passwords.driver.bcrypt_2y
- passwords.driver.bcrypt
- passwords.driver.salted_md5
diff --git a/phpBB/config/default/container/services.yml b/phpBB/config/default/container/services.yml
index 3ead1e6181..2d4720029d 100644
--- a/phpBB/config/default/container/services.yml
+++ b/phpBB/config/default/container/services.yml
@@ -27,6 +27,7 @@ imports:
- { resource: services_text_formatter.yml }
- { resource: services_text_reparser.yml }
- { resource: services_twig.yml }
+ - { resource: services_ucp.yml }
- { resource: services_user.yml }
- { resource: tables.yml }
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/config/default/container/services_cron.yml b/phpBB/config/default/container/services_cron.yml
index d7f6388536..70f70e355d 100644
--- a/phpBB/config/default/container/services_cron.yml
+++ b/phpBB/config/default/container/services_cron.yml
@@ -3,6 +3,7 @@ services:
class: phpbb\cron\manager
arguments:
- '@cron.task_collection'
+ - '@routing.helper'
- '%core.root_path%'
- '%core.php_ext%'
@@ -13,6 +14,18 @@ services:
- '@config'
- '@dbal.conn'
+ cron.controller:
+ class: phpbb\cron\controller\cron
+
+ cron.event_listener:
+ class: phpbb\cron\event\cron_runner_listener
+ arguments:
+ - '@cron.lock_db'
+ - '@cron.manager'
+ - '@request'
+ tags:
+ - { name: kernel.event_subscriber }
+
# ----- Cron tasks -----
cron.task_collection:
class: phpbb\di\service_collection
diff --git a/phpBB/config/default/container/services_password.yml b/phpBB/config/default/container/services_password.yml
index d5f5fe287b..a9adbebfd7 100644
--- a/phpBB/config/default/container/services_password.yml
+++ b/phpBB/config/default/container/services_password.yml
@@ -1,4 +1,7 @@
parameters:
+ passwords.driver.argon2_memory_cost: 1024
+ passwords.driver.argon2_threads: 2
+ passwords.driver.argon2_time_cost: 2
passwords.driver.bcrypt_cost: 10
services:
@@ -27,6 +30,23 @@ services:
tags:
- { name: service_collection, tag: passwords.driver }
+ passwords.driver.argon2i:
+ class: phpbb\passwords\driver\argon2i
+ arguments:
+ - '@config'
+ - '@passwords.driver_helper'
+ - '%passwords.driver.argon2_memory_cost%'
+ - '%passwords.driver.argon2_threads%'
+ - '%passwords.driver.argon2_time_cost%'
+ tags:
+ - { name: passwords.driver }
+
+ passwords.driver.argon2id:
+ class: phpbb\passwords\driver\argon2id
+ parent: passwords.driver.argon2i
+ tags:
+ - { name: passwords.driver }
+
passwords.driver.bcrypt:
class: phpbb\passwords\driver\bcrypt
arguments:
diff --git a/phpBB/config/default/container/services_routing.yml b/phpBB/config/default/container/services_routing.yml
index 3048145a2f..0bf0a33ab4 100644
--- a/phpBB/config/default/container/services_routing.yml
+++ b/phpBB/config/default/container/services_routing.yml
@@ -12,8 +12,6 @@ services:
class: Symfony\Component\HttpKernel\EventListener\RouterListener
arguments:
- '@router'
- - null
- - null
- '@request_stack'
tags:
- { name: kernel.event_subscriber }
diff --git a/phpBB/config/default/container/services_twig.yml b/phpBB/config/default/container/services_twig.yml
index a9b5b6d4cd..6f70155295 100644
--- a/phpBB/config/default/container/services_twig.yml
+++ b/phpBB/config/default/container/services_twig.yml
@@ -38,10 +38,23 @@ services:
class: phpbb\template\twig\extension
arguments:
- '@template_context'
+ - '@template.twig.environment'
- '@language'
tags:
- { name: twig.extension }
+ template.twig.extensions.avatar:
+ class: phpbb\template\twig\extension\avatar
+ tags:
+ - { name: twig.extension }
+
+ template.twig.extensions.config:
+ class: phpbb\template\twig\extension\config
+ arguments:
+ - '@config'
+ tags:
+ - { name: twig.extension }
+
template.twig.extensions.routing:
class: phpbb\template\twig\extension\routing
arguments:
@@ -49,6 +62,11 @@ services:
tags:
- { name: twig.extension }
+ template.twig.extensions.username:
+ class: phpbb\template\twig\extension\username
+ tags:
+ - { name: twig.extension }
+
template.twig.extensions.debug:
class: Twig_Extension_Debug
diff --git a/phpBB/config/default/container/services_ucp.yml b/phpBB/config/default/container/services_ucp.yml
new file mode 100644
index 0000000000..861fa4ac75
--- /dev/null
+++ b/phpBB/config/default/container/services_ucp.yml
@@ -0,0 +1,17 @@
+services:
+ phpbb.ucp.controller.reset_password:
+ class: phpbb\ucp\controller\reset_password
+ arguments:
+ - '@config'
+ - '@dbal.conn'
+ - '@dispatcher'
+ - '@controller.helper'
+ - '@language'
+ - '@log'
+ - '@passwords.manager'
+ - '@request'
+ - '@template'
+ - '@user'
+ - '%tables.users%'
+ - '%core.root_path%'
+ - '%core.php_ext%'
diff --git a/phpBB/config/default/routing/cron.yml b/phpBB/config/default/routing/cron.yml
new file mode 100644
index 0000000000..5a634166fa
--- /dev/null
+++ b/phpBB/config/default/routing/cron.yml
@@ -0,0 +1,3 @@
+phpbb_cron_run:
+ path: /{cron_type}
+ defaults: { _controller: cron.controller:handle }
diff --git a/phpBB/config/default/routing/routing.yml b/phpBB/config/default/routing/routing.yml
index f381f024ad..a5e9265dc3 100644
--- a/phpBB/config/default/routing/routing.yml
+++ b/phpBB/config/default/routing/routing.yml
@@ -8,6 +8,10 @@
# instantiate the 'foo_service' service and call the 'method' method.
#
+phpbb_cron_routing:
+ resource: cron.yml
+ prefix: /cron
+
phpbb_feed_routing:
resource: feed.yml
prefix: /feed
@@ -22,3 +26,7 @@ phpbb_help_routing:
phpbb_report_routing:
resource: report.yml
+
+phpbb_ucp_routing:
+ resource: ucp.yml
+ prefix: /user
diff --git a/phpBB/config/default/routing/ucp.yml b/phpBB/config/default/routing/ucp.yml
new file mode 100644
index 0000000000..06bd7c3a58
--- /dev/null
+++ b/phpBB/config/default/routing/ucp.yml
@@ -0,0 +1,7 @@
+phpbb_ucp_reset_password_controller:
+ path: /reset_password
+ defaults: { _controller: phpbb.ucp.controller.reset_password:reset }
+
+phpbb_ucp_forgot_password_controller:
+ path: /forgot_password
+ defaults: { _controller: phpbb.ucp.controller.reset_password:request }
diff --git a/phpBB/config/development/config.yml b/phpBB/config/development/config.yml
index f39eb52e73..c782e7a45f 100644
--- a/phpBB/config/development/config.yml
+++ b/phpBB/config/development/config.yml
@@ -3,11 +3,19 @@ imports:
core:
require_dev_dependencies: true
+ allow_install_dir: true
debug:
exceptions: true
+ load_time: true
+ sql_explain: true
+ memory: true
+ show_errors: true
twig:
debug: true
auto_reload: true
enable_debug_extension: true
+
+ session:
+ log_errors: true
diff --git a/phpBB/config/test/config.yml b/phpBB/config/test/config.yml
index 1c17b08931..a603f59dec 100644
--- a/phpBB/config/test/config.yml
+++ b/phpBB/config/test/config.yml
@@ -3,3 +3,4 @@ imports:
core:
require_dev_dependencies: true
+ allow_install_dir: true
diff --git a/phpBB/cron.php b/phpBB/cron.php
index 2f519947aa..c99b772487 100644
--- a/phpBB/cron.php
+++ b/phpBB/cron.php
@@ -11,10 +11,11 @@
*
*/
+use Symfony\Component\HttpFoundation\RedirectResponse;
+
/**
*/
define('IN_PHPBB', true);
-define('IN_CRON', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
@@ -23,62 +24,14 @@ include($phpbb_root_path . 'common.' . $phpEx);
$user->session_begin(false);
$auth->acl($user->data);
-function output_image()
-{
- // Output transparent gif
- header('Cache-Control: no-cache');
- header('Content-type: image/gif');
- header('Content-length: 43');
-
- echo base64_decode('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
-
- // Flush here to prevent browser from showing the page as loading while
- // running cron.
- flush();
-}
-
-// Thanks to various fatal errors and lack of try/finally, it is quite easy to leave
-// the cron lock locked, especially when working on cron-related code.
-//
-// Attempt to alleviate the problem by doing setup outside of the lock as much as possible.
-
$cron_type = $request->variable('cron_type', '');
-// Comment this line out for debugging so the page does not return an image.
-output_image();
-
-/* @var $cron_lock \phpbb\lock\db */
-$cron_lock = $phpbb_container->get('cron.lock_db');
-if ($cron_lock->acquire())
-{
- /* @var $cron \phpbb\cron\manager */
- $cron = $phpbb_container->get('cron.manager');
-
- $task = $cron->find_task($cron_type);
- if ($task)
- {
- /**
- * This event enables you to catch the task before it runs
- *
- * @event core.cron_run_before
- * @var \phpbb\cron\task\wrapper task Current Cron task
- * @since 3.1.8-RC1
- */
- $vars = array(
- 'task',
- );
- extract($phpbb_dispatcher->trigger_event('core.cron_run_before', compact($vars)));
-
- if ($task->is_parametrized())
- {
- $task->parse_parameters($request);
- }
- if ($task->is_ready())
- {
- $task->run();
- }
- }
- $cron_lock->release();
-}
+$get_params_array = $request->get_super_global(\phpbb\request\request_interface::GET);
-garbage_collection();
+/** @var \phpbb\controller\helper $controller_helper */
+$controller_helper = $phpbb_container->get('controller.helper');
+$response = new RedirectResponse(
+ $controller_helper->route('phpbb_cron_run', $get_params_array, false),
+ 301
+);
+$response->send();
diff --git a/phpBB/develop/add_permissions.php b/phpBB/develop/add_permissions.php
index d7308a1acc..d2c8bffd90 100644
--- a/phpBB/develop/add_permissions.php
+++ b/phpBB/develop/add_permissions.php
@@ -210,7 +210,7 @@ foreach ($prefixes as $prefix)
);
$db->sql_query('INSERT INTO ' . ACL_OPTIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
-
+
echo "<p><b>Adding $auth_option...</b></p>\n";
mass_auth('group', 0, 'guests', $auth_option, ACL_NEVER);
@@ -231,7 +231,7 @@ $db->sql_query($sql);
$cache->destroy('_acl_options');
echo "<p><b>Done</b></p>\n";
-
+
/*
$ug_type = user|group
$forum_id = forum ids (array|int|0) -> 0 == all forums
@@ -374,11 +374,6 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting)
case 'insert':
switch ($db->get_sql_layer())
{
- case 'mysql':
- case 'mysql4':
- $sql = 'VALUES ' . implode(', ', preg_replace('#^(.*?)$#', '(\1)', $sql_subary));
- break;
-
case 'sqlite3':
$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
break;
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/create_schema_files.php b/phpBB/develop/create_schema_files.php
index 6e0a082045..fdaa285f99 100644
--- a/phpBB/develop/create_schema_files.php
+++ b/phpBB/develop/create_schema_files.php
@@ -21,7 +21,6 @@
$schema_path = dirname(__FILE__) . '/../install/schemas/';
$supported_dbms = array(
'mssql',
- 'mysql_40',
'mysql_41',
'oracle',
'postgres',
diff --git a/phpBB/develop/mysql_upgrader.php b/phpBB/develop/mysql_upgrader.php
deleted file mode 100644
index 276c010e84..0000000000
--- a/phpBB/develop/mysql_upgrader.php
+++ /dev/null
@@ -1,212 +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.
-*
-*/
-
-/**
-* This file creates SQL statements to upgrade phpBB on MySQL 3.x/4.0.x to 4.1.x/5.x
-*/
-
-//
-// 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");
-
-define('IN_PHPBB', true);
-$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
-$phpEx = substr(strrchr(__FILE__, '.'), 1);
-include($phpbb_root_path . 'common.' . $phpEx);
-
-$prefix = $table_prefix;
-
-$newline = "\n";
-
-if (PHP_SAPI !== 'cli')
-{
- $newline = '<br>';
-}
-
-$sql = 'DESCRIBE ' . POSTS_TABLE . ' post_text';
-$result = $db->sql_query($sql);
-
-$row = $db->sql_fetchrow($result);
-
-$db->sql_freeresult($result);
-
-$mysql_indexer = $drop_index = false;
-
-if (strtolower($row['Type']) === 'mediumtext')
-{
- $mysql_indexer = true;
-}
-
-if (strtolower($row['Key']) === 'mul')
-{
- $drop_index = true;
-}
-
-echo "USE $dbname;$newline$newline";
-
-
-@set_time_limit(0);
-
-$finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path);
-$classes = $finder->core_path('phpbb/')
- ->directory('/db/migration/data')
- ->get_classes();
-
-$factory = new \phpbb\db\tools\factory();
-$db_tools = $factory->get($db, true);
-
-$schema_generator = new \phpbb\db\migration\schema_generator($classes, $config, $db, $db_tools, $phpbb_root_path, $phpEx, $table_prefix);
-$schema_data = $schema_generator->get_schema();
-$dbms_type_map = \phpbb\db\tools\tools::get_dbms_type_map();
-
-foreach ($schema_data as $table_name => $table_data)
-{
- $table_name = str_replace('phpbb_', $prefix, $table_name);
- // Write comment about table
- echo "# Table: '{$table_name}'$newline";
-
- // Create Table statement
- $generator = $textimage = false;
-
- // Do we need to DROP a fulltext index before we alter the table?
- if ($table_name == ($prefix . 'posts') && $drop_index)
- {
- echo "ALTER TABLE {$table_name}{$newline}";
- echo "DROP INDEX post_text,{$newline}DROP INDEX post_subject,{$newline}DROP INDEX post_content;{$newline}{$newline}";
- }
-
- $line = "ALTER TABLE {$table_name} $newline";
-
- // Table specific so we don't get overlap
- $modded_array = array();
-
- // Write columns one by one...
- foreach ($table_data['COLUMNS'] as $column_name => $column_data)
- {
- // Get type
- if (strpos($column_data[0], ':') !== false)
- {
- list($orig_column_type, $column_length) = explode(':', $column_data[0]);
- $column_type = sprintf($dbms_type_map['mysql_41'][$orig_column_type . ':'], $column_length);
-
- if (isset($dbms_type_map['mysql_40'][$orig_column_type . ':']['limit']) &&
- isset($dbms_type_map['mysql_40'][$orig_column_type . ':']['limit'][0]))
- {
- switch ($dbms_type_map['mysql_40'][$orig_column_type . ':']['limit'][0])
- {
- case 'mult':
- if (($column_length * $dbms_type_map['mysql_40'][$orig_column_type . ':']['limit'][1]) > $dbms_type_map['mysql_40'][$orig_column_type . ':']['limit'][2])
- {
- $modded_array[$column_name] = $column_type;
- }
- break;
- }
- }
-
- $orig_column_type .= ':';
- }
- else
- {
- $orig_column_type = $column_data[0];
- $other_column_type = $dbms_type_map['mysql_40'][$column_data[0]];
- if ($other_column_type == 'text' || $other_column_type == 'blob')
- {
- $modded_array[$column_name] = $column_type;
- }
- $column_type = $dbms_type_map['mysql_41'][$column_data[0]];
- }
-
- // Adjust default value if db-dependent specified
- if (is_array($column_data[1]))
- {
- $column_data[1] = (isset($column_data[1][$dbms])) ? $column_data[1][$dbms] : $column_data[1]['default'];
- }
-
- $line .= "\tMODIFY {$column_name} {$column_type} ";
-
- // For hexadecimal values do not use single quotes
- if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob')
- {
- $line .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' ";
- }
- $line .= 'NOT NULL';
-
- if (isset($column_data[2]))
- {
- if ($column_data[2] == 'auto_increment')
- {
- $line .= ' auto_increment';
- }
- else if ($column_data[2] == 'true_sort')
- {
- $line .= ' COLLATE utf8_unicode_ci';
- }
- else if ($column_data[2] == 'no_sort')
- {
- $line .= ' COLLATE utf8_bin';
- }
- }
- else if (preg_match('/(?:var)?char|(?:medium)?text/i', $column_type))
- {
- $line .= ' COLLATE utf8_bin';
- }
-
- $line .= ",$newline";
- }
-
- // Write Keys
- if (isset($table_data['KEYS']))
- {
- foreach ($table_data['KEYS'] as $key_name => $key_data)
- {
- $temp = '';
- if (!is_array($key_data[1]))
- {
- $key_data[1] = array($key_data[1]);
- }
-
- $temp .= ($key_data[0] == 'INDEX') ? "\tADD KEY" : '';
- $temp .= ($key_data[0] == 'UNIQUE') ? "\tADD UNIQUE" : '';
- $repair = false;
- foreach ($key_data[1] as $key => $col_name)
- {
- if (isset($modded_array[$col_name]))
- {
- $repair = true;
- }
- }
- if ($repair)
- {
- $line .= "\tDROP INDEX " . $key_name . ",$newline";
- $line .= $temp;
- $line .= ' ' . $key_name . ' (' . implode(', ', $key_data[1]) . "),$newline";
- }
- }
- }
-
- //$line .= "\tCONVERT TO CHARACTER SET `utf8`$newline";
- $line .= "\tDEFAULT CHARSET=utf8 COLLATE=utf8_bin;$newline$newline";
-
- echo $line . "$newline";
-
- // Do we now need to re-add the fulltext index? ;)
- if ($table_name == ($prefix . 'posts') && $drop_index)
- {
- echo "ALTER TABLE $table_name ADD FULLTEXT (post_subject), ADD FULLTEXT (post_text), ADD FULLTEXT post_content (post_subject, post_text);{$newline}";
- }
-}
diff --git a/phpBB/develop/regex.php b/phpBB/develop/regex.php
index 46b6fff701..77c6d5c0e6 100644
--- a/phpBB/develop/regex.php
+++ b/phpBB/develop/regex.php
@@ -8,46 +8,6 @@
//
die("Please read the first lines of this script for instructions on how to enable it");
-
-// IP regular expressions
-
-$dec_octet = '(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])';
-$h16 = '[\dA-F]{1,4}';
-$ipv4 = "(?:$dec_octet\.){3}$dec_octet";
-$ls32 = "(?:$h16:$h16|$ipv4)";
-
-$ipv6_construct = array(
- array(false, '', '{6}', $ls32),
- array(false, '::', '{0,5}', "(?:$h16(?::$h16)?|$ipv4)"),
- array('', ':', '{4}', $ls32),
- array('{1,2}', ':', '{3}', $ls32),
- array('{1,3}', ':', '{2}', $ls32),
- array('{1,4}', ':', '', $ls32),
- array('{1,5}', ':', false, $ls32),
- array('{1,6}', ':', false, $h16),
- array('{1,7}', ':', false, ''),
- array(false, '::', false, '')
-);
-
-$ipv6 = '(?:';
-foreach ($ipv6_construct as $ip_type)
-{
- $ipv6 .= '(?:';
- if ($ip_type[0] !== false)
- {
- $ipv6 .= "(?:$h16:)" . $ip_type[0];
- }
- $ipv6 .= $ip_type[1];
- if ($ip_type[2] !== false)
- {
- $ipv6 .= "(?:$h16:)" . $ip_type[2];
- }
- $ipv6 .= $ip_type[3] . ')|';
-}
-$ipv6 = substr($ipv6, 0, -1) . ')';
-
-echo 'IPv4: ' . $ipv4 . "<br />\nIPv6: " . $ipv6 . "<br />\n";
-
// URL regular expressions
$pct_encoded = "%[\dA-F]{2}";
diff --git a/phpBB/develop/regex_idn.php b/phpBB/develop/regex_idn.php
index 30373f8de3..24d1eb9196 100644
--- a/phpBB/develop/regex_idn.php
+++ b/phpBB/develop/regex_idn.php
@@ -8,45 +8,6 @@
//
die("Please read the first lines of this script for instructions on how to enable it");
-// IP regular expressions
-
-$dec_octet = '(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])';
-$h16 = '[\dA-F]{1,4}';
-$ipv4 = "(?:$dec_octet\.){3}$dec_octet";
-$ls32 = "(?:$h16:$h16|$ipv4)";
-
-$ipv6_construct = array(
- array(false, '', '{6}', $ls32),
- array(false, '::', '{0,5}', "(?:$h16(?::$h16)?|$ipv4)"),
- array('', ':', '{4}', $ls32),
- array('{1,2}', ':', '{3}', $ls32),
- array('{1,3}', ':', '{2}', $ls32),
- array('{1,4}', ':', '', $ls32),
- array('{1,5}', ':', false, $ls32),
- array('{1,6}', ':', false, $h16),
- array('{1,7}', ':', false, ''),
- array(false, '::', false, '')
-);
-
-$ipv6 = '(?:';
-foreach ($ipv6_construct as $ip_type)
-{
- $ipv6 .= '(?:';
- if ($ip_type[0] !== false)
- {
- $ipv6 .= "(?:$h16:)" . $ip_type[0];
- }
- $ipv6 .= $ip_type[1];
- if ($ip_type[2] !== false)
- {
- $ipv6 .= "(?:$h16:)" . $ip_type[2];
- }
- $ipv6 .= $ip_type[3] . ')|';
-}
-$ipv6 = substr($ipv6, 0, -1) . ')';
-
-echo 'IPv4: ' . $ipv4 . "<br /><br />\n\nIPv6: " . $ipv6 . "<br /><br />\n\n";
-
// URL regular expressions
/* IDN2008 characters derivation
@@ -72,7 +33,7 @@ $no_hangul = '\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C
*/
$no_cdm = '\x{20D0}-\x{20FF}'; // \p{block=Combining_Diacritical_Marks_For_Symbols}
$no_musical = '\x{1D100}-\x{1D1FF}'; // \p{block=Musical_Symbols}
-$no_ancient_greek_musical = '\x{1D200}-\x{1D24F}'; // \p{block=Ancient_Greek_Musical_Notation}
+$no_ancient_greek_musical = '\x{1D200}-\x{1D24F}'; // \p{block=Ancient_Greek_Musical_Notation}
/* Remove certain exceptions:
** U+0640 ARABIC TATWEEL
** U+07FA NKO LAJANYALAN
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 06cdb37b56..d229b91bd6 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="keywords" content="" />
-<meta name="description" content="phpBB 3.2.x Changelog" />
+<meta name="description" content="phpBB 3.3.x Changelog" />
<title>phpBB &bull; Changelog</title>
<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen" />
@@ -21,7 +21,7 @@
<div id="doc-description">
<a href="../index.php" id="logo"><img src="assets/images/site_logo.gif" alt="" /></a>
- <h1>phpBB 3.2.x Changelog</h1>
+ <h1>phpBB 3.3.x Changelog</h1>
<p style="display: none;"><a href="#start_here">Skip</a></p>
</div>
@@ -36,7 +36,7 @@
<!-- BEGIN DOCUMENT -->
<p class="paragraph main-description">
- This is a non-exhaustive (but still near complete) changelog for phpBB 3.2.x including release candidate versions.
+ This is a non-exhaustive (but still near complete) changelog for phpBB 3.3.x including release candidate versions.
Our thanks to all those people who've contributed bug reports and code fixes.
</p>
@@ -50,6 +50,8 @@
<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>
<li><a href="#v326">Changes since 3.2.6</a></li>
@@ -140,6 +142,138 @@
<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>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14670">PHPBB3-14670</a>] - Use latest symfony branch in master</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14769">PHPBB3-14769</a>] - CLI Installer Fails</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14815">PHPBB3-14815</a>] - The facebook page link is not displayed properly in membership.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15255">PHPBB3-15255</a>] - Language variables of filesystem exception should moved</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15351">PHPBB3-15351</a>] - Confirm box function does not work with symlink on server config</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15377">PHPBB3-15377</a>] - INCLUDECSS and INCLUDEJS broken on all front controllers (app.php)</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15400">PHPBB3-15400</a>] - app.php urls aren't working in vagrant because of nginx</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15424">PHPBB3-15424</a>] - Fix typos in coding guidelines, comments, events list &amp; credits</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15436">PHPBB3-15436</a>] - Remove folder icons from index</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15522">PHPBB3-15522</a>] - Allow multiple color palettes per page</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15643">PHPBB3-15643</a>] - $phpbb_filesystem-&gt;resolve_path() may triggers open_basedir restriction</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15686">PHPBB3-15686</a>] - Update homestead for vagrant</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15720">PHPBB3-15720</a>] - Redirections dont need to escape ampersands</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15725">PHPBB3-15725</a>] - Testing framework fails to install extensions because of outdated assertion</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15744">PHPBB3-15744</a>] - Not all sql querys need to free memory</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15828">PHPBB3-15828</a>] - php 7.3 warning in installing 3.2.3 and installtion failed</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15846">PHPBB3-15846</a>] - Wrong id for downloadable extension group</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15922">PHPBB3-15922</a>] - Remove support for APC cache</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15935">PHPBB3-15935</a>] - Check if APCu is installed before installing it</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15938">PHPBB3-15938</a>] - Static attributes blacklist references no longer existing classes</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15991">PHPBB3-15991</a>] - Tables in ACP are displayed incorrectly</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16003">PHPBB3-16003</a>] - Post count not updated when deleting only post in topic</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16048">PHPBB3-16048</a>] - Unable to restore any backup from ACP</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16050">PHPBB3-16050</a>] - PHP warning in MCP banning tab on PHP 7.2+</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16057">PHPBB3-16057</a>] - Fix vagrant in 3.3</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16074">PHPBB3-16074</a>] - Twemoji -fe0f sequence not rendering</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16076">PHPBB3-16076</a>] - Limit attachment size by extension group</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16131">PHPBB3-16131</a>] - Force vagrant to install phpBB with a specific PHP version</li>
+ </ul>
+ <h4>Improvement</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11515">PHPBB3-11515</a>] - Add interface for lock classes and add new methods</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11838">PHPBB3-11838</a>] - OAuth registration from ucp_register</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12591">PHPBB3-12591</a>] - Improve breadcrumb functionality with new &quot;Home page&quot;/&quot;Forum index&quot; link</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14465">PHPBB3-14465</a>] - Remove maximum password length setting</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14573">PHPBB3-14573</a>] - Extend breadcrumb to support more pages</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14948">PHPBB3-14948</a>] - Changes 3.3 PHP requirement to 7.1</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14972">PHPBB3-14972</a>] - PHP 7.2 compatibility: wrong sizeof/count parameter type</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15088">PHPBB3-15088</a>] - Optimize code for extension manager to avoid repetitions</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15153">PHPBB3-15153</a>] - Update laravel/homestead box for vagrant</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15203">PHPBB3-15203</a>] - Missing constants during web installation</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15257">PHPBB3-15257</a>] - Extensions may indicate reasons why they cannot enable</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15269">PHPBB3-15269</a>] - Set development environment and enable all debugs when installing with vagrant</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15274">PHPBB3-15274</a>] - Migration &quot;custom&quot; tool does not allow parameters</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15295">PHPBB3-15295</a>] - Restore MyIsam and mysql environments to test suite</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15330">PHPBB3-15330</a>] - Twig function to know if a language string is defined</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15413">PHPBB3-15413</a>] - Login from any page and redirecting back there</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15508">PHPBB3-15508</a>] - Upgrade Twig to version 2.x</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15564">PHPBB3-15564</a>] - Switch to Invisible reCAPTCHA</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15580">PHPBB3-15580</a>] - Remove extra settings in ACP</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15610">PHPBB3-15610</a>] - Improving UI of Board Statistics in ACP</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15646">PHPBB3-15646</a>] - Add support for Argon2i passwords</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15663">PHPBB3-15663</a>] - Remove flash support in attachments</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15664">PHPBB3-15664</a>] - Manage extensions with ajax</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15671">PHPBB3-15671</a>] - Limit accepted formats to allowed extensions in avatars upload</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15694">PHPBB3-15694</a>] - Add style-related language files into .gitignore</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15714">PHPBB3-15714</a>] - Login after register</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15718">PHPBB3-15718</a>] - Update CONTRIBUTING.md</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15772">PHPBB3-15772</a>] - Hide warning message in acp when install dir is present and allow_install_dir is true</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15905">PHPBB3-15905</a>] - Create multiple twig extensions</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15940">PHPBB3-15940</a>] - Expose user_id to notif method's is_available and add event before it to load user data</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15987">PHPBB3-15987</a>] - Make table parameters an array</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16016">PHPBB3-16016</a>] - Provide a base class to implement password hashing via native functions</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16017">PHPBB3-16017</a>] - Add support for Argon2id password hashing</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16081">PHPBB3-16081</a>] - Remove eAccelerator as its latest supported PHP version is 5.3</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16082">PHPBB3-16082</a>] - Remove XCache as it does not support PHP 7</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16115">PHPBB3-16115</a>] - Add PHP 7.4 builds to travis CI</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16144">PHPBB3-16144</a>] - NO_STYLE_DATA - Provide extra fallback to board's default style for $user.</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16148">PHPBB3-16148</a>] - Add template events to acp_groups.html</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16159">PHPBB3-16159</a>] - Wrap post times in html time tag</li>
+ </ul>
+ <h4>New Feature</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11327">PHPBB3-11327</a>] - Implement reset password functionality via form instead of sending password</li>
+ </ul>
+ <h4>Sub-task</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12624">PHPBB3-12624</a>] - Add debug.load_time</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12627">PHPBB3-12627</a>] - Add debug.sql_explain</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12628">PHPBB3-12628</a>] - Add debug.memory</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12629">PHPBB3-12629</a>] - Add debug.errors_show</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12635">PHPBB3-12635</a>] - Add allow_install_dir</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12636">PHPBB3-12636</a>] - Add log.session_errors</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14542">PHPBB3-14542</a>] - Move cron to controller</li>
+ </ul>
+ <h4>Task</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14584">PHPBB3-14584</a>] - Move deprecated globals and functions to compatibility_*.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14761">PHPBB3-14761</a>] - Update travis tests setup too, move myisam from PHP 5.4 to 5.5</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15244">PHPBB3-15244</a>] - Remove the UNGLOBALISE-related code</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15410">PHPBB3-15410</a>] - Remove obsolete code from BBCodes ACP</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15422">PHPBB3-15422</a>] - Remove the unnecessary helpline function and help_line variable</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15738">PHPBB3-15738</a>] - Remove code related with safe mode</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15746">PHPBB3-15746</a>] - Update dependencies for 3.2.3</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15921">PHPBB3-15921</a>] - Update TextFormatter to 1.3.2</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15927">PHPBB3-15927</a>] - Fix ACP table display error</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16051">PHPBB3-16051</a>] - Remove mysql driver as it's unsupported</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16052">PHPBB3-16052</a>] - Branch off 3.3.x branch</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16067">PHPBB3-16067</a>] - Define trusty build environment for travis builds</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16072">PHPBB3-16072</a>] - Update s9e/text-formatter</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16112">PHPBB3-16112</a>] - Update composer dependencies to latest</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16175">PHPBB3-16175</a>] - Update composer.json dependencies for 3.3.0-b1</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16185">PHPBB3-16185</a>] - Use Xenial build environment on travis-ci</li>
+ </ul>
+
<a name="v328rc1"></a><h3>Changes since 3.2.8-RC1</h3>
<h4>Bug</h4>
<ul>
diff --git a/phpBB/docs/CREDITS.txt b/phpBB/docs/CREDITS.txt
index 596f4545fa..64f5588bac 100644
--- a/phpBB/docs/CREDITS.txt
+++ b/phpBB/docs/CREDITS.txt
@@ -84,10 +84,10 @@ prosilver by subBlue Design, Tom Beddard, (c) 2004 phpBB Limited
phpBB contains code from the following applications:
-LGPL licenced:
+LGPL licensed:
Smarty (c) 2001, 2002 by ispi of Lincoln, Inc, http://smarty.php.net/
-GPL licenced:
+GPL licensed:
phpMyAdmin (c) 2001, 2003 phpMyAdmin Devel team, http://www.phpmyadmin.net/
Jabber Class (c) 2006 Flyspray.org, http://www.flyspray.org/
Chora (c) 2000-2006, The Horde Project. http://horde.org/chora/
@@ -101,7 +101,7 @@ Pear (c) 2001-2004 PHP Group, http://pear.php.net
Text_Diff-0.2.1 http://pear.php.net/package/Text_Diff
-MIT licenced:
+MIT licensed:
Symfony2 (c) 2004-2011 Fabien Potencier, https://symfony.com/
Cookie Consent (c) 2015 Silktide Ltd, https://cookieconsent.insites.com
diff --git a/phpBB/docs/FAQ.html b/phpBB/docs/FAQ.html
index 09ee6c1ddd..fb097911d8 100644
--- a/phpBB/docs/FAQ.html
+++ b/phpBB/docs/FAQ.html
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="keywords" content="" />
-<meta name="description" content="phpBB 3.2.x frequently asked questions" />
+<meta name="description" content="phpBB 3.3.x frequently asked questions" />
<title>phpBB &bull; FAQ</title>
<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen" />
@@ -21,8 +21,8 @@
<div id="doc-description">
<a href="../index.php" id="logo"><img src="assets/images/site_logo.gif" alt="" /></a>
- <h1>phpBB 3.2.x FAQ</h1>
- <p>phpBB 3.2.x frequently asked questions</p>
+ <h1>phpBB 3.3.x FAQ</h1>
+ <p>phpBB 3.3.x frequently asked questions</p>
<p style="display: none;"><a href="#start_here">Skip</a></p>
</div>
@@ -249,7 +249,7 @@ I want to sue you because i think you host an illegal board!</h2>
<div class="content">
-<p>Please read the paragraph about permissions in our extensive <a href="https://www.phpbb.com/support/docs/en/3.2/ug/">online documentation</a>.</p>
+<p>Please read the paragraph about permissions in our extensive <a href="https://www.phpbb.com/support/docs/en/3.3/ug/">online documentation</a>.</p>
</div>
@@ -305,7 +305,7 @@ I want to sue you because i think you host an illegal board!</h2>
<div class="content">
-<p>Please read our <a href="https://www.phpbb.com/support/docs/en/3.2/ug/">extensive user documentation</a> first, it may just explain what you want to know.</p>
+<p>Please read our <a href="https://www.phpbb.com/support/docs/en/3.3/ug/">extensive user documentation</a> first, it may just explain what you want to know.</p>
<p>Feel free to search our community forum for the information you require. <strong>PLEASE DO NOT</strong> post your question without having first used search, chances are someone has already asked and answered your question. You can find our board here:</p>
diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html
index 4f7f07d3dc..fbc701a2ca 100644
--- a/phpBB/docs/INSTALL.html
+++ b/phpBB/docs/INSTALL.html
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="keywords" content="" />
-<meta name="description" content="phpBB 3.2.x Installation, updating and conversion informations" />
+<meta name="description" content="phpBB 3.3.x Installation, updating and conversion informations" />
<title>phpBB &bull; Install</title>
<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen" />
@@ -21,8 +21,8 @@
<div id="doc-description">
<a href="../index.php" id="logo"><img src="assets/images/site_logo.gif" alt="" /></a>
- <h1>phpBB 3.2.x Install</h1>
- <p>phpBB 3.2.x Installation, updating and conversion informations</p>
+ <h1>phpBB 3.3.x Install</h1>
+ <p>phpBB 3.3.x Installation, updating and conversion informations</p>
<p style="display: none;"><a href="#start_here">Skip</a></p>
</div>
@@ -44,7 +44,7 @@
<p>
A basic overview of running phpBB can be found in the accompanying <a href="README.html">README</a> file.
Please ensure you read that document in addition to this! For more detailed information on using, installing,
- updating and converting phpBB you should read <a href="https://www.phpbb.com/support/docs/en/3.2/ug/">the documentation</a>
+ updating and converting phpBB you should read <a href="https://www.phpbb.com/support/docs/en/3.3/ug/">the documentation</a>
available online.
</p>
</div>
@@ -59,7 +59,7 @@
<li><a href="#quickinstall">Quick install</a></li>
<li><a href="#require">Requirements</a></li>
<li><a href="#install">New installation</a></li>
- <li><a href="#update">Updating from stable releases of phpBB 3.2.x</a>
+ <li><a href="#update">Updating from stable releases of phpBB 3.3.x</a>
<ol style="list-style-type: lower-roman;">
<li><a href="#update_full">Full package</a></li>
<li><a href="#update_files">Changed files</a></li>
@@ -68,8 +68,8 @@
<li><a href="#update_all">All package types</a></li>
</ol>
</li>
- <li><a href="#update30_31">Updating from phpBB 3.0.x/3.1.x to phpBB 3.2.x</a></li>
- <li><a href="#convert">Conversion from phpBB 2.0.x to phpBB 3.2.x</a>
+ <li><a href="#update30_31">Updating from phpBB 3.0.x/3.1.x to phpBB 3.2.x or phpBB 3.3.x</a></li>
+ <li><a href="#convert">Conversion from phpBB 2.0.x to phpBB 3.3.x</a>
<ol style="list-style-type: lower-roman;">
<li><a href="#prereq">Requirements before converting</a></li>
<li><a href="#conversion">Converting</a></li>
@@ -139,7 +139,7 @@
<li>A webserver or web hosting account running on any major Operating System with support for PHP</li>
<li>A SQL database system, <strong>one of</strong>:
<ul>
- <li>MySQL 3.23 or above (MySQLi supported)</li>
+ <li>MySQL 4.1.3 or above (MySQLi required)</li>
<li>MariaDB 5.1 or above</li>
<li>PostgreSQL 8.3+</li>
<li>SQLite 3.6.15+</li>
@@ -147,10 +147,11 @@
<li>Oracle</li>
</ul>
</li>
- <li><strong>PHP 5.4.7+</strong> but less than <strong>PHP 7.3</strong> with support for the database you intend to use.</li>
+ <li><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>
+ <li>XML support</li>
</ul>
</li>
<li>getimagesize() function must be enabled.</li>
@@ -158,13 +159,12 @@
<ul>
<li>zlib Compression support</li>
<li>Remote FTP support</li>
- <li>XML support</li>
<li>GD Support</li>
</ul>
</li>
</ul>
- <p>If your server or hosting account does not meet the requirements above then you will be unable to install phpBB 3.2.x.</p>
+ <p>If your server or hosting account does not meet the requirements above then you will be unable to install phpBB 3.3.x.</p>
</div>
@@ -255,7 +255,7 @@
<hr />
- <a name="update"></a><h2>4. Updating from stable releases of phpBB 3.2.x</h2>
+ <a name="update"></a><h2>4. Updating from stable releases of phpBB 3.3.x</h2>
<div class="paragraph">
<div class="inner">
@@ -280,7 +280,7 @@
<p>This package is meant for those wanting to only replace the files that were changed between a previous version and the latest version.</p>
- <p>This package contains a number of archives, each contains the files changed from a given release to the latest version. You should select the appropriate archive for your current version, e.g. if you currently have <strong>3.2.0</strong> you should select the appropriate <code>phpBB-3.2.1-files.zip/tar.bz2</code> file.</p>
+ <p>This package contains a number of archives, each contains the files changed from a given release to the latest version. You should select the appropriate archive for your current version, e.g. if you currently have <strong>3.3.0</strong> you should select the appropriate <code>phpBB-3.3.1-files.zip/tar.bz2</code> file.</p>
<p>The directory structure has been preserved, enabling you (if you wish) to simply upload the uncompressed contents of the archive to the appropriate location on your server, i.e. simply overwrite the existing files with the new versions. Do not forget that if you have installed any modifications (MODs) these files will overwrite the originals, possibly destroying them in the process. You will need to re-add MODs to any affected file before uploading.</p>
@@ -292,7 +292,7 @@
<p>The patch file is one solution for those with changes in to the phpBB core files and do not want to re-add them back to all the changed files. To use this you will need command line access to a standard UNIX type <strong>patch</strong> application. If you do not have access to such an application, but still want to use this update approach, we strongly recommend the <a href="#update_auto">Automatic update package</a> explained below. It is also the recommended update method.</p>
- <p>A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is <strong>3.2.0</strong>, you need the <code>phpBB-3.2.1-patch.zip/tar.bz2</code> file. Place the correct patch in the parent directory containing the phpBB core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: <code>patch -cl -d [PHPBB DIRECTORY] -p1 &lt; [PATCH NAME]</code> (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.</p>
+ <p>A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is <strong>3.3.0</strong>, you need the <code>phpBB-3.3.1-patch.zip/tar.bz2</code> file. Place the correct patch in the parent directory containing the phpBB core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: <code>patch -cl -d [PHPBB DIRECTORY] -p1 &lt; [PATCH NAME]</code> (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.</p>
<p>If you do get failures, you should look at using the <a href="#update_files">Changed Files</a> package to replace the files which failed to patch. Please note that you will need to manually re-add any MODs to these particular files. Alternatively, if you know how, you can examine the .rej files to determine what failed where and make manual adjustments to the relevant source.</p>
@@ -302,7 +302,7 @@
<p>This update method is only recommended for installations with modifications to core phpBB files. This package detects changed files automatically and merges in changes if needed.</p>
- <p>The automatic update package will update the board from a given version to the latest version. A number of automatic update files are available, and you should choose the one that corresponds to the version of the board that you are currently running. For example, if your current version is <strong>3.2.0</strong>, you need the <code>phpBB-3.2.0_to_3.2.1.zip/tar.bz2</code> file.</p>
+ <p>The automatic update package will update the board from a given version to the latest version. A number of automatic update files are available, and you should choose the one that corresponds to the version of the board that you are currently running. For example, if your current version is <strong>3.3.0</strong>, you need the <code>phpBB-3.3.0_to_3.3.1.zip/tar.bz2</code> file.</p>
<p>To perform the update, either follow the instructions from the <strong>Administration Control Panel-&gt;System</strong> Tab - this should point out that you are running an outdated version and will guide you through the update - or follow the instructions listed below.</p>
@@ -331,16 +331,16 @@
<hr />
- <a name="update30_31"></a><h2>5. Updating from phpBB 3.0.x/3.1x to phpBB 3.2.x</h2>
+ <a name="update30_31"></a><h2>5. Updating from phpBB 3.0.x/3.1x to phpBB 3.2.x or phpBB 3.3.x</h2>
<div class="paragraph">
<div class="inner"><span class="corners-top"><span></span></span>
<div class="content">
- <p>Updating from phpBB 3.0.x or 3.1.x to 3.2.x is just the same as <a href="#update">updating from stable releases of phpBB 3.2.x</a></p>
+ <p>Updating from phpBB 3.0.x or 3.1.x to 3.2.x or 3.3.x is just the same as <a href="#update">updating from stable releases of phpBB 3.3.x</a></p>
- <p>However you can also start with a new set of phpBB 3.2.x files.</p>
+ <p>However you can also start with a new set of phpBB 3.3.x files.</p>
<ol>
<li>Delete all files <strong>EXCEPT</strong> for the following:
@@ -353,7 +353,7 @@
<li>(The <code>ext/</code> directory</li>
</ul></li>
- <li>Upload the contents of the 3.2.x Full Package into your forum's directory. Make sure the root level .htaccess file is included in the upload.</li>
+ <li>Upload the contents of the 3.3.x Full Package into your forum's directory. Make sure the root level .htaccess file is included in the upload.</li>
<li>Browse to <code>/install/app.php/update</code></li>
<li>Read the notice <em>Update database only</em> and press <strong>Submit</strong></li>
<li>Delete the <code>install/</code> directory</li>
@@ -367,7 +367,7 @@
<hr />
- <a name="convert"></a><h2>6. Conversion from phpBB 2.0.x to phpBB 3.2.x</h2>
+ <a name="convert"></a><h2>6. Conversion from phpBB 2.0.x to phpBB 3.3.x</h2>
<div class="paragraph">
<div class="inner">
diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html
index 8fb9036ad8..ca50fe95be 100644
--- a/phpBB/docs/README.html
+++ b/phpBB/docs/README.html
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="keywords" content="" />
-<meta name="description" content="phpBB 3.2.x Readme" />
+<meta name="description" content="phpBB 3.3.x Readme" />
<title>phpBB &bull; Readme</title>
<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen" />
@@ -21,7 +21,7 @@
<div id="doc-description">
<a href="../index.php" id="logo"><img src="assets/images/site_logo.gif" alt="" /></a>
- <h1>phpBB 3.2.x Readme</h1>
+ <h1>phpBB 3.3.x Readme</h1>
<p style="display: none;"><a href="#start_here">Skip</a></p>
</div>
@@ -91,13 +91,13 @@
<div class="content">
<p>Installation, update and conversion instructions can be found in the <a href="INSTALL.html">INSTALL</a> document in this directory. If you are intending on converting from a phpBB 2.0.x or 3.0.x installation we highly recommend that you backup any existing data before proceeding!</p>
- <p>Users of phpBB 3.0, 3.1 and 3.2 Beta versions cannot directly update.</p>
+ <p>Users of phpBB 3.0, 3.1, 3.2, and 3.3 Beta versions cannot directly update.</p>
<p>Please note that we don't support the following installation types:</p>
<ul>
<li>Updates from phpBB Beta versions and lower to phpBB Release Candidates and higher</li>
- <li>Conversions from phpBB 2.0.x to phpBB 3.0 Beta, 3.1 Beta and 3.2 Beta versions</li>
- <li>phpBB 3.0 Beta, 3.1 Beta or 3.2 beta installations</li>
+ <li>Conversions from phpBB 2.0.x to phpBB 3.0 Beta, 3.1 Beta, 3.2 Beta, and 3.3 Beta versions</li>
+ <li>phpBB 3.0 Beta, 3.1 Beta, 3.2 beta, or 3.3 beta installations</li>
</ul>
<p>We give support for the following installation types:</p>
@@ -106,8 +106,8 @@
<li>Updates from phpBB 3.0 RC1, 3.1 RC1 and 3.2 RC1 to the latest version</li>
<li>Note: if using the <em>Automatic Update Package</em>, updates are supported from phpBB 3.0.2 onward. To update a pre-3.0.2 installation, first update to 3.0.2 and then update to the current version.</li>
<li>Conversions from phpBB 2.0.x to the latest version</li>
- <li>New installations of phpBB 3.1.x - only the latest released version</li>
<li>New installations of phpBB 3.2.x - only the latest released version</li>
+ <li>New installations of phpBB 3.3.x - only the latest released version</li>
</ul>
</div>
@@ -184,7 +184,7 @@
<p>Comprehensive documentation is now available on the phpBB website:</p>
- <p><a href="https://www.phpbb.com/support/docs/en/3.2/ug/">https://www.phpbb.com/support/docs/en/3.2/ug/</a></p>
+ <p><a href="https://www.phpbb.com/support/docs/en/3.3/ug/">https://www.phpbb.com/support/docs/en/3.3/ug/</a></p>
<p>This covers everything from installation to setting permissions and managing users.</p>
@@ -224,7 +224,7 @@
<div class="content">
- <p>This is a stable release of phpBB. The 3.2.x line is feature frozen, with point releases principally including fixes for bugs and security issues. Feature alterations and minor feature additions may be done if deemed absolutely required. The next major release will be phpBB 3.3 which is currently under development. Please do not post questions asking when 3.3 will be available, no release date has been set.</p>
+ <p>This is a stable release of phpBB. The 3.3.x line is feature frozen, with point releases principally including fixes for bugs and security issues. Feature alterations and minor feature additions may be done if deemed absolutely required. The next major release will be phpBB 3.3 which is currently under development. Please do not post questions asking when 3.3 will be available, no release date has been set.</p>
<p>Those interested in the development of phpBB should keep an eye on the development forums to see how things are progressing:</p>
@@ -265,7 +265,7 @@
<ul>
<li>Your server type/version, e.g. Apache 2.2.3, IIS 7, Sambar, etc.</li>
- <li>PHP version and mode of operation, e.g. PHP 5.4.0 as a module, PHP 5.4.0 running as CGI, etc.</li>
+ <li>PHP version and mode of operation, e.g. PHP 7.1.0 as a module, PHP 7.1.0 running as CGI, etc.</li>
<li>DB type/version, e.g. MySQL 5.0.77, PostgreSQL 9.0.6, MSSQL Server 2000 (via ODBC), etc.</li>
</ul>
@@ -273,7 +273,7 @@
<p>Please be as detailed as you can in your report, and if possible, list the steps required to duplicate the problem. If you have a patch that fixes the issue, please attach it to the ticket or submit a pull request to our repository <a href="https://github.com/phpbb/phpbb">on GitHub</a>.</p>
- <p>If you create a patch, it is very much appreciated (but not required) if you follow the phpBB coding guidelines. Please note that the coding guidelines are somewhat different between different versions of phpBB. For phpBB 3.2.x the coding guidelines may be found here: <a href="http://area51.phpbb.com/docs/32x/coding-guidelines.html">http://area51.phpbb.com/docs/32x/coding-guidelines.html</a></p>
+ <p>If you create a patch, it is very much appreciated (but not required) if you follow the phpBB coding guidelines. Please note that the coding guidelines are somewhat different between different versions of phpBB. For phpBB 3.3.x the coding guidelines may be found here: <a href="http://area51.phpbb.com/docs/33x/coding-guidelines.html">http://area51.phpbb.com/docs/33x/coding-guidelines.html</a></p>
<p>Once a bug has been submitted you will be emailed any follow up comments added to it. <strong>Please</strong> if you are requested to supply additional information, do so! It is frustrating for us to receive bug reports, ask for additional information but get nothing. In these cases we have a policy of closing the bug, which may leave a very real problem in place. Obviously we would rather not have this situation arise.</p>
@@ -323,11 +323,11 @@
<div class="content">
- <p>phpBB 3.2.x takes advantage of new features added in PHP 5.4. We recommend that you upgrade to the latest stable release of PHP to run phpBB. The minimum version required is PHP 5.4.7 and the maximum supported version is the latest stable version of PHP.</p>
+ <p>phpBB 3.3.x takes advantage of new features added in PHP 7.1.0. We recommend that you upgrade to the latest stable release of PHP to run phpBB. The minimum version required is PHP 7.1.0 and the maximum supported version is the latest stable version of PHP.</p>
<p>Please remember that running any application on a development (unstable, e.g. a beta release) version of PHP can lead to strange/unexpected results which may appear to be bugs in the application. Therefore, we recommend you upgrade to the newest stable version of PHP before running phpBB. If you are running a development version of PHP please check any bugs you find on a system running a stable release before submitting.</p>
- <p>This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MariaDB 5.x, PostgreSQL 8.x, Oracle 8 and SQLite 3. Versions of PHP used range from 5.4.7 above 5.6.x to 7.1.x and 7.2.x without problem.</p>
+ <p>This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQLi 4.1.3, 4.x, 5.x, MariaDB 5.x, PostgreSQL 8.x, Oracle 8 and SQLite 3. Versions of PHP used range from 7.1.0 to 7.2.x and 7.3.x without issues.</p>
<a name="phpsec"></a><h3>7.i. Notice on PHP security issues</h3>
diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html
index 569ffe680c..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)
@@ -738,7 +738,7 @@ static private function f()</pre>
<a name="sql"></a><h3>2.iii. SQL/SQL Layout</h3>
<h4>Common SQL Guidelines: </h4>
- <p>All SQL should be cross-DB compatible, if DB specific SQL is used alternatives must be provided which work on all supported DB's (MySQL3/4/5, MSSQL (7.0 and 2000), PostgreSQL (8.3+), SQLite, Oracle8, ODBC (generalised if possible)).</p>
+ <p>All SQL should be cross-DB compatible, if DB specific SQL is used alternatives must be provided which work on all supported DB's (MySQL4/5, MSSQL (7.0 and 2000), PostgreSQL (8.3+), SQLite, Oracle8, ODBC (generalised if possible)).</p>
<p>All SQL commands should utilise the DataBase Abstraction Layer (DBAL)</p>
<h4>SQL code layout:</h4>
@@ -1184,8 +1184,8 @@ append_sid(&quot;{$phpbb_root_path}memberlist.$phpEx&quot;, 'mode=group&amp;amp;
# General Information about this style
name = prosilver_duplicate
copyright = © phpBB Limited, 2007
-style_version = 3.2.0
-phpbb_version = 3.2.0
+style_version = 3.3.0
+phpbb_version = 3.3.0
# Defining a different template bitfield
# template_bitfield = lNg=
@@ -1211,7 +1211,7 @@ parent = prosilver</pre>
&lt;td class=&quot;gensmall&quot;&gt;TEST&lt;/td&gt;
</pre></div>
-<p>Try to match text class types with existing useage, e.g. don't use the nav class where viewtopic uses gensmall for example.</p>
+<p>Try to match text class types with existing usage, e.g. don't use the nav class where viewtopic uses gensmall for example.</p>
<p>Row colours/classes are now defined by the template, use an <code>IF S_ROW_COUNT</code> switch, see viewtopic or viewforum for an example.</p>
@@ -1223,7 +1223,7 @@ parent = prosilver</pre>
<p>The separate catXXXX and thXXX classes are gone. When defining a header cell just use <code>&lt;th&gt;</code> rather than <code>&lt;th class="thHead"&gt;</code> etc. Similarly for cat, don't use <code>&lt;td class="catLeft"&gt;</code> use <code>&lt;td class="cat"&gt;</code> etc.</p>
-<p>Try to retain consistency of basic layout and class useage, i.e. _EXPLAIN text should generally be placed below the title it explains, e.g. <code>{L_POST_USERNAME}&lt;br /&gt;&lt;span class="gensmall"&gt;{L_POST_USERNAME_EXPLAIN}&lt;/span&gt;</code> is the typical way of handling this ... there may be exceptions and this isn't a hard and fast rule.</p>
+<p>Try to retain consistency of basic layout and class usage, i.e. _EXPLAIN text should generally be placed below the title it explains, e.g. <code>{L_POST_USERNAME}&lt;br /&gt;&lt;span class="gensmall"&gt;{L_POST_USERNAME_EXPLAIN}&lt;/span&gt;</code> is the typical way of handling this ... there may be exceptions and this isn't a hard and fast rule.</p>
<p>Try to keep template conditional and other statements tabbed in line with the block to which they refer.</p>
@@ -1767,7 +1767,7 @@ This may span multiple lines.
<p>The <a href="http://en.wikipedia.org/wiki/Universal_Character_Set">Universal Character Set (UCS)</a> described in ISO/IEC 10646 consists of a large amount of characters. Each of them has a unique name and a code point which is an integer number. <a href="http://en.wikipedia.org/wiki/Unicode">Unicode</a> - which is an industry standard - complements the Universal Character Set with further information about the characters' properties and alternative character encodings. More information on Unicode can be found on the <a href="http://www.unicode.org/">Unicode Consortium's website</a>. One of the Unicode encodings is the <a href="http://en.wikipedia.org/wiki/UTF-8">8-bit Unicode Transformation Format (UTF-8)</a>. It encodes characters with up to four bytes aiming for maximum compatibility with the <a href="http://en.wikipedia.org/wiki/ASCII">American Standard Code for Information Interchange</a> which is a 7-bit encoding of a relatively small subset of the UCS.</p>
<h4>phpBB's use of Unicode</h4>
-<p>Unfortunately PHP does not faciliate the use of Unicode prior to version 6. Most functions simply treat strings as sequences of bytes assuming that each character takes up exactly one byte. This behaviour still allows for storing UTF-8 encoded text in PHP strings but many operations on strings have unexpected results. To circumvent this problem we have created some alternative functions to PHP's native string operations which use code points instead of bytes. These functions can be found in <code>/includes/utf/utf_tools.php</code>. They are also covered in the <a href="http://area51.phpbb.com/docs/code/">phpBB3 Sourcecode Documentation</a>. A lot of native PHP functions still work with UTF-8 as long as you stick to certain restrictions. For example <code>explode</code> still works as long as the first and the last character of the delimiter string are ASCII characters.</p>
+<p>Unfortunately PHP does not facilitate the use of Unicode prior to version 6. Most functions simply treat strings as sequences of bytes assuming that each character takes up exactly one byte. This behaviour still allows for storing UTF-8 encoded text in PHP strings but many operations on strings have unexpected results. To circumvent this problem we have created some alternative functions to PHP's native string operations which use code points instead of bytes. These functions can be found in <code>/includes/utf/utf_tools.php</code>. They are also covered in the <a href="http://area51.phpbb.com/docs/code/">phpBB3 Sourcecode Documentation</a>. A lot of native PHP functions still work with UTF-8 as long as you stick to certain restrictions. For example <code>explode</code> still works as long as the first and the last character of the delimiter string are ASCII characters.</p>
<p>phpBB only uses the ASCII and the UTF-8 character encodings. Still all Strings are UTF-8 encoded because ASCII is a subset of UTF-8. The only exceptions to this rule are code sections which deal with external systems which use other encodings and character sets. Such external data should be converted to UTF-8 using the <code>utf8_recode()</code> function supplied with phpBB. It supports a variety of other character sets and encodings, a full list can be found below.</p>
@@ -1848,7 +1848,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2))
<p>The <abbr title="Internet Engineering Task Force">IETF</abbr> recently published <a href="http://tools.ietf.org/html/rfc4646">RFC 4646</a> for tags used to identify languages, which in combination with <a href="http://tools.ietf.org/html/rfc4647">RFC 4647</a> obseletes the older <a href="http://tools.ietf.org/html/rfc3066">RFC 3006</a> and older-still <a href="http://tools.ietf.org/html/rfc1766">RFC 1766</a>. <a href="http://tools.ietf.org/html/rfc4646">RFC 4646</a> uses <a href="http://www.loc.gov/standards/iso639-2/php/English_list.php">ISO 639-1/ISO 639-2</a>, <a href="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166-1 alpha-2</a>, <a href="http://www.unicode.org/iso15924/iso15924-codes.html">ISO 15924</a> and <a href="http://unstats.un.org/unsd/methods/m49/m49.htm">UN M.49</a> to define a language tag. Each complete tag is composed of subtags which are not case sensitive and can also be empty.</p>
- <p>Ordering of the subtags in the case that they are all non-empty is: <code>language</code>-<code>script</code>-<code>region</code>-<code>variant</code>-<code>extension</code>-<code>privateuse</code>. Should any subtag be empty, its corresponding hyphen would also be ommited. Thus, the language tag for English will be <code>en</code> <strong>and not</strong> <code>en-----</code>.</p>
+ <p>Ordering of the subtags in the case that they are all non-empty is: <code>language</code>-<code>script</code>-<code>region</code>-<code>variant</code>-<code>extension</code>-<code>privateuse</code>. Should any subtag be empty, its corresponding hyphen would also be omitted. Thus, the language tag for English will be <code>en</code> <strong>and not</strong> <code>en-----</code>.</p>
<p>Most language tags consist of a two- or three-letter language subtag (from <a href="http://www.loc.gov/standards/iso639-2/php/English_list.php">ISO 639-1/ISO 639-2</a>). Sometimes, this is followed by a two-letter or three-digit region subtag (from <a href="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166-1 alpha-2</a> or <a href="http://unstats.un.org/unsd/methods/m49/m49.htm">UN M.49</a>). Some examples are:</p>
@@ -1902,7 +1902,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2))
<p>The ultimate aim of a language tag is to convey the needed <strong>useful distingushing information</strong>, whilst keeping it as <strong>short as possible</strong>. So for example, use <code>en</code>, <code>fr</code> and <code>ja</code> as opposed to <code>en-GB</code>, <code>fr-FR</code> and <code>ja-JP</code>, since we know English, French and Japanese are the native language of Great Britain, France and Japan respectively.</p>
- <p>Next is the <a href="http://www.unicode.org/iso15924/iso15924-codes.html">ISO 15924</a> language script code and when one should or shouldn't use it. For example, whilst <code>en-Latn</code> is syntaxically correct for describing English written with Latin script, real world English writing is <strong>more-or-less exclusively in the Latin script</strong>. For such languages like English that are written in a single script, the <a href="http://www.iana.org/assignments/language-subtag-registry"><abbr title="Internet Assigned Numbers Authority">IANA</abbr> Language Subtag Registry</a> has a "Suppress-Script" field meaning the script code <strong>should be ommitted</strong> unless a specific language tag requires a specific script code. Some languages are <strong>written in more than one script</strong> and in such cases, the script code <strong>is encouraged</strong> since an end-user may be able to read their language in one script, but not the other. Some examples are:</p>
+ <p>Next is the <a href="http://www.unicode.org/iso15924/iso15924-codes.html">ISO 15924</a> language script code and when one should or shouldn't use it. For example, whilst <code>en-Latn</code> is syntaxically correct for describing English written with Latin script, real world English writing is <strong>more-or-less exclusively in the Latin script</strong>. For such languages like English that are written in a single script, the <a href="http://www.iana.org/assignments/language-subtag-registry"><abbr title="Internet Assigned Numbers Authority">IANA</abbr> Language Subtag Registry</a> has a "Suppress-Script" field meaning the script code <strong>should be omitted</strong> unless a specific language tag requires a specific script code. Some languages are <strong>written in more than one script</strong> and in such cases, the script code <strong>is encouraged</strong> since an end-user may be able to read their language in one script, but not the other. Some examples are:</p>
<table>
<caption>Examples of using a language subtag in combination with a script subtag</caption>
@@ -1967,7 +1967,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2))
</tbody>
</table>
- <p>Usage of the three-digit <a href="http://unstats.un.org/unsd/methods/m49/m49.htm">UN M.49</a> code over the two-letter <a href="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166-1 alpha-2</a> code should hapen if a macro-geographical entity is required and/or the <a href="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166-1 alpha-2</a> is ambiguous.</p>
+ <p>Usage of the three-digit <a href="http://unstats.un.org/unsd/methods/m49/m49.htm">UN M.49</a> code over the two-letter <a href="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166-1 alpha-2</a> code should happen if a macro-geographical entity is required and/or the <a href="http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO 3166-1 alpha-2</a> is ambiguous.</p>
<p>Examples of English using marco-geographical regions:</p>
diff --git a/phpBB/download/file.php b/phpBB/download/file.php
index 9ee489cef4..6d0796d2c4 100644
--- a/phpBB/download/file.php
+++ b/phpBB/download/file.php
@@ -257,11 +257,6 @@ else
$display_cat = ATTACHMENT_CATEGORY_NONE;
}
- if ($display_cat == ATTACHMENT_CATEGORY_FLASH && !$user->optionget('viewflash'))
- {
- $display_cat = ATTACHMENT_CATEGORY_NONE;
- }
-
/**
* Event to modify data before sending file to browser
*
diff --git a/phpBB/feed.php b/phpBB/feed.php
index 1480867d6c..e384489ee9 100644
--- a/phpBB/feed.php
+++ b/phpBB/feed.php
@@ -36,17 +36,17 @@ $mode = $request->variable('mode', '');
if ($forum_id !== 0)
{
- $url = $controller_helper->route('phpbb_feed_forum', array('forum_id' => $forum_id));
+ $url = $controller_helper->route('phpbb_feed_forum', array('forum_id' => $forum_id), false);
}
else if ($topic_id !== 0)
{
- $url = $controller_helper->route('phpbb_feed_topic', array('topic_id' => $topic_id));
+ $url = $controller_helper->route('phpbb_feed_topic', array('topic_id' => $topic_id), false);
}
else
{
try
{
- $url = $controller_helper->route('phpbb_feed_overall', array('mode' => $mode));
+ $url = $controller_helper->route('phpbb_feed_overall', array('mode' => $mode), false);
}
catch (InvalidParameterException $e)
{
diff --git a/phpBB/images/upload_icons/flash.gif b/phpBB/images/upload_icons/flash.gif
deleted file mode 100644
index 00ee0f4f72..0000000000
--- a/phpBB/images/upload_icons/flash.gif
+++ /dev/null
Binary files differ
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index 94e3660de8..feeccbe853 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -610,7 +610,6 @@ class acp_attachments
$cat_lang = array(
ATTACHMENT_CATEGORY_NONE => $user->lang['NO_FILE_CAT'],
ATTACHMENT_CATEGORY_IMAGE => $user->lang['CAT_IMAGES'],
- ATTACHMENT_CATEGORY_FLASH => $user->lang['CAT_FLASH_FILES'],
);
$group_id = $request->variable('g', 0);
@@ -1385,7 +1384,6 @@ class acp_attachments
$types = array(
ATTACHMENT_CATEGORY_NONE => $user->lang['NO_FILE_CAT'],
ATTACHMENT_CATEGORY_IMAGE => $user->lang['CAT_IMAGES'],
- ATTACHMENT_CATEGORY_FLASH => $user->lang['CAT_FLASH_FILES'],
);
if ($group_id)
diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php
index bd8df6a63b..a67f3c54f9 100644
--- a/phpBB/includes/acp/acp_bbcodes.php
+++ b/phpBB/includes/acp/acp_bbcodes.php
@@ -446,144 +446,7 @@ class acp_bbcodes
function build_regexp(&$bbcode_match, &$bbcode_tpl)
{
$bbcode_match = trim($bbcode_match);
- $bbcode_tpl = trim($bbcode_tpl);
-
- // Allow unicode characters for URL|LOCAL_URL|RELATIVE_URL|INTTEXT tokens
- $utf8 = preg_match('/(URL|LOCAL_URL|RELATIVE_URL|INTTEXT)/', $bbcode_match);
-
- $fp_match = preg_quote($bbcode_match, '!');
- $fp_replace = preg_replace('#^\[(.*?)\]#', '[$1:$uid]', $bbcode_match);
- $fp_replace = preg_replace('#\[/(.*?)\]$#', '[/$1:$uid]', $fp_replace);
-
- $sp_match = preg_quote($bbcode_match, '!');
- $sp_match = preg_replace('#^\\\\\[(.*?)\\\\\]#', '\[$1:$uid\]', $sp_match);
- $sp_match = preg_replace('#\\\\\[/(.*?)\\\\\]$#', '\[/$1:$uid\]', $sp_match);
- $sp_replace = $bbcode_tpl;
-
- // @todo Make sure to change this too if something changed in message parsing
- $tokens = array(
- 'URL' => array(
- '!(?:(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('url')) . ')|(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('www_url')) . '))!ie' => "\$this->bbcode_specialchars(('\$1') ? '\$1' : 'http://\$2')"
- ),
- 'LOCAL_URL' => array(
- '!(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')!e' => "\$this->bbcode_specialchars('$1')"
- ),
- 'RELATIVE_URL' => array(
- '!(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')!e' => "\$this->bbcode_specialchars('$1')"
- ),
- 'EMAIL' => array(
- '!(' . get_preg_expression('email') . ')!ie' => "\$this->bbcode_specialchars('$1')"
- ),
- 'TEXT' => array(
- '!(.*?)!es' => "str_replace(array(\"\\r\\n\", '\\\"', '\\'', '(', ')'), array(\"\\n\", '\"', '&#39;', '&#40;', '&#41;'), trim('\$1'))"
- ),
- 'SIMPLETEXT' => array(
- '!([a-zA-Z0-9-+.,_ ]+)!' => "$1"
- ),
- 'INTTEXT' => array(
- '!([\p{L}\p{N}\-+,_. ]+)!u' => "$1"
- ),
- 'IDENTIFIER' => array(
- '!([a-zA-Z0-9-_]+)!' => "$1"
- ),
- 'COLOR' => array(
- '!([a-z]+|#[0-9abcdef]+)!i' => '$1'
- ),
- 'NUMBER' => array(
- '!([0-9]+)!' => '$1'
- )
- );
-
- $sp_tokens = array(
- 'URL' => '(?i)((?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('url')) . ')|(?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('www_url')) . '))(?-i)',
- 'LOCAL_URL' => '(?i)(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')(?-i)',
- 'RELATIVE_URL' => '(?i)(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')(?-i)',
- 'EMAIL' => '(' . get_preg_expression('email') . ')',
- 'TEXT' => '(.*?)',
- 'SIMPLETEXT' => '([a-zA-Z0-9-+.,_ ]+)',
- 'INTTEXT' => '([\p{L}\p{N}\-+,_. ]+)',
- 'IDENTIFIER' => '([a-zA-Z0-9-_]+)',
- 'COLOR' => '([a-zA-Z]+|#[0-9abcdefABCDEF]+)',
- 'NUMBER' => '([0-9]+)',
- );
-
- $pad = 0;
- $modifiers = 'i';
- $modifiers .= ($utf8) ? 'u' : '';
-
- if (preg_match_all('/\{(' . implode('|', array_keys($tokens)) . ')[0-9]*\}/i', $bbcode_match, $m))
- {
- foreach ($m[0] as $n => $token)
- {
- $token_type = $m[1][$n];
-
- reset($tokens[strtoupper($token_type)]);
- list($match, $replace) = each($tokens[strtoupper($token_type)]);
-
- // Pad backreference numbers from tokens
- if (preg_match_all('/(?<!\\\\)\$([0-9]+)/', $replace, $repad))
- {
- $repad = $pad + count(array_unique($repad[0]));
- $replace = preg_replace_callback('/(?<!\\\\)\$([0-9]+)/', function ($match) use ($pad) {
- return '${' . ($match[1] + $pad) . '}';
- }, $replace);
- $pad = $repad;
- }
-
- // Obtain pattern modifiers to use and alter the regex accordingly
- $regex = preg_replace('/!(.*)!([a-z]*)/', '$1', $match);
- $regex_modifiers = preg_replace('/!(.*)!([a-z]*)/', '$2', $match);
-
- for ($i = 0, $size = strlen($regex_modifiers); $i < $size; ++$i)
- {
- if (strpos($modifiers, $regex_modifiers[$i]) === false)
- {
- $modifiers .= $regex_modifiers[$i];
-
- if ($regex_modifiers[$i] == 'e')
- {
- $fp_replace = "'" . str_replace("'", "\\'", $fp_replace) . "'";
- }
- }
-
- if ($regex_modifiers[$i] == 'e')
- {
- $replace = "'.$replace.'";
- }
- }
-
- $fp_match = str_replace(preg_quote($token, '!'), $regex, $fp_match);
- $fp_replace = str_replace($token, $replace, $fp_replace);
-
- $sp_match = str_replace(preg_quote($token, '!'), $sp_tokens[$token_type], $sp_match);
-
- // Prepend the board url to local relative links
- $replace_prepend = ($token_type === 'LOCAL_URL') ? generate_board_url() . '/' : '';
-
- $sp_replace = str_replace($token, $replace_prepend . '${' . ($n + 1) . '}', $sp_replace);
- }
-
- $fp_match = '!' . $fp_match . '!' . $modifiers;
- $sp_match = '!' . $sp_match . '!s' . (($utf8) ? 'u' : '');
-
- if (strpos($fp_match, 'e') !== false)
- {
- $fp_replace = str_replace("'.'", '', $fp_replace);
- $fp_replace = str_replace(".''.", '.', $fp_replace);
- }
- }
- else
- {
- // No replacement is present, no need for a second-pass pattern replacement
- // A simple str_replace will suffice
- $fp_match = '!' . $fp_match . '!' . $modifiers;
- $sp_match = $fp_replace;
- $sp_replace = '';
- }
-
- // Lowercase tags
$bbcode_tag = preg_replace('/.*?\[([a-z0-9_-]+).*/i', '$1', $bbcode_match);
- $bbcode_search = preg_replace('/.*?\[([a-z0-9_-]+).*/i', '$1', $bbcode_match);
if (!preg_match('/^[a-zA-Z0-9_-]+$/', $bbcode_tag))
{
@@ -591,25 +454,13 @@ class acp_bbcodes
trigger_error($user->lang['BBCODE_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
- $fp_match = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
- return strtolower($match[0]);
- }, $fp_match);
- $fp_replace = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
- return strtolower($match[0]);
- }, $fp_replace);
- $sp_match = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
- return strtolower($match[0]);
- }, $sp_match);
- $sp_replace = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
- return strtolower($match[0]);
- }, $sp_replace);
-
return array(
'bbcode_tag' => $bbcode_tag,
- 'first_pass_match' => $fp_match,
- 'first_pass_replace' => $fp_replace,
- 'second_pass_match' => $sp_match,
- 'second_pass_replace' => $sp_replace
+ 'first_pass_match' => '/(?!)/',
+ 'first_pass_replace' => '',
+ // Use a non-matching, valid regexp to effectively disable this BBCode
+ 'second_pass_match' => '/(?!)/',
+ 'second_pass_replace' => ''
);
}
}
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 0730b4e285..2441a37edc 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -85,34 +85,26 @@ class acp_board
$display_vars = array(
'title' => 'ACP_BOARD_FEATURES',
'vars' => array(
- 'legend1' => 'ACP_BOARD_FEATURES',
- 'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
- 'allow_topic_notify' => array('lang' => 'ALLOW_TOPIC_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'allow_forum_notify' => array('lang' => 'ALLOW_FORUM_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'allow_attachments' => array('lang' => 'ALLOW_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'allow_pm_report' => array('lang' => 'ALLOW_PM_REPORT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
- 'allow_bbcode' => array('lang' => 'ALLOW_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'allow_smilies' => array('lang' => 'ALLOW_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'allow_sig' => array('lang' => 'ALLOW_SIG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'legend1' => 'ACP_BOARD_FEATURES',
+ 'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'allow_topic_notify' => array('lang' => 'ALLOW_TOPIC_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'allow_forum_notify' => array('lang' => 'ALLOW_FORUM_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'allow_attachments' => array('lang' => 'ALLOW_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'allow_pm_report' => array('lang' => 'ALLOW_PM_REPORT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'allow_bbcode' => array('lang' => 'ALLOW_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'allow_smilies' => array('lang' => 'ALLOW_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
+ 'allow_sig' => array('lang' => 'ALLOW_SIG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'allow_board_notifications' => array('lang' => 'ALLOW_BOARD_NOTIFICATIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
- '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),
- 'allow_quick_reply' => array('lang' => 'ALLOW_QUICK_REPLY', 'validate' => 'bool', 'type' => 'custom', 'method' => 'quick_reply', 'explain' => true),
-
- 'legend2' => 'ACP_LOAD_SETTINGS',
- 'load_birthdays' => array('lang' => 'YES_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
- 'load_moderators' => array('lang' => 'YES_MODERATORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'load_jumpbox' => array('lang' => 'YES_JUMPBOX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'load_cpf_pm' => array('lang' => 'LOAD_CPF_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'load_cpf_viewprofile' => array('lang' => 'LOAD_CPF_VIEWPROFILE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'load_cpf_viewtopic' => array('lang' => 'LOAD_CPF_VIEWTOPIC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
-
- 'legend3' => 'ACP_SUBMIT_CHANGES',
+ 'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ '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',
)
);
break;
@@ -263,7 +255,6 @@ class acp_board
'vars' => array(
'legend1' => 'GENERAL_SETTINGS',
'max_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:8:180', 'type' => false, 'method' => false, 'explain' => false,),
- 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,),
'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'select', 'method' => 'select_acc_activation', 'explain' => true),
'new_member_post_limit' => array('lang' => 'NEW_MEMBER_POST_LIMIT', 'validate' => 'int:0:255', 'type' => 'number:0:255', 'explain' => true, 'append' => ' ' . $user->lang['POSTS']),
@@ -426,7 +417,6 @@ class acp_board
'remote_upload_verify' => array('lang' => 'UPLOAD_CERT_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'check_dnsbl' => array('lang' => 'CHECK_DNSBL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'email_check_mx' => array('lang' => 'EMAIL_CHECK_MX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
- 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,),
'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true),
'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true),
'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
@@ -904,13 +894,13 @@ class acp_board
}
/**
- * Maximum/Minimum password length
+ * Minimum password length
*/
function password_length($value, $key)
{
global $user;
- return '<input id="' . $key . '" type="number" min="1" max="999" name="config[min_pass_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . '&nbsp;&nbsp;<input type="number" min="8" max="255" name="config[max_pass_chars]" value="' . $this->new_config['max_pass_chars'] . '" /> ' . $user->lang['MAX_CHARS'];
+ return '<input id="' . $key . '" type="number" min="1" max="999" name="config[min_pass_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'];
}
/**
diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php
index 677fce7217..c1c748832b 100644
--- a/phpBB/includes/acp/acp_database.php
+++ b/phpBB/includes/acp/acp_database.php
@@ -248,8 +248,6 @@ class acp_database
switch ($db->get_sql_layer())
{
- case 'mysql':
- case 'mysql4':
case 'mysqli':
case 'sqlite3':
while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php
index a1cb2108e7..6ac70ce3a8 100644
--- a/phpBB/includes/acp/acp_extensions.php
+++ b/phpBB/includes/acp/acp_extensions.php
@@ -38,7 +38,7 @@ class acp_extensions
private $phpbb_container;
private $php_ini;
- function main()
+ function main($id, $mode)
{
// Start the page
global $config, $user, $template, $request, $phpbb_extension_manager, $phpbb_root_path, $phpbb_log, $phpbb_dispatcher, $phpbb_container;
@@ -172,23 +172,27 @@ class acp_extensions
}
$extension = $this->ext_manager->get_extension($ext_name);
- if (!$extension->is_enableable())
- {
- trigger_error($this->user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
- }
+
+ $this->check_is_enableable($extension);
if ($this->ext_manager->is_enabled($ext_name))
{
redirect($this->u_action);
}
- $this->tpl_name = 'acp_ext_enable';
-
- $this->template->assign_vars(array(
- 'PRE' => true,
- 'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_ENABLE_CONFIRM', $md_manager->get_metadata('display-name')),
- 'U_ENABLE' => $this->u_action . '&amp;action=enable&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('enable.' . $ext_name),
- ));
+ if (confirm_box(true))
+ {
+ redirect($this->u_action . '&amp;action=enable&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('enable.' . $ext_name));
+ }
+ else
+ {
+ confirm_box(false, $this->user->lang('EXTENSION_ENABLE_CONFIRM', $md_manager->get_metadata('display-name')), build_hidden_fields(array(
+ 'i' => $id,
+ 'mode' => $mode,
+ 'action' => 'enable_pre',
+ 'ext_name' => $ext_name,
+ )));
+ }
break;
case 'enable':
@@ -203,10 +207,8 @@ class acp_extensions
}
$extension = $this->ext_manager->get_extension($ext_name);
- if (!$extension->is_enableable())
- {
- trigger_error($this->user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING);
- }
+
+ $this->check_is_enableable($extension);
try
{
@@ -215,9 +217,8 @@ class acp_extensions
// Are we approaching the time limit? If so we want to pause the update and continue after refreshing
if ((time() - $start_time) >= $safe_time_limit)
{
- $this->template->assign_var('S_NEXT_STEP', true);
-
meta_refresh(0, $this->u_action . '&amp;action=enable&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('enable.' . $ext_name));
+ trigger_error('EXTENSION_ENABLE_IN_PROGRESS', E_USER_NOTICE);
}
}
@@ -233,14 +234,22 @@ class acp_extensions
}
catch (\phpbb\db\migration\exception $e)
{
- $this->template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($this->user));
+ trigger_error($this->user->lang('MIGRATION_EXCEPTION_ERROR', $e->getLocalisedMessage($this->user)), E_USER_WARNING);
}
- $this->tpl_name = 'acp_ext_enable';
-
- $this->template->assign_vars(array(
- 'U_RETURN' => $this->u_action . '&amp;action=list',
- ));
+ if ($this->request->is_ajax())
+ {
+ $actions = $this->output_actions('enabled', [
+ 'DISABLE' => $this->u_action . '&amp;action=disable_pre&amp;ext_name=' . urlencode($ext_name),
+ ]);
+
+ $json_response = new \phpbb\json_response;
+ $json_response->send(array(
+ 'EXT_ENABLE_SUCCESS' => true,
+ 'ACTIONS' => $actions,
+ ));
+ }
+ trigger_error($this->user->lang('EXTENSION_ENABLE_SUCCESS') . adm_back_link($this->u_action), E_USER_NOTICE);
break;
case 'disable_pre':
@@ -249,13 +258,19 @@ class acp_extensions
redirect($this->u_action);
}
- $this->tpl_name = 'acp_ext_disable';
-
- $this->template->assign_vars(array(
- 'PRE' => true,
- 'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_DISABLE_CONFIRM', $md_manager->get_metadata('display-name')),
- 'U_DISABLE' => $this->u_action . '&amp;action=disable&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('disable.' . $ext_name),
- ));
+ if (confirm_box(true))
+ {
+ redirect($this->u_action . '&amp;action=disable&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('disable.' . $ext_name));
+ }
+ else
+ {
+ confirm_box(false, $this->user->lang('EXTENSION_DISABLE_CONFIRM', $md_manager->get_metadata('display-name')), build_hidden_fields(array(
+ 'i' => $id,
+ 'mode' => $mode,
+ 'action' => 'disable_pre',
+ 'ext_name' => $ext_name,
+ )));
+ }
break;
case 'disable':
@@ -272,15 +287,25 @@ class acp_extensions
$this->template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=disable&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('disable.' . $ext_name));
+ trigger_error('EXTENSION_DISABLE_IN_PROGRESS', E_USER_NOTICE);
}
}
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_DISABLE', time(), array($ext_name));
- $this->tpl_name = 'acp_ext_disable';
-
- $this->template->assign_vars(array(
- 'U_RETURN' => $this->u_action . '&amp;action=list',
- ));
+ if ($this->request->is_ajax())
+ {
+ $actions = $this->output_actions('disabled', [
+ 'ENABLE' => $this->u_action . '&amp;action=enable_pre&amp;ext_name=' . urlencode($ext_name),
+ 'DELETE_DATA' => $this->u_action . '&amp;action=delete_data_pre&amp;ext_name=' . urlencode($ext_name),
+ ]);
+
+ $json_response = new \phpbb\json_response;
+ $json_response->send(array(
+ 'EXT_DISABLE_SUCCESS' => true,
+ 'ACTIONS' => $actions,
+ ));
+ }
+ trigger_error($this->user->lang('EXTENSION_DISABLE_SUCCESS') . adm_back_link($this->u_action), E_USER_NOTICE);
break;
case 'delete_data_pre':
@@ -288,13 +313,20 @@ class acp_extensions
{
redirect($this->u_action);
}
- $this->tpl_name = 'acp_ext_delete_data';
- $this->template->assign_vars(array(
- 'PRE' => true,
- 'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_DELETE_DATA_CONFIRM', $md_manager->get_metadata('display-name')),
- 'U_PURGE' => $this->u_action . '&amp;action=delete_data&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('delete_data.' . $ext_name),
- ));
+ if (confirm_box(true))
+ {
+ redirect($this->u_action . '&amp;action=delete_data&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('delete_data.' . $ext_name));
+ }
+ else
+ {
+ confirm_box(false, $this->user->lang('EXTENSION_DELETE_DATA_CONFIRM', $md_manager->get_metadata('display-name')), build_hidden_fields(array(
+ 'i' => $id,
+ 'mode' => $mode,
+ 'action' => 'delete_data_pre',
+ 'ext_name' => $ext_name,
+ )));
+ }
break;
case 'delete_data':
@@ -313,20 +345,29 @@ class acp_extensions
$this->template->assign_var('S_NEXT_STEP', true);
meta_refresh(0, $this->u_action . '&amp;action=delete_data&amp;ext_name=' . urlencode($ext_name) . '&amp;hash=' . generate_link_hash('delete_data.' . $ext_name));
+ trigger_error('EXTENSION_DELETE_DATA_IN_PROGRESS', E_USER_NOTICE);
}
}
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_PURGE', time(), array($ext_name));
}
catch (\phpbb\db\migration\exception $e)
{
- $this->template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($this->user));
+ trigger_error($this->user->lang('MIGRATION_EXCEPTION_ERROR', $e->getLocalisedMessage($this->user)), E_USER_WARNING);
}
- $this->tpl_name = 'acp_ext_delete_data';
-
- $this->template->assign_vars(array(
- 'U_RETURN' => $this->u_action . '&amp;action=list',
- ));
+ if ($this->request->is_ajax())
+ {
+ $actions = $this->output_actions('disabled', [
+ 'ENABLE' => $this->u_action . '&amp;action=enable_pre&amp;ext_name=' . urlencode($ext_name),
+ ]);
+
+ $json_response = new \phpbb\json_response;
+ $json_response->send(array(
+ 'EXT_DELETE_DATA_SUCCESS' => true,
+ 'ACTIONS' => $actions,
+ ));
+ }
+ trigger_error($this->user->lang('EXTENSION_DELETE_DATA_SUCCESS') . adm_back_link($this->u_action), E_USER_NOTICE);
break;
case 'details':
@@ -605,17 +646,37 @@ class acp_extensions
*
* @param string $block
* @param array $actions
+ * @return array List of actions to be performed on the extension
*/
private function output_actions($block, $actions)
{
- foreach ($actions as $lang => $url)
+ $vars_ary = array();
+ foreach ($actions as $lang => $options)
{
- $this->template->assign_block_vars($block . '.actions', array(
+ $url = $options;
+ if (is_array($options))
+ {
+ $url = $options['url'];
+ }
+
+ $vars = array(
'L_ACTION' => $this->user->lang('EXTENSION_' . $lang),
'L_ACTION_EXPLAIN' => (isset($this->user->lang['EXTENSION_' . $lang . '_EXPLAIN'])) ? $this->user->lang('EXTENSION_' . $lang . '_EXPLAIN') : '',
'U_ACTION' => $url,
- ));
+ 'ACTION_AJAX' => 'ext_' . strtolower($lang),
+ );
+
+ if (isset($options['color']))
+ {
+ $vars['COLOR'] = $options['color'];
+ }
+
+ $this->template->assign_block_vars($block . '.actions', $vars);
+
+ $vars_ary[] = $vars;
}
+
+ return $vars_ary;
}
/**
@@ -662,4 +723,28 @@ class acp_extensions
));
}
}
+
+ /**
+ * Checks whether the extension can be enabled. Triggers error if not.
+ * Error message can be set by the extension.
+ *
+ * @param \phpbb\extension\extension_interface $extension Extension to check
+ */
+ protected function check_is_enableable(\phpbb\extension\extension_interface $extension)
+ {
+ $message = $extension->is_enableable();
+ if ($message !== true)
+ {
+ if (empty($message))
+ {
+ $message = $this->user->lang('EXTENSION_NOT_ENABLEABLE');
+ }
+ else if (is_array($message))
+ {
+ $message = implode('<br>', $message);
+ }
+
+ trigger_error($message . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+ }
}
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index 22c775b7c3..ba3901f67a 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -131,11 +131,12 @@ class acp_forums
'forum_rules_link' => $request->variable('forum_rules_link', ''),
'forum_image' => $request->variable('forum_image', ''),
'forum_style' => $request->variable('forum_style', 0),
- 'display_subforum_list' => $request->variable('display_subforum_list', false),
- 'display_on_index' => $request->variable('display_on_index', false),
+ '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),
- 'enable_icons' => $request->variable('enable_icons', false),
+ 'enable_icons' => $request->variable('enable_icons', true),
'enable_prune' => $request->variable('enable_prune', false),
'enable_post_review' => $request->variable('enable_post_review', true),
'enable_quick_reply' => $request->variable('enable_quick_reply', false),
@@ -454,10 +455,11 @@ class acp_forums
'forum_image' => '',
'forum_style' => 0,
'display_subforum_list' => true,
- 'display_on_index' => false,
+ 'display_subforum_limit' => false,
+ 'display_on_index' => true,
'forum_topics_per_page' => 0,
'enable_indexing' => true,
- 'enable_icons' => false,
+ 'enable_icons' => true,
'enable_prune' => false,
'prune_days' => 7,
'prune_viewed' => 7,
@@ -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,
@@ -1901,7 +1904,6 @@ class acp_forums
switch ($db->get_sql_layer())
{
- case 'mysql4':
case 'mysqli':
// Delete everything else and thank MySQL for offering multi-table deletion
diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php
index 8f169d15a7..27fac54777 100644
--- a/phpBB/includes/acp/acp_main.php
+++ b/phpBB/includes/acp/acp_main.php
@@ -657,7 +657,7 @@ class acp_main
}
// Warn if install is still present
- if (file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install'))
+ if (!defined('IN_INSTALL') && !$phpbb_container->getParameter('allow_install_dir') && file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install'))
{
$template->assign_var('S_REMOVE_INSTALL', true);
}
diff --git a/phpBB/includes/acp/acp_reasons.php b/phpBB/includes/acp/acp_reasons.php
index dfb2ccbfd3..f3f82bdfca 100644
--- a/phpBB/includes/acp/acp_reasons.php
+++ b/phpBB/includes/acp/acp_reasons.php
@@ -222,8 +222,6 @@ class acp_reasons
{
// The ugly one!
case 'mysqli':
- case 'mysql4':
- case 'mysql':
// Change the reports using this reason to 'other'
$sql = 'UPDATE ' . REPORTS_TABLE . '
SET reason_id = ' . $other_reason_id . ", report_text = CONCAT('" . $db->sql_escape($reason_row['reason_description']) . "\n\n', report_text)
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index fd4b5e8c24..6993c86279 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -844,9 +844,9 @@ class acp_users
// Validation data - we do not check the password complexity setting here
$check_ary = array(
'new_password' => array(
- array('string', true, $config['min_pass_chars'], $config['max_pass_chars']),
+ array('string', true, $config['min_pass_chars'], 0),
array('password')),
- 'password_confirm' => array('string', true, $config['min_pass_chars'], $config['max_pass_chars']),
+ 'password_confirm' => array('string', true, $config['min_pass_chars'], 0),
);
// Check username if altered
@@ -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,
@@ -1130,7 +1127,7 @@ class acp_users
$template->assign_vars(array(
'L_NAME_CHARS_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])),
- 'L_CHANGE_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars']), $user->lang('CHARACTERS', (int) $config['max_pass_chars'])),
+ 'L_CHANGE_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars'])),
'L_POSTS_IN_QUEUE' => $user->lang('NUM_POSTS_IN_QUEUE', $user_row['posts_in_queue']),
'S_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false,
diff --git a/phpBB/includes/compatibility_globals.php b/phpBB/includes/compatibility_globals.php
index ad394e3782..15880d4bc8 100644
--- a/phpBB/includes/compatibility_globals.php
+++ b/phpBB/includes/compatibility_globals.php
@@ -18,6 +18,14 @@ if (!defined('IN_PHPBB'))
exit;
}
+//
+// Deprecated globals
+//
+define('ATTACHMENT_CATEGORY_WM', 2); // Windows Media Files - Streaming - @deprecated 3.2
+define('ATTACHMENT_CATEGORY_RM', 3); // Real Media Files - Streaming - @deprecated 3.2
+define('ATTACHMENT_CATEGORY_QUICKTIME', 6); // Quicktime/Mov files - @deprecated 3.2
+define('ATTACHMENT_CATEGORY_FLASH', 5); // Flash/SWF files - @deprecated 3.3
+
/**
* Sets compatibility globals in the global scope
*
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index a2e7d92f7d..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.2.9-dev');
+@define('PHPBB_VERSION', '3.3.0-RC1-dev');
// QA-related
// define('PHPBB_QA', 1);
@@ -171,11 +171,7 @@ define('CONFIRM_REPORT', 4);
// Categories - Attachments
define('ATTACHMENT_CATEGORY_NONE', 0);
define('ATTACHMENT_CATEGORY_IMAGE', 1); // Inline Images
-define('ATTACHMENT_CATEGORY_WM', 2); // Windows Media Files - Streaming - @deprecated 3.2
-define('ATTACHMENT_CATEGORY_RM', 3); // Real Media Files - Streaming - @deprecated 3.2
define('ATTACHMENT_CATEGORY_THUMB', 4); // Not used within the database, only while displaying posts
-define('ATTACHMENT_CATEGORY_FLASH', 5); // Flash/SWF files
-define('ATTACHMENT_CATEGORY_QUICKTIME', 6); // Quicktime/Mov files - @deprecated 3.2
// BBCode UID length
define('BBCODE_UID_LEN', 8);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index c9f589c174..994323531a 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -52,18 +52,6 @@ function phpbb_load_extensions_autoloaders($phpbb_root_path)
}
/**
-* Casts a variable to the given type.
-*
-* @deprecated
-*/
-function set_var(&$result, $var, $type, $multibyte = false)
-{
- // no need for dependency injection here, if you have the object, call the method yourself!
- $type_cast_helper = new \phpbb\request\type_cast_helper();
- $type_cast_helper->set_var($result, $var, $type, $multibyte);
-}
-
-/**
* Generates an alphanumeric random string of given length
*
* @param int $num_chars Length of random string, defaults to 8.
@@ -276,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.
*
@@ -2288,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())
@@ -2528,11 +2505,14 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
$s_hidden_fields = build_hidden_fields($s_hidden_fields);
+ /** @var \phpbb\controller\helper $controller_helper */
+ $controller_helper = $phpbb_container->get('controller.helper');
+
$login_box_template_data = array(
'LOGIN_ERROR' => $err,
'LOGIN_EXPLAIN' => $l_explain,
- 'U_SEND_PASSWORD' => ($config['email_enable']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=sendpassword') : '',
+ 'U_SEND_PASSWORD' => ($config['email_enable']) ? $controller_helper->route('phpbb_ucp_forgot_password_controller') : '',
'U_RESEND_ACTIVATION' => ($config['require_activation'] == USER_ACTIVATION_SELF && $config['email_enable']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=resend_act') : '',
'U_TERMS_USE' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=terms'),
'U_PRIVACY' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=privacy'),
@@ -2860,10 +2840,13 @@ function get_preg_expression($mode)
// Whoa these look impressive!
// The code to generate the following two regular expressions which match valid IPv4/IPv6 addresses
// can be found in the develop directory
+
+ // @deprecated
case 'ipv4':
return '#^(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$#';
break;
+ // @deprecated
case 'ipv6':
return '#^(?:(?:(?:[\dA-F]{1,4}:){6}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:::(?:[\dA-F]{1,4}:){0,5}(?:[\dA-F]{1,4}(?::[\dA-F]{1,4})?|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:):(?:[\dA-F]{1,4}:){4}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,2}:(?:[\dA-F]{1,4}:){3}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,3}:(?:[\dA-F]{1,4}:){2}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,4}:(?:[\dA-F]{1,4}:)(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,5}:(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,6}:[\dA-F]{1,4})|(?:(?:[\dA-F]{1,4}:){1,7}:)|(?:::))$#i';
break;
@@ -2989,331 +2972,26 @@ function short_ipv6($ip, $length)
* @return mixed false if specified address is not valid,
* string otherwise
*/
-function phpbb_ip_normalise($address)
+function phpbb_ip_normalise(string $address)
{
- $address = trim($address);
+ $ip_normalised = false;
- if (empty($address) || !is_string($address))
+ if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
{
- return false;
+ $ip_normalised = $address;
}
-
- if (preg_match(get_preg_expression('ipv4'), $address))
+ else if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
{
- return $address;
- }
-
- return phpbb_inet_ntop(phpbb_inet_pton($address));
-}
+ $ip_normalised = inet_ntop(inet_pton($address));
-/**
-* Wrapper for inet_ntop()
-*
-* Converts a packed internet address to a human readable representation
-* inet_ntop() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
-*
-* @param string $in_addr A 32bit IPv4, or 128bit IPv6 address.
-*
-* @return mixed false on failure,
-* string otherwise
-*/
-function phpbb_inet_ntop($in_addr)
-{
- $in_addr = bin2hex($in_addr);
-
- switch (strlen($in_addr))
- {
- case 8:
- return implode('.', array_map('hexdec', str_split($in_addr, 2)));
-
- case 32:
- if (substr($in_addr, 0, 24) === '00000000000000000000ffff')
- {
- return phpbb_inet_ntop(pack('H*', substr($in_addr, 24)));
- }
-
- $parts = str_split($in_addr, 4);
- $parts = preg_replace('/^0+(?!$)/', '', $parts);
- $ret = implode(':', $parts);
-
- $matches = array();
- preg_match_all('/(?<=:|^)(?::?0){2,}/', $ret, $matches, PREG_OFFSET_CAPTURE);
- $matches = $matches[0];
-
- if (empty($matches))
- {
- return $ret;
- }
-
- $longest_match = '';
- $longest_match_offset = 0;
- foreach ($matches as $match)
- {
- if (strlen($match[0]) > strlen($longest_match))
- {
- $longest_match = $match[0];
- $longest_match_offset = $match[1];
- }
- }
-
- $ret = substr_replace($ret, '', $longest_match_offset, strlen($longest_match));
-
- if ($longest_match_offset == strlen($ret))
- {
- $ret .= ':';
- }
-
- if ($longest_match_offset == 0)
- {
- $ret = ':' . $ret;
- }
-
- return $ret;
-
- default:
- return false;
- }
-}
-
-/**
-* Wrapper for inet_pton()
-*
-* Converts a human readable IP address to its packed in_addr representation
-* inet_pton() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
-*
-* @param string $address A human readable IPv4 or IPv6 address.
-*
-* @return mixed false if address is invalid,
-* in_addr representation of the given address otherwise (string)
-*/
-function phpbb_inet_pton($address)
-{
- $ret = '';
- if (preg_match(get_preg_expression('ipv4'), $address))
- {
- foreach (explode('.', $address) as $part)
- {
- $ret .= ($part <= 0xF ? '0' : '') . dechex($part);
- }
-
- return pack('H*', $ret);
- }
-
- if (preg_match(get_preg_expression('ipv6'), $address))
- {
- $parts = explode(':', $address);
- $missing_parts = 8 - count($parts) + 1;
-
- if (substr($address, 0, 2) === '::')
- {
- ++$missing_parts;
- }
-
- if (substr($address, -2) === '::')
- {
- ++$missing_parts;
- }
-
- $embedded_ipv4 = false;
- $last_part = end($parts);
-
- if (preg_match(get_preg_expression('ipv4'), $last_part))
+ // If is ipv4
+ if (stripos($ip_normalised, '::ffff:') === 0)
{
- $parts[count($parts) - 1] = '';
- $last_part = phpbb_inet_pton($last_part);
- $embedded_ipv4 = true;
- --$missing_parts;
+ $ip_normalised = substr($ip_normalised, 7);
}
-
- foreach ($parts as $i => $part)
- {
- if (strlen($part))
- {
- $ret .= str_pad($part, 4, '0', STR_PAD_LEFT);
- }
- else if ($i && $i < count($parts) - 1)
- {
- $ret .= str_repeat('0000', $missing_parts);
- }
- }
-
- $ret = pack('H*', $ret);
-
- if ($embedded_ipv4)
- {
- $ret .= $last_part;
- }
-
- return $ret;
}
- return false;
-}
-
-/**
-* Wrapper for php's checkdnsrr function.
-*
-* @param string $host Fully-Qualified Domain Name
-* @param string $type Resource record type to lookup
-* Supported types are: MX (default), A, AAAA, NS, TXT, CNAME
-* Other types may work or may not work
-*
-* @return mixed true if entry found,
-* false if entry not found,
-* null if this function is not supported by this environment
-*
-* Since null can also be returned, you probably want to compare the result
-* with === true or === false,
-*/
-function phpbb_checkdnsrr($host, $type = 'MX')
-{
- // The dot indicates to search the DNS root (helps those having DNS prefixes on the same domain)
- if (substr($host, -1) == '.')
- {
- $host_fqdn = $host;
- $host = substr($host, 0, -1);
- }
- else
- {
- $host_fqdn = $host . '.';
- }
- // $host has format some.host.example.com
- // $host_fqdn has format some.host.example.com.
-
- // If we're looking for an A record we can use gethostbyname()
- if ($type == 'A' && function_exists('gethostbyname'))
- {
- return (@gethostbyname($host_fqdn) == $host_fqdn) ? false : true;
- }
-
- if (function_exists('checkdnsrr'))
- {
- return checkdnsrr($host_fqdn, $type);
- }
-
- if (function_exists('dns_get_record'))
- {
- // dns_get_record() expects an integer as second parameter
- // We have to convert the string $type to the corresponding integer constant.
- $type_constant = 'DNS_' . $type;
- $type_param = (defined($type_constant)) ? constant($type_constant) : DNS_ANY;
-
- // dns_get_record() might throw E_WARNING and return false for records that do not exist
- $resultset = @dns_get_record($host_fqdn, $type_param);
-
- if (empty($resultset) || !is_array($resultset))
- {
- return false;
- }
- else if ($type_param == DNS_ANY)
- {
- // $resultset is a non-empty array
- return true;
- }
-
- foreach ($resultset as $result)
- {
- if (
- isset($result['host']) && $result['host'] == $host &&
- isset($result['type']) && $result['type'] == $type
- )
- {
- return true;
- }
- }
-
- return false;
- }
-
- // If we're on Windows we can still try to call nslookup via exec() as a last resort
- if (DIRECTORY_SEPARATOR == '\\' && function_exists('exec'))
- {
- @exec('nslookup -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host_fqdn), $output);
-
- // If output is empty, the nslookup failed
- if (empty($output))
- {
- return NULL;
- }
-
- foreach ($output as $line)
- {
- $line = trim($line);
-
- if (empty($line))
- {
- continue;
- }
-
- // Squash tabs and multiple whitespaces to a single whitespace.
- $line = preg_replace('/\s+/', ' ', $line);
-
- switch ($type)
- {
- case 'MX':
- if (stripos($line, "$host MX") === 0)
- {
- return true;
- }
- break;
-
- case 'NS':
- if (stripos($line, "$host nameserver") === 0)
- {
- return true;
- }
- break;
-
- case 'TXT':
- if (stripos($line, "$host text") === 0)
- {
- return true;
- }
- break;
-
- case 'CNAME':
- if (stripos($line, "$host canonical name") === 0)
- {
- return true;
- }
- break;
-
- default:
- case 'AAAA':
- // AAAA records returned by nslookup on Windows XP/2003 have this format.
- // Later Windows versions use the A record format below for AAAA records.
- if (stripos($line, "$host AAAA IPv6 address") === 0)
- {
- return true;
- }
- // No break
-
- case 'A':
- if (!empty($host_matches))
- {
- // Second line
- if (stripos($line, "Address: ") === 0)
- {
- return true;
- }
- else
- {
- $host_matches = false;
- }
- }
- else if (stripos($line, "Name: $host") === 0)
- {
- // First line
- $host_matches = true;
- }
- break;
- }
- }
-
- return false;
- }
-
- return NULL;
+ return $ip_normalised;
}
// Handler, header and footer
@@ -3325,6 +3003,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
{
global $cache, $db, $auth, $template, $config, $user, $request;
global $phpbb_root_path, $msg_title, $msg_long_text, $phpbb_log;
+ global $phpbb_container;
// Do not display notices if we suppress them via @
if (error_reporting() == 0 && $errno != E_USER_ERROR && $errno != E_USER_WARNING && $errno != E_USER_NOTICE)
@@ -3345,7 +3024,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
// Check the error reporting level and return if the error level does not match
// If DEBUG is defined the default level is E_ALL
- if (($errno & ((defined('DEBUG')) ? E_ALL : error_reporting())) == 0)
+ if (($errno & ($phpbb_container->getParameter('debug.show_errors') ? E_ALL : error_reporting())) == 0)
{
return;
}
@@ -3403,7 +3082,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
$log_text .= '<br /><br />BACKTRACE<br />' . $backtrace;
}
- if (defined('IN_INSTALL') || defined('DEBUG') || isset($auth) && $auth->acl_get('a_'))
+ if (defined('IN_INSTALL') || ($phpbb_container != null && $phpbb_container->getParameter('debug.show_errors')) || isset($auth) && $auth->acl_get('a_'))
{
$msg_text = $log_text;
@@ -4291,7 +3970,8 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
}
else
{
- $u_login_logout = append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login');
+ $redirect = $request->variable('redirect', rawurlencode($user->page['page']));
+ $u_login_logout = append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login&amp;redirect=' . $redirect);
$l_login_logout = $user->lang['LOGIN'];
}
@@ -4566,7 +4246,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/stylesheet.css?assets_version=' . $config['assets_version'],
'T_STYLESHEET_LANG_LINK'=> "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'],
'T_FONT_AWESOME_LINK' => !empty($config['allow_cdn']) && !empty($config['load_font_awesome_url']) ? $config['load_font_awesome_url'] : "{$web_path}assets/css/font-awesome.min.css?assets_version=" . $config['assets_version'],
- 'T_JQUERY_LINK' => !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.min.js?assets_version=" . $config['assets_version'],
+ 'T_JQUERY_LINK' => !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery-3.4.1.min.js?assets_version=" . $config['assets_version'],
'S_ALLOW_CDN' => !empty($config['allow_cdn']),
'S_COOKIE_NOTICE' => !empty($config['cookie_notice']),
@@ -4638,7 +4318,9 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
*/
function phpbb_check_and_display_sql_report(\phpbb\request\request_interface $request, \phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db)
{
- if ($request->variable('explain', false) && $auth->acl_get('a_') && defined('DEBUG'))
+ global $phpbb_container;
+
+ if ($phpbb_container->getParameter('debug.sql_explain') && $request->variable('explain', false) && $auth->acl_get('a_'))
{
$db->sql_report('display');
}
@@ -4656,19 +4338,22 @@ function phpbb_check_and_display_sql_report(\phpbb\request\request_interface $re
*/
function phpbb_generate_debug_output(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\auth\auth $auth, \phpbb\user $user, \phpbb\event\dispatcher_interface $phpbb_dispatcher)
{
+ global $phpbb_container;
+
$debug_info = array();
// Output page creation time
- if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ if ($phpbb_container->getParameter('debug.load_time'))
{
if (isset($GLOBALS['starttime']))
{
$totaltime = microtime(true) - $GLOBALS['starttime'];
$debug_info[] = sprintf('<span title="SQL time: %.3fs / PHP time: %.3fs">Time: %.3fs</span>', $db->get_sql_time(), ($totaltime - $db->get_sql_time()), $totaltime);
}
+ }
- $debug_info[] = sprintf('<span title="Cached: %d">Queries: %d</span>', $db->sql_num_queries(true), $db->sql_num_queries());
-
+ if ($phpbb_container->getParameter('debug.memory'))
+ {
$memory_usage = memory_get_peak_usage();
if ($memory_usage)
{
@@ -4676,16 +4361,18 @@ function phpbb_generate_debug_output(\phpbb\db\driver\driver_interface $db, \php
$debug_info[] = 'Peak Memory Usage: ' . $memory_usage;
}
- }
- if (defined('DEBUG'))
- {
$debug_info[] = 'GZIP: ' . (($config['gzip_compress'] && @extension_loaded('zlib')) ? 'On' : 'Off');
if ($user->load)
{
$debug_info[] = 'Load: ' . $user->load;
}
+ }
+
+ if ($phpbb_container->getParameter('debug.sql_explain'))
+ {
+ $debug_info[] = sprintf('<span title="Cached: %d">Queries: %d</span>', $db->sql_num_queries(true), $db->sql_num_queries());
if ($auth->acl_get('a_'))
{
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index a2014a7d5b..4926351461 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -177,7 +177,7 @@ function adm_page_footer($copyright_html = true)
'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '',
'S_COPYRIGHT_HTML' => $copyright_html,
'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>&reg; Forum Software &copy; phpBB Limited'),
- 'T_JQUERY_LINK' => !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$phpbb_root_path}assets/javascript/jquery.min.js",
+ 'T_JQUERY_LINK' => !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$phpbb_root_path}assets/javascript/jquery-3.4.1.min.js",
'S_ALLOW_CDN' => !empty($config['allow_cdn']),
'VERSION' => $config['version'])
);
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index cc82fdbda3..4629706048 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -1191,28 +1191,6 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
}
/**
-* Delete Attachments
-*
-* @deprecated 3.2.0-a1 (To be removed: 3.4.0)
-*
-* @param string $mode can be: post|message|topic|attach|user
-* @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids
-* @param bool $resync set this to false if you are deleting posts or topics
-*/
-function delete_attachments($mode, $ids, $resync = true)
-{
- global $phpbb_container;
-
- /** @var \phpbb\attachment\manager $attachment_manager */
- $attachment_manager = $phpbb_container->get('attachment.manager');
- $num_deleted = $attachment_manager->delete($mode, $ids, $resync);
-
- unset($attachment_manager);
-
- return $num_deleted;
-}
-
-/**
* Deletes shadow topics pointing to a specified forum.
*
* @param int $forum_id The forum id
@@ -1324,23 +1302,6 @@ function update_posted_info(&$topic_ids)
}
/**
-* Delete attached file
-*
-* @deprecated 3.2.0-a1 (To be removed: 3.4.0)
-*/
-function phpbb_unlink($filename, $mode = 'file', $entry_removed = false)
-{
- global $phpbb_container;
-
- /** @var \phpbb\attachment\manager $attachment_manager */
- $attachment_manager = $phpbb_container->get('attachment.manager');
- $unlink = $attachment_manager->unlink($filename, $mode, $entry_removed);
- unset($attachment_manager);
-
- return $unlink;
-}
-
-/**
* All-encompasing sync function
*
* Exaples:
@@ -1423,7 +1384,6 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false,
$db->sql_transaction('begin');
switch ($db->get_sql_layer())
{
- case 'mysql4':
case 'mysqli':
$sql = 'DELETE FROM ' . TOPICS_TABLE . '
USING ' . TOPICS_TABLE . ' t1, ' . TOPICS_TABLE . " t2
@@ -2722,8 +2682,7 @@ function phpbb_update_foes($db, $auth, $group_id = false, $user_id = false)
switch ($db->get_sql_layer())
{
case 'mysqli':
- case 'mysql4':
- $sql = 'DELETE ' . (($db->get_sql_layer() === 'mysqli' || version_compare($db->sql_server_info(true), '4.1', '>=')) ? 'z.*' : ZEBRA_TABLE) . '
+ $sql = 'DELETE z.*
FROM ' . ZEBRA_TABLE . ' z, ' . USER_GROUP_TABLE . ' ug
WHERE z.zebra_id = ug.user_id
AND z.foe = 1
@@ -2879,8 +2838,6 @@ function get_database_size()
// This code is heavily influenced by a similar routine in phpMyAdmin 2.2.0
switch ($db->get_sql_layer())
{
- case 'mysql':
- case 'mysql4':
case 'mysqli':
$sql = 'SELECT VERSION() AS mysql_version';
$result = $db->sql_query($sql);
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
index e95fa40a58..92e24c055c 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -22,7 +22,7 @@ if (!defined('IN_PHPBB'))
/**
* Get user avatar
*
-* @deprecated 3.1.0-a1 (To be removed: 3.3.0)
+* @deprecated 3.1.0-a1 (To be removed: 4.0.0)
*
* @param string $avatar Users assigned avatar name
* @param int $avatar_type Type of avatar
@@ -50,7 +50,7 @@ function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $
/**
* Hash the password
*
-* @deprecated 3.1.0-a2 (To be removed: 3.3.0)
+* @deprecated 3.1.0-a2 (To be removed: 4.0.0)
*
* @param string $password Password to be hashed
*
@@ -68,7 +68,7 @@ function phpbb_hash($password)
/**
* Check for correct password
*
-* @deprecated 3.1.0-a2 (To be removed: 3.3.0)
+* @deprecated 3.1.0-a2 (To be removed: 4.0.0)
*
* @param string $password The password in plain text
* @param string $hash The stored password hash
@@ -92,7 +92,7 @@ function phpbb_check_hash($password, $hash)
* @param string $path Path to clean
* @return string Cleaned path
*
-* @deprecated 3.1.0 (To be removed: 3.3.0)
+* @deprecated 3.1.0 (To be removed: 4.0.0)
*/
function phpbb_clean_path($path)
{
@@ -136,7 +136,7 @@ function phpbb_clean_path($path)
*
* @return string Returns the options for timezone selector only
*
-* @deprecated 3.1.0 (To be removed: 3.3.0)
+* @deprecated 3.1.0 (To be removed: 4.0.0)
*/
function tz_select($default = '', $truncate = false)
{
@@ -150,7 +150,7 @@ function tz_select($default = '', $truncate = false)
* via admin_permissions. Changes of usernames and group names
* must be carried through for the moderators table.
*
-* @deprecated 3.1.0 (To be removed: 3.3.0)
+* @deprecated 3.1.0 (To be removed: 4.0.0)
* @return null
*/
function cache_moderators()
@@ -162,7 +162,7 @@ function cache_moderators()
/**
* Removes moderators and administrators from foe lists.
*
-* @deprecated 3.1.0 (To be removed: 3.3.0)
+* @deprecated 3.1.0 (To be removed: 4.0.0)
* @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore
* @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore
* @return null
@@ -182,7 +182,7 @@ function update_foes($group_id = false, $user_id = false)
* @param string &$rank_img the rank image as full img tag is stored here after execution
* @param string &$rank_img_src the rank image source is stored here after execution
*
-* @deprecated 3.1.0-RC5 (To be removed: 3.3.0)
+* @deprecated 3.1.0-RC5 (To be removed: 4.0.0)
*
* Note: since we do not want to break backwards-compatibility, this function will only properly assign ranks to guests if you call it for them with user_posts == false
*/
@@ -232,7 +232,7 @@ function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port
*
* @return int|bool Returns the log_id, if the entry was added to the database, false otherwise.
*
- * @deprecated 3.1.0 (To be removed: 3.3.0)
+ * @deprecated 3.1.0 (To be removed: 4.0.0)
*/
function add_log()
{
@@ -280,7 +280,7 @@ function add_log()
*
* @return null
*
- * @deprecated 3.1.0 (To be removed: 3.3.0)
+ * @deprecated 3.1.0 (To be removed: 4.0.0)
*/
function set_config($config_name, $config_value, $is_dynamic = false, \phpbb\config\config $set_config = null)
{
@@ -310,7 +310,7 @@ function set_config($config_name, $config_value, $is_dynamic = false, \phpbb\con
*
* @return null
*
- * @deprecated 3.1.0 (To be removed: 3.3.0)
+ * @deprecated 3.1.0 (To be removed: 4.0.0)
*/
function set_config_count($config_name, $increment, $is_dynamic = false, \phpbb\config\config $set_config = null)
{
@@ -331,7 +331,7 @@ function set_config_count($config_name, $increment, $is_dynamic = false, \phpbb\
* See {@link \phpbb\request\request_interface::variable \phpbb\request\request_interface::variable} for
* documentation of this function's use.
*
- * @deprecated 3.1.0 (To be removed: 3.3.0)
+ * @deprecated 3.1.0 (To be removed: 4.0.0)
* @param mixed $var_name The form variable's name from which data shall be retrieved.
* If the value is an array this may be an array of indizes which will give
* direct access to a value at any depth. E.g. if the value of "var" is array(1 => "a")
@@ -389,7 +389,7 @@ function request_var($var_name, $default, $multibyte = false, $cookie = false, $
/**
* Get tables of a database
*
- * @deprecated 3.1.0 (To be removed: 3.3.0)
+ * @deprecated 3.1.0 (To be removed: 4.0.0)
*/
function get_tables($db)
{
@@ -492,7 +492,7 @@ function phpbb_realpath($path)
* @param $number int|float The number we want to get the plural case for. Float numbers are floored.
* @return int The plural-case we need to use for the number plural-rule combination
*
- * @deprecated 3.2.0-dev (To be removed: 3.3.0)
+ * @deprecated 3.2.0-dev (To be removed: 4.0.0)
*/
function phpbb_get_plural_form($rule, $number)
{
@@ -511,3 +511,165 @@ function phpbb_pcre_utf8_support()
{
return true;
}
+
+/**
+ * Casts a variable to the given type.
+ *
+ * @deprecated 3.1 (To be removed 4.0.0)
+ */
+function set_var(&$result, $var, $type, $multibyte = false)
+{
+ // no need for dependency injection here, if you have the object, call the method yourself!
+ $type_cast_helper = new \phpbb\request\type_cast_helper();
+ $type_cast_helper->set_var($result, $var, $type, $multibyte);
+}
+
+/**
+ * Delete Attachments
+ *
+ * @deprecated 3.2.0-a1 (To be removed: 4.0.0)
+ *
+ * @param string $mode can be: post|message|topic|attach|user
+ * @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids
+ * @param bool $resync set this to false if you are deleting posts or topics
+ */
+function delete_attachments($mode, $ids, $resync = true)
+{
+ global $phpbb_container;
+
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $num_deleted = $attachment_manager->delete($mode, $ids, $resync);
+
+ unset($attachment_manager);
+
+ return $num_deleted;
+}
+
+/**
+ * Delete attached file
+ *
+ * @deprecated 3.2.0-a1 (To be removed: 4.0.0)
+ */
+function phpbb_unlink($filename, $mode = 'file', $entry_removed = false)
+{
+ global $phpbb_container;
+
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $unlink = $attachment_manager->unlink($filename, $mode, $entry_removed);
+ unset($attachment_manager);
+
+ return $unlink;
+}
+
+/**
+ * Display reasons
+ *
+ * @deprecated 3.2.0-dev (To be removed: 4.0.0)
+ */
+function display_reasons($reason_id = 0)
+{
+ global $phpbb_container;
+
+ $phpbb_container->get('phpbb.report.report_reason_list_provider')->display_reasons($reason_id);
+}
+
+/**
+ * Upload Attachment - filedata is generated here
+ * Uses upload class
+ *
+ * @deprecated 3.2.0-a1 (To be removed: 4.0.0)
+ *
+ * @param string $form_name The form name of the file upload input
+ * @param int $forum_id The id of the forum
+ * @param bool $local Whether the file is local or not
+ * @param string $local_storage The path to the local file
+ * @param bool $is_message Whether it is a PM or not
+ * @param array $local_filedata A filespec object created for the local file
+ *
+ * @return array File data array
+ */
+function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false)
+{
+ global $phpbb_container;
+
+ /** @var \phpbb\attachment\manager $attachment_manager */
+ $attachment_manager = $phpbb_container->get('attachment.manager');
+ $file = $attachment_manager->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata);
+ unset($attachment_manager);
+
+ return $file;
+}
+
+/**
+* Wrapper for php's checkdnsrr function.
+*
+* @param string $host Fully-Qualified Domain Name
+* @param string $type Resource record type to lookup
+* Supported types are: MX (default), A, AAAA, NS, TXT, CNAME
+* Other types may work or may not work
+*
+* @return mixed true if entry found,
+* false if entry not found,
+* null if this function is not supported by this environment
+*
+* Since null can also be returned, you probably want to compare the result
+* with === true or === false,
+*
+* @deprecated 3.3.0-b2 (To be removed: 4.0.0)
+*/
+function phpbb_checkdnsrr($host, $type = 'MX')
+{
+ return checkdnsrr($host, $type);
+}
+
+/*
+ * Wrapper for inet_ntop()
+ *
+ * Converts a packed internet address to a human readable representation
+ * inet_ntop() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
+ *
+ * @param string $in_addr A 32bit IPv4, or 128bit IPv6 address.
+ *
+ * @return mixed false on failure,
+ * string otherwise
+ *
+ * @deprecated 3.3.0-b2 (To be removed: 4.0.0)
+ */
+function phpbb_inet_ntop($in_addr)
+{
+ return inet_ntop($in_addr);
+}
+
+/**
+ * Wrapper for inet_pton()
+ *
+ * Converts a human readable IP address to its packed in_addr representation
+ * inet_pton() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
+ *
+ * @param string $address A human readable IPv4 or IPv6 address.
+ *
+ * @return mixed false if address is invalid,
+ * in_addr representation of the given address otherwise (string)
+ *
+ * @deprecated 3.3.0-b2 (To be removed: 4.0.0)
+ */
+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_compress.php b/phpBB/includes/functions_compress.php
index e86da77b38..56d64d37fb 100644
--- a/phpBB/includes/functions_compress.php
+++ b/phpBB/includes/functions_compress.php
@@ -305,8 +305,8 @@ class compress_zip extends compress
}
}
}
- // This is a directory, we are not writting files
- continue;
+ // This is a directory, we are not writing files
+ continue 2;
}
else
{
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index 2542be5e02..fd014c741e 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -1245,11 +1245,6 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a
$display_cat = ATTACHMENT_CATEGORY_NONE;
}
- if ($display_cat == ATTACHMENT_CATEGORY_FLASH && !$user->optionget('viewflash'))
- {
- $display_cat = ATTACHMENT_CATEGORY_NONE;
- }
-
$download_link = append_sid("{$phpbb_root_path}download/file.$phpEx", 'id=' . $attachment['attach_id']);
$l_downloaded_viewed = 'VIEWED_COUNTS';
@@ -1281,21 +1276,6 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a
$update_count_ary[] = $attachment['attach_id'];
break;
- // Macromedia Flash Files
- case ATTACHMENT_CATEGORY_FLASH:
- list($width, $height) = @getimagesize($filename);
-
- $block_array += array(
- 'S_FLASH_FILE' => true,
- 'WIDTH' => $width,
- 'HEIGHT' => $height,
- 'U_VIEW_LINK' => $download_link . '&amp;view=1',
- );
-
- // Viewed/Heared File ... update the download count
- $update_count_ary[] = $attachment['attach_id'];
- break;
-
default:
$l_downloaded_viewed = 'DOWNLOAD_COUNTS';
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index 2cfbe9541d..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)
@@ -1647,11 +1637,6 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO)
case 'insert':
switch ($db->get_sql_layer())
{
- case 'mysql':
- case 'mysql4':
- $sql = 'VALUES ' . implode(', ', preg_replace('#^(.*?)$#', '(\1)', $sql_subary));
- break;
-
case 'sqlite3':
case 'mssqlnative':
$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index e4adce14fc..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();
@@ -786,25 +788,25 @@ function generate_forum_nav(&$forum_data_ary)
}
$navlinks_parents[] = array(
- 'S_IS_CAT' => ($parent_type == FORUM_CAT) ? true : false,
- 'S_IS_LINK' => ($parent_type == FORUM_LINK) ? true : false,
- 'S_IS_POST' => ($parent_type == FORUM_POST) ? true : false,
- 'FORUM_NAME' => $parent_name,
- 'FORUM_ID' => $parent_forum_id,
- 'MICRODATA' => $microdata_attr . '="' . $parent_forum_id . '"',
- 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $parent_forum_id),
+ 'S_IS_CAT' => ($parent_type == FORUM_CAT) ? true : false,
+ 'S_IS_LINK' => ($parent_type == FORUM_LINK) ? true : false,
+ 'S_IS_POST' => ($parent_type == FORUM_POST) ? true : false,
+ 'BREADCRUMB_NAME' => $parent_name,
+ 'FORUM_ID' => $parent_forum_id,
+ 'MICRODATA' => $microdata_attr . '="' . $parent_forum_id . '"',
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $parent_forum_id),
);
}
}
$navlinks = array(
- 'S_IS_CAT' => ($forum_data_ary['forum_type'] == FORUM_CAT) ? true : false,
- 'S_IS_LINK' => ($forum_data_ary['forum_type'] == FORUM_LINK) ? true : false,
- 'S_IS_POST' => ($forum_data_ary['forum_type'] == FORUM_POST) ? true : false,
- 'FORUM_NAME' => $forum_data_ary['forum_name'],
- 'FORUM_ID' => $forum_data_ary['forum_id'],
- 'MICRODATA' => $microdata_attr . '="' . $forum_data_ary['forum_id'] . '"',
- 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_data_ary['forum_id']),
+ 'S_IS_CAT' => ($forum_data_ary['forum_type'] == FORUM_CAT) ? true : false,
+ 'S_IS_LINK' => ($forum_data_ary['forum_type'] == FORUM_LINK) ? true : false,
+ 'S_IS_POST' => ($forum_data_ary['forum_type'] == FORUM_POST) ? true : false,
+ 'BREADCRUMB_NAME' => $forum_data_ary['forum_name'],
+ 'FORUM_ID' => $forum_data_ary['forum_id'],
+ 'MICRODATA' => $microdata_attr . '="' . $forum_data_ary['forum_id'] . '"',
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_data_ary['forum_id']),
);
$forum_template_data = array(
@@ -1151,18 +1153,6 @@ function display_custom_bbcodes()
}
/**
-* Display reasons
-*
-* @deprecated 3.2.0-dev
-*/
-function display_reasons($reason_id = 0)
-{
- global $phpbb_container;
-
- $phpbb_container->get('phpbb.report.report_reason_list_provider')->display_reasons($reason_id);
-}
-
-/**
* Display user activity (action forum/topic)
*/
function display_user_activity(&$userdata_ary)
diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php
index 1f409be58c..d2d3924dd8 100644
--- a/phpBB/includes/functions_download.php
+++ b/phpBB/includes/functions_download.php
@@ -206,28 +206,20 @@ function send_file_to_browser($attachment, $upload_dir, $category)
header('X-Content-Type-Options: nosniff');
}
- if ($category == ATTACHMENT_CATEGORY_FLASH && $request->variable('view', 0) === 1)
+ if (empty($user->browser) || ((strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($user->browser, 7)))
{
- // We use content-disposition: inline for flash files and view=1 to let it correctly play with flash player 10 - any other disposition will fail to play inline
- header('Content-Disposition: inline');
+ header('Content-Disposition: attachment; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
+ if (empty($user->browser) || (strpos(strtolower($user->browser), 'msie 6.0') !== false))
+ {
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
+ }
}
else
{
- if (empty($user->browser) || ((strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($user->browser, 7)))
- {
- header('Content-Disposition: attachment; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
- if (empty($user->browser) || (strpos(strtolower($user->browser), 'msie 6.0') !== false))
- {
- header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
- }
- }
- else
+ header('Content-Disposition: ' . ((strpos($attachment['mimetype'], 'image') === 0) ? 'inline' : 'attachment') . '; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
+ if (phpbb_is_greater_ie_version($user->browser, 7) && (strpos($attachment['mimetype'], 'image') !== 0))
{
- header('Content-Disposition: ' . ((strpos($attachment['mimetype'], 'image') === 0) ? 'inline' : 'attachment') . '; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
- if (phpbb_is_greater_ie_version($user->browser, 7) && (strpos($attachment['mimetype'], 'image') !== 0))
- {
- header('X-Download-Options: noopen');
- }
+ header('X-Download-Options: noopen');
}
}
diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php
index 88dafc4300..510d98ec11 100644
--- a/phpBB/includes/functions_module.php
+++ b/phpBB/includes/functions_module.php
@@ -123,7 +123,7 @@ class p_master
// We "could" build a true tree with this function - maybe mod authors want to use this...
// Functions for traversing and manipulating the tree are not available though
- // We might re-structure the module system to use true trees in 3.2.x...
+ // We might re-structure the module system to use true trees in 4.0
// $tree = $this->build_tree($this->module_cache['modules'], $this->module_cache['parents']);
// Clean up module cache array to only let survive modules the user can access
@@ -933,6 +933,14 @@ class p_master
'U_TITLE' => $u_title
);
+ if (isset($this->module_cache['parents'][$item_ary['id']]) || $item_ary['id'] == $this->p_id)
+ {
+ $template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $item_ary['lang'],
+ 'U_BREADCRUMB' => $u_title,
+ ));
+ }
+
$template->assign_block_vars($use_tabular_offset, array_merge($tpl_ary, array_change_key_case($item_ary, CASE_UPPER)));
}
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 1956f65666..45eda4ba17 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -433,34 +433,6 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL)
//
// Attachment related functions
//
-
-/**
-* Upload Attachment - filedata is generated here
-* Uses upload class
-*
-* @deprecated 3.2.0-a1 (To be removed: 3.4.0)
-*
-* @param string $form_name The form name of the file upload input
-* @param int $forum_id The id of the forum
-* @param bool $local Whether the file is local or not
-* @param string $local_storage The path to the local file
-* @param bool $is_message Whether it is a PM or not
-* @param array $local_filedata A filespec object created for the local file
-*
-* @return array File data array
-*/
-function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false)
-{
- global $phpbb_container;
-
- /** @var \phpbb\attachment\manager $attachment_manager */
- $attachment_manager = $phpbb_container->get('attachment.manager');
- $file = $attachment_manager->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata);
- unset($attachment_manager);
-
- return $file;
-}
-
/**
* Calculate the needed size for Thumbnail
*/
@@ -677,12 +649,6 @@ function create_thumbnail($source, $destination, $mimetype)
imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
}
- // If we are in safe mode create the destination file prior to using the gd functions to circumvent a PHP bug
- if (@ini_get('safe_mode') || @strtolower(ini_get('safe_mode')) == 'on')
- {
- @touch($destination);
- }
-
switch ($type['format'])
{
case IMG_GIF:
diff --git a/phpBB/includes/functions_transfer.php b/phpBB/includes/functions_transfer.php
index 7427b89917..f0070b4b1e 100644
--- a/phpBB/includes/functions_transfer.php
+++ b/phpBB/includes/functions_transfer.php
@@ -810,7 +810,7 @@ class ftp_fsock extends transfer
$server_ip = substr($socket_name, 0, strrpos($socket_name, ':'));
}
- if (!isset($server_ip) || preg_match(get_preg_expression('ipv4'), $server_ip))
+ if (isset($server_ip) && filter_var($server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) // ipv4
{
// Passive mode
$this->_send_command('PASV', '', false);
@@ -831,7 +831,7 @@ class ftp_fsock extends transfer
$server_ip = $temp[0] . '.' . $temp[1] . '.' . $temp[2] . '.' . $temp[3];
$server_port = $temp[4] * 256 + $temp[5];
}
- else
+ else // ipv6
{
// Extended Passive Mode - RFC2428
$this->_send_command('EPSV', '', false);
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index e0b6a9d0c6..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'],
);
@@ -1455,12 +1454,7 @@ function user_unban($mode, $ban)
*/
function user_ipwhois($ip)
{
- if (empty($ip))
- {
- return '';
- }
-
- if (!preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip))
+ if (!filter_var($ip, FILTER_VALIDATE_IP))
{
return '';
}
@@ -1910,7 +1904,7 @@ function phpbb_validate_email($email, $config = null)
{
list(, $domain) = explode('@', $email);
- if (phpbb_checkdnsrr($domain, 'A') === false && phpbb_checkdnsrr($domain, 'MX') === false)
+ if (checkdnsrr($domain, 'A') === false && checkdnsrr($domain, 'MX') === false)
{
return 'DOMAIN_NO_MX_RECORD';
}
@@ -1953,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/questionnaire/questionnaire.php b/phpBB/includes/questionnaire/questionnaire.php
index 2f80582918..95036a95bc 100644
--- a/phpBB/includes/questionnaire/questionnaire.php
+++ b/phpBB/includes/questionnaire/questionnaire.php
@@ -110,7 +110,6 @@ class phpbb_questionnaire_php_data_provider
'version' => PHP_VERSION,
'sapi' => PHP_SAPI,
'int_size' => defined('PHP_INT_SIZE') ? PHP_INT_SIZE : '',
- 'safe_mode' => (int) @ini_get('safe_mode'),
'open_basedir' => (int) @ini_get('open_basedir'),
'memory_limit' => @ini_get('memory_limit'),
'allow_url_fopen' => (int) @ini_get('allow_url_fopen'),
@@ -121,8 +120,6 @@ class phpbb_questionnaire_php_data_provider
'disable_functions' => @ini_get('disable_functions'),
'disable_classes' => @ini_get('disable_classes'),
'enable_dl' => (int) @ini_get('enable_dl'),
- 'magic_quotes_gpc' => (int) @ini_get('magic_quotes_gpc'),
- 'register_globals' => (int) @ini_get('register_globals'),
'filter.default' => @ini_get('filter.default'),
'zend.ze1_compatibility_mode' => (int) @ini_get('zend.ze1_compatibility_mode'),
'unicode.semantics' => (int) @ini_get('unicode.semantics'),
@@ -405,7 +402,6 @@ class phpbb_questionnaire_phpbb_data_provider
'max_login_attempts' => true,
'max_name_chars' => true,
'max_num_search_keywords' => true,
- 'max_pass_chars' => true,
'max_poll_options' => true,
'max_post_chars' => true,
'max_post_font_size' => true,
diff --git a/phpBB/includes/startup.php b/phpBB/includes/startup.php
index 66f85657a5..d42ae58c42 100644
--- a/phpBB/includes/startup.php
+++ b/phpBB/includes/startup.php
@@ -23,11 +23,11 @@ $level = E_ALL & ~E_NOTICE & ~E_DEPRECATED;
error_reporting($level);
/**
-* Minimum Requirement: PHP 5.4.0
+* Minimum Requirement: PHP 7.1.0
*/
-if (version_compare(PHP_VERSION, '5.4') < 0)
+if (version_compare(PHP_VERSION, '7.1') < 0)
{
- die('You are running an unsupported PHP version. Please upgrade to PHP 5.4.0 or higher before trying to install or update to phpBB 3.2');
+ die('You are running an unsupported PHP version. Please upgrade to PHP 7.1.0 or higher before trying to install or update to phpBB 3.3');
}
// Register globals and magic quotes have been dropped in PHP 5.4 so no need for extra checks
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index 36ab3d0463..dca7e7eeb7 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -70,9 +70,9 @@ class ucp_profile
// Do not check cur_password, it is the old one.
$check_ary = array(
'new_password' => array(
- array('string', true, $config['min_pass_chars'], $config['max_pass_chars']),
+ array('string', true, $config['min_pass_chars'], 0),
array('password')),
- 'password_confirm' => array('string', true, $config['min_pass_chars'], $config['max_pass_chars']),
+ 'password_confirm' => array('string', true, $config['min_pass_chars'], 0),
'email' => array(
array('string', false, 6, 60),
array('user_email')),
@@ -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'],
);
@@ -267,7 +266,7 @@ class ucp_profile
'CUR_PASSWORD' => '',
'L_USERNAME_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])),
- 'L_CHANGE_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars']), $user->lang('CHARACTERS', (int) $config['max_pass_chars'])),
+ 'L_CHANGE_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars'])),
'S_FORCE_PASSWORD' => ($auth->acl_get('u_chgpasswd') && $config['chg_passforce'] && $user->data['user_passchg'] < time() - ($config['chg_passforce'] * 86400)) ? true : false,
'S_CHANGE_USERNAME' => ($config['allow_namechange'] && $auth->acl_get('u_chgname')) ? true : false,
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 03ac63b12b..00fa8034f9 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -276,9 +276,9 @@ class ucp_register
array('string', false, $config['min_name_chars'], $config['max_name_chars']),
array('username', '')),
'new_password' => array(
- array('string', false, $config['min_pass_chars'], $config['max_pass_chars']),
+ array('string', false, $config['min_pass_chars'], 0),
array('password')),
- 'password_confirm' => array('string', false, $config['min_pass_chars'], $config['max_pass_chars']),
+ 'password_confirm' => array('string', false, $config['min_pass_chars'], 0),
'email' => array(
array('string', false, 6, 60),
array('user_email')),
@@ -452,6 +452,9 @@ class ucp_register
{
$message = $user->lang['ACCOUNT_ADDED'];
$email_template = 'user_welcome';
+
+ // Autologin after registration
+ $user->session_create($user_id, 0, false, 1);
}
if ($config['email_enable'])
@@ -600,6 +603,31 @@ class ucp_register
break;
}
+ /* @var $provider_collection \phpbb\auth\provider_collection */
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+ $auth_provider = $provider_collection->get_provider();
+
+ $auth_provider_data = $auth_provider->get_login_data();
+ if ($auth_provider_data)
+ {
+ if (isset($auth_provider_data['VARS']))
+ {
+ $template->assign_vars($auth_provider_data['VARS']);
+ }
+
+ if (isset($auth_provider_data['BLOCK_VAR_NAME']))
+ {
+ foreach ($auth_provider_data['BLOCK_VARS'] as $block_vars)
+ {
+ $template->assign_block_vars($auth_provider_data['BLOCK_VAR_NAME'], $block_vars);
+ }
+ }
+
+ $template->assign_vars(array(
+ 'PROVIDER_TEMPLATE_FILE' => $auth_provider_data['TEMPLATE_FILE'],
+ ));
+ }
+
// Assign template vars for timezone select
phpbb_timezone_select($template, $user, $data['tz'], true);
@@ -611,7 +639,7 @@ class ucp_register
'L_REG_COND' => $l_reg_cond,
'L_USERNAME_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])),
- 'L_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars']), $user->lang('CHARACTERS', (int) $config['max_pass_chars'])),
+ 'L_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars'])),
'S_LANG_OPTIONS' => language_select($data['lang']),
'S_TZ_PRESELECT' => !$submit,
diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php
deleted file mode 100644
index e50428bfea..0000000000
--- a/phpBB/includes/ucp/ucp_remind.php
+++ /dev/null
@@ -1,174 +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.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* ucp_remind
-* Sending password reminders
-*/
-class ucp_remind
-{
- var $u_action;
-
- function main($id, $mode)
- {
- global $config, $phpbb_root_path, $phpEx, $request;
- global $db, $user, $template, $phpbb_container, $phpbb_dispatcher;
-
- if (!$config['allow_password_reset'])
- {
- trigger_error($user->lang('UCP_PASSWORD_RESET_DISABLED', '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>'));
- }
-
- $username = $request->variable('username', '', true);
- $email = strtolower($request->variable('email', ''));
- $submit = (isset($_POST['submit'])) ? true : false;
-
- add_form_key('ucp_remind');
-
- if ($submit)
- {
- if (!check_form_key('ucp_remind'))
- {
- trigger_error('FORM_INVALID');
- }
-
- if (empty($email))
- {
- trigger_error('NO_EMAIL_USER');
- }
-
- $sql_array = array(
- 'SELECT' => 'user_id, username, user_permissions, user_email, user_jabber, user_notify_type, user_type, user_lang, user_inactive_reason',
- 'FROM' => array(USERS_TABLE => 'u'),
- 'WHERE' => "user_email_hash = '" . $db->sql_escape(phpbb_email_hash($email)) . "'" .
- (!empty($username) ? " AND username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'" : ''),
- );
-
- /**
- * Change SQL query for fetching user data
- *
- * @event core.ucp_remind_modify_select_sql
- * @var string email User's email from the form
- * @var string username User's username from the form
- * @var array sql_array Fully assembled SQL query with keys SELECT, FROM, WHERE
- * @since 3.1.11-RC1
- */
- $vars = array(
- 'email',
- 'username',
- 'sql_array',
- );
- extract($phpbb_dispatcher->trigger_event('core.ucp_remind_modify_select_sql', compact($vars)));
-
- $sql = $db->sql_build_query('SELECT', $sql_array);
- $result = $db->sql_query_limit($sql, 2); // don't waste resources on more rows than we need
- $rowset = $db->sql_fetchrowset($result);
-
- if (count($rowset) > 1)
- {
- $db->sql_freeresult($result);
-
- $template->assign_vars(array(
- 'USERNAME_REQUIRED' => true,
- 'EMAIL' => $email,
- ));
- }
- else
- {
- $message = $user->lang['PASSWORD_UPDATED_IF_EXISTED'] . '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>');
-
- if (empty($rowset))
- {
- trigger_error($message);
- }
-
- $user_row = $rowset[0];
- $db->sql_freeresult($result);
-
- if (!$user_row)
- {
- trigger_error($message);
- }
-
- if ($user_row['user_type'] == USER_IGNORE || $user_row['user_type'] == USER_INACTIVE)
- {
- trigger_error($message);
- }
-
- // Check users permissions
- $auth2 = new \phpbb\auth\auth();
- $auth2->acl($user_row);
-
- if (!$auth2->acl_get('u_chgpasswd'))
- {
- trigger_error($message);
- }
-
- $server_url = generate_board_url();
-
- // Make password at least 8 characters long, make it longer if admin wants to.
- // gen_rand_string() however has a limit of 12 or 13.
- $user_password = gen_rand_string_friendly(max(8, mt_rand((int) $config['min_pass_chars'], (int) $config['max_pass_chars'])));
-
- // For the activation key a random length between 6 and 10 will do.
- $user_actkey = gen_rand_string(mt_rand(6, 10));
-
- // Instantiate passwords manager
- /* @var $manager \phpbb\passwords\manager */
- $passwords_manager = $phpbb_container->get('passwords.manager');
-
- $sql = 'UPDATE ' . USERS_TABLE . "
- SET user_newpasswd = '" . $db->sql_escape($passwords_manager->hash($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "'
- WHERE user_id = " . $user_row['user_id'];
- $db->sql_query($sql);
-
- include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
-
- $messenger = new messenger(false);
-
- $messenger->template('user_activate_passwd', $user_row['user_lang']);
-
- $messenger->set_addresses($user_row);
-
- $messenger->anti_abuse_headers($config, $user);
-
- $messenger->assign_vars(array(
- 'USERNAME' => htmlspecialchars_decode($user_row['username']),
- 'PASSWORD' => htmlspecialchars_decode($user_password),
- 'U_ACTIVATE' => "$server_url/ucp.$phpEx?mode=activate&u={$user_row['user_id']}&k=$user_actkey")
- );
-
- $messenger->send($user_row['user_notify_type']);
-
- trigger_error($message);
- }
- }
-
- $template->assign_vars(array(
- 'USERNAME' => $username,
- 'EMAIL' => $email,
- 'S_PROFILE_ACTION' => append_sid($phpbb_root_path . 'ucp.' . $phpEx, 'mode=sendpassword'))
- );
-
- $this->tpl_name = 'ucp_remind';
- $this->page_title = 'UCP_REMIND';
- }
-}
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/index.php b/phpBB/index.php
index 13b914abd3..5622bc37c7 100644
--- a/phpBB/index.php
+++ b/phpBB/index.php
@@ -221,11 +221,6 @@ $template->assign_vars(array(
'LEGEND' => $legend,
'BIRTHDAY_LIST' => (empty($birthday_list)) ? '' : implode($user->lang['COMMA_SEPARATOR'], $birthday_list),
- 'FORUM_IMG' => $user->img('forum_read', 'NO_UNREAD_POSTS'),
- 'FORUM_UNREAD_IMG' => $user->img('forum_unread', 'UNREAD_POSTS'),
- 'FORUM_LOCKED_IMG' => $user->img('forum_read_locked', 'NO_UNREAD_POSTS_LOCKED'),
- 'FORUM_UNREAD_LOCKED_IMG' => $user->img('forum_unread_locked', 'UNREAD_POSTS_LOCKED'),
-
'S_LOGIN_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'),
'U_SEND_PASSWORD' => ($config['email_enable']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=sendpassword') : '',
'S_DISPLAY_BIRTHDAY_LIST' => $show_birthdays,
diff --git a/phpBB/install/app.php b/phpBB/install/app.php
index 710f49570b..9d04ec2156 100644
--- a/phpBB/install/app.php
+++ b/phpBB/install/app.php
@@ -20,9 +20,9 @@ define('PHPBB_ENVIRONMENT', 'production');
$phpbb_root_path = '../';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
-if (version_compare(PHP_VERSION, '5.4.7', '<') || version_compare(PHP_VERSION, '7.3-dev', '>='))
+if (version_compare(PHP_VERSION, '7.1') < 0)
{
- die('You are running an unsupported PHP version. Please upgrade to PHP equal to or greater than 5.4.7 but less than 7.3-dev in order to install or update to phpBB 3.2');
+ die('You are running an unsupported PHP version. Please upgrade to PHP 7.1.0 or higher before trying to install or update to phpBB 3.3');
}
$startup_new_path = $phpbb_root_path . 'install/update/update/new/install/startup.' . $phpEx;
diff --git a/phpBB/install/convert/convertor.php b/phpBB/install/convert/convertor.php
index 5118651b71..09088fe824 100644
--- a/phpBB/install/convert/convertor.php
+++ b/phpBB/install/convert/convertor.php
@@ -63,7 +63,7 @@ class convertor
{
global $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache, $auth;
global $convert, $convert_row, $message_parser, $skip_rows, $language;
- global $request, $phpbb_dispatcher;
+ global $request, $phpbb_dispatcher, $phpbb_container;
$phpbb_config_php_file = new \phpbb\config_php_file($phpbb_root_path, $phpEx);
extract($phpbb_config_php_file->get_all());
@@ -148,16 +148,6 @@ class convertor
$convert->src_truncate_statement = 'DELETE FROM ';
break;
- // Thanks MySQL, for silently converting...
- case 'mysql':
- case 'mysql4':
- if (version_compare($src_db->sql_server_info(true, false), '4.1.3', '>='))
- {
- $convert->mysql_convert = true;
- }
- $convert->src_truncate_statement = 'TRUNCATE TABLE ';
- break;
-
case 'mysqli':
$convert->mysql_convert = true;
$convert->src_truncate_statement = 'TRUNCATE TABLE ';
@@ -687,7 +677,7 @@ class convertor
$this->template->assign_block_vars('checks', array(
'TITLE' => "skip_rows = $skip_rows",
- 'RESULT' => $rows . ((defined('DEBUG') && function_exists('memory_get_usage')) ? ceil(memory_get_usage()/1024) . ' ' . $user->lang['KIB'] : ''),
+ 'RESULT' => $rows . (($phpbb_container->getParameter('debug.memory') && function_exists('memory_get_usage')) ? ceil(memory_get_usage()/1024) . ' ' . $user->lang['KIB'] : ''),
));
$mtime = explode(' ', microtime());
@@ -748,8 +738,6 @@ class convertor
switch ($db->get_sql_layer())
{
// If MySQL, we'll wait to have num_wait_rows rows to submit at once
- case 'mysql':
- case 'mysql4':
case 'mysqli':
$waiting_rows[] = '(' . implode(', ', $insert_values) . ')';
@@ -920,6 +908,7 @@ class convertor
{
global $user, $db, $phpbb_root_path, $phpEx, $config, $cache;
global $convert;
+ global $phpbb_container;
include_once ($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
@@ -959,7 +948,7 @@ class convertor
sync('topic', 'range', 'topic_id BETWEEN ' . $sync_batch . ' AND ' . $end, true, true);
$this->template->assign_block_vars('checks', array(
- 'TITLE' => sprintf($user->lang['SYNC_TOPIC_ID'], $sync_batch, ($sync_batch + $batch_size)) . ((defined('DEBUG') && function_exists('memory_get_usage')) ? ' [' . ceil(memory_get_usage()/1024) . ' ' . $user->lang['KIB'] . ']' : ''),
+ 'TITLE' => sprintf($user->lang['SYNC_TOPIC_ID'], $sync_batch, ($sync_batch + $batch_size)) . (($phpbb_container->getParameter('debug.memory') && function_exists('memory_get_usage')) ? ' [' . ceil(memory_get_usage()/1024) . ' ' . $user->lang['KIB'] . ']' : ''),
'RESULT' => $user->lang['DONE'],
));
@@ -1257,9 +1246,7 @@ class convertor
global $db, $user;
global $convert;
- // Can we use IGNORE with this DBMS?
- $sql_ignore = (strpos($db->get_sql_layer(), 'mysql') === 0 && !defined('DEBUG')) ? 'IGNORE ' : '';
- $insert_query = 'INSERT ' . $sql_ignore . 'INTO ' . $schema['target'] . ' (';
+ $insert_query = 'INSERT INTO ' . $schema['target'] . ' (';
$aliases = array();
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php
index 654f705967..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.2.8',
+ '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/convertors/functions_phpbb20.php b/phpBB/install/convertors/functions_phpbb20.php
index 2da901d3de..b89c086533 100644
--- a/phpBB/install/convertors/functions_phpbb20.php
+++ b/phpBB/install/convertors/functions_phpbb20.php
@@ -1399,10 +1399,6 @@ function phpbb_attachment_category($cat_id)
case 2:
return ATTACHMENT_CATEGORY_WM;
break;
-
- case 3:
- return ATTACHMENT_CATEGORY_FLASH;
- break;
}
return ATTACHMENT_CATEGORY_NONE;
@@ -1758,21 +1754,6 @@ function phpbb_create_userconv_table()
switch ($db->get_sql_layer())
{
- case 'mysql':
- $map_dbms = 'mysql_40';
- break;
-
- case 'mysql4':
- if (version_compare($db->sql_server_info(true), '4.1.3', '>='))
- {
- $map_dbms = 'mysql_41';
- }
- else
- {
- $map_dbms = 'mysql_40';
- }
- break;
-
case 'mysqli':
$map_dbms = 'mysql_41';
break;
@@ -1798,13 +1779,6 @@ function phpbb_create_userconv_table()
)';
break;
- case 'mysql_40':
- $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' (
- user_id mediumint(8) NOT NULL,
- username_clean blob NOT NULL
- )';
- break;
-
case 'mysql_41':
$create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' (
user_id mediumint(8) NOT NULL,
diff --git a/phpBB/install/phpbbcli.php b/phpBB/install/phpbbcli.php
index ddf17fa5f6..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.2.8');
+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 d614579f3d..8e7b26d60c 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -206,7 +206,6 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_filesize_pm',
INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_login_attempts', '3');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_name_chars', '20');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_num_search_keywords', '10');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_pass_chars', '100');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_poll_options', '10');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_post_chars', '60000');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_post_font_size', '200');
@@ -279,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.2.9-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');
@@ -483,7 +482,7 @@ INSERT INTO phpbb_styles (style_name, style_copyright, style_active, style_path,
# -- Forums
INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts_approved, forum_posts_unapproved, forum_posts_softdeleted, forum_topics_approved, forum_topics_unapproved, forum_topics_softdeleted, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents) VALUES ('{L_FORUMS_FIRST_CATEGORY}', '', 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 'Admin', 'AA0000', 972086460, '', '', '', '', '', '', '', 0, 0, '');
-INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts_approved, forum_posts_unapproved, forum_posts_softdeleted, forum_topics_approved, forum_topics_unapproved, forum_topics_softdeleted, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_subject, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents, forum_flags) VALUES ('{L_FORUMS_TEST_FORUM_TITLE}', '{L_FORUMS_TEST_FORUM_DESC}', 2, 3, 1, 1, 1, 0, 0, 1, 0, 0, 1, 2, 'Admin', 'AA0000', '{L_TOPICS_TOPIC_TITLE}', 972086460, '', '', '', '', '', '', '', 0, 0, '', 48);
+INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts_approved, forum_posts_unapproved, forum_posts_softdeleted, forum_topics_approved, forum_topics_unapproved, forum_topics_softdeleted, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_subject, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_freq, prune_days, prune_viewed, forum_parents, forum_flags) VALUES ('{L_FORUMS_TEST_FORUM_TITLE}', '{L_FORUMS_TEST_FORUM_DESC}', 2, 3, 1, 1, 1, 0, 0, 1, 0, 0, 1, 2, 'Admin', 'AA0000', '{L_TOPICS_TOPIC_TITLE}', 972086460, '', '', '', '', '', '', '', 1, 7, 7, '', 48);
# -- Users / Anonymous user
INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_jabber, user_actkey, user_newpasswd, user_allow_massemail) VALUES (2, 1, 'Anonymous', 'anonymous', 0, '', '', 'en', 1, 0, '', 0, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', 0);
@@ -724,7 +723,6 @@ INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mo
INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('ARCHIVES', 0, 1, 1, '', 0, '');
INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('PLAIN_TEXT', 0, 0, 1, '', 0, '');
INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('DOCUMENTS', 0, 0, 1, '', 0, '');
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('FLASH_FILES', 5, 0, 1, '', 0, '');
INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('DOWNLOADABLE_FILES', 0, 0, 1, '', 0, '');
# -- extensions
@@ -781,13 +779,11 @@ INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'ods');
INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'odt');
INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'rtf');
-INSERT INTO phpbb_extensions (group_id, extension) VALUES (5, 'swf');
-
-INSERT INTO phpbb_extensions (group_id, extension) VALUES (6, 'mp3');
-INSERT INTO phpbb_extensions (group_id, extension) VALUES (6, 'mpeg');
-INSERT INTO phpbb_extensions (group_id, extension) VALUES (6, 'mpg');
-INSERT INTO phpbb_extensions (group_id, extension) VALUES (6, 'ogg');
-INSERT INTO phpbb_extensions (group_id, extension) VALUES (6, 'ogm');
+INSERT INTO phpbb_extensions (group_id, extension) VALUES (5, 'mp3');
+INSERT INTO phpbb_extensions (group_id, extension) VALUES (5, 'mpeg');
+INSERT INTO phpbb_extensions (group_id, extension) VALUES (5, 'mpg');
+INSERT INTO phpbb_extensions (group_id, extension) VALUES (5, 'ogg');
+INSERT INTO phpbb_extensions (group_id, extension) VALUES (5, 'ogm');
# Add default profile fields
INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_location', 'profilefields.type.string', 'phpbb_location', '20', '2', '100', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, '', '');
diff --git a/phpBB/install/startup.php b/phpBB/install/startup.php
index 9a4f9bfe39..50758f5b98 100644
--- a/phpBB/install/startup.php
+++ b/phpBB/install/startup.php
@@ -120,6 +120,7 @@ $phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relati
$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path;
// Include files
+phpbb_require_updated('includes/compatibility_globals.' . $phpEx, $phpbb_root_path);
phpbb_require_updated('includes/functions.' . $phpEx, $phpbb_root_path);
phpbb_require_updated('includes/functions_content.' . $phpEx, $phpbb_root_path);
phpbb_include_updated('includes/functions_compatibility.' . $phpEx, $phpbb_root_path);
diff --git a/phpBB/language/en/acp/attachments.php b/phpBB/language/en/acp/attachments.php
index 86430f46bd..67454f8b76 100644
--- a/phpBB/language/en/acp/attachments.php
+++ b/phpBB/language/en/acp/attachments.php
@@ -68,7 +68,6 @@ $lang = array_merge($lang, array(
'ATTACH_QUOTA_EXPLAIN' => 'Maximum drive space available for attachments for the whole board, with 0 being unlimited.',
'ATTACH_TO_POST' => 'Attach file to post',
- 'CAT_FLASH_FILES' => 'Flash files',
'CAT_IMAGES' => 'Images',
'CHECK_CONTENT' => 'Check attachment files',
'CHECK_CONTENT_EXPLAIN' => 'Some browsers can be tricked to assume an incorrect mimetype for uploaded files. This option ensures that such files likely to cause this are rejected.',
@@ -99,7 +98,6 @@ $lang = array_merge($lang, array(
'EXT_GROUP_ARCHIVES' => 'Archives',
'EXT_GROUP_DOCUMENTS' => 'Documents',
'EXT_GROUP_DOWNLOADABLE_FILES' => 'Downloadable Files',
- 'EXT_GROUP_FLASH_FILES' => 'Flash Files',
'EXT_GROUP_IMAGES' => 'Images',
'EXT_GROUP_PLAIN_TEXT' => 'Plain Text',
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index 651b76625d..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',
@@ -437,7 +439,7 @@ $lang = array_merge($lang, array(
'AUTH_PROVIDER_OAUTH_TITLE' => 'OAuth',
'AUTH_PROVIDER_OAUTH_SECRET' => 'Secret',
- 'APACHE_SETUP_BEFORE_USE' => 'You have to setup apache authentication before you switch phpBB to this authentication method. Keep in mind that the username you use for apache authentication has to be the same as your phpBB username. Apache authentication can only be used with mod_php (not with a CGI version) and safe_mode disabled.',
+ 'APACHE_SETUP_BEFORE_USE' => 'You have to setup apache authentication before you switch phpBB to this authentication method. Keep in mind that the username you use for apache authentication has to be the same as your phpBB username. Apache authentication can only be used with mod_php (not with a CGI version).',
'LDAP' => 'LDAP',
'LDAP_DN' => 'LDAP base <var>dn</var>',
diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index 1c2253542c..5ac4b445dc 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -226,16 +226,6 @@ $lang = array_merge($lang, array(
'BACK' => 'Back',
- 'CANNOT_CHANGE_FILE_GROUP' => 'Unable to change file group',
- 'CANNOT_CHANGE_FILE_PERMISSIONS' => 'Unable to change file permissions',
- 'CANNOT_COPY_FILES' => 'Unable to copy files',
- 'CANNOT_CREATE_SYMLINK' => 'Unable to create a symlink',
- 'CANNOT_DELETE_FILES' => 'Unable to delete files from the system',
- 'CANNOT_DUMP_FILE' => 'Unable to dump file',
- 'CANNOT_MIRROR_DIRECTORY' => 'Unable to mirror directory',
- 'CANNOT_RENAME_FILE' => 'Unable to rename a file from the system',
- 'CANNOT_TOUCH_FILES' => 'Unable to determine if the file exists',
-
'CONTAINER_EXCEPTION' => 'phpBB encountered an error building the container due to an installed extension. For this reason, all extensions have been temporarily disabled. Please try purging your forum cache. All extensions will automatically be re-enabled once the container error is resolved. If this error continues, please visit <a href="https://www.phpbb.com/support">phpBB.com</a> for support.',
'EXCEPTION' => 'Exception',
@@ -373,7 +363,7 @@ $lang = array_merge($lang, array(
'DATABASE_SERVER_INFO' => 'Database server',
'DATABASE_SIZE' => 'Database size',
- // Enviroment configuration checks, mbstring related
+ // Environment configuration checks, mbstring related
'ERROR_MBSTRING_FUNC_OVERLOAD' => 'Function overloading is improperly configured',
'ERROR_MBSTRING_FUNC_OVERLOAD_EXPLAIN' => '<var>mbstring.func_overload</var> must be set to either 0 or 4. You can check the current value on the <samp>PHP information</samp> page.',
'ERROR_MBSTRING_ENCODING_TRANSLATION' => 'Transparent character encoding is improperly configured',
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/acp/permissions.php b/phpBB/language/en/acp/permissions.php
index 54d968cdaa..875e424906 100644
--- a/phpBB/language/en/acp/permissions.php
+++ b/phpBB/language/en/acp/permissions.php
@@ -54,7 +54,7 @@ $lang = array_merge($lang, array(
<br />
- <p>For further information on setting up and managing permissions on your phpBB3 board, please see the section on <a href="https://www.phpbb.com/support/docs/en/3.2/ug/quickstart/permissions/">Setting permissions of our Quick Start Guide</a>.</p>
+ <p>For further information on setting up and managing permissions on your phpBB3 board, please see the section on <a href="https://www.phpbb.com/support/docs/en/3.3/ug/quickstart/permissions/">Setting permissions of our Quick Start Guide</a>.</p>
',
'ACL_NEVER' => 'Never',
diff --git a/phpBB/language/en/captcha_recaptcha.php b/phpBB/language/en/captcha_recaptcha.php
index dde2a4ba08..68546ae73c 100644
--- a/phpBB/language/en/captcha_recaptcha.php
+++ b/phpBB/language/en/captcha_recaptcha.php
@@ -43,10 +43,10 @@ $lang = array_merge($lang, array(
'RECAPTCHA_INCORRECT' => 'The solution you provided was incorrect',
'RECAPTCHA_NOSCRIPT' => 'Please enable JavaScript in your browser to load the challenge.',
- 'RECAPTCHA_PUBLIC' => 'Public reCaptcha key',
- 'RECAPTCHA_PUBLIC_EXPLAIN' => 'Your public reCaptcha key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.',
- 'RECAPTCHA_PRIVATE' => 'Private reCaptcha key',
- 'RECAPTCHA_PRIVATE_EXPLAIN' => 'Your private reCaptcha key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.',
+ 'RECAPTCHA_PUBLIC' => 'Site key',
+ 'RECAPTCHA_PUBLIC_EXPLAIN' => 'Your site reCAPTCHA key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>. Please, use reCAPTCHA v2 &gt; Invisible reCAPTCHA badge type.',
+ 'RECAPTCHA_PRIVATE' => 'Secret key',
+ 'RECAPTCHA_PRIVATE_EXPLAIN' => 'Your secret reCAPTCHA key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>. Please, use reCAPTCHA v2 &gt; Invisible reCAPTCHA badge type.',
- 'RECAPTCHA_EXPLAIN' => 'In an effort to prevent automatic submissions, we require that you complete the following challenge.',
+ 'RECAPTCHA_INVISIBLE' => 'This CAPTCHA is actually invisible. To verify that it works, a small icon should appear in right bottom corner of this page.',
));
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 3ba63746c8..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',
@@ -267,6 +268,17 @@ $lang = array_merge($lang, array(
'FSOCK_DISABLED' => 'The operation could not be completed because the <var>fsockopen</var> function has been disabled or the server being queried could not be found.',
'FSOCK_TIMEOUT' => 'A timeout occurred while reading from the network stream.',
+ 'FILESYSTEM_CANNOT_CHANGE_FILE_GROUP' => 'Unable to change file group',
+ 'FILESYSTEM_CANNOT_CHANGE_FILE_PERMISSIONS' => 'Unable to change file permissions',
+ 'FILESYSTEM_CANNOT_COPY_FILES' => 'Unable to copy files',
+ 'FILESYSTEM_CANNOT_CREATE_SYMLINK' => 'Unable to create a symlink',
+ 'FILESYSTEM_CANNOT_CREATE_DIRECTORY' => 'Unable to create directory',
+ 'FILESYSTEM_CANNOT_DELETE_FILES' => 'Unable to delete files from the system',
+ 'FILESYSTEM_CANNOT_DUMP_FILE' => 'Unable to dump file',
+ 'FILESYSTEM_CANNOT_MIRROR_DIRECTORY' => 'Unable to mirror directory',
+ 'FILESYSTEM_CANNOT_RENAME_FILE' => 'Unable to rename a file from the system',
+ 'FILESYSTEM_CANNOT_TOUCH_FILES' => 'Unable to determine if the file exists',
+
'FTP_FSOCK_HOST' => 'FTP host',
'FTP_FSOCK_HOST_EXPLAIN' => 'FTP server used to connect your site.',
'FTP_FSOCK_PASSWORD' => 'FTP password',
@@ -381,7 +393,7 @@ $lang = array_merge($lang, array(
'LOGIN_CHECK_PM' => 'Log in to check your private messages.',
'LOGIN_CONFIRMATION' => 'Confirmation of login',
'LOGIN_CONFIRM_EXPLAIN' => 'To prevent brute forcing accounts the board requires you to enter a confirmation code after a maximum amount of failed logins. The code is displayed in the image you should see below. If you are visually impaired or cannot otherwise read this code please contact the %sBoard Administrator%s.', // unused
- 'LOGIN_ERROR_ATTEMPTS' => 'You exceeded the maximum allowed number of login attempts. In addition to your username and password you now also have to solve the CAPTCHA below.',
+ 'LOGIN_ERROR_ATTEMPTS' => 'You exceeded the maximum allowed number of login attempts. In addition to your username and password you now also have to pass the CAPTCHA test.',
'LOGIN_ERROR_EXTERNAL_AUTH_APACHE' => 'You have not been authenticated by Apache.',
'LOGIN_ERROR_OAUTH_SERVICE_DOES_NOT_EXIST' => 'A non-existant OAuth service has been requested.',
'LOGIN_ERROR_PASSWORD' => 'You have specified an incorrect password. Please check your password and try again. If you continue to have problems please contact the %sBoard Administrator%s.',
@@ -484,7 +496,7 @@ $lang = array_merge($lang, array(
'NOTIFICATION_TOPIC_IN_QUEUE' => '<strong>Topic approval</strong> request by %1$s:',
'NOTIFICATION_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.',
'NOTIFICATION_ADMIN_ACTIVATE_USER' => '<strong>Activation required</strong> for deactivated or newly registered user: “%1$s”',
- // Used in conjuction with NOTIFICATION_BOOKMARK and NOTIFICATION_POST.
+ // Used in conjunction with NOTIFICATION_BOOKMARK and NOTIFICATION_POST.
'NOTIFICATION_MANY_OTHERS' => 'others',
'NOTIFICATION_X_OTHERS' => array(
2 => '%d others',
@@ -604,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/language/en/email/user_activate_passwd.txt b/phpBB/language/en/email/user_activate_passwd.txt
deleted file mode 100644
index 965d5a552c..0000000000
--- a/phpBB/language/en/email/user_activate_passwd.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Subject: New password activation
-
-Hello {USERNAME}
-
-You are receiving this notification because you have (or someone pretending to be you has) requested a new password be sent for your account on "{SITENAME}". If you did not request this notification then please ignore it, if you keep receiving it please contact the board administrator.
-
-To use the new password you need to activate it. To do this click the link provided below.
-
-{U_ACTIVATE}
-
-If successful you will be able to login using the following password:
-
-Password: {PASSWORD}
-
-You can of course change this password yourself via the profile page. If you have any difficulties please contact the board administrator.
-
-{EMAIL_SIG}
diff --git a/phpBB/language/en/email/user_forgot_password.txt b/phpBB/language/en/email/user_forgot_password.txt
new file mode 100644
index 0000000000..4826a7bfd9
--- /dev/null
+++ b/phpBB/language/en/email/user_forgot_password.txt
@@ -0,0 +1,13 @@
+Subject: Account password reset
+
+Hello {USERNAME}
+
+You are receiving this notification because you have requested to recover a forgotten password for your account on "{SITENAME}".
+
+To reset your password, please click the link provided below:
+
+{U_RESET_PASSWORD}
+
+If you did not authorize the request you can ignore this email. Please contact the board administrator if you keep receiving it.
+
+{EMAIL_SIG}
diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php
index 9bceeccde7..53d9940560 100644
--- a/phpBB/language/en/install.php
+++ b/phpBB/language/en/install.php
@@ -49,7 +49,7 @@ $lang = array_merge($lang, array(
// Support page
'SUPPORT_TITLE' => 'Support',
- 'SUPPORT_BODY' => 'Full support will be provided for the current stable release of phpBB3, free of charge. This includes:</p><ul><li>installation</li><li>configuration</li><li>technical questions</li><li>problems relating to potential bugs in the software</li><li>updating from Release Candidate (RC) versions to the latest stable version</li><li>converting from phpBB 2.0.x to phpBB3</li><li>converting from other discussion board software to phpBB3 (please see the <a href="https://www.phpbb.com/community/viewforum.php?f=486">Convertors Forum</a>)</li></ul><p>We encourage users still running beta versions of phpBB3 to replace their installation with a fresh copy of the latest version.</p><h2>Extensions / Styles</h2><p>For issues relating to Extensions, please post in the appropriate <a href="https://www.phpbb.com/community/viewforum.php?f=451">Extensions Forum</a>.<br />For issues relating to styles, templates and themes, please post in the appropriate <a href="https://www.phpbb.com/community/viewforum.php?f=471">Styles Forum</a>.<br /><br />If your question relates to a specific package, please post directly in the topic dedicated to the package.</p><h2>Obtaining Support</h2><p><a href="https://www.phpbb.com/support/">Support Section</a><br /><a href="https://www.phpbb.com/support/docs/en/3.2/ug/quickstart/">Quick Start Guide</a><br /><br />To ensure you stay up to date with the latest news and releases, follow us on <a href="https://www.twitter.com/phpbb/">Twitter</a> and <a href="https://www.facebook.com/phpbb/">Facebook</a><br /><br />',
+ 'SUPPORT_BODY' => 'Full support will be provided for the current stable release of phpBB3, free of charge. This includes:</p><ul><li>installation</li><li>configuration</li><li>technical questions</li><li>problems relating to potential bugs in the software</li><li>updating from Release Candidate (RC) versions to the latest stable version</li><li>converting from phpBB 2.0.x to phpBB3</li><li>converting from other discussion board software to phpBB3 (please see the <a href="https://www.phpbb.com/community/viewforum.php?f=486">Convertors Forum</a>)</li></ul><p>We encourage users still running beta versions of phpBB3 to replace their installation with a fresh copy of the latest version.</p><h2>Extensions / Styles</h2><p>For issues relating to Extensions, please post in the appropriate <a href="https://www.phpbb.com/community/viewforum.php?f=451">Extensions Forum</a>.<br />For issues relating to styles, templates and themes, please post in the appropriate <a href="https://www.phpbb.com/community/viewforum.php?f=471">Styles Forum</a>.<br /><br />If your question relates to a specific package, please post directly in the topic dedicated to the package.</p><h2>Obtaining Support</h2><p><a href="https://www.phpbb.com/support/">Support Section</a><br /><a href="https://www.phpbb.com/support/docs/en/3.3/ug/quickstart/">Quick Start Guide</a><br /><br />To ensure you stay up to date with the latest news and releases, follow us on <a href="https://www.twitter.com/phpbb/">Twitter</a> and <a href="https://www.facebook.com/phpbb/">Facebook</a><br /><br />',
// License
'LICENSE_TITLE' => 'General Public License',
@@ -70,7 +70,7 @@ $lang = array_merge($lang, array(
<p>phpBB3 supports the following databases:</p>
<ul>
- <li>MySQL 3.23 or above (MySQLi supported)</li>
+ <li>MySQL 4.1.3 or above (MySQLi required)</li>
<li>PostgreSQL 8.3+</li>
<li>SQLite 3.6.15+</li>
<li>MS SQL Server 2000 or above (directly or via ODBC)</li>
@@ -105,7 +105,7 @@ $lang = array_merge($lang, array(
// Server requirements
'PHP_VERSION_REQD' => 'PHP version',
- 'PHP_VERSION_REQD_EXPLAIN' => 'phpBB requires PHP version 5.4.0 or higher.',
+ 'PHP_VERSION_REQD_EXPLAIN' => 'phpBB requires PHP version 7.1.0 or higher.',
'PHP_GETIMAGESIZE_SUPPORT' => 'PHP getimagesize() function is required',
'PHP_GETIMAGESIZE_SUPPORT_EXPLAIN' => 'In order for phpBB to function correctly, the getimagesize function needs to be available.',
'PCRE_UTF_SUPPORT' => 'PCRE UTF-8 support',
@@ -186,7 +186,6 @@ $lang = array_merge($lang, array(
// Database options
'DB_OPTION_MSSQL_ODBC' => 'MSSQL Server 2000+ via ODBC',
'DB_OPTION_MSSQLNATIVE' => 'MSSQL Server 2005+ [ Native ]',
- 'DB_OPTION_MYSQL' => 'MySQL',
'DB_OPTION_MYSQLI' => 'MySQL with MySQLi Extension',
'DB_OPTION_ORACLE' => 'Oracle',
'DB_OPTION_POSTGRES' => 'PostgreSQL',
@@ -220,7 +219,7 @@ $lang = array_merge($lang, array(
'UPDATE_INCOMPLETE_MORE' => 'Please read the information below in order to fix this error.',
'UPDATE_INCOMPLETE_EXPLAIN' => '<h1>Incomplete update</h1>
- <p>We noticed that the last update of your phpBB installation hasn’t been completed. Visit the <a href="%1$s" title="%1$s">database updater</a>, ensure <em>Update database only</em> is selected and click on <strong>Submit</strong>. Don\'t forget to delete the "install"-directory after you have updated the database sucessfully.</p>',
+ <p>We noticed that the last update of your phpBB installation hasn’t been completed. Visit the <a href="%1$s" title="%1$s">database updater</a>, ensure <em>Update database only</em> is selected and click on <strong>Submit</strong>. Don\'t forget to delete the "install"-directory after you have updated the database successfully.</p>',
//
// Server data
@@ -565,7 +564,7 @@ $lang = array_merge($lang, array(
// Finish conversion
'CONVERT_COMPLETE' => 'Conversion completed',
- 'CONVERT_COMPLETE_EXPLAIN' => 'You have now successfully converted your board to phpBB 3.2. You can now login and <a href="../">access your board</a>. Please ensure that the settings were transferred correctly before enabling your board by deleting the install directory. Remember that help on using phpBB is available online via the <a href="https://www.phpbb.com/support/docs/en/3.2/ug/">Documentation</a> and the <a href="https://www.phpbb.com/community/viewforum.php?f=466">support forums</a>.',
+ 'CONVERT_COMPLETE_EXPLAIN' => 'You have now successfully converted your board to phpBB 3.3. You can now login and <a href="../">access your board</a>. Please ensure that the settings were transferred correctly before enabling your board by deleting the install directory. Remember that help on using phpBB is available online via the <a href="https://www.phpbb.com/support/docs/en/3.2/ug/">Documentation</a> and the <a href="https://www.phpbb.com/community/viewforum.php?f=466">support forums</a>.',
'CONV_ERROR_ATTACH_FTP_DIR' => 'FTP upload for attachments is enabled at the old board. Please disable the FTP upload option and make sure a valid upload directory is specified, then copy all attachment files to this new web accessible directory. Once you have done this, restart the convertor.',
'CONV_ERROR_CONFIG_EMPTY' => 'There is no configuration information available for the conversion.',
diff --git a/phpBB/language/en/migrator.php b/phpBB/language/en/migrator.php
index 8a82d40be5..03802549d2 100644
--- a/phpBB/language/en/migrator.php
+++ b/phpBB/language/en/migrator.php
@@ -46,7 +46,7 @@ $lang = array_merge($lang, array(
'MIGRATION_DATA_IN_PROGRESS' => 'Installing Data: %1$s; Time: %2$.2f seconds',
'MIGRATION_DATA_RUNNING' => 'Installing Data: %s.',
'MIGRATION_EFFECTIVELY_INSTALLED' => 'Migration already effectively installed (skipped): %s',
- 'MIGRATION_EXCEPTION_ERROR' => 'Something went wrong during the request and an exception was thrown. The changes made before the error occurred were reversed to the best of our abilities, but you should check the board for errors.',
+ 'MIGRATION_EXCEPTION_ERROR' => 'Something went wrong during the request and an exception was thrown. The changes made before the error occurred were reversed to the best of our abilities, but you should check the board for errors:<br><br>%s',
'MIGRATION_NOT_FULFILLABLE' => 'The migration "%1$s" is not fulfillable, missing migration "%2$s".',
'MIGRATION_NOT_INSTALLED' => 'The migration "%s" is not installed.',
'MIGRATION_NOT_VALID' => '%s is not a valid migration.',
diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php
index 426475e77a..639b8d8370 100644
--- a/phpBB/language/en/posting.php
+++ b/phpBB/language/en/posting.php
@@ -266,7 +266,6 @@ $lang = array_merge($lang, array(
'TOPIC_BUMPED' => 'Topic has been bumped successfully.',
'UNAUTHORISED_BBCODE' => 'You cannot use certain BBCodes: %s.',
- 'UNGLOBALISE_EXPLAIN' => 'To switch this topic back from being global to a normal topic, you need to select the forum you wish this topic to be displayed.',
'UNSUPPORTED_CHARACTERS_MESSAGE' => 'Your message contains the following unsupported characters:<br />%s',
'UNSUPPORTED_CHARACTERS_SUBJECT' => 'Your subject contains the following unsupported characters:<br />%s',
'UPDATE_COMMENT' => 'Update comment',
diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php
index 8549230b9f..57319ae26b 100644
--- a/phpBB/language/en/ucp.php
+++ b/phpBB/language/en/ucp.php
@@ -62,7 +62,7 @@ $lang = array_merge($lang, array(
'ACCOUNT_ACTIVE' => 'Your account has now been activated. Thank you for registering.',
'ACCOUNT_ACTIVE_ADMIN' => 'The account has now been activated.',
'ACCOUNT_ACTIVE_PROFILE' => 'Your account has now been successfully reactivated.',
- 'ACCOUNT_ADDED' => 'Thank you for registering, your account has been created. You may now login with your username and password.',
+ 'ACCOUNT_ADDED' => 'Thank you for registering, your account has been created.',
'ACCOUNT_COPPA' => 'Your account has been created but has to be approved, please check your email for details.',
'ACCOUNT_EMAIL_CHANGED' => 'Your account has been updated. However, this board requires account reactivation on email changes. An activation key has been sent to the new email address you provided. Please check your email for further information.',
'ACCOUNT_EMAIL_CHANGED_ADMIN' => 'Your account has been updated. However, this board requires account reactivation by the administrators on email changes. An email has been sent to them and you will be informed when your account has been reactivated.',
@@ -402,6 +402,7 @@ $lang = array_merge($lang, array(
'NO_OLDER_PM' => 'No older messages.',
'NO_PASSWORD_SUPPLIED' => 'You cannot login without a password.',
'NO_RECIPIENT' => 'No recipient defined.',
+ 'NO_RESET_TOKEN' => 'You did not provide a password reset token.',
'NO_RULES_DEFINED' => 'No rules defined.',
'NO_SAVED_DRAFTS' => 'No drafts saved.',
'NO_TO_RECIPIENT' => 'None',
@@ -409,13 +410,14 @@ $lang = array_merge($lang, array(
'NO_WATCHED_SELECTED' => 'You have not selected any subscribed topics or forums.',
'NO_WATCHED_TOPICS' => 'You are not subscribed to any topics.',
- 'PASS_TYPE_ALPHA_EXPLAIN' => 'Password must be between %1$s and %2$s long, must contain letters in mixed case and must contain numbers.',
- 'PASS_TYPE_ANY_EXPLAIN' => 'Must be between %1$s and %2$s.',
- 'PASS_TYPE_CASE_EXPLAIN' => 'Password must be between %1$s and %2$s long and must contain letters in mixed case.',
- 'PASS_TYPE_SYMBOL_EXPLAIN' => 'Password must be between %1$s and %2$s long, must contain letters in mixed case, must contain numbers and must contain symbols.',
+ 'PASS_TYPE_ALPHA_EXPLAIN' => 'Password must be at least %1$s long, must contain letters in mixed case and must contain numbers.',
+ 'PASS_TYPE_ANY_EXPLAIN' => 'Must be at least %1$s long.',
+ 'PASS_TYPE_CASE_EXPLAIN' => 'Password must be at least %1$s long and must contain letters in mixed case.',
+ 'PASS_TYPE_SYMBOL_EXPLAIN' => 'Password must be at least %1$s long, must contain letters in mixed case, must contain numbers and must contain symbols.',
'PASSWORD' => 'Password',
'PASSWORD_ACTIVATED' => 'Your new password has been activated.',
- 'PASSWORD_UPDATED_IF_EXISTED' => 'If your account exists, a new password was sent to your registered email address. If you do not receive an email, it may be because you are banned, your account is not activated, or you are not allowed to change your password. Contact admin if any of those reasons apply. Also, check your spam filter.',
+ 'PASSWORD_RESET' => 'Your password has been successfully reset.',
+ 'PASSWORD_RESET_LINK_SENT' => 'If your account exists, a password reset link was sent to your registered email address. If you do not receive an email, it may be because you are banned, your account is not activated, you have requested multiple password resets within a short time frame, or you are not allowed to change your password. Contact an administrator if any of those reasons apply. Also, please check your spam filter.',
'PERMISSIONS_RESTORED' => 'Successfully restored original permissions.',
'PERMISSIONS_TRANSFERRED' => 'Successfully transferred permissions from <strong>%s</strong>, you are now able to browse the board with this user’s permissions.<br />Please note that admin permissions were not transferred. You are able to revert to your permission set at any time.',
'PM_DISABLED' => 'Private messaging has been disabled on this board.',
@@ -450,6 +452,7 @@ $lang = array_merge($lang, array(
'RECIPIENT' => 'Recipient',
'RECIPIENTS' => 'Recipients',
'REGISTRATION' => 'Registration',
+ 'OAUTH_REGISTRATION' => 'Registration using external services',
'RELEASE_MESSAGES' => '%sRelease all on-hold messages%s… they will be re-sorted into the appropriate folder if enough space is made available.',
'REMOVE_ADDRESS' => 'Remove address',
'REMOVE_SELECTED_BOOKMARKS' => 'Remove selected bookmarks',
@@ -462,6 +465,8 @@ $lang = array_merge($lang, array(
'REPLIED_MESSAGE' => 'Replied to message',
'REPLY_TO_ALL' => 'Reply to sender and all recipients.',
'REPORT_PM' => 'Report private message',
+ 'RESET_PASSWORD' => 'Reset password',
+ 'RESET_TOKEN_EXPIRED_OR_INVALID' => 'The password reset token you supplied is invalid or has expired.',
'RESIGN_SELECTED' => 'Resign selected',
'RETURN_FOLDER' => '%1$sReturn to previous folder%2$s',
'RETURN_UCP' => '%sReturn to the User Control Panel%s',
@@ -477,7 +482,6 @@ $lang = array_merge($lang, array(
'SAME_PASSWORD_ERROR' => 'The new password you entered is the same as your current password.',
'SEARCH_YOUR_POSTS' => 'Show your posts',
- 'SEND_PASSWORD' => 'Send password',
'SENT_AT' => 'Sent', // Used before dates in private messages
'SHOW_EMAIL' => 'Users can contact me by email',
'SIGNATURE_EXPLAIN' => 'This is a block of text that can be added to posts you make. There is a %d character limit.',
@@ -561,7 +565,6 @@ $lang = array_merge($lang, array(
'UCP_PASSWORD_RESET_DISABLED' => 'The password reset functionality has been disabled. If you need help accessing your account, please contact the %sBoard Administrator%s',
'UCP_REGISTER_DISABLE' => 'Creating a new account is currently not possible.',
- 'UCP_REMIND' => 'Send password',
'UCP_RESEND' => 'Send activation email',
'UCP_WELCOME' => 'Welcome to the User Control Panel. From here you can monitor, view and update your profile, preferences, subscribed forums and topics. You can also send messages to other users (if permitted). Please ensure you read any announcements before continuing.',
'UCP_ZEBRA' => 'Friends &amp; Foes',
diff --git a/phpBB/mcp.php b/phpBB/mcp.php
index c4a8a66c18..6215a675b4 100644
--- a/phpBB/mcp.php
+++ b/phpBB/mcp.php
@@ -308,6 +308,11 @@ $vars = array(
);
extract($phpbb_dispatcher->trigger_event('core.modify_mcp_modules_display_option', compact($vars)));
+$template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $user->lang('MCP'),
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}mcp.$phpEx"),
+));
+
// Load and execute the relevant module
$module->load_active();
diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php
index 1343bd7c60..43b58969a5 100644
--- a/phpBB/memberlist.php
+++ b/phpBB/memberlist.php
@@ -364,6 +364,11 @@ switch ($mode)
}
}
+ $template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $page_title,
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=team"),
+ ));
+
$template->assign_vars(array(
'PM_IMG' => $user->img('icon_contact_pm', $user->lang['SEND_PRIVATE_MESSAGE']))
);
@@ -461,6 +466,11 @@ switch ($mode)
break;
}
+ $template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $page_title,
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&amp;action=$action&amp;u=$user_id"),
+ ));
+
// Send vars to the template
$template->assign_vars(array(
'IM_CONTACT' => $row[$sql_field],
@@ -865,6 +875,15 @@ switch ($mode)
$page_title = sprintf($user->lang['VIEWING_PROFILE'], $member['username']);
$template_html = 'memberlist_view.html';
+ $template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $user->lang('MEMBERLIST'),
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}memberlist.$phpEx"),
+ ));
+ $template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $member['username'],
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=viewprofile&u=$user_id"),
+ ));
+
break;
case 'contactadmin':
@@ -914,6 +933,41 @@ switch ($mode)
$template_html = $form->get_template_file();
$form->render($template);
+ if ($user_id)
+ {
+ $navlink_name = $user->lang('SEND_EMAIL');
+ $navlink_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&u=$user_id");
+ }
+ else if ($topic_id)
+ {
+ $sql = 'SELECT f.parent_id, f.forum_parents, f.left_id, f.right_id, f.forum_type, f.forum_name, f.forum_id, f.forum_desc, f.forum_desc_uid, f.forum_desc_bitfield, f.forum_desc_options, f.forum_options, t.topic_title
+ FROM ' . FORUMS_TABLE . ' as f,
+ ' . TOPICS_TABLE . ' as t
+ WHERE t.forum_id = f.forum_id';
+ $result = $db->sql_query($sql);
+ $topic_data = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ generate_forum_nav($topic_data);
+ $template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $topic_data['topic_title'],
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id"),
+ ));
+
+ $navlink_name = $user->lang('EMAIL_TOPIC');
+ $navlink_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&t=$topic_id");
+ }
+ else if ($mode === 'contactadmin')
+ {
+ $navlink_name = $user->lang('CONTACT_ADMIN');
+ $navlink_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contactadmin");
+ }
+
+ $template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $navlink_name,
+ 'U_BREADCRUMB' => $navlink_url,
+ ));
+
break;
case 'livesearch':
@@ -951,6 +1005,11 @@ switch ($mode)
$page_title = $user->lang['MEMBERLIST'];
$template_html = 'memberlist_body.html';
+ $template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $page_title,
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}memberlist.$phpEx"),
+ ));
+
/* @var $pagination \phpbb\pagination */
$pagination = $phpbb_container->get('pagination');
@@ -1267,6 +1326,11 @@ switch ($mode)
unset($module);
}
+ $template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $group_helper->get_name($group_row['group_name']),
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=group&amp;g=$group_id"),
+ ));
+
$template->assign_vars(array(
'GROUP_DESC' => generate_text_for_display($group_row['group_desc'], $group_row['group_desc_uid'], $group_row['group_desc_bitfield'], $group_row['group_desc_options']),
'GROUP_NAME' => $group_helper->get_name($group_row['group_name']),
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/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php
index a012bb15b6..a5b704b4ff 100644
--- a/phpBB/phpbb/avatar/driver/upload.php
+++ b/phpBB/phpbb/avatar/driver/upload.php
@@ -84,6 +84,7 @@ class upload extends \phpbb\avatar\driver\driver
$template->assign_vars(array(
'S_UPLOAD_AVATAR_URL' => ($this->config['allow_avatar_remote_upload']) ? true : false,
'AVATAR_UPLOAD_SIZE' => $this->config['avatar_filesize'],
+ 'AVATAR_ALLOWED_EXTENSIONS' => implode(',', preg_replace('/^/', '.', $this->allowed_extensions)),
));
return true;
diff --git a/phpBB/phpbb/cache/driver/apc.php b/phpBB/phpbb/cache/driver/apc.php
deleted file mode 100644
index 521d5d41ea..0000000000
--- a/phpBB/phpbb/cache/driver/apc.php
+++ /dev/null
@@ -1,70 +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;
-
-/**
-* ACM for APC
-*/
-class apc extends \phpbb\cache\driver\memory
-{
- var $extension = 'apc';
-
- /**
- * {@inheritDoc}
- */
- function purge()
- {
- apc_clear_cache('user');
-
- parent::purge();
- }
-
- /**
- * Fetch an item from the cache
- *
- * @access protected
- * @param string $var Cache key
- * @return mixed Cached data
- */
- function _read($var)
- {
- return apc_fetch($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)
- {
- return apc_store($this->key_prefix . $var, $data, $ttl);
- }
-
- /**
- * Remove an item from the cache
- *
- * @access protected
- * @param string $var Cache key
- * @return bool True if the operation succeeded
- */
- function _delete($var)
- {
- return apc_delete($this->key_prefix . $var);
- }
-}
diff --git a/phpBB/phpbb/cache/driver/eaccelerator.php b/phpBB/phpbb/cache/driver/eaccelerator.php
deleted file mode 100644
index 740855144f..0000000000
--- a/phpBB/phpbb/cache/driver/eaccelerator.php
+++ /dev/null
@@ -1,107 +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;
-
-/**
-* ACM for eAccelerator
-* @todo Missing locks from destroy() talk with David
-*/
-class eaccelerator extends \phpbb\cache\driver\memory
-{
- var $extension = 'eaccelerator';
- var $function = 'eaccelerator_get';
-
- var $serialize_header = '#phpbb-serialized#';
-
- /**
- * {@inheritDoc}
- */
- function purge()
- {
- foreach (eaccelerator_list_keys() as $var)
- {
- // @todo Check why the substr()
- // @todo Only unset vars matching $this->key_prefix
- eaccelerator_rm(substr($var['name'], 1));
- }
-
- parent::purge();
- }
-
- /**
- * {@inheritDoc}
- */
- function tidy()
- {
- global $config;
-
- eaccelerator_gc();
-
- $config->set('cache_last_gc', time(), false);
- }
-
- /**
- * Fetch an item from the cache
- *
- * @access protected
- * @param string $var Cache key
- * @return mixed Cached data
- */
- function _read($var)
- {
- $result = eaccelerator_get($this->key_prefix . $var);
-
- if ($result === null)
- {
- return false;
- }
-
- // Handle serialized objects
- if (is_string($result) && strpos($result, $this->serialize_header . 'O:') === 0)
- {
- $result = unserialize(substr($result, strlen($this->serialize_header)));
- }
-
- return $result;
- }
-
- /**
- * 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)
- {
- // Serialize objects and make them easy to detect
- $data = (is_object($data)) ? $this->serialize_header . serialize($data) : $data;
-
- return eaccelerator_put($this->key_prefix . $var, $data, $ttl);
- }
-
- /**
- * Remove an item from the cache
- *
- * @access protected
- * @param string $var Cache key
- * @return bool True if the operation succeeded
- */
- function _delete($var)
- {
- return eaccelerator_rm($this->key_prefix . $var);
- }
-}
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/cache/driver/memory.php b/phpBB/phpbb/cache/driver/memory.php
index eba9549877..956936bf6f 100644
--- a/phpBB/phpbb/cache/driver/memory.php
+++ b/phpBB/phpbb/cache/driver/memory.php
@@ -25,7 +25,7 @@ abstract class memory extends \phpbb\cache\driver\base
*/
function __construct()
{
- global $phpbb_root_path, $dbname, $table_prefix, $phpbb_container;
+ global $dbname, $table_prefix, $phpbb_container;
$this->cache_dir = $phpbb_container->getParameter('core.cache_dir');
$this->key_prefix = substr(md5($dbname . $table_prefix), 0, 8) . '_';
diff --git a/phpBB/phpbb/cache/driver/xcache.php b/phpBB/phpbb/cache/driver/xcache.php
deleted file mode 100644
index 0c845a6a8d..0000000000
--- a/phpBB/phpbb/cache/driver/xcache.php
+++ /dev/null
@@ -1,107 +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;
-
-/**
-* ACM for XCache
-*
-* To use this module you need ini_get() enabled and the following INI settings configured as follows:
-* - xcache.var_size > 0
-* - xcache.admin.enable_auth = off (or xcache.admin.user and xcache.admin.password set)
-*
-*/
-class xcache extends \phpbb\cache\driver\memory
-{
- var $extension = 'XCache';
-
- function __construct()
- {
- parent::__construct();
-
- if (!function_exists('ini_get') || (int) ini_get('xcache.var_size') <= 0)
- {
- trigger_error('Increase xcache.var_size setting above 0 or enable ini_get() to use this ACM module.', E_USER_ERROR);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- function purge()
- {
- // Run before for XCache, if admin functions are disabled it will terminate execution
- parent::purge();
-
- // If the admin authentication is enabled but not set up, this will cause a nasty error.
- // Not much we can do about it though.
- $n = xcache_count(XC_TYPE_VAR);
-
- for ($i = 0; $i < $n; $i++)
- {
- xcache_clear_cache(XC_TYPE_VAR, $i);
- }
- }
-
- /**
- * Fetch an item from the cache
- *
- * @access protected
- * @param string $var Cache key
- * @return mixed Cached data
- */
- function _read($var)
- {
- $result = xcache_get($this->key_prefix . $var);
-
- return ($result !== null) ? $result : false;
- }
-
- /**
- * 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)
- {
- return xcache_set($this->key_prefix . $var, $data, $ttl);
- }
-
- /**
- * Remove an item from the cache
- *
- * @access protected
- * @param string $var Cache key
- * @return bool True if the operation succeeded
- */
- function _delete($var)
- {
- return xcache_unset($this->key_prefix . $var);
- }
-
- /**
- * Check if a cache var exists
- *
- * @access protected
- * @param string $var Cache key
- * @return bool True if it exists, otherwise false
- */
- function _isset($var)
- {
- return xcache_isset($this->key_prefix . $var);
- }
-}
diff --git a/phpBB/phpbb/class_loader.php b/phpBB/phpbb/class_loader.php
index cfdcc2af0b..a4b69311ca 100644
--- a/phpBB/phpbb/class_loader.php
+++ b/phpBB/phpbb/class_loader.php
@@ -64,7 +64,7 @@ class class_loader
/**
* Provide the class loader with a cache to store paths. If set to null, the
- * the class loader will resolve paths by checking for the existance of every
+ * the class loader will resolve paths by checking for the existence of every
* directory in the class name every time.
*
* @param \phpbb\cache\driver\driver_interface $cache An implementation of the phpBB cache interface.
diff --git a/phpBB/phpbb/config/config.php b/phpBB/phpbb/config/config.php
index aaad333006..c619cae2fd 100644
--- a/phpBB/phpbb/config/config.php
+++ b/phpBB/phpbb/config/config.php
@@ -148,6 +148,25 @@ class config implements \ArrayAccess, \IteratorAggregate, \Countable
}
/**
+ * Checks configuration option's value only if the new_value matches the
+ * current configuration value and the configuration value does exist.Called
+ * only after set_atomic has been called.
+ *
+ * @param string $key The configuration option's name
+ * @param string $new_value New configuration value
+ * @throws \phpbb\exception\http_exception when config value is set and not equal to new_value.
+ * @return bool True if the value was changed, false otherwise.
+ */
+ public function ensure_lock($key, $new_value)
+ {
+ if (isset($this->config[$key]) && $this->config[$key] == $new_value)
+ {
+ return true;
+ }
+ throw new \phpbb\exception\http_exception(500, 'Failure while aqcuiring locks.');
+ }
+
+ /**
* Increments an integer configuration value.
*
* @param string $key The configuration option's name
diff --git a/phpBB/phpbb/config_php_file.php b/phpBB/phpbb/config_php_file.php
index 7445e7df22..e3f7357720 100644
--- a/phpBB/phpbb/config_php_file.php
+++ b/phpBB/phpbb/config_php_file.php
@@ -155,6 +155,12 @@ class config_php_file
return $dbms;
}
+ // Force use of mysqli when specifying mysql
+ if (preg_match('/(phpbb\\\db\\\driver\\\)?mysql$/i', $dbms))
+ {
+ return 'phpbb\db\driver\mysqli';
+ }
+
throw new \RuntimeException("You have specified an invalid dbms driver: $dbms");
}
}
diff --git a/phpBB/phpbb/console/command/cron/run.php b/phpBB/phpbb/console/command/cron/run.php
index dea6493007..df8bcf44f9 100644
--- a/phpBB/phpbb/console/command/cron/run.php
+++ b/phpBB/phpbb/console/command/cron/run.php
@@ -73,7 +73,7 @@ class run extends \phpbb\console\command\command
* @param InputInterface $input The input stream used to get the argument and verboe option.
* @param OutputInterface $output The output stream, used for printing verbose-mode and error information.
*
- * @return int 0 if all is ok, 1 if a lock error occured and 2 if no task matching the argument was found.
+ * @return int 0 if all is ok, 1 if a lock error occurred and 2 if no task matching the argument was found.
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php
index a6f5b10e86..504b5546b3 100644
--- a/phpBB/phpbb/console/command/extension/enable.php
+++ b/phpBB/phpbb/console/command/extension/enable.php
@@ -46,9 +46,11 @@ class enable extends command
$extension = $this->manager->get_extension($name);
- if (!$extension->is_enableable())
+ if (($enableable = $extension->is_enableable()) !== true)
{
- $io->error($this->user->lang('CLI_EXTENSION_NOT_ENABLEABLE', $name));
+ $message = !empty($enableable) ? $enableable : $this->user->lang('CLI_EXTENSION_NOT_ENABLEABLE', $name);
+ $message = is_array($message) ? implode(PHP_EOL, $message) : $message;
+ $io->error($message);
return 1;
}
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/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php
index 9ced651e8b..85c6cf7379 100644
--- a/phpBB/phpbb/console/command/update/check.php
+++ b/phpBB/phpbb/console/command/update/check.php
@@ -77,7 +77,7 @@ class check extends \phpbb\console\command\command
*
* @param InputInterface $input Input stream, used to get the options.
* @param OutputInterface $output Output stream, used to print messages.
- * @return int 0 if the board is up to date, 1 if it is not and 2 if an error occured.
+ * @return int 0 if the board is up to date, 1 if it is not and 2 if an error occurred.
* @throws \RuntimeException
*/
protected function execute(InputInterface $input, OutputInterface $output)
diff --git a/phpBB/phpbb/console/command/user/add.php b/phpBB/phpbb/console/command/user/add.php
index c60a059251..303216a93d 100644
--- a/phpBB/phpbb/console/command/user/add.php
+++ b/phpBB/phpbb/console/command/user/add.php
@@ -239,7 +239,7 @@ class add extends command
array('string', false, $this->config['min_name_chars'], $this->config['max_name_chars']),
array('username', '')),
'new_password' => array(
- array('string', false, $this->config['min_pass_chars'], $this->config['max_pass_chars']),
+ array('string', false, $this->config['min_pass_chars'], 0),
array('password')),
'email' => array(
array('string', false, 6, 60),
diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php
index f023e0742c..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 . ')';
}
@@ -684,7 +698,7 @@ class content_visibility
* @param $time int Timestamp when the action is performed
* @param $reason string Reason why the visibilty was changed.
* @param $force_update_all bool Force to update all posts within the topic
- * @return array Changed topic data, empty array if an error occured.
+ * @return array Changed topic data, empty array if an error occurred.
*/
public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false)
{
diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php
index 664b4f4e0f..58a4a492f8 100644
--- a/phpBB/phpbb/controller/helper.php
+++ b/phpBB/phpbb/controller/helper.php
@@ -121,7 +121,7 @@ class helper
* @param int $code The error code (e.g. 404, 500, 503, etc.)
* @return Response A Response instance
*
- * @deprecated 3.1.3 (To be removed: 3.3.0) Use exceptions instead.
+ * @deprecated 3.1.3 (To be removed: 4.0.0) Use exceptions instead.
*/
public function error($message, $code = 500)
{
diff --git a/phpBB/phpbb/cron/controller/cron.php b/phpBB/phpbb/cron/controller/cron.php
new file mode 100644
index 0000000000..6f0e35e4cd
--- /dev/null
+++ b/phpBB/phpbb/cron/controller/cron.php
@@ -0,0 +1,40 @@
+<?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\cron\controller;
+
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * Controller for running cron jobs
+ */
+class cron
+{
+ /**
+ * Handles CRON requests
+ *
+ * @param string $cron_type
+ *
+ * @return Response
+ */
+ public function handle($cron_type)
+ {
+ $response = new Response();
+ $response->headers->set('Cache-Control', 'no-cache');
+ $response->headers->set('Content-type', 'image/gif');
+ $response->headers->set('Content-length', '43');
+ $response->setContent(base64_decode('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='));
+
+ return $response;
+ }
+}
diff --git a/phpBB/phpbb/cron/event/cron_runner_listener.php b/phpBB/phpbb/cron/event/cron_runner_listener.php
new file mode 100644
index 0000000000..9e9ecf0d47
--- /dev/null
+++ b/phpBB/phpbb/cron/event/cron_runner_listener.php
@@ -0,0 +1,103 @@
+<?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\cron\event;
+
+use phpbb\cron\manager;
+use phpbb\lock\db;
+use phpbb\request\request_interface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\PostResponseEvent;
+
+/**
+ * Event listener that executes cron tasks, after the response was served
+ */
+class cron_runner_listener implements EventSubscriberInterface
+{
+ /**
+ * @var \phpbb\lock\db
+ */
+ private $cron_lock;
+
+ /**
+ * @var \phpbb\cron\manager
+ */
+ private $cron_manager;
+
+ /**
+ * @var \phpbb\request\request_interface
+ */
+ private $request;
+
+ /**
+ * Constructor
+ *
+ * @param db $lock
+ * @param manager $manager
+ * @param request_interface $request
+ */
+ public function __construct(db $lock, manager $manager, request_interface $request)
+ {
+ $this->cron_lock = $lock;
+ $this->cron_manager = $manager;
+ $this->request = $request;
+ }
+
+ /**
+ * Runs the cron job after the response was sent
+ *
+ * @param PostResponseEvent $event The event
+ */
+ public function on_kernel_terminate(PostResponseEvent $event)
+ {
+ $request = $event->getRequest();
+ $controller_name = $request->get('_route');
+
+ if ($controller_name !== 'phpbb_cron_run')
+ {
+ return;
+ }
+
+ $cron_type = $request->get('cron_type');
+
+ if ($this->cron_lock->acquire())
+ {
+ $task = $this->cron_manager->find_task($cron_type);
+ if ($task)
+ {
+ if ($task->is_parametrized())
+ {
+ $task->parse_parameters($this->request);
+ }
+
+ if ($task->is_ready())
+ {
+ $task->run();
+ }
+
+ $this->cron_lock->release();
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function getSubscribedEvents()
+ {
+ return array(
+ KernelEvents::TERMINATE => 'on_kernel_terminate',
+ );
+ }
+}
diff --git a/phpBB/phpbb/cron/manager.php b/phpBB/phpbb/cron/manager.php
index 9bd30a0a5b..59ee693074 100644
--- a/phpBB/phpbb/cron/manager.php
+++ b/phpBB/phpbb/cron/manager.php
@@ -13,6 +13,9 @@
namespace phpbb\cron;
+use phpbb\cron\task\wrapper;
+use phpbb\routing\helper;
+
/**
* Cron manager class.
*
@@ -21,6 +24,11 @@ namespace phpbb\cron;
class manager
{
/**
+ * @var helper
+ */
+ protected $routing_helper;
+
+ /**
* Set of \phpbb\cron\task\wrapper objects.
* Array holding all tasks that have been found.
*
@@ -28,18 +36,27 @@ class manager
*/
protected $tasks = array();
+ /**
+ * @var string
+ */
protected $phpbb_root_path;
+
+ /**
+ * @var string
+ */
protected $php_ext;
/**
* Constructor. Loads all available tasks.
*
* @param array|\Traversable $tasks Provides an iterable set of task names
+ * @param helper $routing_helper Routing helper
* @param string $phpbb_root_path Relative path to phpBB root
* @param string $php_ext PHP file extension
*/
- public function __construct($tasks, $phpbb_root_path, $php_ext)
+ public function __construct($tasks, helper $routing_helper, $phpbb_root_path, $php_ext)
{
+ $this->routing_helper = $routing_helper;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
@@ -142,6 +159,6 @@ class manager
*/
public function wrap_task(\phpbb\cron\task\task $task)
{
- return new \phpbb\cron\task\wrapper($task, $this->phpbb_root_path, $this->php_ext);
+ return new wrapper($task, $this->routing_helper, $this->phpbb_root_path, $this->php_ext);
}
}
diff --git a/phpBB/phpbb/cron/task/wrapper.php b/phpBB/phpbb/cron/task/wrapper.php
index 8a4a8b1f0c..4dc3a7fb95 100644
--- a/phpBB/phpbb/cron/task/wrapper.php
+++ b/phpBB/phpbb/cron/task/wrapper.php
@@ -13,14 +13,32 @@
namespace phpbb\cron\task;
+use phpbb\routing\helper;
+
/**
* Cron task wrapper class.
* Enhances cron tasks with convenience methods that work identically for all tasks.
*/
class wrapper
{
+ /**
+ * @var helper
+ */
+ protected $routing_helper;
+
+ /**
+ * @var task
+ */
protected $task;
+
+ /**
+ * @var string
+ */
protected $phpbb_root_path;
+
+ /**
+ * @var string
+ */
protected $php_ext;
/**
@@ -28,13 +46,15 @@ class wrapper
*
* Wraps a task $task, which must implement cron_task interface.
*
- * @param \phpbb\cron\task\task $task The cron task to wrap.
- * @param string $phpbb_root_path Relative path to phpBB root
- * @param string $php_ext PHP file extension
+ * @param task $task The cron task to wrap.
+ * @param helper $routing_helper Routing helper for route generation
+ * @param string $phpbb_root_path Relative path to phpBB root
+ * @param string $php_ext PHP file extension
*/
- public function __construct(\phpbb\cron\task\task $task, $phpbb_root_path, $php_ext)
+ public function __construct(task $task, helper $routing_helper, $phpbb_root_path, $php_ext)
{
$this->task = $task;
+ $this->routing_helper = $routing_helper;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
}
@@ -49,7 +69,7 @@ class wrapper
*/
public function is_parametrized()
{
- return $this->task instanceof \phpbb\cron\task\parametrized;
+ return $this->task instanceof parametrized;
}
/**
@@ -76,22 +96,13 @@ class wrapper
*/
public function get_url()
{
- $name = $this->get_name();
+ $params['cron_type'] = $this->get_name();
if ($this->is_parametrized())
{
- $params = $this->task->get_parameters();
- $extra = '';
- foreach ($params as $key => $value)
- {
- $extra .= '&amp;' . $key . '=' . urlencode($value);
- }
+ $params = array_merge($params, $this->task->get_parameters());
}
- else
- {
- $extra = '';
- }
- $url = append_sid($this->phpbb_root_path . 'cron.' . $this->php_ext, 'cron_type=' . $name . $extra);
- return $url;
+
+ return $this->routing_helper->route('phpbb_cron_run', $params);
}
/**
diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php
index a36ce8c0d7..93f0a749e5 100644
--- a/phpBB/phpbb/db/driver/driver.php
+++ b/phpBB/phpbb/db/driver/driver.php
@@ -76,6 +76,16 @@ abstract class driver implements driver_interface
const SUBQUERY_BUILD = 5;
/**
+ * @var bool
+ */
+ protected $debug_load_time = false;
+
+ /**
+ * @var bool
+ */
+ protected $debug_sql_explain = false;
+
+ /**
* Constructor
*/
function __construct()
@@ -98,6 +108,22 @@ abstract class driver implements driver_interface
/**
* {@inheritdoc}
*/
+ public function set_debug_load_time($value)
+ {
+ $this->debug_load_time = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set_debug_sql_explain($value)
+ {
+ $this->debug_sql_explain = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function get_sql_layer()
{
return $this->sql_layer;
@@ -955,7 +981,7 @@ abstract class driver implements driver_interface
// Show complete SQL error and path to administrators only
// Additionally show complete error on installation or if extended debug mode is enabled
// The DEBUG constant is for development only!
- if ((isset($auth) && $auth->acl_get('a_')) || defined('IN_INSTALL') || defined('DEBUG'))
+ if ((isset($auth) && $auth->acl_get('a_')) || defined('IN_INSTALL') || $this->debug_sql_explain)
{
$message .= ($sql) ? '<br /><br />SQL<br /><br />' . htmlspecialchars($sql) : '';
}
diff --git a/phpBB/phpbb/db/driver/driver_interface.php b/phpBB/phpbb/db/driver/driver_interface.php
index 8b487c5d42..05ff5ef066 100644
--- a/phpBB/phpbb/db/driver/driver_interface.php
+++ b/phpBB/phpbb/db/driver/driver_interface.php
@@ -16,6 +16,20 @@ namespace phpbb\db\driver;
interface driver_interface
{
/**
+ * Set value for load_time debug parameter
+ *
+ * @param bool $value
+ */
+ public function set_debug_load_time($value);
+
+ /**
+ * Set value for sql_explain debug parameter
+ *
+ * @param bool $value
+ */
+ public function set_debug_sql_explain($value);
+
+ /**
* Gets the name of the sql layer.
*
* @return string
diff --git a/phpBB/phpbb/db/driver/factory.php b/phpBB/phpbb/db/driver/factory.php
index fb3a826254..bb6e7a2682 100644
--- a/phpBB/phpbb/db/driver/factory.php
+++ b/phpBB/phpbb/db/driver/factory.php
@@ -68,6 +68,22 @@ class factory implements driver_interface
/**
* {@inheritdoc}
*/
+ public function set_debug_load_time($value)
+ {
+ $this->get_driver()->set_debug_load_time($value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set_debug_sql_explain($value)
+ {
+ $this->get_driver()->set_debug_sql_explain($value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function get_sql_layer()
{
return $this->get_driver()->get_sql_layer();
diff --git a/phpBB/phpbb/db/driver/mssql_odbc.php b/phpBB/phpbb/db/driver/mssql_odbc.php
index 9d9ad603e0..06cdce7a15 100644
--- a/phpBB/phpbb/db/driver/mssql_odbc.php
+++ b/phpBB/phpbb/db/driver/mssql_odbc.php
@@ -151,12 +151,11 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
{
global $cache;
- // EXPLAIN only in extra debug mode
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('start', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->curtime = microtime(true);
}
@@ -172,11 +171,11 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
$this->sql_error($query);
}
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('stop', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->sql_time += microtime(true) - $this->curtime;
}
@@ -196,7 +195,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base
$this->open_queries[(int) $this->query_result] = $this->query_result;
}
}
- else if (defined('DEBUG'))
+ else if ($this->debug_sql_explain)
{
$this->sql_report('fromcache', $query);
}
diff --git a/phpBB/phpbb/db/driver/mssqlnative.php b/phpBB/phpbb/db/driver/mssqlnative.php
index a4dcac5966..30ef9d9bc4 100644
--- a/phpBB/phpbb/db/driver/mssqlnative.php
+++ b/phpBB/phpbb/db/driver/mssqlnative.php
@@ -123,12 +123,11 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
{
global $cache;
- // EXPLAIN only in extra debug mode
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('start', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->curtime = microtime(true);
}
@@ -146,11 +145,11 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
// reset options for next query
$this->query_options = array();
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('stop', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->sql_time += microtime(true) - $this->curtime;
}
@@ -170,7 +169,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base
$this->open_queries[(int) $this->query_result] = $this->query_result;
}
}
- else if (defined('DEBUG'))
+ else if ($this->debug_sql_explain)
{
$this->sql_report('fromcache', $query);
}
diff --git a/phpBB/phpbb/db/driver/mysql.php b/phpBB/phpbb/db/driver/mysql.php
deleted file mode 100644
index a94e88b331..0000000000
--- a/phpBB/phpbb/db/driver/mysql.php
+++ /dev/null
@@ -1,503 +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\db\driver;
-
-/**
-* MySQL4 Database Abstraction Layer
-* Compatible with:
-* MySQL 3.23+
-* MySQL 4.0+
-* MySQL 4.1+
-* MySQL 5.0+
-*/
-class mysql extends \phpbb\db\driver\mysql_base
-{
- var $multi_insert = true;
- var $connect_error = '';
-
- /**
- * {@inheritDoc}
- */
- function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
- {
- $this->persistency = $persistency;
- $this->user = $sqluser;
- $this->server = $sqlserver . (($port) ? ':' . $port : '');
- $this->dbname = $database;
-
- $this->sql_layer = 'mysql4';
-
- if ($this->persistency)
- {
- if (!function_exists('mysql_pconnect'))
- {
- $this->connect_error = 'mysql_pconnect function does not exist, is mysql extension installed?';
- return $this->sql_error('');
- }
- $this->db_connect_id = @mysql_pconnect($this->server, $this->user, $sqlpassword);
- }
- else
- {
- if (!function_exists('mysql_connect'))
- {
- $this->connect_error = 'mysql_connect function does not exist, is mysql extension installed?';
- return $this->sql_error('');
- }
- $this->db_connect_id = @mysql_connect($this->server, $this->user, $sqlpassword, $new_link);
- }
-
- if ($this->db_connect_id && $this->dbname != '')
- {
- if (@mysql_select_db($this->dbname, $this->db_connect_id))
- {
- // Determine what version we are using and if it natively supports UNICODE
- if (version_compare($this->sql_server_info(true), '4.1.0', '>='))
- {
- @mysql_query("SET NAMES 'utf8'", $this->db_connect_id);
-
- // enforce strict mode on databases that support it
- if (version_compare($this->sql_server_info(true), '5.0.2', '>='))
- {
- $result = @mysql_query('SELECT @@session.sql_mode AS sql_mode', $this->db_connect_id);
- if ($result)
- {
- $row = mysql_fetch_assoc($result);
- mysql_free_result($result);
- $modes = array_map('trim', explode(',', $row['sql_mode']));
- }
- else
- {
- $modes = array();
- }
-
- // TRADITIONAL includes STRICT_ALL_TABLES and STRICT_TRANS_TABLES
- if (!in_array('TRADITIONAL', $modes))
- {
- if (!in_array('STRICT_ALL_TABLES', $modes))
- {
- $modes[] = 'STRICT_ALL_TABLES';
- }
-
- if (!in_array('STRICT_TRANS_TABLES', $modes))
- {
- $modes[] = 'STRICT_TRANS_TABLES';
- }
- }
-
- $mode = implode(',', $modes);
- @mysql_query("SET SESSION sql_mode='{$mode}'", $this->db_connect_id);
- }
- }
- else if (version_compare($this->sql_server_info(true), '4.0.0', '<'))
- {
- $this->sql_layer = 'mysql';
- }
-
- return $this->db_connect_id;
- }
- }
-
- return $this->sql_error('');
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_server_info($raw = false, $use_cache = true)
- {
- global $cache;
-
- if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('mysql_version')) === false)
- {
- $result = @mysql_query('SELECT VERSION() AS version', $this->db_connect_id);
- if ($result)
- {
- $row = mysql_fetch_assoc($result);
- mysql_free_result($result);
-
- $this->sql_server_version = $row['version'];
-
- if (!empty($cache) && $use_cache)
- {
- $cache->put('mysql_version', $this->sql_server_version);
- }
- }
- }
-
- return ($raw) ? $this->sql_server_version : 'MySQL ' . $this->sql_server_version;
- }
-
- /**
- * SQL Transaction
- * @access private
- */
- function _sql_transaction($status = 'begin')
- {
- switch ($status)
- {
- case 'begin':
- return @mysql_query('BEGIN', $this->db_connect_id);
- break;
-
- case 'commit':
- return @mysql_query('COMMIT', $this->db_connect_id);
- break;
-
- case 'rollback':
- return @mysql_query('ROLLBACK', $this->db_connect_id);
- break;
- }
-
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_query($query = '', $cache_ttl = 0)
- {
- if ($query != '')
- {
- global $cache;
-
- // EXPLAIN only in extra debug mode
- if (defined('DEBUG'))
- {
- $this->sql_report('start', $query);
- }
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
- {
- $this->curtime = microtime(true);
- }
-
- $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
- $this->sql_add_num_queries($this->query_result);
-
- if ($this->query_result === false)
- {
- if (($this->query_result = @mysql_query($query, $this->db_connect_id)) === false)
- {
- $this->sql_error($query);
- }
-
- if (defined('DEBUG'))
- {
- $this->sql_report('stop', $query);
- }
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
- {
- $this->sql_time += microtime(true) - $this->curtime;
- }
-
- if (!$this->query_result)
- {
- return false;
- }
-
- if ($cache && $cache_ttl)
- {
- $this->open_queries[(int) $this->query_result] = $this->query_result;
- $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
- }
- else if (strpos($query, 'SELECT') === 0)
- {
- $this->open_queries[(int) $this->query_result] = $this->query_result;
- }
- }
- else if (defined('DEBUG'))
- {
- $this->sql_report('fromcache', $query);
- }
- }
- else
- {
- return false;
- }
-
- return $this->query_result;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_affectedrows()
- {
- if ($this->db_connect_id)
- {
- // We always want the number of matched rows
- // instead of changed rows, when running an update.
- // So when mysql_info() returns the number of matched rows
- // we return that one instead of mysql_affected_rows()
- $mysql_info = @mysql_info($this->db_connect_id);
- if ($mysql_info !== false)
- {
- $match = array();
- preg_match('#^Rows matched: (\d)+ Changed: (\d)+ Warnings: (\d)+$#', $mysql_info, $match);
- if (isset($match[1]))
- {
- return $match[1];
- }
- }
-
- return @mysql_affected_rows($this->db_connect_id);
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_fetchrow($query_id = false)
- {
- global $cache;
-
- if ($query_id === false)
- {
- $query_id = $this->query_result;
- }
-
- if ($cache && $cache->sql_exists($query_id))
- {
- return $cache->sql_fetchrow($query_id);
- }
-
- return ($query_id) ? mysql_fetch_assoc($query_id) : false;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_rowseek($rownum, &$query_id)
- {
- global $cache;
-
- if ($query_id === false)
- {
- $query_id = $this->query_result;
- }
-
- if ($cache && $cache->sql_exists($query_id))
- {
- return $cache->sql_rowseek($rownum, $query_id);
- }
-
- return ($query_id !== false) ? @mysql_data_seek($query_id, $rownum) : false;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_nextid()
- {
- return ($this->db_connect_id) ? @mysql_insert_id($this->db_connect_id) : false;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_freeresult($query_id = false)
- {
- global $cache;
-
- if ($query_id === false)
- {
- $query_id = $this->query_result;
- }
-
- if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
- {
- return $cache->sql_freeresult($query_id);
- }
-
- if (isset($this->open_queries[(int) $query_id]))
- {
- unset($this->open_queries[(int) $query_id]);
- return mysql_free_result($query_id);
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- function sql_escape($msg)
- {
- if (!$this->db_connect_id)
- {
- return @mysql_real_escape_string($msg);
- }
-
- return @mysql_real_escape_string($msg, $this->db_connect_id);
- }
-
- /**
- * return sql error array
- * @access private
- */
- function _sql_error()
- {
- if ($this->db_connect_id)
- {
- $error = array(
- 'message' => @mysql_error($this->db_connect_id),
- 'code' => @mysql_errno($this->db_connect_id),
- );
- }
- else if (function_exists('mysql_error'))
- {
- $error = array(
- 'message' => @mysql_error(),
- 'code' => @mysql_errno(),
- );
- }
- else
- {
- $error = array(
- 'message' => $this->connect_error,
- 'code' => '',
- );
- }
-
- return $error;
- }
-
- /**
- * Close sql connection
- * @access private
- */
- function _sql_close()
- {
- return @mysql_close($this->db_connect_id);
- }
-
- /**
- * Build db-specific report
- * @access private
- */
- function _sql_report($mode, $query = '')
- {
- static $test_prof;
-
- // current detection method, might just switch to see the existance of INFORMATION_SCHEMA.PROFILING
- if ($test_prof === null)
- {
- $test_prof = false;
- if (version_compare($this->sql_server_info(true), '5.0.37', '>=') && version_compare($this->sql_server_info(true), '5.1', '<'))
- {
- $test_prof = true;
- }
- }
-
- switch ($mode)
- {
- case 'start':
-
- $explain_query = $query;
- if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
- {
- $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
- }
- else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
- {
- $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
- }
-
- if (preg_match('/^SELECT/', $explain_query))
- {
- $html_table = false;
-
- // begin profiling
- if ($test_prof)
- {
- @mysql_query('SET profiling = 1;', $this->db_connect_id);
- }
-
- if ($result = @mysql_query("EXPLAIN $explain_query", $this->db_connect_id))
- {
- while ($row = mysql_fetch_assoc($result))
- {
- $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
- }
- mysql_free_result($result);
- }
-
- if ($html_table)
- {
- $this->html_hold .= '</table>';
- }
-
- if ($test_prof)
- {
- $html_table = false;
-
- // get the last profile
- if ($result = @mysql_query('SHOW PROFILE ALL;', $this->db_connect_id))
- {
- $this->html_hold .= '<br />';
- while ($row = mysql_fetch_assoc($result))
- {
- // make <unknown> HTML safe
- if (!empty($row['Source_function']))
- {
- $row['Source_function'] = str_replace(array('<', '>'), array('&lt;', '&gt;'), $row['Source_function']);
- }
-
- // remove unsupported features
- foreach ($row as $key => $val)
- {
- if ($val === null)
- {
- unset($row[$key]);
- }
- }
- $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
- }
- mysql_free_result($result);
- }
-
- if ($html_table)
- {
- $this->html_hold .= '</table>';
- }
-
- @mysql_query('SET profiling = 0;', $this->db_connect_id);
- }
- }
-
- break;
-
- case 'fromcache':
- $endtime = explode(' ', microtime());
- $endtime = $endtime[0] + $endtime[1];
-
- $result = @mysql_query($query, $this->db_connect_id);
- if ($result)
- {
- while ($void = mysql_fetch_assoc($result))
- {
- // Take the time spent on parsing rows into account
- }
- mysql_free_result($result);
- }
-
- $splittime = explode(' ', microtime());
- $splittime = $splittime[0] + $splittime[1];
-
- $this->sql_report('record_fromcache', $query, $endtime, $splittime);
-
- break;
- }
- }
-}
diff --git a/phpBB/phpbb/db/driver/mysqli.php b/phpBB/phpbb/db/driver/mysqli.php
index b429ad97aa..0c1c063262 100644
--- a/phpBB/phpbb/db/driver/mysqli.php
+++ b/phpBB/phpbb/db/driver/mysqli.php
@@ -176,12 +176,11 @@ class mysqli extends \phpbb\db\driver\mysql_base
{
global $cache;
- // EXPLAIN only in extra debug mode
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('start', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->curtime = microtime(true);
}
@@ -196,11 +195,11 @@ class mysqli extends \phpbb\db\driver\mysql_base
$this->sql_error($query);
}
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('stop', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->sql_time += microtime(true) - $this->curtime;
}
@@ -215,7 +214,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
$this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
}
}
- else if (defined('DEBUG'))
+ else if ($this->debug_sql_explain)
{
$this->sql_report('fromcache', $query);
}
@@ -376,7 +375,7 @@ class mysqli extends \phpbb\db\driver\mysql_base
{
static $test_prof;
- // current detection method, might just switch to see the existance of INFORMATION_SCHEMA.PROFILING
+ // current detection method, might just switch to see the existence of INFORMATION_SCHEMA.PROFILING
if ($test_prof === null)
{
$test_prof = false;
diff --git a/phpBB/phpbb/db/driver/oracle.php b/phpBB/phpbb/db/driver/oracle.php
index 5fd14709f8..f2a0bb557a 100644
--- a/phpBB/phpbb/db/driver/oracle.php
+++ b/phpBB/phpbb/db/driver/oracle.php
@@ -246,12 +246,11 @@ class oracle extends \phpbb\db\driver\driver
{
global $cache;
- // EXPLAIN only in extra debug mode
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('start', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->curtime = microtime(true);
}
@@ -428,11 +427,11 @@ class oracle extends \phpbb\db\driver\driver
}
}
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('stop', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->sql_time += microtime(true) - $this->curtime;
}
@@ -452,7 +451,7 @@ class oracle extends \phpbb\db\driver\driver
$this->open_queries[(int) $this->query_result] = $this->query_result;
}
}
- else if (defined('DEBUG'))
+ else if ($this->debug_sql_explain)
{
$this->sql_report('fromcache', $query);
}
diff --git a/phpBB/phpbb/db/driver/postgres.php b/phpBB/phpbb/db/driver/postgres.php
index 44476612c3..ed330bc540 100644
--- a/phpBB/phpbb/db/driver/postgres.php
+++ b/phpBB/phpbb/db/driver/postgres.php
@@ -173,12 +173,11 @@ class postgres extends \phpbb\db\driver\driver
{
global $cache;
- // EXPLAIN only in extra debug mode
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('start', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->curtime = microtime(true);
}
@@ -194,11 +193,11 @@ class postgres extends \phpbb\db\driver\driver
$this->sql_error($query);
}
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('stop', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->sql_time += microtime(true) - $this->curtime;
}
@@ -218,7 +217,7 @@ class postgres extends \phpbb\db\driver\driver
$this->open_queries[(int) $this->query_result] = $this->query_result;
}
}
- else if (defined('DEBUG'))
+ else if ($this->debug_sql_explain)
{
$this->sql_report('fromcache', $query);
}
diff --git a/phpBB/phpbb/db/driver/sqlite3.php b/phpBB/phpbb/db/driver/sqlite3.php
index 0508500c52..43906f1b58 100644
--- a/phpBB/phpbb/db/driver/sqlite3.php
+++ b/phpBB/phpbb/db/driver/sqlite3.php
@@ -118,12 +118,11 @@ class sqlite3 extends \phpbb\db\driver\driver
{
global $cache;
- // EXPLAIN only in extra debug mode
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('start', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->curtime = microtime(true);
}
@@ -156,11 +155,11 @@ class sqlite3 extends \phpbb\db\driver\driver
}
}
- if (defined('DEBUG'))
+ if ($this->debug_sql_explain)
{
$this->sql_report('stop', $query);
}
- else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ else if ($this->debug_load_time)
{
$this->sql_time += microtime(true) - $this->curtime;
}
@@ -175,7 +174,7 @@ class sqlite3 extends \phpbb\db\driver\driver
$this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
}
}
- else if (defined('DEBUG'))
+ else if ($this->debug_sql_explain)
{
$this->sql_report('fromcache', $query);
}
diff --git a/phpBB/phpbb/db/extractor/mysql_extractor.php b/phpBB/phpbb/db/extractor/mysql_extractor.php
index 34e309c19e..f3cb0db457 100644
--- a/phpBB/phpbb/db/extractor/mysql_extractor.php
+++ b/phpBB/phpbb/db/extractor/mysql_extractor.php
@@ -79,14 +79,7 @@ class mysql_extractor extends base_extractor
throw new extractor_not_initialized_exception();
}
- if ($this->db->get_sql_layer() === 'mysqli')
- {
- $this->write_data_mysqli($table_name);
- }
- else
- {
- $this->write_data_mysql($table_name);
- }
+ $this->write_data_mysqli($table_name);
}
/**
@@ -180,101 +173,6 @@ class mysql_extractor extends base_extractor
}
/**
- * Extracts data from database table (for MySQL driver)
- *
- * @param string $table_name name of the database table
- * @return null
- * @throws \phpbb\db\extractor\exception\extractor_not_initialized_exception when calling this function before init_extractor()
- */
- protected function write_data_mysql($table_name)
- {
- if (!$this->is_initialized)
- {
- throw new extractor_not_initialized_exception();
- }
-
- $sql = "SELECT *
- FROM $table_name";
- $result = mysql_unbuffered_query($sql, $this->db->get_db_connect_id());
-
- if ($result != false)
- {
- $fields_cnt = mysql_num_fields($result);
-
- // Get field information
- $field = array();
- for ($i = 0; $i < $fields_cnt; $i++)
- {
- $field[] = mysql_fetch_field($result, $i);
- }
- $field_set = array();
-
- for ($j = 0; $j < $fields_cnt; $j++)
- {
- $field_set[] = $field[$j]->name;
- }
-
- $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
- $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
- $fields = implode(', ', $field_set);
- $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
- $first_set = true;
- $query_len = 0;
- $max_len = get_usable_memory();
-
- while ($row = mysql_fetch_row($result))
- {
- $values = array();
- if ($first_set)
- {
- $query = $sql_data . '(';
- }
- else
- {
- $query .= ',(';
- }
-
- for ($j = 0; $j < $fields_cnt; $j++)
- {
- if (!isset($row[$j]) || is_null($row[$j]))
- {
- $values[$j] = 'NULL';
- }
- else if ($field[$j]->numeric && ($field[$j]->type !== 'timestamp'))
- {
- $values[$j] = $row[$j];
- }
- else
- {
- $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
- }
- }
- $query .= implode(', ', $values) . ')';
-
- $query_len += strlen($query);
- if ($query_len > $max_len)
- {
- $this->flush($query . ";\n\n");
- $query = '';
- $query_len = 0;
- $first_set = true;
- }
- else
- {
- $first_set = false;
- }
- }
- mysql_free_result($result);
-
- // check to make sure we have nothing left to flush
- if (!$first_set && $query)
- {
- $this->flush($query . ";\n\n");
- }
- }
- }
-
- /**
* Extracts database table structure (for MySQLi or MySQL 3.23.20+)
*
* @param string $table_name name of the database table
@@ -300,7 +198,7 @@ class mysql_extractor extends base_extractor
}
/**
- * Extracts database table structure (for MySQL verisons older than 3.23.20)
+ * Extracts database table structure (for MySQL versions older than 3.23.20)
*
* @param string $table_name name of the database table
* @return null
diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php
index 10343438b3..247ccc7a76 100644
--- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php
+++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php
@@ -117,7 +117,7 @@ class release_3_0_4_rc1 extends \phpbb\db\migration\migration
}
else
{
- // equivelant to "none", which is the "Display in user control panel" option
+ // equivalent to "none", which is the "Display in user control panel" option
$sql_ary['field_show_profile'] = 1;
}
diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php b/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php
index b1e7486e24..877cdc2fa3 100644
--- a/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php
+++ b/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php
@@ -132,7 +132,7 @@ class softdelete_p1 extends \phpbb\db\migration\migration
/*
* Using sql_case here to avoid "BIGINT UNSIGNED value is out of range" errors.
* As we update all topics in 2 queries, one broken topic would stop the conversion
- * for all topics and the surpressed error will cause the admin to not even notice it.
+ * for all topics and the suppressed error will cause the admin to not even notice it.
*/
$sql = 'UPDATE ' . $this->table_prefix . 'topics
SET topic_posts_approved = topic_replies + 1,
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/dev.php b/phpBB/phpbb/db/migration/data/v330/dev.php
new file mode 100644
index 0000000000..209f9fc7ec
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/dev.php
@@ -0,0 +1,36 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v330;
+
+class dev extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return version_compare($this->config['version'], '3.3.0-dev', '>=');
+ }
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v32x\v327',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.3.0-dev')),
+ );
+ }
+}
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/jquery_update.php b/phpBB/phpbb/db/migration/data/v330/jquery_update.php
new file mode 100644
index 0000000000..f1ac6cdd41
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/jquery_update.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\db\migration\data\v330;
+
+class jquery_update extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return $this->config['load_jquery_url'] === '//ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js';
+ }
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v330\dev',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js')),
+ );
+ }
+
+}
diff --git a/phpBB/phpbb/db/migration/data/v330/remove_attachment_flash.php b/phpBB/phpbb/db/migration/data/v330/remove_attachment_flash.php
new file mode 100644
index 0000000000..11dc43483b
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/remove_attachment_flash.php
@@ -0,0 +1,84 @@
+<?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_attachment_flash extends \phpbb\db\migration\migration
+{
+ // Following constants were deprecated in 3.3
+ // and moved from constants.php to compatibility_globals.php,
+ // thus define them as class constants
+ const ATTACHMENT_CATEGORY_FLASH = 5;
+
+ protected $cat_id = array(
+ self::ATTACHMENT_CATEGORY_FLASH,
+ );
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'remove_flash_group'))),
+ );
+ }
+
+ public function remove_flash_group()
+ {
+ // select group ids of outdated media
+ $sql = 'SELECT group_id
+ FROM ' . EXTENSION_GROUPS_TABLE . '
+ WHERE ' . $this->db->sql_in_set('cat_id', $this->cat_id);
+ $result = $this->db->sql_query($sql);
+
+ $group_ids = array();
+ while ($group_id = (int) $this->db->sql_fetchfield('group_id'))
+ {
+ $group_ids[] = $group_id;
+ }
+ $this->db->sql_freeresult($result);
+
+ // nothing to do, admin has removed all the outdated media extension groups
+ if (empty($group_ids))
+ {
+ return true;
+ }
+
+ // get the group id of downloadable files
+ $sql = 'SELECT group_id
+ FROM ' . EXTENSION_GROUPS_TABLE . "
+ WHERE group_name = 'DOWNLOADABLE_FILES'";
+ $result = $this->db->sql_query($sql);
+ $download_id = (int) $this->db->sql_fetchfield('group_id');
+ $this->db->sql_freeresult($result);
+
+ if (empty($download_id))
+ {
+ $sql = 'UPDATE ' . EXTENSIONS_TABLE . '
+ SET group_id = 0
+ WHERE ' . $this->db->sql_in_set('group_id', $group_ids);
+ }
+ else
+ {
+ // move outdated media extensions to downloadable files
+ $sql = 'UPDATE ' . EXTENSIONS_TABLE . "
+ SET group_id = $download_id" . '
+ WHERE ' . $this->db->sql_in_set('group_id', $group_ids);
+ }
+
+ $this->db->sql_query($sql);
+
+ // delete the now empty, outdated media extension groups
+ $sql = 'DELETE FROM ' . EXTENSION_GROUPS_TABLE . '
+ WHERE ' . $this->db->sql_in_set('group_id', $group_ids);
+ $this->db->sql_query($sql);
+ }
+}
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/remove_max_pass_chars.php b/phpBB/phpbb/db/migration/data/v330/remove_max_pass_chars.php
new file mode 100644
index 0000000000..10e5ee385d
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/remove_max_pass_chars.php
@@ -0,0 +1,43 @@
+<?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_max_pass_chars extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return !$this->config->offsetExists('max_pass_chars');
+ }
+
+ public static function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v330\dev',
+ ];
+ }
+
+ public function update_data()
+ {
+ return [
+ ['config.remove', ['max_pass_chars']],
+ ];
+ }
+
+ public function revert_data()
+ {
+ return [
+ ['config.add', ['max_pass_chars', 100]],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v330/reset_password.php b/phpBB/phpbb/db/migration/data/v330/reset_password.php
new file mode 100644
index 0000000000..953d478ccc
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/reset_password.php
@@ -0,0 +1,48 @@
+<?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 reset_password extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v330\dev',
+ ];
+ }
+
+ public function update_schema()
+ {
+ return [
+ 'add_columns' => [
+ $this->table_prefix . 'users' => [
+ 'reset_token' => ['VCHAR:64', '', 'after' => 'user_actkey'],
+ 'reset_token_expiration' => ['TIMESTAMP', 0, 'after' => 'reset_token'],
+ ],
+ ],
+ ];
+ }
+
+ public function revert_schema()
+ {
+ return [
+ 'drop_columns' => [
+ $this->table_prefix . 'users' => [
+ 'reset_token',
+ 'reset_token_expiration',
+ ],
+ ],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v330/v330b1.php b/phpBB/phpbb/db/migration/data/v330/v330b1.php
new file mode 100644
index 0000000000..3df44504fc
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/v330b1.php
@@ -0,0 +1,41 @@
+<?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 v330b1 extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return version_compare($this->config['version'], '3.3.0-b1', '>=');
+ }
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v330\jquery_update',
+ '\phpbb\db\migration\data\v330\reset_password',
+ '\phpbb\db\migration\data\v330\remove_attachment_flash',
+ '\phpbb\db\migration\data\v330\remove_max_pass_chars',
+ '\phpbb\db\migration\data\v32x\v328',
+ '\phpbb\db\migration\data\v330\dev',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.3.0-b1')),
+ );
+ }
+}
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/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php
index e5133c8152..93c338437e 100644
--- a/phpBB/phpbb/db/migration/tool/module.php
+++ b/phpBB/phpbb/db/migration/tool/module.php
@@ -509,7 +509,7 @@ class module implements \phpbb\db\migration\tool\tool_interface
* Get parent module id
*
* @param string|int $parent_id The parent module_id|module_langname
- * @param int|string|array $data The module_id, module_langname for existance checking or module data array for adding
+ * @param int|string|array $data The module_id, module_langname for existence checking or module data array for adding
* @param bool $throw_exception The flag indicating if exception should be thrown on error
* @return mixed The int parent module_id, an array of int parent module_id values or false
* @throws \phpbb\db\migration\exception
diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php
index 2b0c66fc58..3a1ee758cf 100644
--- a/phpBB/phpbb/db/migrator.php
+++ b/phpBB/phpbb/db/migrator.php
@@ -784,7 +784,7 @@ class migrator
{
return array(
$parameters[0],
- array($last_result),
+ isset($parameters[1]) ? array_merge($parameters[1], array($last_result)) : array($last_result),
);
}
break;
diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php
index cbedf9a5c4..29f816a869 100644
--- a/phpBB/phpbb/db/tools/mssql.php
+++ b/phpBB/phpbb/db/tools/mssql.php
@@ -194,7 +194,7 @@ class mssql extends tools
$primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set'];
}
- // create sequence DDL based off of the existance of auto incrementing columns
+ // create sequence DDL based off of the existence of auto incrementing columns
if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment'])
{
$create_sequence = $column_name;
diff --git a/phpBB/phpbb/db/tools/postgres.php b/phpBB/phpbb/db/tools/postgres.php
index 077d6e06f9..276ac135be 100644
--- a/phpBB/phpbb/db/tools/postgres.php
+++ b/phpBB/phpbb/db/tools/postgres.php
@@ -141,7 +141,7 @@ class postgres extends tools
$primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set'];
}
- // create sequence DDL based off of the existance of auto incrementing columns
+ // create sequence DDL based off of the existence of auto incrementing columns
if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment'])
{
$create_sequence = $column_name;
diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php
index c3352a1f66..1250a8901d 100644
--- a/phpBB/phpbb/db/tools/tools.php
+++ b/phpBB/phpbb/db/tools/tools.php
@@ -74,37 +74,6 @@ class tools implements tools_interface
'VARBINARY' => 'varbinary(255)',
),
- 'mysql_40' => array(
- 'INT:' => 'int(%d)',
- 'BINT' => 'bigint(20)',
- 'ULINT' => 'INT(10) UNSIGNED',
- 'UINT' => 'mediumint(8) UNSIGNED',
- 'UINT:' => 'int(%d) UNSIGNED',
- 'TINT:' => 'tinyint(%d)',
- 'USINT' => 'smallint(4) UNSIGNED',
- 'BOOL' => 'tinyint(1) UNSIGNED',
- 'VCHAR' => 'varbinary(255)',
- 'VCHAR:' => 'varbinary(%d)',
- 'CHAR:' => 'binary(%d)',
- 'XSTEXT' => 'blob',
- 'XSTEXT_UNI'=> 'blob',
- 'STEXT' => 'blob',
- 'STEXT_UNI' => 'blob',
- 'TEXT' => 'blob',
- 'TEXT_UNI' => 'blob',
- 'MTEXT' => 'mediumblob',
- 'MTEXT_UNI' => 'mediumblob',
- 'TIMESTAMP' => 'int(11) UNSIGNED',
- 'DECIMAL' => 'decimal(5,2)',
- 'DECIMAL:' => 'decimal(%d,2)',
- 'PDECIMAL' => 'decimal(6,3)',
- 'PDECIMAL:' => 'decimal(%d,3)',
- 'VCHAR_UNI' => 'blob',
- 'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')),
- 'VCHAR_CI' => 'blob',
- 'VARBINARY' => 'varbinary(255)',
- ),
-
'oracle' => array(
'INT:' => 'number(%d)',
'BINT' => 'number(20)',
@@ -197,21 +166,6 @@ class tools implements tools_interface
// Determine mapping database type
switch ($this->db->get_sql_layer())
{
- case 'mysql':
- $this->sql_layer = 'mysql_40';
- break;
-
- case 'mysql4':
- if (version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
- {
- $this->sql_layer = 'mysql_41';
- }
- else
- {
- $this->sql_layer = 'mysql_40';
- }
- break;
-
case 'mysqli':
$this->sql_layer = 'mysql_41';
break;
@@ -240,8 +194,6 @@ class tools implements tools_interface
{
switch ($this->db->get_sql_layer())
{
- case 'mysql':
- case 'mysql4':
case 'mysqli':
$sql = 'SHOW TABLES';
break;
@@ -335,7 +287,7 @@ class tools implements tools_interface
$primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set'];
}
- // create sequence DDL based off of the existance of auto incrementing columns
+ // create sequence DDL based off of the existence of auto incrementing columns
if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment'])
{
$create_sequence = $column_name;
@@ -359,7 +311,6 @@ class tools implements tools_interface
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
case 'sqlite3':
$table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')';
@@ -381,7 +332,6 @@ class tools implements tools_interface
$statements[] = $table_sql;
break;
- case 'mysql_40':
case 'sqlite3':
$table_sql .= "\n);";
$statements[] = $table_sql;
@@ -834,7 +784,6 @@ class tools implements tools_interface
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
$sql = "SHOW COLUMNS FROM $table_name";
break;
@@ -911,7 +860,6 @@ class tools implements tools_interface
{
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
$sql = 'SHOW KEYS
FROM ' . $table_name;
@@ -936,7 +884,7 @@ class tools implements tools_interface
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
- if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique'])
+ if ($this->sql_layer == 'mysql_41' && !$row['Non_unique'])
{
continue;
}
@@ -971,7 +919,6 @@ class tools implements tools_interface
{
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
$sql = 'SHOW KEYS
FROM ' . $table_name;
@@ -996,7 +943,7 @@ class tools implements tools_interface
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
- if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && ($row['Non_unique'] || $row[$col] == 'PRIMARY'))
+ if ($this->sql_layer == 'mysql_41' && ($row['Non_unique'] || $row[$col] == 'PRIMARY'))
{
continue;
}
@@ -1094,7 +1041,6 @@ class tools implements tools_interface
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
$sql .= " {$column_type} ";
@@ -1248,7 +1194,6 @@ class tools implements tools_interface
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
$after = (!empty($column_data['after'])) ? ' AFTER ' . $column_data['after'] : '';
$statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql'] . $after;
@@ -1281,7 +1226,6 @@ class tools implements tools_interface
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
$statements[] = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`';
break;
@@ -1360,7 +1304,6 @@ class tools implements tools_interface
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
$index_name = $this->check_index_name_length($table_name, $index_name, false);
$statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name;
@@ -1422,7 +1365,6 @@ class tools implements tools_interface
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
$statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')';
break;
@@ -1500,7 +1442,6 @@ class tools implements tools_interface
$statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
break;
- case 'mysql_40':
case 'mysql_41':
$index_name = $this->check_index_name_length($table_name, $index_name);
$statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX ' . $index_name . '(' . implode(', ', $column) . ')';
@@ -1517,11 +1458,7 @@ class tools implements tools_interface
{
$statements = array();
- // remove index length unless MySQL4
- if ('mysql_40' != $this->sql_layer)
- {
- $column = preg_replace('#:.*$#', '', $column);
- }
+ $column = preg_replace('#:.*$#', '', $column);
switch ($this->sql_layer)
{
@@ -1531,17 +1468,6 @@ class tools implements tools_interface
$statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
break;
- case 'mysql_40':
- // add index size to definition as required by MySQL4
- foreach ($column as $i => $col)
- {
- if (false !== strpos($col, ':'))
- {
- list($col, $index_size) = explode(':', $col);
- $column[$i] = "$col($index_size)";
- }
- }
- // no break
case 'mysql_41':
$index_name = $this->check_index_name_length($table_name, $index_name);
$statements[] = 'ALTER TABLE ' . $table_name . ' ADD INDEX ' . $index_name . ' (' . implode(', ', $column) . ')';
@@ -1609,7 +1535,6 @@ class tools implements tools_interface
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
$sql = 'SHOW KEYS
FROM ' . $table_name;
@@ -1634,7 +1559,7 @@ class tools implements tools_interface
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
- if (($this->sql_layer == 'mysql_40' || $this->sql_layer == 'mysql_41') && !$row['Non_unique'])
+ if ($this->sql_layer == 'mysql_41' && !$row['Non_unique'])
{
continue;
}
@@ -1677,7 +1602,6 @@ class tools implements tools_interface
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
$statements[] = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql'];
break;
@@ -1826,7 +1750,6 @@ class tools implements tools_interface
{
switch ($this->sql_layer)
{
- case 'mysql_40':
case 'mysql_41':
case 'sqlite3':
// Not supported
diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php
index 8c1ce8bde2..70ceb9b5e3 100644
--- a/phpBB/phpbb/di/container_builder.php
+++ b/phpBB/phpbb/di/container_builder.php
@@ -158,13 +158,18 @@ class container_builder
}
else
{
- $this->container_extensions = array(new extension\core($this->get_config_path()));
+ $this->container_extensions = [
+ new extension\core($this->get_config_path()),
+ ];
if ($this->use_extensions)
{
$this->load_extensions();
}
+ // Add tables extension after all extensions
+ $this->container_extensions[] = new extension\tables();
+
// Inject the config
if ($this->config_php_file)
{
@@ -481,7 +486,7 @@ class container_builder
$cached_container_dump = $dumper->dump(array(
'class' => 'phpbb_cache_container',
- 'base_class' => 'Symfony\\Component\\DependencyInjection\\ContainerBuilder',
+ 'base_class' => 'Symfony\\Component\\DependencyInjection\\Container',
));
$cache->write($cached_container_dump, $this->container->getResources());
diff --git a/phpBB/phpbb/di/extension/container_configuration.php b/phpBB/phpbb/di/extension/container_configuration.php
index 4585d6509e..57e7ef6ca6 100644
--- a/phpBB/phpbb/di/extension/container_configuration.php
+++ b/phpBB/phpbb/di/extension/container_configuration.php
@@ -31,10 +31,15 @@ class container_configuration implements ConfigurationInterface
$rootNode
->children()
->booleanNode('require_dev_dependencies')->defaultValue(false)->end()
+ ->booleanNode('allow_install_dir')->defaultValue(false)->end()
->arrayNode('debug')
->addDefaultsIfNotSet()
->children()
->booleanNode('exceptions')->defaultValue(false)->end()
+ ->booleanNode('load_time')->defaultValue(false)->end()
+ ->booleanNode('sql_explain')->defaultValue(false)->end()
+ ->booleanNode('memory')->defaultValue(false)->end()
+ ->booleanNode('show_errors')->defaultValue(false)->end()
->end()
->end()
->arrayNode('twig')
@@ -45,6 +50,12 @@ class container_configuration implements ConfigurationInterface
->booleanNode('enable_debug_extension')->defaultValue(false)->end()
->end()
->end()
+ ->arrayNode('session')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->booleanNode('log_errors')->defaultValue(false)->end()
+ ->end()
+ ->end()
->end()
;
return $treeBuilder;
diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php
index 67150f0103..0497c90e2a 100644
--- a/phpBB/phpbb/di/extension/core.php
+++ b/phpBB/phpbb/di/extension/core.php
@@ -71,6 +71,8 @@ class core extends Extension
}
}
+ $container->setParameter('allow_install_dir', $config['allow_install_dir']);
+
// Set the Twig options if defined in the environment
$definition = $container->getDefinition('template.twig.environment');
$twig_environment_options = $definition->getArgument(static::TWIG_OPTIONS_POSITION);
@@ -97,6 +99,12 @@ class core extends Extension
{
$container->setParameter('debug.' . $name, $value);
}
+
+ // Set the log options
+ foreach ($config['session'] as $name => $value)
+ {
+ $container->setParameter('session.' . $name, $value);
+ }
}
/**
diff --git a/phpBB/phpbb/di/extension/tables.php b/phpBB/phpbb/di/extension/tables.php
new file mode 100644
index 0000000000..40684b6038
--- /dev/null
+++ b/phpBB/phpbb/di/extension/tables.php
@@ -0,0 +1,59 @@
+<?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\di\extension;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+
+/**
+ * Container tables extension
+ */
+class tables extends Extension
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function load(array $configs, ContainerBuilder $container)
+ {
+ // Tables is a reserved parameter and will be overwritten at all times
+ $tables = [];
+
+ // Add access via 'tables' parameter to acquire array with all tables
+ $parameterBag = $container->getParameterBag();
+ $parameters = $parameterBag->all();
+ foreach ($parameters as $parameter_name => $parameter_value)
+ {
+ if (!preg_match('/tables\.(.+)/', $parameter_name, $matches))
+ {
+ continue;
+ }
+
+ $tables[$matches[1]] = $parameter_value;
+ }
+
+ $container->setParameter('tables', $tables);
+ }
+
+ /**
+ * Returns the recommended alias to use in XML.
+ *
+ * This alias is also the mandatory prefix to use when using YAML.
+ *
+ * @return string The alias
+ */
+ public function getAlias()
+ {
+ return 'tables';
+ }
+}
diff --git a/phpBB/phpbb/di/service_collection.php b/phpBB/phpbb/di/service_collection.php
index 8e9175e204..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);
}
/**
@@ -103,4 +88,35 @@ class service_collection extends \ArrayObject
{
return $this->service_classes;
}
+
+ /**
+ * Returns the service associated to a class
+ *
+ * @return mixed
+ * @throw \RuntimeException if the
+ */
+ public function get_by_class($class)
+ {
+ $service_id = null;
+
+ foreach ($this->service_classes as $id => $service_class)
+ {
+ if ($service_class === $class)
+ {
+ if ($service_id !== null)
+ {
+ throw new \RuntimeException('More than one service definitions found for class "'.$class.'" in collection.');
+ }
+
+ $service_id = $id;
+ }
+ }
+
+ if ($service_id === null)
+ {
+ throw new \RuntimeException('No service found for class "'.$class.'" in collection.');
+ }
+
+ return $this->offsetGet($service_id);
+ }
}
diff --git a/phpBB/phpbb/extension/extension_interface.php b/phpBB/phpbb/extension/extension_interface.php
index 6a6b6adb8f..46072d420c 100644
--- a/phpBB/phpbb/extension/extension_interface.php
+++ b/phpBB/phpbb/extension/extension_interface.php
@@ -22,7 +22,8 @@ interface extension_interface
/**
* Indicate whether or not the extension can be enabled.
*
- * @return bool
+ * @return bool|array True if extension is enableable, array of reasons
+ * if not, false for generic reason.
*/
public function is_enableable();
diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php
index 4b4109bd85..1ce8425fff 100644
--- a/phpBB/phpbb/extension/manager.php
+++ b/phpBB/phpbb/extension/manager.php
@@ -161,6 +161,47 @@ class manager
}
/**
+ * Update the database entry for an extension
+ *
+ * @param string $name Extension name to update
+ * @param array $data Data to update in the database
+ * @param string $action Action to perform, by default 'update', may be also 'insert' or 'delete'
+ */
+ protected function update_state($name, $data, $action = 'update')
+ {
+ switch ($action)
+ {
+ case 'insert':
+ $this->extensions[$name] = $data;
+ $this->extensions[$name]['ext_path'] = $this->get_extension_path($name);
+ ksort($this->extensions);
+ $sql = 'INSERT INTO ' . $this->extension_table . ' ' . $this->db->sql_build_array('INSERT', $data);
+ $this->db->sql_query($sql);
+ break;
+
+ case 'update':
+ $this->extensions[$name] = array_merge($this->extensions[$name], $data);
+ $sql = 'UPDATE ' . $this->extension_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $data) . "
+ WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
+ $this->db->sql_query($sql);
+ break;
+
+ case 'delete':
+ unset($this->extensions[$name]);
+ $sql = 'DELETE FROM ' . $this->extension_table . "
+ WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
+ $this->db->sql_query($sql);
+ break;
+ }
+
+ if ($this->cache)
+ {
+ $this->cache->purge();
+ }
+ }
+
+ /**
* Runs a step of the extension enabling process.
*
* Allows the exentension to enable in a long running script that works
@@ -197,35 +238,7 @@ class manager
'ext_state' => serialize($state),
);
- $this->extensions[$name] = $extension_data;
- $this->extensions[$name]['ext_path'] = $this->get_extension_path($extension_data['ext_name']);
- ksort($this->extensions);
-
- $sql = 'SELECT COUNT(ext_name) as row_count
- FROM ' . $this->extension_table . "
- WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
- $result = $this->db->sql_query($sql);
- $count = $this->db->sql_fetchfield('row_count');
- $this->db->sql_freeresult($result);
-
- if ($count)
- {
- $sql = 'UPDATE ' . $this->extension_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
- WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
- $this->db->sql_query($sql);
- }
- else
- {
- $sql = 'INSERT INTO ' . $this->extension_table . '
- ' . $this->db->sql_build_array('INSERT', $extension_data);
- $this->db->sql_query($sql);
- }
-
- if ($this->cache)
- {
- $this->cache->purge();
- }
+ $this->update_state($name, $extension_data, $this->is_configured($name) ? 'update' : 'insert');
if ($active)
{
@@ -272,46 +285,15 @@ class manager
$extension = $this->get_extension($name);
$state = $extension->disable_step($old_state);
-
- // continue until the state is false
- if ($state !== false)
- {
- $extension_data = array(
- 'ext_state' => serialize($state),
- );
- $this->extensions[$name]['ext_state'] = serialize($state);
-
- $sql = 'UPDATE ' . $this->extension_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
- WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
- $this->db->sql_query($sql);
-
- if ($this->cache)
- {
- $this->cache->purge();
- }
-
- return true;
- }
+ $active = ($state !== false);
$extension_data = array(
- 'ext_active' => false,
- 'ext_state' => serialize(false),
+ 'ext_active' => $active,
+ 'ext_state' => serialize($state),
);
- $this->extensions[$name]['ext_active'] = false;
- $this->extensions[$name]['ext_state'] = serialize(false);
+ $this->update_state($name, $extension_data);
- $sql = 'UPDATE ' . $this->extension_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
- WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
- $this->db->sql_query($sql);
-
- if ($this->cache)
- {
- $this->cache->purge();
- }
-
- return false;
+ return $active;
}
/**
@@ -357,40 +339,16 @@ class manager
$extension = $this->get_extension($name);
$state = $extension->purge_step($old_state);
+ $purged = ($state === false);
- // continue until the state is false
- if ($state !== false)
- {
- $extension_data = array(
- 'ext_state' => serialize($state),
- );
- $this->extensions[$name]['ext_state'] = serialize($state);
-
- $sql = 'UPDATE ' . $this->extension_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
- WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
- $this->db->sql_query($sql);
-
- if ($this->cache)
- {
- $this->cache->purge();
- }
-
- return true;
- }
-
- unset($this->extensions[$name]);
-
- $sql = 'DELETE FROM ' . $this->extension_table . "
- WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
- $this->db->sql_query($sql);
+ $extension_data = array(
+ 'ext_state' => serialize($state),
+ );
- if ($this->cache)
- {
- $this->cache->purge();
- }
+ $this->update_state($name, $extension_data, $purged ? 'delete' : 'update');
- return false;
+ // continue until the state is false
+ return !$purged;
}
/**
diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php
index ea9ee97b9d..ee7fe177f5 100644
--- a/phpBB/phpbb/feed/topics_active.php
+++ b/phpBB/phpbb/feed/topics_active.php
@@ -17,7 +17,7 @@ namespace phpbb\feed;
* Active Topics feed
*
* This will give you the last {$this->num_items} topics
- * with replies made withing the last {$this->sort_days} days
+ * with replies made within the last {$this->sort_days} days
* including the last post.
*/
class topics_active extends topic_base
diff --git a/phpBB/phpbb/files/filespec.php b/phpBB/phpbb/files/filespec.php
index 6847bca4cb..1e6771a3a4 100644
--- a/phpBB/phpbb/files/filespec.php
+++ b/phpBB/phpbb/files/filespec.php
@@ -420,7 +420,7 @@ class filespec
return false;
}
- $upload_mode = ($this->php_ini->getBool('open_basedir') || $this->php_ini->getBool('safe_mode')) ? 'move' : 'copy';
+ $upload_mode = ($this->php_ini->getBool('open_basedir')) ? 'move' : 'copy';
$upload_mode = ($this->local) ? 'local' : $upload_mode;
$this->destination_file = $this->destination_path . '/' . utf8_basename($this->realname);
diff --git a/phpBB/phpbb/filesystem.php b/phpBB/phpbb/filesystem.php
index af56d78845..6ac9459331 100644
--- a/phpBB/phpbb/filesystem.php
+++ b/phpBB/phpbb/filesystem.php
@@ -14,7 +14,7 @@
namespace phpbb;
/**
- * @deprecated 3.2.0-dev (To be removed 3.3.0) use \phpbb\filesystem\filesystem instead
+ * @deprecated 3.2.0-dev (To be removed 4.0.0) use \phpbb\filesystem\filesystem instead
*/
class filesystem extends \phpbb\filesystem\filesystem
{
diff --git a/phpBB/phpbb/filesystem/filesystem.php b/phpBB/phpbb/filesystem/filesystem.php
index c5be284d8c..9acead0876 100644
--- a/phpBB/phpbb/filesystem/filesystem.php
+++ b/phpBB/phpbb/filesystem/filesystem.php
@@ -67,7 +67,7 @@ class filesystem implements filesystem_interface
$error = trim($e->getMessage());
$file = substr($error, strrpos($error, ' '));
- throw new filesystem_exception('CANNOT_CHANGE_FILE_GROUP', $file, array(), $e);
+ throw new filesystem_exception('FILESYSTEM_CANNOT_CHANGE_FILE_GROUP', $file, array(), $e);
}
}
@@ -124,14 +124,14 @@ class filesystem implements filesystem_interface
{
if (true !== @chmod($file, $dir_perm))
{
- throw new filesystem_exception('CANNOT_CHANGE_FILE_PERMISSIONS', $file, array());
+ throw new filesystem_exception('FILESYSTEM_CANNOT_CHANGE_FILE_PERMISSIONS', $file, array());
}
}
else if (is_file($file))
{
if (true !== @chmod($file, $file_perm))
{
- throw new filesystem_exception('CANNOT_CHANGE_FILE_PERMISSIONS', $file, array());
+ throw new filesystem_exception('FILESYSTEM_CANNOT_CHANGE_FILE_PERMISSIONS', $file, array());
}
}
}
@@ -153,7 +153,7 @@ class filesystem implements filesystem_interface
$error = trim($e->getMessage());
$file = substr($error, strrpos($error, ' '));
- throw new filesystem_exception('CANNOT_CHANGE_FILE_GROUP', $file, array(), $e);
+ throw new filesystem_exception('FILESYSTEM_CANNOT_CHANGE_FILE_GROUP', $file, array(), $e);
}
}
@@ -195,7 +195,7 @@ class filesystem implements filesystem_interface
}
catch (\Symfony\Component\Filesystem\Exception\IOException $e)
{
- throw new filesystem_exception('CANNOT_COPY_FILES', '', array(), $e);
+ throw new filesystem_exception('FILESYSTEM_CANNOT_COPY_FILES', '', array(), $e);
}
}
@@ -210,7 +210,7 @@ class filesystem implements filesystem_interface
}
catch (\Symfony\Component\Filesystem\Exception\IOException $e)
{
- throw new filesystem_exception('CANNOT_DUMP_FILE', $filename, array(), $e);
+ throw new filesystem_exception('FILESYSTEM_CANNOT_DUMP_FILE', $filename, array(), $e);
}
}
@@ -322,7 +322,7 @@ class filesystem implements filesystem_interface
$msg = $e->getMessage();
$filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"'));
- throw new filesystem_exception('CANNOT_MIRROR_DIRECTORY', $filename, array(), $e);
+ throw new filesystem_exception('FILESYSTEM_CANNOT_MIRROR_DIRECTORY', $filename, array(), $e);
}
}
@@ -340,7 +340,7 @@ class filesystem implements filesystem_interface
$msg = $e->getMessage();
$filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"'));
- throw new filesystem_exception('CANNOT_CREATE_DIRECTORY', $filename, array(), $e);
+ throw new filesystem_exception('FILESYSTEM_CANNOT_CREATE_DIRECTORY', $filename, array(), $e);
}
}
@@ -525,7 +525,7 @@ class filesystem implements filesystem_interface
$error = trim($e->getMessage());
$file = substr($error, strrpos($error, ' '));
- throw new filesystem_exception('CANNOT_DELETE_FILES', $file, array(), $e);
+ throw new filesystem_exception('FILESYSTEM_CANNOT_DELETE_FILES', $file, array(), $e);
}
}
@@ -543,7 +543,7 @@ class filesystem implements filesystem_interface
$msg = $e->getMessage();
$filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"'));
- throw new filesystem_exception('CANNOT_RENAME_FILE', $filename, array(), $e);
+ throw new filesystem_exception('FILESYSTEM_CANNOT_RENAME_FILE', $filename, array(), $e);
}
}
@@ -558,7 +558,7 @@ class filesystem implements filesystem_interface
}
catch (\Symfony\Component\Filesystem\Exception\IOException $e)
{
- throw new filesystem_exception('CANNOT_CREATE_SYMLINK', $origin_dir, array(), $e);
+ throw new filesystem_exception('FILESYSTEM_CANNOT_CREATE_SYMLINK', $origin_dir, array(), $e);
}
}
@@ -578,7 +578,7 @@ class filesystem implements filesystem_interface
$error = trim($e->getMessage());
$file = substr($error, strrpos($error, ' '));
- throw new filesystem_exception('CANNOT_TOUCH_FILES', $file, array(), $e);
+ throw new filesystem_exception('FILESYSTEM_CANNOT_TOUCH_FILES', $file, array(), $e);
}
}
diff --git a/phpBB/phpbb/filesystem/filesystem_interface.php b/phpBB/phpbb/filesystem/filesystem_interface.php
index 1093be2499..39ae0c3954 100644
--- a/phpBB/phpbb/filesystem/filesystem_interface.php
+++ b/phpBB/phpbb/filesystem/filesystem_interface.php
@@ -204,7 +204,7 @@ interface filesystem_interface
* This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions.
* The function determines owner and group from common.php file and sets the same to the provided file.
* The function uses bit fields to build the permissions.
- * The function sets the appropiate execute bit on directories.
+ * The function sets the appropriate execute bit on directories.
*
* Supported constants representing bit fields are:
*
diff --git a/phpBB/phpbb/finder.php b/phpBB/phpbb/finder.php
index 1f1d931880..0a2b67a034 100644
--- a/phpBB/phpbb/finder.php
+++ b/phpBB/phpbb/finder.php
@@ -80,7 +80,7 @@ class finder
/**
* Set the array of extensions
*
- * @param array $extensions A list of extensions that should be searched aswell
+ * @param array $extensions A list of extensions that should be searched as well
* @param bool $replace_list Should the list be emptied before adding the extensions
* @return \phpbb\finder This object for chaining calls
*/
@@ -237,7 +237,7 @@ class finder
}
/**
- * Removes occurances of /./ and makes sure path ends without trailing slash
+ * Removes occurrences of /./ and makes sure path ends without trailing slash
*
* @param string $directory A directory pattern
* @return string A cleaned up directory pattern
diff --git a/phpBB/phpbb/help/controller/bbcode.php b/phpBB/phpbb/help/controller/bbcode.php
index e16f99023d..560b0c02ce 100644
--- a/phpBB/phpbb/help/controller/bbcode.php
+++ b/phpBB/phpbb/help/controller/bbcode.php
@@ -25,6 +25,11 @@ class bbcode extends controller
{
$this->language->add_lang('help/bbcode');
+ $this->template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $this->language->lang('BBCODE_GUIDE'),
+ 'U_BREADCRUMB' => $this->helper->route('phpbb_help_bbcode_controller'),
+ ));
+
$this->manager->add_block(
'HELP_BBCODE_BLOCK_INTRO',
false,
diff --git a/phpBB/phpbb/help/controller/faq.php b/phpBB/phpbb/help/controller/faq.php
index 5e45cfe667..0f63be5b56 100644
--- a/phpBB/phpbb/help/controller/faq.php
+++ b/phpBB/phpbb/help/controller/faq.php
@@ -25,6 +25,11 @@ class faq extends controller
{
$this->language->add_lang('help/faq');
+ $this->template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $this->language->lang('FAQ_EXPLAIN'),
+ 'U_BREADCRUMB' => $this->helper->route('phpbb_help_faq_controller'),
+ ));
+
$this->manager->add_block(
'HELP_FAQ_BLOCK_LOGIN',
false,
diff --git a/phpBB/phpbb/install/controller/helper.php b/phpBB/phpbb/install/controller/helper.php
index ff7e691224..f61c7de41f 100644
--- a/phpBB/phpbb/install/controller/helper.php
+++ b/phpBB/phpbb/install/controller/helper.php
@@ -267,7 +267,7 @@ class helper
'L_SKIP' => $this->language->lang('SKIP'),
'PAGE_TITLE' => $this->language->lang($page_title),
'T_IMAGE_PATH' => $this->path_helper->get_web_root_path() . $path . 'images',
- 'T_JQUERY_LINK' => $this->path_helper->get_web_root_path() . $path . '../assets/javascript/jquery.min.js',
+ 'T_JQUERY_LINK' => $this->path_helper->get_web_root_path() . $path . '../assets/javascript/jquery-3.4.1.min.js',
'T_TEMPLATE_PATH' => $this->path_helper->get_web_root_path() . $path . 'style',
'T_ASSETS_PATH' => $this->path_helper->get_web_root_path() . $path . '../assets',
diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php
index 9e372fecde..655760270a 100644
--- a/phpBB/phpbb/install/helper/container_factory.php
+++ b/phpBB/phpbb/install/helper/container_factory.php
@@ -181,7 +181,7 @@ class container_factory
$this->request->disable_super_globals();
}
- // Get compatibilty globals and constants
+ // Get compatibility globals and constants
$this->update_helper->include_file('includes/compatibility_globals.' . $this->php_ext);
register_compatibility_globals();
diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php
index fa5a10c6fc..51fd18f874 100644
--- a/phpBB/phpbb/install/helper/database.php
+++ b/phpBB/phpbb/install/helper/database.php
@@ -45,15 +45,6 @@ class database
'AVAILABLE' => true,
'2.0.x' => true,
),
- 'mysql' => array(
- 'LABEL' => 'MySQL',
- 'SCHEMA' => 'mysql',
- 'MODULE' => 'mysql',
- 'DELIM' => ';',
- 'DRIVER' => 'phpbb\db\driver\mysql',
- 'AVAILABLE' => true,
- '2.0.x' => true,
- ),
'mssql_odbc'=> array(
'LABEL' => 'MS SQL Server [ ODBC ]',
'SCHEMA' => 'mssql',
@@ -256,7 +247,6 @@ class database
$dbms_info = $this->get_available_dbms($dbms);
switch ($dbms_info[$dbms]['SCHEMA'])
{
- case 'mysql':
case 'mysql_41':
$prefix_length = 36;
break;
@@ -382,14 +372,6 @@ class database
// Check if database version is supported
switch ($dbms)
{
- case 'mysqli':
- if (version_compare($db->sql_server_info(true), '4.1.3', '<'))
- {
- $errors[] = array(
- 'title' => 'INST_ERR_DB_NO_MYSQLI',
- );
- }
- break;
case 'sqlite3':
if (version_compare($db->sql_server_info(true), '3.6.15', '<'))
{
diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php
index 440748901c..3df9a91936 100644
--- a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php
+++ b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php
@@ -31,7 +31,7 @@ interface iohandler_interface
* @param string $name Name of the input variable to obtain
* @param mixed $default A default value that is returned if the variable was not set.
* This function will always return a value of the same type as the default.
- * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters
+ * @param bool $multibyte If $default is a string this parameter has to be true if the variable may contain any UTF-8 characters
* Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks
*
* @return mixed Value of the input variable
diff --git a/phpBB/phpbb/install/installer_configuration.php b/phpBB/phpbb/install/installer_configuration.php
index 805140338c..dfafc40b4b 100644
--- a/phpBB/phpbb/install/installer_configuration.php
+++ b/phpBB/phpbb/install/installer_configuration.php
@@ -48,9 +48,9 @@ class installer_configuration implements ConfigurationInterface
->cannotBeEmpty()
->end()
->scalarNode('description')
- ->defaultValue('My amazing new phpBB board')
- ->cannotBeEmpty()
- ->end()
+ ->defaultValue('My amazing new phpBB board')
+ ->cannotBeEmpty()
+ ->end()
->end()
->end()
->arrayNode('database')
@@ -128,12 +128,11 @@ class installer_configuration implements ConfigurationInterface
->integerNode('server_port')
->defaultValue(80)
->min(1)
- ->cannotBeEmpty()
->end()
->scalarNode('script_path')
->defaultValue('/')
->cannotBeEmpty()
- ->end()
+ ->end()
->end()
->end()
->arrayNode('extensions')
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/install/module/install_database/task/create_schema.php b/phpBB/phpbb/install/module/install_database/task/create_schema.php
index a5635d5dbe..983bb42122 100644
--- a/phpBB/phpbb/install/module/install_database/task/create_schema.php
+++ b/phpBB/phpbb/install/module/install_database/task/create_schema.php
@@ -129,14 +129,7 @@ class create_schema extends \phpbb\install\task_base
if ($dbms === 'mysql')
{
- if (version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
- {
- $schema_name .= '_41';
- }
- else
- {
- $schema_name .= '_40';
- }
+ $schema_name .= '_41';
}
$db_schema_path = $this->phpbb_root_path . 'install/schemas/' . $schema_name . '_schema.sql';
diff --git a/phpBB/phpbb/install/module/install_database/task/set_up_database.php b/phpBB/phpbb/install/module/install_database/task/set_up_database.php
index 49c8ea23ad..4da5ece228 100644
--- a/phpBB/phpbb/install/module/install_database/task/set_up_database.php
+++ b/phpBB/phpbb/install/module/install_database/task/set_up_database.php
@@ -102,14 +102,7 @@ class set_up_database extends \phpbb\install\task_base
if ($dbms === 'mysql')
{
- if (version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
- {
- $schema_name .= '_41';
- }
- else
- {
- $schema_name .= '_40';
- }
+ $schema_name .= '_41';
}
$this->schema_file_path = $this->phpbb_root_path . 'install/schemas/' . $schema_name . '_schema.sql';
diff --git a/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php b/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php
index 5bc425b929..900d5b94bc 100644
--- a/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php
+++ b/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php
@@ -165,7 +165,7 @@ class create_config_file extends \phpbb\install\task_base
protected function get_config_data($debug = false, $debug_container = false, $environment = null)
{
$config_content = "<?php\n";
- $config_content .= "// phpBB 3.2.x auto-generated configuration file\n// Do not change anything in this file!\n";
+ $config_content .= "// phpBB 3.3.x auto-generated configuration file\n// Do not change anything in this file!\n";
$dbms = $this->install_config->get('dbms');
$db_driver = $this->db_helper->get_available_dbms($dbms);
@@ -191,7 +191,6 @@ class create_config_file extends \phpbb\install\task_base
}
$config_content .= "\n@define('PHPBB_INSTALLED', true);\n";
- $config_content .= "// @define('PHPBB_DISPLAY_LOAD_TIME', true);\n";
if ($environment)
{
diff --git a/phpBB/phpbb/install/module/requirements/task/check_server_environment.php b/phpBB/phpbb/install/module/requirements/task/check_server_environment.php
index 29f9777747..4607ce9ec2 100644
--- a/phpBB/phpbb/install/module/requirements/task/check_server_environment.php
+++ b/phpBB/phpbb/install/module/requirements/task/check_server_environment.php
@@ -98,7 +98,7 @@ class check_server_environment extends \phpbb\install\task_base
{
$php_version = PHP_VERSION;
- if (version_compare($php_version, '5.4') < 0)
+ if (version_compare($php_version, '7.1') < 0)
{
$this->response_helper->add_error_message('PHP_VERSION_REQD', 'PHP_VERSION_REQD_EXPLAIN');
diff --git a/phpBB/phpbb/lock/db.php b/phpBB/phpbb/lock/db.php
index 85ba9a7aa3..eea919f8f7 100644
--- a/phpBB/phpbb/lock/db.php
+++ b/phpBB/phpbb/lock/db.php
@@ -110,6 +110,13 @@ class db
// process we failed to acquire the lock.
$this->locked = $this->config->set_atomic($this->config_name, $lock_value, $this->unique_id, false);
+ if ($this->locked == true)
+ {
+ if ($this->config->ensure_lock($this->config_name, $this->unique_id))
+ {
+ return true;
+ }
+ }
return $this->locked;
}
diff --git a/phpBB/phpbb/lock/flock.php b/phpBB/phpbb/lock/flock.php
index df88e1490a..af051afb56 100644
--- a/phpBB/phpbb/lock/flock.php
+++ b/phpBB/phpbb/lock/flock.php
@@ -101,7 +101,10 @@ class flock
if ($this->lock_fp)
{
- @flock($this->lock_fp, LOCK_EX);
+ if (!@flock($this->lock_fp, LOCK_EX))
+ {
+ throw new \phpbb\exception\http_exception(500, 'Failure while aqcuiring locks.');
+ }
}
return (bool) $this->lock_fp;
diff --git a/phpBB/phpbb/mimetype/guesser.php b/phpBB/phpbb/mimetype/guesser.php
index 8baa77089b..f8cbffe8f5 100644
--- a/phpBB/phpbb/mimetype/guesser.php
+++ b/phpBB/phpbb/mimetype/guesser.php
@@ -76,7 +76,7 @@ class guesser
* should be used first and vice versa. usort() orders the array values
* from low to high depending on what the comparison function returns
* to it. Return value should be smaller than 0 if value a is smaller
- * than value b. This has been reversed in the comparision function in
+ * than value b. This has been reversed in the comparison function in
* order to sort the guessers from high to low.
* Method has been set to public in order to allow proper testing.
*
diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php
index e4b111e4da..139b5fabb9 100644
--- a/phpBB/phpbb/notification/type/approve_post.php
+++ b/phpBB/phpbb/notification/type/approve_post.php
@@ -78,10 +78,7 @@ class approve_post extends \phpbb\notification\type\post
'ignore_users' => array(),
), $options);
- $users = array();
- $users[$post['poster_id']] = $this->notification_manager->get_default_methods();
-
- return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(
+ return $this->get_authorised_recipients(array($post['poster_id']), $post['forum_id'], array_merge($options, array(
'item_type' => static::$notification_option['id'],
)));
}
@@ -94,7 +91,7 @@ class approve_post extends \phpbb\notification\type\post
*
* @param array $post Post data from submit_post
* @param array $notify_users Notify users list
- * Formated from find_users_for_notification()
+ * Formatted from find_users_for_notification()
* @return array Whatever you want to send to create_insert_array().
*/
public function pre_create_insert_array($post, $notify_users)
diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php
index f8a3fdec6f..0c343646ee 100644
--- a/phpBB/phpbb/notification/type/approve_topic.php
+++ b/phpBB/phpbb/notification/type/approve_topic.php
@@ -78,10 +78,7 @@ class approve_topic extends \phpbb\notification\type\topic
'ignore_users' => array(),
), $options);
- $users = array();
- $users[$post['poster_id']] = $this->notification_manager->get_default_methods();
-
- return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(
+ return $this->get_authorised_recipients(array($post['poster_id']), $post['forum_id'], array_merge($options, array(
'item_type' => static::$notification_option['id'],
)));
}
@@ -94,7 +91,7 @@ class approve_topic extends \phpbb\notification\type\topic
*
* @param array $post Post data from submit_post
* @param array $notify_users Notify users list
- * Formated from find_users_for_notification()
+ * Formatted from find_users_for_notification()
* @return array Whatever you want to send to create_insert_array().
*/
public function pre_create_insert_array($post, $notify_users)
diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php
index 77ed7f2b09..e4600add11 100644
--- a/phpBB/phpbb/notification/type/base.php
+++ b/phpBB/phpbb/notification/type/base.php
@@ -336,7 +336,7 @@ abstract class base implements \phpbb\notification\type\type_interface
}
/**
- * Get the reference of the notifcation (fall back)
+ * Get the reference of the notification (fall back)
*
* @return string
*/
@@ -356,7 +356,7 @@ abstract class base implements \phpbb\notification\type\type_interface
}
/**
- * Get the reason for the notifcation (fall back)
+ * Get the reason for the notification (fall back)
*
* @return string
*/
diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php
index 254f4c07b3..f0e938d3ce 100644
--- a/phpBB/phpbb/notification/type/post.php
+++ b/phpBB/phpbb/notification/type/post.php
@@ -352,7 +352,7 @@ class post extends \phpbb\notification\type\base
*
* @param array $post Post data from submit_post
* @param array $notify_users Notify users list
- * Formated from find_users_for_notification()
+ * Formatted from find_users_for_notification()
* @return array Whatever you want to send to create_insert_array().
*/
public function pre_create_insert_array($post, $notify_users)
diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php
index 5c42afa8c8..2535cdaed6 100644
--- a/phpBB/phpbb/notification/type/topic.php
+++ b/phpBB/phpbb/notification/type/topic.php
@@ -256,7 +256,7 @@ class topic extends \phpbb\notification\type\base
*
* @param array $post Post data from submit_post
* @param array $notify_users Notify users list
- * Formated from find_users_for_notification()
+ * Formatted from find_users_for_notification()
* @return array Whatever you want to send to create_insert_array().
*/
public function pre_create_insert_array($post, $notify_users)
diff --git a/phpBB/phpbb/notification/type/type_interface.php b/phpBB/phpbb/notification/type/type_interface.php
index f9f832bdda..ed77335ce5 100644
--- a/phpBB/phpbb/notification/type/type_interface.php
+++ b/phpBB/phpbb/notification/type/type_interface.php
@@ -170,7 +170,7 @@ interface type_interface
*
* @param array $type_data The type specific data
* @param array $notify_users Notify users list
- * Formated from find_users_for_notification()
+ * Formatted from find_users_for_notification()
* @return array Whatever you want to send to create_insert_array().
*/
public function pre_create_insert_array($type_data, $notify_users);
diff --git a/phpBB/phpbb/passwords/driver/argon2i.php b/phpBB/phpbb/passwords/driver/argon2i.php
new file mode 100644
index 0000000000..49d7d6393e
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/argon2i.php
@@ -0,0 +1,73 @@
+<?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\passwords\driver;
+
+class argon2i extends base_native
+{
+ /** @var int Maximum memory (in bytes) that may be used to compute the Argon2 hash */
+ protected $memory_cost;
+
+ /** @var int Number of threads to use for computing the Argon2 hash */
+ protected $threads;
+
+ /** @var int Maximum amount of time it may take to compute the Argon2 hash */
+ protected $time_cost;
+
+ /**
+ * Constructor of passwords driver object
+ *
+ * @param \phpbb\config\config $config phpBB config
+ * @param \phpbb\passwords\driver\helper $helper Password driver helper
+ * @param int $memory_cost Maximum memory (optional)
+ * @param int $threads Number of threads to use (optional)
+ * @param int $time_cost Maximum amount of time (optional)
+ */
+ public function __construct(\phpbb\config\config $config, helper $helper, $memory_cost = 1024, $threads = 2, $time_cost = 2)
+ {
+ parent::__construct($config, $helper);
+
+ // Don't allow cost factors to be below default settings
+ $this->memory_cost = max($memory_cost, 1024);
+ $this->threads = max($threads, 2);
+ $this->time_cost = max($time_cost, 2);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_algo_name()
+ {
+ return 'PASSWORD_ARGON2I';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_options()
+ {
+ return [
+ 'memory_cost' => $this->memory_cost,
+ 'time_cost' => $this->time_cost,
+ 'threads' => $this->threads
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return '$argon2i$';
+ }
+}
diff --git a/phpBB/phpbb/passwords/driver/argon2id.php b/phpBB/phpbb/passwords/driver/argon2id.php
new file mode 100644
index 0000000000..9e4b08bbb9
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/argon2id.php
@@ -0,0 +1,33 @@
+<?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\passwords\driver;
+
+class argon2id extends argon2i
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_algo_name()
+ {
+ return 'PASSWORD_ARGON2ID';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_prefix()
+ {
+ return '$argon2id$';
+ }
+}
diff --git a/phpBB/phpbb/passwords/driver/base_native.php b/phpBB/phpbb/passwords/driver/base_native.php
new file mode 100644
index 0000000000..87498327f9
--- /dev/null
+++ b/phpBB/phpbb/passwords/driver/base_native.php
@@ -0,0 +1,75 @@
+<?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\passwords\driver;
+
+abstract class base_native extends base
+{
+ /**
+ * Return the constant name for this driver's algorithm
+ *
+ * @link https://www.php.net/manual/en/password.constants.php
+ *
+ * @return string
+ */
+ abstract public function get_algo_name();
+
+ /**
+ * Return the options set for this driver instance
+ *
+ * @return array
+ */
+ abstract public function get_options();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check($password, $hash, $user_row = [])
+ {
+ return password_verify($password, $hash);
+ }
+
+ /**
+ * Return the value for this driver's algorithm
+ *
+ * @return integer
+ */
+ public function get_algo_value()
+ {
+ return constant($this->get_algo_name());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hash($password)
+ {
+ return password_hash($password, $this->get_algo_value(), $this->get_options());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_supported()
+ {
+ return defined($this->get_algo_name()) && function_exists('password_hash') && function_exists('password_needs_rehash') && function_exists('password_verify');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function needs_rehash($hash)
+ {
+ return password_needs_rehash($hash, $this->get_algo_value(), $this->get_options());
+ }
+}
diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php
index fad76a9fe5..54e6dce4be 100644
--- a/phpBB/phpbb/passwords/manager.php
+++ b/phpBB/phpbb/passwords/manager.php
@@ -250,7 +250,7 @@ class manager
/**
* Check supplied password against hash and set convert_flag if password
- * needs to be converted to different format (preferrably newer one)
+ * needs to be converted to different format (preferably newer one)
*
* @param string $password Password that should be checked
* @param string $hash Stored hash
diff --git a/phpBB/phpbb/report/report_handler.php b/phpBB/phpbb/report/report_handler.php
index 854318c559..97acc1763e 100644
--- a/phpBB/phpbb/report/report_handler.php
+++ b/phpBB/phpbb/report/report_handler.php
@@ -51,7 +51,7 @@ abstract class report_handler implements report_handler_interface
protected $report_data;
/**
- * Construtor
+ * Constructor
*
* @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\event\dispatcher_interface $dispatcher
diff --git a/phpBB/phpbb/request/request.php b/phpBB/phpbb/request/request.php
index a0267d1370..5c30f9b062 100644
--- a/phpBB/phpbb/request/request.php
+++ b/phpBB/phpbb/request/request.php
@@ -179,7 +179,7 @@ class request implements \phpbb\request\request_interface
* then specifying array("var", 1) as the name will return "a".
* @param mixed $default A default value that is returned if the variable was not set.
* This function will always return a value of the same type as the default.
- * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters
+ * @param bool $multibyte If $default is a string this parameter has to be true if the variable may contain any UTF-8 characters
* Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks
* @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global
* Specifies which super global should be used
@@ -203,7 +203,7 @@ class request implements \phpbb\request\request_interface
* then specifying array("var", 1) as the name will return "a".
* @param mixed $default A default value that is returned if the variable was not set.
* This function will always return a value of the same type as the default.
- * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters
+ * @param bool $multibyte If $default is a string this parameter has to be true if the variable may contain any UTF-8 characters
* Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks
* @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global
* Specifies which super global should be used
@@ -395,7 +395,7 @@ class request implements \phpbb\request\request_interface
* then specifying array("var", 1) as the name will return "a".
* @param mixed $default A default value that is returned if the variable was not set.
* This function will always return a value of the same type as the default.
- * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters
+ * @param bool $multibyte If $default is a string this parameter has to be true if the variable may contain any UTF-8 characters
* Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks
* @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global
* Specifies which super global should be used
diff --git a/phpBB/phpbb/request/request_interface.php b/phpBB/phpbb/request/request_interface.php
index 3bfa8bb424..54dd8cef15 100644
--- a/phpBB/phpbb/request/request_interface.php
+++ b/phpBB/phpbb/request/request_interface.php
@@ -54,7 +54,7 @@ interface request_interface
* then specifying array("var", 1) as the name will return "a".
* @param mixed $default A default value that is returned if the variable was not set.
* This function will always return a value of the same type as the default.
- * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters
+ * @param bool $multibyte If $default is a string this parameter has to be true if the variable may contain any UTF-8 characters
* Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks
* @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global
* Specifies which super global should be used
diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php
index 1105d0892f..8bdc31e128 100644
--- a/phpBB/phpbb/search/fulltext_mysql.php
+++ b/phpBB/phpbb/search/fulltext_mysql.php
@@ -150,11 +150,11 @@ class fulltext_mysql extends \phpbb\search\base
/**
* Checks for correct MySQL version and stores min/max word length in the config
*
- * @return string|bool Language key of the error/incompatiblity occurred
+ * @return string|bool Language key of the error/incompatibility occurred
*/
public function init()
{
- if ($this->db->get_sql_layer() != 'mysql4' && $this->db->get_sql_layer() != 'mysqli')
+ if ($this->db->get_sql_layer() != 'mysqli')
{
return $this->user->lang['FULLTEXT_MYSQL_INCOMPATIBLE_DATABASE'];
}
@@ -1005,14 +1005,7 @@ class fulltext_mysql extends \phpbb\search\base
if (!isset($this->stats['post_subject']))
{
$alter_entry = array();
- if ($this->db->get_sql_layer() == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
- {
- $alter_entry[] = 'MODIFY post_subject varchar(255) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL';
- }
- else
- {
- $alter_entry[] = 'MODIFY post_subject text NOT NULL';
- }
+ $alter_entry[] = 'MODIFY post_subject varchar(255) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL';
$alter_entry[] = 'ADD FULLTEXT (post_subject)';
$alter_list[] = $alter_entry;
}
@@ -1020,15 +1013,7 @@ class fulltext_mysql extends \phpbb\search\base
if (!isset($this->stats['post_content']))
{
$alter_entry = array();
- if ($this->db->get_sql_layer() == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
- {
- $alter_entry[] = 'MODIFY post_text mediumtext COLLATE utf8_unicode_ci NOT NULL';
- }
- else
- {
- $alter_entry[] = 'MODIFY post_text mediumtext NOT NULL';
- }
-
+ $alter_entry[] = 'MODIFY post_text mediumtext COLLATE utf8_unicode_ci NOT NULL';
$alter_entry[] = 'ADD FULLTEXT post_content (post_text, post_subject)';
$alter_list[] = $alter_entry;
}
diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php
index c83de75eed..295c2cf33c 100644
--- a/phpBB/phpbb/search/fulltext_native.php
+++ b/phpBB/phpbb/search/fulltext_native.php
@@ -351,7 +351,7 @@ class fulltext_native extends \phpbb\search\base
$this->db->sql_freeresult($result);
}
- // Handle +, - without preceeding whitespace character
+ // Handle +, - without preceding whitespace character
$match = array('#(\S)\+#', '#(\S)-#');
$replace = array('$1 +', '$1 +');
@@ -889,7 +889,6 @@ class fulltext_native extends \phpbb\search\base
switch ($this->db->get_sql_layer())
{
- case 'mysql4':
case 'mysqli':
// 3.x does not support SQL_CALC_FOUND_ROWS
@@ -1184,7 +1183,6 @@ class fulltext_native extends \phpbb\search\base
{
switch ($this->db->get_sql_layer())
{
- case 'mysql4':
case 'mysqli':
// $select = 'SQL_CALC_FOUND_ROWS ' . $select;
$is_mysql = true;
diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php
index 2f387e791e..6241f21fcf 100644
--- a/phpBB/phpbb/search/fulltext_postgres.php
+++ b/phpBB/phpbb/search/fulltext_postgres.php
@@ -173,7 +173,7 @@ class fulltext_postgres extends \phpbb\search\base
/**
* Checks for correct PostgreSQL version and stores min/max word length in the config
*
- * @return string|bool Language key of the error/incompatiblity occurred
+ * @return string|bool Language key of the error/incompatibility occurred
*/
public function init()
{
diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php
index 2c2eb84dc7..6230f92da3 100644
--- a/phpBB/phpbb/search/fulltext_sphinx.php
+++ b/phpBB/phpbb/search/fulltext_sphinx.php
@@ -18,7 +18,7 @@ define('SPHINX_CONNECT_RETRIES', 3);
define('SPHINX_CONNECT_WAIT_TIME', 300);
/**
-* Fulltext search based on the sphinx search deamon
+* Fulltext search based on the sphinx search daemon
*/
class fulltext_sphinx
{
@@ -210,11 +210,11 @@ class fulltext_sphinx
/**
* Checks permissions and paths, if everything is correct it generates the config file
*
- * @return string|bool Language key of the error/incompatiblity encountered, or false if successful
+ * @return string|bool Language key of the error/incompatibility encountered, or false if successful
*/
public function init()
{
- if ($this->db->get_sql_layer() != 'mysql' && $this->db->get_sql_layer() != 'mysql4' && $this->db->get_sql_layer() != 'mysqli' && $this->db->get_sql_layer() != 'postgres')
+ if ($this->db->get_sql_layer() != 'mysqli' && $this->db->get_sql_layer() != 'postgres')
{
return $this->user->lang['FULLTEXT_SPHINX_WRONG_DATABASE'];
}
@@ -233,7 +233,7 @@ class fulltext_sphinx
protected function config_generate()
{
// Check if Database is supported by Sphinx
- if ($this->db->get_sql_layer() =='mysql' || $this->db->get_sql_layer() == 'mysql4' || $this->db->get_sql_layer() == 'mysqli')
+ if ($this->db->get_sql_layer() == 'mysqli')
{
$this->dbtype = 'mysql';
}
diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php
index cc5a1b8f8f..7c76c08b73 100644
--- a/phpBB/phpbb/session.php
+++ b/phpBB/phpbb/session.php
@@ -250,8 +250,7 @@ class session
$ips = explode(' ', $this->forwarded_for);
foreach ($ips as $ip)
{
- // check IPv4 first, the IPv6 is hopefully only going to be used very seldomly
- if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip))
+ if (!filter_var($ip, FILTER_VALIDATE_IP))
{
// contains invalid data, don't use the forwarded for header
$this->forwarded_for = '';
@@ -311,49 +310,17 @@ class session
foreach ($ips as $ip)
{
- if (function_exists('phpbb_ip_normalise'))
- {
- // Normalise IP address
- $ip = phpbb_ip_normalise($ip);
-
- if (empty($ip))
- {
- // IP address is invalid.
- break;
- }
-
- // IP address is valid.
- $this->ip = $ip;
+ // Normalise IP address
+ $ip = phpbb_ip_normalise($ip);
- // Skip legacy code.
- continue;
- }
-
- if (preg_match(get_preg_expression('ipv4'), $ip))
- {
- $this->ip = $ip;
- }
- else if (preg_match(get_preg_expression('ipv6'), $ip))
+ if ($ip === false)
{
- // Quick check for IPv4-mapped address in IPv6
- if (stripos($ip, '::ffff:') === 0)
- {
- $ipv4 = substr($ip, 7);
-
- if (preg_match(get_preg_expression('ipv4'), $ipv4))
- {
- $ip = $ipv4;
- }
- }
-
- $this->ip = $ip;
- }
- else
- {
- // We want to use the last valid address in the chain
- // Leave foreach loop when address is invalid
+ // IP address is invalid.
break;
}
+
+ // IP address is valid.
+ $this->ip = $ip;
}
$this->load = false;
@@ -478,8 +445,8 @@ class session
}
else
{
- // Added logging temporarly to help debug bugs...
- if (defined('DEBUG') && $this->data['user_id'] != ANONYMOUS)
+ // Added logging temporarily to help debug bugs...
+ if ($phpbb_container->getParameter('session.log_errors') && $this->data['user_id'] != ANONYMOUS)
{
if ($referer_valid)
{
@@ -1362,7 +1329,7 @@ class session
* Only IPv4 (rbldns does not support AAAA records/IPv6 lookups)
*
* @author satmd (from the php manual)
- * @param string $mode register/post - spamcop for example is ommitted for posting
+ * @param string $mode register/post - spamcop for example is omitted for posting
* @param string|false $ip the IPv4 address to check
*
* @return false if ip is not blacklisted, else an array([checked server], [lookup])
@@ -1400,7 +1367,7 @@ class session
foreach ($dnsbl_check as $dnsbl => $lookup)
{
- if (phpbb_checkdnsrr($reverse_ip . '.' . $dnsbl . '.', 'A') === true)
+ if (checkdnsrr($reverse_ip . '.' . $dnsbl . '.', 'A') === true)
{
$info = array($dnsbl, $lookup . $ip);
}
@@ -1421,7 +1388,7 @@ class session
/**
* Check if URI is blacklisted
- * This should be called only where absolutly necessary, for example on the submitted website field
+ * This should be called only where absolutely necessary, for example on the submitted website field
* This function is not in use at the moment and is only included for testing purposes, it may not work at all!
* This means it is untested at the moment and therefore commented out
*
@@ -1444,7 +1411,7 @@ class session
{
// One problem here... the return parameter for the "windows" method is different from what
// we expect... this may render this check useless...
- if (phpbb_checkdnsrr($uri . '.multi.uribl.com.', 'A') === true)
+ if (checkdnsrr($uri . '.multi.uribl.com.', 'A') === true)
{
return true;
}
diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php
index cb00f16549..d6b46234f0 100644
--- a/phpBB/phpbb/template/asset.php
+++ b/phpBB/phpbb/template/asset.php
@@ -45,13 +45,6 @@ class asset
*/
public function set_url($url)
{
- if (version_compare(PHP_VERSION, '5.4.7') < 0 && substr($url, 0, 2) === '//')
- {
- // Workaround for PHP 5.4.6 and older bug #62844 - add fake scheme and then remove it
- $this->components = parse_url('http:' . $url);
- $this->components['scheme'] = '';
- return;
- }
$this->components = parse_url($url);
}
diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php
index 202e29ce00..f059c327c1 100644
--- a/phpBB/phpbb/template/context.php
+++ b/phpBB/phpbb/template/context.php
@@ -87,7 +87,7 @@ class context
}
/**
- * Retreive a single scalar value from a single key.
+ * Retrieve a single scalar value from a single key.
*
* @param string $varname Variable name
* @return mixed Variable value, or null if not set
@@ -149,7 +149,7 @@ class context
{
// If the key name is lowercase and the data is an array,
// it could be a template loop. So we set the S_NUM_ROWS there
- // aswell.
+ // as well.
if ($sub_block_name === strtolower($sub_block_name) && is_array($sub_block))
{
$this->set_num_rows($sub_block);
diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php
index df83d5bc43..6634c28d02 100644
--- a/phpBB/phpbb/template/template.php
+++ b/phpBB/phpbb/template/template.php
@@ -136,7 +136,7 @@ interface template
public function retrieve_vars(array $vararray);
/**
- * Retreive a single scalar value from a single key.
+ * Retrieve a single scalar value from a single key.
*
* @param string $varname Variable name
* @return mixed Variable value, or null if not set
diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php
index f6f8e03ca2..1131a7f3aa 100644
--- a/phpBB/phpbb/template/twig/extension.php
+++ b/phpBB/phpbb/template/twig/extension.php
@@ -18,6 +18,9 @@ class extension extends \Twig_Extension
/** @var \phpbb\template\context */
protected $context;
+ /** @var \phpbb\template\twig\environment */
+ protected $environment;
+
/** @var \phpbb\language\language */
protected $language;
@@ -25,12 +28,13 @@ class extension extends \Twig_Extension
* Constructor
*
* @param \phpbb\template\context $context
+ * @param \phpbb\template\twig\environment $environment
* @param \phpbb\language\language $language
- * @return \phpbb\template\twig\extension
*/
- public function __construct(\phpbb\template\context $context, $language)
+ public function __construct(\phpbb\template\context $context, \phpbb\template\twig\environment $environment, $language)
{
$this->context = $context;
+ $this->environment = $environment;
$this->language = $language;
}
@@ -56,9 +60,9 @@ class extension extends \Twig_Extension
new \phpbb\template\twig\tokenparser\includeparser,
new \phpbb\template\twig\tokenparser\includejs,
new \phpbb\template\twig\tokenparser\includecss,
- new \phpbb\template\twig\tokenparser\event,
- new \phpbb\template\twig\tokenparser\includephp,
- new \phpbb\template\twig\tokenparser\php,
+ new \phpbb\template\twig\tokenparser\event($this->environment),
+ new \phpbb\template\twig\tokenparser\includephp($this->environment),
+ new \phpbb\template\twig\tokenparser\php($this->environment),
);
}
@@ -85,6 +89,8 @@ class extension extends \Twig_Extension
{
return array(
new \Twig_SimpleFunction('lang', array($this, 'lang')),
+ new \Twig_SimpleFunction('lang_defined', array($this, 'lang_defined')),
+ new \Twig_SimpleFunction('get_class', 'get_class'),
);
}
@@ -136,7 +142,7 @@ class extension extends \Twig_Extension
*
* @return mixed The sliced variable
*/
- function loop_subset(\Twig_Environment $env, $item, $start, $end = null, $preserveKeys = false)
+ public function loop_subset(\Twig_Environment $env, $item, $start, $end = null, $preserveKeys = false)
{
// We do almost the same thing as Twig's slice (array_slice), except when $end is positive
if ($end >= 1)
@@ -165,7 +171,7 @@ class extension extends \Twig_Extension
*
* @return string
*/
- function lang()
+ public function lang()
{
$args = func_get_args();
$key = $args[0];
@@ -182,4 +188,14 @@ class extension extends \Twig_Extension
return call_user_func_array(array($this->language, 'lang'), $args);
}
+
+ /**
+ * Check if a language variable exists
+ *
+ * @return bool
+ */
+ public function lang_defined($key)
+ {
+ return call_user_func_array([$this->language, 'is_set'], [$key]);
+ }
}
diff --git a/phpBB/phpbb/template/twig/extension/avatar.php b/phpBB/phpbb/template/twig/extension/avatar.php
new file mode 100644
index 0000000000..7a17fd4b42
--- /dev/null
+++ b/phpBB/phpbb/template/twig/extension/avatar.php
@@ -0,0 +1,80 @@
+<?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\template\twig\extension;
+
+class avatar extends \Twig_Extension
+{
+ /**
+ * Get the name of this extension
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return 'avatar';
+ }
+
+ /**
+ * Returns a list of global functions to add to the existing list.
+ *
+ * @return array An array of global functions
+ */
+ public function getFunctions()
+ {
+ return array(
+ new \Twig_SimpleFunction('avatar', array($this, 'get_avatar')),
+ );
+ }
+
+ /**
+ * Get avatar for placing into templates.
+ *
+ * How to use in a template:
+ * - {{ avatar('mode', row, alt, ignore_config, lazy) }}
+ *
+ * The mode and row (group_row or user_row) are required.
+ * The other fields (alt|ignore_config|lazy) are optional.
+ *
+ * @uses \phpbb_get_group_avatar()
+ * @uses \phpbb_get_user_avatar()
+ *
+ * @return string The avatar HTML for the specified mode
+ */
+ public function get_avatar()
+ {
+ $args = func_get_args();
+
+ $mode = (string) $args[0];
+ $row = (array) $args[1];
+ $alt = isset($args[2]) ? (string) $args[2] : false;
+ $ignore_config = isset($args[3]) ? (bool) $args[3] : false;
+ $lazy = isset($args[4]) ? (bool) $args[4] : false;
+
+ // To prevent having to redefine alt attribute ('USER_AVATAR'|'GROUP_AVATAR'), we check if an alternative has been provided
+ switch ($mode)
+ {
+ case 'group':
+ return $alt ? phpbb_get_group_avatar($row, $alt, $ignore_config, $lazy) : phpbb_get_group_avatar($row);
+ break;
+
+ case 'user':
+ return $alt ? phpbb_get_user_avatar($row, $alt, $ignore_config, $lazy) : phpbb_get_user_avatar($row);
+ break;
+
+ default:
+ return '';
+ break;
+ }
+ }
+}
diff --git a/phpBB/phpbb/template/twig/extension/config.php b/phpBB/phpbb/template/twig/extension/config.php
new file mode 100644
index 0000000000..cbf6e505c5
--- /dev/null
+++ b/phpBB/phpbb/template/twig/extension/config.php
@@ -0,0 +1,64 @@
+<?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\template\twig\extension;
+
+class config extends \Twig_Extension
+{
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ /**
+ * Constructor.
+ *
+ * @param \phpbb\config\config $config Configuration object
+ */
+ public function __construct(\phpbb\config\config $config)
+ {
+ $this->config = $config;
+ }
+
+ /**
+ * Get the name of this extension
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return 'config';
+ }
+
+ /**
+ * Returns a list of global functions to add to the existing list.
+ *
+ * @return array An array of global functions
+ */
+ public function getFunctions()
+ {
+ return array(
+ new \Twig_SimpleFunction('config', array($this, 'get_config')),
+ );
+ }
+
+ /**
+ * Retrieves a configuration value for use in templates.
+ *
+ * @return string The configuration value
+ */
+ public function get_config()
+ {
+ $args = func_get_args();
+
+ return $this->config->offsetGet($args[0]);
+ }
+}
diff --git a/phpBB/phpbb/template/twig/extension/username.php b/phpBB/phpbb/template/twig/extension/username.php
new file mode 100644
index 0000000000..ef149693a0
--- /dev/null
+++ b/phpBB/phpbb/template/twig/extension/username.php
@@ -0,0 +1,84 @@
+<?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\template\twig\extension;
+
+class username extends \Twig_Extension
+{
+ /**
+ * Get the name of this extension
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return 'username';
+ }
+
+ /**
+ * Returns a list of global functions to add to the existing list.
+ *
+ * @return array An array of global functions
+ */
+ public function getFunctions()
+ {
+ return array(
+ new \Twig_SimpleFunction('username', array($this, 'get_username')),
+ );
+ }
+
+ /**
+ * Get username details for placing into templates.
+ *
+ * How to use in a template:
+ * - {{ username('mode', user_id, username, user_colour, guest_username, custom_profile_url) }}
+ * - {{ username('mode', user_row, guest_username, custom_profile_url) }}
+ * It's possible to provide the user identifier, name and colour separately,
+ * or provide the entire user row at once as an array.
+ *
+ * The mode, user_id and username are required (separately or through a user row).
+ * The other fields (user_colour|guest_username|custom_profile_url) are optional.
+ *
+ * @uses \get_username_string()
+ *
+ * @return string A string based on what is wanted depending on $mode
+ */
+ public function get_username()
+ {
+ $args = func_get_args();
+
+ $mode = $args[0];
+ $user = $args[1];
+
+ // If the entire user row is provided
+ if (is_array($user))
+ {
+ $user_id = isset($user['user_id']) ? $user['user_id'] : '';
+ $username = isset($user['username']) ? $user['username'] : '';
+ $user_colour = isset($user['user_colour']) ? $user['user_colour'] : '';
+ $guest_username = isset($args[2]) ? $args[2] : false;
+ $custom_profile_url = isset($args[3]) ? $args[3] : false;
+ }
+ else
+ {
+ // Options are provided separately
+ $user_id = $user;
+ $username = $args[2];
+ $user_colour = isset($args[3]) ? $args[3] : '';
+ $guest_username = isset($args[4]) ? $args[4] : false;
+ $custom_profile_url = isset($args[5]) ? $args[5] : false;
+ }
+
+ return get_username_string($mode, $user_id, $username, $user_colour, $guest_username, $custom_profile_url);
+ }
+}
diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php
index d0bcfa615e..6615a46067 100644
--- a/phpBB/phpbb/template/twig/lexer.php
+++ b/phpBB/phpbb/template/twig/lexer.php
@@ -15,20 +15,10 @@ namespace phpbb\template\twig;
class lexer extends \Twig_Lexer
{
- public function set_environment(\Twig_Environment $env)
+ public function tokenize(\Twig_Source $source)
{
- $this->env = $env;
- }
-
- public function tokenize($code, $filename = null)
- {
- // Handle \Twig_Source format input
- if ($code instanceof \Twig_Source)
- {
- $source = $code;
- $code = $source->getCode();
- $filename = $source->getName();
- }
+ $code = $source->getCode();
+ $filename = $source->getName();
// Our phpBB tags
// Commented out tokens are handled separately from the main replace
diff --git a/phpBB/phpbb/template/twig/loader.php b/phpBB/phpbb/template/twig/loader.php
index c13e3ee298..0f193dbe59 100644
--- a/phpBB/phpbb/template/twig/loader.php
+++ b/phpBB/phpbb/template/twig/loader.php
@@ -35,7 +35,7 @@ class loader extends \Twig_Loader_Filesystem
{
$this->filesystem = $filesystem;
- parent::__construct($paths, $this->filesystem->realpath(dirname(__FILE__)));
+ parent::__construct($paths, __DIR__);
}
/**
@@ -116,7 +116,7 @@ class loader extends \Twig_Loader_Filesystem
* Override for Twig_Loader_Filesystem::findTemplate to add support
* for loading from safe directories.
*/
- protected function findTemplate($name)
+ protected function findTemplate($name, $throw = true)
{
$name = (string) $name;
@@ -132,12 +132,12 @@ class loader extends \Twig_Loader_Filesystem
// First, find the template name. The override above of validateName
// causes the validateName process to be skipped for this call
- $file = parent::findTemplate($name);
+ $file = parent::findTemplate($name, $throw);
try
{
// Try validating the name (which may throw an exception)
- parent::validateName($name);
+ $this->validateName($name);
}
catch (\Twig_Error_Loader $e)
{
diff --git a/phpBB/phpbb/template/twig/node/definenode.php b/phpBB/phpbb/template/twig/node/definenode.php
index ddbd151d20..1c51596916 100644
--- a/phpBB/phpbb/template/twig/node/definenode.php
+++ b/phpBB/phpbb/template/twig/node/definenode.php
@@ -16,7 +16,7 @@ namespace phpbb\template\twig\node;
class definenode extends \Twig_Node
{
- public function __construct($capture, \Twig_NodeInterface $name, \Twig_NodeInterface $value, $lineno, $tag = null)
+ public function __construct($capture, \Twig_Node $name, \Twig_Node $value, $lineno, $tag = null)
{
parent::__construct(array('name' => $name, 'value' => $value), array('capture' => $capture, 'safe' => false), $lineno, $tag);
}
diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php
index 12034b7820..69bfd58803 100644
--- a/phpBB/phpbb/template/twig/node/includeasset.php
+++ b/phpBB/phpbb/template/twig/node/includeasset.php
@@ -15,15 +15,11 @@ namespace phpbb\template\twig\node;
abstract class includeasset extends \Twig_Node
{
- /** @var \Twig_Environment */
- protected $environment;
-
- public function __construct(\Twig_Node_Expression $expr, \phpbb\template\twig\environment $environment, $lineno, $tag = null)
+ public function __construct(\Twig_Node_Expression $expr, $lineno, $tag = null)
{
- $this->environment = $environment;
-
parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
}
+
/**
* Compiles the node to PHP.
*
@@ -33,20 +29,18 @@ abstract class includeasset extends \Twig_Node
{
$compiler->addDebugInfo($this);
- $config = $this->environment->get_phpbb_config();
-
$compiler
->write("\$asset_file = ")
->subcompile($this->getNode('expr'))
->raw(";\n")
- ->write("\$asset = new \phpbb\\template\\asset(\$asset_file, \$this->getEnvironment()->get_path_helper(), \$this->getEnvironment()->get_filesystem());\n")
+ ->write("\$asset = new \phpbb\\template\\asset(\$asset_file, \$this->env->get_path_helper(), \$this->env->get_filesystem());\n")
->write("if (substr(\$asset_file, 0, 2) !== './' && \$asset->is_relative()) {\n")
->indent()
->write("\$asset_path = \$asset->get_path();")
- ->write("\$local_file = \$this->getEnvironment()->get_phpbb_root_path() . \$asset_path;\n")
+ ->write("\$local_file = \$this->env->get_phpbb_root_path() . \$asset_path;\n")
->write("if (!file_exists(\$local_file)) {\n")
->indent()
- ->write("\$local_file = \$this->getEnvironment()->findTemplate(\$asset_path);\n")
+ ->write("\$local_file = \$this->env->findTemplate(\$asset_path);\n")
->write("\$asset->set_path(\$local_file, true);\n")
->outdent()
->write("}\n")
@@ -55,10 +49,10 @@ abstract class includeasset extends \Twig_Node
->write("\n")
->write("if (\$asset->is_relative()) {\n")
->indent()
- ->write("\$asset->add_assets_version('{$config['assets_version']}');\n")
+ ->write("\$asset->add_assets_version(\$this->env->get_phpbb_config()['assets_version']);\n")
->outdent()
->write("}\n")
- ->write("\$this->getEnvironment()->get_assets_bag()->add_{$this->get_setters_name()}(\$asset);")
+ ->write("\$this->env->get_assets_bag()->add_{$this->get_setters_name()}(\$asset);")
;
}
diff --git a/phpBB/phpbb/template/twig/node/includephp.php b/phpBB/phpbb/template/twig/node/includephp.php
index 76182c2f84..0cf95abe99 100644
--- a/phpBB/phpbb/template/twig/node/includephp.php
+++ b/phpBB/phpbb/template/twig/node/includephp.php
@@ -63,15 +63,15 @@ class includephp extends \Twig_Node
// Absolute path specified
->write("require(\$location);\n")
->outdent()
- ->write("} else if (file_exists(\$this->getEnvironment()->get_phpbb_root_path() . \$location)) {\n")
+ ->write("} else if (file_exists(\$this->env->get_phpbb_root_path() . \$location)) {\n")
->indent()
// PHP file relative to phpbb_root_path
- ->write("require(\$this->getEnvironment()->get_phpbb_root_path() . \$location);\n")
+ ->write("require(\$this->env->get_phpbb_root_path() . \$location);\n")
->outdent()
->write("} else {\n")
->indent()
// Local path (behaves like INCLUDE)
- ->write("require(\$this->getEnvironment()->getLoader()->getCacheKey(\$location));\n")
+ ->write("require(\$this->env->getLoader()->getCacheKey(\$location));\n")
->outdent()
->write("}\n")
;
diff --git a/phpBB/phpbb/template/twig/tokenparser/defineparser.php b/phpBB/phpbb/template/twig/tokenparser/defineparser.php
index b755836ccd..6285091e94 100644
--- a/phpBB/phpbb/template/twig/tokenparser/defineparser.php
+++ b/phpBB/phpbb/template/twig/tokenparser/defineparser.php
@@ -21,7 +21,7 @@ class defineparser extends \Twig_TokenParser
*
* @param \Twig_Token $token A Twig_Token instance
*
- * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ * @return \Twig_Node A Twig_Node instance
* @throws \Twig_Error_Syntax
* @throws \phpbb\template\twig\node\definenode
*/
@@ -41,7 +41,7 @@ class defineparser extends \Twig_TokenParser
{
// This would happen if someone improperly formed their DEFINE syntax
// e.g. <!-- DEFINE $VAR = foo -->
- throw new \Twig_Error_Syntax('Invalid DEFINE', $token->getLine(), $this->parser->getFilename());
+ throw new \Twig_Error_Syntax('Invalid DEFINE', $token->getLine(), $this->parser->getStream()->getSourceContext()->getPath());
}
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
diff --git a/phpBB/phpbb/template/twig/tokenparser/event.php b/phpBB/phpbb/template/twig/tokenparser/event.php
index f73ef4ae25..92ecff4a74 100644
--- a/phpBB/phpbb/template/twig/tokenparser/event.php
+++ b/phpBB/phpbb/template/twig/tokenparser/event.php
@@ -15,12 +15,25 @@ namespace phpbb\template\twig\tokenparser;
class event extends \Twig_TokenParser
{
+ /** @var \phpbb\template\twig\environment */
+ protected $environment;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\template\twig\environment $environment
+ */
+ public function __construct(\phpbb\template\twig\environment $environment)
+ {
+ $this->environment = $environment;
+ }
+
/**
* Parses a token and returns a node.
*
* @param \Twig_Token $token A Twig_Token instance
*
- * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ * @return \Twig_Node A Twig_Node instance
*/
public function parse(\Twig_Token $token)
{
@@ -29,7 +42,7 @@ class event extends \Twig_TokenParser
$stream = $this->parser->getStream();
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
- return new \phpbb\template\twig\node\event($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag());
+ return new \phpbb\template\twig\node\event($expr, $this->environment, $token->getLine(), $this->getTag());
}
/**
diff --git a/phpBB/phpbb/template/twig/tokenparser/includecss.php b/phpBB/phpbb/template/twig/tokenparser/includecss.php
index 1f30811754..f7e55a46fb 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includecss.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includecss.php
@@ -20,7 +20,7 @@ class includecss extends \Twig_TokenParser
*
* @param \Twig_Token $token A Twig_Token instance
*
- * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ * @return \Twig_Node A Twig_Node instance
*/
public function parse(\Twig_Token $token)
{
@@ -29,7 +29,7 @@ class includecss extends \Twig_TokenParser
$stream = $this->parser->getStream();
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
- return new \phpbb\template\twig\node\includecss($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag());
+ return new \phpbb\template\twig\node\includecss($expr, $token->getLine(), $this->getTag());
}
/**
diff --git a/phpBB/phpbb/template/twig/tokenparser/includejs.php b/phpBB/phpbb/template/twig/tokenparser/includejs.php
index 4b67d2c468..598ea0a70d 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includejs.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includejs.php
@@ -20,7 +20,7 @@ class includejs extends \Twig_TokenParser
*
* @param \Twig_Token $token A Twig_Token instance
*
- * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ * @return \Twig_Node A Twig_Node instance
*/
public function parse(\Twig_Token $token)
{
@@ -29,7 +29,7 @@ class includejs extends \Twig_TokenParser
$stream = $this->parser->getStream();
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
- return new \phpbb\template\twig\node\includejs($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag());
+ return new \phpbb\template\twig\node\includejs($expr, $token->getLine(), $this->getTag());
}
/**
diff --git a/phpBB/phpbb/template/twig/tokenparser/includeparser.php b/phpBB/phpbb/template/twig/tokenparser/includeparser.php
index aa7236aaa6..2fba4ac4c4 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includeparser.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includeparser.php
@@ -21,7 +21,7 @@ class includeparser extends \Twig_TokenParser_Include
*
* @param \Twig_Token $token A Twig_Token instance
*
- * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ * @return \Twig_Node A Twig_Node instance
*/
public function parse(\Twig_Token $token)
{
diff --git a/phpBB/phpbb/template/twig/tokenparser/includephp.php b/phpBB/phpbb/template/twig/tokenparser/includephp.php
index 3992636f8c..2fdf396452 100644
--- a/phpBB/phpbb/template/twig/tokenparser/includephp.php
+++ b/phpBB/phpbb/template/twig/tokenparser/includephp.php
@@ -16,12 +16,25 @@ namespace phpbb\template\twig\tokenparser;
class includephp extends \Twig_TokenParser
{
+ /** @var \phpbb\template\twig\environment */
+ protected $environment;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\template\twig\environment $environment
+ */
+ public function __construct(\phpbb\template\twig\environment $environment)
+ {
+ $this->environment = $environment;
+ }
+
/**
* Parses a token and returns a node.
*
* @param \Twig_Token $token A Twig_Token instance
*
- * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ * @return \Twig_Node A Twig_Node instance
*/
public function parse(\Twig_Token $token)
{
@@ -40,7 +53,7 @@ class includephp extends \Twig_TokenParser
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
- return new \phpbb\template\twig\node\includephp($expr, $this->parser->getEnvironment(), $token->getLine(), $ignoreMissing, $this->getTag());
+ return new \phpbb\template\twig\node\includephp($expr, $this->environment, $token->getLine(), $ignoreMissing, $this->getTag());
}
/**
diff --git a/phpBB/phpbb/template/twig/tokenparser/php.php b/phpBB/phpbb/template/twig/tokenparser/php.php
index f11ce35896..3007912b47 100644
--- a/phpBB/phpbb/template/twig/tokenparser/php.php
+++ b/phpBB/phpbb/template/twig/tokenparser/php.php
@@ -15,12 +15,25 @@ namespace phpbb\template\twig\tokenparser;
class php extends \Twig_TokenParser
{
+ /** @var \phpbb\template\twig\environment */
+ protected $environment;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\template\twig\environment $environment
+ */
+ public function __construct(\phpbb\template\twig\environment $environment)
+ {
+ $this->environment = $environment;
+ }
+
/**
* Parses a token and returns a node.
*
* @param \Twig_Token $token A Twig_Token instance
*
- * @return \Twig_NodeInterface A Twig_NodeInterface instance
+ * @return \Twig_Node A Twig_Node instance
*/
public function parse(\Twig_Token $token)
{
@@ -32,7 +45,7 @@ class php extends \Twig_TokenParser
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
- return new \phpbb\template\twig\node\php($body, $this->parser->getEnvironment(), $token->getLine(), $this->getTag());
+ return new \phpbb\template\twig\node\php($body, $this->environment, $token->getLine(), $this->getTag());
}
public function decideEnd(\Twig_Token $token)
diff --git a/phpBB/phpbb/textformatter/s9e/bbcode_merger.php b/phpBB/phpbb/textformatter/s9e/bbcode_merger.php
index 264eb93782..d1bedb0b72 100644
--- a/phpBB/phpbb/textformatter/s9e/bbcode_merger.php
+++ b/phpBB/phpbb/textformatter/s9e/bbcode_merger.php
@@ -14,7 +14,7 @@
namespace phpbb\textformatter\s9e;
use phpbb\textformatter\s9e\factory;
-use s9e\TextFormatter\Configurator\Helpers\TemplateHelper;
+use s9e\TextFormatter\Configurator\Helpers\TemplateLoader;
use s9e\TextFormatter\Configurator\Items\UnsafeTemplate;
class bbcode_merger
@@ -91,9 +91,9 @@ class bbcode_merger
*/
protected function indent_template($template)
{
- $dom = TemplateHelper::loadTemplate($template);
+ $dom = TemplateLoader::load($template);
$dom->formatOutput = true;
- $template = TemplateHelper::saveTemplate($dom);
+ $template = TemplateLoader::save($dom);
// Remove the first level of indentation if the template starts with whitespace
if (preg_match('(^\\n +)', $template, $m))
diff --git a/phpBB/phpbb/ucp/controller/reset_password.php b/phpBB/phpbb/ucp/controller/reset_password.php
new file mode 100644
index 0000000000..5c27c4f414
--- /dev/null
+++ b/phpBB/phpbb/ucp/controller/reset_password.php
@@ -0,0 +1,443 @@
+<?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\ucp\controller;
+
+use phpbb\auth\auth;
+use phpbb\config\config;
+use phpbb\controller\helper;
+use phpbb\db\driver\driver_interface;
+use phpbb\event\dispatcher;
+use phpbb\exception\http_exception;
+use phpbb\language\language;
+use phpbb\log\log_interface;
+use phpbb\passwords\manager;
+use phpbb\request\request_interface;
+use phpbb\template\template;
+use phpbb\user;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+* Handling forgotten passwords via reset password functionality
+*/
+class reset_password
+{
+ /** @var config */
+ protected $config;
+
+ /** @var driver_interface */
+ protected $db;
+
+ /** @var dispatcher */
+ protected $dispatcher;
+
+ /** @var helper */
+ protected $helper;
+
+ /** @var language */
+ protected $language;
+
+ /** @var log_interface */
+ protected $log;
+
+ /** @var manager */
+ protected $passwords_manager;
+
+ /** @var request_interface */
+ protected $request;
+
+ /** @var template */
+ protected $template;
+
+ /** @var user */
+ protected $user;
+
+ /** @var array phpBB DB table names */
+ protected $users_table;
+
+ /** @var string phpBB root path */
+ protected $root_path;
+
+ /** @var string PHP extension */
+ protected $php_ext;
+
+ /**
+ * Reset password controller constructor.
+ *
+ * @param config $config
+ * @param driver_interface $db
+ * @param dispatcher $dispatcher
+ * @param helper $helper
+ * @param language $language
+ * @param log_interface $log
+ * @param manager $passwords_manager
+ * @param request_interface $request
+ * @param template $template
+ * @param user $user
+ * @param string $users_table
+ * @param string $root_path
+ * @param string $php_ext
+ */
+ public function __construct(config $config, driver_interface $db, dispatcher $dispatcher, helper $helper,
+ language $language, log_interface $log, manager $passwords_manager,
+ request_interface $request, template $template, user $user, string $users_table,
+ string $root_path, string $php_ext)
+ {
+ $this->config = $config;
+ $this->db = $db;
+ $this->dispatcher = $dispatcher;
+ $this->helper = $helper;
+ $this->language = $language;
+ $this->log = $log;
+ $this->passwords_manager = $passwords_manager;
+ $this->request = $request;
+ $this->template = $template;
+ $this->user = $user;
+ $this->users_table = $users_table;
+ $this->root_path = $root_path;
+ $this->php_ext = $php_ext;
+ }
+
+ /**
+ * Init controller
+ */
+ protected function init_controller()
+ {
+ $this->language->add_lang('ucp');
+
+ if (!$this->config['allow_password_reset'])
+ {
+ throw new http_exception(Response::HTTP_OK, 'UCP_PASSWORD_RESET_DISABLED', [
+ '<a href="mailto:' . htmlspecialchars($this->config['board_contact']) . '">',
+ '</a>'
+ ]);
+ }
+ }
+
+ /**
+ * Remove reset token for specified user
+ *
+ * @param int $user_id User ID
+ */
+ protected function remove_reset_token(int $user_id)
+ {
+ $sql_ary = [
+ 'reset_token' => '',
+ 'reset_token_expiration' => 0,
+ ];
+
+ $sql = 'UPDATE ' . $this->users_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . '
+ WHERE user_id = ' . $user_id;
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * Handle password reset request
+ *
+ * @return Response
+ */
+ public function request()
+ {
+ $this->init_controller();
+
+ $submit = $this->request->is_set_post('submit');
+ $username = $this->request->variable('username', '', true);
+ $email = strtolower($this->request->variable('email', ''));
+
+ add_form_key('ucp_reset_password');
+
+ if ($submit)
+ {
+ if (!check_form_key('ucp_reset_password'))
+ {
+ throw new http_exception(Response::HTTP_UNAUTHORIZED, 'FORM_INVALID');
+ }
+
+ if (empty($email))
+ {
+ return $this->helper->message('NO_EMAIL_USER');
+ }
+
+ $sql_array = [
+ '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 = '" . $this->db->sql_escape($email) . "'" .
+ (!empty($username) ? " AND username_clean = '" . $this->db->sql_escape(utf8_clean_string($username)) . "'" : ''),
+ ];
+
+ /**
+ * Change SQL query for fetching user data
+ *
+ * @event core.ucp_remind_modify_select_sql
+ * @var string email User's email from the form
+ * @var string username User's username from the form
+ * @var array sql_array Fully assembled SQL query with keys SELECT, FROM, WHERE
+ * @since 3.1.11-RC1
+ * @changed 3.3.0-b1 Moved to reset password controller
+ */
+ $vars = [
+ 'email',
+ 'username',
+ 'sql_array',
+ ];
+ extract($this->dispatcher->trigger_event('core.ucp_remind_modify_select_sql', compact($vars)));
+
+ $sql = $this->db->sql_build_query('SELECT', $sql_array);
+ $result = $this->db->sql_query_limit($sql, 2); // don't waste resources on more rows than we need
+ $rowset = $this->db->sql_fetchrowset($result);
+ $this->db->sql_freeresult($result);
+
+ if (count($rowset) > 1)
+ {
+ $this->template->assign_vars([
+ 'USERNAME_REQUIRED' => true,
+ 'EMAIL' => $email,
+ ]);
+ }
+ else
+ {
+ $message = $this->language->lang('PASSWORD_RESET_LINK_SENT') . '<br /><br />' . $this->language->lang('RETURN_INDEX', '<a href="' . append_sid("{$this->root_path}index.{$this->php_ext}") . '">', '</a>');
+
+ if (empty($rowset))
+ {
+ return $this->helper->message($message);
+ }
+
+ $user_row = $rowset[0];
+
+ if ($user_row['user_type'] == USER_IGNORE || $user_row['user_type'] == USER_INACTIVE)
+ {
+ return $this->helper->message($message);
+ }
+
+ // Do not create multiple valid reset tokens
+ if (!empty($user_row['reset_token']) && (int) $user_row['reset_token_expiration'] >= time())
+ {
+ return $this->helper->message($message);
+ }
+
+ // Check users permissions
+ $auth = new auth();
+ $auth->acl($user_row);
+
+ if (!$auth->acl_get('u_chgpasswd'))
+ {
+ return $this->helper->message($message);
+ }
+
+ // Generate reset token
+ $reset_token = strtolower(gen_rand_string(32));
+
+ $sql_ary = [
+ 'reset_token' => $reset_token,
+ 'reset_token_expiration' => strtotime('+1 day'),
+ ];
+
+ $sql = 'UPDATE ' . $this->users_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . '
+ WHERE user_id = ' . $user_row['user_id'];
+ $this->db->sql_query($sql);
+
+ if (!class_exists('messenger'))
+ {
+ include($this->root_path . 'includes/functions_messenger.' . $this->php_ext);
+ }
+
+ /** @var \messenger $messenger */
+ $messenger = new \messenger(false);
+
+ $messenger->template('user_forgot_password', $user_row['user_lang']);
+
+ $messenger->set_addresses($user_row);
+
+ $messenger->anti_abuse_headers($this->config, $this->user);
+
+ $messenger->assign_vars([
+ 'USERNAME' => htmlspecialchars_decode($user_row['username']),
+ 'U_RESET_PASSWORD' => generate_board_url(true) . $this->helper->route('phpbb_ucp_reset_password_controller', [
+ 'u' => $user_row['user_id'],
+ 'token' => $reset_token,
+ ], false)
+ ]);
+
+ $messenger->send($user_row['user_notify_type']);
+
+ return $this->helper->message($message);
+ }
+ }
+
+ $this->template->assign_vars([
+ 'USERNAME' => $username,
+ 'EMAIL' => $email,
+ 'U_RESET_PASSWORD_ACTION' => $this->helper->route('phpbb_ucp_forgot_password_controller'),
+ ]);
+
+ return $this->helper->render('ucp_reset_password.html', $this->language->lang('RESET_PASSWORD'));
+ }
+
+ /**
+ * Handle controller requests
+ *
+ * @return Response
+ */
+ public function reset()
+ {
+ $this->init_controller();
+
+ $submit = $this->request->is_set_post('submit');
+ $reset_token = $this->request->variable('token', '');
+ $user_id = $this->request->variable('u', 0);
+
+ if (empty($reset_token))
+ {
+ return $this->helper->message('NO_RESET_TOKEN');
+ }
+
+ if (!$user_id)
+ {
+ return $this->helper->message('NO_USER');
+ }
+
+ add_form_key('ucp_reset_password');
+
+ $sql_array = [
+ '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_id = ' . $user_id,
+ ];
+
+ /**
+ * Change SQL query for fetching user data
+ *
+ * @event core.ucp_reset_password_modify_select_sql
+ * @var int user_id User ID from the form
+ * @var string reset_token Reset token
+ * @var array sql_array Fully assembled SQL query with keys SELECT, FROM, WHERE
+ * @since 3.3.0-b1
+ */
+ $vars = [
+ 'user_id',
+ 'reset_token',
+ 'sql_array',
+ ];
+ extract($this->dispatcher->trigger_event('core.ucp_reset_password_modify_select_sql', compact($vars)));
+
+ $sql = $this->db->sql_build_query('SELECT', $sql_array);
+ $result = $this->db->sql_query_limit($sql, 1);
+ $user_row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ $message = $this->language->lang('RESET_TOKEN_EXPIRED_OR_INVALID') . '<br /><br />' . $this->language->lang('RETURN_INDEX', '<a href="' . append_sid("{$this->root_path}index.{$this->php_ext}") . '">', '</a>');
+
+ if (empty($user_row))
+ {
+ return $this->helper->message($message);
+ }
+
+ if (!hash_equals($reset_token, $user_row['reset_token']))
+ {
+ return $this->helper->message($message);
+ }
+
+ if ($user_row['reset_token_expiration'] < time())
+ {
+ $this->remove_reset_token($user_id);
+
+ return $this->helper->message($message);
+ }
+
+ $errors = [];
+
+ if ($submit)
+ {
+ if (!check_form_key('ucp_reset_password'))
+ {
+ return $this->helper->message('FORM_INVALID');
+ }
+
+ if ($user_row['user_type'] == USER_IGNORE || $user_row['user_type'] == USER_INACTIVE)
+ {
+ return $this->helper->message($message);
+ }
+
+ // Check users permissions
+ $auth = new auth();
+ $auth->acl($user_row);
+
+ if (!$auth->acl_get('u_chgpasswd'))
+ {
+ return $this->helper->message($message);
+ }
+
+ if (!function_exists('validate_data'))
+ {
+ include($this->root_path . 'includes/functions_user.' . $this->php_ext);
+ }
+
+ $data = [
+ 'new_password' => $this->request->untrimmed_variable('new_password', '', true),
+ 'password_confirm' => $this->request->untrimmed_variable('new_password_confirm', '', true),
+ ];
+ $check_data = [
+ 'new_password' => [
+ ['string', false, $this->config['min_pass_chars'], 0],
+ ['password'],
+ ],
+ 'password_confirm' => ['string', true, $this->config['min_pass_chars'], 0],
+ ];
+ $errors = array_merge($errors, validate_data($data, $check_data));
+ if (strcmp($data['new_password'], $data['password_confirm']) !== 0)
+ {
+ $errors[] = $data['password_confirm'] ? 'NEW_PASSWORD_ERROR' : 'NEW_PASSWORD_CONFIRM_EMPTY';
+ }
+ if (empty($errors))
+ {
+ $sql_ary = [
+ 'user_password' => $this->passwords_manager->hash($data['new_password']),
+ 'user_login_attempts' => 0,
+ 'reset_token' => '',
+ 'reset_token_expiration' => 0,
+ ];
+ $sql = 'UPDATE ' . $this->users_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . '
+ WHERE user_id = ' . (int) $user_row['user_id'];
+ $this->db->sql_query($sql);
+ $this->log->add('user', $user_row['user_id'], $this->user->ip, 'LOG_USER_NEW_PASSWORD', false, [
+ 'reportee_id' => $user_row['user_id'],
+ $user_row['username']
+ ]);
+ meta_refresh(3, append_sid("{$this->root_path}index.{$this->php_ext}"));
+ return $this->helper->message($this->language->lang('PASSWORD_RESET'));
+ }
+ }
+
+ if (!empty($errors))
+ {
+ $this->template->assign_block_vars_array('PASSWORD_RESET_ERRORS', array_map([$this->language, 'lang'], $errors));
+ }
+
+ $this->template->assign_vars([
+ 'S_IS_PASSWORD_RESET' => true,
+ 'U_RESET_PASSWORD_ACTION' => $this->helper->route('phpbb_ucp_reset_password_controller'),
+ 'S_HIDDEN_FIELDS' => build_hidden_fields([
+ 'u' => $user_id,
+ 'token' => $reset_token,
+ ]),
+ ]);
+
+ return $this->helper->render('ucp_reset_password.html', $this->language->lang('RESET_PASSWORD'));
+ }
+}
diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php
index 9817e40edb..21d156e060 100644
--- a/phpBB/phpbb/user.php
+++ b/phpBB/phpbb/user.php
@@ -110,7 +110,7 @@ class user extends \phpbb\session
function setup($lang_set = false, $style_id = false)
{
global $db, $request, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache;
- global $phpbb_dispatcher;
+ global $phpbb_dispatcher, $phpbb_container;
$this->language->set_default_language($config['default_lang']);
@@ -361,8 +361,8 @@ class user extends \phpbb\session
}
// Disable board if the install/ directory is still present
- // For the brave development army we do not care about this, else we need to comment out this everytime we develop locally
- if (!defined('DEBUG') && !defined('ADMIN_START') && !defined('IN_INSTALL') && !defined('IN_LOGIN') && file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install'))
+ // For the brave development army we do not care about this, else we need to comment out this every time we develop locally
+ if (!$phpbb_container->getParameter('allow_install_dir') && !defined('ADMIN_START') && !defined('IN_INSTALL') && !defined('IN_LOGIN') && file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install'))
{
// Adjust the message slightly according to the permissions
if ($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))
@@ -480,7 +480,7 @@ class user extends \phpbb\session
* @return int|bool The plural-case we need to use for the number plural-rule combination, false if $force_rule
* was invalid.
*
- * @deprecated: 3.2.0-dev (To be removed: 3.3.0)
+ * @deprecated: 3.2.0-dev (To be removed: 4.0.0)
*/
function get_plural_form($number, $force_rule = false)
{
@@ -491,8 +491,8 @@ class user extends \phpbb\session
* Add Language Items - use_db and use_help are assigned where needed (only use them to force inclusion)
*
* @param mixed $lang_set specifies the language entries to include
- * @param bool $use_db internal variable for recursion, do not use @deprecated 3.2.0-dev (To be removed: 3.3.0)
- * @param bool $use_help internal variable for recursion, do not use @deprecated 3.2.0-dev (To be removed: 3.3.0)
+ * @param bool $use_db internal variable for recursion, do not use @deprecated 3.2.0-dev (To be removed: 4.0.0)
+ * @param bool $use_help internal variable for recursion, do not use @deprecated 3.2.0-dev (To be removed: 4.0.0)
* @param string $ext_name The extension to load language from, or empty for core files
*
* Examples:
@@ -507,7 +507,7 @@ class user extends \phpbb\session
* Note: $use_db and $use_help should be removed. The old function was kept for BC purposes,
* so the BC logic is handled here.
*
- * @deprecated: 3.2.0-dev (To be removed: 3.3.0)
+ * @deprecated: 3.2.0-dev (To be removed: 4.0.0)
*/
function add_lang($lang_set, $use_db = false, $use_help = false, $ext_name = '')
{
@@ -548,7 +548,7 @@ class user extends \phpbb\session
/**
* BC function for loading language files
*
- * @deprecated 3.2.0-dev (To be removed: 3.3.0)
+ * @deprecated 3.2.0-dev (To be removed: 4.0.0)
*/
private function set_lang($lang_set, $use_help, $ext_name)
{
@@ -584,7 +584,7 @@ class user extends \phpbb\session
*
* Note: $use_db and $use_help should be removed. Kept for BC purposes.
*
- * @deprecated: 3.2.0-dev (To be removed: 3.3.0)
+ * @deprecated: 3.2.0-dev (To be removed: 4.0.0)
*/
function add_lang_ext($ext_name, $lang_set, $use_db = false, $use_help = false)
{
@@ -786,7 +786,7 @@ class user extends \phpbb\session
}
/**
- * Funtion to make the user leave the NEWLY_REGISTERED system group.
+ * Function to make the user leave the NEWLY_REGISTERED system group.
* @access public
*/
function leave_newly_registered()
diff --git a/phpBB/phpbb/user_loader.php b/phpBB/phpbb/user_loader.php
index 9297450f3e..3dacf07ff5 100644
--- a/phpBB/phpbb/user_loader.php
+++ b/phpBB/phpbb/user_loader.php
@@ -123,7 +123,7 @@ class user_loader
/**
* Get a user row from our users cache
*
- * @param int $user_id User ID of the user you want to retreive
+ * @param int $user_id User ID of the user you want to retrieve
* @param bool $query Should we query the database if this user has not yet been loaded?
* Typically this should be left as false and you should make sure
* you load users ahead of time with load_users()
@@ -150,7 +150,7 @@ class user_loader
/**
* Get username
*
- * @param int $user_id User ID of the user you want to retreive the username for
+ * @param int $user_id User ID of the user you want to retrieve the username for
* @param string $mode The mode to load (same as get_username_string). One of the following:
* profile (for getting an url to the profile)
* username (for obtaining the username)
@@ -204,7 +204,7 @@ class user_loader
/**
* Get rank
*
- * @param int $user_id User ID of the user you want to retreive the rank for
+ * @param int $user_id User ID of the user you want to retrieve the rank for
* @param bool $query Should we query the database if this user has not yet been loaded?
* Typically this should be left as false and you should make sure
* you load users ahead of time with load_users()
diff --git a/phpBB/posting.php b/phpBB/posting.php
index 59616a2858..c5d0693f35 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -40,7 +40,7 @@ $load = (isset($_POST['load'])) ? true : false;
$confirm = $request->is_set_post('confirm');
$cancel = (isset($_POST['cancel']) && !isset($_POST['save'])) ? true : false;
-$refresh = (isset($_POST['add_file']) || isset($_POST['delete_file']) || isset($_POST['cancel_unglobalise']) || $save || $load || $preview);
+$refresh = (isset($_POST['add_file']) || isset($_POST['delete_file']) || $save || $load || $preview);
$submit = $request->is_set_post('post') && !$refresh && !$preview;
$mode = $request->variable('mode', '');
diff --git a/phpBB/report.php b/phpBB/report.php
index bb26b972aa..d0d7b3776a 100644
--- a/phpBB/report.php
+++ b/phpBB/report.php
@@ -35,7 +35,7 @@ $controller_helper = $phpbb_container->get('controller.helper');
$response = new RedirectResponse(
$controller_helper->route($redirect_route_name, array(
'id' => ($pm_id === 0) ? $post_id : $pm_id,
- )),
+ ), false),
301
);
$response->send();
diff --git a/phpBB/search.php b/phpBB/search.php
index 64f6041371..bd8025dae5 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -129,6 +129,11 @@ $phpbb_content_visibility = $phpbb_container->get('content.visibility');
/* @var $pagination \phpbb\pagination */
$pagination = $phpbb_container->get('pagination');
+$template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $user->lang('SEARCH'),
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}search.$phpEx"),
+));
+
/**
* This event allows you to alter the above parameters, such as keywords and submit
*
@@ -511,6 +516,11 @@ if ($keywords || $author || $author_id || $search_id || $submit)
$l_search_title = $user->lang['SEARCH_SELF'];
break;
}
+
+ $template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $l_search_title,
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}search.$phpEx", "search_id=$search_id"),
+ ));
}
/**
@@ -710,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?
@@ -718,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 8e3ba24aaa..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.2.8
-phpbb_version = 3.2.8
+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/attachment.html b/phpBB/styles/prosilver/template/attachment.html
index 615717e026..45b9dc2145 100644
--- a/phpBB/styles/prosilver/template/attachment.html
+++ b/phpBB/styles/prosilver/template/attachment.html
@@ -29,19 +29,6 @@
</dl>
<!-- ENDIF -->
- <!-- IF _file.S_FLASH_FILE -->
- <object classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=5,0,0,0" width="{_file.WIDTH}" height="{_file.HEIGHT}">
- <param name="movie" value="{_file.U_VIEW_LINK}" />
- <param name="play" value="true" />
- <param name="loop" value="true" />
- <param name="quality" value="high" />
- <param name="allowScriptAccess" value="never" />
- <param name="allowNetworking" value="internal" />
- <embed src="{_file.U_VIEW_LINK}" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" width="{_file.WIDTH}" height="{_file.HEIGHT}" play="true" loop="true" quality="high" allowscriptaccess="never" allownetworking="internal"></embed>
- </object>
- <p><a href="{_file.U_DOWNLOAD_LINK}">{_file.DOWNLOAD_NAME}</a> [ {_file.FILESIZE} {_file.SIZE_LANG} | {_file.L_DOWNLOAD_COUNT} ]</p>
- <!-- ENDIF -->
-
<!-- EVENT attachment_file_append -->
<!-- ENDIF -->
<!-- END _file -->
diff --git a/phpBB/styles/prosilver/template/captcha_recaptcha.html b/phpBB/styles/prosilver/template/captcha_recaptcha.html
index a123f543a8..8fc7faa50f 100644
--- a/phpBB/styles/prosilver/template/captcha_recaptcha.html
+++ b/phpBB/styles/prosilver/template/captcha_recaptcha.html
@@ -1,30 +1,9 @@
-<!-- IF S_TYPE == 1 -->
-<div class="panel captcha-panel">
- <div class="inner">
-
- <h3 class="captcha-title">{L_CONFIRMATION}</h3>
- <p>{L_CONFIRM_EXPLAIN}</p>
-
- <fieldset class="fields2">
-<!-- ENDIF -->
-
<!-- IF S_RECAPTCHA_AVAILABLE -->
- <dl>
- <dt><label>{L_CONFIRM_CODE}{L_COLON}</label><br /><span>{L_RECAPTCHA_EXPLAIN}</span></dt>
- <dd class="captcha">
- <noscript>
- <div>{L_RECAPTCHA_NOSCRIPT}</div>
- </noscript>
- <script src="{RECAPTCHA_SERVER}.js?hl={LA_RECAPTCHA_LANG}" async defer></script>
- <div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}" data-tabindex="<!-- IF $CAPTCHA_TAB_INDEX -->{$CAPTCHA_TAB_INDEX}<!-- ELSE -->10<!-- ENDIF -->"></div>
- </dd>
- </dl>
+ <noscript>
+ <div>{L_RECAPTCHA_NOSCRIPT}</div>
+ </noscript>
+ {% INCLUDEJS RECAPTCHA_SERVER ~ '.js?onload=phpbbRecaptchaOnLoad&hl=' ~ lang('RECAPTCHA_LANG') %}
+ <div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}" data-callback="phpbbRecaptchaOnSubmit" data-size="invisible" data-tabindex="<!-- IF $CAPTCHA_TAB_INDEX -->{$CAPTCHA_TAB_INDEX}<!-- ELSE -->10<!-- ENDIF -->"></div>
<!-- ELSE -->
{L_RECAPTCHA_NOT_AVAILABLE}
<!-- ENDIF -->
-
-<!-- IF S_TYPE == 1 -->
- </fieldset>
- </div>
-</div>
-<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js
index 3f28f8a326..2e393657e8 100644
--- a/phpBB/styles/prosilver/template/forum_fn.js
+++ b/phpBB/styles/prosilver/template/forum_fn.js
@@ -460,7 +460,7 @@ function parseDocument($container) {
$linksLast = $linksNotSkip.filter(filterLast), // The items that will be hidden last
persistent = $this.attr('id') === 'nav-main', // Does this list already have a menu (such as quick-links)?
html = '<li class="responsive-menu hidden"><a href="javascript:void(0);" class="js-responsive-menu-link responsive-menu-link"><i class="icon fa-bars fa-fw" aria-hidden="true"></i></a><div class="dropdown"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>',
- slack = 3; // Vertical slack space (in pixels). Determines how sensitive the script is in determining whether a line-break has occured.
+ slack = 3; // Vertical slack space (in pixels). Determines how sensitive the script is in determining whether a line-break has occurred.
// Add a hidden drop-down menu to each links list (except those that already have one)
if (!persistent) {
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/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html
index 77f5dae0c0..4a1a436d4a 100644
--- a/phpBB/styles/prosilver/template/navbar_header.html
+++ b/phpBB/styles/prosilver/template/navbar_header.html
@@ -189,8 +189,10 @@
<span class="crumb" {$MICRODATA}><a href="{U_INDEX}" itemtype="https://schema.org/Thing" itemscope itemprop="item" accesskey="h" data-navbar-reference="index"><!-- IF not U_SITE_HOME --><i class="icon fa-home fa-fw"></i><!-- ENDIF --><span itemprop="name">{L_INDEX}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span>
<!-- BEGIN navlinks -->
+ {% set NAVLINK_NAME = navlinks.BREADCRUMB_NAME | default(navlinks.FORUM_NAME) %}
+ {% set NAVLINK_LINK = navlinks.U_BREADCRUMB | default(navlinks.U_VIEW_FORUM) %}
<!-- EVENT overall_header_navlink_prepend -->
- <span class="crumb" {$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->><a href="{navlinks.U_VIEW_FORUM}" itemtype="https://schema.org/Thing" itemscope itemprop="item"><span itemprop="name">{navlinks.FORUM_NAME}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span>
+ <span class="crumb" {$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->><a href="{{ NAVLINK_LINK }}" itemtype="https://schema.org/Thing" itemscope itemprop="item"><span itemprop="name">{{ NAVLINK_NAME }}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span>
<!-- EVENT overall_header_navlink_append -->
<!-- END navlinks -->
<!-- EVENT overall_header_breadcrumb_append -->
diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html
index cd245decc4..d1b8863438 100644
--- a/phpBB/styles/prosilver/template/overall_footer.html
+++ b/phpBB/styles/prosilver/template/overall_footer.html
@@ -64,7 +64,7 @@
</div>
<script src="{T_JQUERY_LINK}"></script>
-<!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF -->
+<!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery-3.4.1.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF -->
<script src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- INCLUDEJS forum_fn.js -->
<!-- INCLUDEJS ajax.js -->
diff --git a/phpBB/styles/prosilver/template/posting_buttons.html b/phpBB/styles/prosilver/template/posting_buttons.html
index cb305eee4b..1564b5f522 100644
--- a/phpBB/styles/prosilver/template/posting_buttons.html
+++ b/phpBB/styles/prosilver/template/posting_buttons.html
@@ -31,7 +31,7 @@
<div id="colour_palette" style="display: none;">
<dl style="clear: left;">
<dt><label>{L_FONT_COLOR}{L_COLON}</label></dt>
- <dd id="color_palette_placeholder" class="color_palette_placeholder" data-orientation="h" data-height="12" data-width="15" data-bbcode="true"></dd>
+ <dd id="color_palette_placeholder" class="color_palette_placeholder" data-color-palette="h" data-height="12" data-width="15" data-bbcode="true"></dd>
</dl>
</div>
diff --git a/phpBB/styles/prosilver/template/posting_layout.html b/phpBB/styles/prosilver/template/posting_layout.html
index bca9195f0e..7c9deb5369 100644
--- a/phpBB/styles/prosilver/template/posting_layout.html
+++ b/phpBB/styles/prosilver/template/posting_layout.html
@@ -38,27 +38,6 @@
<!-- IF S_POST_REVIEW --><!-- INCLUDE posting_review.html --><!-- ENDIF -->
-<!-- IF S_UNGLOBALISE -->
- <div class="panel bg3">
- <div class="inner">
- <fieldset class="fields1">
- <h2>{L_SELECT_DESTINATION_FORUM}</h2>
- <p>{L_UNGLOBALISE_EXPLAIN}</p>
- <dl>
- <dt><label for="to_forum_id">{L_MOVE}{L_COLON}</label></dt>
- <dd><select id="to_forum_id" name="to_forum_id">{S_FORUM_SELECT}</select></dd>
- </dl>
-
- <dl>
- <dt>&nbsp;</dt>
- <dd><input class="button1" type="submit" name="post" value="{L_CONFIRM}" /> <input class="button2" type="submit" name="cancel_unglobalise" value="{L_CANCEL}" /></dd>
- </dl>
- </fieldset>
-
- </div>
- </div>
-<!-- ENDIF -->
-
<!-- IF S_DISPLAY_PREVIEW --><!-- INCLUDE posting_preview.html --><!-- ENDIF -->
<div class="panel" id="postingbox">
diff --git a/phpBB/styles/prosilver/template/simple_footer.html b/phpBB/styles/prosilver/template/simple_footer.html
index 1ef44d1688..fde162ab34 100644
--- a/phpBB/styles/prosilver/template/simple_footer.html
+++ b/phpBB/styles/prosilver/template/simple_footer.html
@@ -25,7 +25,7 @@
</div>
<script src="{T_JQUERY_LINK}"></script>
-<!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF -->
+<!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery-3.4.1.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF -->
<script src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- INCLUDEJS forum_fn.js -->
<!-- INCLUDEJS ajax.js -->
diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options_upload.html b/phpBB/styles/prosilver/template/ucp_avatar_options_upload.html
index 63a734ea7d..666950e0ae 100644
--- a/phpBB/styles/prosilver/template/ucp_avatar_options_upload.html
+++ b/phpBB/styles/prosilver/template/ucp_avatar_options_upload.html
@@ -1,6 +1,6 @@
<dl>
<dt><label for="avatar_upload_file">{L_UPLOAD_AVATAR_FILE}{L_COLON}</label></dt>
- <dd><input type="hidden" name="MAX_FILE_SIZE" value="{AVATAR_UPLOAD_SIZE}" /><input type="file" name="avatar_upload_file" id="avatar_upload_file" class="inputbox autowidth" /></dd>
+ <dd><input type="hidden" name="MAX_FILE_SIZE" value="{AVATAR_UPLOAD_SIZE}" /><input type="file" name="avatar_upload_file" id="avatar_upload_file" class="inputbox autowidth" accept="{{ AVATAR_ALLOWED_EXTENSIONS }}" /></dd>
</dl>
<!-- IF S_UPLOAD_AVATAR_URL -->
diff --git a/phpBB/styles/prosilver/template/ucp_groups_manage.html b/phpBB/styles/prosilver/template/ucp_groups_manage.html
index f2b4f003e0..adc8c614e6 100644
--- a/phpBB/styles/prosilver/template/ucp_groups_manage.html
+++ b/phpBB/styles/prosilver/template/ucp_groups_manage.html
@@ -58,7 +58,7 @@
<input name="group_colour" type="text" id="group_colour" value="{GROUP_COLOUR}" size="6" maxlength="6" class="inputbox narrow" />
<span style="background-color: #{GROUP_COLOUR};">&nbsp;&nbsp;&nbsp;</span>
[ <a href="#" id="color_palette_toggle">{L_COLOUR_SWATCH}</a> ]
- <div id="color_palette_placeholder" class="color_palette_placeholder hidden" data-orientation="h" data-height="12" data-width="15" data-target="#group_colour"></div>
+ <div id="color_palette_placeholder" class="color_palette_placeholder hidden" data-color-palette="h" data-height="12" data-width="15" data-target="#group_colour"></div>
</dd>
</dl>
<dl>
diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html
index bf39990c35..f44382f500 100644
--- a/phpBB/styles/prosilver/template/ucp_register.html
+++ b/phpBB/styles/prosilver/template/ucp_register.html
@@ -12,6 +12,17 @@
}
</script>
+{% if PROVIDER_TEMPLATE_FILE %}
+ <div class="panel">
+ <div class="inner">
+
+ <h2>{{ SITENAME }} - {{ lang('OAUTH_REGISTRATION') }}</h2>
+
+ {% include PROVIDER_TEMPLATE_FILE %}
+ </div>
+ </div>
+{% endif %}
+
<form id="register" method="post" action="{S_UCP_ACTION}"{S_FORM_ENCTYPE}>
<div class="panel">
diff --git a/phpBB/styles/prosilver/template/ucp_remind.html b/phpBB/styles/prosilver/template/ucp_remind.html
deleted file mode 100644
index 8b700de430..0000000000
--- a/phpBB/styles/prosilver/template/ucp_remind.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!-- INCLUDE overall_header.html -->
-
-<form action="{S_PROFILE_ACTION}" method="post" id="remind">
-
-<div class="panel">
- <div class="inner">
-
- <div class="content">
- <h2>{L_SEND_PASSWORD}</h2>
-
- <fieldset>
- {% if USERNAME_REQUIRED %}
- <p class="error">{{ lang('EMAIL_NOT_UNIQUE') }}</p>
- {% endif %}
- <dl>
- <dt><label for="email">{L_EMAIL_ADDRESS}{L_COLON}</label><br /><span>{L_EMAIL_REMIND}</span></dt>
- <dd><input class="inputbox narrow" type="email" name="email" id="email" size="25" maxlength="100" value="{{ EMAIL }}" autofocus /></dd>
- </dl>
- {% if USERNAME_REQUIRED %}
- <dl>
- <dt><label for="username">{L_USERNAME}{L_COLON}</label></dt>
- <dd><input class="inputbox narrow" type="text" name="username" id="username" size="25" /></dd>
- </dl>
- {% endif %}
- <dl>
- <dt>&nbsp;</dt>
- <dd>{S_HIDDEN_FIELDS}<input type="submit" name="submit" id="submit" class="button1" value="{L_SUBMIT}" tabindex="2" />&nbsp; <input type="reset" value="{L_RESET}" name="reset" class="button2" /></dd>
- </dl>
- {S_FORM_TOKEN}
- </fieldset>
- </div>
-
- </div>
-</div>
-</form>
-
-<!-- INCLUDE overall_footer.html -->
diff --git a/phpBB/styles/prosilver/template/ucp_reset_password.html b/phpBB/styles/prosilver/template/ucp_reset_password.html
new file mode 100644
index 0000000000..0a05f69aed
--- /dev/null
+++ b/phpBB/styles/prosilver/template/ucp_reset_password.html
@@ -0,0 +1,49 @@
+<!-- INCLUDE overall_header.html -->
+
+<form action="{{ U_RESET_PASSWORD_ACTION }}" method="post" id="reset_password">
+
+<div class="panel">
+ <div class="inner">
+
+ <div class="content">
+ <h2>{{ lang('RESET_PASSWORD') }}</h2>
+
+ <fieldset>
+ {% if S_IS_PASSWORD_RESET %}
+ {% if PASSWORD_RESET_ERRORS %}<p class="error">{{ PASSWORD_RESET_ERRORS | join('<br>') }}</p>{% endif %}
+ <dl>
+ <dt><label for="new_password">{{ lang('NEW_PASSWORD') ~ lang('COLON') }}</label></dt>
+ <dd><input type="password" name="new_password" id="new_password" size="25" maxlength="255" title="{{ lang('CHANGE_PASSWORD') }}" autocomplete="off" /></dd>
+ </dl>
+ <dl>
+ <dt><label for="new_password_confirm">{{ lang('CONFIRM_PASSWORD') ~ lang('COLON') }}</label></dt>
+ <dd><input type="password" name="new_password_confirm" id="new_password_confirm" size="25" maxlength="255" title="{{ lang('CONFIRM_PASSWORD') }}" autocomplete="off" /></dd>
+ </dl>
+ {% else %}
+ {% if USERNAME_REQUIRED %}
+ <p class="error">{{ lang('EMAIL_NOT_UNIQUE') }}</p>
+ {% endif %}
+ <dl>
+ <dt><label for="email">{{ lang('EMAIL_ADDRESS') ~ lang('COLON') }}</label><br /><span>{{ lang('EMAIL_REMIND') }}</span></dt>
+ <dd><input class="inputbox narrow" type="email" name="email" id="email" size="25" maxlength="100" value="{{ EMAIL }}" autofocus /></dd>
+ </dl>
+ {% if USERNAME_REQUIRED %}
+ <dl>
+ <dt><label for="username">{{ lang('USERNAME') ~ lang('COLON') }}</label></dt>
+ <dd><input class="inputbox narrow" type="text" name="username" id="username" size="25" /></dd>
+ </dl>
+ {% endif %}
+ {% endif %}
+ <dl>
+ <dt>&nbsp;</dt>
+ <dd>{{ S_HIDDEN_FIELDS }}<input type="submit" name="submit" id="submit" class="button1" value="{{ lang('SUBMIT') }}" tabindex="2" />&nbsp; <input type="reset" value="{{ lang('RESET') }}" name="reset" class="button2" /></dd>
+ </dl>
+ {{ S_FORM_TOKEN }}
+ </fieldset>
+ </div>
+
+ </div>
+</div>
+</form>
+
+<!-- INCLUDE overall_footer.html -->
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/styles/prosilver/theme/icons.css b/phpBB/styles/prosilver/theme/icons.css
index 6643f12d06..3ac598486c 100644
--- a/phpBB/styles/prosilver/theme/icons.css
+++ b/phpBB/styles/prosilver/theme/icons.css
@@ -5,7 +5,7 @@
/* Global module setup
--------------------------------*/
-/* Renamed version of .fa class for agnostic useage of icon fonts.
+/* Renamed version of .fa class for agnostic usage of icon fonts.
* Just change the name of the font after the 14/1 to the name of
* the font you wish to use.
*/
diff --git a/phpBB/styles/prosilver/theme/print.css b/phpBB/styles/prosilver/theme/print.css
index 9445279773..ee916dce51 100644
--- a/phpBB/styles/prosilver/theme/print.css
+++ b/phpBB/styles/prosilver/theme/print.css
@@ -90,7 +90,7 @@ hr {
font-size: 75%;
}
-/* Dont want to print url for names or titles in content area */
+/* Don't want to print url for names or titles in content area */
.postbody .author a:link, .postbody .author a:visited,
html>body .postbody .author a:link:after,
html>body .postbody .author a:visited:after,
diff --git a/phpBB/styles/prosilver/theme/stylesheet.css b/phpBB/styles/prosilver/theme/stylesheet.css
index 45eb5b6fc9..c402d563c6 100644
--- a/phpBB/styles/prosilver/theme/stylesheet.css
+++ b/phpBB/styles/prosilver/theme/stylesheet.css
@@ -1,21 +1,21 @@
/* phpBB3 Style Sheet
--------------------------------------------------------------
- Style name: prosilver (the default phpBB 3.2.x style)
+ Style name: prosilver (the default phpBB 3.3.x style)
Based on style:
Original author: Tom Beddard ( http://www.subblue.com/ )
Modified by: phpBB Limited ( https://www.phpbb.com/ )
--------------------------------------------------------------
*/
-@import url("normalize.css?v=3.2");
-@import url("base.css?v=3.2");
-@import url("utilities.css?v=3.2");
-@import url("common.css?v=3.2");
-@import url("links.css?v=3.2");
-@import url("content.css?v=3.2");
-@import url("buttons.css?v=3.2");
-@import url("cp.css?v=3.2");
-@import url("forms.css?v=3.2");
-@import url("icons.css?v=3.2");
-@import url("colours.css?v=3.2");
-@import url("responsive.css?v=3.2");
+@import url("normalize.css?v=3.3");
+@import url("base.css?v=3.3");
+@import url("utilities.css?v=3.3");
+@import url("common.css?v=3.3");
+@import url("links.css?v=3.3");
+@import url("content.css?v=3.3");
+@import url("buttons.css?v=3.3");
+@import url("cp.css?v=3.3");
+@import url("forms.css?v=3.3");
+@import url("icons.css?v=3.3");
+@import url("colours.css?v=3.3");
+@import url("responsive.css?v=3.3");
diff --git a/phpBB/ucp.php b/phpBB/ucp.php
index 96a3efea97..0992e3ef90 100644
--- a/phpBB/ucp.php
+++ b/phpBB/ucp.php
@@ -63,8 +63,10 @@ switch ($mode)
break;
case 'sendpassword':
- $module->load('ucp', 'remind');
- $module->display($user->lang['UCP_REMIND']);
+ /** @var \phpbb\controller\helper $controller_helper */
+ $controller_helper = $phpbb_container->get('controller.helper');
+
+ redirect($controller_helper->route('phpbb_ucp_forgot_password_controller'));
break;
case 'register':
@@ -393,6 +395,11 @@ if (!$config['allow_topic_notify'] && !$config['allow_forum_notify'])
$vars = array('module', 'id', 'mode');
extract($phpbb_dispatcher->trigger_event('core.ucp_display_module_before', compact($vars)));
+$template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $user->lang('UCP'),
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}ucp.$phpEx"),
+));
+
// Select the active module
$module->set_active($id, $mode);
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/viewonline.php b/phpBB/viewonline.php
index d5ddb0ba13..1b28750a0b 100644
--- a/phpBB/viewonline.php
+++ b/phpBB/viewonline.php
@@ -487,6 +487,11 @@ $start = $pagination->validate_start($start, $config['topics_per_page'], $counte
$base_url = append_sid("{$phpbb_root_path}viewonline.$phpEx", "sg=$show_guests&amp;sk=$sort_key&amp;sd=$sort_dir");
$pagination->generate_template_pagination($base_url, 'pagination', 'start', $counter, $config['topics_per_page'], $start);
+$template->assign_block_vars('navlinks', array(
+ 'BREADCRUMB_NAME' => $user->lang('WHO_IS_ONLINE'),
+ 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}viewonline.$phpEx"),
+));
+
// Send data to template
$template->assign_vars(array(
'TOTAL_REGISTERED_USERS_ONLINE' => $user->lang('REG_USERS_ONLINE', (int) $logged_visible_online, $user->lang('HIDDEN_USERS_ONLINE', (int) $logged_hidden_online)),
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,