aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB')
-rw-r--r--phpBB/.htaccess56
-rw-r--r--phpBB/adm/style/acp_attachments.html22
-rw-r--r--phpBB/adm/style/acp_logs.html10
-rw-r--r--phpBB/adm/style/acp_users.html10
-rw-r--r--phpBB/adm/style/acp_users_prefs.html10
-rw-r--r--phpBB/adm/style/admin.css5
-rw-r--r--phpBB/adm/style/simple_footer.html1
-rw-r--r--phpBB/adm/style/simple_header.html1
-rw-r--r--phpBB/assets/javascript/core.js435
-rwxr-xr-xphpBB/bin/phpbbcli.php4
-rw-r--r--phpBB/common.php31
-rw-r--r--phpBB/composer.json4
-rw-r--r--phpBB/composer.lock459
-rw-r--r--phpBB/config/console.yml23
-rw-r--r--phpBB/config/profilefields.yml1
-rw-r--r--phpBB/config/services.yml15
-rw-r--r--phpBB/develop/add_permissions.php1
-rw-r--r--phpBB/develop/create_schema_files.php1
-rw-r--r--phpBB/develop/export_events_for_wiki.php340
-rw-r--r--phpBB/docs/AUTHORS1
-rw-r--r--phpBB/docs/CHANGELOG.html218
-rw-r--r--phpBB/docs/INSTALL.html3
-rw-r--r--phpBB/docs/events.md321
-rw-r--r--phpBB/feed.php7
-rw-r--r--phpBB/includes/acp/acp_attachments.php9
-rw-r--r--phpBB/includes/acp/acp_ban.php2
-rw-r--r--phpBB/includes/acp/acp_bbcodes.php16
-rw-r--r--phpBB/includes/acp/acp_board.php2
-rw-r--r--phpBB/includes/acp/acp_bots.php27
-rw-r--r--phpBB/includes/acp/acp_captcha.php1
-rw-r--r--phpBB/includes/acp/acp_database.php114
-rw-r--r--phpBB/includes/acp/acp_extensions.php6
-rw-r--r--phpBB/includes/acp/acp_forums.php27
-rw-r--r--phpBB/includes/acp/acp_groups.php4
-rw-r--r--phpBB/includes/acp/acp_icons.php4
-rw-r--r--phpBB/includes/acp/acp_logs.php4
-rw-r--r--phpBB/includes/acp/acp_main.php2
-rw-r--r--phpBB/includes/acp/acp_permission_roles.php2
-rw-r--r--phpBB/includes/acp/acp_permissions.php1
-rw-r--r--phpBB/includes/acp/acp_php_info.php2
-rw-r--r--phpBB/includes/acp/acp_profile.php6
-rw-r--r--phpBB/includes/acp/acp_prune.php16
-rw-r--r--phpBB/includes/acp/acp_ranks.php1
-rw-r--r--phpBB/includes/acp/acp_reasons.php1
-rw-r--r--phpBB/includes/acp/acp_users.php103
-rw-r--r--phpBB/includes/acp/acp_words.php3
-rw-r--r--phpBB/includes/acp/auth.php1
-rw-r--r--phpBB/includes/captcha/captcha_gd.php21
-rw-r--r--phpBB/includes/compatibility_globals.php44
-rw-r--r--phpBB/includes/constants.php11
-rw-r--r--phpBB/includes/functions.php82
-rw-r--r--phpBB/includes/functions_acp.php8
-rw-r--r--phpBB/includes/functions_admin.php52
-rw-r--r--phpBB/includes/functions_content.php52
-rw-r--r--phpBB/includes/functions_convert.php2
-rw-r--r--phpBB/includes/functions_display.php13
-rw-r--r--phpBB/includes/functions_install.php22
-rw-r--r--phpBB/includes/functions_messenger.php7
-rw-r--r--phpBB/includes/functions_module.php2
-rw-r--r--phpBB/includes/functions_posting.php93
-rw-r--r--phpBB/includes/functions_privmsgs.php7
-rw-r--r--phpBB/includes/functions_upload.php2
-rw-r--r--phpBB/includes/functions_url_matcher.php22
-rw-r--r--phpBB/includes/functions_user.php54
-rw-r--r--phpBB/includes/mcp/info/mcp_pm_reports.php2
-rw-r--r--phpBB/includes/mcp/mcp_ban.php2
-rw-r--r--phpBB/includes/mcp/mcp_forum.php4
-rw-r--r--phpBB/includes/mcp/mcp_front.php4
-rw-r--r--phpBB/includes/mcp/mcp_main.php4
-rw-r--r--phpBB/includes/mcp/mcp_pm_reports.php4
-rw-r--r--phpBB/includes/mcp/mcp_post.php2
-rw-r--r--phpBB/includes/mcp/mcp_queue.php50
-rw-r--r--phpBB/includes/mcp/mcp_reports.php8
-rw-r--r--phpBB/includes/mcp/mcp_topic.php6
-rw-r--r--phpBB/includes/message_parser.php2
-rw-r--r--phpBB/includes/ucp/ucp_main.php2
-rw-r--r--phpBB/includes/ucp/ucp_notifications.php2
-rw-r--r--phpBB/includes/ucp/ucp_pm.php1
-rw-r--r--phpBB/includes/ucp/ucp_pm_compose.php86
-rw-r--r--phpBB/includes/ucp/ucp_pm_options.php22
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewmessage.php66
-rw-r--r--phpBB/includes/ucp/ucp_prefs.php12
-rw-r--r--phpBB/includes/ucp/ucp_register.php23
-rw-r--r--phpBB/includes/ucp/ucp_zebra.php10
-rw-r--r--phpBB/includes/utf/utf_normalizer.php6
-rw-r--r--phpBB/index.php4
-rw-r--r--phpBB/install/convertors/convert_phpbb20.php2
-rw-r--r--phpBB/install/convertors/functions_phpbb20.php3
-rw-r--r--phpBB/install/database_update.php10
-rw-r--r--phpBB/install/install_convert.php3
-rw-r--r--phpBB/install/install_install.php48
-rw-r--r--phpBB/install/schemas/schema_data.sql4
-rw-r--r--phpBB/language/en/acp/board.php6
-rw-r--r--phpBB/language/en/acp/common.php6
-rw-r--r--phpBB/language/en/acp/extensions.php1
-rw-r--r--phpBB/language/en/acp/permissions.php1
-rw-r--r--phpBB/language/en/acp/posting.php6
-rw-r--r--phpBB/language/en/acp/profile.php4
-rw-r--r--phpBB/language/en/app.php3
-rw-r--r--phpBB/language/en/common.php22
-rw-r--r--phpBB/language/en/email/admin_activate.txt3
-rw-r--r--phpBB/language/en/email/admin_send_email.txt1
-rw-r--r--phpBB/language/en/email/admin_welcome_activated.txt2
-rw-r--r--phpBB/language/en/email/admin_welcome_inactive.txt2
-rw-r--r--phpBB/language/en/email/email_notify.txt2
-rw-r--r--phpBB/language/en/email/installed.txt2
-rw-r--r--phpBB/language/en/email/pm_report_closed.txt3
-rw-r--r--phpBB/language/en/email/pm_report_deleted.txt3
-rw-r--r--phpBB/language/en/email/post_approved.txt2
-rw-r--r--phpBB/language/en/email/short/post_approved.txt2
-rw-r--r--phpBB/language/en/email/user_activate.txt2
-rw-r--r--phpBB/language/en/email/user_activate_inactive.txt2
-rw-r--r--phpBB/language/en/email/user_activate_passwd.txt2
-rw-r--r--phpBB/language/en/email/user_reactivate_account.txt2
-rw-r--r--phpBB/language/en/email/user_remind_inactive.txt2
-rw-r--r--phpBB/language/en/email/user_resend_inactive.txt2
-rw-r--r--phpBB/language/en/email/user_welcome.txt2
-rw-r--r--phpBB/language/en/email/user_welcome_inactive.txt2
-rw-r--r--phpBB/language/en/groups.php2
-rw-r--r--phpBB/language/en/help_bbcode.php2
-rw-r--r--phpBB/language/en/help_faq.php2
-rw-r--r--phpBB/language/en/install.php5
-rw-r--r--phpBB/language/en/mcp.php2
-rw-r--r--phpBB/language/en/memberlist.php1
-rw-r--r--phpBB/language/en/posting.php2
-rw-r--r--phpBB/language/en/ucp.php8
-rw-r--r--phpBB/mcp.php22
-rw-r--r--phpBB/memberlist.php120
-rw-r--r--phpBB/phpbb/avatar/driver/upload.php2
-rw-r--r--phpBB/phpbb/console/command/cache/purge.php62
-rw-r--r--phpBB/phpbb/console/command/db/migrate.php128
-rw-r--r--phpBB/phpbb/content_visibility.php74
-rw-r--r--phpBB/phpbb/controller/helper.php6
-rw-r--r--phpBB/phpbb/controller/provider.php26
-rw-r--r--phpBB/phpbb/db/driver/sqlite3.php375
-rw-r--r--phpBB/phpbb/db/migration/data/v310/beta3.php32
-rw-r--r--phpBB/phpbb/db/migration/data/v310/board_contact_name.php30
-rw-r--r--phpBB/phpbb/db/migration/data/v310/live_searches_config.php25
-rw-r--r--phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php33
-rw-r--r--phpBB/phpbb/db/migration/data/v310/timezone.php45
-rw-r--r--phpBB/phpbb/db/migrator.php15
-rw-r--r--phpBB/phpbb/db/tools.php334
-rw-r--r--phpBB/phpbb/event/kernel_request_subscriber.php15
-rw-r--r--phpBB/phpbb/event/md_exporter.php439
-rw-r--r--phpBB/phpbb/event/php_exporter.php608
-rw-r--r--phpBB/phpbb/event/recursive_event_filter_iterator.php70
-rw-r--r--phpBB/phpbb/feed/attachments_base.php83
-rw-r--r--phpBB/phpbb/feed/forum.php3
-rw-r--r--phpBB/phpbb/feed/news.php7
-rw-r--r--phpBB/phpbb/feed/post_base.php42
-rw-r--r--phpBB/phpbb/feed/topic.php9
-rw-r--r--phpBB/phpbb/feed/topic_base.php23
-rw-r--r--phpBB/phpbb/feed/topics.php7
-rw-r--r--phpBB/phpbb/feed/topics_active.php7
-rw-r--r--phpBB/phpbb/log/log.php36
-rw-r--r--phpBB/phpbb/notification/type/approve_post.php8
-rw-r--r--phpBB/phpbb/notification/type/base.php8
-rw-r--r--phpBB/phpbb/notification/type/bookmark.php12
-rw-r--r--phpBB/phpbb/notification/type/post.php49
-rw-r--r--phpBB/phpbb/notification/type/post_in_queue.php8
-rw-r--r--phpBB/phpbb/notification/type/quote.php31
-rw-r--r--phpBB/phpbb/notification/type/type_interface.php7
-rw-r--r--phpBB/phpbb/path_helper.php116
-rw-r--r--phpBB/phpbb/permissions.php2
-rw-r--r--phpBB/phpbb/profilefields/manager.php45
-rw-r--r--phpBB/phpbb/search/fulltext_native.php6
-rw-r--r--phpBB/phpbb/session.php5
-rw-r--r--phpBB/phpbb/template/twig/lexer.php15
-rw-r--r--phpBB/phpbb/user.php46
-rw-r--r--phpBB/posting.php32
-rw-r--r--phpBB/report.php2
-rw-r--r--phpBB/search.php115
-rw-r--r--phpBB/styles/prosilver/style.cfg4
-rw-r--r--phpBB/styles/prosilver/template/ajax.js6
-rw-r--r--phpBB/styles/prosilver/template/captcha_default.html2
-rw-r--r--phpBB/styles/prosilver/template/captcha_qa.html2
-rw-r--r--phpBB/styles/prosilver/template/captcha_recaptcha.html2
-rw-r--r--phpBB/styles/prosilver/template/confirm_body.html2
-rw-r--r--phpBB/styles/prosilver/template/confirm_delete_body.html2
-rw-r--r--phpBB/styles/prosilver/template/drafts.html2
-rw-r--r--phpBB/styles/prosilver/template/faq_body.html4
-rw-r--r--phpBB/styles/prosilver/template/index_body.html20
-rw-r--r--phpBB/styles/prosilver/template/login_body.html2
-rw-r--r--phpBB/styles/prosilver/template/login_forum.html4
-rw-r--r--phpBB/styles/prosilver/template/mcp_approve.html2
-rw-r--r--phpBB/styles/prosilver/template/mcp_header.html2
-rw-r--r--phpBB/styles/prosilver/template/mcp_message.html2
-rw-r--r--phpBB/styles/prosilver/template/mcp_move.html2
-rw-r--r--phpBB/styles/prosilver/template/memberlist_body.html10
-rw-r--r--phpBB/styles/prosilver/template/memberlist_search.html16
-rw-r--r--phpBB/styles/prosilver/template/memberlist_view.html4
-rw-r--r--phpBB/styles/prosilver/template/message_body.html2
-rw-r--r--phpBB/styles/prosilver/template/navbar_footer.html6
-rw-r--r--phpBB/styles/prosilver/template/navbar_header.html4
-rw-r--r--phpBB/styles/prosilver/template/posting_attach_body.html4
-rw-r--r--phpBB/styles/prosilver/template/posting_layout.html4
-rw-r--r--phpBB/styles/prosilver/template/posting_pm_layout.html2
-rw-r--r--phpBB/styles/prosilver/template/quickreply_editor.html2
-rw-r--r--phpBB/styles/prosilver/template/search_results.html6
-rw-r--r--phpBB/styles/prosilver/template/simple_footer.html16
-rw-r--r--phpBB/styles/prosilver/template/simple_header.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_agreement.html7
-rw-r--r--phpBB/styles/prosilver/template/ucp_attachments.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_header.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_pm_viewmessage.html46
-rw-r--r--phpBB/styles/prosilver/template/ucp_register.html1
-rw-r--r--phpBB/styles/prosilver/template/viewforum_body.html2
-rw-r--r--phpBB/styles/prosilver/template/viewonline_body.html2
-rw-r--r--phpBB/styles/prosilver/template/viewonline_whois.html2
-rw-r--r--phpBB/styles/prosilver/template/viewtopic_body.html57
-rw-r--r--phpBB/styles/prosilver/theme/buttons.css59
-rw-r--r--phpBB/styles/prosilver/theme/colours.css27
-rw-r--r--phpBB/styles/prosilver/theme/common.css8
-rw-r--r--phpBB/styles/prosilver/theme/content.css41
-rw-r--r--phpBB/styles/prosilver/theme/en/stylesheet.css6
-rw-r--r--phpBB/styles/prosilver/theme/forms.css2
-rw-r--r--phpBB/styles/prosilver/theme/images/icon_contact.pngbin0 -> 340 bytes
-rw-r--r--phpBB/styles/prosilver/theme/images/icon_contact_aim.gifbin546 -> 0 bytes
-rw-r--r--phpBB/styles/prosilver/theme/images/icon_contact_email.gifbin523 -> 0 bytes
-rw-r--r--phpBB/styles/prosilver/theme/images/icon_contact_icq.gifbin562 -> 0 bytes
-rw-r--r--phpBB/styles/prosilver/theme/images/icon_contact_jabber.gifbin1014 -> 0 bytes
-rw-r--r--phpBB/styles/prosilver/theme/images/icon_contact_msnm.gifbin1466 -> 0 bytes
-rw-r--r--phpBB/styles/prosilver/theme/images/icon_contact_www.gifbin590 -> 0 bytes
-rw-r--r--phpBB/styles/prosilver/theme/images/icon_contact_yahoo.gifbin541 -> 0 bytes
-rw-r--r--phpBB/styles/prosilver/theme/images/icons_contact.pngbin0 -> 8507 bytes
-rw-r--r--phpBB/styles/prosilver/theme/imageset.css11
-rw-r--r--phpBB/styles/prosilver/theme/plupload.css5
-rw-r--r--phpBB/styles/prosilver/theme/tweaks.css5
-rw-r--r--phpBB/styles/subsilver2/style.cfg4
-rw-r--r--phpBB/styles/subsilver2/template/breadcrumbs.html4
-rw-r--r--phpBB/styles/subsilver2/template/index_body.html33
-rw-r--r--phpBB/styles/subsilver2/template/memberlist_view.html2
-rw-r--r--phpBB/styles/subsilver2/template/search_results.html2
-rw-r--r--phpBB/styles/subsilver2/template/simple_header.html5
-rw-r--r--phpBB/styles/subsilver2/template/ucp_agreement.html3
-rw-r--r--phpBB/styles/subsilver2/template/ucp_register.html1
-rw-r--r--phpBB/styles/subsilver2/template/viewforum_body.html2
-rw-r--r--phpBB/styles/subsilver2/template/viewtopic_body.html11
-rw-r--r--phpBB/ucp.php2
-rw-r--r--phpBB/viewforum.php8
-rw-r--r--phpBB/viewonline.php5
-rw-r--r--phpBB/viewtopic.php137
242 files changed, 5664 insertions, 1495 deletions
diff --git a/phpBB/.htaccess b/phpBB/.htaccess
index 6f33916775..1ae74ed825 100644
--- a/phpBB/.htaccess
+++ b/phpBB/.htaccess
@@ -26,12 +26,50 @@ RewriteRule ^(.*)$ app.php [QSA,L]
#Options +FollowSymLinks
</IfModule>
-<Files "config.php">
-Order Allow,Deny
-Deny from All
-</Files>
-
-<Files "common.php">
-Order Allow,Deny
-Deny from All
-</Files>
+# 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.
+# We could just conditionally provide both versions, but unfortunately Apache
+# does not explicitly tell us its version if the module mod_version is not
+# available. In this case, we check for the availability of module
+# mod_authz_core (which should be on 2.4 or higher only) as a best guess.
+<IfModule mod_version.c>
+ <IfVersion < 2.4>
+ <Files "config.php">
+ Order Allow,Deny
+ Deny from All
+ </Files>
+ <Files "common.php">
+ Order Allow,Deny
+ Deny from All
+ </Files>
+ </IfVersion>
+ <IfVersion >= 2.4>
+ <Files "config.php">
+ Require all denied
+ </Files>
+ <Files "common.php">
+ Require all denied
+ </Files>
+ </IfVersion>
+</IfModule>
+<IfModule !mod_version.c>
+ <IfModule !mod_authz_core.c>
+ <Files "config.php">
+ Order Allow,Deny
+ Deny from All
+ </Files>
+ <Files "common.php">
+ Order Allow,Deny
+ Deny from All
+ </Files>
+ </IfModule>
+ <IfModule mod_authz_core.c>
+ <Files "config.php">
+ Require all denied
+ </Files>
+ <Files "common.php">
+ Require all denied
+ </Files>
+ </IfModule>
+</IfModule>
diff --git a/phpBB/adm/style/acp_attachments.html b/phpBB/adm/style/acp_attachments.html
index 5d35666fdd..0e3b5ff3b2 100644
--- a/phpBB/adm/style/acp_attachments.html
+++ b/phpBB/adm/style/acp_attachments.html
@@ -331,15 +331,15 @@
<fieldset class="tabulated">
<legend>{L_TITLE}</legend>
- <table class="table1 zebra-table">
+ <table class="table1 zebra-table fixed-width-table">
<thead>
<tr>
<th>{L_FILENAME}</th>
- <th>{L_FILEDATE}</th>
- <th>{L_FILESIZE}</th>
- <th>{L_ATTACH_POST_ID}</th>
- <th>{L_ATTACH_TO_POST}</th>
- <th>{L_DELETE}</th>
+ <th style="width: 15%;">{L_FILEDATE}</th>
+ <th style="width: 15%;">{L_FILESIZE}</th>
+ <th style="width: 15%;">{L_ATTACH_POST_ID}</th>
+ <th style="width: 15%;">{L_ATTACH_TO_POST}</th>
+ <th style="width: 15%;">{L_DELETE}</th>
</tr>
</thead>
<tbody>
@@ -348,7 +348,7 @@
<td><a href="{orphan.U_FILE}">{orphan.REAL_FILENAME}</a></td>
<td>{orphan.FILETIME}</td>
<td>{orphan.FILESIZE}</td>
- <td><strong>{L_ATTACH_ID}{L_COLON} </strong><input type="number" name="post_id[{orphan.ATTACH_ID}]" size="7" maxlength="10" value="{orphan.POST_ID}" /></td>
+ <td><strong>{L_ATTACH_ID}{L_COLON} </strong><input type="number" name="post_id[{orphan.ATTACH_ID}]" maxlength="10" value="{orphan.POST_ID}" style="width: 75%;" /></td>
<td><input type="checkbox" class="radio" name="add[{orphan.ATTACH_ID}]" /></td>
<td><input type="checkbox" class="radio" name="delete[{orphan.ATTACH_ID}]" /></td>
</tr>
@@ -390,13 +390,13 @@
</div>
<!-- IF .attachments -->
- <table class="table1 zebra-table">
+ <table class="table1 zebra-table fixed-width-table">
<thead>
<tr>
<th>{L_FILENAME}</th>
- <th>{L_POSTED}</th>
- <th class="centered-text">{L_FILESIZE}</th>
- <th class="centered-text">{L_MARK}</th>
+ <th style="width: 15%;">{L_POSTED}</th>
+ <th style="width: 15%;" class="centered-text">{L_FILESIZE}</th>
+ <th style="width: 10%;" class="centered-text">{L_MARK}</th>
</tr>
</thead>
<tbody>
diff --git a/phpBB/adm/style/acp_logs.html b/phpBB/adm/style/acp_logs.html
index 9343b9b509..ec2065f906 100644
--- a/phpBB/adm/style/acp_logs.html
+++ b/phpBB/adm/style/acp_logs.html
@@ -22,15 +22,15 @@
<div><br style="clear: both;" /></div>
<!-- IF .log -->
- <table class="table1 zebra-table">
+ <table class="table1 zebra-table fixed-width-table">
<thead>
<tr>
- <th>{L_USERNAME}</th>
- <th>{L_IP}</th>
- <th>{L_TIME}</th>
+ <th style="width: 15%;">{L_USERNAME}</th>
+ <th style="width: 15%;">{L_IP}</th>
+ <th style="width: 20%;">{L_TIME}</th>
<th>{L_ACTION}</th>
<!-- IF S_CLEARLOGS -->
- <th>{L_MARK}</th>
+ <th style="width: 50px;">{L_MARK}</th>
<!-- ENDIF -->
</tr>
</thead>
diff --git a/phpBB/adm/style/acp_users.html b/phpBB/adm/style/acp_users.html
index b84e32013f..25064c6f3a 100644
--- a/phpBB/adm/style/acp_users.html
+++ b/phpBB/adm/style/acp_users.html
@@ -164,14 +164,14 @@
</div>
<!-- IF .attach -->
- <table class="table1 zebra-table">
+ <table class="table1 zebra-table fixed-width-table">
<thead>
<tr>
<th>{L_FILENAME}</th>
- <th>{L_POST_TIME}</th>
- <th>{L_FILESIZE}</th>
- <th>{L_DOWNLOADS}</th>
- <th>{L_MARK}</th>
+ <th style="width: 20%;">{L_POST_TIME}</th>
+ <th style="width: 20%;">{L_FILESIZE}</th>
+ <th style="width: 20%;">{L_DOWNLOADS}</th>
+ <th style="width: 50px;">{L_MARK}</th>
</tr>
</thead>
<tbody>
diff --git a/phpBB/adm/style/acp_users_prefs.html b/phpBB/adm/style/acp_users_prefs.html
index d1e389ca04..14715f59e4 100644
--- a/phpBB/adm/style/acp_users_prefs.html
+++ b/phpBB/adm/style/acp_users_prefs.html
@@ -5,9 +5,10 @@
</script>
<form id="user_prefs" method="post" action="{U_ACTION}">
-
+ <!-- EVENT acp_users_prefs_prepend -->
<fieldset>
<legend>{L_UCP_PREFS_PERSONAL}</legend>
+ <!-- EVENT acp_users_prefs_personal_prepend -->
<dl>
<dt><label for="viewemail">{L_SHOW_EMAIL}{L_COLON}</label></dt>
<dd><label><input type="radio" class="radio" name="viewemail" value="1"<!-- IF VIEW_EMAIL --> id="viewemail" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
@@ -53,10 +54,12 @@
<dd><select name="dateoptions" id="dateoptions" onchange="if(this.value=='custom'){phpbb.toggleDisplay('custom_date',1);}else{phpbb.toggleDisplay('custom_date',-1);} if (this.value == 'custom') { document.getElementById('dateformat').value = default_dateformat; } else { document.getElementById('dateformat').value = this.value; }">{S_DATEFORMAT_OPTIONS}</select></dd>
<dd><div id="custom_date"<!-- IF not S_CUSTOM_DATEFORMAT --> style="display:none;"<!-- ENDIF -->><input type="text" name="dateformat" id="dateformat" value="{DATE_FORMAT}" maxlength="30" /></div></dd>
</dl>
+ <!-- EVENT acp_users_prefs_personal_append -->
</fieldset>
<fieldset>
<legend>{L_UCP_PREFS_POST}</legend>
+ <!-- EVENT acp_users_prefs_post_prepend -->
<dl>
<dt><label for="bbcode">{L_DEFAULT_BBCODE}{L_COLON}</label></dt>
<dd><label><input type="radio" class="radio" name="bbcode" value="1"<!-- IF BBCODE --> id="bbcode" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
@@ -77,10 +80,12 @@
<dd><label><input type="radio" class="radio" name="notify" value="1"<!-- IF NOTIFY --> id="notify" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input type="radio" class="radio" name="notify" value="0"<!-- IF not NOTIFY --> id="notify" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
</dl>
+ <!-- EVENT acp_users_prefs_post_append -->
</fieldset>
<fieldset>
<legend>{L_UCP_PREFS_VIEW}</legend>
+ <!-- EVENT acp_users_prefs_view_prepend -->
<dl>
<dt><label for="view_images">{L_VIEW_IMAGES}{L_COLON}</label></dt>
<dd><label><input type="radio" class="radio" name="view_images" value="1"<!-- IF VIEW_IMAGES --> id="view_images" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
@@ -135,8 +140,9 @@
<dt><label>{L_VIEW_POSTS_DIR}{L_COLON}</label></dt>
<dd>{S_POST_SORT_DIR}</dd>
</dl>
+ <!-- EVENT acp_users_prefs_view_append -->
</fieldset>
-
+ <!-- EVENT acp_users_prefs_append -->
<fieldset class="quick">
<input class="button1" type="submit" name="update" value="{L_SUBMIT}" />
{S_FORM_TOKEN}
diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css
index 6f2d65afc0..60a5cd9472 100644
--- a/phpBB/adm/style/admin.css
+++ b/phpBB/adm/style/admin.css
@@ -911,6 +911,11 @@ table.styles td.users, table td.mark {
text-align: center;
}
+table.fixed-width-table {
+ table-layout: fixed;
+ word-break: break-word;
+}
+
@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
{
table.responsive, table.responsive tbody, table.responsive tr, table.responsive td {
diff --git a/phpBB/adm/style/simple_footer.html b/phpBB/adm/style/simple_footer.html
index c549a2df4e..d3f2f17bc7 100644
--- a/phpBB/adm/style/simple_footer.html
+++ b/phpBB/adm/style/simple_footer.html
@@ -21,6 +21,7 @@
<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- EVENT acp_simple_footer_after -->
+{$SCRIPTS}
</body>
</html>
diff --git a/phpBB/adm/style/simple_header.html b/phpBB/adm/style/simple_header.html
index ae25f28d32..bf8f41cd7a 100644
--- a/phpBB/adm/style/simple_header.html
+++ b/phpBB/adm/style/simple_header.html
@@ -83,6 +83,7 @@ function find_username(url)
// ]]>
</script>
<!-- EVENT acp_simple_header_head_append -->
+{$STYLESHEETS}
</head>
<body class="{S_CONTENT_DIRECTION} {BODY_CLASS}">
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index ac866f7c78..ae8583ddbf 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -26,6 +26,7 @@ phpbb.loadingIndicator = function() {
if (!loadingIndicator.is(':visible')) {
loadingIndicator.fadeIn(phpbb.alertTime);
// Wait fifteen seconds and display an error if nothing has been returned by then.
+ phpbb.clearLoadingTimeout();
phpbbAlertTimer = setTimeout(function() {
if (loadingIndicator.is(':visible')) {
phpbb.alert($('#phpbb_alert').attr('data-l-err'), $('#phpbb_alert').attr('data-l-timeout-processing-req'));
@@ -248,7 +249,16 @@ phpbb.ajaxify = function(options) {
callback = options.callback,
overlay = (typeof options.overlay !== 'undefined') ? options.overlay : true,
isForm = elements.is('form'),
- eventName = isForm ? 'submit' : 'click';
+ isText = elements.is('input[type="text"], textarea'),
+ eventName;
+
+ if (isForm) {
+ eventName = 'submit';
+ } else if (isText) {
+ eventName = 'keyup';
+ } else {
+ eventName = 'click';
+ }
elements.bind(eventName, function(event) {
var action, method, data, submit, that = this, $this = $(this);
@@ -315,7 +325,7 @@ phpbb.ajaxify = function(options) {
refresh = false;
}
- setTimeout(function() {
+ phpbbAlertTimer = setTimeout(function() {
if (refresh) {
window.location = res.REFRESH_DATA.url;
}
@@ -348,6 +358,7 @@ phpbb.ajaxify = function(options) {
// If the element is a form, POST must be used and some extra data must
// be taken from the form.
var runFilter = (typeof options.filter === 'function');
+ var data = {};
if (isForm) {
action = $this.attr('action').replace('&amp;', '&');
@@ -361,33 +372,41 @@ phpbb.ajaxify = function(options) {
value: submit.val()
});
}
+ } else if (isText) {
+ var name = ($this.attr('data-name') !== undefined) ? $this.attr('data-name') : this['name'];
+ action = $this.attr('data-url').replace('&amp;', '&');
+ data[name] = this.value;
+ method = 'POST';
} else {
action = this.href;
data = null;
method = 'GET';
}
+ var sendRequest = function() {
+ if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) {
+ phpbb.loadingIndicator();
+ }
+
+ var request = $.ajax({
+ url: action,
+ type: method,
+ data: data,
+ success: returnHandler,
+ error: errorHandler
+ });
+ request.always(function() {
+ loadingIndicator.fadeOut(phpbb.alertTime);
+ });
+ };
+
// If filter function returns false, cancel the AJAX functionality,
// and return true (meaning that the HTTP request will be sent normally).
- if (runFilter && !options.filter.call(this, data)) {
+ if (runFilter && !options.filter.call(this, data, event, sendRequest)) {
return;
}
- if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) {
- phpbb.loadingIndicator();
- }
-
- var request = $.ajax({
- url: action,
- type: method,
- data: data,
- success: returnHandler,
- error: errorHandler
- });
- request.always(function() {
- loadingIndicator.fadeOut(phpbb.alertTime);
- });
-
+ sendRequest();
event.preventDefault();
});
@@ -403,6 +422,346 @@ phpbb.ajaxify = function(options) {
return this;
};
+phpbb.search = {cache: {data: []}, tpl: [], container: []};
+
+/**
+ * Get cached search data.
+ *
+ * @param string id Search ID.
+ * @return bool|object. Cached data object. Returns false if no data exists.
+ */
+phpbb.search.cache.get = function(id) {
+ if (this.data[id]) {
+ return this.data[id];
+ }
+ return false;
+};
+
+/**
+ * Set search cache data value.
+ *
+ * @param string id Search ID.
+ * @param string key Data key.
+ * @param string value Data value.
+ *
+ * @return undefined
+ */
+phpbb.search.cache.set = function(id, key, value) {
+ if (!this.data[id]) {
+ this.data[id] = {results: []};
+ }
+ this.data[id][key] = value;
+};
+
+/**
+ * Cache search result.
+ *
+ * @param string id Search ID.
+ * @param string keyword Keyword.
+ * @param array results Search results.
+ *
+ * @return undefined
+ */
+phpbb.search.cache.setResults = function(id, keyword, value) {
+ this.data[id]['results'][keyword] = value;
+};
+
+/**
+ * Trim spaces from keyword and lower its case.
+ *
+ * @param string keyword Search keyword to clean.
+ * @return string Cleaned string.
+ */
+phpbb.search.cleanKeyword = function(keyword) {
+ return $.trim(keyword).toLowerCase();
+};
+
+/**
+ * Get clean version of search keyword. If textarea supports several keywords
+ * (one per line), it fetches the current keyword based on the caret position.
+ *
+ * @param jQuery el Search input|textarea.
+ * @param string keyword Input|textarea value.
+ * @param bool multiline Whether textarea supports multiple search keywords.
+ *
+ * @return string Clean string.
+ */
+phpbb.search.getKeyword = function(el, keyword, multiline) {
+ if (multiline) {
+ var line = phpbb.search.getKeywordLine(el);
+ keyword = keyword.split("\n").splice(line, 1);
+ }
+ return phpbb.search.cleanKeyword(keyword);
+};
+
+/**
+ * Get the textarea line number on which the keyword resides - for textareas
+ * that support multiple keywords (one per line).
+ *
+ * @param jQuery el Search textarea.
+ * @return int
+ */
+phpbb.search.getKeywordLine = function (el) {
+ return el.val().substr(0, el.get(0).selectionStart).split("\n").length - 1;
+};
+
+/**
+ * Set the value on the input|textarea. If textarea supports multiple
+ * keywords, only the active keyword is replaced.
+ *
+ * @param jQuery el Search input|textarea.
+ * @param string value Value to set.
+ * @param bool multiline Whether textarea supports multiple search keywords.
+ *
+ * @return undefined
+ */
+phpbb.search.setValue = function(el, value, multiline) {
+ if (multiline) {
+ var line = phpbb.search.getKeywordLine(el),
+ lines = el.val().split("\n");
+ lines[line] = value;
+ value = lines.join("\n");
+ }
+ el.val(value);
+};
+
+/**
+ * Sets the onclick event to set the value on the input|textarea to the selected search result.
+ *
+ * @param jQuery el Search input|textarea.
+ * @param object value Result object.
+ * @param object container jQuery object for the search container.
+ *
+ * @return undefined
+ */
+phpbb.search.setValueOnClick = function(el, value, row, container) {
+ row.click(function() {
+ phpbb.search.setValue(el, value.result, el.attr('data-multiline'));
+ container.hide();
+ });
+};
+
+/**
+ * Runs before the AJAX search request is sent and determines whether
+ * there is a need to contact the server. If there are cached results
+ * already, those are displayed instead. Executes the AJAX request function
+ * itself due to the need to use a timeout to limit the number of requests.
+ *
+ * @param array data Data to be sent to the server.
+ * @param object event Onkeyup event object.
+ * @param function sendRequest Function to execute AJAX request.
+ *
+ * @return bool Returns false.
+ */
+phpbb.search.filter = function(data, event, sendRequest) {
+ var el = $(this),
+ dataName = (el.attr('data-name') !== undefined) ? el.attr('data-name') : el.attr('name'),
+ minLength = parseInt(el.attr('data-min-length')),
+ searchID = el.attr('data-results'),
+ keyword = phpbb.search.getKeyword(el, data[dataName], el.attr('data-multiline')),
+ cache = phpbb.search.cache.get(searchID),
+ proceed = true;
+ data[dataName] = keyword;
+
+ if (cache['timeout']) {
+ clearTimeout(cache['timeout']);
+ }
+
+ var timeout = setTimeout(function() {
+ // Check min length and existence of cache.
+ if (minLength > keyword.length) {
+ proceed = false;
+ } else if (cache['last_search']) {
+ // Has the keyword actually changed?
+ if (cache['last_search'] === keyword) {
+ proceed = false;
+ } else {
+ // Do we already have results for this?
+ if (cache['results'][keyword]) {
+ var response = {keyword: keyword, results: cache['results'][keyword]};
+ phpbb.search.handleResponse(response, el, true);
+ proceed = false;
+ }
+
+ // If the previous search didn't yield results and the string only had characters added to it,
+ // then we won't bother sending a request.
+ if (keyword.indexOf(cache['last_search']) === 0 && cache['results'][cache['last_search']].length === 0) {
+ phpbb.search.cache.set(searchID, 'last_search', keyword);
+ phpbb.search.cache.setResults(searchID, keyword, []);
+ proceed = false;
+ }
+ }
+ }
+
+ if (proceed) {
+ sendRequest.call(this);
+ }
+ }, 350);
+ phpbb.search.cache.set(searchID, 'timeout', timeout);
+
+ return false;
+};
+
+/**
+ * Handle search result response.
+ *
+ * @param object res Data received from server.
+ * @param jQuery el Search input|textarea.
+ * @param bool fromCache Whether the results are from the cache.
+ * @param function callback Optional callback to run when assigning each search result.
+ *
+ * @return undefined
+ */
+phpbb.search.handleResponse = function(res, el, fromCache, callback) {
+ if (typeof res !== 'object') {
+ return;
+ }
+
+ var searchID = el.attr('data-results'),
+ container = $(searchID);
+
+ if (this.cache.get(searchID)['callback']) {
+ callback = this.cache.get(searchID)['callback'];
+ } else if (typeof callback === 'function') {
+ this.cache.set(searchID, 'callback', callback);
+ }
+
+ if (!fromCache) {
+ this.cache.setResults(searchID, res.keyword, res.results);
+ }
+
+ this.cache.set(searchID, 'last_search', res.keyword);
+ this.showResults(res.results, el, container, callback);
+};
+
+/**
+ * Show search results.
+ *
+ * @param array results Search results.
+ * @param jQuery el Search input|textarea.
+ * @param jQuery container Search results container element.
+ * @param function callback Optional callback to run when assigning each search result.
+ *
+ * @return undefined
+ */
+phpbb.search.showResults = function(results, el, container, callback) {
+ var resultContainer = $('.search-results', container);
+ this.clearResults(resultContainer);
+
+ if (!results.length) {
+ container.hide();
+ return;
+ }
+
+ var searchID = container.attr('id'),
+ tpl,
+ row;
+
+ if (!this.tpl[searchID]) {
+ tpl = $('.search-result-tpl', container);
+ this.tpl[searchID] = tpl.clone().removeClass('search-result-tpl');
+ tpl.remove();
+ }
+ tpl = this.tpl[searchID];
+
+ $.each(results, function(i, item) {
+ row = tpl.clone();
+ row.find('.search-result').html(item.display);
+
+ if (typeof callback === 'function') {
+ callback.call(this, el, item, row, container);
+ }
+ row.appendTo(resultContainer).show();
+ });
+ container.show();
+};
+
+/**
+ * Clear search results.
+ *
+ * @param jQuery container Search results container.
+ * @return undefined
+ */
+phpbb.search.clearResults = function(container) {
+ container.children(':not(.search-result-tpl)').remove();
+};
+
+$('#phpbb').click(function(e) {
+ var target = $(e.target);
+
+ if (!target.is('.live-search') && !target.parents().is('.live-search')) {
+ $('.live-search').hide();
+ }
+});
+
+phpbb.history = {};
+
+/**
+* Check whether a method in the native history object is supported.
+*
+* @param string fn Method name.
+* @return bool Returns true if the method is supported.
+*/
+phpbb.history.isSupported = function(fn) {
+ if (typeof history === 'undefined' || typeof history[fn] === 'undefined') {
+ return false;
+ }
+ return true;
+};
+
+/**
+* Wrapper for the pushState and replaceState methods of the
+* native history object.
+*
+* @param string mode Mode. Either push or replace.
+* @param string url New URL.
+* @param string title Optional page title.
+* @patam object obj Optional state object.
+*
+* @return undefined
+*/
+phpbb.history.alterUrl = function(mode, url, title, obj) {
+ var fn = mode + 'State';
+
+ if (!url || !phpbb.history.isSupported(fn)) {
+ return;
+ }
+ if (!title) {
+ title = document.title;
+ }
+ if (!obj) {
+ obj = null;
+ }
+
+ history[fn](obj, title, url);
+};
+
+/**
+* Wrapper for the native history.replaceState method.
+*
+* @param string url New URL.
+* @param string title Optional page title.
+* @patam object obj Optional state object.
+*
+* @return undefined
+*/
+phpbb.history.replaceUrl = function(url, title, obj) {
+ phpbb.history.alterUrl('replace', url, title, obj);
+};
+
+/**
+* Wrapper for the native history.pushState method.
+*
+* @param string url New URL.
+* @param string title Optional page title.
+* @patam object obj Optional state object.
+*
+* @return undefined
+*/
+phpbb.history.pushUrl = function(url, title, obj) {
+ phpbb.history.alterUrl('push', url, title, obj);
+};
+
/**
* Hide the optgroups that are not the selected timezone
*
@@ -542,6 +901,12 @@ phpbb.addAjaxCallback = function(id, callback) {
return this;
};
+/**
+ * This callback handles live member searches.
+ */
+phpbb.addAjaxCallback('member_search', function(res) {
+ phpbb.search.handleResponse(res, $(this), false, phpbb.getFunctionByName('phpbb.search.setValueOnClick'));
+});
/**
* This callback alternates text - it replaces the current text with the text in
@@ -917,9 +1282,10 @@ phpbb.toggleDropdown = function() {
// Check dimensions when showing dropdown
// !visible because variable shows state of dropdown before it was toggled
if (!visible) {
+ var windowWidth = $(window).width();
+
options.dropdown.find('.dropdown-contents').each(function() {
- var $this = $(this),
- windowWidth = $(window).width();
+ var $this = $(this);
$this.css({
marginLeft: 0,
@@ -937,6 +1303,13 @@ phpbb.toggleDropdown = function() {
$this.css('margin-left', (windowWidth - offset - width - 2) + 'px');
}
});
+ var freeSpace = parent.offset().left - 4;
+
+ if (direction == 'left') {
+ options.dropdown.css('margin-left', '-' + freeSpace + 'px');
+ } else {
+ options.dropdown.css('margin-right', '-' + (windowWidth + freeSpace) + 'px');
+ }
}
// Prevent event propagation
@@ -1103,6 +1476,24 @@ phpbb.toggleDisplay = function(id, action, type) {
}
/**
+* Get function from name.
+* Based on http://stackoverflow.com/a/359910
+*
+* @param string functionName Function to get.
+* @return function
+*/
+phpbb.getFunctionByName = function (functionName) {
+ var namespaces = functionName.split('.'),
+ func = namespaces.pop(),
+ context = window;
+
+ for (var i = 0; i < namespaces.length; i++) {
+ context = context[namespaces[i]];
+ }
+ return context[func];
+};
+
+/**
* Apply code editor to all textarea elements with data-bbcode attribute
*/
$(document).ready(function() {
@@ -1121,6 +1512,10 @@ $(document).ready(function() {
$('#color_palette_placeholder').each(function() {
phpbb.registerPalette($(this));
});
+
+ // Update browser history URL to point to specific post in viewtopic.php
+ // when using view=unread#unread link.
+ phpbb.history.replaceUrl($('#unread[data-url]').data('url'));
});
})(jQuery); // Avoid conflicts with other libraries
diff --git a/phpBB/bin/phpbbcli.php b/phpBB/bin/phpbbcli.php
index 49f4ca13e7..dd5c8fa774 100755
--- a/phpBB/bin/phpbbcli.php
+++ b/phpBB/bin/phpbbcli.php
@@ -21,7 +21,9 @@ require($phpbb_root_path . 'includes/startup.' . $phpEx);
require($phpbb_root_path . 'config.' . $phpEx);
require($phpbb_root_path . 'includes/constants.' . $phpEx);
require($phpbb_root_path . 'includes/functions.' . $phpEx);
+require($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
require($phpbb_root_path . 'includes/functions_container.' . $phpEx);
+require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);
require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx);
$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx);
@@ -30,6 +32,8 @@ $phpbb_class_loader_ext = new \phpbb\class_loader('\\', "{$phpbb_root_path}ext/"
$phpbb_class_loader_ext->register();
$phpbb_container = phpbb_create_update_container($phpbb_root_path, $phpEx, "$phpbb_root_path/config");
+$phpbb_container->get('request')->enable_super_globals();
+require($phpbb_root_path . 'includes/compatibility_globals.' . $phpEx);
$application = new \phpbb\console\application('phpBB Console', PHPBB_VERSION);
$application->register_container_commands($phpbb_container);
diff --git a/phpBB/common.php b/phpBB/common.php
index b1da2215fb..4ad669a021 100644
--- a/phpBB/common.php
+++ b/phpBB/common.php
@@ -96,34 +96,7 @@ $phpbb_container = phpbb_create_default_container($phpbb_root_path, $phpEx);
$phpbb_class_loader->set_cache($phpbb_container->get('cache.driver'));
$phpbb_class_loader_ext->set_cache($phpbb_container->get('cache.driver'));
-// set up caching
-$cache = $phpbb_container->get('cache');
-
-// Instantiate some basic classes
-$phpbb_dispatcher = $phpbb_container->get('dispatcher');
-$request = $phpbb_container->get('request');
-$user = $phpbb_container->get('user');
-$auth = $phpbb_container->get('auth');
-$db = $phpbb_container->get('dbal.conn');
-
-// make sure request_var uses this request instance
-request_var('', 0, false, false, $request); // "dependency injection" for a function
-
-// Grab global variables, re-cache if necessary
-$config = $phpbb_container->get('config');
-set_config(null, null, null, $config);
-set_config_count(null, null, null, $config);
-
-$phpbb_log = $phpbb_container->get('log');
-$symfony_request = $phpbb_container->get('symfony_request');
-$phpbb_filesystem = $phpbb_container->get('filesystem');
-$phpbb_path_helper = $phpbb_container->get('path_helper');
-
-// load extensions
-$phpbb_extension_manager = $phpbb_container->get('ext.manager');
-$phpbb_subscriber_loader = $phpbb_container->get('event.subscriber_loader');
-
-$template = $phpbb_container->get('template');
+require($phpbb_root_path . 'includes/compatibility_globals.' . $phpEx);
// Add own hook handler
require($phpbb_root_path . 'includes/hooks/index.' . $phpEx);
@@ -151,6 +124,6 @@ if (!$config['use_system_cron'])
* please use the core.user_setup event instead!
*
* @event core.common
-* @since 3.1-A1
+* @since 3.1.0-a1
*/
$phpbb_dispatcher->dispatch('core.common');
diff --git a/phpBB/composer.json b/phpBB/composer.json
index f005fff805..a55733b3c0 100644
--- a/phpBB/composer.json
+++ b/phpBB/composer.json
@@ -16,8 +16,8 @@
},
"require-dev": {
"fabpot/goutte": "1.0.*",
- "phpunit/dbunit": "1.2.*",
- "phpunit/phpunit": "3.7.*",
+ "phpunit/dbunit": "1.3.*",
+ "phpunit/phpunit": "4.1.*",
"phing/phing": "2.4.*",
"squizlabs/php_codesniffer": "1.*"
}
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index ee83dee047..9e0bcf9771 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -3,7 +3,7 @@
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
- "hash": "9b683acbc766a345d90de958db4e7f48",
+ "hash": "194c86e9ae52700a8f6c1b10d7b2e4d0",
"packages": [
{
"name": "lusitanian/oauth",
@@ -88,7 +88,7 @@
"Psr\\Log\\": ""
}
},
- "notification-url": "http://packagist.org/downloads/",
+ "notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
@@ -213,17 +213,17 @@
},
{
"name": "symfony/debug",
- "version": "v2.3.4",
+ "version": "v2.4.4",
"target-dir": "Symfony/Component/Debug",
"source": {
"type": "git",
"url": "https://github.com/symfony/Debug.git",
- "reference": "729f6d19cfc401c4942e43fcc1059103bd6df130"
+ "reference": "6a8eb9aba50595014fef52d6b4d99b31dfaa6f02"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Debug/zipball/729f6d19cfc401c4942e43fcc1059103bd6df130",
- "reference": "729f6d19cfc401c4942e43fcc1059103bd6df130",
+ "url": "https://api.github.com/repos/symfony/Debug/zipball/6a8eb9aba50595014fef52d6b4d99b31dfaa6f02",
+ "reference": "6a8eb9aba50595014fef52d6b4d99b31dfaa6f02",
"shasum": ""
},
"require": {
@@ -234,14 +234,13 @@
"symfony/http-kernel": "~2.1"
},
"suggest": {
- "symfony/class-loader": "",
"symfony/http-foundation": "",
"symfony/http-kernel": ""
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.3-dev"
+ "dev-master": "2.4-dev"
}
},
"autoload": {
@@ -267,7 +266,7 @@
],
"description": "Symfony Debug Component",
"homepage": "http://symfony.com",
- "time": "2013-08-08 14:16:10"
+ "time": "2014-04-16 10:34:42"
},
{
"name": "symfony/dependency-injection",
@@ -385,17 +384,17 @@
},
{
"name": "symfony/filesystem",
- "version": "v2.3.4",
+ "version": "v2.4.4",
"target-dir": "Symfony/Component/Filesystem",
"source": {
"type": "git",
"url": "https://github.com/symfony/Filesystem.git",
- "reference": "87acbbef6d35ba649f96f09cc572c45119b360c3"
+ "reference": "a3af8294bcce4a7c1b2892363b0c9d8109affad4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Filesystem/zipball/87acbbef6d35ba649f96f09cc572c45119b360c3",
- "reference": "87acbbef6d35ba649f96f09cc572c45119b360c3",
+ "url": "https://api.github.com/repos/symfony/Filesystem/zipball/a3af8294bcce4a7c1b2892363b0c9d8109affad4",
+ "reference": "a3af8294bcce4a7c1b2892363b0c9d8109affad4",
"shasum": ""
},
"require": {
@@ -404,7 +403,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.3-dev"
+ "dev-master": "2.4-dev"
}
},
"autoload": {
@@ -430,30 +429,33 @@
],
"description": "Symfony Filesystem Component",
"homepage": "http://symfony.com",
- "time": "2013-07-21 12:12:18"
+ "time": "2014-04-16 10:34:31"
},
{
"name": "symfony/http-foundation",
- "version": "v2.3.4",
+ "version": "v2.4.4",
"target-dir": "Symfony/Component/HttpFoundation",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpFoundation.git",
- "reference": "fdf130fe65457aedbc4639a22f4ef9d3be5c002c"
+ "reference": "22c4dee84271ad0cd08d19f26d89f2878e11159b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/fdf130fe65457aedbc4639a22f4ef9d3be5c002c",
- "reference": "fdf130fe65457aedbc4639a22f4ef9d3be5c002c",
+ "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/22c4dee84271ad0cd08d19f26d89f2878e11159b",
+ "reference": "22c4dee84271ad0cd08d19f26d89f2878e11159b",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
+ "require-dev": {
+ "symfony/expression-language": "~2.4"
+ },
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.3-dev"
+ "dev-master": "2.4-dev"
}
},
"autoload": {
@@ -482,7 +484,7 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "http://symfony.com",
- "time": "2013-08-26 05:49:51"
+ "time": "2014-04-18 21:02:05"
},
{
"name": "symfony/http-kernel",
@@ -694,18 +696,21 @@
"Twig_": "lib/"
}
},
- "notification-url": "http://packagist.org/downloads/",
+ "notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Armin Ronacher",
- "email": "armin.ronacher@active-4.com"
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
@@ -1027,31 +1032,32 @@
},
{
"name": "phpunit/dbunit",
- "version": "1.2.3",
+ "version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/dbunit.git",
- "reference": "8386782a2d55153e44a06eb1a9d13d6ed35d9c2d"
+ "reference": "a5891b7a9c4f21587a51f9bc4e8f7042b741b480"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/8386782a2d55153e44a06eb1a9d13d6ed35d9c2d",
- "reference": "8386782a2d55153e44a06eb1a9d13d6ed35d9c2d",
+ "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/a5891b7a9c4f21587a51f9bc4e8f7042b741b480",
+ "reference": "a5891b7a9c4f21587a51f9bc4e8f7042b741b480",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"ext-simplexml": "*",
"php": ">=5.3.3",
- "phpunit/phpunit": ">=3.7.0@stable"
+ "phpunit/phpunit": ">=3.7.0@stable",
+ "symfony/yaml": ">=2.1.0"
},
"bin": [
- "dbunit.php"
+ "composer/bin/dbunit"
],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2.x-dev"
+ "dev-master": "1.3.x-dev"
}
},
"autoload": {
@@ -1081,44 +1087,48 @@
"testing",
"xunit"
],
- "time": "2013-03-01 11:50:46"
+ "time": "2014-03-26 11:25:06"
},
{
"name": "phpunit/php-code-coverage",
- "version": "1.2.13",
+ "version": "2.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "466e7cd2554b4e264c9e3f31216d25ac0e5f3d94"
+ "reference": "bccecf50645068b44f49a84009e2a0499a500b99"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/466e7cd2554b4e264c9e3f31216d25ac0e5f3d94",
- "reference": "466e7cd2554b4e264c9e3f31216d25ac0e5f3d94",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/bccecf50645068b44f49a84009e2a0499a500b99",
+ "reference": "bccecf50645068b44f49a84009e2a0499a500b99",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
- "phpunit/php-file-iterator": ">=1.3.0@stable",
- "phpunit/php-text-template": ">=1.1.1@stable",
- "phpunit/php-token-stream": ">=1.1.3@stable"
+ "phpunit/php-file-iterator": "~1.3.1",
+ "phpunit/php-text-template": "~1.2.0",
+ "phpunit/php-token-stream": "~1.2.2",
+ "sebastian/environment": "~1.0.0",
+ "sebastian/version": "~1.0.3"
},
"require-dev": {
- "phpunit/phpunit": "3.7.*@dev"
+ "ext-xdebug": ">=2.1.4",
+ "phpunit/phpunit": "~4.0.14"
},
"suggest": {
"ext-dom": "*",
- "ext-xdebug": ">=2.0.5"
+ "ext-xdebug": ">=2.2.1",
+ "ext-xmlwriter": "*"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2.x-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
"classmap": [
- "PHP/"
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -1142,20 +1152,20 @@
"testing",
"xunit"
],
- "time": "2013-09-10 08:14:32"
+ "time": "2014-04-30 09:01:21"
},
{
"name": "phpunit/php-file-iterator",
- "version": "1.3.3",
+ "version": "1.3.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "16a78140ed2fc01b945cfa539665fadc6a038029"
+ "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/16a78140ed2fc01b945cfa539665fadc6a038029",
- "reference": "16a78140ed2fc01b945cfa539665fadc6a038029",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
+ "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
"shasum": ""
},
"require": {
@@ -1182,25 +1192,25 @@
}
],
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
- "homepage": "http://www.phpunit.de/",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
"keywords": [
"filesystem",
"iterator"
],
- "time": "2012-10-11 11:44:38"
+ "time": "2013-10-10 15:34:57"
},
{
"name": "phpunit/php-text-template",
- "version": "1.1.4",
+ "version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-text-template.git",
- "reference": "5180896f51c5b3648ac946b05f9ec02be78a0b23"
+ "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5180896f51c5b3648ac946b05f9ec02be78a0b23",
- "reference": "5180896f51c5b3648ac946b05f9ec02be78a0b23",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
+ "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
"shasum": ""
},
"require": {
@@ -1231,7 +1241,7 @@
"keywords": [
"template"
],
- "time": "2012-10-31 18:15:28"
+ "time": "2014-01-30 17:20:04"
},
{
"name": "phpunit/php-timer",
@@ -1279,16 +1289,16 @@
},
{
"name": "phpunit/php-token-stream",
- "version": "1.2.1",
+ "version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "5220af2a7929aa35cf663d97c89ad3d50cf5fa3e"
+ "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/5220af2a7929aa35cf663d97c89ad3d50cf5fa3e",
- "reference": "5220af2a7929aa35cf663d97c89ad3d50cf5fa3e",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32",
+ "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32",
"shasum": ""
},
"require": {
@@ -1325,56 +1335,56 @@
"keywords": [
"tokenizer"
],
- "time": "2013-09-13 04:58:23"
+ "time": "2014-03-03 05:10:30"
},
{
"name": "phpunit/phpunit",
- "version": "3.7.24",
+ "version": "4.1.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "af7b77ccb5c64458bdfca95665d29558d1df7d08"
+ "reference": "efb1b1334605594417a3bd466477772d06d460a8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/af7b77ccb5c64458bdfca95665d29558d1df7d08",
- "reference": "af7b77ccb5c64458bdfca95665d29558d1df7d08",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/efb1b1334605594417a3bd466477772d06d460a8",
+ "reference": "efb1b1334605594417a3bd466477772d06d460a8",
"shasum": ""
},
"require": {
"ext-dom": "*",
+ "ext-json": "*",
"ext-pcre": "*",
"ext-reflection": "*",
"ext-spl": "*",
"php": ">=5.3.3",
- "phpunit/php-code-coverage": "~1.2.1",
- "phpunit/php-file-iterator": ">=1.3.1",
- "phpunit/php-text-template": ">=1.1.1",
- "phpunit/php-timer": ">=1.0.4",
- "phpunit/phpunit-mock-objects": "~1.2.0",
+ "phpunit/php-code-coverage": "~2.0",
+ "phpunit/php-file-iterator": "~1.3.1",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-timer": "~1.0.2",
+ "phpunit/phpunit-mock-objects": "~2.1",
+ "sebastian/comparator": "~1.0",
+ "sebastian/diff": "~1.1",
+ "sebastian/environment": "~1.0",
+ "sebastian/exporter": "~1.0",
+ "sebastian/version": "~1.0",
"symfony/yaml": "~2.0"
},
- "require-dev": {
- "pear-pear/pear": "1.9.4"
- },
"suggest": {
- "ext-json": "*",
- "ext-simplexml": "*",
- "ext-tokenizer": "*",
- "phpunit/php-invoker": ">=1.1.0,<1.2.0"
+ "phpunit/php-invoker": "~1.1"
},
"bin": [
- "composer/bin/phpunit"
+ "phpunit"
],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.7.x-dev"
+ "dev-master": "4.1.x-dev"
}
},
"autoload": {
"classmap": [
- "PHPUnit/"
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -1399,33 +1409,41 @@
"testing",
"xunit"
],
- "time": "2013-08-09 06:58:24"
+ "time": "2014-05-02 07:13:40"
},
{
"name": "phpunit/phpunit-mock-objects",
- "version": "1.2.3",
+ "version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
- "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875"
+ "reference": "da0eb04d8ee95ec2898187e407e519c118d3d27c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5794e3c5c5ba0fb037b11d8151add2a07fa82875",
- "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/da0eb04d8ee95ec2898187e407e519c118d3d27c",
+ "reference": "da0eb04d8ee95ec2898187e407e519c118d3d27c",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
- "phpunit/php-text-template": ">=1.1.1@stable"
+ "phpunit/php-text-template": "~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.1"
},
"suggest": {
"ext-soap": "*"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1.x-dev"
+ }
+ },
"autoload": {
"classmap": [
- "PHPUnit/"
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -1448,7 +1466,274 @@
"mock",
"xunit"
],
- "time": "2013-01-13 10:24:48"
+ "time": "2014-05-02 07:04:11"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2",
+ "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/diff": "~1.1",
+ "sebastian/exporter": "~1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.1"
+ },
+ "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": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "time": "2014-05-02 07:05:58"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d",
+ "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "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",
+ "role": "lead"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "http://www.github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff"
+ ],
+ "time": "2013-08-03 16:46:33"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/79517609ec01139cd7e9fded0dd7ce08c952ef6a",
+ "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.0.*@dev"
+ },
+ "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": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "time": "2014-02-18 16:17:19"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529",
+ "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.0.*@dev"
+ },
+ "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": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2014-02-16 08:26:31"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "1.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
+ "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "time": "2014-03-07 15:35:33"
},
{
"name": "squizlabs/php_codesniffer",
diff --git a/phpBB/config/console.yml b/phpBB/config/console.yml
index a4aae75e40..1340d9c0d7 100644
--- a/phpBB/config/console.yml
+++ b/phpBB/config/console.yml
@@ -1,4 +1,15 @@
services:
+ console.command.cache.purge:
+ class: phpbb\console\command\cache\purge
+ arguments:
+ - @cache.driver
+ - @dbal.conn
+ - @auth
+ - @log
+ - @user
+ tags:
+ - { name: console.command }
+
console.command.config.delete:
class: phpbb\console\command\config\delete
arguments:
@@ -34,6 +45,18 @@ services:
tags:
- { name: console.command }
+ console.command.db.migrate:
+ class: phpbb\console\command\db\migrate
+ arguments:
+ - @migrator
+ - @ext.manager
+ - @config
+ - @cache
+ - @log
+ - @user
+ tags:
+ - { name: console.command }
+
console.command.extension.disable:
class: phpbb\console\command\extension\disable
arguments:
diff --git a/phpBB/config/profilefields.yml b/phpBB/config/profilefields.yml
index d12a1f8a37..00f025e141 100644
--- a/phpBB/config/profilefields.yml
+++ b/phpBB/config/profilefields.yml
@@ -4,6 +4,7 @@ services:
arguments:
- @auth
- @dbal.conn
+ - @dispatcher
- @request
- @template
- @profilefields.type_collection
diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml
index 90a2f3b187..fdd8a33135 100644
--- a/phpBB/config/services.yml
+++ b/phpBB/config/services.yml
@@ -95,6 +95,7 @@ services:
- @user
- @config
- @controller.provider
+ - @ext.manager
- %core.root_path%
- %core.php_ext%
@@ -107,8 +108,6 @@ services:
controller.provider:
class: phpbb\controller\provider
- arguments:
- - @ext.finder
calls:
- [find, [%core.root_path%]]
@@ -175,16 +174,6 @@ services:
- %core.php_ext%
- @cache.driver
- ext.finder:
- class: phpbb\extension\finder
- arguments:
- - @ext.manager
- - @filesystem
- - %core.root_path%
- - @cache.driver
- - %core.php_ext%
- - _ext_finder
-
filesystem:
class: phpbb\filesystem
@@ -217,7 +206,7 @@ services:
kernel_request_subscriber:
class: phpbb\event\kernel_request_subscriber
arguments:
- - @ext.finder
+ - @ext.manager
- %core.root_path%
- %core.php_ext%
tags:
diff --git a/phpBB/develop/add_permissions.php b/phpBB/develop/add_permissions.php
index 449d931507..688e228729 100644
--- a/phpBB/develop/add_permissions.php
+++ b/phpBB/develop/add_permissions.php
@@ -376,6 +376,7 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting)
case 'mssql':
case 'sqlite':
+ case 'sqlite3':
$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
break;
diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php
index 9ab8bd193f..d89de2cee3 100644
--- a/phpBB/develop/create_schema_files.php
+++ b/phpBB/develop/create_schema_files.php
@@ -70,6 +70,7 @@ foreach ($supported_dbms as $dbms)
case 'mysql_41':
case 'firebird':
case 'sqlite':
+ case 'sqlite3':
fwrite($fp, "# DO NOT EDIT THIS FILE, IT IS GENERATED\n");
fwrite($fp, "#\n");
fwrite($fp, "# To change the contents of this file, edit\n");
diff --git a/phpBB/develop/export_events_for_wiki.php b/phpBB/develop/export_events_for_wiki.php
index 3021b64e05..f4ebb42cf4 100644
--- a/phpBB/develop/export_events_for_wiki.php
+++ b/phpBB/develop/export_events_for_wiki.php
@@ -16,316 +16,84 @@ $phpbb_root_path = __DIR__ . '/../';
function usage()
{
- echo "Usage: export_events_for_wiki.php COMMAND\n";
+ echo "Usage: export_events_for_wiki.php COMMAND [EXTENSION]\n";
echo "\n";
- echo "acp:\n";
- echo " Export all events for files in the acp style.\n";
+ echo "COMMAND:\n";
+ echo " all:\n";
+ echo " Generate the complete wikipage for https://wiki.phpbb.com/Event_List\n";
echo "\n";
- echo "styles:\n";
- echo " Export all events for files in the prosilver and subsilver2 styles.\n";
+ echo " php:\n";
+ echo " Generate the PHP event section of Event_List\n";
+ echo "\n";
+ echo " adm:\n";
+ echo " Generate the ACP Template event section of Event_List\n";
+ echo "\n";
+ echo " styles:\n";
+ echo " Generate the Styles Template event section of Event_List\n";
+ echo "\n";
+ echo "EXTENSION (Optional):\n";
+ echo " If not given, only core events will be exported.\n";
+ echo " Otherwise only events from the extension will be exported.\n";
echo "\n";
- echo "php:\n";
- echo " Export all events for php-files.\n";
exit(2);
}
-function export_from_eventsmd($phpbb_root_path, $filter)
+function validate_argument_count($arguments, $count)
{
- $file_content = file_get_contents($phpbb_root_path . 'docs/events.md');
-
- $events = explode("\n\n", $file_content);
- foreach ($events as $event)
+ if ($arguments <= $count)
{
- // Last row of the file
- if (strpos($event, "\n===\n") === false) continue;
-
- list($event_name, $details) = explode("\n===\n", $event);
-
- if ($filter == 'acp' && strpos($event_name, 'acp_') !== 0) continue;
- if ($filter == 'styles' && strpos($event_name, 'acp_') === 0) continue;
-
- list($file_details, $details) = explode("\n* Since: ", $details);
- list($version, $explanition) = explode("\n* Purpose: ", $details);
-
- echo "|- id=\"{$event_name}\"\n";
- echo "| [[#{$event_name}|{$event_name}]] || ";
-
- if (strpos($file_details, "* Locations:\n + ") === 0)
- {
- $file_details = substr($file_details, strlen("* Locations:\n + "));
- $files = explode("\n + ", $file_details);
- $prosilver = $subsilver2 = $adm = array();
- foreach ($files as $file)
- {
- if (strpos($file, 'styles/prosilver/template/') === 0)
- {
- $prosilver[] = substr($file, strlen('styles/prosilver/template/'));
- }
- if (strpos($file, 'styles/subsilver2/template/') === 0)
- {
- $subsilver2[] = substr($file, strlen('styles/subsilver2/template/'));
- }
- if (strpos($file, 'adm/style/') === 0)
- {
- $adm[] = substr($file, strlen('adm/style/'));
- }
- }
- if ($filter == 'acp')
- {
- echo implode(', ', $adm);
- }
- else
- {
- echo implode(', ', $prosilver) . ' || ' . implode(', ', $subsilver2);
- }
- }
- else if ($filter == 'acp')
- {
- echo substr($file_details, strlen("* Location: adm/style/"));
- }
- echo " || {$version} || " . str_replace("\n", ' ', $explanition) . "\n";
-
+ usage();
}
}
-function export_from_php($phpbb_root_path)
-{
- $files = get_file_list($phpbb_root_path);
- $events = array();
- foreach ($files as $file)
- {
- $file_events = check_for_events($phpbb_root_path, $file);
- if (!empty($file_events))
- {
- $events = array_merge($events, $file_events);
- }
- }
-
- ksort($events);
+validate_argument_count($argc, 1);
- foreach ($events as $event)
- {
- echo '|- id="' . $event['event'] . '"' . "\n";
- echo '| [[#' . $event['event'] . '|' . $event['event'] . ']] || ' . $event['file'] . ' || ' . implode(', ', $event['arguments']) . ' || ' . $event['since'] . ' || ' . $event['description'] . "\n";
- }
-}
+$action = $argv[1];
+$extension = isset($argv[2]) ? $argv[2] : null;
+require __DIR__ . '/../phpbb/event/php_exporter.' . $phpEx;
+require __DIR__ . '/../phpbb/event/md_exporter.' . $phpEx;
+require __DIR__ . '/../phpbb/event/recursive_event_filter_iterator.' . $phpEx;
+require __DIR__ . '/../phpbb/recursive_dot_prefix_filter_iterator.' . $phpEx;
-function check_for_events($phpbb_root_path, $file)
+switch ($action)
{
- $events = array();
- $content = file_get_contents($phpbb_root_path . $file);
-
- if (strpos($content, "phpbb_dispatcher->trigger_event('") || strpos($content, "phpbb_dispatcher->dispatch('"))
- {
- $lines = explode("\n", $content);
- for ($i = 0, $num_lines = sizeof($lines); $i < $num_lines; $i++)
- {
- $event_line = 0;
- $found_trigger_event = strpos($lines[$i], "phpbb_dispatcher->trigger_event('");
- if ($found_trigger_event !== false)
- {
- $event_line = $i;
- $event_name = $lines[$event_line];
- $event_name = substr($event_name, $found_trigger_event + strlen("phpbb_dispatcher->trigger_event('"));
- $event_name = substr($event_name, 0, strpos($event_name, "'"));
+ case 'all':
+ echo '__FORCETOC__' . "\n";
- $current_line = trim($lines[$event_line]);
- $arguments = array();
- $found_inline_array = strpos($current_line, "', compact(array('");
- if ($found_inline_array !== false)
- {
- $varsarray = substr($current_line, $found_inline_array + strlen("', compact(array('"), -6);
- $arguments = explode("', '", $varsarray);
- }
-
- if (empty($arguments))
- {
- // Find $vars array lines
- $find_varsarray_line = 1;
- while (strpos($lines[$event_line - $find_varsarray_line], "vars = array('") === false)
- {
- $find_varsarray_line++;
-
- if ($find_varsarray_line > min(50, $event_line))
- {
- throw new LogicException('Can not find "$vars = array()"-line for event "' . $event_name . '" in file "' . $file . '"');
- }
- }
- $varsarray = substr(trim($lines[$event_line - $find_varsarray_line]), strlen("\$vars = array('"), -3);
- $arguments = explode("', '", $varsarray);
- }
-
- // Validate $vars array with @var
- $find_vars_line = 3;
- $doc_vars = array();
- while (strpos(trim($lines[$event_line - $find_vars_line]), '*') === 0)
- {
- $var_line = trim($lines[$event_line - $find_vars_line]);
- $var_line = preg_replace('!\s+!', ' ', $var_line);
- if (strpos($var_line, '* @var ') === 0)
- {
- $doc_line = explode(' ', $var_line);
- if (isset($doc_line[3]))
- {
- $doc_vars[] = $doc_line[3];
- }
- }
- $find_vars_line++;
- }
- if (sizeof($arguments) !== sizeof($doc_vars) && array_intersect($arguments, $doc_vars))
- {
- throw new LogicException('$vars array does not match the list of @var tags for event "' . $event_name . '" in file "' . $file . '"');
- }
- }
- $found_dispatch = strpos($lines[$i], "phpbb_dispatcher->dispatch('");
- if ($found_dispatch !== false)
- {
- $event_line = $i;
- $event_name = $lines[$event_line];
- $event_name = substr($event_name, $found_dispatch + strlen("phpbb_dispatcher->dispatch('"));
- $event_name = substr($event_name, 0, strpos($event_name, "'"));
- $arguments = array();
- }
-
- if ($event_line)
- {
- // Validate @event name
- $find_event_line = 1;
- while (strpos($lines[$event_line - $find_event_line], '* @event ') === false)
- {
- $find_event_line++;
-
- if ($find_event_line > min(50, $event_line))
- {
- throw new LogicException('Can not find @event tag for event "' . $event_name . '" in file "' . $file . '"');
- }
- }
- $event_name_tag = substr(trim($lines[$event_line - $find_event_line]), strlen('* @event '));
- if ($event_name_tag !== $event_name)
- {
- throw new LogicException('Event name does not match @event tag for event "' . $event_name . '" in file "' . $file . '"');
- }
-
- // Find @since
- $find_since_line = 1;
- while (strpos($lines[$event_line - $find_since_line], '* @since ') === false)
- {
- $find_since_line++;
-
- if ($find_since_line > min(50, $event_line))
- {
- throw new LogicException('Can not find @since tag for event "' . $event_name . '" in file "' . $file . '"');
- }
- }
- $since = substr(trim($lines[$event_line - $find_since_line]), strlen('* @since '));
- $since = ($since == '3.1-A1') ? '3.1.0-a1' : $since;
-
- // Find event description line
- $find_description_line = 3;
- while (strpos(trim($lines[$event_line - $find_description_line]), '*') === 0)
- {
- $find_description_line++;
-
- if ($find_description_line > min(50, $event_line))
- {
- throw new LogicException('Can not find description-line for event "' . $event_name . '" in file "' . $file . '"');
- }
- }
- $description = substr(trim($lines[$event_line - $find_description_line + 1]), strlen('* '));
+ case 'php':
+ $exporter = new \phpbb\event\php_exporter($phpbb_root_path, $extension);
+ $exporter->crawl_phpbb_directory_php();
+ echo $exporter->export_events_for_wiki();
- $events[$event_name] = array(
- 'event' => $event_name,
- 'file' => $file,
- 'arguments' => $arguments,
- 'since' => $since,
- 'description' => $description,
- );
- }
+ if ($action === 'php')
+ {
+ break;
}
- }
-
- return $events;
-}
+ echo "\n";
+ // no break;
-/**
-* Returns a list of files in that directory
-*
-* Works recursive with any depth
-*
-* @param string $dir Directory to go through
-* @return array List of files (including directories from within $dir
-*/
-function get_file_list($dir, $path = '')
-{
- try
- {
- $iterator = new \DirectoryIterator($dir);
- }
- catch (Exception $e)
- {
- return array();
- }
+ case 'styles':
+ $exporter = new \phpbb\event\md_exporter($phpbb_root_path, $extension);
+ $exporter->crawl_phpbb_directory_styles('docs/events.md');
+ echo $exporter->export_events_for_wiki();
- $files = array();
- foreach ($iterator as $file_info)
- {
- if ($file_info->isDot())
+ if ($action === 'styles')
{
- continue;
+ break;
}
+ echo "\n";
+ // no break;
- // Do not scan some directories
- if ($file_info->isDir() && (
- ($path == '' && in_array($file_info->getFilename(), array('cache', 'develop', 'ext', 'files', 'language', 'store', 'vendor')))
- || ($path == '/includes' && in_array($file_info->getFilename(), array('utf')))
- || ($path == '/phpbb/db/migration' && in_array($file_info->getFilename(), array('data')))
- || ($path == '/phpbb' && in_array($file_info->getFilename(), array('event')))
- ))
- {
- continue;
- }
- else if ($file_info->isDir())
- {
- $sub_dir = get_file_list($file_info->getPath() . '/' . $file_info->getFilename(), $path . '/' . $file_info->getFilename());
- foreach ($sub_dir as $file)
- {
- $files[] = $file_info->getFilename() . '/' . $file;
- }
- }
- else if (substr($file_info->getFilename(), -4) == '.php')
+ case 'adm':
+ $exporter = new \phpbb\event\md_exporter($phpbb_root_path, $extension);
+ $exporter->crawl_phpbb_directory_adm('docs/events.md');
+ echo $exporter->export_events_for_wiki();
+
+ if ($action === 'all')
{
- $files[] = $file_info->getFilename();
+ echo "\n" . '[[Category:Events and Listeners]]' . "\n";
}
- }
-
- return $files;
-}
-
-function validate_argument_count($arguments, $count)
-{
- if ($arguments <= $count)
- {
- usage();
- }
-}
-
-validate_argument_count($argc, 1);
-
-$action = $argv[1];
-
-switch ($action)
-{
- case 'acp':
- export_from_eventsmd($phpbb_root_path, 'acp');
- break;
-
- case 'styles':
- export_from_eventsmd($phpbb_root_path, 'styles');
- break;
-
- case 'php':
- export_from_php($phpbb_root_path);
- break;
+ break;
default:
usage();
diff --git a/phpBB/docs/AUTHORS b/phpBB/docs/AUTHORS
index 5ca52c19c0..29ee72caa3 100644
--- a/phpBB/docs/AUTHORS
+++ b/phpBB/docs/AUTHORS
@@ -26,6 +26,7 @@ phpBB Developers: bantu (Andreas Fischer)
dhruv.goel92 (Dhruv Goel)
EXreaction (Nathan Guse)
imkingdavid (David King)
+ marc1706 (Marc Alexander)
nickvergessen (Joas Schilling)
prototech (Cesar Gallegos)
diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html
index 8499431f83..b1e85131f2 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -46,6 +46,7 @@
<ol>
<li><a href="#changelog">Changelog</a>
<ol style="list-style-type: lower-roman;">
+ <li><a href="#v310b2">Changes since 3.1.0-b2</a></li>
<li><a href="#v310b1">Changes since 3.1.0-b1</a></li>
<li><a href="#v310a3">Changes since 3.1.0-a3</a></li>
<li><a href="#v310a2">Changes since 3.1.0-a2</a></li>
@@ -91,7 +92,172 @@
<div class="content">
- <a name="v310b1"></a><h3>1.i. Changes since 3.1.0-b1</h3>
+ <a name="v310b2"></a><h3>1.i. Changes since 3.1.0-b2</h3>
+
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-7707">PHPBB3-7707</a>] - Missing occurrences of get_username_string</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8323">PHPBB3-8323</a>] - Banned User (PMs and Mails)</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8558">PHPBB3-8558</a>] - Board Emails not setting a correct email header</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8700">PHPBB3-8700</a>] - Language file &quot;acp/styles.php&quot; contains many unused language entries</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-8960">PHPBB3-8960</a>] - Allow changing allow_avatar_remote when images/avatars/upload is not writable</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10423">PHPBB3-10423</a>] - Searching for the term &quot;test *&quot; will highlight nearly every word and displays htmlspecialchars as htmlentities.</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10687">PHPBB3-10687</a>] - UNABLE_GET_IMAGE_SIZE text misleading for remote avatars</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10851">PHPBB3-10851</a>] - HTML files containing certain tags being rejected as possible attack vectors with &quot;Check attachment file&quot; set to &quot;No&quot;</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11098">PHPBB3-11098</a>] - New persistent login keys list should have (un)select all and order options.</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11339">PHPBB3-11339</a>] - Using AJAX calls one after another</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11352">PHPBB3-11352</a>] - Disapproving topic takes you to quick reply for that topic</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11431">PHPBB3-11431</a>] - All topic notifications are deleted if one reply is edited and needs to be approved</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11508">PHPBB3-11508</a>] - General error &quot;not allowed as quickmod&quot; when changing the forum while merging two topics</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11772">PHPBB3-11772</a>] - New topic notification triggered when editing an existing post with post-approval enabled</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11860">PHPBB3-11860</a>] - .htaccess not working for Apache 2.4</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11881">PHPBB3-11881</a>] - Timezone migration can take a long time</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11917">PHPBB3-11917</a>] - &quot;Manage external account&quot; shows when not activated</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11978">PHPBB3-11978</a>] - Text field for topic-search</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12004">PHPBB3-12004</a>] - Support empty routes to app.php/ in path_helper</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12012">PHPBB3-12012</a>] - DB Tools should correctly remove columns that are part of indexes</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12043">PHPBB3-12043</a>] - Sort Extensions by Name in ACP Ext Mgr</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12052">PHPBB3-12052</a>] - Post edited by user on moderation queue is not marked as unapproved.</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12083">PHPBB3-12083</a>] - &quot;Select all&quot; selects nothing in Webkit Browsers with only one character in [code] -</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12097">PHPBB3-12097</a>] - The validate_data() function doesn't work with class method</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12113">PHPBB3-12113</a>] - Deleting warnings does not use plurals correctly</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12121">PHPBB3-12121</a>] - Update process doesn't preserve total redirects for links</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12130">PHPBB3-12130</a>] - Bullet character disappears on mouse-over in IE8</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12186">PHPBB3-12186</a>] - MCP should open &quot;Reported posts&quot; instead of PM Reports</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12191">PHPBB3-12191</a>] - UCP should open with global settings instead of notification settings</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12193">PHPBB3-12193</a>] - Broken HTML when an SQL error occurs during migration</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12211">PHPBB3-12211</a>] - Attachment file names are run through htmlspecialchars twice</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12254">PHPBB3-12254</a>] - Language switching on Registration page doesn't work for Extensions</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12265">PHPBB3-12265</a>] - Contact profile fields icons should be hidden in a dropdown</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12286">PHPBB3-12286</a>] - Fix coding guidelines</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12331">PHPBB3-12331</a>] - Fix DB error in update_profile_field_data() with disabled fields</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12342">PHPBB3-12342</a>] - Javascript Bugs and Fixes</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12348">PHPBB3-12348</a>] - Make create_schema_files.php runnable when phpBB is not installed yet</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12350">PHPBB3-12350</a>] - tests/extension/modules_test.php can not be run alone</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12351">PHPBB3-12351</a>] - Ajax &quot;Mark topics read&quot; does not give feedback</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12353">PHPBB3-12353</a>] - User attachments in ACP are not displaying every attachment</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12354">PHPBB3-12354</a>] - passwords_manager_test::test_unique_id fails from time to time</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12355">PHPBB3-12355</a>] - Topic Tools not updated fully updated when subscribing/bookmarking</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12356">PHPBB3-12356</a>] - Plupload does not load in PM editor</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12358">PHPBB3-12358</a>] - data-refresh not working as expected for routes</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12359">PHPBB3-12359</a>] - Day and Month of Birthday Misaligned When Editing</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12360">PHPBB3-12360</a>] - User is displayed twice in online list after second login</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12362">PHPBB3-12362</a>] - Infinite loop in schema generator if dependency can't be resolved</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12367">PHPBB3-12367</a>] - Travis fails in phpbb_wrapper_gmgetdate_test::test_gmgetdate()</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12372">PHPBB3-12372</a>] - dE() function does not toggle in ACP</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12373">PHPBB3-12373</a>] - Add to/from forum ids to LOG_MOVE entries </li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12375">PHPBB3-12375</a>] - Attachment deletion broken after jQuery update</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12378">PHPBB3-12378</a>] - Prosilver common.css has duplicate entries</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12379">PHPBB3-12379</a>] - Plupload labels duplicated when responsive</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12380">PHPBB3-12380</a>] - “Remember Me” login keys are not sorted in UCP</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12381">PHPBB3-12381</a>] - Broken error message when selecting invalid DB driver</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12382">PHPBB3-12382</a>] - Template event listners can not access subloops when loop is defined in the original file</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12386">PHPBB3-12386</a>] - Add DEBUG_EXTRA again and use it for container creation</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12388">PHPBB3-12388</a>] - Log entries without log_data display language key instead of translated string</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12391">PHPBB3-12391</a>] - core.posting_modify_template_vars pass some variables to listeners</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12395">PHPBB3-12395</a>] - Pagination tests fail on travis with postgresql</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12397">PHPBB3-12397</a>] - db_tools::sql_unique_index_exists() has wrong doc block</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12398">PHPBB3-12398</a>] - Prune shadow topics tests fail due to wrong forum_last_post_id</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12405">PHPBB3-12405</a>] - create_user() in functional tests uses invalid timezone and no dateformat</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12406">PHPBB3-12406</a>] - Fix description of page_title var in core.viewtopic_modify_page_title</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12412">PHPBB3-12412</a>] - Styling issue with pagination numbering for smilies and icons</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12413">PHPBB3-12413</a>] - Fatal error &quot;Call to undefined method phpbb\feed\*::fetch_attachments()&quot; for topic based feeds</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12418">PHPBB3-12418</a>] - Notice displayed for feed.php </li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12422">PHPBB3-12422</a>] - Log searches error due to plural arrays in language files</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12429">PHPBB3-12429</a>] - Update phpunit to 3.8+</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12432">PHPBB3-12432</a>] - Migrator should not automatically revert custom functions defined in update_data()</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12436">PHPBB3-12436</a>] - Functional test framework's add_style() should not use sql_multi_insert()</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12444">PHPBB3-12444</a>] - The logs message aren't filled correctly when some values are missing.</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12455">PHPBB3-12455</a>] - Remove unused strings EXTENSION_CONTROLLER_MISSING and EXTENSION_CLASS_WRONG_TYPE from common.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12456">PHPBB3-12456</a>] - Missing new lines at the end of file in language files</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12467">PHPBB3-12467</a>] - Add config_*.php and tests_config_*.php to .gitignore</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12469">PHPBB3-12469</a>] - Convert Timezone test fails because of outdated schema</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12470">PHPBB3-12470</a>] - Move commands from .travis.yml to separate files to allow reuse</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12472">PHPBB3-12472</a>] - Set fast finish for .travis.yml</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12474">PHPBB3-12474</a>] - The console command for updating/migrating the db should display the error with the &lt;error&gt; tag</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12475">PHPBB3-12475</a>] - Undefined variable $log in db:migrate console command</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12477">PHPBB3-12477</a>] - PM link no longer displays in viewtopic</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12478">PHPBB3-12478</a>] - ucp_pm_viewmessage_contact_fields_before/after missing in PM page</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12480">PHPBB3-12480</a>] - \phpbb\extension\finder is finding too many routing files</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12482">PHPBB3-12482</a>] - Undefined variable: data in viewtopic when not logged in</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12485">PHPBB3-12485</a>] - Broken tests due to absolute exclude</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12494">PHPBB3-12494</a>] - Undefined index: user_type on viewtopic.php</li>
+ </ul>
+ <h4>Improvement</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9758">PHPBB3-9758</a>] - Make users avatar available to the template</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10521">PHPBB3-10521</a>] - Override Board Language via URL</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11962">PHPBB3-11962</a>] - Resize images to 100% with in viewtopic</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12150">PHPBB3-12150</a>] - Automatically prune shadow topics</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12201">PHPBB3-12201</a>] - Clean up ACP attachment management page</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12273">PHPBB3-12273</a>] - Add a test to run the event exporter on travis</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12282">PHPBB3-12282</a>] - Add an interface for dbal driver to ensure that functions are there</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12283">PHPBB3-12283</a>] - Online status on posting review page.</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12322">PHPBB3-12322</a>] - Add CSS classes for post-profile &lt;dd&gt; elements</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12323">PHPBB3-12323</a>] - Add Template Event search_results_author_prepend</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12327">PHPBB3-12327</a>] - Changing poll result-bars width from absolute % to relative</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12328">PHPBB3-12328</a>] - Add Template Event index_body_stat_blocks_after</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12329">PHPBB3-12329</a>] - Add &lt;div&gt; container to index blocks (online-list, birthday-list, statistics)</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12333">PHPBB3-12333</a>] - Add Template Event overall_header_page_body_before</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12335">PHPBB3-12335</a>] - Add Events to phpbb\profilefields\manager (grab &amp; show)</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12336">PHPBB3-12336</a>] - Add functions_module.php core events to allow adjusting parameters for custom ACP, MCP, UCP modules</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12337">PHPBB3-12337</a>] - Update jQuery to version 1.11.0</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12338">PHPBB3-12338</a>] - Add Template Event overall_footer_page_body_after</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12339">PHPBB3-12339</a>] - Add Event core.page_header_after</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12344">PHPBB3-12344</a>] - Add event to submit_pm()</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12345">PHPBB3-12345</a>] - Improve search flood interval message</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12346">PHPBB3-12346</a>] - Add Template Event overall_header_navlink_append/prepend</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12347">PHPBB3-12347</a>] - Move breadcrumb seperator from template to CSS</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12361">PHPBB3-12361</a>] - Replace the Google logo with the phpBB logo in the BBCode FAQ</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12364">PHPBB3-12364</a>] - Add template identifier var to all missing pages</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12365">PHPBB3-12365</a>] - Do not crop image attachment heights at 350px</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12366">PHPBB3-12366</a>] - Add Event core.search_get_posts_data</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12369">PHPBB3-12369</a>] - Add template variable for extensions to add classes to &lt;body&gt; element without JS</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12374">PHPBB3-12374</a>] - Add Template events index_body_block_&lt;blockname&gt;_append</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12376">PHPBB3-12376</a>] - Add template events viewtopic_body_polls</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12377">PHPBB3-12377</a>] - Move navbars to separate template files</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12389">PHPBB3-12389</a>] - Move &quot;print topic&quot; &amp; &quot;email topic&quot; icons (and PM versions) to topic tools</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12392">PHPBB3-12392</a>] - Include $profile_fields in core.memberlist_view_profile event</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12396">PHPBB3-12396</a>] - Add Template events viewforum_forum_name_append/prepend</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12400">PHPBB3-12400</a>] - Add viewforum.php core event to allow modifying topics data before display the page</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12401">PHPBB3-12401</a>] - Add $topic_data array to core.viewtopic_modify_post_row event in viewtopic.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12403">PHPBB3-12403</a>] - Add template events to acp_users_prefs.html</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12409">PHPBB3-12409</a>] - Add acp_users.php core events to modify users preferences data</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12410">PHPBB3-12410</a>] - Add Template events search_results_post_before/after</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12411">PHPBB3-12411</a>] - Expand dispatch vars of event: core.search_modify_tpl_ary</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12419">PHPBB3-12419</a>] - Improve font size in notifications drop-down</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12437">PHPBB3-12437</a>] - Clean up redundant &quot;clear&quot; elements &amp; &quot;corners&quot;</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12438">PHPBB3-12438</a>] - Add Template event memberlist_view_content_prepend</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12442">PHPBB3-12442</a>] - Add CSS classes to heading elements</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12473">PHPBB3-12473</a>] - Add console command for updating/migrating database</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12484">PHPBB3-12484</a>] - Template event ucp_agreement_terms_before/after</li>
+ </ul>
+ <h4>New Feature</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9728">PHPBB3-9728</a>] - Support for sqlite version 3</li>
+ </ul>
+ <h4>Sub-task</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12349">PHPBB3-12349</a>] - License in migrations header not linking to version 2 of GNU GPL</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12370">PHPBB3-12370</a>] - Editing a post removes topic notifications</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12371">PHPBB3-12371</a>] - Notifications are incorrectly updated when a post is deleted or moved to ModerationQueue</li>
+ </ul>
+ <h4>Task</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12071">PHPBB3-12071</a>] - Test suite fails if Fileinfo isn't installed</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12199">PHPBB3-12199</a>] - Move deprecated functions to functions_compatibility.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12318">PHPBB3-12318</a>] - Correctly setup HHVM functional tests on Travis CI</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12320">PHPBB3-12320</a>] - No longer allow Travis CI HHVM environment to fail</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12341">PHPBB3-12341</a>] - Add tests for get_username_string()</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12390">PHPBB3-12390</a>] - Released packages MUST NOT contain vendor tests or other non-library code</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12417">PHPBB3-12417</a>] - hhvm-nightly 2014.04.16~precise breaks tests</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12423">PHPBB3-12423</a>] - Increase composer minimum-stability from beta to stable</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12424">PHPBB3-12424</a>] - Update Symfony Dependencies to latest 2.3 releaes</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12458">PHPBB3-12458</a>] - Apply Squiz.WhiteSpace.SuperfluousWhitespace.* sniffs to legacy codebase</li>
+ </ul>
+
+
+ <a name="v310b1"></a><h3>1.ii. Changes since 3.1.0-b1</h3>
<h4>Bug</h4>
<ul>
@@ -159,7 +325,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12302">PHPBB3-12302</a>] - Upgrade composer.phar to 1.0.0-alpha8</li>
</ul>
- <a name="v310a3"></a><h3>1.ii. Changes since 3.1.0-a3</h3>
+ <a name="v310a3"></a><h3>1.iii. Changes since 3.1.0-a3</h3>
<h4>Bug</h4>
<ul>
@@ -306,7 +472,7 @@
</ul>
- <a name="v310a2"></a><h3>1.iii. Changes since 3.1.0-a2</h3>
+ <a name="v310a2"></a><h3>1.iv. Changes since 3.1.0-a2</h3>
<h4>Bug</h4>
<ul>
@@ -414,7 +580,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12147">PHPBB3-12147</a>] - Remove Travis CI notification configuration</li>
</ul>
- <a name="v310a1"></a><h3>1.iv. Changes since 3.1.0-a1</h3>
+ <a name="v310a1"></a><h3>1.v. Changes since 3.1.0-a1</h3>
<h4>Bug</h4>
<ul>
@@ -490,7 +656,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11998">PHPBB3-11998</a>] - Add console / command line client environment </li>
</ul>
- <a name="v30x"></a><h3>1.v. Changes since 3.0.x</h3>
+ <a name="v30x"></a><h3>1.vi. Changes since 3.0.x</h3>
<h4>Bug</h4>
<ul>
@@ -1171,7 +1337,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11913">PHPBB3-11913</a>] - Apply reorganisation of download.phpbb.com to build_announcement.php</li>
</ul>
- <a name="v3011"></a><h3>1.vi. Changes since 3.0.11</h3>
+ <a name="v3011"></a><h3>1.vii. Changes since 3.0.11</h3>
<h4>Bug</h4>
<ul>
@@ -1326,7 +1492,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11753">PHPBB3-11753</a>] - Upgrade mysql_upgrader.php schema data.</li>
</ul>
- <a name="v3010"></a><h3>1.vii. Changes since 3.0.10</h3>
+ <a name="v3010"></a><h3>1.viii. Changes since 3.0.10</h3>
<h4>Bug</h4>
<ul>
@@ -1451,7 +1617,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10909">PHPBB3-10909</a>] - Update Travis Test Configuration: Travis no longer supports PHP 5.3.2</li>
</ul>
- <a name="v309"></a><h3>1.viii. Changes since 3.0.9</h3>
+ <a name="v309"></a><h3>1.ix. Changes since 3.0.9</h3>
<h4>Bug</h4>
<ul>
@@ -1587,7 +1753,7 @@
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10480">PHPBB3-10480</a>] - Automate changelog building</li>
</ul>
- <a name="v308"></a><h3>1.ix. Changes since 3.0.8</h3>
+ <a name="v308"></a><h3>1.x. Changes since 3.0.8</h3>
<h4> Bug
</h4>
@@ -1955,7 +2121,7 @@
</ul>
- <a name="v307-PL1"></a><h3>1.x. Changes since 3.0.7-PL1</h3>
+ <a name="v307-PL1"></a><h3>1.xi. Changes since 3.0.7-PL1</h3>
<h4> Security
</h4>
<ul>
@@ -2413,13 +2579,13 @@
</ul>
- <a name="v307"></a><h3>1.xi. Changes since 3.0.7</h3>
+ <a name="v307"></a><h3>1.xii. Changes since 3.0.7</h3>
<ul>
<li>[Sec] Do not expose forum content of forums with ACL entries but no actual permission in ATOM Feeds. (Bug #58595)</li>
</ul>
- <a name="v306"></a><h3>1.xii. Changes since 3.0.6</h3>
+ <a name="v306"></a><h3>1.xiii. Changes since 3.0.6</h3>
<ul>
<li>[Fix] Allow ban reason and length to be selected and copied in ACP and subsilver2 MCP. (Bug #51095)</li>
@@ -2523,7 +2689,7 @@
</ul>
- <a name="v305"></a><h3>1.xiii. Changes since 3.0.5</h3>
+ <a name="v305"></a><h3>1.xiv. Changes since 3.0.5</h3>
<ul>
<li>[Fix] Allow whitespaces in avatar gallery names. (Bug #44955)</li>
@@ -2745,7 +2911,7 @@
<li>[Feature] Send anonymous statistical information to phpBB on installation and update (optional).</li>
</ul>
- <a name="v304"></a><h3>1.xiv. Changes since 3.0.4</h3>
+ <a name="v304"></a><h3>1.xv. Changes since 3.0.4</h3>
<ul>
<li>[Fix] Delete user entry from ban list table upon user deletion (Bug #40015 - Patch by TerraFrost)</li>
@@ -2834,7 +3000,7 @@
<li>[Sec] Only use forum id supplied for posting if global announcement detected. (Reported by nickvergessen)</li>
</ul>
- <a name="v303"></a><h3>1.xv. Changes since 3.0.3</h3>
+ <a name="v303"></a><h3>1.xvi. Changes since 3.0.3</h3>
<ul>
<li>[Fix] Allow mixed-case template directories to be inherited (Bug #36725)</li>
@@ -2866,7 +3032,7 @@
<li>[Sec] Ask for forum password if post within passworded forum quoted in private message. (Reported by nickvergessen)</li>
</ul>
- <a name="v302"></a><h3>1.xvi. Changes since 3.0.2</h3>
+ <a name="v302"></a><h3>1.xvii. Changes since 3.0.2</h3>
<ul>
<li>[Fix] Correctly set topic starter if first post in topic removed (Bug #30575 - Patch by blueray2048)</li>
@@ -2965,7 +3131,7 @@
<li>[Sec Precaution] Stricter validation of the HTTP_HOST header (Thanks to Techie-Micheal et al for pointing out possible issues in derived code)</li>
</ul>
- <a name="v301"></a><h3>1.xvii. Changes since 3.0.1</h3>
+ <a name="v301"></a><h3>1.xviii. Changes since 3.0.1</h3>
<ul>
<li>[Fix] Ability to set permissions on non-mysql dbms (Bug #24955)</li>
@@ -3013,7 +3179,7 @@
<li>[Sec] Only allow urls gone through redirect() being used within login_box(). (thanks nookieman)</li>
</ul>
- <a name="v300"></a><h3>1.xviii. Changes since 3.0.0</h3>
+ <a name="v300"></a><h3>1.xix. Changes since 3.0.0</h3>
<ul>
<li>[Change] Validate birthdays (Bug #15004)</li>
@@ -3084,7 +3250,7 @@
<li>[Fix] Find and display colliding usernames correctly when converting from one database to another (Bug #23925)</li>
</ul>
- <a name="v30rc8"></a><h3>1.xix. Changes since 3.0.RC8</h3>
+ <a name="v30rc8"></a><h3>1.xx. Changes since 3.0.RC8</h3>
<ul>
<li>[Fix] Cleaned usernames contain only single spaces, so &quot;a_name&quot; and &quot;a__name&quot; are treated as the same name (Bug #15634)</li>
@@ -3093,7 +3259,7 @@
<li>[Fix] Call garbage_collection() within database updater to correctly close connections (affects Oracle for example)</li>
</ul>
- <a name="v30rc7"></a><h3>1.xx. Changes since 3.0.RC7</h3>
+ <a name="v30rc7"></a><h3>1.xxi. Changes since 3.0.RC7</h3>
<ul>
<li>[Fix] Fixed MSSQL related bug in the update system</li>
@@ -3128,7 +3294,7 @@
<li>[Fix] No duplication of active topics (Bug #15474)</li>
</ul>
- <a name="v30rc6"></a><h3>1.xxi. Changes since 3.0.RC6</h3>
+ <a name="v30rc6"></a><h3>1.xxii. Changes since 3.0.RC6</h3>
<ul>
<li>[Fix] Submitting language changes using acp_language (Bug #14736)</li>
@@ -3138,7 +3304,7 @@
<li>[Fix] Able to request new password (Bug #14743)</li>
</ul>
- <a name="v30rc5"></a><h3>1.xxii. Changes since 3.0.RC5</h3>
+ <a name="v30rc5"></a><h3>1.xxiii. Changes since 3.0.RC5</h3>
<ul>
<li>[Feature] Removing constant PHPBB_EMBEDDED in favor of using an exit_handler(); the constant was meant to achive this more or less.</li>
@@ -3201,7 +3367,7 @@
<li>[Sec] New password hashing mechanism for storing passwords (#i42)</li>
</ul>
- <a name="v30rc4"></a><h3>1.xxiii. Changes since 3.0.RC4</h3>
+ <a name="v30rc4"></a><h3>1.xxiv. Changes since 3.0.RC4</h3>
<ul>
<li>[Fix] MySQL, PostgreSQL and SQLite related database fixes (Bug #13862)</li>
@@ -3252,7 +3418,7 @@
<li>[Fix] odbc_autocommit causing existing result sets to be dropped (Bug #14182)</li>
</ul>
- <a name="v30rc3"></a><h3>1.xxiv. Changes since 3.0.RC3</h3>
+ <a name="v30rc3"></a><h3>1.xxv. Changes since 3.0.RC3</h3>
<ul>
<li>[Fix] Fixing some subsilver2 and prosilver style issues</li>
@@ -3361,7 +3527,7 @@
</ul>
- <a name="v30rc2"></a><h3>1.xxv. Changes since 3.0.RC2</h3>
+ <a name="v30rc2"></a><h3>1.xxvi. Changes since 3.0.RC2</h3>
<ul>
<li>[Fix] Re-allow searching within the memberlist</li>
@@ -3407,7 +3573,7 @@
</ul>
- <a name="v30rc1"></a><h3>1.xxvi. Changes since 3.0.RC1</h3>
+ <a name="v30rc1"></a><h3>1.xxvii. Changes since 3.0.RC1</h3>
<ul>
<li>[Fix] (X)HTML issues within the templates (Bug #11255, #11255)</li>
diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html
index 01eeea6540..0b5d06c191 100644
--- a/phpBB/docs/INSTALL.html
+++ b/phpBB/docs/INSTALL.html
@@ -134,7 +134,8 @@
<li>MySQL 3.23 or above (MySQLi supported)</li>
<li>MariaDB 5.1 or above</li>
<li>PostgreSQL 8.3+</li>
- <li>SQLite 2.8.2+ (SQLite 3 is not supported)</li>
+ <li>SQLite 2.8.2+</li>
+ <li>SQLite 3.6.15+</li>
<li>Firebird 2.1+</li>
<li>MS SQL Server 2000 or above (directly or via ODBC or the native adapter)</li>
<li>Oracle</li>
diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md
index 6897c3f22e..66b558a665 100644
--- a/phpBB/docs/events.md
+++ b/phpBB/docs/events.md
@@ -66,16 +66,64 @@ acp_simple_header_body_before
acp_simple_header_head_append
===
-* Location: adm/style/overall_header.html
+* Location: adm/style/simple_header.html
* Since: 3.1.0-a1
* Purpose: Add assets within the `<head>` tags in the simple header of the ACP
acp_users_overview_options_append
===
-* Location: adm/style/acp_users.html
+* Location: adm/style/acp_users_overview.html
* Since: 3.1.0-a1
* Purpose: Add options and settings on user overview page
+acp_users_prefs_append
+===
+* Location: adm/style/acp_users_prefs.html
+* Since: 3.1.0-b3
+* Purpose: Add user options fieldset to the bottom of ACP users prefs settings
+
+acp_users_prefs_prepend
+===
+* Location: adm/style/acp_users_prefs.html
+* Since: 3.1.0-b3
+* Purpose: Add user options fieldset to the top of ACP users prefs settings
+
+acp_users_prefs_personal_append
+===
+* Location: adm/style/acp_users_prefs.html
+* Since: 3.1.0-b3
+* Purpose: Add user options fieldset to the bottom of ACP users personal prefs settings
+
+acp_users_prefs_personal_prepend
+===
+* Location: adm/style/acp_users_prefs.html
+* Since: 3.1.0-b3
+* Purpose: Add user options fieldset to the top of ACP users personal prefs settings
+
+acp_users_prefs_post_append
+===
+* Location: adm/style/acp_users_prefs.html
+* Since: 3.1.0-b3
+* Purpose: Add user options fieldset to the bottom of ACP users post prefs settings
+
+acp_users_prefs_post_prepend
+===
+* Location: adm/style/acp_users_prefs.html
+* Since: 3.1.0-b3
+* Purpose: Add user options fieldset to the top of ACP users post prefs settings
+
+acp_users_prefs_view_append
+===
+* Location: adm/style/acp_users_prefs.html
+* Since: 3.1.0-b3
+* Purpose: Add user options fieldset to the bottom of ACP users view prefs settings
+
+acp_users_prefs_view_prepend
+===
+* Location: adm/style/acp_users_prefs.html
+* Since: 3.1.0-b3
+* Purpose: Add user options fieldset to the top of ACP users view prefs settings
+
acp_users_signature_editor_buttons_after
===
* Locations:
@@ -91,7 +139,7 @@ acp_users_signature_editor_buttons_before
* Purpose: Add content before BBCode posting buttons in the ACP user signature
forumlist_body_category_header_after
-====
+===
* Locations:
+ styles/prosilver/template/forumlist_body.html
+ styles/subsilver2/template/forumlist_body.html
@@ -99,7 +147,7 @@ forumlist_body_category_header_after
* Purpose: Add content after the header of the category on the forum list.
forumlist_body_category_header_before
-====
+===
* Locations:
+ styles/prosilver/template/forumlist_body.html
+ styles/subsilver2/template/forumlist_body.html
@@ -107,7 +155,7 @@ forumlist_body_category_header_before
* Purpose: Add content before the header of the category on the forum list.
forumlist_body_last_post_title_prepend
-====
+===
* Locations:
+ styles/prosilver/template/forumlist_body.html
+ styles/subsilver2/template/forumlist_body.html
@@ -115,7 +163,7 @@ forumlist_body_last_post_title_prepend
* Purpose: Add content before the post title of the latest post in a forum on the forum list.
forumlist_body_subforums_after
-====
+===
* Locations:
+ styles/prosilver/template/forumlist_body.html
+ styles/subsilver2/template/forumlist_body.html
@@ -123,7 +171,7 @@ forumlist_body_subforums_after
* Purpose: Add content after the list of subforums (if any) for each forum on the forum list.
forumlist_body_subforums_before
-====
+===
* Locations:
+ styles/prosilver/template/forumlist_body.html
+ styles/subsilver2/template/forumlist_body.html
@@ -131,13 +179,61 @@ forumlist_body_subforums_before
* Purpose: Add content before the list of subforums (if any) for each forum on the forum list.
forumlist_body_last_row_after
-====
+===
* Locations:
+ styles/prosilver/template/forumlist_body.html
+ styles/subsilver2/template/forumlist_body.html
* Since: 3.1.0-b2
* Purpose: Add content after the very last row of the forum list.
+index_body_block_birthday_append
+===
+* Locations:
+ + styles/prosilver/template/index_body.html
+ + styles/subsilver2/template/index_body.html
+* Since: 3.1.0-b3
+* Purpose: Append content to the birthday list on the Board index
+
+index_body_block_birthday_prepend
+===
+* Locations:
+ + styles/prosilver/template/index_body.html
+ + styles/subsilver2/template/index_body.html
+* Since: 3.1.0-b3
+* Purpose: Prepend content to the birthday list on the Board index
+
+index_body_block_online_append
+===
+* Locations:
+ + styles/prosilver/template/index_body.html
+ + styles/subsilver2/template/index_body.html
+* Since: 3.1.0-b3
+* Purpose: Append content to the online list on the Board index
+
+index_body_block_online_prepend
+===
+* Locations:
+ + styles/prosilver/template/index_body.html
+ + styles/subsilver2/template/index_body.html
+* Since: 3.1.0-b3
+* Purpose: Prepend content to the online list on the Board index
+
+index_body_block_stats_append
+===
+* Locations:
+ + styles/prosilver/template/index_body.html
+ + styles/subsilver2/template/index_body.html
+* Since: 3.1.0-b3
+* Purpose: Append content to the statistics list on the Board index
+
+index_body_block_stats_prepend
+===
+* Locations:
+ + styles/prosilver/template/index_body.html
+ + styles/subsilver2/template/index_body.html
+* Since: 3.1.0-b3
+* Purpose: Prepend content to the statistics list on the Board index
+
index_body_linklist_after
===
* Locations:
@@ -212,6 +308,14 @@ memberlist_view_content_append
* Since: 3.1.0-b2
* Purpose: Add custom content to the user profile view after the main content
+memberlist_view_content_prepend
+===
+* Locations:
+ + styles/prosilver/template/memberlist_view.html
+ + styles/subsilver2/template/memberlist_view.html
+* Since: 3.1.0-b3
+* Purpose: Add custom content to the user profile view before the main content
+
memberlist_view_user_statistics_after
===
* Locations:
@@ -275,6 +379,38 @@ overall_footer_page_body_after
* Since: 3.1.0-b3
* Purpose: Add content after the page-body, but before the footer
+overall_footer_teamlink_after
+===
+* Locations:
+ + styles/prosilver/template/navbar_footer.html
+ + styles/subsilver2/template/index_body.html
+* Since: 3.1.0-b3
+* Purpose: Add contents after the team-link in the footer
+
+overall_footer_teamlink_before
+===
+* Locations:
+ + styles/prosilver/template/navbar_footer.html
+ + styles/subsilver2/template/index_body.html
+* Since: 3.1.0-b3
+* Purpose: Add contents before the team-link in the footer
+
+overall_footer_timezone_after
+===
+* Locations:
+ + styles/prosilver/template/navbar_footer.html
+ + styles/subsilver2/template/breadcrumbs.html
+* Since: 3.1.0-b3
+* Purpose: Add content to the navbar in the page footer, after "Timezone"
+
+overall_footer_timezone_before
+===
+* Locations:
+ + styles/prosilver/template/navbar_footer.html
+ + styles/subsilver2/template/breadcrumbs.html
+* Since: 3.1.0-b3
+* Purpose: Add content to the navbar in the page footer, before "Timezone"
+
overall_header_body_before
===
* Locations:
@@ -323,6 +459,22 @@ overall_header_navigation_prepend
* Since: 3.1.0-a1
* Purpose: Add links before the navigation links in the header
+overall_header_navlink_append
+===
+* Locations:
+ + styles/prosilver/template/navbar_header.html
+ + styles/subsilver2/template/breadcrumbs.html
+* Since: 3.1.0-b3
+* Purpose: Add content after each individual navlink (breadcrumb)
+
+overall_header_navlink_prepend
+===
+* Locations:
+ + styles/prosilver/template/navbar_header.html
+ + styles/subsilver2/template/breadcrumbs.html
+* Since: 3.1.0-b3
+* Purpose: Add content before each individual navlink (breadcrumb)
+
overall_header_page_body_before
===
* Locations:
@@ -419,10 +571,41 @@ quickreply_editor_message_before
* Since: 3.1.0-a4
* Purpose: Add content before the quick reply textbox
+search_results_post_after
+===
+* Locations:
+ + styles/prosilver/template/search_results.html
+ + styles/subsilver2/template/search_results.html
+* Since: 3.1.0-b3
+* Purpose: Add data after search result posts
+
+search_results_post_before
+===
+* Locations:
+ + styles/prosilver/template/search_results.html
+ + styles/subsilver2/template/search_results.html
+* Since: 3.1.0-b3
+* Purpose: Add data before search result posts
+
+search_results_postprofile_after
+===
+* Locations:
+ + styles/prosilver/template/search_results.html
+* Since: 3.1.0-b3
+* Purpose: Add content after the post author and stats in search results (posts view mode)
+
+search_results_postprofile_before
+===
+* Locations:
+ + styles/prosilver/template/search_results.html
+* Since: 3.1.0-b3
+* Purpose: Add content directly before the post author in search results (posts view mode)
+
simple_footer_after
===
* Locations:
+ styles/prosilver/template/simple_footer.html
+ + styles/subsilver2/template/simple_footer.html
* Since: 3.1.0-a1
* Purpose: Add content directly prior to the `</body>` tag of the simple footer
@@ -434,6 +617,14 @@ simple_header_body_before
* Since: 3.1.0-b2
* Purpose: Add content to the header body
+simple_header_head_append
+===
+* Locations:
+ + styles/prosilver/template/simple_header.html
+ + styles/subsilver2/template/simple_header.html
+* Since: 3.1.0-b4
+* Purpose: Add asset calls directly before the `</head>` tag
+
topiclist_row_prepend
===
* Locations:
@@ -454,6 +645,38 @@ topiclist_row_append
* Since: 3.1.0-a1
* Purpose: Add content into topic rows (inside the elements containing topic titles)
+ucp_agreement_terms_after
+===
+* Locations:
+ + styles/prosilver/template/ucp_agreement.html
+ + styles/subsilver2/template/ucp_agreement.html
+* Since: 3.1.0-b3
+* Purpose: Add content after the terms of agreement text at user registration
+
+ucp_agreement_terms_before
+===
+* Locations:
+ + styles/prosilver/template/ucp_agreement.html
+ + styles/subsilver2/template/ucp_agreement.html
+* Since: 3.1.0-b3
+* Purpose: Add content before the terms of agreement text at user registration
+
+ucp_pm_viewmessage_contact_fields_after
+===
+* Locations:
+ + styles/prosilver/template/ucp_pm_viewmessage.html
+* Since: 3.1.0-b1
+* Purpose: Add data after the contact fields on the user profile when viewing
+a private message
+
+ucp_pm_viewmessage_contact_fields_before
+===
+* Locations:
+ + styles/prosilver/template/ucp_pm_viewmessage.html
+* Since: 3.1.0-b1
+* Purpose: Add data before the contact fields on the user profile when viewing
+a private message
+
ucp_pm_viewmessage_custom_fields_after
===
* Locations:
@@ -549,19 +772,35 @@ Display Options screen
ucp_friend_list_before
===
* Locations:
- + styles/prosilver/template/ucp_zebra_friends.html
- + styles/subsilver2/template/ucp_zebra_friends.html
+ + styles/prosilver/template/ucp_zebra_friends.html
+ + styles/subsilver2/template/ucp_zebra_friends.html
* Since: 3.1.0-a4
* Purpose: Add optional elements before list of friends in UCP
ucp_friend_list_after
===
* Locations:
- + styles/prosilver/template/ucp_zebra_friends.html
- + styles/subsilver2/template/ucp_zebra_friends.html
+ + styles/prosilver/template/ucp_zebra_friends.html
+ + styles/subsilver2/template/ucp_zebra_friends.html
* Since: 3.1.0-a4
* Purpose: Add optional elements after list of friends in UCP
+viewforum_forum_name_append
+===
+* Locations:
+ + styles/prosilver/template/viewforum_body.html
+ + styles/subsilver2/template/viewforum_body.html
+* Since: 3.1.0-b3
+* Purpose: Add content directly after the forum name link on the View forum screen
+
+viewforum_forum_name_prepend
+===
+* Locations:
+ + styles/prosilver/template/viewforum_body.html
+ + styles/subsilver2/template/viewforum_body.html
+* Since: 3.1.0-b3
+* Purpose: Add content directly before the forum name link on the View forum screen
+
viewtopic_print_head_append
===
* Locations:
@@ -570,6 +809,22 @@ viewtopic_print_head_append
* Since: 3.1.0-a1
* Purpose: Add asset calls directly before the `</head>` tag of the Print Topic screen
+viewtopic_body_contact_fields_after
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+* Since: 3.1.0-b3
+* Purpose: Add data after the contact fields on the user profile when viewing
+a post
+
+viewtopic_body_contact_fields_before
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+* Since: 3.1.0-b3
+* Purpose: Add data before the contact fields on the user profile when viewing
+a post
+
viewtopic_body_footer_before
===
* Locations:
@@ -580,6 +835,40 @@ viewtopic_body_footer_before
and quick reply, directly before the jumpbox in Prosilver, breadcrumbs in
Subsilver2.
+viewtopic_body_poll_option_after
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+ + styles/subsilver2/template/viewtopic_body.html
+* Since: 3.1.0-b3
+* Purpose: Add content after the poll option
+the list.
+
+viewtopic_body_poll_option_before
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+ + styles/subsilver2/template/viewtopic_body.html
+* Since: 3.1.0-b3
+* Purpose: Add content before the poll option
+the list.
+
+viewtopic_body_poll_question_append
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+ + styles/subsilver2/template/viewtopic_body.html
+* Since: 3.1.0-b3
+* Purpose: Add content directly after the poll question on the View topic screen
+
+viewtopic_body_poll_question_prepend
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+ + styles/subsilver2/template/viewtopic_body.html
+* Since: 3.1.0-b3
+* Purpose: Add content directly before the poll question on the View topic screen
+
viewtopic_body_post_buttons_after
===
* Locations:
@@ -656,6 +945,14 @@ viewtopic_body_topic_actions_before
* Since: 3.1.0-a4
* Purpose: Add data before the topic actions buttons (after the posts sorting options)
+viewtopic_topic_title_append
+===
+* Locations:
+ + styles/prosilver/template/viewtopic_body.html
+ + styles/subsilver2/template/viewtopic_body.html
+* Since: 3.1.0-b3
+* Purpose: Add content directly after the topic title link on the View topic screen
+
viewtopic_topic_title_prepend
===
* Locations:
diff --git a/phpBB/feed.php b/phpBB/feed.php
index 9ff8c66b9d..db0ed5364e 100644
--- a/phpBB/feed.php
+++ b/phpBB/feed.php
@@ -73,9 +73,6 @@ if ($feed === false)
trigger_error('NO_FEED');
}
-// Get attachments for this feed
-$feed->fetch_attachments();
-
// Open Feed
$feed->open();
@@ -103,6 +100,8 @@ while ($row = $feed->get_item())
$published = ($feed->get('published') !== NULL) ? (int) $row[$feed->get('published')] : 0;
$updated = ($feed->get('updated') !== NULL) ? (int) $row[$feed->get('updated')] : 0;
+ $display_attachments = ($auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']) && isset($row['post_attachment']) && $row['post_attachment']) ? true : false;
+
$item_row = array(
'author' => ($feed->get('creator') !== NULL) ? $row[$feed->get('creator')] : '',
'published' => ($published > 0) ? $phpbb_feed_helper->format_date($published) : '',
@@ -111,7 +110,7 @@ while ($row = $feed->get_item())
'title' => censor_text($title),
'category' => ($config['feed_item_statistics'] && !empty($row['forum_id'])) ? $board_url . '/viewforum.' . $phpEx . '?f=' . $row['forum_id'] : '',
'category_name' => ($config['feed_item_statistics'] && isset($row['forum_name'])) ? $row['forum_name'] : '',
- 'description' => censor_text($phpbb_feed_helper->generate_content($row[$feed->get('text')], $row[$feed->get('bbcode_uid')], $row[$feed->get('bitfield')], $options, $row['forum_id'], (($row['post_attachment']) ? $feed->attachments[$row['post_id']] : array()))),
+ 'description' => censor_text($phpbb_feed_helper->generate_content($row[$feed->get('text')], $row[$feed->get('bbcode_uid')], $row[$feed->get('bitfield')], $options, $row['forum_id'], ($display_attachments ? $feed->get_attachments($row['post_id']) : array()))),
'statistics' => '',
);
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index d8d382b2bd..03d3e0f85f 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -147,7 +147,6 @@ class acp_attachments
'secure_allow_empty_referer' => array('lang' => 'SECURE_EMPTY_REFERRER', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'check_attachment_content' => array('lang' => 'CHECK_CONTENT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
-
'legend2' => $l_legend_cat_images,
'img_display_inlined' => array('lang' => 'DISPLAY_INLINED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'img_create_thumbnail' => array('lang' => 'CREATE_THUMBNAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
@@ -1223,7 +1222,7 @@ class acp_attachments
'ATTACHMENT_POSTER' => get_username_string('full', (int) $row['poster_id'], (string) $row['username'], (string) $row['user_colour'], (string) $row['username']),
'FILESIZE' => get_formatted_filesize((int) $row['filesize']),
'FILETIME' => $user->format_date((int) $row['filetime']),
- 'REAL_FILENAME' => (!$row['in_message']) ? utf8_wordwrap(utf8_basename((string) $row['real_filename']), 40, '<br />', true) : '',
+ 'REAL_FILENAME' => (!$row['in_message']) ? utf8_basename((string) $row['real_filename']) : '',
'PHYSICAL_FILENAME' => utf8_basename((string) $row['physical_filename']),
'EXT_GROUP_NAME' => (!empty($extensions[$row['extension']]['group_name'])) ? $user->lang['EXT_GROUP_' . $extensions[$row['extension']]['group_name']] : '',
'COMMENT' => $comment,
@@ -1287,7 +1286,7 @@ class acp_attachments
/**
* Set config attachment stat values
*
- * @param $stats array Array of config key => value pairs to set.
+ * @param $stats array Array of config key => value pairs to set.
* @return null
*/
public function set_attachment_stats($stats)
@@ -1301,7 +1300,7 @@ class acp_attachments
/**
* Check accuracy of attachment statistics.
*
- * @param $resync bool Resync stats if they're incorrect.
+ * @param $resync bool Resync stats if they're incorrect.
* @return bool|string Returns false if stats are correct or error message
* otherwise.
*/
@@ -1312,7 +1311,7 @@ class acp_attachments
// Get current files stats
$num_files = (int) $this->config['num_files'];
- $total_size = (float) $this->config['upload_dir_size'];
+ $total_size = (float) $this->config['upload_dir_size'];
if (($num_files != $stats['num_files']) || ($total_size != $stats['upload_dir_size']))
{
diff --git a/phpBB/includes/acp/acp_ban.php b/phpBB/includes/acp/acp_ban.php
index 3ed9c225f5..41095f1382 100644
--- a/phpBB/includes/acp/acp_ban.php
+++ b/phpBB/includes/acp/acp_ban.php
@@ -109,7 +109,7 @@ class acp_ban
'L_NO_BAN_CELL' => $l_no_ban_cell,
'S_USERNAME_BAN' => ($mode == 'user') ? true : false,
-
+
'U_ACTION' => $this->u_action,
'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&amp;form=acp_ban&amp;field=ban'),
));
diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php
index 84382b6276..4b9072d12a 100644
--- a/phpBB/includes/acp/acp_bbcodes.php
+++ b/phpBB/includes/acp/acp_bbcodes.php
@@ -142,7 +142,7 @@ class acp_bbcodes
case 'create':
$sql_ary = $hidden_fields = array();
-
+
/**
* Modify custom bbcode data before the modify/create action
*
@@ -159,7 +159,16 @@ class acp_bbcodes
* submitting form when $warn_text is true
* @since 3.1.0-a3
*/
- $vars = array('action', 'sql_ary', 'bbcode_id', 'display_on_posting', 'bbcode_match', 'bbcode_tpl', 'bbcode_helpline', 'hidden_fields');
+ $vars = array(
+ 'action',
+ 'sql_ary',
+ 'bbcode_id',
+ 'display_on_posting',
+ 'bbcode_match',
+ 'bbcode_tpl',
+ 'bbcode_helpline',
+ 'hidden_fields',
+ );
extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_modify_create', compact($vars)));
$warn_text = preg_match('%<[^>]*\{text[\d]*\}[^>]*>%i', $bbcode_tpl);
@@ -210,7 +219,6 @@ class acp_bbcodes
trigger_error($user->lang['BBCODE_TAG_DEF_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING);
}
-
if (strlen($bbcode_helpline) > 255)
{
trigger_error($user->lang['BBCODE_HELPLINE_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING);
@@ -311,7 +319,7 @@ class acp_bbcodes
$db->sql_query('DELETE FROM ' . BBCODES_TABLE . " WHERE bbcode_id = $bbcode_id");
$cache->destroy('sql', BBCODES_TABLE);
add_log('admin', 'LOG_BBCODE_DELETE', $row['bbcode_tag']);
-
+
if ($request->is_ajax())
{
$json_response = new \phpbb\json_response;
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 2c0eb95cd5..cf0f23a16e 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -345,6 +345,7 @@ class acp_board
'load_user_activity' => array('lang' => 'LOAD_USER_ACTIVITY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'load_tplcompile' => array('lang' => 'RECOMPILE_STYLES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'allow_cdn' => array('lang' => 'ALLOW_CDN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'allow_live_searches' => array('lang' => 'ALLOW_LIVE_SEARCHES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'legend3' => 'CUSTOM_PROFILE_FIELDS',
'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
@@ -434,6 +435,7 @@ class acp_board
'email_function_name' => array('lang' => 'EMAIL_FUNCTION_NAME', 'validate' => 'string', 'type' => 'text:20:50', 'explain' => true),
'email_package_size' => array('lang' => 'EMAIL_PACKAGE_SIZE', 'validate' => 'int:0', 'type' => 'number:0:99999', 'explain' => true),
'board_contact' => array('lang' => 'CONTACT_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true),
+ 'board_contact_name' => array('lang' => 'CONTACT_EMAIL_NAME', 'validate' => 'string', 'type' => 'text:25:50', 'explain' => true),
'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true),
'board_email_sig' => array('lang' => 'EMAIL_SIG', 'validate' => 'string', 'type' => 'textarea:5:30', 'explain' => true),
'board_hide_emails' => array('lang' => 'BOARD_HIDE_EMAILS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
diff --git a/phpBB/includes/acp/acp_bots.php b/phpBB/includes/acp/acp_bots.php
index e28a8d6451..7384f719bf 100644
--- a/phpBB/includes/acp/acp_bots.php
+++ b/phpBB/includes/acp/acp_bots.php
@@ -157,7 +157,7 @@ class acp_bots
{
$error[] = $user->lang['ERR_BOT_NO_MATCHES'];
}
-
+
if ($bot_row['bot_ip'] && !preg_match('#^[\d\.,:]+$#', $bot_row['bot_ip']))
{
if (!$ip_list = gethostbynamel($bot_row['bot_ip']))
@@ -176,7 +176,7 @@ class acp_bots
{
$error[] = $user->lang['ERR_BOT_AGENT_MATCHES_UA'];
}
-
+
$bot_name = false;
if ($bot_id)
{
@@ -201,7 +201,7 @@ class acp_bots
{
$error[] = $user->lang['BOT_NAME_TAKEN'];
}
-
+
if (!sizeof($error))
{
// New bot? Create a new user and group entry
@@ -219,7 +219,6 @@ class acp_bots
{
trigger_error($user->lang['NO_BOT_GROUP'] . adm_back_link($this->u_action . "&amp;id=$bot_id&amp;action=$action"), E_USER_WARNING);
}
-
$user_id = user_add(array(
'user_type' => (int) USER_IGNORE,
@@ -233,7 +232,7 @@ class acp_bots
'user_style' => (int) $bot_row['bot_style'],
'user_allow_massemail' => 0,
));
-
+
$sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
'user_id' => (int) $user_id,
'bot_name' => (string) $bot_row['bot_name'],
@@ -242,7 +241,7 @@ class acp_bots
'bot_ip' => (string) $bot_row['bot_ip'])
);
$db->sql_query($sql);
-
+
$log = 'ADDED';
}
else if ($bot_id)
@@ -289,12 +288,12 @@ class acp_bots
$log = 'UPDATED';
}
-
+
$cache->destroy('_bots');
-
+
add_log('admin', 'LOG_BOT_' . $log, $bot_row['bot_name']);
trigger_error($user->lang['BOT_' . $log] . adm_back_link($this->u_action));
-
+
}
}
else if ($bot_id)
@@ -335,11 +334,11 @@ class acp_bots
'U_ACTION' => $this->u_action . "&amp;id=$bot_id&amp;action=$action",
'U_BACK' => $this->u_action,
'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '',
-
+
'BOT_NAME' => $bot_row['bot_name'],
'BOT_IP' => $bot_row['bot_ip'],
'BOT_AGENT' => $bot_row['bot_agent'],
-
+
'S_EDIT_BOT' => true,
'S_ACTIVE_OPTIONS' => $s_active_options,
'S_STYLE_OPTIONS' => $style_select,
@@ -352,7 +351,7 @@ class acp_bots
break;
}
-
+
if ($request->is_ajax() && ($action == 'activate' || $action == 'deactivate'))
{
$json_response = new \phpbb\json_response;
@@ -397,7 +396,7 @@ class acp_bots
}
$db->sql_freeresult($result);
}
-
+
/**
* Validate bot name against username table
*/
@@ -417,7 +416,7 @@ class acp_bots
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
-
+
return ($row) ? false : true;
}
}
diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php
index 1a083c20ac..71defda09f 100644
--- a/phpBB/includes/acp/acp_captcha.php
+++ b/phpBB/includes/acp/acp_captcha.php
@@ -36,7 +36,6 @@ class acp_captcha
$selected = (isset($captchas['available'][$selected]) || isset($captchas['unavailable'][$selected])) ? $selected : $config['captcha_plugin'];
$configure = request_var('configure', false);
-
// Oh, they are just here for the view
if (isset($_GET['captcha_demo']))
{
diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php
index 8afc3709b9..51715141eb 100644
--- a/phpBB/includes/acp/acp_database.php
+++ b/phpBB/includes/acp/acp_database.php
@@ -101,6 +101,10 @@ class acp_database
$extractor = new sqlite_extractor($format, $filename, $time, $download, $store);
break;
+ case 'sqlite3':
+ $extractor = new sqlite3_extractor($format, $filename, $time, $download, $store);
+ break;
+
case 'postgres':
$extractor = new postgres_extractor($format, $filename, $time, $download, $store);
break;
@@ -135,6 +139,7 @@ class acp_database
switch ($db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
case 'firebird':
$extractor->flush('DELETE FROM ' . $table_name . ";\n");
break;
@@ -325,6 +330,7 @@ class acp_database
case 'mysql4':
case 'mysqli':
case 'sqlite':
+ case 'sqlite3':
while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
{
$db->sql_query($sql);
@@ -1052,6 +1058,112 @@ class sqlite_extractor extends base_extractor
/**
* @package acp
*/
+class sqlite3_extractor extends base_extractor
+{
+ function write_start($prefix)
+ {
+ $sql_data = "--\n";
+ $sql_data .= "-- phpBB Backup Script\n";
+ $sql_data .= "-- Dump of tables for $prefix\n";
+ $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
+ $sql_data .= "--\n";
+ $sql_data .= "BEGIN TRANSACTION;\n";
+ $this->flush($sql_data);
+ }
+
+ function write_table($table_name)
+ {
+ global $db;
+ $sql_data = '-- Table: ' . $table_name . "\n";
+ $sql_data .= "DROP TABLE $table_name;\n";
+
+ $sql = "SELECT sql
+ FROM sqlite_master
+ WHERE type = 'table'
+ AND name = '" . $db->sql_escape($table_name) . "'
+ ORDER BY name ASC;";
+ $result = $db->sql_query($sql);
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ // Create Table
+ $sql_data .= $row['sql'] . ";\n";
+
+ $result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');");
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ if (strpos($row['name'], 'autoindex') !== false)
+ {
+ continue;
+ }
+
+ $result2 = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($row['name']) . "');");
+
+ $fields = array();
+ while ($row2 = $db->sql_fetchrow($result2))
+ {
+ $fields[] = $row2['name'];
+ }
+ $db->sql_freeresult($result2);
+
+ $sql_data .= 'CREATE ' . ($row['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $row['name'] . ' ON ' . $table_name . ' (' . implode(', ', $fields) . ");\n";
+ }
+ $db->sql_freeresult($result);
+
+ $this->flush($sql_data . "\n");
+ }
+
+ function write_data($table_name)
+ {
+ global $db;
+
+ $result = $db->sql_query("PRAGMA table_info('" . $db->sql_escape($table_name) . "');");
+
+ $col_types = array();
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $col_types[$row['name']] = $row['type'];
+ }
+ $db->sql_freeresult($result);
+
+ $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES (';
+
+ $sql = "SELECT *
+ FROM $table_name";
+ $result = $db->sql_query($sql);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ foreach ($row as $column_name => $column_data)
+ {
+ if (is_null($column_data))
+ {
+ $row[$column_name] = 'NULL';
+ }
+ else if ($column_data === '')
+ {
+ $row[$column_name] = "''";
+ }
+ else if (stripos($col_types[$column_name], 'text') !== false || stripos($col_types[$column_name], 'char') !== false || stripos($col_types[$column_name], 'blob') !== false)
+ {
+ $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data));
+ }
+ }
+ $this->flush($sql_insert . implode(', ', $row) . ");\n");
+ }
+ }
+
+ function write_end()
+ {
+ $this->flush("COMMIT;\n");
+ parent::write_end();
+ }
+}
+
+/**
+* @package acp
+*/
class postgres_extractor extends base_extractor
{
function write_start($prefix)
@@ -1180,7 +1292,6 @@ class postgres_extractor extends base_extractor
}
$db->sql_freeresult($result);
-
// Get the listing of primary keys.
$sql_pri_keys = "SELECT ic.relname as index_name, bc.relname as tab_name, ta.attname as column_name, i.indisunique as unique_key, i.indisprimary as primary_key
FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia
@@ -1280,7 +1391,6 @@ class postgres_extractor extends base_extractor
$ary_type[] = pg_field_type($result, $i);
$ary_name[] = pg_field_name($result, $i);
-
$sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
FROM pg_attrdef d, pg_class c
WHERE (c.relname = '{$table_name}')
diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php
index 1de6987624..21a1909ac1 100644
--- a/phpBB/includes/acp/acp_extensions.php
+++ b/phpBB/includes/acp/acp_extensions.php
@@ -242,7 +242,7 @@ class acp_extensions
public function list_enabled_exts(\phpbb\extension\manager $phpbb_extension_manager)
{
$enabled_extension_meta_data = array();
-
+
foreach ($phpbb_extension_manager->all_enabled() as $name => $location)
{
$md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template);
@@ -284,7 +284,7 @@ class acp_extensions
public function list_disabled_exts(\phpbb\extension\manager $phpbb_extension_manager)
{
$disabled_extension_meta_data = array();
-
+
foreach ($phpbb_extension_manager->all_disabled() as $name => $location)
{
$md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template);
@@ -329,7 +329,7 @@ class acp_extensions
$uninstalled = array_diff_key($phpbb_extension_manager->all_available(), $phpbb_extension_manager->all_configured());
$available_extension_meta_data = array();
-
+
foreach ($uninstalled as $name => $location)
{
$md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template);
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index c47d9bc185..160bfc05de 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -158,7 +158,7 @@ class acp_forums
* @event core.acp_manage_forums_request_data
* @var string action Type of the action: add|edit
* @var array forum_data Array with new forum data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('action', 'forum_data');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_request_data', compact($vars)));
@@ -484,7 +484,7 @@ class acp_forums
* empty when creating new forum
* @var array forum_data Array with new forum data
* @var string parents_list List of parent options
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('action', 'update', 'forum_id', 'row', 'forum_data', 'parents_list');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_initialise_data', compact($vars)));
@@ -705,9 +705,18 @@ class acp_forums
* ensure to update the template variables
* S_ERROR and ERROR_MSG to display it
* @var array template_data Array with new forum data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
- $vars = array('action', 'update', 'forum_id', 'row', 'forum_data', 'parents_list', 'errors', 'template_data');
+ $vars = array(
+ 'action',
+ 'update',
+ 'forum_id',
+ 'row',
+ 'forum_data',
+ 'parents_list',
+ 'errors',
+ 'template_data',
+ );
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_display_form', compact($vars)));
$template->assign_vars($template_data);
@@ -946,7 +955,7 @@ class acp_forums
* @var array forum_data Array with new forum data
* @var array errors Array of errors, should be strings and not
* language key.
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('forum_data', 'errors');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_validate_data', compact($vars)));
@@ -1054,7 +1063,7 @@ class acp_forums
* @var array forum_data_sql Array with data we are going to update
* If forum_data_sql[forum_id] is set, we update
* that forum, otherwise a new one is created.
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('forum_data', 'forum_data_sql');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_before', compact($vars)));
@@ -1347,7 +1356,7 @@ class acp_forums
* ensure to set forum_data_sql[forum_id]
* @var array errors Array of errors, should be strings and not
* language key.
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('forum_data', 'forum_data_sql', 'is_new_forum', 'errors');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_after', compact($vars)));
@@ -1385,7 +1394,7 @@ class acp_forums
* @var int to_id If of the new parent forum
* @var array errors Array of errors, should be strings and not
* language key.
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('from_id', 'to_id', 'errors');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_children', compact($vars)));
@@ -1489,7 +1498,7 @@ class acp_forums
* @var array errors Array of errors, should be strings and not
* language key. If this array is not empty,
* The content will not be moved.
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('from_id', 'to_id', 'sync', 'errors');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_content', compact($vars)));
diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php
index 7ecedcf51e..c52289aa72 100644
--- a/phpBB/includes/acp/acp_groups.php
+++ b/phpBB/includes/acp/acp_groups.php
@@ -53,7 +53,6 @@ class acp_groups
$start = request_var('start', 0);
$update = (isset($_POST['update'])) ? true : false;
-
// Clear some vars
$group_row = array();
@@ -140,7 +139,7 @@ class acp_groups
if (confirm_box(true))
{
$group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'];
- group_user_attributes('default', $group_id, $mark_ary, false, $group_name, $group_row);
+ group_user_attributes('default', $group_id, $mark_ary, false, $group_name, $group_row);
trigger_error($user->lang['GROUP_DEFS_UPDATED'] . adm_back_link($this->u_action . '&amp;action=list&amp;g=' . $group_id));
}
else
@@ -331,7 +330,6 @@ class acp_groups
}
}
-
// Did we submit?
if ($update)
{
diff --git a/phpBB/includes/acp/acp_icons.php b/phpBB/includes/acp/acp_icons.php
index 20b1f56182..e4221a86dc 100644
--- a/phpBB/includes/acp/acp_icons.php
+++ b/phpBB/includes/acp/acp_icons.php
@@ -203,7 +203,6 @@ class acp_icons
unset($_images[$row[$fields . '_url']]);
}
-
if ($row[$fields . '_id'] == $icon_id)
{
$after = true;
@@ -539,6 +538,7 @@ class acp_icons
switch ($db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
case 'firebird':
$db->sql_query('DELETE FROM ' . $table);
break;
@@ -781,7 +781,7 @@ class acp_icons
$cache->destroy('_icons');
$cache->destroy('sql', $table);
-
+
if ($request->is_ajax())
{
$json_response = new \phpbb\json_response;
diff --git a/phpBB/includes/acp/acp_logs.php b/phpBB/includes/acp/acp_logs.php
index 10852e3a68..2c795bb77b 100644
--- a/phpBB/includes/acp/acp_logs.php
+++ b/phpBB/includes/acp/acp_logs.php
@@ -118,7 +118,7 @@ class acp_logs
if ($mode == 'mod')
{
$forum_box = '<option value="0">' . $user->lang['ALL_FORUMS'] . '</option>' . make_forum_select($forum_id);
-
+
$template->assign_vars(array(
'S_SHOW_FORUMS' => true,
'S_FORUM_BOX' => $forum_box)
@@ -149,7 +149,7 @@ class acp_logs
foreach ($log_data as $row)
{
$data = array();
-
+
$checks = array('viewtopic', 'viewlogs', 'viewforum');
foreach ($checks as $check)
{
diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php
index 4512905539..9c1613e24a 100644
--- a/phpBB/includes/acp/acp_main.php
+++ b/phpBB/includes/acp/acp_main.php
@@ -271,6 +271,7 @@ class acp_main
switch ($db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
case 'firebird':
$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
break;
@@ -376,6 +377,7 @@ class acp_main
switch ($db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
case 'firebird':
$db->sql_query("DELETE FROM $table");
break;
diff --git a/phpBB/includes/acp/acp_permission_roles.php b/phpBB/includes/acp/acp_permission_roles.php
index aca45575d3..812e22a025 100644
--- a/phpBB/includes/acp/acp_permission_roles.php
+++ b/phpBB/includes/acp/acp_permission_roles.php
@@ -270,7 +270,7 @@ class acp_permission_roles
case 'edit':
if ($action == 'edit')
- {
+ {
$sql = 'SELECT *
FROM ' . ACL_ROLES_TABLE . '
WHERE role_id = ' . $role_id;
diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php
index e7dc03db5c..1924e2075b 100644
--- a/phpBB/includes/acp/acp_permissions.php
+++ b/phpBB/includes/acp/acp_permissions.php
@@ -330,7 +330,6 @@ class acp_permissions
}
}
-
// Setting permissions screen
$s_hidden_fields = build_hidden_fields(array(
'user_id' => $user_id,
diff --git a/phpBB/includes/acp/acp_php_info.php b/phpBB/includes/acp/acp_php_info.php
index 125b77529f..13d2fd770a 100644
--- a/phpBB/includes/acp/acp_php_info.php
+++ b/phpBB/includes/acp/acp_php_info.php
@@ -81,7 +81,7 @@ class acp_php_info
$template->assign_var('PHPINFO', $output);
}
-
+
function remove_spaces($matches)
{
return '<a name="' . str_replace(' ', '_', $matches[1]) . '">';
diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php
index 4d316d84e4..8940410d72 100644
--- a/phpBB/includes/acp/acp_profile.php
+++ b/phpBB/includes/acp/acp_profile.php
@@ -114,6 +114,7 @@ class acp_profile
switch ($db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
$sql = "SELECT sql
FROM sqlite_master
WHERE type = 'table'
@@ -485,7 +486,6 @@ class acp_profile
}
$db->sql_freeresult($result);
-
$sql = 'SELECT lang_id, lang_name, lang_explain, lang_default_value
FROM ' . PROFILE_LANG_TABLE . '
WHERE lang_id <> ' . $this->edit_lang_id . "
@@ -1116,7 +1116,6 @@ class acp_profile
}
}
-
$db->sql_transaction('begin');
if ($action == 'create')
@@ -1206,7 +1205,8 @@ class acp_profile
break;
case 'sqlite':
- if (version_compare(sqlite_libversion(), '3.0') == -1)
+ case 'sqlite3':
+ if (version_compare($db->sql_server_info(true), '3.0') == -1)
{
$sql = "SELECT sql
FROM sqlite_master
diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php
index d0e5dfb5f4..3850e7efe7 100644
--- a/phpBB/includes/acp/acp_prune.php
+++ b/phpBB/includes/acp/acp_prune.php
@@ -79,7 +79,7 @@ class acp_prune
$prune_posted = request_var('prune_days', 0);
$prune_viewed = request_var('prune_vieweddays', 0);
$prune_all = (!$prune_posted && !$prune_viewed) ? true : false;
-
+
$prune_flags = 0;
$prune_flags += (request_var('prune_old_polls', 0)) ? 2 : 0;
$prune_flags += (request_var('prune_announce', 0)) ? 4 : 0;
@@ -109,7 +109,7 @@ class acp_prune
$p_result['topics'] = 0;
$p_result['posts'] = 0;
$log_data = '';
-
+
do
{
if (!$auth->acl_get('f_list', $row['forum_id']))
@@ -129,7 +129,7 @@ class acp_prune
$p_result['topics'] += $return['topics'];
$p_result['posts'] += $return['posts'];
}
-
+
if ($prune_viewed)
{
$return = prune($row['forum_id'], 'viewed', $prunedate_viewed, $prune_flags, false);
@@ -145,11 +145,11 @@ class acp_prune
'NUM_TOPICS' => $p_result['topics'],
'NUM_POSTS' => $p_result['posts'])
);
-
+
$log_data .= (($log_data != '') ? ', ' : '') . $row['forum_name'];
}
while ($row = $db->sql_fetchrow($result));
-
+
// Sync all pruned forums at once
sync('forum', 'forum_id', $prune_ids, true, true);
add_log('admin', 'LOG_PRUNE', $log_data);
@@ -256,7 +256,7 @@ class acp_prune
if ($deleteposts)
{
user_delete('remove', $user_ids);
-
+
$l_log = 'LOG_PRUNE_USER_DEL_DEL';
}
else
@@ -444,7 +444,7 @@ class acp_prune
if (sizeof($active) && (int) $active[0] == 0 && (int) $active[1] == 0 && (int) $active[2] == 0)
{
$where_sql .= ' AND user_lastvisit = 0';
- }
+ }
else if (sizeof($active) && $active_select != 'lt')
{
$where_sql .= ' AND user_lastvisit ' . $key_match[$active_select] . ' ' . gmmktime(0, 0, 0, (int) $active[1], (int) $active[2], (int) $active[0]);
@@ -533,7 +533,7 @@ class acp_prune
WHERE u.user_id <> ' . ANONYMOUS . '
AND u.user_type <> ' . USER_FOUNDER .
((!empty($user_ids)) ? 'AND ' . $db->sql_in_set('p.poster_id', $user_ids) : '') . '
- AND p.post_visibility = ' . ITEM_UNAPPROVED . '
+ AND ' . $db->sql_in_set('p.post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . '
AND u.user_id = p.poster_id
GROUP BY p.poster_id
HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue;
diff --git a/phpBB/includes/acp/acp_ranks.php b/phpBB/includes/acp/acp_ranks.php
index 73e1de44d9..55028cc882 100644
--- a/phpBB/includes/acp/acp_ranks.php
+++ b/phpBB/includes/acp/acp_ranks.php
@@ -214,7 +214,6 @@ class acp_ranks
'MIN_POSTS' => (isset($ranks['rank_min']) && !$ranks['rank_special']) ? $ranks['rank_min'] : 0)
);
-
return;
break;
diff --git a/phpBB/includes/acp/acp_reasons.php b/phpBB/includes/acp/acp_reasons.php
index 569bb73ab0..3f61a76d3a 100644
--- a/phpBB/includes/acp/acp_reasons.php
+++ b/phpBB/includes/acp/acp_reasons.php
@@ -253,6 +253,7 @@ class acp_reasons
case 'oracle':
case 'firebird':
case 'sqlite':
+ case 'sqlite3':
// Change the reports using this reason to 'other'
$sql = 'UPDATE ' . REPORTS_TABLE . '
SET reason_id = ' . $other_reason_id . ", report_text = '" . $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 a720334ed2..de8f1b48c6 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -657,6 +657,7 @@ class acp_users
{
if ($topic_id_ary[$row['topic_id']][ITEM_APPROVED] == $row['topic_posts_approved']
&& $topic_id_ary[$row['topic_id']][ITEM_UNAPPROVED] == $row['topic_posts_unapproved']
+ && $topic_id_ary[$row['topic_id']][ITEM_REAPPROVE] == $row['topic_posts_unapproved']
&& $topic_id_ary[$row['topic_id']][ITEM_DELETED] == $row['topic_posts_softdeleted'])
{
$move_topic_ary[] = $row['topic_id'];
@@ -735,7 +736,6 @@ class acp_users
sync('forum', 'forum_id', $forum_id_ary, false, true);
}
-
add_log('admin', 'LOG_USER_MOVE_POSTS', $user_row['username'], $forum_info['forum_name']);
add_log('user', $user_id, 'LOG_USER_MOVE_POSTS_USER', $forum_info['forum_name']);
@@ -772,7 +772,7 @@ class acp_users
* @event core.acp_users_overview_run_quicktool
* @var array user_row Current user data
* @var string action Quick tool that should be run
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('action', 'user_row');
extract($phpbb_dispatcher->trigger_event('core.acp_users_overview_run_quicktool', compact($vars)));
@@ -893,7 +893,7 @@ class acp_users
* @var array user_row Current user data
* @var array data Submitted user data
* @var array sql_ary User data we udpate
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('user_row', 'data', 'sql_ary');
extract($phpbb_dispatcher->trigger_event('core.acp_users_overview_modify_data', compact($vars)));
@@ -1008,7 +1008,7 @@ class acp_users
* @event core.acp_users_display_overview
* @var array user_row Array with user data
* @var array quick_tool_ary Ouick tool options
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('user_row', 'quick_tool_ary');
extract($phpbb_dispatcher->trigger_event('core.acp_users_display_overview', compact($vars)));
@@ -1050,7 +1050,7 @@ class acp_users
$sql = 'SELECT COUNT(post_id) as posts_in_queue
FROM ' . POSTS_TABLE . '
WHERE poster_id = ' . $user_id . '
- AND post_visibility = ' . ITEM_UNAPPROVED;
+ AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE));
$result = $db->sql_query($sql);
$user_row['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue');
$db->sql_freeresult($result);
@@ -1329,7 +1329,6 @@ class acp_users
}
}
-
$template->assign_block_vars('warn', array(
'ID' => $row['warning_id'],
'USERNAME' => ($row['log_operation']) ? get_username_string('full', $row['mod_user_id'], $row['mod_username'], $row['mod_user_colour']) : '-',
@@ -1379,7 +1378,6 @@ class acp_users
$data['bday_year'] = request_var('bday_year', $data['bday_year']);
$data['user_birthday'] = sprintf('%2d-%2d-%4d', $data['bday_day'], $data['bday_month'], $data['bday_year']);
-
if ($submit)
{
$error = validate_data($data, array(
@@ -1503,6 +1501,17 @@ class acp_users
'notify' => request_var('notify', $user_row['user_notify']),
);
+ /**
+ * Modify users preferences data
+ *
+ * @event core.acp_users_prefs_modify_data
+ * @var array data Array with users preferences data
+ * @var array user_row Array with user data
+ * @since 3.1.0-b3
+ */
+ $vars = array('data', 'user_row');
+ extract($phpbb_dispatcher->trigger_event('core.acp_users_prefs_modify_data', compact($vars)));
+
if ($submit)
{
$error = validate_data($data, array(
@@ -1559,37 +1568,53 @@ class acp_users
'user_notify' => $data['notify'],
);
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
- WHERE user_id = $user_id";
- $db->sql_query($sql);
+ /**
+ * Modify SQL query before users preferences are updated
+ *
+ * @event core.acp_users_prefs_modify_sql
+ * @var array data Array with users preferences data
+ * @var array user_row Array with user data
+ * @var array sql_ary SQL array with users preferences data to update
+ * @var array error Array with errors data
+ * @since 3.1.0-b3
+ */
+ $vars = array('data', 'user_row', 'sql_ary', 'error');
+ extract($phpbb_dispatcher->trigger_event('core.acp_users_prefs_modify_sql', compact($vars)));
- // Check if user has an active session
- if ($user_row['session_id'])
+ if (!sizeof($error))
{
- // We'll update the session if user_allow_viewonline has changed and the user is a bot
- // Or if it's a regular user and the admin set it to hide the session
- if ($user_row['user_allow_viewonline'] != $sql_ary['user_allow_viewonline'] && $user_row['user_type'] == USER_IGNORE
- || $user_row['user_allow_viewonline'] && !$sql_ary['user_allow_viewonline'])
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
+ WHERE user_id = $user_id";
+ $db->sql_query($sql);
+
+ // Check if user has an active session
+ if ($user_row['session_id'])
{
- // We also need to check if the user has the permission to cloak.
- $user_auth = new \phpbb\auth\auth();
- $user_auth->acl($user_row);
+ // We'll update the session if user_allow_viewonline has changed and the user is a bot
+ // Or if it's a regular user and the admin set it to hide the session
+ if ($user_row['user_allow_viewonline'] != $sql_ary['user_allow_viewonline'] && $user_row['user_type'] == USER_IGNORE
+ || $user_row['user_allow_viewonline'] && !$sql_ary['user_allow_viewonline'])
+ {
+ // We also need to check if the user has the permission to cloak.
+ $user_auth = new \phpbb\auth\auth();
+ $user_auth->acl($user_row);
- $session_sql_ary = array(
- 'session_viewonline' => ($user_auth->acl_get('u_hideonline')) ? $sql_ary['user_allow_viewonline'] : true,
- );
+ $session_sql_ary = array(
+ 'session_viewonline' => ($user_auth->acl_get('u_hideonline')) ? $sql_ary['user_allow_viewonline'] : true,
+ );
- $sql = 'UPDATE ' . SESSIONS_TABLE . '
- SET ' . $db->sql_build_array('UPDATE', $session_sql_ary) . "
- WHERE session_user_id = $user_id";
- $db->sql_query($sql);
+ $sql = 'UPDATE ' . SESSIONS_TABLE . '
+ SET ' . $db->sql_build_array('UPDATE', $session_sql_ary) . "
+ WHERE session_user_id = $user_id";
+ $db->sql_query($sql);
- unset($user_auth);
+ unset($user_auth);
+ }
}
- }
- trigger_error($user->lang['USER_PREFS_UPDATED'] . adm_back_link($this->u_action . '&amp;u=' . $user_id));
+ trigger_error($user->lang['USER_PREFS_UPDATED'] . adm_back_link($this->u_action . '&amp;u=' . $user_id));
+ }
}
// Replace "error" strings with their real, localised form
@@ -1653,7 +1678,7 @@ class acp_users
}
$timezone_selects = phpbb_timezone_select($user, $data['tz'], true);
- $template->assign_vars(array(
+ $user_prefs_data = array(
'S_PREFS' => true,
'S_JABBER_DISABLED' => ($config['jab_enable'] && $user_row['user_jabber'] && @extension_loaded('xml')) ? false : true,
@@ -1693,9 +1718,22 @@ class acp_users
'S_STYLE_OPTIONS' => style_select($data['style']),
'S_TZ_OPTIONS' => $timezone_selects['tz_select'],
'S_TZ_DATE_OPTIONS' => $timezone_selects['tz_dates'],
- )
);
+ /**
+ * Modify users preferences data before assigning it to the template
+ *
+ * @event core.acp_users_prefs_modify_template_data
+ * @var array data Array with users preferences data
+ * @var array user_row Array with user data
+ * @var array user_prefs_data Array with users preferences data to be assigned to the template
+ * @since 3.1.0-b3
+ */
+ $vars = array('data', 'user_row', 'user_prefs_data');
+ extract($phpbb_dispatcher->trigger_event('core.acp_users_prefs_modify_template_data', compact($vars)));
+
+ $template->assign_vars($user_prefs_data);
+
break;
case 'avatar':
@@ -2243,7 +2281,6 @@ class acp_users
$error = array();
}
-
$sql = 'SELECT ug.*, g.*
FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . " ug
WHERE ug.user_id = $user_id
diff --git a/phpBB/includes/acp/acp_words.php b/phpBB/includes/acp/acp_words.php
index d8d14ba4ad..859b586302 100644
--- a/phpBB/includes/acp/acp_words.php
+++ b/phpBB/includes/acp/acp_words.php
@@ -101,7 +101,7 @@ class acp_words
'word' => $word,
'replacement' => $replacement
);
-
+
if ($word_id)
{
$db->sql_query('UPDATE ' . WORDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE word_id = ' . $word_id);
@@ -162,7 +162,6 @@ class acp_words
break;
}
-
$template->assign_vars(array(
'U_ACTION' => $this->u_action,
'S_HIDDEN_FIELDS' => $s_hidden_fields)
diff --git a/phpBB/includes/acp/auth.php b/phpBB/includes/acp/auth.php
index 5404efded3..c95dd1d153 100644
--- a/phpBB/includes/acp/auth.php
+++ b/phpBB/includes/acp/auth.php
@@ -139,7 +139,6 @@ class auth_admin extends \phpbb\auth\auth
$auth2 = &$auth;
}
-
$hold_ary[$userdata['user_id']] = array();
foreach ($forum_ids as $f_id)
{
diff --git a/phpBB/includes/captcha/captcha_gd.php b/phpBB/includes/captcha/captcha_gd.php
index 3a82457c4a..e7c01c040a 100644
--- a/phpBB/includes/captcha/captcha_gd.php
+++ b/phpBB/includes/captcha/captcha_gd.php
@@ -32,7 +32,7 @@ class captcha
function execute($code, $seed)
{
global $config;
-
+
mt_srand($seed);
// Create image
@@ -160,13 +160,13 @@ class captcha
function wave($img)
{
global $config;
-
+
$period_x = mt_rand(12,18);
$period_y = mt_rand(7,14);
$amp_x = mt_rand(5,10);
- $amp_y = mt_rand(2,4);
+ $amp_y = mt_rand(2,4);
$socket = mt_rand(0,100);
-
+
$dampen_x = mt_rand($this->width/5, $this->width/2);
$dampen_y = mt_rand($this->height/5, $this->height/2);
$direction_x = (mt_rand (0, 1));
@@ -185,7 +185,7 @@ class captcha
}
return $img;
}
-
+
/**
* Noise line
*/
@@ -236,7 +236,7 @@ class captcha
}
function captcha_noise_bg_bitmaps()
- {
+ {
return array(
'width' => 15,
'height' => 5,
@@ -300,7 +300,7 @@ class captcha
function captcha_bitmaps()
{
global $config;
-
+
$chars = array(
'A' => array(
array(
@@ -1681,7 +1681,7 @@ class captcha
'J' => $chars['J'][mt_rand(0, min(sizeof($chars['J']), $config['captcha_gd_fonts']) -1)],
'K' => $chars['K'][mt_rand(0, min(sizeof($chars['K']), $config['captcha_gd_fonts']) -1)],
'L' => $chars['L'][mt_rand(0, min(sizeof($chars['L']), $config['captcha_gd_fonts']) -1)],
- 'M' => $chars['M'][mt_rand(0, min(sizeof($chars['M']), $config['captcha_gd_fonts']) -1)],
+ 'M' => $chars['M'][mt_rand(0, min(sizeof($chars['M']), $config['captcha_gd_fonts']) -1)],
'N' => $chars['N'][mt_rand(0, min(sizeof($chars['N']), $config['captcha_gd_fonts']) -1)],
'O' => $chars['O'][mt_rand(0, min(sizeof($chars['O']), $config['captcha_gd_fonts']) -1)],
'P' => $chars['P'][mt_rand(0, min(sizeof($chars['P']), $config['captcha_gd_fonts']) -1)],
@@ -2196,7 +2196,7 @@ class colour_manager
{
$mode = $this->mode;
}
-
+
if (!is_array($colour))
{
if (isset($this->named_rgb[$colour]))
@@ -2352,7 +2352,6 @@ class colour_manager
$colour3[0] += 180;
$colour4[0] += 210;
-
$results[] = $this->allocate($colour2, $mode);
$results[] = $this->allocate($colour3, $mode);
$results[] = $this->allocate($colour4, $mode);
@@ -2390,7 +2389,7 @@ class colour_manager
}
// This is a hard problem. I chicken out and try to maintain readability at the cost of less randomness.
-
+
while ($count > 0)
{
$colour[1] = ($colour[1] + mt_rand(40,60)) % 99;
diff --git a/phpBB/includes/compatibility_globals.php b/phpBB/includes/compatibility_globals.php
new file mode 100644
index 0000000000..fa468ed96a
--- /dev/null
+++ b/phpBB/includes/compatibility_globals.php
@@ -0,0 +1,44 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+// set up caching
+$cache = $phpbb_container->get('cache');
+
+// Instantiate some basic classes
+$phpbb_dispatcher = $phpbb_container->get('dispatcher');
+$request = $phpbb_container->get('request');
+$user = $phpbb_container->get('user');
+$auth = $phpbb_container->get('auth');
+$db = $phpbb_container->get('dbal.conn');
+
+// make sure request_var uses this request instance
+request_var('', 0, false, false, $request); // "dependency injection" for a function
+
+// Grab global variables, re-cache if necessary
+$config = $phpbb_container->get('config');
+set_config(null, null, null, $config);
+set_config_count(null, null, null, $config);
+
+$phpbb_log = $phpbb_container->get('log');
+$symfony_request = $phpbb_container->get('symfony_request');
+$phpbb_filesystem = $phpbb_container->get('filesystem');
+$phpbb_path_helper = $phpbb_container->get('path_helper');
+
+// load extensions
+$phpbb_extension_manager = $phpbb_container->get('ext.manager');
+$phpbb_subscriber_loader = $phpbb_container->get('event.subscriber_loader');
+
+$template = $phpbb_container->get('template');
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index 11bbcd4154..77cb499533 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -24,7 +24,7 @@ if (!defined('IN_PHPBB'))
*/
// phpBB Version
-define('PHPBB_VERSION', '3.1.0-b3-dev');
+define('PHPBB_VERSION', '3.1.0-b4-dev');
// QA-related
// define('PHPBB_QA', 1);
@@ -46,10 +46,10 @@ define('USER_INACTIVE', 1);
define('USER_IGNORE', 2);
define('USER_FOUNDER', 3);
-define('INACTIVE_REGISTER', 1);
-define('INACTIVE_PROFILE', 2);
-define('INACTIVE_MANUAL', 3);
-define('INACTIVE_REMIND', 4);
+define('INACTIVE_REGISTER', 1); // Newly registered account
+define('INACTIVE_PROFILE', 2); // Profile details changed
+define('INACTIVE_MANUAL', 3); // Account deactivated by administrator
+define('INACTIVE_REMIND', 4); // Forced user account reactivation
// ACL
define('ACL_NEVER', 0);
@@ -91,6 +91,7 @@ define('ITEM_MOVED', 2);
define('ITEM_UNAPPROVED', 0); // => has not yet been approved
define('ITEM_APPROVED', 1); // => has been approved, and has not been soft deleted
define('ITEM_DELETED', 2); // => has been soft deleted
+define('ITEM_REAPPROVE', 3); // => has been edited and needs to be re-approved
// Forum Flags
define('FORUM_FLAG_LINK_TRACK', 1);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 0d14f5ae67..a0e2a46f54 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -2004,7 +2004,7 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false)
* the global one (false)
* @var bool|string append_sid_overwrite Overwrite function (string
* URL) or not (false)
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('url', 'params', 'is_amp', 'session_id', 'append_sid_overwrite');
extract($phpbb_dispatcher->trigger_event('core.append_sid', compact($vars)));
@@ -2326,8 +2326,9 @@ function reapply_sid($url)
*/
function build_url($strip_vars = false)
{
- global $config, $user, $phpEx, $phpbb_root_path;
+ global $config, $user, $phpbb_path_helper;
+ $php_ext = $phpbb_path_helper->get_php_ext();
$page = $user->page['page'];
// We need to be cautious here.
@@ -2340,71 +2341,27 @@ function build_url($strip_vars = false)
if ($url_parts === false || empty($url_parts['scheme']) || empty($url_parts['host']))
{
// Remove 'app.php/' from the page, when rewrite is enabled
- if ($config['enable_mod_rewrite'] && strpos($page, 'app.' . $phpEx . '/') === 0)
+ if ($config['enable_mod_rewrite'] && strpos($page, 'app.' . $php_ext . '/') === 0)
{
- $page = substr($page, strlen('app.' . $phpEx . '/'));
+ $page = substr($page, strlen('app.' . $php_ext . '/'));
}
- $page = $phpbb_root_path . $page;
+ $page = $phpbb_path_helper->get_phpbb_root_path() . $page;
}
// Append SID
$redirect = append_sid($page, false, false);
- // Add delimiter if not there...
- if (strpos($redirect, '?') === false)
+ if ($strip_vars !== false)
{
- $redirect .= '?';
+ $redirect = $phpbb_path_helper->strip_url_params($redirect, $strip_vars, false);
}
-
- // Strip vars...
- if ($strip_vars !== false && strpos($redirect, '?') !== false)
+ else
{
- if (!is_array($strip_vars))
- {
- $strip_vars = array($strip_vars);
- }
-
- $query = $_query = array();
-
- $args = substr($redirect, strpos($redirect, '?') + 1);
- $args = ($args) ? explode('&', $args) : array();
- $redirect = substr($redirect, 0, strpos($redirect, '?'));
-
- foreach ($args as $argument)
- {
- $arguments = explode('=', $argument);
- $key = $arguments[0];
- unset($arguments[0]);
-
- if ($key === '')
- {
- continue;
- }
-
- $query[$key] = implode('=', $arguments);
- }
-
- // Strip the vars off
- foreach ($strip_vars as $strip)
- {
- if (isset($query[$strip]))
- {
- unset($query[$strip]);
- }
- }
-
- // Glue the remaining parts together... already urlencoded
- foreach ($query as $key => $value)
- {
- $_query[] = $key . '=' . $value;
- }
- $query = implode('&', $_query);
-
- $redirect .= ($query) ? '?' . $query : '';
+ $redirect = str_replace('&', '&amp;', $redirect);
}
- return str_replace('&', '&amp;', $redirect);
+ return $redirect . ((strpos($redirect, '?') === false) ? '?' : '');
}
/**
@@ -2694,7 +2651,6 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
WHERE user_id = " . $user->data['user_id'];
$db->sql_query($sql);
-
if ($request->is_ajax())
{
$u_action .= '&confirm_uid=' . $user->data['user_id'] . '&sess=' . $user->session_id . '&sid=' . $user->session_id;
@@ -4037,7 +3993,7 @@ function obtain_guest_count($item_id = 0, $item = 'forum')
// Get number of online guests
- if ($db->sql_layer === 'sqlite')
+ if ($db->sql_layer === 'sqlite' || $db->sql_layer === 'sqlite3')
{
$sql = 'SELECT COUNT(session_ip) as num_guests
FROM (
@@ -4727,7 +4683,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
* @var int item_id Restrict online users to item id
* @var bool page_header_override Shall we return instead of running
* the rest of page_header()
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('page_title', 'display_online_list', 'item_id', 'item', 'page_header_override');
extract($phpbb_dispatcher->trigger_event('core.page_header', compact($vars)));
@@ -4903,12 +4859,10 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
}
}
- $hidden_fields_for_jumpbox = phpbb_build_hidden_fields_for_query_params($request, array('f'));
$notification_mark_hash = generate_link_hash('mark_all_notifications_read');
// The following assigns all _common_ variables that may be used at any point in a template.
$template->assign_vars(array(
- 'CURRENT_USER_AVATAR' => phpbb_get_user_avatar($user->data),
'SITENAME' => $config['sitename'],
'SITE_DESCRIPTION' => $config['site_desc'],
'PAGE_TITLE' => $page_title,
@@ -4919,9 +4873,10 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'TOTAL_USERS_ONLINE' => $l_online_users,
'LOGGED_IN_USER_LIST' => $online_userlist,
'RECORD_USERS' => $l_online_record,
- 'PRIVATE_MESSAGE_COUNT' => (!empty($user->data['user_unread_privmsg'])) ? $user->data['user_unread_privmsg'] : 0,
- 'HIDDEN_FIELDS_FOR_JUMPBOX' => $hidden_fields_for_jumpbox,
+ 'PRIVATE_MESSAGE_COUNT' => (!empty($user->data['user_unread_privmsg'])) ? $user->data['user_unread_privmsg'] : 0,
+ 'CURRENT_USER_AVATAR' => phpbb_get_user_avatar($user->data),
+ 'CURRENT_USERNAME_FULL' => get_username_string('full', $user->data['user_id'], $user->data['username'], $user->data['user_colour']),
'UNREAD_NOTIFICATIONS_COUNT' => ($notifications !== false) ? $notifications['unread_count'] : '',
'NOTIFICATIONS_COUNT' => ($notifications !== false) ? $notifications['unread_count'] : '',
'U_VIEW_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications'),
@@ -4938,7 +4893,6 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'SESSION_ID' => $user->session_id,
'ROOT_PATH' => $web_path,
'BOARD_URL' => $board_url,
- 'USERNAME_FULL' => get_username_string('full', $user->data['user_id'], $user->data['username'], $user->data['user_colour']),
'L_LOGIN_LOGOUT' => $l_login_logout,
'L_INDEX' => ($config['board_index_text'] !== '') ? $config['board_index_text'] : $user->lang['FORUM_INDEX'],
@@ -5092,7 +5046,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler =
* @var bool run_cron Shall we run cron tasks
* @var bool page_footer_override Shall we return instead of running
* the rest of page_footer()
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('run_cron', 'page_footer_override');
extract($phpbb_dispatcher->trigger_event('core.page_footer', compact($vars)));
@@ -5200,7 +5154,7 @@ function garbage_collection()
* Unload some objects, to free some memory, before we finish our task
*
* @event core.garbage_collection
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$phpbb_dispatcher->dispatch('core.garbage_collection');
}
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index cb44ed2794..2c66f6009c 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -41,7 +41,7 @@ function adm_page_header($page_title)
* @var string page_title Page title
* @var bool adm_page_header_override Shall we return instead of
* running the rest of adm_page_header()
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('page_title', 'adm_page_header_override');
extract($phpbb_dispatcher->trigger_event('core.adm_page_header', compact($vars)));
@@ -132,7 +132,7 @@ function adm_page_footer($copyright_html = true)
* @var bool copyright_html Shall we display the copyright?
* @var bool adm_page_footer_override Shall we return instead of
* running the rest of adm_page_footer()
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('copyright_html', 'adm_page_footer_override');
extract($phpbb_dispatcher->trigger_event('core.adm_page_footer', compact($vars)));
@@ -396,7 +396,7 @@ function build_cfg_template($tpl_type, $key, &$new, $config_key, $vars)
* @var string name Should be used for the name attribute
* @var array vars Array with the options for the config
* @var string tpl The resulting html code we display
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('tpl_type', 'key', 'new', 'name', 'vars', 'tpl');
extract($phpbb_dispatcher->trigger_event('core.build_config_template', compact($vars)));
@@ -606,7 +606,7 @@ function validate_config_vars($config_vars, &$cfg_array, &$error)
* @var array error Array of errors, the errors should
* be strings only, language keys are
* not replaced afterwards
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('cfg_array', 'config_name', 'config_definition', 'error');
extract($phpbb_dispatcher->trigger_event('core.validate_config_variable', compact($vars)));
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index a343da7a7c..db430c6940 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -736,8 +736,6 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
// Notifications types to delete
$delete_notifications_types = array(
'quote',
- 'bookmark',
- 'post',
'approve_post',
'post_in_queue',
);
@@ -746,7 +744,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
* Perform additional actions before post(s) deletion
*
* @event core.delete_posts_before
- * @var string where_type Variable containing posts deletion mode
+ * @var string where_type Variable containing posts deletion mode
* @var mixed where_ids Array or comma separated list of posts ids to delete
* @var bool auto_sync Flag indicating if topics/forums should be synchronized
* @var bool posted_sync Flag indicating if topics_posted table should be resynchronized
@@ -755,7 +753,15 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
* @var array delete_notifications_types Array with notifications types to delete
* @since 3.1.0-a4
*/
- $vars = array('where_type', 'where_ids', 'auto_sync', 'posted_sync', 'post_count_sync', 'call_delete_topics', 'delete_notifications_types');
+ $vars = array(
+ 'where_type',
+ 'where_ids',
+ 'auto_sync',
+ 'posted_sync',
+ 'post_count_sync',
+ 'call_delete_topics',
+ 'delete_notifications_types',
+ );
extract($phpbb_dispatcher->trigger_event('core.delete_posts_before', compact($vars)));
if ($where_type === 'range')
@@ -907,12 +913,20 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
* @var array poster_ids Array with deleted posts' author ids
* @var array topic_ids Array with deleted posts' topic ids
* @var array forum_ids Array with deleted posts' forum ids
- * @var string where_type Variable containing posts deletion mode
+ * @var string where_type Variable containing posts deletion mode
* @var mixed where_ids Array or comma separated list of posts ids to delete
* @var array delete_notifications_types Array with notifications types to delete
* @since 3.1.0-a4
*/
- $vars = array('post_ids', 'poster_ids', 'topic_ids', 'forum_ids', 'where_type', 'where_ids', 'delete_notifications_types');
+ $vars = array(
+ 'post_ids',
+ 'poster_ids',
+ 'topic_ids',
+ 'forum_ids',
+ 'where_type',
+ 'where_ids',
+ 'delete_notifications_types',
+ );
extract($phpbb_dispatcher->trigger_event('core.delete_posts_in_transaction', compact($vars)));
$db->sql_transaction('commit');
@@ -925,12 +939,20 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
* @var array poster_ids Array with deleted posts' author ids
* @var array topic_ids Array with deleted posts' topic ids
* @var array forum_ids Array with deleted posts' forum ids
- * @var string where_type Variable containing posts deletion mode
+ * @var string where_type Variable containing posts deletion mode
* @var mixed where_ids Array or comma separated list of posts ids to delete
* @var array delete_notifications_types Array with notifications types to delete
* @since 3.1.0-a4
*/
- $vars = array('post_ids', 'poster_ids', 'topic_ids', 'forum_ids', 'where_type', 'where_ids', 'delete_notifications_types');
+ $vars = array(
+ 'post_ids',
+ 'poster_ids',
+ 'topic_ids',
+ 'forum_ids',
+ 'where_type',
+ 'where_ids',
+ 'delete_notifications_types',
+ );
extract($phpbb_dispatcher->trigger_event('core.delete_posts_after', compact($vars)));
// Resync topics_posted table
@@ -1489,7 +1511,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false,
ITEM_DELETED => (!empty($topics_softdeleted)) ? ' WHERE ' . $db->sql_in_set('topic_id', $topics_softdeleted) : '',
);
- foreach ($topic_visiblities as $visibility => $sql_where)
+ foreach ($update_ary as $visibility => $sql_where)
{
if ($sql_where)
{
@@ -1778,7 +1800,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false,
{
$forum_data[$forum_id]['topics_approved'] = $row['total_topics'];
}
- else if ($row['topic_visibility'] == ITEM_UNAPPROVED)
+ else if ($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE)
{
$forum_data[$forum_id]['topics_unapproved'] = $row['total_topics'];
}
@@ -2001,7 +2023,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false,
{
$topic_data[$topic_id]['posts_approved'] = $row['total_posts'];
}
- else if ($row['post_visibility'] == ITEM_UNAPPROVED)
+ else if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE)
{
$topic_data[$topic_id]['posts_unapproved'] = $row['total_posts'];
}
@@ -2023,7 +2045,7 @@ function sync($mode, $where_type = '', $where_ids = '', $resync_parents = false,
$topic_data[$topic_id]['first_post_id'] = (!empty($topic_data[$topic_id]['first_post_id'])) ? min($topic_data[$topic_id]['first_post_id'], $row['first_post_id']) : $row['first_post_id'];
$topic_data[$topic_id]['last_post_id'] = max($topic_data[$topic_id]['last_post_id'], $row['last_post_id']);
- if ($topic_data[$topic_id]['visibility'] == ITEM_UNAPPROVED)
+ if ($topic_data[$topic_id]['visibility'] == ITEM_UNAPPROVED || $topic_data[$topic_id]['visibility'] == ITEM_REAPPROVE)
{
// Soft delete status is stronger than unapproved.
$topic_data[$topic_id]['visibility'] = $row['post_visibility'];
@@ -2418,6 +2440,7 @@ function phpbb_cache_moderators($db, $cache, $auth)
switch ($db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
case 'firebird':
$db->sql_query('DELETE FROM ' . MODERATOR_CACHE_TABLE);
break;
@@ -2885,6 +2908,7 @@ function get_database_size()
break;
case 'sqlite':
+ case 'sqlite3':
global $dbhost;
if (file_exists($dbhost))
@@ -2901,7 +2925,7 @@ function get_database_size()
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
-
+
$sql = 'SELECT ((SUM(size) * 8.0) * 1024.0) as dbsize
FROM sysfiles';
@@ -2910,7 +2934,7 @@ function get_database_size()
// Azure stats are stored elsewhere
if (strpos($row['mssql_version'], 'SQL Azure') !== false)
{
- $sql = 'SELECT ((SUM(reserved_page_count) * 8.0) * 1024.0) as dbsize
+ $sql = 'SELECT ((SUM(reserved_page_count) * 8.0) * 1024.0) as dbsize
FROM sys.dm_db_partition_stats';
}
}
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index b1f69c5756..d56f02dd09 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -110,7 +110,7 @@ function gen_sort_selects(&$limit_days, &$sort_by_text, &$sort_days, &$sort_key,
*/
function make_jumpbox($action, $forum_id = false, $select_all = false, $acl_list = false, $force_display = false)
{
- global $config, $auth, $template, $user, $db;
+ global $config, $auth, $template, $user, $db, $phpbb_path_helper;
// We only return if the jumpbox is not forced to be displayed (in case it is needed for functionality)
if (!$config['load_jumpbox'] && $force_display === false)
@@ -196,10 +196,13 @@ function make_jumpbox($action, $forum_id = false, $select_all = false, $acl_list
$db->sql_freeresult($result);
unset($padding_store);
+ $url_parts = $phpbb_path_helper->get_url_parts($action);
+
$template->assign_vars(array(
- 'S_DISPLAY_JUMPBOX' => $display_jumpbox,
- 'S_JUMPBOX_ACTION' => $action)
- );
+ 'S_DISPLAY_JUMPBOX' => $display_jumpbox,
+ 'S_JUMPBOX_ACTION' => $action,
+ 'HIDDEN_FIELDS_FOR_JUMPBOX' => build_hidden_fields($url_parts['params']),
+ ));
return;
}
@@ -445,13 +448,13 @@ function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text
* @var string bitfield The BBCode Bitfield
* @var int flags The BBCode Flags
* @var bool censor_text Whether or not to apply word censors
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('text', 'uid', 'bitfield', 'flags', 'censor_text');
extract($phpbb_dispatcher->trigger_event('core.modify_text_for_display_before', compact($vars)));
if ($censor_text)
- {
+ {
$text = censor_text($text);
}
@@ -487,7 +490,7 @@ function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text
* @var string uid The BBCode UID
* @var string bitfield The BBCode Bitfield
* @var int flags The BBCode Flags
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('text', 'uid', 'bitfield', 'flags');
extract($phpbb_dispatcher->trigger_event('core.modify_text_for_display_after', compact($vars)));
@@ -499,7 +502,7 @@ function generate_text_for_display($text, $uid, $bitfield, $flags, $censor_text
* For parsing custom parsed text to be stored within the database.
* This function additionally returns the uid and bitfield that needs to be stored.
* Expects $text to be the value directly from request_var() and in it's non-parsed form
-*
+*
* @param string $text The text to be replaced with the parsed one
* @param string $uid The BBCode uid for this parse
* @param string $bitfield The BBCode bitfield for this parse
@@ -525,9 +528,17 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb
* @var bool allow_bbcode Whether or not to parse BBCode
* @var bool allow_urls Whether or not to parse URLs
* @var bool allow_smilies Whether or not to parse Smilies
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
- $vars = array('text', 'uid', 'bitfield', 'flags', 'allow_bbcode', 'allow_urls', 'allow_smilies');
+ $vars = array(
+ 'text',
+ 'uid',
+ 'bitfield',
+ 'flags',
+ 'allow_bbcode',
+ 'allow_urls',
+ 'allow_smilies',
+ );
extract($phpbb_dispatcher->trigger_event('core.modify_text_for_storage_before', compact($vars)));
$uid = $bitfield = '';
@@ -565,7 +576,7 @@ function generate_text_for_storage(&$text, &$uid, &$bitfield, &$flags, $allow_bb
* @var string uid The BBCode UID
* @var string bitfield The BBCode Bitfield
* @var int flags The BBCode Flags
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('text', 'uid', 'bitfield', 'flags');
extract($phpbb_dispatcher->trigger_event('core.modify_text_for_storage_after', compact($vars)));
@@ -588,7 +599,7 @@ function generate_text_for_edit($text, $uid, $flags)
* @var string text The text to parse
* @var string uid The BBCode UID
* @var int flags The BBCode Flags
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('text', 'uid', 'flags');
extract($phpbb_dispatcher->trigger_event('core.modify_text_for_edit_before', compact($vars)));
@@ -601,7 +612,7 @@ function generate_text_for_edit($text, $uid, $flags)
* @event core.modify_text_for_edit_after
* @var string text The text to parse
* @var int flags The BBCode Flags
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('text', 'flags');
extract($phpbb_dispatcher->trigger_event('core.modify_text_for_edit_after', compact($vars)));
@@ -1392,7 +1403,7 @@ function get_username_string($mode, $user_id, $username, $username_colour = '',
{
$username_string = str_replace(array('{PROFILE_URL}', '{USERNAME_COLOUR}', '{USERNAME}'), array($profile_url, $username_colour, $username), (!$username_colour) ? $_profile_cache['tpl_profile'] : $_profile_cache['tpl_profile_colour']);
}
-
+
/**
* Use this event to change the output of get_username_string()
*
@@ -1408,9 +1419,18 @@ function get_username_string($mode, $user_id, $username, $username_colour = '',
* profile url.
* @var string username_string The string that has been generated
* @var array _profile_cache Array of original return templates
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
- $vars = array('mode', 'user_id', 'username', 'username_colour', 'guest_username', 'custom_profile_url', 'username_string', '_profile_cache');
+ $vars = array(
+ 'mode',
+ 'user_id',
+ 'username',
+ 'username_colour',
+ 'guest_username',
+ 'custom_profile_url',
+ 'username_string',
+ '_profile_cache',
+ );
extract($phpbb_dispatcher->trigger_event('core.modify_username_string', compact($vars)));
return $username_string;
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index 1646c79161..dbc66446b3 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -1650,6 +1650,7 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO)
case 'mssql':
case 'sqlite':
+ case 'sqlite3':
case 'mssqlnative':
$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
break;
@@ -2037,6 +2038,7 @@ function update_topics_posted()
switch ($db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
case 'firebird':
$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
break;
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index 2b11d00f1e..353f0be04b 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -138,7 +138,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
*
* @event core.display_forums_modify_sql
* @var array sql_ary The SQL array to get the data of the forums
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('sql_ary');
extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_sql', compact($vars)));
@@ -161,7 +161,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
* @event core.display_forums_modify_row
* @var int branch_root_id Last top-level forum
* @var array row The data of the forum
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('branch_root_id', 'row');
extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_row', compact($vars)));
@@ -318,7 +318,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
* @var int branch_root_id Current top-level forum
* @var int parent_id Current parent forum
* @var array row The data of the forum
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('forum_rows', 'subforums', 'branch_root_id', 'parent_id', 'row');
extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_forum_rows', compact($vars)));
@@ -568,7 +568,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
* @event core.display_forums_modify_template_vars
* @var array forum_row Template data of the forum
* @var array row The data of the forum
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('forum_row', 'row');
extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_template_vars', compact($vars)));
@@ -900,7 +900,6 @@ function topic_status(&$topic_row, $replies, $unread_topic, &$folder_img, &$fold
$folder_new .= '_locked';
}
-
$folder_img = ($unread_topic) ? $folder_new : $folder;
$folder_alt = ($unread_topic) ? 'UNREAD_POSTS' : (($topic_row['topic_status'] == ITEM_LOCKED) ? 'TOPIC_LOCKED' : 'NO_UNREAD_POSTS');
@@ -975,7 +974,7 @@ function display_custom_bbcodes()
* @event core.display_custom_bbcodes_modify_row
* @var array custom_tags Template data of the bbcode
* @var array row The data of the bbcode
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('custom_tags', 'row');
extract($phpbb_dispatcher->trigger_event('core.display_custom_bbcodes_modify_row', compact($vars)));
@@ -990,7 +989,7 @@ function display_custom_bbcodes()
* Display custom bbcodes
*
* @event core.display_custom_bbcodes
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$phpbb_dispatcher->dispatch('core.display_custom_bbcodes');
}
diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php
index 4f8ec99d88..f484461b77 100644
--- a/phpBB/includes/functions_install.php
+++ b/phpBB/includes/functions_install.php
@@ -106,6 +106,15 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'AVAILABLE' => true,
'2.0.x' => false,
),
+ 'sqlite3' => array(
+ 'LABEL' => 'SQLite3',
+ 'SCHEMA' => 'sqlite',
+ 'MODULE' => 'sqlite3',
+ 'DELIM' => ';',
+ 'DRIVER' => 'phpbb\db\driver\sqlite3',
+ 'AVAILABLE' => true,
+ '2.0.x' => false,
+ ),
);
if ($dbms)
@@ -206,14 +215,14 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
$db->sql_return_on_error(true);
// Check that we actually have a database name before going any further.....
- if ($dbms_details['DRIVER'] != 'phpbb\db\driver\sqlite' && $dbms_details['DRIVER'] != 'phpbb\db\driver\oracle' && $dbname === '')
+ if ($dbms_details['DRIVER'] != 'phpbb\db\driver\sqlite' && $dbms_details['DRIVER'] != 'phpbb\db\driver\sqlite3' && $dbms_details['DRIVER'] != 'phpbb\db\driver\oracle' && $dbname === '')
{
$error[] = $lang['INST_ERR_DB_NO_NAME'];
return false;
}
// Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea
- if ($dbms_details['DRIVER'] == 'phpbb\db\driver\sqlite' && stripos(phpbb_realpath($dbhost), phpbb_realpath('../')) === 0)
+ if (($dbms_details['DRIVER'] == 'phpbb\db\driver\sqlite' || $dbms_details['DRIVER'] == 'phpbb\db\driver\sqlite3') && stripos(phpbb_realpath($dbhost), phpbb_realpath('../')) === 0)
{
$error[] = $lang['INST_ERR_DB_FORUM_PATH'];
return false;
@@ -243,6 +252,7 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
break;
case 'phpbb\db\driver\sqlite':
+ case 'phpbb\db\driver\sqlite3':
$prefix_length = 200;
break;
@@ -299,6 +309,14 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
}
break;
+ case 'phpbb\db\driver\sqlite3':
+ $version = \SQLite3::version();
+ if (version_compare($version['versionString'], '3.6.15', '<'))
+ {
+ $error[] = $lang['INST_ERR_DB_NO_SQLITE3'];
+ }
+ break;
+
case 'phpbb\db\driver\firebird':
// check the version of FB, use some hackery if we can't get access to the server info
if ($db->service_handle !== false && function_exists('ibase_server_info'))
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index 907252f6d8..79a5aeda1a 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -484,14 +484,17 @@ class messenger
$use_queue = true;
}
+ $contact_name = htmlspecialchars_decode($config['board_contact_name']);
+ $board_contact = (($contact_name !== '') ? '"' . mail_encode($contact_name) . '" ' : '') . '<' . $config['board_contact'] . '>';
+
if (empty($this->replyto))
{
- $this->replyto = '<' . $config['board_contact'] . '>';
+ $this->replyto = $board_contact;
}
if (empty($this->from))
{
- $this->from = '<' . $config['board_contact'] . '>';
+ $this->from = $board_contact;
}
$encode_eol = ($config['smtp_delivery']) ? "\r\n" : $this->eol;
diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php
index 98b2848c19..04efcb7b2e 100644
--- a/phpBB/includes/functions_module.php
+++ b/phpBB/includes/functions_module.php
@@ -410,7 +410,7 @@ class p_master
* @var string module_auth The module_auth of the current
* module
* @var int forum_id The current forum_id
- * @since 3.1-A3
+ * @since 3.1.0-a3
*/
$vars = array('valid_tokens', 'module_auth', 'forum_id');
extract($phpbb_dispatcher->trigger_event('core.module_auth', compact($vars)));
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 51bbcb8bae..cc46799252 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -21,7 +21,7 @@ if (!defined('IN_PHPBB'))
function generate_smilies($mode, $forum_id)
{
global $db, $user, $config, $template, $phpbb_dispatcher;
- global $phpEx, $phpbb_root_path, $phpbb_container;
+ global $phpEx, $phpbb_root_path, $phpbb_container, $phpbb_path_helper;
$base_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&amp;f=' . $forum_id);
$pagination = $phpbb_container->get('pagination');
@@ -111,7 +111,7 @@ function generate_smilies($mode, $forum_id)
if (sizeof($smilies))
{
- $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_root_path;
+ $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_path_helper->get_web_root_path();
foreach ($smilies as $row)
{
@@ -133,7 +133,7 @@ function generate_smilies($mode, $forum_id)
* @var string mode Mode of the smilies: window|inline
* @var int forum_id The forum ID we are currently in
* @var bool display_link Shall we display the "more smilies" link?
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('mode', 'forum_id', 'display_link');
extract($phpbb_dispatcher->trigger_event('core.generate_smilies_after', compact($vars)));
@@ -173,7 +173,6 @@ function update_post_information($type, $ids, $return_update_sql = false)
$ids = array($ids);
}
-
$update_sql = $empty_forums = $not_empty_forums = array();
if ($type != 'topic')
@@ -1296,7 +1295,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
{
$sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1';
}
- else if ($data['topic_visibility'] == ITEM_UNAPPROVED)
+ else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE)
{
$sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1';
}
@@ -1403,7 +1402,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data, $is_soft = false, $
{
$phpbb_content_visibility->remove_post_from_statistic($data, $sql_data);
}
- else if ($data['post_visibility'] == ITEM_UNAPPROVED)
+ else if ($data['post_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE)
{
$sql_data[FORUMS_TABLE] = (($sql_data[FORUMS_TABLE]) ? $sql_data[FORUMS_TABLE] . ', ' : '') . 'forum_posts_unapproved = forum_posts_unapproved - 1';
$sql_data[TOPICS_TABLE] = (($sql_data[TOPICS_TABLE]) ? $sql_data[TOPICS_TABLE] . ', ' : '') . 'topic_posts_unapproved = topic_posts_unapproved - 1';
@@ -1497,7 +1496,17 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
* @var bool update_search_index Flag indicating if the search index will be updated
* @since 3.1.0-a4
*/
- extract($phpbb_dispatcher->trigger_event('core.modify_submit_post_data', compact(array('mode', 'subject', 'username', 'topic_type', 'poll', 'data', 'update_message', 'update_search_index'))));
+ $vars = array(
+ 'mode',
+ 'subject',
+ 'username',
+ 'topic_type',
+ 'poll',
+ 'data',
+ 'update_message',
+ 'update_search_index',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.modify_submit_post_data', compact($vars)));
// We do not handle erasing posts here
if ($mode == 'delete')
@@ -1555,16 +1564,25 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
{
// Post not approved, but in queue
$post_visibility = ITEM_UNAPPROVED;
+ switch ($post_mode)
+ {
+ case 'edit_first_post':
+ case 'edit':
+ case 'edit_last_post':
+ case 'edit_topic':
+ $post_visibility = ITEM_REAPPROVE;
+ break;
+ }
}
// MODs/Extensions are able to force any visibility on posts
if (isset($data['force_approved_state']))
{
- $post_visibility = (in_array((int) $data['force_approved_state'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED))) ? (int) $data['force_approved_state'] : $post_visibility;
+ $post_visibility = (in_array((int) $data['force_approved_state'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED, ITEM_REAPPROVE))) ? (int) $data['force_approved_state'] : $post_visibility;
}
if (isset($data['force_visibility']))
{
- $post_visibility = (in_array((int) $data['force_visibility'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED))) ? (int) $data['force_visibility'] : $post_visibility;
+ $post_visibility = (in_array((int) $data['force_visibility'], array(ITEM_APPROVED, ITEM_UNAPPROVED, ITEM_DELETED, ITEM_REAPPROVE))) ? (int) $data['force_visibility'] : $post_visibility;
}
// Start the transaction here
@@ -2032,6 +2050,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
$first_post_has_topic_info = ($post_mode == 'edit_first_post' &&
(($post_visibility == ITEM_DELETED && $data['topic_posts_softdeleted'] == 1) ||
($post_visibility == ITEM_UNAPPROVED && $data['topic_posts_unapproved'] == 1) ||
+ ($post_visibility == ITEM_REAPPROVE && $data['topic_posts_unapproved'] == 1) ||
($post_visibility == ITEM_APPROVED && $data['topic_posts_approved'] == 1)));
// Fix the post's and topic's visibility and first/last post information, when the post is edited
if (($post_mode != 'post' && $post_mode != 'reply') && $data['post_visibility'] != $post_visibility)
@@ -2039,7 +2058,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
// If the post was not approved, it could also be the starter,
// so we sync the starter after approving/restoring, to ensure that the stats are correct
// Same applies for the last post
- $is_starter = ($post_mode == 'edit_first_post' || $data['post_visibility'] != ITEM_APPROVED);
+ $is_starter = ($post_mode == 'edit_first_post' || $post_mode == 'edit_topic' || $data['post_visibility'] != ITEM_APPROVED);
$is_latest = ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || $data['post_visibility'] != ITEM_APPROVED);
$phpbb_content_visibility = $phpbb_container->get('content.visibility');
@@ -2272,43 +2291,51 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
case 'edit_first_post':
case 'edit':
case 'edit_last_post':
- if ($data['topic_visibility'] != ITEM_APPROVED)
- {
- $phpbb_notifications->delete_notifications('topic', $data['topic_id']);
- }
-
- $phpbb_notifications->delete_notifications(array(
- 'quote',
- 'bookmark',
- 'post',
- ), $data['post_id']);
+ // Nothing to do here
break;
}
}
- else if ($post_visibility == ITEM_DELETED)
+ else if ($post_visibility == ITEM_REAPPROVE)
{
switch ($mode)
{
+ case 'edit_topic':
+ case 'edit_first_post':
+ $phpbb_notifications->add_notifications('topic_in_queue', $notification_data);
+
+ // Delete the approve_post notification so we can notify the user again,
+ // when his post got reapproved
+ $phpbb_notifications->delete_notifications('approve_post', $notification_data['post_id']);
+ break;
+
+ case 'edit':
+ case 'edit_last_post':
+ $phpbb_notifications->add_notifications('post_in_queue', $notification_data);
+
+ // Delete the approve_post notification so we can notify the user again,
+ // when his post got reapproved
+ $phpbb_notifications->delete_notifications('approve_post', $notification_data['post_id']);
+ break;
+
case 'post':
case 'reply':
case 'quote':
// Nothing to do here
break;
-
+ }
+ }
+ else if ($post_visibility == ITEM_DELETED)
+ {
+ switch ($mode)
+ {
+ case 'post':
+ case 'reply':
+ case 'quote':
case 'edit_topic':
case 'edit_first_post':
case 'edit':
case 'edit_last_post':
- if ($data['topic_visibility'] != ITEM_APPROVED)
- {
- $phpbb_notifications->delete_notifications('topic', $data['topic_id']);
- }
-
- $phpbb_notifications->delete_notifications(array(
- 'quote',
- 'bookmark',
- 'post',
- ), $data['post_id']);
+ // Nothing to do here
break;
}
}
@@ -2345,7 +2372,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
* @var string url The "Return to topic" URL
* @var array data Array of post data about the
* submitted post
- * @since 3.1-A3
+ * @since 3.1.0-a3
*/
$vars = array('url', 'data');
extract($phpbb_dispatcher->trigger_event('core.submit_post_end', compact($vars)));
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index 9b44984dfa..352e3b8c1f 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -314,7 +314,6 @@ function check_rule(&$rules, &$rule_row, &$message_row, $user_id)
break;
}
-
if (!$result)
{
return false;
@@ -1588,7 +1587,7 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
/**
* Get all parts of the PM that are to be submited to the DB.
*
- * @event core.submit_pm_before
+ * @event core.submit_pm_before
* @var string mode PM Post mode - post|reply|quote|quotepost|forward|edit
* @var string subject Subject of the private message
* @var array data The whole row data of the PM.
@@ -2030,10 +2029,10 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode
$decoded_message = bbcode_nl2br($decoded_message);
}
-
+
$parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0);
$parse_flags |= ($row['enable_smilies'] ? OPTION_FLAG_SMILIES : 0);
-
+
$message = generate_text_for_display($message, $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, false);
$subject = censor_text($subject);
diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php
index 9d61e39c98..b4e165502b 100644
--- a/phpBB/includes/functions_upload.php
+++ b/phpBB/includes/functions_upload.php
@@ -475,7 +475,7 @@ class fileerror extends filespec
class fileupload
{
var $allowed_extensions = array();
- var $disallowed_content = array('body', 'head', 'html', 'img', 'plaintext', 'a href', 'pre', 'script', 'table', 'title');
+ var $disallowed_content = array('body', 'head', 'html', 'img', 'plaintext', 'a href', 'pre', 'script', 'table', 'title');
var $max_filesize = 0;
var $min_width = 0;
var $min_height = 0;
diff --git a/phpBB/includes/functions_url_matcher.php b/phpBB/includes/functions_url_matcher.php
index 8e5ae20f93..cdbe60595c 100644
--- a/phpBB/includes/functions_url_matcher.php
+++ b/phpBB/includes/functions_url_matcher.php
@@ -22,22 +22,22 @@ if (!defined('IN_PHPBB'))
/**
* Create a new UrlMatcher class and dump it into the cache file
*
-* @param \phpbb\extension\finder $finder Extension finder
+* @param \phpbb\extension\manager $manager Extension manager
* @param RequestContext $context Symfony RequestContext object
* @param string $root_path Root path
* @param string $php_ext PHP extension
* @return null
*/
-function phpbb_get_url_matcher(\phpbb\extension\finder $finder, RequestContext $context, $root_path, $php_ext)
+function phpbb_get_url_matcher(\phpbb\extension\manager $manager, RequestContext $context, $root_path, $php_ext)
{
if (defined('DEBUG'))
{
- return phpbb_create_url_matcher($finder, $context, $root_path);
+ return phpbb_create_url_matcher($manager, $context, $root_path);
}
if (!phpbb_url_matcher_dumped($root_path, $php_ext))
{
- phpbb_create_dumped_url_matcher($finder, $root_path, $php_ext);
+ phpbb_create_dumped_url_matcher($manager, $root_path, $php_ext);
}
return phpbb_load_url_matcher($context, $root_path, $php_ext);
@@ -46,14 +46,15 @@ function phpbb_get_url_matcher(\phpbb\extension\finder $finder, RequestContext $
/**
* Create a new UrlMatcher class and dump it into the cache file
*
-* @param \phpbb\extension\finder $finder Extension finder
+* @param \phpbb\extension\manager $manager Extension manager
* @param string $root_path Root path
* @param string $php_ext PHP extension
* @return null
*/
-function phpbb_create_dumped_url_matcher(\phpbb\extension\finder $finder, $root_path, $php_ext)
+function phpbb_create_dumped_url_matcher(\phpbb\extension\manager $manager, $root_path, $php_ext)
{
- $provider = new \phpbb\controller\provider($finder);
+ $provider = new \phpbb\controller\provider();
+ $provider->find_routing_files($manager->get_finder());
$routes = $provider->find($root_path)->get_routes();
$dumper = new PhpMatcherDumper($routes);
$cached_url_matcher_dump = $dumper->dump(array(
@@ -66,13 +67,14 @@ function phpbb_create_dumped_url_matcher(\phpbb\extension\finder $finder, $root_
/**
* Create a non-cached UrlMatcher
*
-* @param \phpbb\extension\finder $finder Extension finder
+* @param \phpbb\extension\manager $manager Extension manager
* @param RequestContext $context Symfony RequestContext object
* @return UrlMatcher
*/
-function phpbb_create_url_matcher(\phpbb\extension\finder $finder, RequestContext $context, $root_path)
+function phpbb_create_url_matcher(\phpbb\extension\manager $manager, RequestContext $context, $root_path)
{
- $provider = new \phpbb\controller\provider($finder);
+ $provider = new \phpbb\controller\provider();
+ $provider->find_routing_files($manager->get_finder());
$routes = $provider->find($root_path)->get_routes();
return new UrlMatcher($routes, $context);
}
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 6682622d94..0dd1708c55 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -143,7 +143,7 @@ function user_update_name($old_name, $new_name)
* @event core.update_username
* @var string old_name The old username that is replaced
* @var string new_name The new username
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('old_name', 'new_name');
extract($phpbb_dispatcher->trigger_event('core.update_username', compact($vars)));
@@ -259,7 +259,7 @@ function user_add($user_row, $cp_data = false)
*
* @event core.user_add_modify_data
* @var array sql_ary Array of data to be inserted when a user is added
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('sql_ary');
extract($phpbb_dispatcher->trigger_event('core.user_add_modify_data', compact($vars)));
@@ -386,7 +386,7 @@ function user_delete($mode, $user_ids, $retain_username = true)
* @var array user_ids IDs of the deleted user
* @var mixed retain_username True if username should be retained
* or false if not
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('mode', 'user_ids', 'retain_username');
extract($phpbb_dispatcher->trigger_event('core.delete_user_before', compact($vars)));
@@ -615,7 +615,7 @@ function user_delete($mode, $user_ids, $retain_username = true)
* @var array user_ids IDs of the deleted user
* @var mixed retain_username True if username should be retained
* or false if not
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('mode', 'user_ids', 'retain_username');
extract($phpbb_dispatcher->trigger_event('core.delete_user_after', compact($vars)));
@@ -1326,9 +1326,18 @@ function validate_data($data, $val_ary)
{
$function = array_shift($validate);
array_unshift($validate, $data[$var]);
- $function_prefix = (function_exists('phpbb_validate_' . $function)) ? 'phpbb_validate_' : 'validate_';
- if ($result = call_user_func_array($function_prefix . $function, $validate))
+ if (is_array($function))
+ {
+ $result = call_user_func_array(array($function[0], 'validate_' . $function[1]), $validate);
+ }
+ else
+ {
+ $function_prefix = (function_exists('phpbb_validate_' . $function)) ? 'phpbb_validate_' : 'validate_';
+ $result = call_user_func_array($function_prefix . $function, $validate);
+ }
+
+ if ($result)
{
// Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted.
$error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var);
@@ -2077,7 +2086,6 @@ function get_avatar_filename($avatar_entry)
{
global $config;
-
if ($avatar_entry[0] === 'g')
{
$avatar_group = true;
@@ -2504,7 +2512,7 @@ function group_delete($group_id, $group_name = false)
* @event core.delete_group_after
* @var int group_id ID of the deleted group
* @var string group_name Name of the deleted group
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('group_id', 'group_name');
extract($phpbb_dispatcher->trigger_event('core.delete_group_after', compact($vars)));
@@ -2752,7 +2760,7 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false,
* @var string group_name Name of the group
* @var array user_id_ary IDs of the users which are removed
* @var array username_ary names of the users which are removed
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('group_id', 'group_name', 'user_id_ary', 'username_ary');
extract($phpbb_dispatcher->trigger_event('core.group_delete_user_before', compact($vars)));
@@ -3198,7 +3206,7 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal
* @var array group_attributes Group attributes which were changed
* @var array update_listing Update the list of moderators and foes
* @var array sql_ary User attributes which were changed
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('group_id', 'user_id_ary', 'group_attributes', 'update_listing', 'sql_ary');
extract($phpbb_dispatcher->trigger_event('core.user_set_default_group', compact($vars)));
@@ -3447,9 +3455,12 @@ function remove_newly_registered($user_id, $user_data = false)
*
* @param array $user_ids Array of users' ids to check for banning,
* leave empty to get complete list of banned ids
+* @param bool|int $ban_end Bool True to get users currently banned
+* Bool False to only get permanently banned users
+* Int Unix timestamp to get users banned until that time
* @return array Array of banned users' ids if any, empty array otherwise
*/
-function phpbb_get_banned_user_ids($user_ids = array())
+function phpbb_get_banned_user_ids($user_ids = array(), $ban_end = true)
{
global $db;
@@ -3461,9 +3472,26 @@ function phpbb_get_banned_user_ids($user_ids = array())
$sql = 'SELECT ban_userid
FROM ' . BANLIST_TABLE . "
WHERE $sql_user_ids
- AND ban_exclude <> 1
- AND (ban_end > " . time() . '
+ AND ban_exclude <> 1";
+
+ if ($ban_end === true)
+ {
+ // Banned currently
+ $sql .= " AND (ban_end > " . time() . '
OR ban_end = 0)';
+ }
+ else if ($ban_end === false)
+ {
+ // Permanently banned
+ $sql .= " AND ban_end = 0";
+ }
+ else
+ {
+ // Banned until a specified time
+ $sql .= " AND (ban_end > " . (int) $ban_end . '
+ OR ban_end = 0)';
+ }
+
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
diff --git a/phpBB/includes/mcp/info/mcp_pm_reports.php b/phpBB/includes/mcp/info/mcp_pm_reports.php
index 07dc564b19..d530a917cb 100644
--- a/phpBB/includes/mcp/info/mcp_pm_reports.php
+++ b/phpBB/includes/mcp/info/mcp_pm_reports.php
@@ -19,7 +19,7 @@ class mcp_pm_reports_info
'title' => 'MCP_PM_REPORTS',
'version' => '1.0.0',
'modes' => array(
- 'pm_reports' => array('title' => 'MCP_PM_REPORTS_OPEN', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')),
+ 'pm_reports' => array('title' => 'MCP_PM_REPORTS_OPEN', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')),
'pm_reports_closed' => array('title' => 'MCP_PM_REPORTS_CLOSED', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')),
'pm_report_details' => array('title' => 'MCP_PM_REPORT_DETAILS', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')),
),
diff --git a/phpBB/includes/mcp/mcp_ban.php b/phpBB/includes/mcp/mcp_ban.php
index d3bc336293..925d0878fc 100644
--- a/phpBB/includes/mcp/mcp_ban.php
+++ b/phpBB/includes/mcp/mcp_ban.php
@@ -171,7 +171,7 @@ class mcp_ban
case 'user':
$pre_fill = (string) $db->sql_fetchfield('username');
break;
-
+
case 'ip':
$pre_fill = (string) $db->sql_fetchfield('user_ip');
break;
diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php
index 7c1c61dae7..b4f7f4d70a 100644
--- a/phpBB/includes/mcp/mcp_forum.php
+++ b/phpBB/includes/mcp/mcp_forum.php
@@ -224,7 +224,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
$topic_title = censor_text($row['topic_title']);
- $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false;
+ $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false;
$posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $row['forum_id'])) ? true : false;
$topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
$u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? $url . '&amp;i=queue&amp;mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . '&amp;t=' . $row['topic_id'] : '';
@@ -302,7 +302,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
* @event core.mcp_view_forum_modify_topicrow
* @var array row Array with topic data
* @var array topic_row Template array with topic data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('row', 'topic_row');
extract($phpbb_dispatcher->trigger_event('core.mcp_view_forum_modify_topicrow', compact($vars)));
diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php
index 44cab5d910..aee43c471d 100644
--- a/phpBB/includes/mcp/mcp_front.php
+++ b/phpBB/includes/mcp/mcp_front.php
@@ -39,7 +39,7 @@ function mcp_front_view($id, $mode, $action)
$sql = 'SELECT COUNT(post_id) AS total
FROM ' . POSTS_TABLE . '
WHERE ' . $db->sql_in_set('forum_id', $forum_list) . '
- AND post_visibility = ' . ITEM_UNAPPROVED;
+ AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE));
$result = $db->sql_query($sql);
$total = (int) $db->sql_fetchfield('total');
$db->sql_freeresult($result);
@@ -60,7 +60,7 @@ function mcp_front_view($id, $mode, $action)
$sql = 'SELECT post_id
FROM ' . POSTS_TABLE . '
WHERE ' . $db->sql_in_set('forum_id', $forum_list) . '
- AND post_visibility = ' . ITEM_UNAPPROVED . '
+ AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . '
ORDER BY post_time DESC';
$result = $db->sql_query_limit($sql, 5);
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index 55440bf192..6b2e9266b3 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -493,7 +493,7 @@ function mcp_move_topic($topic_ids)
{
$topics_moved++;
}
- elseif ($topic_info['topic_visibility'] == ITEM_UNAPPROVED)
+ elseif ($topic_info['topic_visibility'] == ITEM_UNAPPROVED || $topic_info['topic_visibility'] == ITEM_REAPPROVE)
{
$topics_moved_unapproved++;
}
@@ -1230,6 +1230,7 @@ function mcp_fork_topic($topic_ids)
$total_topics++;
break;
case ITEM_UNAPPROVED:
+ case ITEM_REAPPROVE:
$total_topics_unapproved++;
break;
case ITEM_DELETED:
@@ -1316,6 +1317,7 @@ function mcp_fork_topic($topic_ids)
$total_posts++;
break;
case ITEM_UNAPPROVED:
+ case ITEM_REAPPROVE:
$total_posts_unapproved++;
break;
case ITEM_DELETED:
diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php
index 008984b1c3..b0a06dd6ce 100644
--- a/phpBB/includes/mcp/mcp_pm_reports.php
+++ b/phpBB/includes/mcp/mcp_pm_reports.php
@@ -170,7 +170,7 @@ class mcp_pm_reports
'U_MCP_USER_NOTES' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&amp;mode=user_notes&amp;u=' . $pm_info['author_id']),
'U_MCP_WARN_REPORTER' => ($auth->acl_get('m_warn')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&amp;mode=warn_user&amp;u=' . $report['user_id']) : '',
'U_MCP_WARN_USER' => ($auth->acl_get('m_warn')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&amp;mode=warn_user&amp;u=' . $pm_info['author_id']) : '',
-
+
'EDIT_IMG' => $user->img('icon_post_edit', $user->lang['EDIT_POST']),
'MINI_POST_IMG' => $user->img('icon_post_target', 'POST'),
@@ -304,7 +304,7 @@ class mcp_pm_reports
$template->assign_vars(array(
'L_EXPLAIN' => ($mode == 'pm_reports') ? $user->lang['MCP_PM_REPORTS_OPEN_EXPLAIN'] : $user->lang['MCP_PM_REPORTS_CLOSED_EXPLAIN'],
'L_TITLE' => ($mode == 'pm_reports') ? $user->lang['MCP_PM_REPORTS_OPEN'] : $user->lang['MCP_PM_REPORTS_CLOSED'],
-
+
'S_PM' => true,
'S_MCP_ACTION' => $this->u_action,
'S_CLOSED' => ($mode == 'pm_reports_closed') ? true : false,
diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php
index e2d6cd15c9..5925575577 100644
--- a/phpBB/includes/mcp/mcp_post.php
+++ b/phpBB/includes/mcp/mcp_post.php
@@ -203,7 +203,7 @@ function mcp_post_details($id, $mode, $action)
'S_CAN_DELETE_POST' => $auth->acl_get('m_delete', $post_info['forum_id']),
'S_POST_REPORTED' => ($post_info['post_reported']) ? true : false,
- 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED) ? true : false,
+ 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE) ? true : false,
'S_POST_DELETED' => ($post_info['post_visibility'] == ITEM_DELETED) ? true : false,
'S_POST_LOCKED' => ($post_info['post_edit_locked']) ? true : false,
'S_USER_NOTES' => true,
diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php
index 8d998919e5..a71bc997e9 100644
--- a/phpBB/includes/mcp/mcp_queue.php
+++ b/phpBB/includes/mcp/mcp_queue.php
@@ -115,10 +115,10 @@ class mcp_queue
if (!empty($topic_id_list))
{
- $post_visibility = ($mode == 'deleted_topics') ? ITEM_DELETED : ITEM_UNAPPROVED;
+ $post_visibility = ($mode == 'deleted_topics') ? ITEM_DELETED : array(ITEM_UNAPPROVED, ITEM_REAPPROVE);
$sql = 'SELECT post_id
FROM ' . POSTS_TABLE . '
- WHERE post_visibility = ' . $post_visibility . '
+ WHERE ' . $db->sql_in_set('post_visibility', $post_visibility) . '
AND ' . $db->sql_in_set('topic_id', $topic_id_list);
$result = $db->sql_query($sql);
@@ -281,7 +281,7 @@ class mcp_queue
'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;p=$post_id&amp;f=$forum_id"),
'S_CAN_VIEWIP' => $auth->acl_get('m_info', $post_info['forum_id']),
'S_POST_REPORTED' => $post_info['post_reported'],
- 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED),
+ 'S_POST_UNAPPROVED' => $post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE,
'S_POST_LOCKED' => $post_info['post_edit_locked'],
'S_USER_NOTES' => true,
'S_POST_DELETED' => ($post_info['post_visibility'] == ITEM_DELETED),
@@ -298,7 +298,6 @@ class mcp_queue
'MINI_POST_IMG' => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'),
-
'RETURN_QUEUE' => sprintf($user->lang['RETURN_QUEUE'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue' . (($topic_id) ? '&amp;mode=unapproved_topics' : '&amp;mode=unapproved_posts')) . '&amp;start=' . $start . '">', '</a>'),
'RETURN_POST' => sprintf($user->lang['RETURN_POST'], '<a href="' . $post_url . '">', '</a>'),
'RETURN_TOPIC_SIMPLE' => sprintf($user->lang['RETURN_TOPIC_SIMPLE'], '<a href="' . $topic_url . '">', '</a>'),
@@ -331,7 +330,7 @@ class mcp_queue
$m_perm = 'm_approve';
$is_topics = ($mode == 'unapproved_topics' || $mode == 'deleted_topics') ? true : false;
$is_restore = ($mode == 'deleted_posts' || $mode == 'deleted_topics') ? true : false;
- $visibility_const = (!$is_restore) ? ITEM_UNAPPROVED : ITEM_DELETED;
+ $visibility_const = (!$is_restore) ? array(ITEM_UNAPPROVED, ITEM_REAPPROVE) : ITEM_DELETED;
$user->add_lang(array('viewtopic', 'viewforum'));
@@ -419,7 +418,7 @@ class mcp_queue
$sql = 'SELECT p.post_id
FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t' . (($sort_order_sql[0] == 'u') ? ', ' . USERS_TABLE . ' u' : '') . '
WHERE ' . $db->sql_in_set('p.forum_id', $forum_list) . '
- AND p.post_visibility = ' . $visibility_const . '
+ AND ' . $db->sql_in_set('p.post_visibility', $visibility_const) . '
' . (($sort_order_sql[0] == 'u') ? 'AND u.user_id = p.poster_id' : '') . '
' . (($topic_id) ? 'AND p.topic_id = ' . $topic_id : '') . "
AND t.topic_id = p.topic_id
@@ -472,7 +471,7 @@ class mcp_queue
$sql = 'SELECT t.forum_id, t.topic_id, t.topic_title, t.topic_title AS post_subject, t.topic_time AS post_time, t.topic_poster AS poster_id, t.topic_first_post_id AS post_id, t.topic_attachment AS post_attachment, t.topic_first_poster_name AS username, t.topic_first_poster_colour AS user_colour
FROM ' . TOPICS_TABLE . ' t
WHERE ' . $db->sql_in_set('forum_id', $forum_list) . '
- AND topic_visibility = ' . $visibility_const . "
+ AND ' . $db->sql_in_set('topic_visibility', $visibility_const) . "
AND topic_delete_user <> 0
$limit_time_sql
ORDER BY $sort_order_sql";
@@ -660,11 +659,18 @@ class mcp_queue
}
$phpbb_notifications->delete_notifications('post_in_queue', $post_id);
- $phpbb_notifications->add_notifications(array(
- 'quote',
- 'bookmark',
- 'post',
- ), $post_data);
+ // Only add notifications, if we are not reapproving post
+ // When the topic was already approved, but was edited and
+ // now needs re-approval, we don't want to notify the users
+ // again.
+ if ($post_data['post_visibility'] == ITEM_UNAPPROVED)
+ {
+ $phpbb_notifications->add_notifications(array(
+ 'quote',
+ 'bookmark',
+ 'post',
+ ), $post_data);
+ }
$phpbb_notifications->mark_notifications_read(array(
'quote',
@@ -832,10 +838,18 @@ class mcp_queue
));
$phpbb_notifications->delete_notifications('topic_in_queue', $topic_id);
- $phpbb_notifications->add_notifications(array(
- 'quote',
- 'topic',
- ), $topic_data);
+
+ // Only add notifications, if we are not reapproving post
+ // When the topic was already approved, but was edited and
+ // now needs re-approval, we don't want to notify the users
+ // again.
+ if ($topic_data['topic_visibility'] == ITEM_UNAPPROVED)
+ {
+ $phpbb_notifications->add_notifications(array(
+ 'quote',
+ 'topic',
+ ), $topic_data);
+ }
$phpbb_notifications->mark_notifications_read('quote', $topic_data['post_id'], $user->data['user_id']);
$phpbb_notifications->mark_notifications_read('topic', $topic_id, $user->data['user_id']);
@@ -1060,7 +1074,7 @@ class mcp_queue
if ($is_disapproving)
{
$l_log_message = ($log_data['type'] == 'topic') ? 'LOG_TOPIC_DISAPPROVED' : 'LOG_POST_DISAPPROVED';
- add_log('mod', $log_data['forum_id'], $log_data['topic_id'], $l_log_message, $log_data['post_subject'], $disapprove_reason);
+ add_log('mod', $log_data['forum_id'], $log_data['topic_id'], $l_log_message, $log_data['post_subject'], $disapprove_reason, $log_data['post_username']);
}
else
{
@@ -1126,7 +1140,6 @@ class mcp_queue
$post_data['disapprove_reason'] .= ($reason) ? "\n\n" . $reason : '';
}
-
if ($disapprove_all_posts_in_topic && $topic_information[$topic_id]['topic_posts_unapproved'] == 1)
{
// If there is only 1 post when disapproving the topic,
@@ -1144,7 +1157,6 @@ class mcp_queue
unset($lang_reasons, $post_info, $disapprove_reason, $disapprove_reason_lang);
-
if ($num_disapproved_topics)
{
$success_msg = ($num_disapproved_topics == 1) ? 'TOPIC' : 'TOPICS';
diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php
index 8026e071cd..5681b83212 100644
--- a/phpBB/includes/mcp/mcp_reports.php
+++ b/phpBB/includes/mcp/mcp_reports.php
@@ -98,10 +98,10 @@ class mcp_reports
$post_id = $report['post_id'];
$report_id = $report['report_id'];
-
+
$parse_post_flags = $report['reported_post_enable_bbcode'] ? OPTION_FLAG_BBCODE : 0;
$parse_post_flags += $report['reported_post_enable_smilies'] ? OPTION_FLAG_SMILIES : 0;
- $parse_post_flags += $report['reported_post_enable_magic_url'] ? OPTION_FLAG_LINKS : 0;
+ $parse_post_flags += $report['reported_post_enable_magic_url'] ? OPTION_FLAG_LINKS : 0;
$post_info = get_post_data(array($post_id), 'm_report', true);
@@ -144,7 +144,6 @@ class mcp_reports
$post_unread = (isset($topic_tracking_info[$post_info['topic_id']]) && $post_info['post_time'] > $topic_tracking_info[$post_info['topic_id']]) ? true : false;
-
$report['report_text'] = make_clickable(bbcode_nl2br($report['report_text']));
if ($post_info['post_attachment'] && $auth->acl_get('u_download') && $auth->acl_get('f_download', $post_info['forum_id']))
@@ -187,7 +186,7 @@ class mcp_reports
'S_CLOSE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=report_details&amp;f=' . $post_info['forum_id'] . '&amp;p=' . $post_id),
'S_CAN_VIEWIP' => $auth->acl_get('m_info', $post_info['forum_id']),
'S_POST_REPORTED' => $post_info['post_reported'],
- 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED),
+ 'S_POST_UNAPPROVED' => $post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE,
'S_POST_LOCKED' => $post_info['post_edit_locked'],
'S_REPORT_CLOSED' => $report['report_closed'],
'S_USER_NOTES' => true,
@@ -578,7 +577,6 @@ function close_report($report_id_list, $mode, $action, $pm = false)
}
$db->sql_query($sql);
-
if (sizeof($close_report_posts))
{
if ($pm)
diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php
index cdb88bf2bf..48efa330d4 100644
--- a/phpBB/includes/mcp/mcp_topic.php
+++ b/phpBB/includes/mcp/mcp_topic.php
@@ -212,7 +212,7 @@ function mcp_topic_view($id, $mode, $action)
parse_attachments($topic_info['forum_id'], $message, $attachments[$row['post_id']], $update_count);
}
- if ($row['post_visibility'] == ITEM_UNAPPROVED)
+ if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE)
{
$has_unapproved_posts = true;
}
@@ -239,7 +239,7 @@ function mcp_topic_view($id, $mode, $action)
'MINI_POST_IMG' => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'),
'S_POST_REPORTED' => ($row['post_reported'] && $auth->acl_get('m_report', $topic_info['forum_id'])),
- 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $topic_info['forum_id'])),
+ 'S_POST_UNAPPROVED' => (($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $topic_info['forum_id'])),
'S_POST_DELETED' => ($row['post_visibility'] == ITEM_DELETED && $auth->acl_get('m_approve', $topic_info['forum_id'])),
'S_CHECKED' => (($submitted_id_list && !in_array(intval($row['post_id']), $submitted_id_list)) || in_array(intval($row['post_id']), $checked_ids)) ? true : false,
'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false,
@@ -462,7 +462,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject)
while ($row = $db->sql_fetchrow($result))
{
// If split from selected post (split_beyond), we split the unapproved items too.
- if ($row['post_visibility'] == ITEM_UNAPPROVED && !$auth->acl_get('m_approve', $row['forum_id']))
+ if (($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) && !$auth->acl_get('m_approve', $row['forum_id']))
{
// continue;
}
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php
index ad6743b3a3..17a350bab3 100644
--- a/phpBB/includes/message_parser.php
+++ b/phpBB/includes/message_parser.php
@@ -104,7 +104,7 @@ class bbcode_firstpass extends bbcode
function bbcode_init($allow_custom_bbcode = true)
{
global $phpbb_dispatcher;
-
+
static $rowset;
// This array holds all bbcode data. BBCodes will be processed in this
diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php
index b4b14b11d7..11ba2fba4d 100644
--- a/phpBB/includes/ucp/ucp_main.php
+++ b/phpBB/includes/ucp/ucp_main.php
@@ -619,7 +619,6 @@ class ucp_main
break;
}
-
$template->assign_vars(array(
'L_TITLE' => $user->lang['UCP_MAIN_' . strtoupper($mode)],
@@ -691,7 +690,6 @@ class ucp_main
AND t.topic_id = tw.topic_id
AND ' . $db->sql_in_set('t.forum_id', $forbidden_forum_ary, true, true),
-
'ORDER_BY' => 't.topic_last_post_time DESC'
);
diff --git a/phpBB/includes/ucp/ucp_notifications.php b/phpBB/includes/ucp/ucp_notifications.php
index 7c487b9073..f3b72d12aa 100644
--- a/phpBB/includes/ucp/ucp_notifications.php
+++ b/phpBB/includes/ucp/ucp_notifications.php
@@ -99,7 +99,7 @@ class ucp_notifications
meta_refresh(3, $this->u_action);
$message = $user->lang['NOTIFICATIONS_MARK_ALL_READ_SUCCESS'];
-
+
if ($request->is_ajax())
{
$json_response = new \phpbb\json_response();
diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php
index 7e13b5b9c6..74dc08d875 100644
--- a/phpBB/includes/ucp/ucp_pm.php
+++ b/phpBB/includes/ucp/ucp_pm.php
@@ -172,7 +172,6 @@ class ucp_pm
trigger_error('NO_AUTH_READ_HOLD_MESSAGE');
}
-
// First Handle Mark actions and moving messages
$submit_mark = (isset($_POST['submit_mark'])) ? true : false;
$move_pm = (isset($_POST['move_pm'])) ? true : false;
diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php
index 3d95dc9a97..16b3ca8573 100644
--- a/phpBB/includes/ucp/ucp_pm_compose.php
+++ b/phpBB/includes/ucp/ucp_pm_compose.php
@@ -586,7 +586,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
);
$s_hidden_fields .= build_address_field($address_list);
-
confirm_box(false, 'SAVE_DRAFT', $s_hidden_fields);
}
}
@@ -748,7 +747,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
$return_box_url = ($action === 'post' || $action === 'edit') ? $outbox_folder_url : $inbox_folder_url;
$return_box_lang = ($action === 'post' || $action === 'edit') ? 'PM_OUTBOX' : 'PM_INBOX';
-
$save_message = ($action === 'edit') ? $user->lang['MESSAGE_EDITED'] : $user->lang['MESSAGE_STORED'];
$message = $save_message . '<br /><br />' . $user->lang('VIEW_PRIVATE_MESSAGE', '<a href="' . $return_message_url . '">', '</a>');
@@ -1006,7 +1004,6 @@ function compose_pm($id, $mode, $action, $user_folders = array())
// Build hidden address list
$s_hidden_address_field = build_address_field($address_list);
-
$bbcode_checked = (isset($enable_bbcode)) ? !$enable_bbcode : (($config['allow_bbcode'] && $auth->acl_get('u_pm_bbcode')) ? !$user->optionget('bbcode') : 1);
$smilies_checked = (isset($enable_smilies)) ? !$enable_smilies : (($config['allow_smilies'] && $auth->acl_get('u_pm_smilies')) ? !$user->optionget('smilies') : 1);
$urls_checked = (isset($enable_urls)) ? !$enable_urls : 0;
@@ -1229,29 +1226,80 @@ function handle_message_list_actions(&$address_list, &$error, $remove_u, $remove
// Check for disallowed recipients
if (!empty($address_list['u']))
{
- // We need to check their PM status (do they want to receive PM's?)
- // Only check if not a moderator or admin, since they are allowed to override this user setting
- if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
+ $can_ignore_allow_pm = $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_');
+
+ // Administrator deactivated users check and we need to check their
+ // PM status (do they want to receive PM's?)
+ // Only check PM status if not a moderator or admin, since they
+ // are allowed to override this user setting
+ $sql = 'SELECT user_id, user_allow_pm
+ FROM ' . USERS_TABLE . '
+ WHERE ' . $db->sql_in_set('user_id', array_keys($address_list['u'])) . '
+ AND (
+ (user_type = ' . USER_INACTIVE . '
+ AND user_inactive_reason = ' . INACTIVE_MANUAL . ')
+ ' . ($can_ignore_allow_pm ? '' : ' OR user_allow_pm = 0') . '
+ )';
+
+ $result = $db->sql_query($sql);
+
+ $removed_no_pm = $removed_no_permission = false;
+ while ($row = $db->sql_fetchrow($result))
{
- $sql = 'SELECT user_id
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('user_id', array_keys($address_list['u'])) . '
- AND user_allow_pm = 0';
- $result = $db->sql_query($sql);
+ if (!$can_ignore_allow_pm && !$row['user_allow_pm'])
+ {
+ $removed_no_pm = true;
+ }
+ else
+ {
+ $removed_no_permission = true;
+ }
- $removed = false;
- while ($row = $db->sql_fetchrow($result))
+ unset($address_list['u'][$row['user_id']]);
+ }
+ $db->sql_freeresult($result);
+
+ // print a notice about users not being added who do not want to receive pms
+ if ($removed_no_pm)
+ {
+ $error[] = $user->lang['PM_USERS_REMOVED_NO_PM'];
+ }
+
+ // print a notice about users not being added who do not have permission to receive PMs
+ if ($removed_no_permission)
+ {
+ $error[] = $user->lang['PM_USERS_REMOVED_NO_PERMISSION'];
+ }
+
+ if (!sizeof(array_keys($address_list['u'])))
+ {
+ return;
+ }
+
+ // Check if users have permission to read PMs
+ $can_read = $auth->acl_get_list(array_keys($address_list['u']), 'u_readpm');
+ $can_read = (empty($can_read) || !isset($can_read[0]['u_readpm'])) ? array() : $can_read[0]['u_readpm'];
+ $cannot_read_list = array_diff(array_keys($address_list['u']), $can_read);
+ if (!empty($cannot_read_list))
+ {
+ foreach ($cannot_read_list as $cannot_read)
{
- $removed = true;
- unset($address_list['u'][$row['user_id']]);
+ unset($address_list['u'][$cannot_read]);
}
- $db->sql_freeresult($result);
- // print a notice about users not being added who do not want to receive pms
- if ($removed)
+ $error[] = $user->lang['PM_USERS_REMOVED_NO_PERMISSION'];
+ }
+
+ // Check if users are banned
+ $banned_user_list = phpbb_get_banned_user_ids(array_keys($address_list['u']), false);
+ if (!empty($banned_user_list))
+ {
+ foreach ($banned_user_list as $banned_user)
{
- $error[] = $user->lang['PM_USERS_REMOVED_NO_PM'];
+ unset($address_list['u'][$banned_user]);
}
+
+ $error[] = $user->lang['PM_USERS_REMOVED_NO_PERMISSION'];
}
}
}
diff --git a/phpBB/includes/ucp/ucp_pm_options.php b/phpBB/includes/ucp/ucp_pm_options.php
index 26ce6ed28f..71c96a25b6 100644
--- a/phpBB/includes/ucp/ucp_pm_options.php
+++ b/phpBB/includes/ucp/ucp_pm_options.php
@@ -65,7 +65,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit
trigger_error($message);
}
}
-
+
// Add Folder
if (isset($_POST['addfolder']))
{
@@ -226,7 +226,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit
// Move Messages
case 1:
$num_moved = move_pm($user->data['user_id'], $user->data['message_limit'], $msg_ids, $move_to, $remove_folder_id);
-
+
// Something went wrong, only partially moved?
if ($num_moved != $folder_row['pm_count'])
{
@@ -418,7 +418,7 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit
$result = $db->sql_query($sql);
$num_messages = (int) $db->sql_fetchfield('num_messages');
$db->sql_freeresult($result);
-
+
$folder[PRIVMSGS_INBOX] = array(
'folder_name' => $user->lang['PM_INBOX'],
'message_status' => $user->lang('FOLDER_MESSAGE_STATUS', $user->lang('MESSAGES_COUNT', (int) $user->data['message_limit']), $num_messages),
@@ -691,7 +691,7 @@ function define_rule_option($hardcoded, $rule_option, $rule_lang, $check_ary)
function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule_conditions)
{
global $db, $template, $auth, $user;
-
+
$template->assign_vars(array(
'S_COND_DEFINED' => true,
'S_COND_SELECT' => (!$hardcoded && isset($global_rule_conditions[$rule_option])) ? true : false)
@@ -715,7 +715,7 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule
{
case 'text':
$rule_string = utf8_normalize_nfc(request_var('rule_string', '', true));
-
+
$template->assign_vars(array(
'S_TEXT_CONDITION' => true,
'CURRENT_STRING' => $rule_string,
@@ -729,7 +729,7 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule
case 'user':
$rule_user_id = request_var('rule_user_id', 0);
$rule_string = utf8_normalize_nfc(request_var('rule_string', '', true));
-
+
if ($rule_string && !$rule_user_id)
{
$sql = 'SELECT user_id
@@ -791,10 +791,10 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule
{
$sql .= 'WHERE';
}
-
- $sql .= " (g.group_name NOT IN ('GUESTS', 'BOTS') OR g.group_type <> " . GROUP_SPECIAL . ')
+
+ $sql .= " (g.group_name NOT IN ('GUESTS', 'BOTS') OR g.group_type <> " . GROUP_SPECIAL . ')
ORDER BY g.group_type DESC, g.group_name ASC';
-
+
$result = $db->sql_query($sql);
$s_group_options = '';
@@ -807,7 +807,7 @@ function define_cond_option($hardcoded, $cond_option, $rule_option, $global_rule
$s_class = ($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '';
$s_selected = ($row['group_id'] == $rule_group_id) ? ' selected="selected"' : '';
-
+
$s_group_options .= '<option value="' . $row['group_id'] . '"' . $s_class . $s_selected . '>' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
}
$db->sql_freeresult($result);
@@ -845,7 +845,7 @@ function show_defined_rules($user_id, $check_lang, $rule_lang, $action_lang, $fo
WHERE user_id = ' . $user_id . '
ORDER BY rule_id ASC';
$result = $db->sql_query($sql);
-
+
$count = 0;
while ($row = $db->sql_fetchrow($result))
{
diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php
index 03064a31d3..8a60a7e680 100644
--- a/phpBB/includes/ucp/ucp_pm_viewmessage.php
+++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php
@@ -177,6 +177,18 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
}
}
+ $u_pm = $u_jabber = '';
+
+ if ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($user_info['user_allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_')))
+ {
+ $u_pm = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;u=' . $author_id);
+ }
+
+ if ($user_info['user_jabber'] && $auth->acl_get('u_sendim'))
+ {
+ $u_jabber = append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&amp;action=jabber&amp;u=' . $author_id);
+ }
+
$msg_data = array(
'MESSAGE_AUTHOR_FULL' => get_username_string('full', $author_id, $user_info['username'], $user_info['user_colour'], $user_info['username']),
'MESSAGE_AUTHOR_COLOUR' => get_username_string('colour', $author_id, $user_info['username'], $user_info['user_colour'], $user_info['username']),
@@ -208,8 +220,8 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
'EDITED_MESSAGE' => $l_edited_by,
'MESSAGE_ID' => $message_row['msg_id'],
- 'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($user_info['user_allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;u=' . $author_id) : '',
- 'U_JABBER' => ($user_info['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&amp;action=jabber&amp;u=' . $author_id) : '',
+ 'U_PM' => $u_pm,
+ 'U_JABBER' => $u_jabber,
'U_DELETE' => ($auth->acl_get('u_pm_delete')) ? "$url&amp;mode=compose&amp;action=delete&amp;f=$folder_id&amp;p=" . $message_row['msg_id'] : '',
'U_EMAIL' => $user_info['email'],
@@ -248,13 +260,48 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
* @var array message_row Array with message data
* @var array cp_row Array with senders custom profile field data
* @var array msg_data Template array with message data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
- $vars = array('id', 'mode', 'folder_id', 'msg_id', 'folder', 'message_row', 'cp_row', 'msg_data');
+ $vars = array(
+ 'id',
+ 'mode',
+ 'folder_id',
+ 'msg_id',
+ 'folder',
+ 'message_row',
+ 'cp_row',
+ 'msg_data',
+ );
extract($phpbb_dispatcher->trigger_event('core.ucp_pm_view_messsage', compact($vars)));
$template->assign_vars($msg_data);
+ $contact_fields = array(
+ array(
+ 'ID' => 'pm',
+ 'NAME' => $user->lang['PRIVATE_MESSAGE'],
+ 'U_CONTACT' => $u_pm,
+ ),
+ array(
+ 'ID' => 'email',
+ 'NAME' => $user->lang['SEND_EMAIL'],
+ 'U_CONTACT' => $user_info['email'],
+ ),
+ array(
+ 'ID' => 'jabber',
+ 'NAME' => $user->lang['JABBER'],
+ 'U_CONTACT' => $u_jabber,
+ ),
+ );
+
+ foreach ($contact_fields as $field)
+ {
+ if ($field['U_CONTACT'])
+ {
+ $template->assign_block_vars('contact', $field);
+ }
+ }
+
// Display the custom profile fields
if (!empty($cp_row['row']))
{
@@ -263,6 +310,15 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
foreach ($cp_row['blockrow'] as $cp_block_row)
{
$template->assign_block_vars('custom_fields', $cp_block_row);
+
+ if ($cp_block_row['S_PROFILE_CONTACT'])
+ {
+ $template->assign_block_vars('contact', array(
+ 'ID' => $cp_block_row['PROFILE_FIELD_IDENT'],
+ 'NAME' => $cp_block_row['PROFILE_FIELD_NAME'],
+ 'U_CONTACT' => $cp_block_row['PROFILE_FIELD_CONTACT'],
+ ));
+ }
}
}
@@ -274,7 +330,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
{
$template->assign_block_vars('dl_method', $method);
}
-
+
foreach ($attachments as $attachment)
{
$template->assign_block_vars('attachment', array(
diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php
index e80cc2dce3..e3339c4c0b 100644
--- a/phpBB/includes/ucp/ucp_prefs.php
+++ b/phpBB/includes/ucp/ucp_prefs.php
@@ -64,7 +64,7 @@ class ucp_prefs
* @var bool submit Do we display the form only
* or did the user press submit
* @var array data Array with current ucp options data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('submit', 'data');
extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_personal_data', compact($vars)));
@@ -113,7 +113,7 @@ class ucp_prefs
* @event core.ucp_prefs_personal_update_data
* @var array data Submitted display options data
* @var array sql_ary Display options data we udpate
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('data', 'sql_ary');
extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_personal_update_data', compact($vars)));
@@ -243,7 +243,7 @@ class ucp_prefs
* @var bool submit Do we display the form only
* or did the user press submit
* @var array data Array with current ucp options data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('submit', 'data');
extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_view_data', compact($vars)));
@@ -292,7 +292,7 @@ class ucp_prefs
* @event core.ucp_prefs_view_update_data
* @var array data Submitted display options data
* @var array sql_ary Display options data we udpate
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('data', 'sql_ary');
extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_view_update_data', compact($vars)));
@@ -394,7 +394,7 @@ class ucp_prefs
* @var bool submit Do we display the form only
* or did the user press submit
* @var array data Array with current ucp options data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('submit', 'data');
extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_post_data', compact($vars)));
@@ -418,7 +418,7 @@ class ucp_prefs
* @event core.ucp_prefs_post_update_data
* @var array data Submitted display options data
* @var array sql_ary Display options data we udpate
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('data', 'sql_ary');
extract($phpbb_dispatcher->trigger_event('core.ucp_prefs_post_update_data', compact($vars)));
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index ff51ca7b3c..8660a06dcf 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -64,10 +64,7 @@ class ucp_register
$agreed = false;
}
- $user->lang_name = $user_lang = $use_lang;
- $user->lang = array();
- $user->data['user_lang'] = $user->lang_name;
- $user->add_lang(array('common', 'ucp'));
+ $user_lang = $use_lang;
}
else
{
@@ -101,7 +98,6 @@ class ucp_register
if (!$agreed || ($coppa === false && $config['coppa_enable']) || ($coppa && !$config['coppa_enable']))
{
- $add_lang = ($change_lang) ? '&amp;change_lang=' . urlencode($change_lang) : '';
$add_coppa = ($coppa !== false) ? '&amp;coppa=' . $coppa : '';
$s_hidden_fields = array_merge($s_hidden_fields, array(
@@ -147,12 +143,15 @@ class ucp_register
'L_COPPA_NO' => sprintf($user->lang['UCP_COPPA_BEFORE'], $coppa_birthday),
'L_COPPA_YES' => sprintf($user->lang['UCP_COPPA_ON_AFTER'], $coppa_birthday),
- 'U_COPPA_NO' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register&amp;coppa=0' . $add_lang),
- 'U_COPPA_YES' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register&amp;coppa=1' . $add_lang),
+ 'U_COPPA_NO' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register&amp;coppa=0'),
+ 'U_COPPA_YES' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register&amp;coppa=1'),
'S_SHOW_COPPA' => true,
'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields),
- 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register' . $add_lang),
+ 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'),
+
+ 'COOKIE_NAME' => $config['cookie_name'],
+ 'COOKIE_PATH' => $config['cookie_path'],
));
}
else
@@ -164,7 +163,10 @@ class ucp_register
'S_SHOW_COPPA' => false,
'S_REGISTRATION' => true,
'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields),
- 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register' . $add_lang . $add_coppa),
+ 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register' . $add_coppa),
+
+ 'COOKIE_NAME' => $config['cookie_name'],
+ 'COOKIE_PATH' => $config['cookie_path'],
)
);
}
@@ -469,6 +471,9 @@ class ucp_register
'S_COPPA' => $coppa,
'S_HIDDEN_FIELDS' => $s_hidden_fields,
'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'),
+
+ 'COOKIE_NAME' => $config['cookie_name'],
+ 'COOKIE_PATH' => $config['cookie_path'],
));
//
diff --git a/phpBB/includes/ucp/ucp_zebra.php b/phpBB/includes/ucp/ucp_zebra.php
index 090f9bf34c..bf9a15027a 100644
--- a/phpBB/includes/ucp/ucp_zebra.php
+++ b/phpBB/includes/ucp/ucp_zebra.php
@@ -62,7 +62,7 @@ class ucp_zebra
* @event core.ucp_remove_zebra
* @var string mode Zebra type: friends|foes
* @var array user_ids User ids we remove
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('mode', 'user_ids');
extract($phpbb_dispatcher->trigger_event('core.ucp_remove_zebra', compact($vars)));
@@ -207,7 +207,7 @@ class ucp_zebra
* friends|foes
* @var array sql_ary Array of
* entries we add
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('mode', 'sql_ary');
extract($phpbb_dispatcher->trigger_event('core.ucp_add_zebra', compact($vars)));
@@ -224,15 +224,15 @@ class ucp_zebra
}
}
}
-
+
if ($request->is_ajax())
{
$message = ($updated) ? $user->lang[$l_mode . '_UPDATED'] : implode('<br />', $error);
-
+
$json_response = new \phpbb\json_response;
$json_response->send(array(
'success' => $updated,
-
+
'MESSAGE_TITLE' => $user->lang['INFORMATION'],
'MESSAGE_TEXT' => $message,
'REFRESH_DATA' => array(
diff --git a/phpBB/includes/utf/utf_normalizer.php b/phpBB/includes/utf/utf_normalizer.php
index a208552d53..f8c9c76d4f 100644
--- a/phpBB/includes/utf/utf_normalizer.php
+++ b/phpBB/includes/utf/utf_normalizer.php
@@ -479,7 +479,6 @@ class utf_normalizer
continue;
}
-
// STEP 1: Decompose current char
// We have found a character that is either:
@@ -527,7 +526,6 @@ class utf_normalizer
$utf_seq = array($utf_char);
}
-
// STEP 2: Capture the starter
// Check out the combining class of the first character of the UTF sequence
@@ -683,7 +681,6 @@ class utf_normalizer
}
}
-
// STEP 3: Capture following combining modifiers
while ($pos < $len)
@@ -752,7 +749,6 @@ class utf_normalizer
}
}
-
// STEP 4: Sort and combine
// Here we sort...
@@ -991,7 +987,6 @@ class utf_normalizer
$tmp_pos = $last_cc = $sort = $dump = 0;
$utf_sort = array();
-
// Main loop
do
{
@@ -1047,7 +1042,6 @@ class utf_normalizer
continue;
}
-
// STEP 1: Decide what to do with current char
// Now, in that order:
diff --git a/phpBB/index.php b/phpBB/index.php
index 32bc118e8c..1c481d4363 100644
--- a/phpBB/index.php
+++ b/phpBB/index.php
@@ -63,7 +63,7 @@ if (($mark_notification = $request->variable('mark_notification', 0)))
redirect(append_sid($phpbb_root_path . $redirect));
}
- redirect($notification->get_url());
+ redirect($notification->get_redirect_url());
}
}
}
@@ -188,7 +188,7 @@ $page_title = $user->lang['INDEX'];
*
* @event core.index_modify_page_title
* @var string page_title Title of the index page
-* @since 3.1-A1
+* @since 3.1.0-a1
*/
$vars = array('page_title');
extract($phpbb_dispatcher->trigger_event('core.index_modify_page_title', compact($vars)));
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php
index 926f139da4..5f672ca092 100644
--- a/phpBB/install/convertors/convert_phpbb20.php
+++ b/phpBB/install/convertors/convert_phpbb20.php
@@ -33,7 +33,7 @@ $dbms = phpbb_convert_30_dbms_to_31($dbms);
$convertor_data = array(
'forum_name' => 'phpBB 2.0.x',
'version' => '1.0.3',
- 'phpbb_version' => '3.1.0-b2',
+ 'phpbb_version' => '3.1.0-b3',
'author' => '<a href="https://www.phpbb.com/">phpBB Group</a>',
'dbms' => $dbms,
'dbhost' => $dbhost,
diff --git a/phpBB/install/convertors/functions_phpbb20.php b/phpBB/install/convertors/functions_phpbb20.php
index 29e5f7ab09..b5a69abe93 100644
--- a/phpBB/install/convertors/functions_phpbb20.php
+++ b/phpBB/install/convertors/functions_phpbb20.php
@@ -71,7 +71,6 @@ function phpbb_insert_forums()
$prune_enabled = (int) $src_db->sql_fetchfield('config_value');
$src_db->sql_freeresult($result);
-
// Insert categories
$sql = 'SELECT cat_id, cat_title
FROM ' . $convert->src_table_prefix . 'categories
@@ -571,7 +570,6 @@ function phpbb_convert_authentication($mode)
// What we will do is handling all 2.0.x admins as founder to replicate what is common in 2.0.x.
// After conversion the main admin need to make sure he is removing permissions and the founder status if wanted.
-
// Grab user ids of users with user_level of ADMIN
$sql = "SELECT user_id
FROM {$convert->src_table_prefix}users
@@ -1845,6 +1843,7 @@ function phpbb_create_userconv_table()
break;
case 'sqlite':
+ case 'sqlite3':
$create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' (
user_id INTEGER NOT NULL DEFAULT \'0\',
username_clean varchar(255) NOT NULL DEFAULT \'\'
diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php
index 6c9eeb6a75..b1bfbc1839 100644
--- a/phpBB/install/database_update.php
+++ b/phpBB/install/database_update.php
@@ -115,7 +115,13 @@ request_var('', 0, false, false, $request); // "dependency injection" for a func
$config = $phpbb_container->get('config');
set_config(null, null, null, $config);
set_config_count(null, null, null, $config);
-$orig_version = $config['version'];
+
+if (!isset($config['version_update_from']))
+{
+ $config->set('version_update_from', $config['version']);
+}
+
+$orig_version = $config['version_update_from'];
$user->add_lang(array('common', 'acp/common', 'install', 'migrator'));
@@ -287,4 +293,6 @@ else
echo $user->lang['COMPLETE_LOGIN_TO_BOARD'];
}
+$config->delete('version_update_from');
+
phpbb_end_update($cache, $config);
diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php
index 82311bd04d..13001426f7 100644
--- a/phpBB/install/install_convert.php
+++ b/phpBB/install/install_convert.php
@@ -249,6 +249,7 @@ class install_convert extends module
switch ($db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
case 'firebird':
$db->sql_query('DELETE FROM ' . SESSIONS_KEYS_TABLE);
$db->sql_query('DELETE FROM ' . SESSIONS_TABLE);
@@ -696,6 +697,7 @@ class install_convert extends module
switch ($src_db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
case 'firebird':
$convert->src_truncate_statement = 'DELETE FROM ';
break;
@@ -728,6 +730,7 @@ class install_convert extends module
switch ($db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
case 'firebird':
$convert->truncate_statement = 'DELETE FROM ';
break;
diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php
index dcf2756850..f9d5edc903 100644
--- a/phpBB/install/install_install.php
+++ b/phpBB/install/install_install.php
@@ -217,7 +217,6 @@ class install_install extends module
'S_LEGEND' => false,
));
-
// Check for getimagesize
if (@function_exists('getimagesize'))
{
@@ -291,8 +290,8 @@ class install_install extends module
$checks = array(
array('func_overload', '&', MB_OVERLOAD_MAIL|MB_OVERLOAD_STRING),
array('encoding_translation', '!=', 0),
- array('http_input', '!=', 'pass'),
- array('http_output', '!=', 'pass')
+ array('http_input', '!=', array('pass', '')),
+ array('http_output', '!=', array('pass', ''))
);
foreach ($checks as $mb_checks)
@@ -313,7 +312,8 @@ class install_install extends module
break;
case '!=':
- if ($ini_val != $mb_checks[2])
+ if (!is_array($mb_checks[2]) && $ini_val != $mb_checks[2] ||
+ is_array($mb_checks[2]) && !in_array($ini_val, $mb_checks[2]))
{
$result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
$passed['mbstring'] = false;
@@ -535,7 +535,6 @@ class install_install extends module
$url = (!in_array(false, $passed)) ? $this->p_master->module_url . "?mode=$mode&amp;sub=database&amp;language=$language" : $this->p_master->module_url . "?mode=$mode&amp;sub=requirements&amp;language=$language ";
$submit = (!in_array(false, $passed)) ? $lang['INSTALL_START'] : $lang['INSTALL_TEST'];
-
$template->assign_vars(array(
'L_SUBMIT' => $submit,
'S_HIDDEN' => $s_hidden_fields,
@@ -1649,6 +1648,45 @@ class install_install extends module
$_module->move_module_by($row, 'move_up', 5);
}
+ if ($module_class == 'mcp')
+ {
+ // Move pm report details module 3 down...
+ $sql = 'SELECT *
+ FROM ' . MODULES_TABLE . "
+ WHERE module_basename = 'mcp_pm_reports'
+ AND module_class = 'mcp'
+ AND module_mode = 'pm_report_details'";
+ $result = $db->sql_query($sql);
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ $_module->move_module_by($row, 'move_down', 3);
+
+ // Move closed pm reports module 3 down...
+ $sql = 'SELECT *
+ FROM ' . MODULES_TABLE . "
+ WHERE module_basename = 'mcp_pm_reports'
+ AND module_class = 'mcp'
+ AND module_mode = 'pm_reports_closed'";
+ $result = $db->sql_query($sql);
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ $_module->move_module_by($row, 'move_down', 3);
+
+ // Move open pm reports module 3 down...
+ $sql = 'SELECT *
+ FROM ' . MODULES_TABLE . "
+ WHERE module_basename = 'mcp_pm_reports'
+ AND module_class = 'mcp'
+ AND module_mode = 'pm_reports'";
+ $result = $db->sql_query($sql);
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ $_module->move_module_by($row, 'move_down', 3);
+ }
+
if ($module_class == 'ucp')
{
// Move attachment module 4 down...
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index bc76bf55b9..0f9976a96b 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -21,6 +21,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_cdn', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_emailreuse', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_password_reset', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_forum_notify', '1');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_live_searches', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_mass_pm', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_name_chars', 'USERNAME_CHARS_ANY');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_namechange', '0');
@@ -56,6 +57,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_min_width',
INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_path', 'images/avatars/upload');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_salt', 'phpbb_avatar');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact', 'contact@yourdomain.tld');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact_name', '');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_disable', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_disable_msg', '');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email', 'address@yourdomain.tld');
@@ -269,7 +271,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.1.0-b3-dev');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.1.0-b4-dev');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400');
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index 1d2c979e0c..505709d513 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -111,7 +111,7 @@ $lang = array_merge($lang, array(
'AVATAR_GALLERY_PATH' => 'Avatar gallery path',
'AVATAR_GALLERY_PATH_EXPLAIN' => 'Path under your phpBB root directory for pre-loaded images, e.g. <samp>images/avatars/gallery</samp>.',
'AVATAR_STORAGE_PATH' => 'Avatar storage path',
- 'AVATAR_STORAGE_PATH_EXPLAIN' => 'Path under your phpBB root directory, e.g. <samp>images/avatars/upload</samp>.',
+ 'AVATAR_STORAGE_PATH_EXPLAIN' => 'Path under your phpBB root directory, e.g. <samp>images/avatars/upload</samp>.<br />Avatar uploading <strong>will not be available</strong> if this path is not writable.',
'MAX_AVATAR_SIZE' => 'Maximum avatar dimensions',
'MAX_AVATAR_SIZE_EXPLAIN' => 'Width x Height in pixels.',
'MAX_FILESIZE' => 'Maximum avatar file size',
@@ -356,6 +356,8 @@ $lang = array_merge($lang, array(
'ALLOW_CDN' => 'Allow usage of third party content delivery networks',
'ALLOW_CDN_EXPLAIN' => 'If this setting is enabled, some files will be served from external third party servers instead of your server. This reduces the network bandwidth required by your server, but may present a privacy issue for some board administrators. In a default phpBB installation, this includes loading “jQuery” and the font “Open Sans” from Google’s content delivery network.',
+ 'ALLOW_LIVE_SEARCHES' => 'Allow live searches',
+ 'ALLOW_LIVE_SEARCHES_EXPLAIN' => 'If this setting is enabled, users are provided with keyword suggestions as they type in certain fields throughout the board.',
'CUSTOM_PROFILE_FIELDS' => 'Custom profile fields',
'LIMIT_LOAD' => 'Limit system load',
'LIMIT_LOAD_EXPLAIN' => 'If the system’s 1-minute load average exceeds this value the board will automatically go offline. A value of 1.0 equals ~100% utilisation of one processor. This only functions on UNIX based servers and where this information is accessible. The value here resets itself to 0 if phpBB was unable to get the load limit.',
@@ -524,6 +526,8 @@ $lang = array_merge($lang, array(
'BOARD_HIDE_EMAILS_EXPLAIN' => 'This function keeps email addresses completely private.',
'CONTACT_EMAIL' => 'Contact email address',
'CONTACT_EMAIL_EXPLAIN' => 'This address will be used whenever a specific contact point is needed, e.g. spam, error output, etc. It will always be used as the <samp>From</samp> and <samp>Reply-To</samp> address in emails.',
+ 'CONTACT_EMAIL_NAME' => 'Contact name',
+ 'CONTACT_EMAIL_NAME_EXPLAIN' => 'This is the contact name that e-mail recipients will see. If you don’t want to have a contact name, leave this field empty.',
'EMAIL_FUNCTION_NAME' => 'Email function name',
'EMAIL_FUNCTION_NAME_EXPLAIN' => 'The email function used to send mails through PHP.',
'EMAIL_PACKAGE_SIZE' => 'Email package size',
diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index 6f16dfabd4..6f6a5f901f 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -85,7 +85,6 @@ $lang = array_merge($lang, array(
'ACP_EXTENSION_MANAGEMENT' => 'Extension management',
'ACP_EXTENSIONS' => 'Manage extensions',
-
'ACP_FORUM_BASED_PERMISSIONS' => 'Forum based permissions',
'ACP_FORUM_LOGS' => 'Forum logs',
'ACP_FORUM_MANAGEMENT' => 'Forum management',
@@ -551,7 +550,7 @@ $lang = array_merge($lang, array(
'LOG_PM_REPORT_CLOSED' => '<strong>Closed PM report</strong><br />» %s',
'LOG_PM_REPORT_DELETED' => '<strong>Deleted PM report</strong><br />» %s',
'LOG_POST_APPROVED' => '<strong>Approved post</strong><br />» %s',
- 'LOG_POST_DISAPPROVED' => '<strong>Disapproved post “%1$s” with the following reason</strong><br />» %2$s',
+ 'LOG_POST_DISAPPROVED' => '<strong>Disapproved post “%1$s” written by “%3$s” for the following reason</strong><br />» %2$s',
'LOG_POST_EDITED' => '<strong>Edited post “%1$s” written by</strong><br />» %2$s',
'LOG_POST_RESTORED' => '<strong>Restored post</strong><br />» %s',
'LOG_REPORT_CLOSED' => '<strong>Closed report</strong><br />» %s',
@@ -564,7 +563,7 @@ $lang = array_merge($lang, array(
'LOG_TOPIC_APPROVED' => '<strong>Approved topic</strong><br />» %s',
'LOG_TOPIC_RESTORED' => '<strong>Restored topic</strong><br />» %s',
- 'LOG_TOPIC_DISAPPROVED' => '<strong>Disapproved topic “%1$s” with the following reason</strong><br />%2$s',
+ 'LOG_TOPIC_DISAPPROVED' => '<strong>Disapproved topic “%1$s” written by “%3$s” for the following reason</strong><br />» %2$s',
'LOG_TOPIC_RESYNC' => '<strong>Resynchronised topic counters</strong><br />» %s',
'LOG_TOPIC_TYPE_CHANGED' => '<strong>Changed topic type</strong><br />» %s',
'LOG_UNLOCK' => '<strong>Unlocked topic</strong><br />» %s',
@@ -678,7 +677,6 @@ $lang = array_merge($lang, array(
'LOG_PURGE_CACHE' => '<strong>Purged cache</strong>',
'LOG_PURGE_SESSIONS' => '<strong>Purged sessions</strong>',
-
'LOG_RANK_ADDED' => '<strong>Added new rank</strong><br />» %s',
'LOG_RANK_REMOVED' => '<strong>Removed rank</strong><br />» %s',
'LOG_RANK_UPDATED' => '<strong>Updated rank</strong><br />» %s',
diff --git a/phpBB/language/en/acp/extensions.php b/phpBB/language/en/acp/extensions.php
index baa7d01763..39881668c4 100644
--- a/phpBB/language/en/acp/extensions.php
+++ b/phpBB/language/en/acp/extensions.php
@@ -33,7 +33,6 @@ if (empty($lang) || !is_array($lang))
// equally where a string contains only two placeholders which are used to wrap text
// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
-
$lang = array_merge($lang, array(
'EXTENSION' => 'Extension',
'EXTENSIONS' => 'Extensions',
diff --git a/phpBB/language/en/acp/permissions.php b/phpBB/language/en/acp/permissions.php
index 6e3ba6876a..36af461f87 100644
--- a/phpBB/language/en/acp/permissions.php
+++ b/phpBB/language/en/acp/permissions.php
@@ -182,7 +182,6 @@ $lang = array_merge($lang, array(
'ROLE_USER_STANDARD' => 'Standard Features',
'ROLE_USER_NEW_MEMBER' => 'Newly Registered User Features',
-
'ROLE_DESCRIPTION_ADMIN_FORUM' => 'Can access the forum management and forum permission settings.',
'ROLE_DESCRIPTION_ADMIN_FULL' => 'Has access to all administrative functions of this board.<br />Not recommended.',
'ROLE_DESCRIPTION_ADMIN_STANDARD' => 'Has access to most administrative features but is not allowed to use server or system related tools.',
diff --git a/phpBB/language/en/acp/posting.php b/phpBB/language/en/acp/posting.php
index ea3eadb0dd..cf570d844f 100644
--- a/phpBB/language/en/acp/posting.php
+++ b/phpBB/language/en/acp/posting.php
@@ -85,8 +85,8 @@ $lang = array_merge($lang, array(
'URL' => 'A valid URL using any protocol (http, ftp, etc… cannot be used for javascript exploits). If none is given, “http://” is prefixed to the string.',
'LOCAL_URL' => 'A local URL. The URL must be relative to the topic page and cannot contain a server name or protocol, as links are prefixed with “%s”',
'RELATIVE_URL' => 'A relative URL. You can use this to match parts of a URL, but be careful: a full URL is a valid relative URL. When you want to use relative URLs of your board, use the LOCAL_URL token.',
- 'COLOR' => 'A HTML colour, can be either in the numeric form <samp>#FF1234</samp> or a <a href="http://www.w3.org/TR/CSS21/syndata.html#value-def-color">CSS colour keyword</a> such as <samp>fuchsia</samp> or <samp>InactiveBorder</samp>'
- )
+ 'COLOR' => 'A HTML colour, can be either in the numeric form <samp>#FF1234</samp> or a <a href="http://www.w3.org/TR/CSS21/syndata.html#value-def-color">CSS colour keyword</a> such as <samp>fuchsia</samp> or <samp>InactiveBorder</samp>',
+ ),
));
// Smilies and topic icons
@@ -109,8 +109,6 @@ $lang = array_merge($lang, array(
'DISPLAY_POSTING' => 'On posting page',
'DISPLAY_POSTING_NO' => 'Not on posting page',
-
-
'EDIT_ICONS' => 'Edit icons',
'EDIT_SMILIES' => 'Edit smilies',
'EMOTION' => 'Emotion',
diff --git a/phpBB/language/en/acp/profile.php b/phpBB/language/en/acp/profile.php
index dc42693ca7..ab4db02053 100644
--- a/phpBB/language/en/acp/profile.php
+++ b/phpBB/language/en/acp/profile.php
@@ -68,8 +68,8 @@ $lang = array_merge($lang, array(
'DISPLAY_AT_REGISTER_EXPLAIN' => 'If this option is enabled, the field will be displayed on registration.',
'DISPLAY_ON_MEMBERLIST' => 'Display on memberlist screen',
'DISPLAY_ON_MEMBERLIST_EXPLAIN' => 'If this option is enabled, the field will be displayed in the user rows on the memberlist screen.',
- 'DISPLAY_ON_PM' => 'Display on view pm screen',
- 'DISPLAY_ON_PM_EXPLAIN' => 'If this option is enabled, the field will be displayed in the mini-profile on the pm screen.',
+ 'DISPLAY_ON_PM' => 'Display on view private message screen',
+ 'DISPLAY_ON_PM_EXPLAIN' => 'If this option is enabled, the field will be displayed in the mini-profile on the private message screen.',
'DISPLAY_ON_VT' => 'Display on viewtopic screen',
'DISPLAY_ON_VT_EXPLAIN' => 'If this option is enabled, the field will be displayed in the mini-profile on the topic screen.',
'DISPLAY_PROFILE_FIELD' => 'Publicly display profile field',
diff --git a/phpBB/language/en/app.php b/phpBB/language/en/app.php
index cb56015c30..6697532150 100644
--- a/phpBB/language/en/app.php
+++ b/phpBB/language/en/app.php
@@ -41,9 +41,6 @@ if (empty($lang) || !is_array($lang))
$lang = array_merge($lang, array(
'CONTROLLER_ARGUMENT_VALUE_MISSING' => 'Missing value for argument #%1$s: <strong>%3$s</strong> in class <strong>%2$s</strong>',
'CONTROLLER_NOT_SPECIFIED' => 'No controller has been specified.',
- 'CONTROLLER_NOT_FOUND' => 'The requested page could not be found.',
'CONTROLLER_METHOD_NOT_SPECIFIED' => 'No method was specified for the controller.',
- 'CONTROLLER_SERVICE_NOT_GIVEN' => 'The controller "<strong>%s</strong>" must have a service specified in ./config/routing.yml.',
'CONTROLLER_SERVICE_UNDEFINED' => 'The service for controller "<strong>%s</strong>" is not defined in ./config/services.yml.',
- 'CONTROLLER_RETURN_TYPE_INVALID' => 'The controller object <strong>%s</strong> must return a Symfony\Component\HttpFoundation\Response object.',
));
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index 677b228cc6..7faa46daf3 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -167,6 +167,7 @@ $lang = array_merge($lang, array(
'CONGRATULATIONS' => 'Congratulations to',
'CONNECTION_FAILED' => 'Connection failed.',
'CONNECTION_SUCCESS' => 'Connection was successful!',
+ 'CONTACT_USER' => 'Contact',
'COOKIES_DELETED' => 'All board cookies successfully deleted.',
'CURRENT_TIME' => 'It is currently %s',
@@ -217,8 +218,6 @@ $lang = array_merge($lang, array(
'ERROR' => 'Error',
'EXPAND_VIEW' => 'Expand view',
'EXTENSION' => 'Extension',
- 'EXTENSION_CONTROLLER_MISSING' => 'The extension <strong>%s</strong> is missing a controller class and cannot be accessed through the front-end.',
- 'EXTENSION_CLASS_WRONG_TYPE' => 'The extension controller class <strong>%s</strong> is not an instance of the phpbb_extension_controller_interface.',
'EXTENSION_DISABLED' => 'The extension <strong>%s</strong> is not enabled.',
'EXTENSION_DISABLED_AFTER_POSTING' => 'The extension <strong>%s</strong> has been deactivated and can no longer be displayed.',
'EXTENSION_DOES_NOT_EXIST' => 'The extension <strong>%s</strong> does not exist.',
@@ -348,6 +347,7 @@ $lang = array_merge($lang, array(
'LDAP_NO_SERVER_CONNECTION' => 'Could not connect to LDAP server.',
'LDAP_SEARCH_FAILED' => 'An error occurred while searching the LDAP directory.',
'LEGEND' => 'Legend',
+ 'LIVE_SEARCHES_NOT_ALLOWED' => 'Live searches are not allowed.',
'LOADING' => 'Loading',
'LOCATION' => 'Location',
'LOCK_POST' => 'Lock post',
@@ -422,14 +422,16 @@ $lang = array_merge($lang, array(
'NOT_WATCHING_FORUM' => 'You are no longer subscribed to updates on this forum.',
'NOT_WATCHING_TOPIC' => 'You are no longer subscribed to this topic.',
'NOTIFICATIONS' => 'Notifications',
- // This applies for NOTIFICATION_BOOKMARK, NOTIFICATION_POST, and NOTIFICATION_QUOTE.
+ // This applies for NOTIFICATION_BOOKMARK and NOTIFICATION_POST.
// %1$s will return a list of users that's concatenated using "," and "and" - see STRING_LIST
// Once the user count reaches 5 users or more, the list is trimmed using NOTIFICATION_X_OTHERS
+ // Once the user count reaches 20 users or more, the list is trimmed using NOTIFICATION_MANY_OTHERS
// Examples:
// A replied...
// A and B replied...
// A, B and C replied...
// A, B, C and 2 others replied...
+ // A, B, C and others replied...
'NOTIFICATION_BOOKMARK' => array(
1 => '%1$s replied to the topic “%2$s” you have bookmarked.',
),
@@ -454,7 +456,8 @@ $lang = array_merge($lang, array(
'NOTIFICATION_TOPIC_IN_QUEUE' => 'A new topic titled "%2$s" was posted by %1$s and needs approval.',
'NOTIFICATION_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.',
'NOTIFICATION_ADMIN_ACTIVATE_USER' => 'The user “%1$s” is newly registered and requires activation.',
- // Used in conjuction with NOTIFICATION_BOOKMARK, NOTIFICATION_POST, and NOTIFICATION_QUOTE.
+ // Used in conjuction with NOTIFICATION_BOOKMARK and NOTIFICATION_POST.
+ 'NOTIFICATION_MANY_OTHERS' => 'others',
'NOTIFICATION_X_OTHERS' => array(
2 => '%d others',
),
@@ -552,7 +555,8 @@ $lang = array_merge($lang, array(
'POST_BY_FOE' => '<strong>%1$s</strong>, who is currently on your ignore list, made this post.',
'POST_DISPLAY' => '%1$sDisplay this post%2$s.',
'POST_DAY' => '%.2f posts per day',
- 'POST_DELETED' => 'Deleted post:',
+ 'POST_DELETED_ACTION' => 'Deleted post:',
+ 'POST_DELETED' => 'This post has been deleted.',
'POST_DELETED_BY' => '<strong>%2$s</strong> deleted the post by <strong>%1$s</strong> on %3$s.',
'POST_DELETED_BY_REASON'=> '<strong>%2$s</strong> deleted the post by <strong>%1$s</strong> on %3$s for the following reason: %4$s',
'POST_DETAILS' => 'Post details',
@@ -565,7 +569,8 @@ $lang = array_merge($lang, array(
'POST_SUBJECT' => 'Post subject',
'POST_TIME' => 'Post time',
'POST_TOPIC' => 'Post a new topic',
- 'POST_UNAPPROVED' => 'Post awaiting approval:',
+ 'POST_UNAPPROVED_ACTION' => 'Post awaiting approval:',
+ 'POST_UNAPPROVED' => 'This post has not been approved.',
'POWERED_BY' => 'Powered by %s',
'PREVIEW' => 'Preview',
'PREVIOUS' => 'Previous', // Used in pagination
@@ -735,7 +740,8 @@ $lang = array_merge($lang, array(
'TOPIC_MOVED' => 'Moved topic',
'TOPIC_REVIEW' => 'Topic review',
'TOPIC_TITLE' => 'Topic title',
- 'TOPIC_UNAPPROVED' => 'This topic has not been approved',
+ 'TOPIC_UNAPPROVED' => 'This topic has not been approved.',
+ 'TOPIC_DELETED' => 'This topic has been deleted.',
'TOTAL_ATTACHMENTS' => 'Attachment(s)',
'TOTAL_LOGS' => array(
1 => '%d log',
@@ -1370,7 +1376,7 @@ $lang = array_merge($lang, array(
'D M d, Y g:i a' => 'Mon Jan 01, 2007 1:37 pm',
'F jS, Y, g:i a' => 'January 1st, 2007, 1:37 pm',
'|d M Y|, H:i' => 'Today, 13:37 / 01 Jan 2007, 13:37',
- '|F jS, Y|, g:i a' => 'Today, 1:37 pm / January 1st, 2007, 1:37 pm'
+ '|F jS, Y|, g:i a' => 'Today, 1:37 pm / January 1st, 2007, 1:37 pm',
),
// The default dateformat which will be used on new installs in this language
diff --git a/phpBB/language/en/email/admin_activate.txt b/phpBB/language/en/email/admin_activate.txt
index 8b11f1b450..a53ab1269e 100644
--- a/phpBB/language/en/email/admin_activate.txt
+++ b/phpBB/language/en/email/admin_activate.txt
@@ -10,5 +10,4 @@ Use this link to view the user's profile:
Use this link to activate the account:
{U_ACTIVATE}
-
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/admin_send_email.txt b/phpBB/language/en/email/admin_send_email.txt
index b778496258..7345a040fd 100644
--- a/phpBB/language/en/email/admin_send_email.txt
+++ b/phpBB/language/en/email/admin_send_email.txt
@@ -10,5 +10,4 @@ Message sent to you follows:
{MESSAGE}
-
{EMAIL_SIG}
diff --git a/phpBB/language/en/email/admin_welcome_activated.txt b/phpBB/language/en/email/admin_welcome_activated.txt
index cfdb69bdcb..2e136ac530 100644
--- a/phpBB/language/en/email/admin_welcome_activated.txt
+++ b/phpBB/language/en/email/admin_welcome_activated.txt
@@ -6,4 +6,4 @@ Your account on "{SITENAME}" has been activated by an administrator, you may log
Your password has been securely stored in our database and cannot be retrieved. In the event that it is forgotten, you will be able to reset it using the email address associated with your account.
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/admin_welcome_inactive.txt b/phpBB/language/en/email/admin_welcome_inactive.txt
index 8605956318..f9a57b9fe3 100644
--- a/phpBB/language/en/email/admin_welcome_inactive.txt
+++ b/phpBB/language/en/email/admin_welcome_inactive.txt
@@ -16,4 +16,4 @@ Your password has been securely stored in our database and cannot be retrieved.
Thank you for registering.
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/email_notify.txt b/phpBB/language/en/email/email_notify.txt
index 725b52f0cc..43c9098a4f 100644
--- a/phpBB/language/en/email/email_notify.txt
+++ b/phpBB/language/en/email/email_notify.txt
@@ -14,4 +14,4 @@ A message from {FROM_USERNAME} may also be included below. Please note that this
----------
-{MESSAGE} \ No newline at end of file
+{MESSAGE}
diff --git a/phpBB/language/en/email/installed.txt b/phpBB/language/en/email/installed.txt
index 8f63d07635..93444581f2 100644
--- a/phpBB/language/en/email/installed.txt
+++ b/phpBB/language/en/email/installed.txt
@@ -16,4 +16,4 @@ Useful information regarding the phpBB software can be found in the docs folder
In order to keep your board safe and secure, we highly recommended keeping current with software releases. For your convenience, a mailing list is available at the page referenced above.
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/pm_report_closed.txt b/phpBB/language/en/email/pm_report_closed.txt
index 1b9f4a6658..0202b9d374 100644
--- a/phpBB/language/en/email/pm_report_closed.txt
+++ b/phpBB/language/en/email/pm_report_closed.txt
@@ -4,5 +4,4 @@ Hello {USERNAME},
You are receiving this notification because the report you filed regarding the private message "{PM_SUBJECT}" at "{SITENAME}" has been tended to by a moderator or administrator. The report is now closed. If you have further questions, please contact {CLOSER_NAME} by private message.
-
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/pm_report_deleted.txt b/phpBB/language/en/email/pm_report_deleted.txt
index a868837841..991ed59f31 100644
--- a/phpBB/language/en/email/pm_report_deleted.txt
+++ b/phpBB/language/en/email/pm_report_deleted.txt
@@ -4,5 +4,4 @@ Hello {USERNAME},
You are receiving this notification because the report you filed regarding the private message "{PM_SUBJECT}" at "{SITENAME}" was deleted by a moderator or administrator.
-
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/post_approved.txt b/phpBB/language/en/email/post_approved.txt
index a02dba142a..854d785f5f 100644
--- a/phpBB/language/en/email/post_approved.txt
+++ b/phpBB/language/en/email/post_approved.txt
@@ -10,4 +10,4 @@ If you want to view the post, click the following link:
If you want to view the topic, click the following link:
{U_VIEW_TOPIC}
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/short/post_approved.txt b/phpBB/language/en/email/short/post_approved.txt
index a02dba142a..854d785f5f 100644
--- a/phpBB/language/en/email/short/post_approved.txt
+++ b/phpBB/language/en/email/short/post_approved.txt
@@ -10,4 +10,4 @@ If you want to view the post, click the following link:
If you want to view the topic, click the following link:
{U_VIEW_TOPIC}
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/user_activate.txt b/phpBB/language/en/email/user_activate.txt
index 7d7960c4c5..b949b68651 100644
--- a/phpBB/language/en/email/user_activate.txt
+++ b/phpBB/language/en/email/user_activate.txt
@@ -6,4 +6,4 @@ Your account on "{SITENAME}" has been deactivated, most likely due to changes ma
{U_ACTIVATE}
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/user_activate_inactive.txt b/phpBB/language/en/email/user_activate_inactive.txt
index a90773d48c..7743420698 100644
--- a/phpBB/language/en/email/user_activate_inactive.txt
+++ b/phpBB/language/en/email/user_activate_inactive.txt
@@ -4,4 +4,4 @@ Hello {USERNAME},
Your account on "{SITENAME}" has been deactivated, most likely due to changes made to your profile. The administrator of the board will need to activate it before you can log in. You will receive another notification when this has occurred.
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/user_activate_passwd.txt b/phpBB/language/en/email/user_activate_passwd.txt
index 695be115f8..965d5a552c 100644
--- a/phpBB/language/en/email/user_activate_passwd.txt
+++ b/phpBB/language/en/email/user_activate_passwd.txt
@@ -14,4 +14,4 @@ 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} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/user_reactivate_account.txt b/phpBB/language/en/email/user_reactivate_account.txt
index 385c09f4c5..7564b0a8e4 100644
--- a/phpBB/language/en/email/user_reactivate_account.txt
+++ b/phpBB/language/en/email/user_reactivate_account.txt
@@ -15,4 +15,4 @@ Please visit the following link to reactivate your account:
{U_ACTIVATE}
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/user_remind_inactive.txt b/phpBB/language/en/email/user_remind_inactive.txt
index 1ba28329f6..1f136b56f2 100644
--- a/phpBB/language/en/email/user_remind_inactive.txt
+++ b/phpBB/language/en/email/user_remind_inactive.txt
@@ -8,4 +8,4 @@ This notification is a reminder that your account at "{SITENAME}", created on {R
Thank you for registering at "{SITENAME}", we look forward to your participation.
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/user_resend_inactive.txt b/phpBB/language/en/email/user_resend_inactive.txt
index b9b95ce9e5..d975a07b13 100644
--- a/phpBB/language/en/email/user_resend_inactive.txt
+++ b/phpBB/language/en/email/user_resend_inactive.txt
@@ -16,4 +16,4 @@ Please visit the following link in order to activate your account:
Thank you for registering.
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/user_welcome.txt b/phpBB/language/en/email/user_welcome.txt
index aaead86afc..f299b7b23e 100644
--- a/phpBB/language/en/email/user_welcome.txt
+++ b/phpBB/language/en/email/user_welcome.txt
@@ -14,4 +14,4 @@ Your password has been securely stored in our database and cannot be retrieved.
Thank you for registering.
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/email/user_welcome_inactive.txt b/phpBB/language/en/email/user_welcome_inactive.txt
index 5cbb3af3de..b4300d0032 100644
--- a/phpBB/language/en/email/user_welcome_inactive.txt
+++ b/phpBB/language/en/email/user_welcome_inactive.txt
@@ -18,4 +18,4 @@ Your password has been securely stored in our database and cannot be retrieved.
Thank you for registering.
-{EMAIL_SIG} \ No newline at end of file
+{EMAIL_SIG}
diff --git a/phpBB/language/en/groups.php b/phpBB/language/en/groups.php
index 6155d34a8c..c36d87f793 100644
--- a/phpBB/language/en/groups.php
+++ b/phpBB/language/en/groups.php
@@ -81,7 +81,7 @@ $lang = array_merge($lang, array(
'NOT_LEADER_OF_GROUP' => 'The requested operation cannot be taken because you are not a leader of the selected group.',
'NOT_MEMBER_OF_GROUP' => 'The requested operation cannot be taken because you are not a member of the selected group or your membership has not been approved yet.',
'NOT_RESIGN_FROM_DEFAULT_GROUP' => 'You are not allowed to resign from your default group.',
-
+
'PRIMARY_GROUP' => 'Primary group',
'REMOVE_SELECTED' => 'Remove selected',
diff --git a/phpBB/language/en/help_bbcode.php b/phpBB/language/en/help_bbcode.php
index d627ac3908..61263752b2 100644
--- a/phpBB/language/en/help_bbcode.php
+++ b/phpBB/language/en/help_bbcode.php
@@ -109,5 +109,5 @@ $help = array(
array(
0 => 'Can I add my own tags?',
1 => 'If you are an administrator on this board and have the proper permissions, you can add further BBCodes through the Custom BBCodes section.'
- )
+ ),
);
diff --git a/phpBB/language/en/help_faq.php b/phpBB/language/en/help_faq.php
index 94e6622685..d803ec91e4 100644
--- a/phpBB/language/en/help_faq.php
+++ b/phpBB/language/en/help_faq.php
@@ -337,5 +337,5 @@ $help = array(
array(
0 => 'Who do I contact about abusive and/or legal matters related to this board?',
1 => 'Any of the administrators listed on the “The team” page should be an appropriate point of contact for your complaints. If this still gets no response then you should contact the owner of the domain (do a <a href="http://www.google.com/search?q=whois">whois lookup</a>) or, if this is running on a free service (e.g. Yahoo!, free.fr, f2s.com, etc.), the management or abuse department of that service. Please note that the phpBB Group has <strong>absolutely no jurisdiction</strong> and cannot in any way be held liable over how, where or by whom this board is used. Do not contact the phpBB Group in relation to any legal (cease and desist, liable, defamatory comment, etc.) matter <strong>not directly related</strong> to the phpBB.com website or the discrete software of phpBB itself. If you do email phpBB Group <strong>about any third party</strong> use of this software then you should expect a terse response or no response at all.'
- )
+ ),
);
diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php
index 081361f661..caefc1219d 100644
--- a/phpBB/language/en/install.php
+++ b/phpBB/language/en/install.php
@@ -151,7 +151,8 @@ $lang = array_merge($lang, array(
'DLL_MYSQLI' => 'MySQL with MySQLi Extension',
'DLL_ORACLE' => 'Oracle',
'DLL_POSTGRES' => 'PostgreSQL',
- 'DLL_SQLITE' => 'SQLite',
+ 'DLL_SQLITE' => 'SQLite 2',
+ 'DLL_SQLITE3' => 'SQLite 3',
'DLL_XML' => 'XML support [ Jabber ]',
'DLL_ZLIB' => 'zlib compression support [ gz, .tar.gz, .zip ]',
'DL_CONFIG' => 'Download config',
@@ -212,6 +213,7 @@ $lang = array_merge($lang, array(
<li>MySQL 3.23 or above (MySQLi supported)</li>
<li>PostgreSQL 8.3+</li>
<li>SQLite 2.8.2+</li>
+ <li>SQLite 3.6.15+</li>
<li>Firebird 2.1+</li>
<li>MS SQL Server 2000 or above (directly or via ODBC)</li>
<li>MS SQL Server 2005 or above (native)</li>
@@ -235,6 +237,7 @@ $lang = array_merge($lang, array(
'INST_ERR_DB_NO_ERROR' => 'No error message given.',
'INST_ERR_DB_NO_MYSQLI' => 'The version of MySQL installed on this machine is incompatible with the “MySQL with MySQLi Extension” option you have selected. Please try the “MySQL” option instead.',
'INST_ERR_DB_NO_SQLITE' => 'The version of the SQLite extension you have installed is too old, it must be upgraded to at least 2.8.2.',
+ 'INST_ERR_DB_NO_SQLITE3' => 'The version of the SQLite extension you have installed is too old, it must be upgraded to at least 3.6.15.',
'INST_ERR_DB_NO_ORACLE' => 'The version of Oracle installed on this machine requires you to set the <var>NLS_CHARACTERSET</var> parameter to <var>UTF8</var>. Either upgrade your installation to 9.2+ or change the parameter.',
'INST_ERR_DB_NO_FIREBIRD' => 'The version of Firebird installed on this machine is older than 2.1, please upgrade to a newer version.',
'INST_ERR_DB_NO_FIREBIRD_PS'=> 'The database you selected for Firebird has a page size less than 8192, it must be at least 8192.',
diff --git a/phpBB/language/en/mcp.php b/phpBB/language/en/mcp.php
index b75e0ea495..dffa40db2f 100644
--- a/phpBB/language/en/mcp.php
+++ b/phpBB/language/en/mcp.php
@@ -426,6 +426,6 @@ $lang = array_merge($lang, array(
'SPAM' => 'The reported message has the only purpose to advertise for a website or another product.',
'OFF_TOPIC' => 'The reported message is off topic.',
'OTHER' => 'The reported message does not fit into any other category, please use the further information field.',
- )
+ ),
),
));
diff --git a/phpBB/language/en/memberlist.php b/phpBB/language/en/memberlist.php
index 95efe35b7d..f92286a092 100644
--- a/phpBB/language/en/memberlist.php
+++ b/phpBB/language/en/memberlist.php
@@ -47,7 +47,6 @@ $lang = array_merge($lang, array(
'BEFORE' => 'Before',
'CC_EMAIL' => 'Send a copy of this email to yourself.',
- 'CONTACT_USER' => 'Contact',
'DEST_LANG' => 'Language',
'DEST_LANG_EXPLAIN' => 'Select an appropriate language (if available) for the recipient of this message.',
diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php
index c1d8cef7de..e3b6101310 100644
--- a/phpBB/language/en/posting.php
+++ b/phpBB/language/en/posting.php
@@ -53,7 +53,7 @@ $lang = array_merge($lang, array(
'BBCODE_IS_OFF' => '%sBBCode%s is <em>OFF</em>',
'BBCODE_IS_ON' => '%sBBCode%s is <em>ON</em>',
'BBCODE_I_HELP' => 'Italic text: [i]text[/i]',
- 'BBCODE_L_HELP' => 'List: [list][*]text[/list]',
+ 'BBCODE_L_HELP' => 'List: [list][*]text[/list]',
'BBCODE_LISTITEM_HELP' => 'List item: [*]text',
'BBCODE_O_HELP' => 'Ordered list: e.g. [list=1][*]First point[/list] or [list=a][*]Point a[/list]',
'BBCODE_P_HELP' => 'Insert image: [img]http://image_url[/img]',
diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php
index 5148589471..3419d34e7a 100644
--- a/phpBB/language/en/ucp.php
+++ b/phpBB/language/en/ucp.php
@@ -413,6 +413,7 @@ $lang = array_merge($lang, array(
'PM_SUBJECT' => 'Message subject',
'PM_TO' => 'Send to',
'PM_TOOLS' => 'Message tools',
+ 'PM_USERS_REMOVED_NO_PERMISSION' => 'Some users couldn’t be added as they do not have permission to read private messages.',
'PM_USERS_REMOVED_NO_PM' => 'Some users couldn’t be added as they have disabled private message receipt.',
'POST_EDIT_PM' => 'Edit message',
'POST_FORWARD_PM' => 'Forward message',
@@ -603,14 +604,14 @@ $lang = array_merge($lang, array(
'PLACE_INTO_FOLDER' => 'Place into folder',
'MARK_AS_READ' => 'Mark as read',
'MARK_AS_IMPORTANT' => 'Mark message',
- 'DELETE_MESSAGE' => 'Delete message'
+ 'DELETE_MESSAGE' => 'Delete message',
),
'PM_CHECK' => array(
'SUBJECT' => 'Subject',
'SENDER' => 'Sender',
'MESSAGE' => 'Message',
'STATUS' => 'Message status',
- 'TO' => 'Sent To'
+ 'TO' => 'Sent To',
),
'PM_RULE' => array(
'IS_LIKE' => 'is like',
@@ -626,10 +627,9 @@ $lang = array_merge($lang, array(
'ANSWERED' => 'answered',
'FORWARDED' => 'forwarded',
'TO_GROUP' => 'to my default usergroup',
- 'TO_ME' => 'to me'
+ 'TO_ME' => 'to me',
),
-
'GROUPS_EXPLAIN' => 'Usergroups enable board admins to better administer users. By default you will be placed in a specific group, this is your default group. This group defines how you may appear to other users, for example your username colouration, avatar, rank, etc. Depending on whether the administrator allows it you may be allowed to change your default group. You may also be placed in or allowed to join other groups. Some groups may give you additional permissions to view content or increase your capabilities in other areas.',
'GROUP_LEADER' => 'Leaderships',
'GROUP_MEMBER' => 'Memberships',
diff --git a/phpBB/mcp.php b/phpBB/mcp.php
index 1449346deb..3555eb3b48 100644
--- a/phpBB/mcp.php
+++ b/phpBB/mcp.php
@@ -197,7 +197,8 @@ if ($quickmod)
* @var bool is_valid_action Flag indicating if the action was handled properly
* @since 3.1.0-a4
*/
- extract($phpbb_dispatcher->trigger_event('core.modify_quickmod_options', compact(array('module', 'action', 'is_valid_action'))));
+ $vars = array('module', 'action', 'is_valid_action');
+ extract($phpbb_dispatcher->trigger_event('core.modify_quickmod_options', compact($vars)));
if (!$is_valid_action)
{
@@ -266,7 +267,16 @@ if (!$user_id && $username == '')
* @var int id Parent module id
* @since 3.1.0-b2
*/
-$vars = array('module', 'mode', 'user_id', 'forum_id', 'topic_id', 'post_id', 'username', 'id');
+$vars = array(
+ 'module',
+ 'mode',
+ 'user_id',
+ 'forum_id',
+ 'topic_id',
+ 'post_id',
+ 'username',
+ 'id',
+);
extract($phpbb_dispatcher->trigger_event('core.modify_mcp_modules_display_option', compact($vars)));
// Load and execute the relevant module
@@ -677,7 +687,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql,
case 'unapproved_posts':
case 'deleted_posts':
- $visibility_const = ($mode == 'unapproved_posts') ? ITEM_UNAPPROVED : ITEM_DELETED;
+ $visibility_const = ($mode == 'unapproved_posts') ? array(ITEM_UNAPPROVED, ITEM_REAPPROVE) : ITEM_DELETED;
$type = 'posts';
$default_key = 't';
$default_dir = 'd';
@@ -686,7 +696,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql,
$sql = 'SELECT COUNT(p.post_id) AS total
FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t
$where_sql " . $db->sql_in_set('p.forum_id', ($forum_id) ? array($forum_id) : array_intersect(get_forum_list('f_read'), get_forum_list('m_approve'))) . '
- AND p.post_visibility = ' . $visibility_const . '
+ AND ' . $db->sql_in_set('p.post_visibility', $visibility_const) .'
AND t.topic_id = p.topic_id
AND t.topic_visibility <> p.post_visibility';
@@ -698,7 +708,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql,
case 'unapproved_topics':
case 'deleted_topics':
- $visibility_const = ($mode == 'unapproved_topics') ? ITEM_UNAPPROVED : ITEM_DELETED;
+ $visibility_const = ($mode == 'unapproved_topics') ? array(ITEM_UNAPPROVED, ITEM_REAPPROVE) : ITEM_DELETED;
$type = 'topics';
$default_key = 't';
$default_dir = 'd';
@@ -706,7 +716,7 @@ function mcp_sorting($mode, &$sort_days, &$sort_key, &$sort_dir, &$sort_by_sql,
$sql = 'SELECT COUNT(topic_id) AS total
FROM ' . TOPICS_TABLE . "
$where_sql " . $db->sql_in_set('forum_id', ($forum_id) ? array($forum_id) : array_intersect(get_forum_list('f_read'), get_forum_list('m_approve'))) . '
- AND topic_visibility = ' . $visibility_const;
+ AND ' . $db->sql_in_set('topic_visibility', $visibility_const);
if ($min_time)
{
diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php
index 8fceb4ac5b..6c28f962dc 100644
--- a/phpBB/memberlist.php
+++ b/phpBB/memberlist.php
@@ -40,7 +40,7 @@ if ($mode == 'leaders')
}
// Check our mode...
-if (!in_array($mode, array('', 'group', 'viewprofile', 'email', 'contact', 'searchuser', 'team')))
+if (!in_array($mode, array('', 'group', 'viewprofile', 'email', 'contact', 'searchuser', 'team', 'livesearch')))
{
trigger_error('NO_MODE');
}
@@ -50,6 +50,13 @@ switch ($mode)
case 'email':
break;
+ case 'livesearch':
+ if (!$config['allow_live_searches'])
+ {
+ trigger_error('LIVE_SEARCHES_NOT_ALLOWED');
+ }
+ // No break
+
default:
// Can this user view profiles/memberlist?
if (!$auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel'))
@@ -558,8 +565,6 @@ switch ($mode)
$member['user_sig'] = generate_text_for_display($member['user_sig'], $member['user_sig_bbcode_uid'], $member['user_sig_bbcode_bitfield'], $parse_flags, true);
}
- $poster_avatar = phpbb_get_user_avatar($member);
-
// We need to check if the modules 'zebra' ('friends' & 'foes' mode), 'notes' ('user_notes' mode) and 'warn' ('warn_user' mode) are accessible to decide if we can display appropriate links
$zebra_enabled = $friends_enabled = $foes_enabled = $user_notes_enabled = $warn_user_enabled = false;
@@ -584,47 +589,54 @@ switch ($mode)
unset($module);
}
+ // Custom Profile Fields
+ $profile_fields = array();
+ if ($config['load_cpf_viewprofile'])
+ {
+ $cp = $phpbb_container->get('profilefields.manager');
+ $profile_fields = $cp->grab_profile_fields_data($user_id);
+ $profile_fields = (isset($profile_fields[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields[$user_id]) : array();
+ }
+
/**
* Modify user data before we display the profile
*
* @event core.memberlist_view_profile
* @var array member Array with user's data
- * @var bool user_notes_enabled Is the mcp user notes module
- * enabled?
- * @var bool warn_user_enabled Is the mcp warnings module
- * enabled?
- * @var bool zebra_enabled Is the ucp zebra module
- * enabled?
- * @var bool friends_enabled Is the ucp friends module
- * enabled?
- * @var bool foes_enabled Is the ucp foes module
- * enabled?
+ * @var bool user_notes_enabled Is the mcp user notes module enabled?
+ * @var bool warn_user_enabled Is the mcp warnings module enabled?
+ * @var bool zebra_enabled Is the ucp zebra module enabled?
+ * @var bool friends_enabled Is the ucp friends module enabled?
+ * @var bool foes_enabled Is the ucp foes module enabled?
* @var bool friend Is the user friend?
* @var bool foe Is the user foe?
- * @since 3.1-A1
+ * @var array profile_fields Array with user's profile field data
+ * @since 3.1.0-a1
* @changed 3.1.0-b2 Added friend and foe status
+ * @changed 3.1.0-b3 Added profile fields data
*/
- $vars = array('member', 'user_notes_enabled', 'warn_user_enabled', 'zebra_enabled', 'friends_enabled', 'foes_enabled', 'friend', 'foe');
+ $vars = array(
+ 'member',
+ 'user_notes_enabled',
+ 'warn_user_enabled',
+ 'zebra_enabled',
+ 'friends_enabled',
+ 'foes_enabled',
+ 'friend',
+ 'foe',
+ 'profile_fields',
+ );
extract($phpbb_dispatcher->trigger_event('core.memberlist_view_profile', compact($vars)));
$template->assign_vars(show_profile($member, $user_notes_enabled, $warn_user_enabled));
- // Custom Profile Fields
- $profile_fields = array();
- if ($config['load_cpf_viewprofile'])
- {
- $cp = $phpbb_container->get('profilefields.manager');
- $profile_fields = $cp->grab_profile_fields_data($user_id);
- $profile_fields = (isset($profile_fields[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields[$user_id]) : array();
- }
-
// If the user has m_approve permission or a_user permission, then list then display unapproved posts
if ($auth->acl_getf_global('m_approve') || $auth->acl_get('a_user'))
{
$sql = 'SELECT COUNT(post_id) as posts_in_queue
FROM ' . POSTS_TABLE . '
WHERE poster_id = ' . $user_id . '
- AND post_visibility = ' . ITEM_UNAPPROVED;
+ AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE));
$result = $db->sql_query($sql);
$member['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue');
$db->sql_freeresult($result);
@@ -643,7 +655,6 @@ switch ($mode)
'SIGNATURE' => $member['user_sig'],
'POSTS_IN_QUEUE'=> $member['posts_in_queue'],
- 'AVATAR_IMG' => $poster_avatar,
'PM_IMG' => $user->img('icon_contact_pm', $user->lang['SEND_PRIVATE_MESSAGE']),
'EMAIL_IMG' => $user->img('icon_contact_email', $user->lang['EMAIL']),
'JABBER_IMG' => $user->img('icon_contact_jabber', $user->lang['JABBER']),
@@ -981,6 +992,35 @@ switch ($mode)
break;
+ case 'livesearch':
+
+ $username_chars = $request->variable('username', '', true);
+
+ $sql = 'SELECT username, user_id, user_colour
+ FROM ' . USERS_TABLE . '
+ WHERE ' . $db->sql_in_set('user_type', array(USER_NORMAL, USER_FOUNDER)) . '
+ AND username_clean ' . $db->sql_like_expression(utf8_clean_string($username_chars) . $db->any_char);
+ $result = $db->sql_query_limit($sql, 10);
+ $user_list = array();
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $user_list[] = array(
+ 'user_id' => (int) $row['user_id'],
+ 'result' => $row['username'],
+ 'username_full' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
+ 'display' => get_username_string('no_profile', $row['user_id'], $row['username'], $row['user_colour']),
+ );
+ }
+ $db->sql_freeresult($result);
+ $json_response = new \phpbb\json_response();
+ $json_response->send(array(
+ 'keyword' => $username_chars,
+ 'results' => $user_list,
+ ));
+
+ break;
+
case 'group':
default:
// The basic memberlist
@@ -1618,6 +1658,7 @@ switch ($mode)
'U_FIND_MEMBER' => ($config['load_search'] || $auth->acl_get('a_')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser' . (($start) ? "&amp;start=$start" : '') . (!empty($params) ? '&amp;' . implode('&amp;', $params) : '')) : '',
'U_HIDE_FIND_MEMBER' => ($mode == 'searchuser' || ($mode == '' && $submit)) ? $u_hide_find_member : '',
+ 'U_LIVE_SEARCH' => ($config['allow_live_searches']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=livesearch') : false,
'U_SORT_USERNAME' => $sort_url . '&amp;sk=a&amp;sd=' . (($sort_key == 'a' && $sort_dir == 'a') ? 'd' : 'a'),
'U_SORT_JOINED' => $sort_url . '&amp;sk=c&amp;sd=' . (($sort_key == 'c' && $sort_dir == 'a') ? 'd' : 'a'),
'U_SORT_POSTS' => $sort_url . '&amp;sk=d&amp;sd=' . (($sort_key == 'd' && $sort_dir == 'a') ? 'd' : 'a'),
@@ -1711,6 +1752,29 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f
}
}
+ if (!function_exists('phpbb_get_banned_user_ids'))
+ {
+ include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
+ }
+
+ // Can this user receive a Private Message?
+ $can_receive_pm = (
+ // They must be a "normal" user
+ $data['user_type'] != USER_IGNORE &&
+
+ // They must not be deactivated by the administrator
+ ($data['user_type'] != USER_INACTIVE || $data['user_inactive_reason'] != INACTIVE_MANUAL) &&
+
+ // They must be able to read PMs
+ sizeof($auth->acl_get_list($user_id, 'u_readpm')) &&
+
+ // They must not be permanently banned
+ !sizeof(phpbb_get_banned_user_ids($user_id, false)) &&
+
+ // They must allow users to contact via PM
+ (($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_')) || $data['user_allow_pm'])
+ );
+
// Dump it out to the template
$template_data = array(
'AGE' => $age,
@@ -1739,7 +1803,7 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f
'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id=$user_id&amp;sr=posts") : '',
'U_NOTES' => ($user_notes_enabled && $auth->acl_getf_global('m_')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&amp;mode=user_notes&amp;u=' . $user_id, true, $user->session_id) : '',
'U_WARN' => ($warn_user_enabled && $auth->acl_get('m_warn')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&amp;mode=warn_user&amp;u=' . $user_id, true, $user->session_id) : '',
- 'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($data['user_allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;u=' . $user_id) : '',
+ 'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && $can_receive_pm) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;u=' . $user_id) : '',
'U_EMAIL' => $email,
'U_JABBER' => ($data['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&amp;action=jabber&amp;u=' . $user_id) : '',
@@ -1755,7 +1819,7 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f
* @event core.memberlist_prepare_profile_data
* @var array data Array with user's data
* @var array template_data Template array with user's data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('data', 'template_data');
extract($phpbb_dispatcher->trigger_event('core.memberlist_prepare_profile_data', compact($vars)));
diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php
index 1e50e135e4..f77ef1332b 100644
--- a/phpBB/phpbb/avatar/driver/upload.php
+++ b/phpBB/phpbb/avatar/driver/upload.php
@@ -147,7 +147,7 @@ class upload extends \phpbb\avatar\driver\driver
return array(
'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
- 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true),
+ 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true),
);
}
diff --git a/phpBB/phpbb/console/command/cache/purge.php b/phpBB/phpbb/console/command/cache/purge.php
new file mode 100644
index 0000000000..017bdc5144
--- /dev/null
+++ b/phpBB/phpbb/console/command/cache/purge.php
@@ -0,0 +1,62 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+namespace phpbb\console\command\cache;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class purge extends \phpbb\console\command\command
+{
+ /** @var \phpbb\cache\driver\driver_interface */
+ protected $cache;
+
+ /** @var \phpbb\db\driver\driver_interface */
+ protected $db;
+
+ /** @var \phpbb\auth\auth */
+ protected $auth;
+
+ /** @var \phpbb\log\log */
+ protected $log;
+
+ /** @var \phpbb\user */
+ protected $user;
+
+ function __construct(\phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\auth\auth $auth, \phpbb\log\log $log, \phpbb\user $user)
+ {
+ $this->cache = $cache;
+ $this->db = $db;
+ $this->auth = $auth;
+ $this->log = $log;
+ $this->user = $user;
+ $this->user->add_lang(array('acp/common'));
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this
+ ->setName('cache:purge')
+ ->setDescription('Purge the cache.')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->cache->purge();
+
+ // Clear permissions
+ $this->auth->acl_clear_prefetch();
+ phpbb_cache_moderators($this->db, $this->cache, $this->auth);
+
+ $this->log->add('admin', ANONYMOUS, '', 'LOG_PURGE_CACHE', time(), array());
+
+ $output->writeln($this->user->lang('PURGE_CACHE_SUCCESS'));
+ }
+}
diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php
new file mode 100644
index 0000000000..d984ac9e7a
--- /dev/null
+++ b/phpBB/phpbb/console/command/db/migrate.php
@@ -0,0 +1,128 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+namespace phpbb\console\command\db;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class migrate extends \phpbb\console\command\command
+{
+ /** @var \phpbb\db\migrator */
+ protected $migrator;
+
+ /** @var \phpbb\extension\manager */
+ protected $extension_manager;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ /** @var \phpbb\cache\service */
+ protected $cache;
+
+ /** @var \phpbb\log\log */
+ protected $log;
+
+ /** @var \phpbb\user */
+ protected $user;
+
+ function __construct(\phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\user $user)
+ {
+ $this->migrator = $migrator;
+ $this->extension_manager = $extension_manager;
+ $this->config = $config;
+ $this->cache = $cache;
+ $this->log = $log;
+ $this->user = $user;
+ $this->user->add_lang(array('common', 'acp/common', 'install', 'migrator'));
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this
+ ->setName('db:migrate')
+ ->setDescription('Updates the database by applying migrations.')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->load_migrations();
+ $orig_version = $this->config['version'];
+ while (!$this->migrator->finished())
+ {
+ $migration_start_time = microtime(true);
+
+ try
+ {
+ $this->migrator->update();
+ }
+ catch (\phpbb\db\migration\exception $e)
+ {
+ $output->writeln('<error>' . $e->getLocalisedMessage($this->user) . '</error>');
+ $this->finalise_update();
+ return 1;
+ }
+
+ $migration_stop_time = microtime(true) - $migration_start_time;
+
+ $state = array_merge(
+ array(
+ 'migration_schema_done' => false,
+ 'migration_data_done' => false,
+ ),
+ $this->migrator->last_run_migration['state']
+ );
+
+ if (!empty($this->migrator->last_run_migration['effectively_installed']))
+ {
+ $msg = $this->user->lang('MIGRATION_EFFECTIVELY_INSTALLED', $this->migrator->last_run_migration['name']);
+ $output->writeln("<comment>$msg</comment>");
+ }
+ else if ($this->migrator->last_run_migration['task'] == 'process_data_step' && $state['migration_data_done'])
+ {
+ $msg = $this->user->lang('MIGRATION_DATA_DONE', $this->migrator->last_run_migration['name'], $migration_stop_time);
+ $output->writeln("<info>$msg</info>");
+ }
+ else if ($this->migrator->last_run_migration['task'] == 'process_data_step')
+ {
+ $output->writeln($this->user->lang('MIGRATION_DATA_IN_PROGRESS', $this->migrator->last_run_migration['name'], $migration_stop_time));
+ }
+ else if ($state['migration_schema_done'])
+ {
+ $msg = $this->user->lang('MIGRATION_SCHEMA_DONE', $this->migrator->last_run_migration['name'], $migration_stop_time);
+ $output->writeln("<info>$msg</info>");
+ }
+ }
+
+ if ($orig_version != $this->config['version'])
+ {
+ $this->log->add('admin', ANONYMOUS, '', 'LOG_UPDATE_DATABASE', time(), array($orig_version, $this->config['version']));
+ }
+
+ $this->finalise_update();
+ $output->writeln($this->user->lang['DATABASE_UPDATE_COMPLETE']);
+ }
+
+ protected function load_migrations()
+ {
+ $migrations = $this->extension_manager
+ ->get_finder()
+ ->core_path('phpbb/db/migration/data/')
+ ->extension_directory('/migrations')
+ ->get_classes();
+ $this->migrator->set_migrations($migrations);
+ }
+
+ protected function finalise_update()
+ {
+ $this->cache->purge();
+ $this->config->increment('assets_version', 1);
+ }
+}
diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php
index f3db37e478..881a8f2c54 100644
--- a/phpBB/phpbb/content_visibility.php
+++ b/phpBB/phpbb/content_visibility.php
@@ -215,23 +215,23 @@ class content_visibility
/**
* Change visibility status of one post or all posts of a topic
*
- * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED}
+ * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE}
* @param $post_id mixed Post ID or array of post IDs to act on,
* if it is empty, all posts of topic_id will be modified
* @param $topic_id int Topic where $post_id is found
* @param $forum_id int Forum where $topic_id is found
* @param $user_id int User performing the action
* @param $time int Timestamp when the action is performed
- * @param $reason string Reason why the visibilty was changed.
+ * @param $reason string Reason why the visibility was changed.
* @param $is_starter bool Is this the first post of the topic changed?
* @param $is_latest bool Is this the last post of the topic changed?
* @param $limit_visibility mixed Limit updating per topic_id to a certain visibility
* @param $limit_delete_time mixed Limit updating per topic_id to a certain deletion time
- * @return array Changed post data, empty array if an error occured.
+ * @return array Changed post data, empty array if an error occurred.
*/
public function set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest, $limit_visibility = false, $limit_delete_time = false)
{
- if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED)))
+ if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE)))
{
return array();
}
@@ -326,7 +326,7 @@ class content_visibility
// Update users postcounts
foreach ($postcounts as $num_posts => $poster_ids)
{
- if ($visibility == ITEM_DELETED)
+ if (in_array($visibility, array(ITEM_REAPPROVE, ITEM_DELETED)))
{
$sql = 'UPDATE ' . $this->users_table . '
SET user_posts = 0
@@ -387,54 +387,36 @@ class content_visibility
// Update the topic's reply count and the forum's post count
if ($update_topic_postcount)
{
- $cur_posts = $cur_unapproved_posts = $cur_softdeleted_posts = 0;
+ $field_alias = array(
+ ITEM_APPROVED => 'posts_approved',
+ ITEM_UNAPPROVED => 'posts_unapproved',
+ ITEM_DELETED => 'posts_softdeleted',
+ ITEM_REAPPROVE => 'posts_unapproved',
+ );
+ $cur_posts = array_fill_keys($field_alias, 0);
+
foreach ($postcount_visibility as $post_visibility => $visibility_posts)
{
- // We need to substract the posts from the counters ...
- if ($post_visibility == ITEM_APPROVED)
- {
- $cur_posts += $visibility_posts;
- }
- else if ($post_visibility == ITEM_UNAPPROVED)
- {
- $cur_unapproved_posts += $visibility_posts;
- }
- else if ($post_visibility == ITEM_DELETED)
- {
- $cur_softdeleted_posts += $visibility_posts;
- }
+ $cur_posts[$field_alias[(int) $post_visibility]] += $visibility_posts;
}
$sql_ary = array();
- if ($visibility == ITEM_DELETED)
+ $recipient_field = $field_alias[$visibility];
+
+ foreach ($cur_posts as $field => $count)
{
- if ($cur_posts)
- {
- $sql_ary['posts_approved'] = ' - ' . $cur_posts;
- }
- if ($cur_unapproved_posts)
+ // Decrease the count for the old statuses.
+ if ($count && $field != $recipient_field)
{
- $sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts;
- }
- if ($cur_posts + $cur_unapproved_posts)
- {
- $sql_ary['posts_softdeleted'] = ' + ' . ($cur_posts + $cur_unapproved_posts);
+ $sql_ary[$field] = " - $count";
}
}
- else
+ // Add up the count from all statuses excluding the recipient status.
+ $count_increase = array_sum(array_diff($cur_posts, array($recipient_field)));
+
+ if ($count_increase)
{
- if ($cur_unapproved_posts)
- {
- $sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts;
- }
- if ($cur_softdeleted_posts)
- {
- $sql_ary['posts_softdeleted'] = ' - ' . $cur_softdeleted_posts;
- }
- if ($cur_softdeleted_posts + $cur_unapproved_posts)
- {
- $sql_ary['posts_approved'] = ' + ' . ($cur_softdeleted_posts + $cur_unapproved_posts);
- }
+ $sql_ary[$recipient_field] = " + $count_increase";
}
if (sizeof($sql_ary))
@@ -475,7 +457,7 @@ class content_visibility
* as soft deleted.
* If you want to update all posts, use the force option.
*
- * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED}
+ * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE}
* @param $topic_id mixed Topic ID to act on
* @param $forum_id int Forum where $topic_id is found
* @param $user_id int User performing the action
@@ -486,7 +468,7 @@ class content_visibility
*/
public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false)
{
- if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED)))
+ if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE)))
{
return array();
}
@@ -532,7 +514,7 @@ class content_visibility
}
else if (!$force_update_all && $original_topic_data['topic_visibility'] == ITEM_APPROVED && $visibility == ITEM_DELETED)
{
- // If we're soft deleting a topic we only approved posts are soft deleted.
+ // If we're soft deleting a topic we only mark approved posts as soft deleted.
$this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility']);
}
else
diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php
index 54c30c93fc..959a24f277 100644
--- a/phpBB/phpbb/controller/helper.php
+++ b/phpBB/phpbb/controller/helper.php
@@ -56,17 +56,19 @@ class helper
* @param \phpbb\user $user User object
* @param \phpbb\config\config $config Config object
* @param \phpbb\controller\provider $provider Path provider
+ * @param \phpbb\extension\manager $manager Extension manager object
* @param string $phpbb_root_path phpBB root path
* @param string $php_ext PHP extension
*/
- public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, $phpbb_root_path, $php_ext)
{
$this->template = $template;
$this->user = $user;
$this->config = $config;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
- $this->route_collection = $provider->get_routes();
+ $provider->find_routing_files($manager->get_finder());
+ $this->route_collection = $provider->find($phpbb_root_path)->get_routes();
}
/**
diff --git a/phpBB/phpbb/controller/provider.php b/phpBB/phpbb/controller/provider.php
index 9df8130210..a32ce1473b 100644
--- a/phpBB/phpbb/controller/provider.php
+++ b/phpBB/phpbb/controller/provider.php
@@ -37,20 +37,24 @@ class provider
* @param array() $routing_files Array of strings containing paths
* to YAML files holding route information
*/
- public function __construct(\phpbb\extension\finder $finder = null, $routing_files = array())
+ public function __construct($routing_files = array())
{
$this->routing_files = $routing_files;
+ }
- if ($finder)
- {
- // We hardcode the path to the core config directory
- // because the finder cannot find it
- $this->routing_files = array_merge($this->routing_files, array('config/routing.yml'), array_keys($finder
- ->directory('config')
- ->suffix('routing.yml')
- ->find()
- ));
- }
+ /**
+ * @param \phpbb\extension\finder $finder
+ * @return null
+ */
+ public function find_routing_files(\phpbb\extension\finder $finder)
+ {
+ // We hardcode the path to the core config directory
+ // because the finder cannot find it
+ $this->routing_files = array_merge($this->routing_files, array('config/routing.yml'), array_keys($finder
+ ->directory('/config')
+ ->suffix('routing.yml')
+ ->find()
+ ));
}
/**
diff --git a/phpBB/phpbb/db/driver/sqlite3.php b/phpBB/phpbb/db/driver/sqlite3.php
new file mode 100644
index 0000000000..971b3e55d3
--- /dev/null
+++ b/phpBB/phpbb/db/driver/sqlite3.php
@@ -0,0 +1,375 @@
+<?php
+/**
+*
+* @package dbal
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\db\driver;
+
+/**
+* SQLite3 Database Abstraction Layer
+* Minimum Requirement: 3.6.15+
+* @package dbal
+*/
+class sqlite3 extends \phpbb\db\driver\driver
+{
+ /**
+ * @var string Stores errors during connection setup in case the driver is not available
+ */
+ protected $connect_error = '';
+
+ /**
+ * @var \SQLite3 The SQLite3 database object to operate against
+ */
+ protected $dbo = null;
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
+ {
+ $this->persistency = false;
+ $this->user = $sqluser;
+ $this->server = $sqlserver . (($port) ? ':' . $port : '');
+ $this->dbname = $database;
+
+ if (!class_exists('SQLite3', false))
+ {
+ $this->connect_error = 'SQLite3 not found, is the extension installed?';
+ return $this->sql_error('');
+ }
+
+ try
+ {
+ $this->dbo = new \SQLite3($this->server, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);
+ $this->db_connect_id = true;
+ }
+ catch (Exception $e)
+ {
+ return array('message' => $e->getMessage());
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_server_info($raw = false, $use_cache = true)
+ {
+ global $cache;
+
+ if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite_version')) === false)
+ {
+ $version = \SQLite3::version();
+
+ $this->sql_server_version = $version['versionString'];
+
+ if (!empty($cache) && $use_cache)
+ {
+ $cache->put('sqlite_version', $this->sql_server_version);
+ }
+ }
+
+ return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version;
+ }
+
+ /**
+ * SQL Transaction
+ *
+ * @param string $status Should be one of the following strings:
+ * begin, commit, rollback
+ * @return bool Success/failure of the transaction query
+ */
+ protected function _sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ return $this->dbo->exec('BEGIN IMMEDIATE');
+ break;
+
+ case 'commit':
+ return $this->dbo->exec('COMMIT');
+ break;
+
+ case 'rollback':
+ return $this->dbo->exec('ROLLBACK');
+ break;
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public 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);
+ }
+
+ $this->last_query_text = $query;
+ $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 = @$this->dbo->query($query)) === false)
+ {
+ $this->sql_error($query);
+ }
+
+ if (defined('DEBUG'))
+ {
+ $this->sql_report('stop', $query);
+ }
+
+ if ($cache && $cache_ttl)
+ {
+ $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
+ }
+ }
+ else if (defined('DEBUG'))
+ {
+ $this->sql_report('fromcache', $query);
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return $this->query_result;
+ }
+
+ /**
+ * Build LIMIT query
+ *
+ * @param string $query The SQL query to execute
+ * @param int $total The number of rows to select
+ * @param int $offset
+ * @param int $cache_ttl Either 0 to avoid caching or
+ * the time in seconds which the result shall be kept in cache
+ * @return mixed Buffered, seekable result handle, false on error
+ */
+ protected function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
+ {
+ $this->query_result = false;
+
+ // if $total is set to 0 we do not want to limit the number of rows
+ if ($total == 0)
+ {
+ $total = -1;
+ }
+
+ $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
+
+ return $this->sql_query($query, $cache_ttl);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_affectedrows()
+ {
+ return ($this->db_connect_id) ? $this->dbo->changes() : false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_fetchrow($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_fetchrow($query_id);
+ }
+
+ return is_object($query_id) ? $query_id->fetchArray(SQLITE3_ASSOC) : false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_nextid()
+ {
+ return ($this->db_connect_id) ? $this->dbo->lastInsertRowID() : false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public 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 ($query_id)
+ {
+ return @$query_id->finalize();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sql_escape($msg)
+ {
+ return \SQLite3::escapeString($msg);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * For SQLite an underscore is a not-known character...
+ */
+ public function sql_like_expression($expression)
+ {
+ // Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it!
+ // We only catch * and ? here, not the character map possible on file globbing.
+ $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
+
+ $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
+ $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
+
+ return 'GLOB \'' . $this->sql_escape($expression) . '\'';
+ }
+
+ /**
+ * return sql error array
+ *
+ * @return array
+ */
+ protected function _sql_error()
+ {
+ if (class_exists('SQLite3', false))
+ {
+ $error = array(
+ 'message' => $this->dbo->lastErrorMsg(),
+ 'code' => $this->dbo->lastErrorCode(),
+ );
+ }
+ else
+ {
+ $error = array(
+ 'message' => $this->connect_error,
+ 'code' => '',
+ );
+ }
+
+ return $error;
+ }
+
+ /**
+ * Build db-specific query data
+ *
+ * @param string $stage Available stages: FROM, WHERE
+ * @param mixed $data A string containing the CROSS JOIN query or an array of WHERE clauses
+ *
+ * @return string The db-specific query fragment
+ */
+ protected function _sql_custom_build($stage, $data)
+ {
+ return $data;
+ }
+
+ /**
+ * Close sql connection
+ *
+ * @return bool False if failure
+ */
+ protected function _sql_close()
+ {
+ return $this->dbo->close();
+ }
+
+ /**
+ * Build db-specific report
+ *
+ * @param string $mode Available modes: display, start, stop,
+ * add_select_row, fromcache, record_fromcache
+ * @param string $query The Query that should be explained
+ * @return mixed Either a full HTML page, boolean or null
+ */
+ protected function _sql_report($mode, $query = '')
+ {
+ 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;
+
+ if ($result = $this->dbo->query("EXPLAIN QUERY PLAN $explain_query"))
+ {
+ while ($row = $result->fetchArray(SQLITE3_ASSOC))
+ {
+ $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
+ }
+ }
+
+ if ($html_table)
+ {
+ $this->html_hold .= '</table>';
+ }
+ }
+
+ break;
+
+ case 'fromcache':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $result = $this->dbo->query($query);
+ while ($void = $result->fetchArray(SQLITE3_ASSOC))
+ {
+ // Take the time spent on parsing rows into account
+ }
+
+ $splittime = explode(' ', microtime());
+ $splittime = $splittime[0] + $splittime[1];
+
+ $this->sql_report('record_fromcache', $query, $endtime, $splittime);
+
+ break;
+ }
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/beta3.php b/phpBB/phpbb/db/migration/data/v310/beta3.php
new file mode 100644
index 0000000000..de4c6f7698
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/beta3.php
@@ -0,0 +1,32 @@
+<?php
+/**
+*
+* @package migration
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License v2
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class beta3 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\beta2',
+ '\phpbb\db\migration\data\v310\auth_provider_oauth2',
+ '\phpbb\db\migration\data\v310\board_contact_name',
+ '\phpbb\db\migration\data\v310\jquery_update2',
+ '\phpbb\db\migration\data\v310\live_searches_config',
+ '\phpbb\db\migration\data\v310\prune_shadow_topics',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.1.0-b3')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/board_contact_name.php b/phpBB/phpbb/db/migration/data/v310/board_contact_name.php
new file mode 100644
index 0000000000..37b4d50545
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/board_contact_name.php
@@ -0,0 +1,30 @@
+<?php
+/**
+*
+* @package migration
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class board_contact_name extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return isset($this->config['board_contact_name']);
+ }
+
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\beta2');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.add', array('board_contact_name', '')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/live_searches_config.php b/phpBB/phpbb/db/migration/data/v310/live_searches_config.php
new file mode 100644
index 0000000000..8b147c954c
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/live_searches_config.php
@@ -0,0 +1,25 @@
+<?php
+/**
+*
+* @package migration
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class live_searches_config extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return isset($this->config['allow_live_searches']);
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.add', array('allow_live_searches', '1')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php b/phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php
new file mode 100644
index 0000000000..8fa6a3ff5b
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/reset_missing_captcha_plugin.php
@@ -0,0 +1,33 @@
+<?php
+/**
+*
+* @package migration
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+/**
+* Class captcha_plugin
+*
+* Reset the captcha setting to the default plugin if the defined 'captcha_plugin' is missing.
+*/
+class reset_missing_captcha_plugin extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\dev');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('if', array(
+ (!is_file($this->phpbb_root_path . "includes/captcha/plugins/{$this->config['captcha_plugin']}_plugin." . $this->php_ext)),
+ array('config.update', array('captcha_plugin', 'phpbb_captcha_nogd')),
+ )),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v310/timezone.php b/phpBB/phpbb/db/migration/data/v310/timezone.php
index c1da2f4998..2efedd4514 100644
--- a/phpBB/phpbb/db/migration/data/v310/timezone.php
+++ b/phpBB/phpbb/db/migration/data/v310/timezone.php
@@ -39,23 +39,48 @@ class timezone extends \phpbb\db\migration\migration
);
}
- public function update_timezones()
+ public function update_timezones($start)
{
- // Update user timezones
- $sql = 'SELECT user_dst, user_timezone
- FROM ' . $this->table_prefix . 'users
- GROUP BY user_timezone, user_dst';
- $result = $this->db->sql_query($sql);
+ $start = (int) $start;
+ $limit = 500;
+ $converted = 0;
+
+ $update_blocks = array();
+ $sql = 'SELECT user_id, user_timezone, user_dst
+ FROM ' . $this->table_prefix . 'users
+ ORDER BY user_id ASC';
+ $result = $this->db->sql_query_limit($sql, $limit, $start);
while ($row = $this->db->sql_fetchrow($result))
{
+ $converted++;
+
+ // In case this is somehow run twice on a row.
+ // Otherwise it would just end up as UTC on the second run
+ if (is_numeric($row['user_timezone']))
+ {
+ $update_blocks[$row['user_timezone'] . ':' . $row['user_dst']][] = (int) $row['user_id'];
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ // Update blocks of users who share the same timezone/dst
+ foreach ($update_blocks as $timezone => $user_ids)
+ {
+ $timezone = explode(':', $timezone);
+ $converted_timezone = $this->convert_phpbb30_timezone($timezone[0], $timezone[1]);
+
$sql = 'UPDATE ' . $this->table_prefix . "users
- SET user_timezone = '" . $this->db->sql_escape($this->convert_phpbb30_timezone($row['user_timezone'], $row['user_dst'])) . "'
- WHERE user_timezone = '" . $this->db->sql_escape($row['user_timezone']) . "'
- AND user_dst = " . (int) $row['user_dst'];
+ SET user_timezone = '" . $this->db->sql_escape($converted_timezone) . "'
+ WHERE " . $this->db->sql_in_set('user_id', $user_ids);
$this->sql_query($sql);
}
- $this->db->sql_freeresult($result);
+
+ if ($converted == $limit)
+ {
+ // There are still more to convert
+ return $start + $limit;
+ }
// Update board default timezone
$sql = 'UPDATE ' . $this->table_prefix . "config
diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php
index d3bbbc63c5..5ad8563e5c 100644
--- a/phpBB/phpbb/db/migrator.php
+++ b/phpBB/phpbb/db/migrator.php
@@ -509,10 +509,17 @@ class migrator
throw new \phpbb\db\migration\exception('MIGRATION_INVALID_DATA_CUSTOM_NOT_CALLABLE', $step);
}
- return array(
- $parameters[0],
- array($last_result),
- );
+ if ($reverse)
+ {
+ return false;
+ }
+ else
+ {
+ return array(
+ $parameters[0],
+ array($last_result),
+ );
+ }
break;
default:
diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php
index 2b0132075b..a983ed91b5 100644
--- a/phpBB/phpbb/db/tools.php
+++ b/phpBB/phpbb/db/tools.php
@@ -257,6 +257,36 @@ class tools
'VARBINARY' => 'blob',
),
+ 'sqlite3' => array(
+ 'INT:' => 'INT(%d)',
+ 'BINT' => 'BIGINT(20)',
+ 'UINT' => 'INTEGER UNSIGNED',
+ 'UINT:' => 'INTEGER UNSIGNED',
+ 'TINT:' => 'TINYINT(%d)',
+ 'USINT' => 'INTEGER UNSIGNED',
+ 'BOOL' => 'INTEGER UNSIGNED',
+ 'VCHAR' => 'VARCHAR(255)',
+ 'VCHAR:' => 'VARCHAR(%d)',
+ 'CHAR:' => 'CHAR(%d)',
+ 'XSTEXT' => 'TEXT(65535)',
+ 'STEXT' => 'TEXT(65535)',
+ 'TEXT' => 'TEXT(65535)',
+ 'MTEXT' => 'MEDIUMTEXT(16777215)',
+ 'XSTEXT_UNI'=> 'TEXT(65535)',
+ 'STEXT_UNI' => 'TEXT(65535)',
+ 'TEXT_UNI' => 'TEXT(65535)',
+ 'MTEXT_UNI' => 'MEDIUMTEXT(16777215)',
+ 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED',
+ 'DECIMAL' => 'DECIMAL(5,2)',
+ 'DECIMAL:' => 'DECIMAL(%d,2)',
+ 'PDECIMAL' => 'DECIMAL(6,3)',
+ 'PDECIMAL:' => 'DECIMAL(%d,3)',
+ 'VCHAR_UNI' => 'VARCHAR(255)',
+ 'VCHAR_UNI:'=> 'VARCHAR(%d)',
+ 'VCHAR_CI' => 'VARCHAR(255)',
+ 'VARBINARY' => 'BLOB',
+ ),
+
'postgres' => array(
'INT:' => 'INT4',
'BINT' => 'INT8',
@@ -299,7 +329,7 @@ class tools
* A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules.
* @var array
*/
- var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite');
+ var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite', 'sqlite3');
/**
* This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array).
@@ -389,6 +419,13 @@ class tools
WHERE type = "table"';
break;
+ case 'sqlite3':
+ $sql = 'SELECT name
+ FROM sqlite_master
+ WHERE type = "table"
+ AND name <> "sqlite_sequence"';
+ break;
+
case 'mssql':
case 'mssql_odbc':
case 'mssqlnative':
@@ -567,6 +604,7 @@ class tools
case 'mysql_41':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')';
break;
@@ -604,6 +642,7 @@ class tools
case 'mysql_40':
case 'sqlite':
+ case 'sqlite3':
$table_sql .= "\n);";
$statements[] = $table_sql;
break;
@@ -722,7 +761,7 @@ class tools
$sqlite = false;
// For SQLite we need to perform the schema changes in a much more different way
- if ($this->db->sql_layer == 'sqlite' && $this->return_statements)
+ if (($this->db->sql_layer == 'sqlite' || $this->db->sql_layer == 'sqlite3') && $this->return_statements)
{
$sqlite_data = array();
$sqlite = true;
@@ -1140,6 +1179,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "SELECT sql
FROM sqlite_master
WHERE type = 'table'
@@ -1273,6 +1313,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "PRAGMA index_list('" . $table_name . "');";
$col = 'name';
break;
@@ -1293,6 +1334,7 @@ class tools
case 'oracle':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
@@ -1377,6 +1419,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "PRAGMA index_list('" . $table_name . "');";
$col = 'name';
break;
@@ -1390,7 +1433,7 @@ class tools
continue;
}
- if ($this->sql_layer == 'sqlite' && !$row['unique'])
+ if (($this->sql_layer == 'sqlite' || $this->sql_layer == 'sqlite3') && !$row['unique'])
{
continue;
}
@@ -1418,6 +1461,7 @@ class tools
case 'firebird':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
@@ -1629,11 +1673,17 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$return_array['primary_key_set'] = false;
if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
{
$sql .= ' INTEGER PRIMARY KEY';
$return_array['primary_key_set'] = true;
+
+ if ($this->sql_layer === 'sqlite3')
+ {
+ $sql .= ' AUTOINCREMENT';
+ }
}
else
{
@@ -1770,67 +1820,63 @@ class tools
break;
case 'sqlite':
-
if ($inline && $this->return_statements)
{
return $column_name . ' ' . $column_data['column_type_sql'];
}
- if (version_compare(sqlite_libversion(), '3.0') == -1)
+ $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name);
+ if (empty($recreate_queries))
{
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = $this->db->sql_query($sql);
-
- if (!$result)
- {
- break;
- }
+ break;
+ }
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
+ $statements[] = 'begin';
- $statements[] = 'begin';
+ $sql_create_table = array_shift($recreate_queries);
- // Create a backup table and populate it, destroy the existing one
- $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
- $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
- $statements[] = 'DROP TABLE ' . $table_name;
+ // Create a backup table and populate it, destroy the existing one
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table);
+ $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
+ $statements[] = 'DROP TABLE ' . $table_name;
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ preg_match('#\((.*)\)#s', $sql_create_table, $matches);
- $new_table_cols = trim($matches[1]);
- $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
- $column_list = array();
+ $new_table_cols = trim($matches[1]);
+ $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
+ $column_list = array();
- foreach ($old_table_cols as $declaration)
+ foreach ($old_table_cols as $declaration)
+ {
+ $entities = preg_split('#\s+#', trim($declaration));
+ if ($entities[0] == 'PRIMARY')
{
- $entities = preg_split('#\s+#', trim($declaration));
- if ($entities[0] == 'PRIMARY')
- {
- continue;
- }
- $column_list[] = $entities[0];
+ continue;
}
+ $column_list[] = $entities[0];
+ }
- $columns = implode(',', $column_list);
+ $columns = implode(',', $column_list);
- $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols;
+ $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols;
- // create a new table and fill it up. destroy the temp one
- $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
- $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
- $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+ // create a new table and fill it up. destroy the temp one
+ $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
+ $statements = array_merge($statements, $recreate_queries);
- $statements[] = 'commit';
- }
- else
+ $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
+ $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+
+ $statements[] = 'commit';
+ break;
+
+ case 'sqlite3':
+ if ($inline && $this->return_statements)
{
- $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']';
+ return $column_name . ' ' . $column_data['column_type_sql'];
}
+
+ $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql'];
break;
}
@@ -1908,67 +1954,61 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
if ($inline && $this->return_statements)
{
return $column_name;
}
- if (version_compare(sqlite_libversion(), '3.0') == -1)
+ $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name, $column_name);
+ if (empty($recreate_queries))
{
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = $this->db->sql_query($sql);
-
- if (!$result)
- {
- break;
- }
+ break;
+ }
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
+ $statements[] = 'begin';
- $statements[] = 'begin';
+ $sql_create_table = array_shift($recreate_queries);
- // Create a backup table and populate it, destroy the existing one
- $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
- $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
- $statements[] = 'DROP TABLE ' . $table_name;
+ // Create a backup table and populate it, destroy the existing one
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table);
+ $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
+ $statements[] = 'DROP TABLE ' . $table_name;
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ preg_match('#\((.*)\)#s', $sql_create_table, $matches);
- $new_table_cols = trim($matches[1]);
- $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
- $column_list = array();
+ $new_table_cols = trim($matches[1]);
+ $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
+ $column_list = array();
- foreach ($old_table_cols as $declaration)
+ foreach ($old_table_cols as $declaration)
+ {
+ $entities = preg_split('#\s+#', trim($declaration));
+ if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name)
{
- $entities = preg_split('#\s+#', trim($declaration));
- if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name)
- {
- continue;
- }
- $column_list[] = $entities[0];
+ continue;
}
+ $column_list[] = $entities[0];
+ }
- $columns = implode(',', $column_list);
-
- $new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols);
-
- // create a new table and fill it up. destroy the temp one
- $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
- $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
- $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+ $columns = implode(',', $column_list);
- $statements[] = 'commit';
- }
- else
+ $new_table_cols = trim(preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols));
+ if (substr($new_table_cols, -1) === ',')
{
- $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name;
+ // Remove the comma from the last entry again
+ $new_table_cols = substr($new_table_cols, 0, -1);
}
+
+ // create a new table and fill it up. destroy the temp one
+ $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
+ $statements = array_merge($statements, $recreate_queries);
+
+ $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
+ $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+
+ $statements[] = 'commit';
break;
}
@@ -1998,6 +2038,7 @@ class tools
case 'oracle':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name;
break;
}
@@ -2104,35 +2145,29 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
if ($inline && $this->return_statements)
{
return $column;
}
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = $this->db->sql_query($sql);
-
- if (!$result)
+ $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name);
+ if (empty($recreate_queries))
{
break;
}
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
-
$statements[] = 'begin';
+ $sql_create_table = array_shift($recreate_queries);
+
// Create a backup table and populate it, destroy the existing one
- $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table);
$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
$statements[] = 'DROP TABLE ' . $table_name;
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ preg_match('#\((.*)\)#s', $sql_create_table, $matches);
$new_table_cols = trim($matches[1]);
$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
@@ -2152,6 +2187,8 @@ class tools
// create a new table and fill it up. destroy the temp one
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));';
+ $statements = array_merge($statements, $recreate_queries);
+
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
@@ -2182,6 +2219,7 @@ class tools
case 'postgres':
case 'oracle':
case 'sqlite':
+ case 'sqlite3':
$statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
break;
@@ -2225,6 +2263,7 @@ class tools
case 'postgres':
case 'oracle':
case 'sqlite':
+ case 'sqlite3':
$statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
break;
@@ -2316,6 +2355,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "PRAGMA index_info('" . $table_name . "');";
$col = 'name';
break;
@@ -2335,6 +2375,7 @@ class tools
case 'oracle':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
@@ -2488,35 +2529,29 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
if ($inline && $this->return_statements)
{
return $column_name . ' ' . $column_data['column_type_sql'];
}
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = $this->db->sql_query($sql);
-
- if (!$result)
+ $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name);
+ if (empty($recreate_queries))
{
break;
}
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
-
$statements[] = 'begin';
+ $sql_create_table = array_shift($recreate_queries);
+
// Create a temp table and populate it, destroy the existing one
- $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table);
$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
$statements[] = 'DROP TABLE ' . $table_name;
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ preg_match('#\((.*)\)#s', $sql_create_table, $matches);
$new_table_cols = trim($matches[1]);
$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
@@ -2534,8 +2569,10 @@ class tools
$columns = implode(',', $column_list);
- // create a new table and fill it up. destroy the temp one
+ // Create a new table and fill it up. destroy the temp one
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');';
+ $statements = array_merge($statements, $recreate_queries);
+
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
@@ -2701,4 +2738,75 @@ class tools
return $this->is_sql_server_2000;
}
+
+ /**
+ * Returns the Queries which are required to recreate a table including indexes
+ *
+ * @param string $table_name
+ * @param string $remove_column When we drop a column, we remove the column
+ * from all indexes. If the index has no other
+ * column, we drop it completly.
+ * @return array
+ */
+ protected function sqlite_get_recreate_table_queries($table_name, $remove_column = '')
+ {
+ $queries = array();
+
+ $sql = "SELECT sql
+ FROM sqlite_master
+ WHERE type = 'table'
+ AND name = '{$table_name}'";
+ $result = $this->db->sql_query($sql);
+ $sql_create_table = $this->db->sql_fetchfield('sql');
+ $this->db->sql_freeresult($result);
+
+ if (!$sql_create_table)
+ {
+ return array();
+ }
+ $queries[] = $sql_create_table;
+
+ $sql = "SELECT sql
+ FROM sqlite_master
+ WHERE type = 'index'
+ AND tbl_name = '{$table_name}'";
+ $result = $this->db->sql_query($sql);
+ while ($sql_create_index = $this->db->sql_fetchfield('sql'))
+ {
+ if ($remove_column)
+ {
+ $match = array();
+ preg_match('#(?:[\w ]+)\((.*)\)#', $sql_create_index, $match);
+ if (!isset($match[1]))
+ {
+ continue;
+ }
+
+ // Find and remove $remove_column from the index
+ $columns = explode(', ', $match[1]);
+ $found_column = array_search($remove_column, $columns);
+ if ($found_column !== false)
+ {
+ unset($columns[$found_column]);
+
+ // If the column list is not empty add the index to the list
+ if (!empty($columns))
+ {
+ $queries[] = str_replace($match[1], implode(', ', $columns), $sql_create_index);
+ }
+ }
+ else
+ {
+ $queries[] = $sql_create_index;
+ }
+ }
+ else
+ {
+ $queries[] = $sql_create_index;
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ return $queries;
+ }
}
diff --git a/phpBB/phpbb/event/kernel_request_subscriber.php b/phpBB/phpbb/event/kernel_request_subscriber.php
index 7d5418498b..a39d622273 100644
--- a/phpBB/phpbb/event/kernel_request_subscriber.php
+++ b/phpBB/phpbb/event/kernel_request_subscriber.php
@@ -18,10 +18,10 @@ use Symfony\Component\Routing\RequestContext;
class kernel_request_subscriber implements EventSubscriberInterface
{
/**
- * Extension finder object
- * @var \phpbb\extension\finder
+ * Extension manager object
+ * @var \phpbb\extension\manager
*/
- protected $finder;
+ protected $manager;
/**
* PHP extension
@@ -38,15 +38,15 @@ class kernel_request_subscriber implements EventSubscriberInterface
/**
* Construct method
*
- * @param \phpbb\extension\finder $finder Extension finder object
+ * @param \phpbb\extension\manager $manager Extension manager object
* @param string $root_path Root path
* @param string $php_ext PHP extension
*/
- public function __construct(\phpbb\extension\finder $finder, $root_path, $php_ext)
+ public function __construct(\phpbb\extension\manager $manager, $root_path, $php_ext)
{
- $this->finder = $finder;
$this->root_path = $root_path;
$this->php_ext = $php_ext;
+ $this->manager = $manager;
}
/**
@@ -55,6 +55,7 @@ class kernel_request_subscriber implements EventSubscriberInterface
* This is responsible for setting up the routing information
*
* @param GetResponseEvent $event
+ * @throws \BadMethodCallException
* @return null
*/
public function on_kernel_request(GetResponseEvent $event)
@@ -63,7 +64,7 @@ class kernel_request_subscriber implements EventSubscriberInterface
$context = new RequestContext();
$context->fromRequest($request);
- $matcher = phpbb_get_url_matcher($this->finder, $context, $this->root_path, $this->php_ext);
+ $matcher = phpbb_get_url_matcher($this->manager, $context, $this->root_path, $this->php_ext);
$router_listener = new RouterListener($matcher, $context);
$router_listener->onKernelRequest($event);
}
diff --git a/phpBB/phpbb/event/md_exporter.php b/phpBB/phpbb/event/md_exporter.php
new file mode 100644
index 0000000000..af86882885
--- /dev/null
+++ b/phpBB/phpbb/event/md_exporter.php
@@ -0,0 +1,439 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\event;
+
+/**
+* Class md_exporter
+* Crawls through a markdown file and grabs all events
+*
+* @package phpbb\event
+*/
+class md_exporter
+{
+ /** @var string Path where we look for files*/
+ protected $path;
+
+ /** @var string phpBB Root Path */
+ protected $root_path;
+
+ /** @var string */
+ protected $filter;
+
+ /** @var string */
+ protected $current_event;
+
+ /** @var array */
+ protected $events;
+
+ /**
+ * @param string $phpbb_root_path
+ * @param mixed $extension String 'vendor/ext' to filter, null for phpBB core
+ */
+ public function __construct($phpbb_root_path, $extension = null)
+ {
+ $this->root_path = $phpbb_root_path;
+ $this->path = $this->root_path;
+ if ($extension)
+ {
+ $this->path .= 'ext/' . $extension . '/';
+ }
+
+ $this->events = array();
+ $this->events_by_file = array();
+ $this->filter = $this->current_event = '';
+ }
+
+ /**
+ * Get the list of all events
+ *
+ * @return array Array with events: name => details
+ */
+ public function get_events()
+ {
+ return $this->events;
+ }
+
+ /**
+ * @param string $md_file Relative from phpBB root
+ * @return int Number of events found
+ * @throws \LogicException
+ */
+ public function crawl_phpbb_directory_adm($md_file)
+ {
+ $this->crawl_eventsmd($md_file, 'adm');
+
+ $file_list = $this->get_recursive_file_list($this->path . 'adm/style/');
+ foreach ($file_list as $file)
+ {
+ $file_name = 'adm/style/' . $file;
+ $this->validate_events_from_file($file_name, $this->crawl_file_for_events($file_name));
+ }
+
+ return sizeof($this->events);
+ }
+
+ /**
+ * @param string $md_file Relative from phpBB root
+ * @return int Number of events found
+ * @throws \LogicException
+ */
+ public function crawl_phpbb_directory_styles($md_file)
+ {
+ $this->crawl_eventsmd($md_file, 'styles');
+
+ $styles = array('prosilver', 'subsilver2');
+ foreach ($styles as $style)
+ {
+ $file_list = $this->get_recursive_file_list(
+ $this->path . 'styles/' . $style . '/template/'
+ );
+
+ foreach ($file_list as $file)
+ {
+ $file_name = 'styles/' . $style . '/template/' . $file;
+ $this->validate_events_from_file($file_name, $this->crawl_file_for_events($file_name));
+ }
+ }
+
+ return sizeof($this->events);
+ }
+
+ /**
+ * @param string $md_file Relative from phpBB root
+ * @param string $filter Should be 'styles' or 'adm'
+ * @return int Number of events found
+ * @throws \LogicException
+ */
+ public function crawl_eventsmd($md_file, $filter)
+ {
+ if (!file_exists($this->path . $md_file))
+ {
+ throw new \LogicException("The event docs file '{$md_file}' could not be found");
+ }
+
+ $file_content = file_get_contents($this->path . $md_file);
+ $this->filter = $filter;
+
+ $events = explode("\n\n", $file_content);
+ foreach ($events as $event)
+ {
+ // Last row of the file
+ if (strpos($event, "\n===\n") === false)
+ {
+ continue;
+ }
+
+ list($event_name, $details) = explode("\n===\n", $event, 2);
+ $this->validate_event_name($event_name);
+ $this->current_event = $event_name;
+
+ if (isset($this->events[$this->current_event]))
+ {
+ throw new \LogicException("The event '{$this->current_event}' is defined multiple times");
+ }
+
+ if (($this->filter == 'adm' && strpos($this->current_event, 'acp_') !== 0)
+ || ($this->filter == 'styles' && strpos($this->current_event, 'acp_') === 0))
+ {
+ continue;
+ }
+
+ list($file_details, $details) = explode("\n* Since: ", $details, 2);
+ list($since, $description) = explode("\n* Purpose: ", $details, 2);
+
+ $files = $this->validate_file_list($file_details);
+ $since = $this->validate_since($since);
+
+ $this->events[$event_name] = array(
+ 'event' => $this->current_event,
+ 'files' => $files,
+ 'since' => $since,
+ 'description' => $description,
+ );
+ }
+
+ return sizeof($this->events);
+ }
+
+ /**
+ * Format the php events as a wiki table
+ * @return string Number of events found
+ */
+ public function export_events_for_wiki()
+ {
+ if ($this->filter === 'adm')
+ {
+ $wiki_page = '= ACP Template Events =' . "\n";
+ $wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n";
+ $wiki_page .= '! Identifier !! Placement !! Added in Release !! Explanation' . "\n";
+ }
+ else
+ {
+ $wiki_page = '= Template Events =' . "\n";
+ $wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n";
+ $wiki_page .= '! Identifier !! Prosilver Placement (If applicable) !! Subsilver Placement (If applicable) !! Added in Release !! Explanation' . "\n";
+ }
+
+ foreach ($this->events as $event_name => $event)
+ {
+ $wiki_page .= "|- id=\"{$event_name}\"\n";
+ $wiki_page .= "| [[#{$event_name}|{$event_name}]] || ";
+
+ if ($this->filter === 'adm')
+ {
+ $wiki_page .= implode(', ', $event['files']['adm']);
+ }
+ else
+ {
+ $wiki_page .= implode(', ', $event['files']['prosilver']) . ' || ' . implode(', ', $event['files']['subsilver2']);
+ }
+
+ $wiki_page .= " || {$event['since']} || " . str_replace("\n", ' ', $event['description']) . "\n";
+ }
+ $wiki_page .= '|}' . "\n";
+
+ return $wiki_page;
+ }
+
+ /**
+ * Validates a template event name
+ *
+ * @param $event_name
+ * @return null
+ * @throws \LogicException
+ */
+ public function validate_event_name($event_name)
+ {
+ if (!preg_match('#^([a-z][a-z0-9]*(?:_[a-z][a-z0-9]*)+)$#', $event_name))
+ {
+ throw new \LogicException("Invalid event name '{$event_name}'");
+ }
+ }
+
+ /**
+ * Validate "Since" Information
+ *
+ * @param string $since
+ * @return string
+ * @throws \LogicException
+ */
+ public function validate_since($since)
+ {
+ if (!preg_match('#^\d+\.\d+\.\d+(?:-(?:a|b|rc|pl)\d+)?$#', $since))
+ {
+ throw new \LogicException("Invalid since information found for event '{$this->current_event}'");
+ }
+
+ return $since;
+ }
+
+ /**
+ * Validate the files list
+ *
+ * @param string $file_details
+ * @return array
+ * @throws \LogicException
+ */
+ public function validate_file_list($file_details)
+ {
+ $files_list = array(
+ 'prosilver' => array(),
+ 'subsilver2' => array(),
+ 'adm' => array(),
+ );
+
+ // Multi file list
+ if (strpos($file_details, "* Locations:\n + ") === 0)
+ {
+ $file_details = substr($file_details, strlen("* Locations:\n + "));
+ $files = explode("\n + ", $file_details);
+ foreach ($files as $file)
+ {
+ if (!file_exists($this->path . $file) || substr($file, -5) !== '.html')
+ {
+ throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 1);
+ }
+
+ if (($this->filter !== 'adm') && strpos($file, 'styles/prosilver/template/') === 0)
+ {
+ $files_list['prosilver'][] = substr($file, strlen('styles/prosilver/template/'));
+ }
+ else if (($this->filter !== 'adm') && strpos($file, 'styles/subsilver2/template/') === 0)
+ {
+ $files_list['subsilver2'][] = substr($file, strlen('styles/subsilver2/template/'));
+ }
+ else if (($this->filter === 'adm') && strpos($file, 'adm/style/') === 0)
+ {
+ $files_list['adm'][] = substr($file, strlen('adm/style/'));
+ }
+ else
+ {
+ throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 2);
+ }
+
+ $this->events_by_file[$file][] = $this->current_event;
+ }
+ }
+ else if ($this->filter == 'adm')
+ {
+ $file = substr($file_details, strlen('* Location: '));
+ if (!file_exists($this->path . $file) || substr($file, -5) !== '.html')
+ {
+ throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 1);
+ }
+
+ $files_list['adm'][] = substr($file, strlen('adm/style/'));
+
+ $this->events_by_file[$file][] = $this->current_event;
+ }
+ else
+ {
+ throw new \LogicException("Invalid file list found for event '{$this->current_event}'", 2);
+ }
+
+ return $files_list;
+ }
+
+ /**
+ * Get all template events in a template file
+ *
+ * @param string $file
+ * @return array
+ * @throws \LogicException
+ */
+ public function crawl_file_for_events($file)
+ {
+ if (!file_exists($this->path . $file))
+ {
+ throw new \LogicException("File '{$file}' does not exist", 1);
+ }
+
+ $event_list = array();
+ $file_content = file_get_contents($this->path . $file);
+
+ $events = explode('<!-- EVENT ', $file_content);
+ // Remove the code before the first event
+ array_shift($events);
+ foreach ($events as $event)
+ {
+ $event = explode(' -->', $event, 2);
+ $event_list[] = array_shift($event);
+ }
+
+ return $event_list;
+ }
+
+ /**
+ * Validates whether all events from $file are in the md file and vice-versa
+ *
+ * @param string $file
+ * @param array $events
+ * @return true
+ * @throws \LogicException
+ */
+ public function validate_events_from_file($file, array $events)
+ {
+ if (empty($this->events_by_file[$file]) && empty($events))
+ {
+ return true;
+ }
+ else if (empty($this->events_by_file[$file]))
+ {
+ $event_list = implode("', '", $events);
+ throw new \LogicException("File '{$file}' should not contain events, but contains: "
+ . "'{$event_list}'", 1);
+ }
+ else if (empty($events))
+ {
+ $event_list = implode("', '", $this->events_by_file[$file]);
+ throw new \LogicException("File '{$file}' contains no events, but should contain: "
+ . "'{$event_list}'", 1);
+ }
+
+ $missing_events_from_file = array();
+ foreach ($this->events_by_file[$file] as $event)
+ {
+ if (!in_array($event, $events))
+ {
+ $missing_events_from_file[] = $event;
+ }
+ }
+
+ if (!empty($missing_events_from_file))
+ {
+ $event_list = implode("', '", $missing_events_from_file);
+ throw new \LogicException("File '{$file}' does not contain events: '{$event_list}'", 2);
+ }
+
+ $missing_events_from_md = array();
+ foreach ($events as $event)
+ {
+ if (!in_array($event, $this->events_by_file[$file]))
+ {
+ $missing_events_from_md[] = $event;
+ }
+ }
+
+ if (!empty($missing_events_from_md))
+ {
+ $event_list = implode("', '", $missing_events_from_md);
+ throw new \LogicException("File '{$file}' contains additional events: '{$event_list}'", 3);
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of files in $dir
+ *
+ * Works recursive with any depth
+ *
+ * @param string $dir Directory to go through
+ * @return array List of files (including directories)
+ */
+ public function get_recursive_file_list($dir)
+ {
+ try
+ {
+ $iterator = new \RecursiveIteratorIterator(
+ new \phpbb\recursive_dot_prefix_filter_iterator(
+ new \RecursiveDirectoryIterator(
+ $dir,
+ \FilesystemIterator::SKIP_DOTS
+ )
+ ),
+ \RecursiveIteratorIterator::SELF_FIRST
+ );
+ }
+ catch (\Exception $e)
+ {
+ return array();
+ }
+
+ $files = array();
+ foreach ($iterator as $file_info)
+ {
+ /** @var \RecursiveDirectoryIterator $file_info */
+ if ($file_info->isDir())
+ {
+ continue;
+ }
+
+ $relative_path = $iterator->getInnerIterator()->getSubPathname();
+
+ if (substr($relative_path, -5) == '.html')
+ {
+ $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $relative_path);
+ }
+ }
+
+ return $files;
+ }
+}
diff --git a/phpBB/phpbb/event/php_exporter.php b/phpBB/phpbb/event/php_exporter.php
new file mode 100644
index 0000000000..d86ee3c045
--- /dev/null
+++ b/phpBB/phpbb/event/php_exporter.php
@@ -0,0 +1,608 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\event;
+
+/**
+* Class php_exporter
+* Crawls through a list of files and grabs all php-events
+*
+* @package phpbb\event
+*/
+class php_exporter
+{
+ /** @var string Path where we look for files*/
+ protected $path;
+
+ /** @var string phpBB Root Path */
+ protected $root_path;
+
+ /** @var string */
+ protected $current_file;
+
+ /** @var string */
+ protected $current_event;
+
+ /** @var int */
+ protected $current_event_line;
+
+ /** @var array */
+ protected $events;
+
+ /** @var array */
+ protected $file_lines;
+
+ /**
+ * @param string $phpbb_root_path
+ * @param mixed $extension String 'vendor/ext' to filter, null for phpBB core
+ */
+ public function __construct($phpbb_root_path, $extension = null)
+ {
+ $this->root_path = $phpbb_root_path;
+ $this->path = $phpbb_root_path;
+ $this->events = $this->file_lines = array();
+ $this->current_file = $this->current_event = '';
+ $this->current_event_line = 0;
+
+ $this->path = $this->root_path;
+ if ($extension)
+ {
+ $this->path .= 'ext/' . $extension . '/';
+ }
+ }
+
+ /**
+ * Get the list of all events
+ *
+ * @return array Array with events: name => details
+ */
+ public function get_events()
+ {
+ return $this->events;
+ }
+
+ /**
+ * Set current event data
+ *
+ * @param string $name Name of the current event (used for error messages)
+ * @param int $line Line where the current event is placed in
+ * @return null
+ */
+ public function set_current_event($name, $line)
+ {
+ $this->current_event = $name;
+ $this->current_event_line = $line;
+ }
+
+ /**
+ * Set the content of this file
+ *
+ * @param array $content Array with the lines of the file
+ * @return null
+ */
+ public function set_content($content)
+ {
+ $this->file_lines = $content;
+ }
+
+ /**
+ * Crawl the phpBB/ directory for php events
+ * @return int The number of events found
+ */
+ public function crawl_phpbb_directory_php()
+ {
+ $files = $this->get_recursive_file_list();
+ $this->events = array();
+ foreach ($files as $file)
+ {
+ $this->crawl_php_file($file);
+ }
+ ksort($this->events);
+
+ return sizeof($this->events);
+ }
+
+ /**
+ * Returns a list of files in $dir
+ *
+ * @return array List of files (including the path)
+ */
+ public function get_recursive_file_list()
+ {
+ try
+ {
+ $iterator = new \RecursiveIteratorIterator(
+ new \phpbb\event\recursive_event_filter_iterator(
+ new \RecursiveDirectoryIterator(
+ $this->path,
+ \FilesystemIterator::SKIP_DOTS
+ ),
+ $this->path
+ ),
+ \RecursiveIteratorIterator::LEAVES_ONLY
+ );
+ }
+ catch (\Exception $e)
+ {
+ return array();
+ }
+
+ $files = array();
+ foreach ($iterator as $file_info)
+ {
+ /** @var \RecursiveDirectoryIterator $file_info */
+ $relative_path = $iterator->getInnerIterator()->getSubPathname();
+ $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $relative_path);
+ }
+
+ return $files;
+ }
+
+ /**
+ * Format the php events as a wiki table
+ * @return string
+ */
+ public function export_events_for_wiki()
+ {
+ $wiki_page = '= PHP Events (Hook Locations) =' . "\n";
+ $wiki_page .= '{| class="sortable zebra" cellspacing="0" cellpadding="5"' . "\n";
+ $wiki_page .= '! Identifier !! Placement !! Arguments !! Added in Release !! Explanation' . "\n";
+ foreach ($this->events as $event)
+ {
+ $wiki_page .= '|- id="' . $event['event'] . '"' . "\n";
+ $wiki_page .= '| [[#' . $event['event'] . '|' . $event['event'] . ']] || ' . $event['file'] . ' || ' . implode(', ', $event['arguments']) . ' || ' . $event['since'] . ' || ' . $event['description'] . "\n";
+ }
+ $wiki_page .= '|}' . "\n";
+
+ return $wiki_page;
+ }
+
+ /**
+ * @param string $file
+ * @return int Number of events found in this file
+ * @throws \LogicException
+ */
+ public function crawl_php_file($file)
+ {
+ $this->current_file = $file;
+ $this->file_lines = array();
+ $content = file_get_contents($this->path . $this->current_file);
+ $num_events_found = 0;
+
+ if (strpos($content, "dispatcher->trigger_event('") || strpos($content, "dispatcher->dispatch('"))
+ {
+ $this->set_content(explode("\n", $content));
+ for ($i = 0, $num_lines = sizeof($this->file_lines); $i < $num_lines; $i++)
+ {
+ $event_line = false;
+ $found_trigger_event = strpos($this->file_lines[$i], "dispatcher->trigger_event('");
+ $arguments = array();
+ if ($found_trigger_event !== false)
+ {
+ $event_line = $i;
+ $this->set_current_event($this->get_event_name($event_line, false), $event_line);
+
+ // Find variables of the event
+ $arguments = $this->get_vars_from_array();
+ $doc_vars = $this->get_vars_from_docblock();
+ $this->validate_vars_docblock_array($arguments, $doc_vars);
+ }
+ else
+ {
+ $found_dispatch = strpos($this->file_lines[$i], "dispatcher->dispatch('");
+ if ($found_dispatch !== false)
+ {
+ $event_line = $i;
+ $this->set_current_event($this->get_event_name($event_line, true), $event_line);
+ }
+ }
+
+ if ($event_line)
+ {
+ // Validate @event
+ $event_line_num = $this->find_event();
+ $this->validate_event($this->current_event, $this->file_lines[$event_line_num]);
+
+ // Validate @since
+ $since_line_num = $this->find_since();
+ $since = $this->validate_since($this->file_lines[$since_line_num]);
+
+ // Find event description line
+ $description_line_num = $this->find_description();
+ $description = substr(trim($this->file_lines[$description_line_num]), strlen('* '));
+
+ if (isset($this->events[$this->current_event]))
+ {
+ throw new \LogicException("The event '{$this->current_event}' from file "
+ . "'{$this->current_file}:{$event_line_num}' already exists in file "
+ . "'{$this->events[$this->current_event]['file']}'", 10);
+ }
+
+ sort($arguments);
+ $this->events[$this->current_event] = array(
+ 'event' => $this->current_event,
+ 'file' => $this->current_file,
+ 'arguments' => $arguments,
+ 'since' => $since,
+ 'description' => $description,
+ );
+ $num_events_found++;
+ }
+ }
+ }
+
+ return $num_events_found;
+ }
+
+ /**
+ * Find the name of the event inside the dispatch() line
+ *
+ * @param int $event_line
+ * @param bool $is_dispatch Do we look for dispatch() or trigger_event() ?
+ * @return string Name of the event
+ * @throws \LogicException
+ */
+ public function get_event_name($event_line, $is_dispatch)
+ {
+ $event_text_line = $this->file_lines[$event_line];
+ $event_text_line = ltrim($event_text_line, "\t");
+
+ if ($is_dispatch)
+ {
+ $regex = '#\$([a-z](?:[a-z0-9_]|->)*)';
+ $regex .= '->dispatch\(';
+ $regex .= '\'' . $this->preg_match_event_name() . '\'';
+ $regex .= '\);#';
+ }
+ else
+ {
+ $regex = '#extract\(\$([a-z](?:[a-z0-9_]|->)*)';
+ $regex .= '->trigger_event\(';
+ $regex .= '\'' . $this->preg_match_event_name() . '\'';
+ $regex .= ', compact\(\$vars\)\)\);#';
+ }
+
+ $match = array();
+ preg_match($regex, $event_text_line, $match);
+ if (!isset($match[2]))
+ {
+ throw new \LogicException("Can not find event name in line '{$event_text_line}' "
+ . "in file '{$this->current_file}:{$event_line}'", 1);
+ }
+
+ return $match[2];
+ }
+
+ /**
+ * Returns a regex match for the event name
+ *
+ * @return string
+ */
+ protected function preg_match_event_name()
+ {
+ return '([a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+)';
+ }
+
+ /**
+ * Find the $vars array
+ *
+ * @return array List of variables
+ * @throws \LogicException
+ */
+ public function get_vars_from_array()
+ {
+ $line = ltrim($this->file_lines[$this->current_event_line - 1], "\t");
+ if ($line === ');')
+ {
+ $vars_array = $this->get_vars_from_multi_line_array();
+ }
+ else
+ {
+ $vars_array = $this->get_vars_from_single_line_array($line);
+ }
+
+ foreach ($vars_array as $var)
+ {
+ if (!preg_match('#^([a-zA-Z_][a-zA-Z0-9_]*)$#', $var))
+ {
+ throw new \LogicException("Found invalid var '{$var}' in array for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3);
+ }
+ }
+
+ sort($vars_array);
+ return $vars_array;
+ }
+
+ /**
+ * Find the variables in single line array
+ *
+ * @param string $line
+ * @param bool $throw_multiline Throw an exception when there are too
+ * many arguments in one line.
+ * @return array List of variables
+ * @throws \LogicException
+ */
+ public function get_vars_from_single_line_array($line, $throw_multiline = true)
+ {
+ $match = array();
+ preg_match('#^\$vars = array\(\'([a-zA-Z0-9_\' ,]+)\'\);$#', $line, $match);
+
+ if (isset($match[1]))
+ {
+ $vars_array = explode("', '", $match[1]);
+ if ($throw_multiline && sizeof($vars_array) > 6)
+ {
+ throw new \LogicException('Should use multiple lines for $vars definition '
+ . "for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+ return $vars_array;
+ }
+ else
+ {
+ throw new \LogicException("Can not find '\$vars = array();'-line for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
+ }
+ }
+
+ /**
+ * Find the variables in single line array
+ *
+ * @return array List of variables
+ * @throws \LogicException
+ */
+ public function get_vars_from_multi_line_array()
+ {
+ $current_vars_line = 2;
+ $var_lines = array();
+ while (ltrim($this->file_lines[$this->current_event_line - $current_vars_line], "\t") !== '$vars = array(')
+ {
+ $var_lines[] = substr(trim($this->file_lines[$this->current_event_line - $current_vars_line]), 0, -1);
+
+ $current_vars_line++;
+ if ($current_vars_line > $this->current_event_line)
+ {
+ // Reached the start of the file
+ throw new \LogicException("Can not find end of \$vars array for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+ }
+
+ return $this->get_vars_from_single_line_array('$vars = array(' . implode(", ", $var_lines) . ');', false);
+ }
+
+ /**
+ * Find the $vars array
+ *
+ * @return array List of variables
+ * @throws \LogicException
+ */
+ public function get_vars_from_docblock()
+ {
+ $doc_vars = array();
+ $current_doc_line = 1;
+ $found_comment_end = false;
+ while (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t") !== '/**')
+ {
+ if (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t") === '*/')
+ {
+ $found_comment_end = true;
+ }
+
+ if ($found_comment_end)
+ {
+ $var_line = trim($this->file_lines[$this->current_event_line - $current_doc_line]);
+ $var_line = preg_replace('!\s+!', ' ', $var_line);
+ if (strpos($var_line, '* @var ') === 0)
+ {
+ $doc_line = explode(' ', $var_line, 5);
+ if (sizeof($doc_line) !== 5)
+ {
+ throw new \LogicException("Found invalid line '{$this->file_lines[$this->current_event_line - $current_doc_line]}' "
+ . "for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
+ }
+ $doc_vars[] = $doc_line[3];
+ }
+ }
+
+ $current_doc_line++;
+ if ($current_doc_line > $this->current_event_line)
+ {
+ // Reached the start of the file
+ throw new \LogicException("Can not find end of docblock for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+ }
+
+ if (empty($doc_vars))
+ {
+ // Reached the start of the file
+ throw new \LogicException("Can not find @var lines for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3);
+ }
+
+ foreach ($doc_vars as $var)
+ {
+ if (!preg_match('#^([a-zA-Z_][a-zA-Z0-9_]*)$#', $var))
+ {
+ throw new \LogicException("Found invalid @var '{$var}' in docblock for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 4);
+ }
+ }
+
+ sort($doc_vars);
+ return $doc_vars;
+ }
+
+ /**
+ * Find the "@since" Information line
+ *
+ * @return int Absolute line number
+ * @throws \LogicException
+ */
+ public function find_since()
+ {
+ return $this->find_tag('since', array('event', 'var'));
+ }
+
+ /**
+ * Find the "@event" Information line
+ *
+ * @return int Absolute line number
+ */
+ public function find_event()
+ {
+ return $this->find_tag('event', array());
+ }
+
+ /**
+ * Find a "@*" Information line
+ *
+ * @param string $find_tag Name of the tag we are trying to find
+ * @param array $disallowed_tags List of tags that must not appear between
+ * the tag and the actual event
+ * @return int Absolute line number
+ * @throws \LogicException
+ */
+ public function find_tag($find_tag, $disallowed_tags)
+ {
+ $find_tag_line = 0;
+ $found_comment_end = false;
+ while (strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t"), '* @' . $find_tag . ' ') !== 0)
+ {
+ if ($found_comment_end && ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '/**')
+ {
+ // Reached the start of this doc block
+ throw new \LogicException("Can not find '@{$find_tag}' information for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
+ }
+
+ foreach ($disallowed_tags as $disallowed_tag)
+ {
+ if ($found_comment_end && strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t"), '* @' . $disallowed_tag) === 0)
+ {
+ // Found @var after the @since
+ throw new \LogicException("Found '@{$disallowed_tag}' information after '@{$find_tag}' for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3);
+ }
+ }
+
+ if (ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '*/')
+ {
+ $found_comment_end = true;
+ }
+
+ $find_tag_line++;
+ if ($find_tag_line >= $this->current_event_line)
+ {
+ // Reached the start of the file
+ throw new \LogicException("Can not find '@{$find_tag}' information for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+ }
+
+ return $this->current_event_line - $find_tag_line;
+ }
+
+ /**
+ * Find a "@*" Information line
+ *
+ * @return int Absolute line number
+ * @throws \LogicException
+ */
+ public function find_description()
+ {
+ $find_desc_line = 0;
+ while (ltrim($this->file_lines[$this->current_event_line - $find_desc_line], "\t") !== '/**')
+ {
+ $find_desc_line++;
+ if ($find_desc_line > $this->current_event_line)
+ {
+ // Reached the start of the file
+ throw new \LogicException("Can not find a description for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
+ }
+ }
+
+ $find_desc_line = $this->current_event_line - $find_desc_line + 1;
+
+ $desc = trim($this->file_lines[$find_desc_line]);
+ if (strpos($desc, '* @') === 0 || $desc[0] !== '*' || substr($desc, 1) == '')
+ {
+ // First line of the doc block is a @-line, empty or only contains "*"
+ throw new \LogicException("Can not find a description for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+
+ return $find_desc_line;
+ }
+
+ /**
+ * Validate "@since" Information
+ *
+ * @param string $line
+ * @return string
+ * @throws \LogicException
+ */
+ public function validate_since($line)
+ {
+ $match = array();
+ preg_match('#^\* @since (\d+\.\d+\.\d+(?:-(?:a|b|rc|pl)\d+)?)$#', ltrim($line, "\t"), $match);
+ if (!isset($match[1]))
+ {
+ throw new \LogicException("Invalid '@since' information for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'");
+ }
+
+ return $match[1];
+ }
+
+ /**
+ * Validate "@event" Information
+ *
+ * @param string $event_name
+ * @param string $line
+ * @return string
+ * @throws \LogicException
+ */
+ public function validate_event($event_name, $line)
+ {
+ $event = substr(ltrim($line, "\t"), strlen('* @event '));
+
+ if ($event !== trim($event))
+ {
+ throw new \LogicException("Invalid '@event' information for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
+ }
+
+ if ($event !== $event_name)
+ {
+ throw new \LogicException("Event name does not match '@event' tag for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
+ }
+
+ return $event;
+ }
+
+ /**
+ * Validates that two arrays contain the same strings
+ *
+ * @param array $vars_array Variables found in the array line
+ * @param array $vars_docblock Variables found in the doc block
+ * @return null
+ * @throws \LogicException
+ */
+ public function validate_vars_docblock_array($vars_array, $vars_docblock)
+ {
+ $vars_array = array_unique($vars_array);
+ $vars_docblock = array_unique($vars_docblock);
+ $sizeof_vars_array = sizeof($vars_array);
+
+ if ($sizeof_vars_array !== sizeof($vars_docblock) || $sizeof_vars_array !== sizeof(array_intersect($vars_array, $vars_docblock)))
+ {
+ throw new \LogicException("\$vars array does not match the list of '@var' tags for event "
+ . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'");
+ }
+ }
+}
diff --git a/phpBB/phpbb/event/recursive_event_filter_iterator.php b/phpBB/phpbb/event/recursive_event_filter_iterator.php
new file mode 100644
index 0000000000..ef2f2ec0ed
--- /dev/null
+++ b/phpBB/phpbb/event/recursive_event_filter_iterator.php
@@ -0,0 +1,70 @@
+<?php
+/**
+*
+* @package event
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\event;
+
+/**
+* Class recursive_event_filter_iterator
+*
+* This filter ignores directories and files starting with a dot.
+* It also skips some directories that do not contain events anyway,
+* such as e.g. files/, store/ and vendor/
+*
+* @package phpbb\event
+*/
+class recursive_event_filter_iterator extends \RecursiveFilterIterator
+{
+ protected $root_path;
+
+ /**
+ * Construct
+ *
+ * @param \RecursiveIterator $iterator
+ * @param string $root_path
+ */
+ public function __construct(\RecursiveIterator $iterator, $root_path)
+ {
+ $this->root_path = str_replace(DIRECTORY_SEPARATOR, '/', $root_path);
+ parent::__construct($iterator);
+ }
+
+ /**
+ * Return the inner iterator's children contained in a recursive_event_filter_iterator
+ *
+ * @return recursive_event_filter_iterator
+ */
+ public function getChildren() {
+ return new self($this->getInnerIterator()->getChildren(), $this->root_path);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function accept()
+ {
+ $relative_path = str_replace(DIRECTORY_SEPARATOR, '/', $this->current());
+ $filename = $this->current()->getFilename();
+
+ return (substr($relative_path, -4) === '.php' || $this->current()->isDir())
+ && $filename[0] !== '.'
+ && strpos($relative_path, $this->root_path . 'cache/') !== 0
+ && strpos($relative_path, $this->root_path . 'develop/') !== 0
+ && strpos($relative_path, $this->root_path . 'docs/') !== 0
+ && strpos($relative_path, $this->root_path . 'ext/') !== 0
+ && strpos($relative_path, $this->root_path . 'files/') !== 0
+ && strpos($relative_path, $this->root_path . 'includes/utf/') !== 0
+ && strpos($relative_path, $this->root_path . 'language/') !== 0
+ && strpos($relative_path, $this->root_path . 'phpbb/db/migration/data/') !== 0
+ && strpos($relative_path, $this->root_path . 'phpbb/event/') !== 0
+ && strpos($relative_path, $this->root_path . 'store/') !== 0
+ && strpos($relative_path, $this->root_path . 'tests/') !== 0
+ && strpos($relative_path, $this->root_path . 'vendor/') !== 0
+ ;
+ }
+}
diff --git a/phpBB/phpbb/feed/attachments_base.php b/phpBB/phpbb/feed/attachments_base.php
new file mode 100644
index 0000000000..a9a8175928
--- /dev/null
+++ b/phpBB/phpbb/feed/attachments_base.php
@@ -0,0 +1,83 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2014 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\feed;
+
+/**
+* Abstract class for feeds displaying attachments
+*
+* @package phpBB3
+*/
+abstract class attachments_base extends \phpbb\feed\base
+{
+ /**
+ * Attachments that may be displayed
+ */
+ protected $attachments = array();
+
+ /**
+ * Retrieve the list of attachments that may be displayed
+ */
+ protected function fetch_attachments()
+ {
+ $sql_array = array(
+ 'SELECT' => 'a.*',
+ 'FROM' => array(
+ ATTACHMENTS_TABLE => 'a'
+ ),
+ 'WHERE' => 'a.in_message = 0 ',
+ 'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC',
+ );
+
+ if (isset($this->topic_id))
+ {
+ $sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id;
+ }
+ else if (isset($this->forum_id))
+ {
+ $sql_array['LEFT_JOIN'] = array(
+ array(
+ 'FROM' => array(TOPICS_TABLE => 't'),
+ 'ON' => 'a.topic_id = t.topic_id',
+ )
+ );
+ $sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id;
+ }
+
+ $sql = $this->db->sql_build_query('SELECT', $sql_array);
+ $result = $this->db->sql_query($sql);
+
+ // Set attachments in feed items
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $this->attachments[$row['post_msg_id']][] = $row;
+ }
+ $this->db->sql_freeresult($result);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function open()
+ {
+ parent::open();
+ $this->fetch_attachments();
+ }
+
+ /**
+ * Get attachments related to a given post
+ *
+ * @param $post_id int Post id
+ * @return mixed Attachments related to $post_id
+ */
+ public function get_attachments($post_id)
+ {
+ return $this->attachments[$post_id];
+ }
+}
diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php
index 85ecb60f7e..e35ec4baa4 100644
--- a/phpBB/phpbb/feed/forum.php
+++ b/phpBB/phpbb/feed/forum.php
@@ -80,6 +80,8 @@ class forum extends \phpbb\feed\post_base
unset($forum_ids_passworded);
}
+
+ parent::open();
}
function get_sql()
@@ -130,6 +132,7 @@ class forum extends \phpbb\feed\post_base
parent::adjust_item($item_row, $row);
$item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
+ $item_row['forum_id'] = $this->forum_id;
}
function get_item()
diff --git a/phpBB/phpbb/feed/news.php b/phpBB/phpbb/feed/news.php
index 1b7c452a92..2242525db6 100644
--- a/phpBB/phpbb/feed/news.php
+++ b/phpBB/phpbb/feed/news.php
@@ -64,9 +64,8 @@ class news extends \phpbb\feed\topic_base
// We really have to get the post ids first!
$sql = 'SELECT topic_first_post_id, topic_time
FROM ' . TOPICS_TABLE . '
- WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
- AND topic_moved_id = 0
- AND topic_visibility = ' . ITEM_APPROVED . '
+ WHERE topic_moved_id = 0
+ AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $in_fid_ary) . '
ORDER BY topic_time DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
@@ -85,7 +84,7 @@ class news extends \phpbb\feed\topic_base
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, t.topic_visibility',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
diff --git a/phpBB/phpbb/feed/post_base.php b/phpBB/phpbb/feed/post_base.php
index c797d6a8ca..cfcd8671a3 100644
--- a/phpBB/phpbb/feed/post_base.php
+++ b/phpBB/phpbb/feed/post_base.php
@@ -14,7 +14,7 @@ namespace phpbb\feed;
*
* @package phpBB3
*/
-abstract class post_base extends \phpbb\feed\base
+abstract class post_base extends \phpbb\feed\attachments_base
{
var $num_items = 'feed_limit_post';
var $attachments = array();
@@ -46,44 +46,8 @@ abstract class post_base extends \phpbb\feed\base
{
$item_row['statistics'] = $this->user->lang['POSTED'] . ' ' . $this->user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row)
. ' ' . $this->separator_stats . ' ' . $this->user->format_date($row[$this->get('published')])
- . (($this->is_moderator_approve_forum($row['forum_id']) && $row['post_visibility'] !== ITEM_APPROVED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : '');
+ . (($this->is_moderator_approve_forum($row['forum_id']) && (int)$row['post_visibility'] === ITEM_UNAPPROVED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : '')
+ . (($this->is_moderator_approve_forum($row['forum_id']) && (int)$row['post_visibility'] === ITEM_DELETED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_DELETED'] : '');
}
}
-
- function fetch_attachments()
- {
- $sql_array = array(
- 'SELECT' => 'a.*',
- 'FROM' => array(
- ATTACHMENTS_TABLE => 'a'
- ),
- 'WHERE' => 'a.in_message = 0 ',
- 'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC',
- );
-
- if (isset($this->topic_id))
- {
- $sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id;
- }
- else if (isset($this->forum_id))
- {
- $sql_array['LEFT_JOIN'] = array(
- array(
- 'FROM' => array(TOPICS_TABLE => 't'),
- 'ON' => 'a.topic_id = t.topic_id',
- )
- );
- $sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id;
- }
-
- $sql = $this->db->sql_build_query('SELECT', $sql_array);
- $result = $this->db->sql_query($sql);
-
- // Set attachments in feed items
- while ($row = $this->db->sql_fetchrow($result))
- {
- $this->attachments[$row['post_msg_id']][] = $row;
- }
- $this->db->sql_freeresult($result);
- }
}
diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php
index a7acfb502f..10b0f4f645 100644
--- a/phpBB/phpbb/feed/topic.php
+++ b/phpBB/phpbb/feed/topic.php
@@ -83,6 +83,8 @@ class topic extends \phpbb\feed\post_base
unset($forum_ids_passworded);
}
+
+ parent::open();
}
function get_sql()
@@ -103,6 +105,13 @@ class topic extends \phpbb\feed\post_base
return true;
}
+ function adjust_item(&$item_row, &$row)
+ {
+ parent::adjust_item($item_row, $row);
+
+ $item_row['forum_id'] = $this->forum_id;
+ }
+
function get_item()
{
return ($row = parent::get_item()) ? array_merge($this->topic_data, $row) : $row;
diff --git a/phpBB/phpbb/feed/topic_base.php b/phpBB/phpbb/feed/topic_base.php
index 7e28e67b82..d25bd0b50f 100644
--- a/phpBB/phpbb/feed/topic_base.php
+++ b/phpBB/phpbb/feed/topic_base.php
@@ -14,7 +14,7 @@ namespace phpbb\feed;
*
* @package phpBB3
*/
-abstract class topic_base extends \phpbb\feed\base
+abstract class topic_base extends \phpbb\feed\attachments_base
{
var $num_items = 'feed_limit_topic';
@@ -45,9 +45,24 @@ abstract class topic_base extends \phpbb\feed\base
{
$item_row['statistics'] = $this->user->lang['POSTED'] . ' ' . $this->user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row)
. ' ' . $this->separator_stats . ' ' . $this->user->format_date($row[$this->get('published')])
- . ' ' . $this->separator_stats . ' ' . $this->user->lang['REPLIES'] . ' ' . $this->content_visibility->get_count('topic_posts', $row, $row['forum_id']) - 1
- . ' ' . $this->separator_stats . ' ' . $this->user->lang['VIEWS'] . ' ' . $row['topic_views']
- . (($this->is_moderator_approve_forum($row['forum_id']) && $row['topic_posts_unapproved']) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POSTS_UNAPPROVED'] : '');
+ . ' ' . $this->separator_stats . ' ' . $this->user->lang['REPLIES'] . ' ' . ($this->content_visibility->get_count('topic_posts', $row, $row['forum_id']) - 1)
+ . ' ' . $this->separator_stats . ' ' . $this->user->lang['VIEWS'] . ' ' . $row['topic_views'];
+
+ if ($this->is_moderator_approve_forum($row['forum_id']))
+ {
+ if ( (int)$row['topic_visibility'] === ITEM_DELETED)
+ {
+ $item_row['statistics'] .= ' ' . $this->separator_stats . ' ' . $this->user->lang['TOPIC_DELETED'];
+ }
+ else if ((int)$row['topic_visibility'] === ITEM_UNAPPROVED)
+ {
+ $item_row['statistics'] .= ' ' . $this->separator_stats . ' ' . $this->user->lang['TOPIC_UNAPPROVED'];
+ }
+ else if ($row['topic_posts_unapproved'])
+ {
+ $item_row['statistics'] .= ' ' . $this->separator_stats . ' ' . $this->user->lang['POSTS_UNAPPROVED'];
+ }
+ }
}
}
}
diff --git a/phpBB/phpbb/feed/topics.php b/phpBB/phpbb/feed/topics.php
index e8b9f6de6c..b6d9ec7cc6 100644
--- a/phpBB/phpbb/feed/topics.php
+++ b/phpBB/phpbb/feed/topics.php
@@ -36,9 +36,8 @@ class topics extends \phpbb\feed\topic_base
// We really have to get the post ids first!
$sql = 'SELECT topic_first_post_id, topic_time
FROM ' . TOPICS_TABLE . '
- WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
- AND topic_moved_id = 0
- AND topic_visibility = ' . ITEM_APPROVED . '
+ WHERE topic_moved_id = 0
+ AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $in_fid_ary) . '
ORDER BY topic_time DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
@@ -57,7 +56,7 @@ class topics extends \phpbb\feed\topic_base
$this->sql = array(
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, t.topic_visibility',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php
index 809a536c2a..c7234510fb 100644
--- a/phpBB/phpbb/feed/topics_active.php
+++ b/phpBB/phpbb/feed/topics_active.php
@@ -51,9 +51,8 @@ class topics_active extends \phpbb\feed\topic_base
// We really have to get the post ids first!
$sql = 'SELECT topic_last_post_id, topic_last_post_time
FROM ' . TOPICS_TABLE . '
- WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
- AND topic_moved_id = 0
- AND topic_visibility = ' . ITEM_APPROVED . '
+ WHERE topic_moved_id = 0
+ AND ' . $this->content_visibility->get_forums_visibility_sql('topic', $in_fid_ary) . '
' . $last_post_time_sql . '
ORDER BY topic_last_post_time DESC';
$result = $this->db->sql_query_limit($sql, $this->num_items);
@@ -74,7 +73,7 @@ class topics_active extends \phpbb\feed\topic_base
'SELECT' => 'f.forum_id, f.forum_name,
t.topic_id, t.topic_title, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views,
t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_post_time,
- p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment',
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, t.topic_visibility',
'FROM' => array(
TOPICS_TABLE => 't',
POSTS_TABLE => 'p',
diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php
index e38950f4c1..e4c5ce47d9 100644
--- a/phpBB/phpbb/log/log.php
+++ b/phpBB/phpbb/log/log.php
@@ -305,9 +305,17 @@ class log implements \phpbb\log\log_interface
* @var array sql_ary Array with log data we insert into the
* database. If sql_ary[log_type] is not set,
* we won't add the entry to the database.
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
- $vars = array('mode', 'user_id', 'log_ip', 'log_operation', 'log_time', 'additional_data', 'sql_ary');
+ $vars = array(
+ 'mode',
+ 'user_id',
+ 'log_ip',
+ 'log_operation',
+ 'log_time',
+ 'additional_data',
+ 'sql_ary',
+ );
extract($this->dispatcher->trigger_event('core.add_log', compact($vars)));
// We didn't find a log_type, so we don't save it in the database.
@@ -403,9 +411,23 @@ class log implements \phpbb\log\log_interface
* is false, no entries will be returned.
* @var string sql_additional Additional conditions for the entries,
* e.g.: 'AND l.forum_id = 1'
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
- $vars = array('mode', 'count_logs', 'limit', 'offset', 'forum_id', 'topic_id', 'user_id', 'log_time', 'sort_by', 'keywords', 'profile_url', 'log_type', 'sql_additional');
+ $vars = array(
+ 'mode',
+ 'count_logs',
+ 'limit',
+ 'offset',
+ 'forum_id',
+ 'topic_id',
+ 'user_id',
+ 'log_time',
+ 'sort_by',
+ 'keywords',
+ 'profile_url',
+ 'log_type',
+ 'sql_additional',
+ );
extract($this->dispatcher->trigger_event('core.get_logs_modify_type', compact($vars)));
if ($log_type === false)
@@ -499,7 +521,7 @@ class log implements \phpbb\log\log_interface
* @event core.get_logs_modify_entry_data
* @var array row Entry data from the database
* @var array log_entry_data Entry's data which is returned
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('row', 'log_entry_data');
extract($this->dispatcher->trigger_event('core.get_logs_modify_entry_data', compact($vars)));
@@ -520,7 +542,7 @@ class log implements \phpbb\log\log_interface
$num_args = 0;
if (!is_array($this->user->lang[$row['log_operation']]))
{
- $num_args = substr_count($log[$i]['action'], '%');
+ $num_args = substr_count($this->user->lang[$row['log_operation']], '%');
}
else
{
@@ -576,7 +598,7 @@ class log implements \phpbb\log\log_interface
* get the permission data
* @var array reportee_id_list Array of additional user IDs we
* get the username strings for
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('log', 'topic_id_list', 'reportee_id_list');
extract($this->dispatcher->trigger_event('core.get_logs_get_additional_data', compact($vars)));
diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php
index e51ff12b3e..5912ad62b4 100644
--- a/phpBB/phpbb/notification/type/approve_post.php
+++ b/phpBB/phpbb/notification/type/approve_post.php
@@ -138,4 +138,12 @@ class approve_post extends \phpbb\notification\type\post
{
return 'post_approved';
}
+
+ /**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return $this->get_url();
+ }
}
diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php
index 0719540bdb..7d08521d40 100644
--- a/phpBB/phpbb/notification/type/base.php
+++ b/phpBB/phpbb/notification/type/base.php
@@ -276,6 +276,14 @@ abstract class base implements \phpbb\notification\type\type_interface
}
/**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return $this->get_url();
+ }
+
+ /**
* Prepare to output the notification to the template
*
* @return array Template variables
diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php
index 003998677d..c981695f74 100644
--- a/phpBB/phpbb/notification/type/bookmark.php
+++ b/phpBB/phpbb/notification/type/bookmark.php
@@ -110,10 +110,14 @@ class bookmark extends \phpbb\notification\type\post
unset($notify_users[$row['user_id']]);
$notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
- $sql = 'UPDATE ' . $this->notifications_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . '
- WHERE notification_id = ' . $row['notification_id'];
- $this->db->sql_query($sql);
+ $update_responders = $notification->add_responders($post);
+ if (!empty($update_responders))
+ {
+ $sql = 'UPDATE ' . $this->notifications_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . '
+ WHERE notification_id = ' . $row['notification_id'];
+ $this->db->sql_query($sql);
+ }
}
$this->db->sql_freeresult($result);
diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php
index f973becc3b..93fbcbde22 100644
--- a/phpBB/phpbb/notification/type/post.php
+++ b/phpBB/phpbb/notification/type/post.php
@@ -152,10 +152,14 @@ class post extends \phpbb\notification\type\base
unset($notify_users[$row['user_id']]);
$notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
- $sql = 'UPDATE ' . $this->notifications_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . '
- WHERE notification_id = ' . $row['notification_id'];
- $this->db->sql_query($sql);
+ $update_responders = $notification->add_responders($post);
+ if (!empty($update_responders))
+ {
+ $sql = 'UPDATE ' . $this->notifications_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . '
+ WHERE notification_id = ' . $row['notification_id'];
+ $this->db->sql_query($sql);
+ }
}
$this->db->sql_freeresult($result);
@@ -206,7 +210,11 @@ class post extends \phpbb\notification\type\base
}
}
- if ($trimmed_responders_cnt)
+ if ($trimmed_responders_cnt > 20)
+ {
+ $usernames[] = $this->user->lang('NOTIFICATION_MANY_OTHERS');
+ }
+ else if ($trimmed_responders_cnt)
{
$usernames[] = $this->user->lang('NOTIFICATION_X_OTHERS', $trimmed_responders_cnt);
}
@@ -270,6 +278,14 @@ class post extends \phpbb\notification\type\base
}
/**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "t={$this->item_parent_id}&amp;view=unread#unread");
+ }
+
+ /**
* Users needed to query before this notification can be displayed
*
* @return array Array of user_ids
@@ -384,19 +400,27 @@ class post extends \phpbb\notification\type\base
// Do not add them as a responder if they were the original poster that created the notification
if ($this->get_data('poster_id') == $post['poster_id'])
{
- return array('notification_data' => serialize($this->get_data(false)));
+ return array();
}
$responders = $this->get_data('responders');
$responders = ($responders === null) ? array() : $responders;
+ // Do not add more than 25 responders,
+ // we trim the username list to "a, b, c and x others" anyway
+ // so there is no use to add all of them anyway.
+ if (sizeof($responders) > 25)
+ {
+ return array();
+ }
+
foreach ($responders as $responder)
{
// Do not add them as a responder multiple times
if ($responder['poster_id'] == $post['poster_id'])
{
- return array('notification_data' => serialize($this->get_data(false)));
+ return array();
}
}
@@ -407,6 +431,15 @@ class post extends \phpbb\notification\type\base
$this->set_data('responders', $responders);
- return array('notification_data' => serialize($this->get_data(false)));
+ $serialized_data = serialize($this->get_data(false));
+
+ // If the data is longer then 4000 characters, it would cause a SQL error.
+ // We don't add the username to the list if this is the case.
+ if (utf8_strlen($serialized_data) >= 4000)
+ {
+ return array();
+ }
+
+ return array('notification_data' => $serialized_data);
}
}
diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php
index db16763583..56dfcce588 100644
--- a/phpBB/phpbb/notification/type/post_in_queue.php
+++ b/phpBB/phpbb/notification/type/post_in_queue.php
@@ -119,6 +119,14 @@ class post_in_queue extends \phpbb\notification\type\post
}
/**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return parent::get_url();
+ }
+
+ /**
* Function for preparing the data for insertion in an SQL query
* (The service handles insertion)
*
diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php
index 745430e114..f4b4d763eb 100644
--- a/phpBB/phpbb/notification/type/quote.php
+++ b/phpBB/phpbb/notification/type/quote.php
@@ -113,29 +113,6 @@ class quote extends \phpbb\notification\type\post
$notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options);
- // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
- $update_notifications = array();
- $sql = 'SELECT n.*
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
- WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
- AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
- AND n.notification_read = 0
- AND nt.notification_type_id = n.notification_type_id
- AND nt.notification_type_enabled = 1';
- $result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
- {
- // Do not create a new notification
- unset($notify_users[$row['user_id']]);
-
- $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
- $sql = 'UPDATE ' . $this->notifications_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . '
- WHERE notification_id = ' . $row['notification_id'];
- $this->db->sql_query($sql);
- }
- $this->db->sql_freeresult($result);
-
return $notify_users;
}
@@ -191,6 +168,14 @@ class quote extends \phpbb\notification\type\post
}
/**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return $this->get_url();
+ }
+
+ /**
* Get email template
*
* @return string|bool
diff --git a/phpBB/phpbb/notification/type/type_interface.php b/phpBB/phpbb/notification/type/type_interface.php
index e3e6898172..2f465aae2b 100644
--- a/phpBB/phpbb/notification/type/type_interface.php
+++ b/phpBB/phpbb/notification/type/type_interface.php
@@ -99,6 +99,13 @@ interface type_interface
public function get_url();
/**
+ * Get the url to redirect after the item has been marked as read
+ *
+ * @return string URL
+ */
+ public function get_redirect_url();
+
+ /**
* URL to unsubscribe to this notification
*
* @param string|bool $method Method name to unsubscribe from (email|jabber|etc), False to unsubscribe from all notifications for this item
diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php
index fefef39c51..f92c2b72b2 100644
--- a/phpBB/phpbb/path_helper.php
+++ b/phpBB/phpbb/path_helper.php
@@ -216,4 +216,120 @@ class path_helper
return $scheme . $this->filesystem->clean_path($path);
}
+
+ /**
+ * Glue URL parameters together
+ *
+ * @param array $params URL parameters in the form of array(name => value)
+ * @return string Returns the glued string, e.g. name1=value1&amp;name2=value2
+ */
+ public function glue_url_params($params)
+ {
+ $_params = array();
+
+ foreach ($params as $key => $value)
+ {
+ $_params[] = $key . '=' . $value;
+ }
+ return implode('&amp;', $_params);
+ }
+
+ /**
+ * Get the base and parameters of a URL
+ *
+ * @param string $url URL to break apart
+ * @param bool $is_amp Is the parameter separator &amp;. Defaults to true.
+ * @return array Returns the base and parameters in the form of array('base' => string, 'params' => array(name => value))
+ */
+ public function get_url_parts($url, $is_amp = true)
+ {
+ $separator = ($is_amp) ? '&amp;' : '&';
+ $params = array();
+
+ if (strpos($url, '?') !== false)
+ {
+ $base = substr($url, 0, strpos($url, '?'));
+ $args = substr($url, strlen($base) + 1);
+ $args = ($args) ? explode($separator, $args) : array();
+
+ foreach ($args as $argument)
+ {
+ if (empty($argument))
+ {
+ continue;
+ }
+ list($key, $value) = explode('=', $argument, 2);
+
+ if ($key === '')
+ {
+ continue;
+ }
+
+ $params[$key] = $value;
+ }
+ }
+ else
+ {
+ $base = $url;
+ }
+
+ return array(
+ 'base' => $base,
+ 'params' => $params,
+ );
+ }
+
+ /**
+ * Strip parameters from an already built URL.
+ *
+ * @param string $url URL to strip parameters from
+ * @param array|string $strip Parameters to strip.
+ * @param bool $is_amp Is the parameter separator &amp;. Defaults to true.
+ * @return string Returns the new URL.
+ */
+ public function strip_url_params($url, $strip, $is_amp = true)
+ {
+ $url_parts = $this->get_url_parts($url, $is_amp);
+ $params = $url_parts['params'];
+
+ if (!is_array($strip))
+ {
+ $strip = array($strip);
+ }
+
+ if (!empty($params))
+ {
+ // Strip the parameters off
+ foreach ($strip as $param)
+ {
+ unset($params[$param]);
+ }
+ }
+
+ return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : '');
+ }
+
+ /**
+ * Append parameters to an already built URL.
+ *
+ * @param string $url URL to append parameters to
+ * @param array $new_params Parameters to add in the form of array(name => value)
+ * @param string $is_amp Is the parameter separator &amp;. Defaults to true.
+ * @return string Returns the new URL.
+ */
+ public function append_url_params($url, $new_params, $is_amp = true)
+ {
+ $url_parts = $this->get_url_parts($url, $is_amp);
+ $params = array_merge($url_parts['params'], $new_params);
+
+ // Move the sid to the end if it's set
+ if (isset($params['sid']))
+ {
+ $sid = $params['sid'];
+ unset($params['sid']);
+ $params['sid'] = $sid;
+ }
+
+ return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : '');
+ }
}
diff --git a/phpBB/phpbb/permissions.php b/phpBB/phpbb/permissions.php
index a3fddb0b9e..3cf39b5126 100644
--- a/phpBB/phpbb/permissions.php
+++ b/phpBB/phpbb/permissions.php
@@ -57,7 +57,7 @@ class permissions
* 'lang' => 'ACL_U_VIEWPROFILE',
* 'cat' => 'profile',
* ),
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('types', 'categories', 'permissions');
extract($phpbb_dispatcher->trigger_event('core.permissions', compact($vars)));
diff --git a/phpBB/phpbb/profilefields/manager.php b/phpBB/phpbb/profilefields/manager.php
index 37449c67c4..7d545a5f72 100644
--- a/phpBB/phpbb/profilefields/manager.php
+++ b/phpBB/phpbb/profilefields/manager.php
@@ -28,6 +28,12 @@ class manager
protected $db;
/**
+ * Event dispatcher object
+ * @var \phpbb\event\dispatcher
+ */
+ protected $dispatcher;
+
+ /**
* Request object
* @var \phpbb\request\request
*/
@@ -64,6 +70,7 @@ class manager
*
* @param \phpbb\auth\auth $auth Auth object
* @param \phpbb\db\driver\driver_interface $db Database object
+ * @param \phpbb\event\dispatcher $dispatcher Event dispatcher object
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\di\service_collection $type_collection
@@ -72,10 +79,11 @@ class manager
* @param string $fields_language_table
* @param string $fields_data_table
*/
- public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\di\service_collection $type_collection, \phpbb\user $user, $fields_table, $fields_language_table, $fields_data_table)
+ public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\event\dispatcher $dispatcher, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\di\service_collection $type_collection, \phpbb\user $user, $fields_table, $fields_language_table, $fields_data_table)
{
$this->auth = $auth;
$this->db = $db;
+ $this->dispatcher = $dispatcher;
$this->request = $request;
$this->template = $template;
$this->type_collection = $type_collection;
@@ -313,6 +321,17 @@ class manager
}
$this->db->sql_freeresult($result);
+ /**
+ * Event to modify profile fields data retrieved from the database
+ *
+ * @event core.grab_profile_fields_data
+ * @var array user_ids Single user id or an array of ids
+ * @var array field_data Array with profile fields data
+ * @since 3.1.0-b3
+ */
+ $vars = array('user_ids', 'field_data');
+ extract($this->dispatcher->trigger_event('core.grab_profile_fields_data', compact($vars)));
+
$user_fields = array();
// Go through the fields in correct order
@@ -351,6 +370,18 @@ class manager
$tpl_fields = array();
$tpl_fields['row'] = $tpl_fields['blockrow'] = array();
+ /**
+ * Event to modify data of the generated profile fields, before the template assignment loop
+ *
+ * @event core.generate_profile_fields_template_data_before
+ * @var array profile_row Array with users profile field data
+ * @var array tpl_fields Array with template data fields
+ * @var bool use_contact_fields Should we display contact fields as such?
+ * @since 3.1.0-b3
+ */
+ $vars = array('profile_row', 'tpl_fields', 'use_contact_fields');
+ extract($this->dispatcher->trigger_event('core.generate_profile_fields_template_data_before', compact($vars)));
+
foreach ($profile_row as $ident => $ident_ary)
{
$profile_field = $this->type_collection[$ident_ary['data']['field_type']];
@@ -404,6 +435,18 @@ class manager
);
}
+ /**
+ * Event to modify template data of the generated profile fields
+ *
+ * @event core.generate_profile_fields_template_data
+ * @var array profile_row Array with users profile field data
+ * @var array tpl_fields Array with template data fields
+ * @var bool use_contact_fields Should we display contact fields as such?
+ * @since 3.1.0-b3
+ */
+ $vars = array('profile_row', 'tpl_fields', 'use_contact_fields');
+ extract($this->dispatcher->trigger_event('core.generate_profile_fields_template_data', compact($vars)));
+
return $tpl_fields;
}
diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php
index 7d51d164c7..f3b229cc7c 100644
--- a/phpBB/phpbb/search/fulltext_native.php
+++ b/phpBB/phpbb/search/fulltext_native.php
@@ -768,6 +768,7 @@ class fulltext_native extends \phpbb\search\base
break;
case 'sqlite':
+ case 'sqlite3':
$sql_array_count['SELECT'] = ($type == 'posts') ? 'DISTINCT p.post_id' : 'DISTINCT p.topic_id';
$sql = 'SELECT COUNT(' . (($type == 'posts') ? 'post_id' : 'topic_id') . ') as total_results
FROM (' . $this->db->sql_build_query('SELECT', $sql_array_count) . ')';
@@ -997,7 +998,7 @@ class fulltext_native extends \phpbb\search\base
}
else
{
- if ($this->db->sql_layer == 'sqlite')
+ if ($this->db->sql_layer == 'sqlite' || $this->db->sql_layer == 'sqlite3')
{
$sql = 'SELECT COUNT(topic_id) as total_results
FROM (SELECT DISTINCT t.topic_id';
@@ -1014,7 +1015,7 @@ class fulltext_native extends \phpbb\search\base
$post_visibility
$sql_fora
AND t.topic_id = p.topic_id
- $sql_time" . (($this->db->sql_layer == 'sqlite') ? ')' : '');
+ $sql_time" . (($this->db->sql_layer == 'sqlite' || $this->db->sql_layer == 'sqlite3') ? ')' : '');
}
$result = $this->db->sql_query($sql);
@@ -1481,6 +1482,7 @@ class fulltext_native extends \phpbb\search\base
switch ($this->db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
case 'firebird':
$this->db->sql_query('DELETE FROM ' . SEARCH_WORDLIST_TABLE);
$this->db->sql_query('DELETE FROM ' . SEARCH_WORDMATCH_TABLE);
diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php
index f530d30f1f..ea421ffcf3 100644
--- a/phpBB/phpbb/session.php
+++ b/phpBB/phpbb/session.php
@@ -1045,8 +1045,9 @@ class session
* @param string $name Name of the cookie, will be automatically prefixed with the phpBB cookie name. track becomes [cookie_name]_track then.
* @param string $cookiedata The data to hold within the cookie
* @param int $cookietime The expiration time as UNIX timestamp. If 0 is provided, a session cookie is set.
+ * @param bool $httponly Use HttpOnly. Defaults to true. Use false to make cookie accessible by client-side scripts.
*/
- function set_cookie($name, $cookiedata, $cookietime)
+ function set_cookie($name, $cookiedata, $cookietime, $httponly = true)
{
global $config;
@@ -1054,7 +1055,7 @@ class session
$expire = gmdate('D, d-M-Y H:i:s \\G\\M\\T', $cookietime);
$domain = (!$config['cookie_domain'] || $config['cookie_domain'] == 'localhost' || $config['cookie_domain'] == '127.0.0.1') ? '' : '; domain=' . $config['cookie_domain'];
- header('Set-Cookie: ' . $name_data . (($cookietime) ? '; expires=' . $expire : '') . '; path=' . $config['cookie_path'] . $domain . ((!$config['cookie_secure']) ? '' : '; secure') . '; HttpOnly', false);
+ header('Set-Cookie: ' . $name_data . (($cookietime) ? '; expires=' . $expire : '') . '; path=' . $config['cookie_path'] . $domain . ((!$config['cookie_secure']) ? '' : '; secure') . ';' . (($httponly) ? ' HttpOnly' : ''), false);
}
/**
diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php
index f4efc58540..49577f6e95 100644
--- a/phpBB/phpbb/template/twig/lexer.php
+++ b/phpBB/phpbb/template/twig/lexer.php
@@ -191,9 +191,16 @@ class lexer extends \Twig_Lexer
$parent_class = $this;
$callback = function ($matches) use ($parent_class, $parent_nodes)
{
- $name = $matches[1];
- $subset = trim(substr($matches[2], 1, -1)); // Remove parenthesis
- $body = $matches[3];
+ $hard_parents = explode('.', $matches[1]);
+ array_pop($hard_parents); // ends with .
+ if ($hard_parents)
+ {
+ $parent_nodes = array_merge($hard_parents, $parent_nodes);
+ }
+
+ $name = $matches[2];
+ $subset = trim(substr($matches[3], 1, -1)); // Remove parenthesis
+ $body = $matches[4];
// Replace <!-- BEGINELSE -->
$body = str_replace('<!-- BEGINELSE -->', '{% else %}', $body);
@@ -242,7 +249,7 @@ class lexer extends \Twig_Lexer
return "{% for {$name} in {$parent}{$name}{$subset} %}{$body}{% endfor %}";
};
- return preg_replace_callback('#<!-- BEGIN ([!a-zA-Z0-9_]+)(\([0-9,\-]+\))? -->(.+?)<!-- END \1 -->#s', $callback, $code);
+ return preg_replace_callback('#<!-- BEGIN ((?:[a-zA-Z0-9_]+\.)*)([!a-zA-Z0-9_]+)(\([0-9,\-]+\))? -->(.+?)<!-- END \1\2 -->#s', $callback, $code);
}
/**
diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php
index b9b3896606..591b5ca30d 100644
--- a/phpBB/phpbb/user.php
+++ b/phpBB/phpbb/user.php
@@ -69,7 +69,7 @@ class user extends \phpbb\session
*/
function setup($lang_set = false, $style_id = false)
{
- global $db, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache;
+ global $db, $request, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache;
global $phpbb_dispatcher;
if ($this->data['user_id'] != ANONYMOUS)
@@ -80,7 +80,25 @@ class user extends \phpbb\session
}
else
{
- $user_lang_name = basename($config['default_lang']);
+ $lang_override = $request->variable('language', '');
+ if ($lang_override)
+ {
+ $this->set_cookie('lang', $lang_override, 0, false);
+ }
+ else
+ {
+ $lang_override = $request->variable($config['cookie_name'] . '_lang', '', true, \phpbb\request\request_interface::COOKIE);
+ }
+ if ($lang_override)
+ {
+ $use_lang = basename($lang_override);
+ $user_lang_name = (file_exists($this->lang_path . $use_lang . "/common.$phpEx")) ? $use_lang : basename($config['default_lang']);
+ $this->data['user_lang'] = $user_lang_name;
+ }
+ else
+ {
+ $user_lang_name = basename($config['default_lang']);
+ }
$user_date_format = $config['default_dateformat'];
$user_timezone = $config['board_timezone'];
@@ -143,9 +161,17 @@ class user extends \phpbb\session
* that are absolutely needed globally using this
* event. Use local events otherwise.
* @var mixed style_id Style we are going to display
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
- $vars = array('user_data', 'user_lang_name', 'user_date_format', 'user_timezone', 'lang_set', 'lang_set_ext', 'style_id');
+ $vars = array(
+ 'user_data',
+ 'user_lang_name',
+ 'user_date_format',
+ 'user_timezone',
+ 'lang_set',
+ 'lang_set_ext',
+ 'style_id',
+ );
extract($phpbb_dispatcher->trigger_event('core.user_setup', compact($vars)));
$this->data = $user_data;
@@ -182,7 +208,7 @@ class user extends \phpbb\session
}
unset($lang_set_ext);
- $style_request = request_var('style', 0);
+ $style_request = $request->variable('style', 0);
if ($style_request && (!$config['override_user_style'] || $auth->acl_get('a_styles')) && !defined('ADMIN_START'))
{
global $SID, $_EXTRA_URL;
@@ -769,8 +795,14 @@ class user extends \phpbb\session
*/
function img($img, $alt = '')
{
- $alt = (!empty($this->lang[$alt])) ? $this->lang[$alt] : $alt;
- return '<span class="imageset ' . $img . '">' . $alt . '</span>';
+ $title = '';
+
+ if ($alt)
+ {
+ $alt = $this->lang($alt);
+ $title = ' title="' . $alt . '"';
+ }
+ return '<span class="imageset ' . $img . '"' . $title . '>' . $alt . '</span>';
}
/**
diff --git a/phpBB/posting.php b/phpBB/posting.php
index 89056f0f11..054f6edb50 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -80,9 +80,24 @@ $current_time = time();
* form submission.
* NOTE: Should be actual language strings, NOT
* language keys.
-* @since 3.1-A1
+* @since 3.1.0-a1
*/
-$vars = array('post_id', 'topic_id', 'forum_id', 'draft_id', 'lastclick', 'submit', 'preview', 'save', 'load', 'delete', 'cancel', 'refresh', 'mode', 'error');
+$vars = array(
+ 'post_id',
+ 'topic_id',
+ 'forum_id',
+ 'draft_id',
+ 'lastclick',
+ 'submit',
+ 'preview',
+ 'save',
+ 'load',
+ 'delete',
+ 'cancel',
+ 'refresh',
+ 'mode',
+ 'error',
+);
extract($phpbb_dispatcher->trigger_event('core.modify_posting_parameters', compact($vars)));
// Was cancel pressed? If so then redirect to the appropriate page
@@ -1561,10 +1576,19 @@ $template->assign_vars(array(
* this is "multipart/form-data" else it is the empty string
* @var string s_action The URL to submit the POST data to
* @var string s_hidden_fields The concatenated input tags of the form's hidden fields
-* @since 3.1-A1
+* @since 3.1.0-a1
* @change 3.1.0-b3 Added vars post_data, moderators, mode, page_title, s_topic_icons, form_enctype, s_action, s_hidden_fields
*/
-$vars = array('post_data', 'moderators', 'mode', 'page_title', 's_topic_icons', 'form_enctype', 's_action', 's_hidden_fields');
+$vars = array(
+ 'post_data',
+ 'moderators',
+ 'mode',
+ 'page_title',
+ 's_topic_icons',
+ 'form_enctype',
+ 's_action',
+ 's_hidden_fields',
+);
extract($phpbb_dispatcher->trigger_event('core.posting_modify_template_vars', compact($vars)));
// Build custom bbcodes array
diff --git a/phpBB/report.php b/phpBB/report.php
index 1adee028dc..f37a2f9d5c 100644
--- a/phpBB/report.php
+++ b/phpBB/report.php
@@ -136,7 +136,7 @@ else
$message .= '<br /><br />' . sprintf($user->lang['RETURN_PM'], '<a href="' . $redirect_url . '">', '</a>');
trigger_error($message);
}
-
+
$reported_post_text = $report_data['message_text'];
$reported_post_bitfield = $report_data['bbcode_bitfield'];
$reported_post_uid = $report_data['bbcode_uid'];
diff --git a/phpBB/search.php b/phpBB/search.php
index fbb4e93089..a34c0a4e5a 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -635,12 +635,66 @@ if ($keywords || $author || $author_id || $search_id || $submit)
}
$db->sql_freeresult($result);
- $sql = 'SELECT p.*, f.forum_id, f.forum_name, t.*, u.username, u.username_clean, u.user_sig, u.user_sig_bbcode_uid, u.user_colour
- FROM ' . POSTS_TABLE . ' p
- LEFT JOIN ' . TOPICS_TABLE . ' t ON (p.topic_id = t.topic_id)
- LEFT JOIN ' . FORUMS_TABLE . ' f ON (p.forum_id = f.forum_id)
- LEFT JOIN ' . USERS_TABLE . " u ON (p.poster_id = u.user_id)
- WHERE $sql_where";
+ $sql_array = array(
+ 'SELECT' => 'p.*, f.forum_id, f.forum_name, t.*, u.username, u.username_clean, u.user_sig, u.user_sig_bbcode_uid, u.user_colour',
+ 'FROM' => array(
+ POSTS_TABLE => 'p',
+ ),
+ 'LEFT_JOIN' => array(
+ array(
+ 'FROM' => array(TOPICS_TABLE => 't'),
+ 'ON' => 'p.topic_id = t.topic_id',
+ ),
+ array(
+ 'FROM' => array(FORUMS_TABLE => 'f'),
+ 'ON' => 'p.forum_id = f.forum_id',
+ ),
+ array(
+ 'FROM' => array(USERS_TABLE => 'u'),
+ 'ON' => 'p.poster_id = u.user_id',
+ ),
+ ),
+ 'WHERE' => $sql_where,
+ 'ORDER_BY' => $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'),
+ );
+
+ /**
+ * Event to modify the SQL query before the posts data is retrieved
+ *
+ * @event core.search_get_posts_data
+ * @var array sql_array The SQL array
+ * @var array zebra Array of zebra data for the current user
+ * @var int total_match_count The total number of search matches
+ * @var string keywords String of the specified keywords
+ * @var array sort_by_sql Array of SQL sorting instructions
+ * @var string s_sort_dir The sort direction
+ * @var string s_sort_key The sort key
+ * @var string s_limit_days Limit the age of results
+ * @var array ex_fid_ary Array of excluded forum ids
+ * @var array author_id_ary Array of exclusive author ids
+ * @var string search_fields The data fields to search in
+ * @var int search_id The id of the search request
+ * @var int start The starting id of the results
+ * @since 3.1.0-b3
+ */
+ $vars = array(
+ 'sql_array',
+ 'zebra',
+ 'total_match_count',
+ 'keywords',
+ 'sort_by_sql',
+ 's_sort_dir',
+ 's_sort_key',
+ 's_limit_days',
+ 'ex_fid_ary',
+ 'author_id_ary',
+ 'search_fields',
+ 'search_id',
+ 'start',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.search_get_posts_data', compact($vars)));
+
+ $sql = $db->sql_build_query('SELECT', $sql_array);
}
else
{
@@ -681,7 +735,7 @@ if ($keywords || $author || $author_id || $search_id || $submit)
* @var string sql_select The SQL SELECT string used by search to get topic data
* @var string sql_from The SQL FROM string used by search to get topic data
* @var string sql_where The SQL WHERE string used by search to get topic data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('sql_select', 'sql_from', 'sql_where');
extract($phpbb_dispatcher->trigger_event('core.search_get_topic_data', compact($vars)));
@@ -689,8 +743,8 @@ if ($keywords || $author || $author_id || $search_id || $submit)
$sql = "SELECT $sql_select
FROM $sql_from
WHERE $sql_where";
+ $sql .= ' ORDER BY ' . $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
}
- $sql .= ' ORDER BY ' . $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
$result = $db->sql_query($sql);
$result_topic_id = 0;
@@ -879,7 +933,7 @@ if ($keywords || $author || $author_id || $search_id || $submit)
$unread_topic = (isset($topic_tracking_info[$forum_id][$row['topic_id']]) && $row['topic_last_post_time'] > $topic_tracking_info[$forum_id][$row['topic_id']]) ? true : false;
- $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $forum_id)) ? true : false;
+ $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $forum_id)) ? true : false;
$posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $forum_id)) ? true : false;
$topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
$u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . "&amp;t=$result_topic_id", true, $user->session_id) : '';
@@ -1002,11 +1056,46 @@ if ($keywords || $author || $author_id || $search_id || $submit)
* Modify the topic data before it is assigned to the template
*
* @event core.search_modify_tpl_ary
- * @var array row Array with topic data
- * @var array tpl_ary Template block array with topic data
- * @since 3.1-A1
+ * @var array row Array with topic data
+ * @var array tpl_ary Template block array with topic data
+ * @var string show_results Display topics or posts
+ * @var string topic_title Cleaned topic title
+ * @var int replies The number of topic replies
+ * @var string view_topic_url The URL to the topic
+ * @var string folder_img The folder image of the topic
+ * @var string folder_alt The alt attribute of the topic folder img
+ * @var int topic_type The topic type
+ * @var bool unread_topic Whether the topic has unread posts
+ * @var bool topic_unapproved Whether the topic is unapproved
+ * @var int posts_unapproved The number of unapproved posts
+ * @var bool topic_deleted Whether the topic has been deleted
+ * @var string u_mcp_queue The URL to the corresponding MCP queue page
+ * @var array zebra The zebra data of the current user
+ * @var array attachments All the attachments of the search results
+ * @since 3.1.0-a1
+ * @changed 3.1.0-b3 Added vars show_results, topic_title, replies,
+ * view_topic_url, folder_img, folder_alt, topic_type, unread_topic,
+ * topic_unapproved, posts_unapproved, topic_deleted, u_mcp_queue,
+ * zebra, attachments
*/
- $vars = array('row', 'tpl_ary');
+ $vars = array(
+ 'row',
+ 'tpl_ary',
+ 'show_results',
+ 'topic_title',
+ 'replies',
+ 'view_topic_url',
+ 'folder_img',
+ 'folder_alt',
+ 'topic_type',
+ 'unread_topic',
+ 'topic_unapproved',
+ 'posts_unapproved',
+ 'topic_deleted',
+ 'u_mcp_queue',
+ 'zebra',
+ 'attachments',
+ );
extract($phpbb_dispatcher->trigger_event('core.search_modify_tpl_ary', compact($vars)));
$template->assign_block_vars('searchresults', $tpl_ary);
diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg
index 1beb32685c..33631bac70 100644
--- a/phpBB/styles/prosilver/style.cfg
+++ b/phpBB/styles/prosilver/style.cfg
@@ -18,8 +18,8 @@
# General Information about this style
name = prosilver
copyright = © phpBB Group, 2007
-style_version = 3.1.0-b2
-phpbb_version = 3.1.0-b2
+style_version = 3.1.0-b3
+phpbb_version = 3.1.0-b3
# Defining a different template bitfield
# template_bitfield = lNg=
diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js
index 4df38f4275..e9f8064b9e 100644
--- a/phpBB/styles/prosilver/template/ajax.js
+++ b/phpBB/styles/prosilver/template/ajax.js
@@ -8,7 +8,7 @@
* @param int Delay in ms until darkenwrapper's click event is triggered
*/
phpbb.closeDarkenWrapper = function(delay) {
- setTimeout(function() {
+ phpbbAlertTimer = setTimeout(function() {
$('#darkenwrapper').trigger('click');
}, delay);
};
@@ -315,13 +315,17 @@ $('.poll_view_results a').click(function(e) {
$('[data-ajax]').each(function() {
var $this = $(this),
ajax = $this.attr('data-ajax'),
+ filter = $this.attr('data-filter'),
fn;
if (ajax !== 'false') {
fn = (ajax !== 'true') ? ajax : null;
+ filter = (filter !== undefined) ? phpbb.getFunctionByName(filter) : null;
+
phpbb.ajaxify({
selector: this,
refresh: $this.attr('data-refresh') !== undefined,
+ filter: filter,
callback: fn
});
}
diff --git a/phpBB/styles/prosilver/template/captcha_default.html b/phpBB/styles/prosilver/template/captcha_default.html
index c9c5295d13..550962db67 100644
--- a/phpBB/styles/prosilver/template/captcha_default.html
+++ b/phpBB/styles/prosilver/template/captcha_default.html
@@ -2,7 +2,7 @@
<div class="panel">
<div class="inner">
- <h3>{L_CONFIRMATION}</h3>
+ <h3 class="captcha-title">{L_CONFIRMATION}</h3>
<p>{L_CONFIRM_EXPLAIN}</p>
<fieldset class="fields2">
diff --git a/phpBB/styles/prosilver/template/captcha_qa.html b/phpBB/styles/prosilver/template/captcha_qa.html
index c179f6dc20..1671987f63 100644
--- a/phpBB/styles/prosilver/template/captcha_qa.html
+++ b/phpBB/styles/prosilver/template/captcha_qa.html
@@ -2,7 +2,7 @@
<div class="panel">
<div class="inner">
- <h3>{L_CONFIRMATION}</h3>
+ <h3 class="captcha-title">{L_CONFIRMATION}</h3>
<fieldset class="fields2">
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/captcha_recaptcha.html b/phpBB/styles/prosilver/template/captcha_recaptcha.html
index aad1008241..bde0c9df13 100644
--- a/phpBB/styles/prosilver/template/captcha_recaptcha.html
+++ b/phpBB/styles/prosilver/template/captcha_recaptcha.html
@@ -2,7 +2,7 @@
<div class="panel">
<div class="inner">
- <h3>{L_CONFIRMATION}</h3>
+ <h3 class="captcha-title">{L_CONFIRMATION}</h3>
<p>{L_CONFIRM_EXPLAIN}</p>
<fieldset class="fields2">
diff --git a/phpBB/styles/prosilver/template/confirm_body.html b/phpBB/styles/prosilver/template/confirm_body.html
index a0428025cf..aaea5cfd05 100644
--- a/phpBB/styles/prosilver/template/confirm_body.html
+++ b/phpBB/styles/prosilver/template/confirm_body.html
@@ -17,7 +17,7 @@
<div class="panel">
<div class="inner">
- <h2>{MESSAGE_TITLE}</h2>
+ <h2 class="message-title">{MESSAGE_TITLE}</h2>
<p>{MESSAGE_TEXT}</p>
<fieldset class="submit-buttons">
diff --git a/phpBB/styles/prosilver/template/confirm_delete_body.html b/phpBB/styles/prosilver/template/confirm_delete_body.html
index dc09974d1c..2d4dde5cd5 100644
--- a/phpBB/styles/prosilver/template/confirm_delete_body.html
+++ b/phpBB/styles/prosilver/template/confirm_delete_body.html
@@ -33,7 +33,7 @@
<div class="panel">
<div class="inner">
- <h2>{MESSAGE_TITLE}</h2>
+ <h2 class="message-title">{MESSAGE_TITLE}</h2>
<p>{MESSAGE_TEXT}</p>
diff --git a/phpBB/styles/prosilver/template/drafts.html b/phpBB/styles/prosilver/template/drafts.html
index 4b2e1bf0c6..ea2849a485 100644
--- a/phpBB/styles/prosilver/template/drafts.html
+++ b/phpBB/styles/prosilver/template/drafts.html
@@ -4,7 +4,7 @@
<div class="panel">
<div class="inner">
- <h3>{L_LOAD_DRAFT}</h3>
+ <h3 class="draft-title">{L_LOAD_DRAFT}</h3>
<p>{L_LOAD_DRAFT_EXPLAIN}</p>
</div>
diff --git a/phpBB/styles/prosilver/template/faq_body.html b/phpBB/styles/prosilver/template/faq_body.html
index f72807cdec..53205d14e9 100644
--- a/phpBB/styles/prosilver/template/faq_body.html
+++ b/phpBB/styles/prosilver/template/faq_body.html
@@ -1,6 +1,6 @@
<!-- INCLUDE overall_header.html -->
-<h2>{L_FAQ_TITLE}</h2>
+<h2 class="faq-title">{L_FAQ_TITLE}</h2>
<div class="panel bg1" id="faqlinks">
@@ -29,7 +29,7 @@
<div class="inner">
<div class="content">
- <h2>{faq_block.BLOCK_TITLE}</h2>
+ <h2 class="faq-title">{faq_block.BLOCK_TITLE}</h2>
<!-- BEGIN faq_row -->
<dl class="faq">
<dt id="f{faq_block.S_ROW_COUNT}r{faq_block.faq_row.S_ROW_COUNT}"><strong>{faq_block.faq_row.FAQ_QUESTION}</strong></dt>
diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html
index 3e9aae28e3..f9c5b4cf20 100644
--- a/phpBB/styles/prosilver/template/index_body.html
+++ b/phpBB/styles/prosilver/template/index_body.html
@@ -48,22 +48,34 @@
<!-- IF S_DISPLAY_ONLINE_LIST -->
<div class="stat-block online-list">
<!-- IF U_VIEWONLINE --><h3><a href="{U_VIEWONLINE}">{L_WHO_IS_ONLINE}</a></h3><!-- ELSE --><h3>{L_WHO_IS_ONLINE}</h3><!-- ENDIF -->
- <p>{TOTAL_USERS_ONLINE} ({L_ONLINE_EXPLAIN})<br />{RECORD_USERS}<br /> <br />{LOGGED_IN_USER_LIST}
- <!-- IF LEGEND --><br /><em>{L_LEGEND}{L_COLON} {LEGEND}</em><!-- ENDIF --></p>
+ <p>
+ <!-- EVENT index_body_block_online_prepend -->
+ {TOTAL_USERS_ONLINE} ({L_ONLINE_EXPLAIN})<br />{RECORD_USERS}<br /> <br />{LOGGED_IN_USER_LIST}
+ <!-- IF LEGEND --><br /><em>{L_LEGEND}{L_COLON} {LEGEND}</em><!-- ENDIF -->
+ <!-- EVENT index_body_block_online_append -->
+ </p>
</div>
<!-- ENDIF -->
<!-- IF S_DISPLAY_BIRTHDAY_LIST -->
<div class="stat-block birthday-list">
<h3>{L_BIRTHDAYS}</h3>
- <p><!-- IF .birthdays -->{L_CONGRATULATIONS}{L_COLON} <strong><!-- BEGIN birthdays -->{birthdays.USERNAME}<!-- IF birthdays.AGE !== '' --> ({birthdays.AGE})<!-- ENDIF --><!-- IF not birthdays.S_LAST_ROW -->, <!-- ENDIF --><!-- END birthdays --></strong><!-- ELSE -->{L_NO_BIRTHDAYS}<!-- ENDIF --></p>
+ <p>
+ <!-- EVENT index_body_block_birthday_prepend -->
+ <!-- IF .birthdays -->{L_CONGRATULATIONS}{L_COLON} <strong><!-- BEGIN birthdays -->{birthdays.USERNAME}<!-- IF birthdays.AGE !== '' --> ({birthdays.AGE})<!-- ENDIF --><!-- IF not birthdays.S_LAST_ROW -->, <!-- ENDIF --><!-- END birthdays --></strong><!-- ELSE -->{L_NO_BIRTHDAYS}<!-- ENDIF -->
+ <!-- EVENT index_body_block_birthday_append -->
+ </p>
</div>
<!-- ENDIF -->
<!-- IF NEWEST_USER -->
<div class="stat-block statistics">
<h3>{L_STATISTICS}</h3>
- <p>{TOTAL_POSTS} &bull; {TOTAL_TOPICS} &bull; {TOTAL_USERS} &bull; {NEWEST_USER}</p>
+ <p>
+ <!-- EVENT index_body_block_stats_prepend -->
+ {TOTAL_POSTS} &bull; {TOTAL_TOPICS} &bull; {TOTAL_USERS} &bull; {NEWEST_USER}
+ <!-- EVENT index_body_block_stats_append -->
+ </p>
</div>
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/login_body.html b/phpBB/styles/prosilver/template/login_body.html
index 38d9f8c68b..c852ffd5f2 100644
--- a/phpBB/styles/prosilver/template/login_body.html
+++ b/phpBB/styles/prosilver/template/login_body.html
@@ -5,7 +5,7 @@
<div class="inner">
<div class="content">
- <h2><!-- IF LOGIN_EXPLAIN -->{LOGIN_EXPLAIN}<!-- ELSE -->{L_LOGIN}<!-- ENDIF --></h2>
+ <h2 class="login-title"><!-- IF LOGIN_EXPLAIN -->{LOGIN_EXPLAIN}<!-- ELSE -->{L_LOGIN}<!-- ENDIF --></h2>
<fieldset <!-- IF not S_CONFIRM_CODE -->class="fields1"<!-- ELSE -->class="fields2"<!-- ENDIF -->>
<!-- IF LOGIN_ERROR --><div class="error">{LOGIN_ERROR}</div><!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/login_forum.html b/phpBB/styles/prosilver/template/login_forum.html
index c83a625b3f..18a95c0a8f 100644
--- a/phpBB/styles/prosilver/template/login_forum.html
+++ b/phpBB/styles/prosilver/template/login_forum.html
@@ -1,6 +1,6 @@
<!-- INCLUDE overall_header.html -->
-<!-- IF FORUM_NAME --><h2><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2><!-- ENDIF -->
+<!-- IF FORUM_NAME --><h2 class="forum-title"><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2><!-- ENDIF -->
<form id="login_forum" method="post" action="{S_LOGIN_ACTION}">
{S_FORM_TOKEN}
@@ -8,7 +8,7 @@
<div class="inner">
<div class="content">
- <h2>{L_LOGIN}</h2>
+ <h2 class="login-title">{L_LOGIN}</h2>
<p>{L_LOGIN_FORUM}</p>
diff --git a/phpBB/styles/prosilver/template/mcp_approve.html b/phpBB/styles/prosilver/template/mcp_approve.html
index ab7f92e262..14472bcf4f 100644
--- a/phpBB/styles/prosilver/template/mcp_approve.html
+++ b/phpBB/styles/prosilver/template/mcp_approve.html
@@ -34,7 +34,7 @@
<div class="content">
- <h2>{MESSAGE_TITLE}</h2>
+ <h2 class="message-title">{MESSAGE_TITLE}</h2>
<!-- IF ADDITIONAL_MSG --><p class="error">{ADDITIONAL_MSG}</p><!-- ENDIF -->
<fieldset>
diff --git a/phpBB/styles/prosilver/template/mcp_header.html b/phpBB/styles/prosilver/template/mcp_header.html
index 2b2105e770..bdfa254741 100644
--- a/phpBB/styles/prosilver/template/mcp_header.html
+++ b/phpBB/styles/prosilver/template/mcp_header.html
@@ -42,7 +42,7 @@
<div id="cp-main" class="mcp-main panel-container">
<!-- IF MESSAGE -->
<div class="content">
- <h2>{L_MESSAGE}</h2>
+ <h2 class="message-title">{L_MESSAGE}</h2>
<p class="error">{MESSAGE}</p>
<p><!-- BEGIN return_links -->{return_links.MESSAGE_LINK}<br /><br /><!-- END return_links --></p>
</div>
diff --git a/phpBB/styles/prosilver/template/mcp_message.html b/phpBB/styles/prosilver/template/mcp_message.html
index 7102c658c4..062103b91c 100644
--- a/phpBB/styles/prosilver/template/mcp_message.html
+++ b/phpBB/styles/prosilver/template/mcp_message.html
@@ -1,7 +1,7 @@
<!-- INCLUDE mcp_header.html -->
<div class="content">
- <h2>{MESSAGE_TITLE}</h2>
+ <h2 class="message-title">{MESSAGE_TITLE}</h2>
<p>{MESSAGE_TEXT}</p>
</div>
diff --git a/phpBB/styles/prosilver/template/mcp_move.html b/phpBB/styles/prosilver/template/mcp_move.html
index c2ee25f0d9..d028fffeb4 100644
--- a/phpBB/styles/prosilver/template/mcp_move.html
+++ b/phpBB/styles/prosilver/template/mcp_move.html
@@ -37,7 +37,7 @@
<div class="inner">
<div class="content">
- <h2>{MESSAGE_TITLE}</h2>
+ <h2 class="message-title">{MESSAGE_TITLE}</h2>
<!-- IF ADDITIONAL_MSG --><p>{ADDITIONAL_MSG}</p><!-- ENDIF -->
<fieldset>
diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html
index 7ba289cfd6..7623fbe38b 100644
--- a/phpBB/styles/prosilver/template/memberlist_body.html
+++ b/phpBB/styles/prosilver/template/memberlist_body.html
@@ -14,7 +14,7 @@
<!-- IF S_SHOW_GROUP -->
- <h2<!-- IF GROUP_COLOR --> style="color:#{GROUP_COLOR};"<!-- ENDIF -->>{GROUP_NAME}</h2>
+ <h2 class="group-title"<!-- IF GROUP_COLOR --> style="color:#{GROUP_COLOR};"<!-- ENDIF -->>{GROUP_NAME}</h2>
<p>{GROUP_DESC} {GROUP_TYPE}</p>
<p>
<!-- IF AVATAR_IMG -->{AVATAR_IMG}<!-- ENDIF -->
@@ -96,10 +96,10 @@
<!-- IF U_SORT_ACTIVE --><th class="active"><a href="{U_SORT_ACTIVE}#memberlist">{L_LAST_ACTIVE}</a></th><!-- ENDIF -->
<!-- ELSEIF S_SHOW_GROUP -->
<th class="name">{L_GROUP_MEMBERS}</th>
- <th class="posts">&nbsp;</th>
- <th class="info">&nbsp;</th>
- <th class="joined">&nbsp;</th>
- <!-- IF U_SORT_ACTIVE --><th class="active">&nbsp;</th><!-- ENDIF -->
+ <th class="posts">{L_POSTS}</th>
+ <th class="info"><!-- BEGIN custom_fields --><!-- IF not custom_fields.S_FIRST_ROW -->{L_COMMA_SEPARATOR} <!-- ENDIF -->{custom_fields.PROFILE_FIELD_NAME}<!-- END custom_fields --></th>
+ <th class="joined">{L_JOINED}</th>
+ <!-- IF U_SORT_ACTIVE --><th class="active">{L_LAST_ACTIVE}</th><!-- ENDIF -->
<!-- ENDIF -->
</tr>
</thead>
diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html
index ee89b103b5..f4439b6934 100644
--- a/phpBB/styles/prosilver/template/memberlist_search.html
+++ b/phpBB/styles/prosilver/template/memberlist_search.html
@@ -7,9 +7,21 @@
<p>{L_FIND_USERNAME_EXPLAIN}</p>
<fieldset class="fields1 column1">
- <dl>
+ <dl style="overflow: visible;">
<dt><label for="username">{L_USERNAME}{L_COLON}</label></dt>
- <dd><input type="text" name="username" id="username" value="{USERNAME}" class="inputbox" /></dd>
+ <dd>
+ <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 --> />
+ <!-- IF U_LIVE_SEARCH -->
+ <div class="dropdown-container">
+ <div class="dropdown live-search hidden" id="user-search">
+ <div class="pointer"><div class="pointer-inner"></div></div>
+ <ul class="dropdown-contents search-results">
+ <li class="search-result-tpl"><span class="search-result"></span></li>
+ </ul>
+ </div>
+ </div>
+ <!-- ENDIF -->
+ </dd>
</dl>
<!-- IF S_EMAIL_SEARCH_ALLOWED -->
<dl>
diff --git a/phpBB/styles/prosilver/template/memberlist_view.html b/phpBB/styles/prosilver/template/memberlist_view.html
index 6665019ab8..a8b1e972fe 100644
--- a/phpBB/styles/prosilver/template/memberlist_view.html
+++ b/phpBB/styles/prosilver/template/memberlist_view.html
@@ -1,6 +1,8 @@
<!-- INCLUDE overall_header.html -->
-<h2>{PAGE_TITLE}</h2>
+<h2 class="memberlist-title">{PAGE_TITLE}</h2>
+
+<!-- EVENT memberlist_view_content_prepend -->
<form method="post" action="{S_PROFILE_ACTION}" id="viewprofile">
<div class="panel bg1<!-- IF S_ONLINE --> online<!-- ENDIF -->">
diff --git a/phpBB/styles/prosilver/template/message_body.html b/phpBB/styles/prosilver/template/message_body.html
index a844246055..8062fed9a0 100644
--- a/phpBB/styles/prosilver/template/message_body.html
+++ b/phpBB/styles/prosilver/template/message_body.html
@@ -6,7 +6,7 @@
<div class="panel" id="message">
<div class="inner">
- <h2>{MESSAGE_TITLE}</h2>
+ <h2 class="message-title">{MESSAGE_TITLE}</h2>
<p>{MESSAGE_TEXT}</p>
<!-- IF SCRIPT_NAME == "search" and not S_BOARD_DISABLED and not S_NO_SEARCH and L_RETURN_TO_SEARCH_ADV --><p><a href="{U_SEARCH}" class="arrow-{S_CONTENT_FLOW_BEGIN}">{L_RETURN_TO_SEARCH_ADV}</a></p><!-- ENDIF -->
</div>
diff --git a/phpBB/styles/prosilver/template/navbar_footer.html b/phpBB/styles/prosilver/template/navbar_footer.html
index 0bc67a4417..13e50dae19 100644
--- a/phpBB/styles/prosilver/template/navbar_footer.html
+++ b/phpBB/styles/prosilver/template/navbar_footer.html
@@ -10,9 +10,13 @@
<!-- IF not S_IS_BOT -->
<!-- IF U_WATCH_FORUM_LINK --><li class="small-icon icon-<!-- IF S_WATCHING_FORUM -->unsubscribe<!-- ELSE -->subscribe<!-- ENDIF -->"><a href="{U_WATCH_FORUM_LINK}" title="{S_WATCH_FORUM_TITLE}" data-ajax="toggle_link" data-toggle-class="small-icon icon-<!-- IF not S_WATCHING_FORUM -->unsubscribe<!-- ELSE -->subscribe<!-- ENDIF -->" data-toggle-text="{S_WATCH_FORUM_TOGGLE}" data-toggle-url="{U_WATCH_FORUM_TOGGLE}">{S_WATCH_FORUM_TITLE}</a></li><!-- ENDIF -->
<!-- ENDIF -->
+ <!-- EVENT overall_footer_timezone_before -->
<li class="rightside">{S_TIMEZONE}</li>
+ <!-- EVENT overall_footer_timezone_after -->
<!-- IF not S_IS_BOT --><li class="rightside"><a href="{U_DELETE_COOKIES}" data-ajax="true" data-refresh="true">{L_DELETE_COOKIES}</a></li><!-- ENDIF -->
- <!-- IF U_TEAM --><li class="rightside"><a href="{U_TEAM}">{L_THE_TEAM}</a><!-- ENDIF -->
+ <!-- EVENT overall_footer_teamlink_before -->
+ <!-- IF U_TEAM --><li class="rightside"><a href="{U_TEAM}">{L_THE_TEAM}</a></li><!-- ENDIF -->
+ <!-- EVENT overall_footer_teamlink_after -->
</ul>
</div>
diff --git a/phpBB/styles/prosilver/template/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html
index 7fbaa1254f..804fa5b2aa 100644
--- a/phpBB/styles/prosilver/template/navbar_header.html
+++ b/phpBB/styles/prosilver/template/navbar_header.html
@@ -6,11 +6,11 @@
<li class="small-icon icon-home breadcrumbs">
<!-- IF U_SITE_HOME --><span class="crumb"><a href="{U_SITE_HOME}"{$MICRODATA}>{L_SITE_HOME}</a></span><!-- ENDIF -->
<span class="crumb"><a href="{U_INDEX}" accesskey="h"{$MICRODATA}>{L_INDEX}</a></span>
- <!-- BEGIN navlinks --><span class="crumb"><a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}>{navlinks.FORUM_NAME}</a></span><!-- END navlinks -->
+ <!-- BEGIN navlinks --><!-- EVENT overall_header_navlink_prepend --><span class="crumb"><a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}>{navlinks.FORUM_NAME}</a></span><!-- EVENT overall_header_navlink_append --><!-- END navlinks -->
<!-- EVENT overall_header_breadcrumb_append -->
</li>
- <!-- IF S_REGISTERED_USER --><li id="username_logged_in" class="rightside"><!-- IF CURRENT_USER_AVATAR --><a href="{U_USER_PROFILE}" class="header-avatar">{CURRENT_USER_AVATAR}</a> <!-- ENDIF -->{USERNAME_FULL}</li><!-- ENDIF -->
+ <!-- IF S_REGISTERED_USER --><li id="username_logged_in" class="rightside"><!-- IF CURRENT_USER_AVATAR --><a href="{U_USER_PROFILE}" class="header-avatar">{CURRENT_USER_AVATAR}</a> <!-- ENDIF -->{CURRENT_USERNAME_FULL}</li><!-- ENDIF -->
<!-- IF S_DISPLAY_SEARCH and not S_IN_SEARCH --><li class="responsive-search rightside" style="display: none;"><a href="{U_SEARCH}" title="{L_SEARCH_ADV_EXPLAIN}">{L_SEARCH}</a></li><!-- ENDIF -->
</ul>
diff --git a/phpBB/styles/prosilver/template/posting_attach_body.html b/phpBB/styles/prosilver/template/posting_attach_body.html
index b6f4d13804..4ad66656b2 100644
--- a/phpBB/styles/prosilver/template/posting_attach_body.html
+++ b/phpBB/styles/prosilver/template/posting_attach_body.html
@@ -35,7 +35,7 @@
<tbody class="responsive-skip-empty" id="file-list">
<tr class="attach-row" id="attach-row-tpl">
<td class="attach-name">
- <span class="file-name"></span>
+ <span class="file-name ellipsis-text"></span>
<span class="attach-controls">
<input type="button" value="{L_PLACE_INLINE}" class="button2 hidden file-inline-bbcode" />&nbsp;
<input type="button" value="{L_DELETE_FILE}" class="button2 file-delete" />
@@ -58,7 +58,7 @@
<!-- BEGIN attach_row -->
<tr class="attach-row" data-attach-id="{attach_row.ATTACH_ID}">
<td class="attach-name">
- <span class="file-name"><a href="{attach_row.U_VIEW_ATTACHMENT}">{attach_row.FILENAME}</a></span>
+ <span class="file-name ellipsis-text"><a href="{attach_row.U_VIEW_ATTACHMENT}">{attach_row.FILENAME}</a></span>
<span class="attach-controls">
<!-- IF S_INLINE_ATTACHMENT_OPTIONS --><input type="button" value="{L_PLACE_INLINE}" class="button2 file-inline-bbcode" />&nbsp; <!-- ENDIF -->
<input type="submit" name="delete_file[{attach_row.ASSOC_INDEX}]" value="{L_DELETE_FILE}" class="button2 file-delete" />
diff --git a/phpBB/styles/prosilver/template/posting_layout.html b/phpBB/styles/prosilver/template/posting_layout.html
index 0b9ddedf47..4ef0954200 100644
--- a/phpBB/styles/prosilver/template/posting_layout.html
+++ b/phpBB/styles/prosilver/template/posting_layout.html
@@ -1,9 +1,9 @@
<!-- INCLUDE overall_header.html -->
<!-- IF TOPIC_TITLE -->
- <h2><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2>
+ <h2 class="posting-title"><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2>
<!-- ELSE -->
- <h2><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2>
+ <h2 class="posting-title"><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2>
<!-- ENDIF -->
<!-- IF S_FORUM_RULES -->
diff --git a/phpBB/styles/prosilver/template/posting_pm_layout.html b/phpBB/styles/prosilver/template/posting_pm_layout.html
index c9b4a915ae..3bdadd06ca 100644
--- a/phpBB/styles/prosilver/template/posting_pm_layout.html
+++ b/phpBB/styles/prosilver/template/posting_pm_layout.html
@@ -15,7 +15,7 @@
<!-- IF S_DISPLAY_PREVIEW --><!-- INCLUDE posting_preview.html --><!-- ENDIF -->
-<h2>{L_TITLE}</h2>
+<h2 class="posting-title">{L_TITLE}</h2>
<div class="panel" id="pmheader-postingbox">
<div class="inner">
diff --git a/phpBB/styles/prosilver/template/quickreply_editor.html b/phpBB/styles/prosilver/template/quickreply_editor.html
index 8da9919db8..6a8846626e 100644
--- a/phpBB/styles/prosilver/template/quickreply_editor.html
+++ b/phpBB/styles/prosilver/template/quickreply_editor.html
@@ -2,7 +2,7 @@
<!-- EVENT quickreply_editor_panel_before -->
<div class="panel">
<div class="inner">
- <h2>{L_QUICKREPLY}</h2>
+ <h2 class="quickreply-title">{L_QUICKREPLY}</h2>
<fieldset class="fields1">
<dl style="clear: left;">
<dt><label for="subject">{L_SUBJECT}{L_COLON}</label></dt>
diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html
index 3307c68627..fe0b0362ce 100644
--- a/phpBB/styles/prosilver/template/search_results.html
+++ b/phpBB/styles/prosilver/template/search_results.html
@@ -1,6 +1,6 @@
<!-- INCLUDE overall_header.html -->
-<h2><!-- IF SEARCH_TITLE -->{SEARCH_TITLE}<!-- ELSE -->{SEARCH_MATCHES}<!-- ENDIF --><!-- IF SEARCH_WORDS -->{L_COLON} <a href="{U_SEARCH_WORDS}">{SEARCH_WORDS}</a><!-- ENDIF --></h2>
+<h2 class="searchresults-title"><!-- IF SEARCH_TITLE -->{SEARCH_TITLE}<!-- ELSE -->{SEARCH_MATCHES}<!-- ENDIF --><!-- IF SEARCH_WORDS -->{L_COLON} <a href="{U_SEARCH_WORDS}">{SEARCH_WORDS}</a><!-- ENDIF --></h2>
<!-- IF SEARCHED_QUERY --> <p>{L_SEARCHED_QUERY}{L_COLON} <strong>{SEARCHED_QUERY}</strong></p><!-- ENDIF -->
<!-- IF IGNORED_WORDS --> <p>{L_IGNORED_TERMS}{L_COLON} <strong>{IGNORED_WORDS}</strong></p><!-- ENDIF -->
<!-- IF PHRASE_SEARCH_DISABLED --> <p><strong>{L_PHRASE_SEARCH_DISABLED}</strong></p><!-- ENDIF -->
@@ -113,6 +113,7 @@
<!-- ELSE -->
<!-- BEGIN searchresults -->
+ <!-- EVENT search_results_post_before -->
<div class="search post <!-- IF searchresults.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF searchresults.S_POST_REPORTED --> reported<!-- ENDIF -->">
<div class="inner">
@@ -122,12 +123,14 @@
</div>
<!-- ELSE -->
<dl class="postprofile">
+ <!-- EVENT search_results_postprofile_before -->
<dt class="author">{L_POST_BY_AUTHOR} {searchresults.POST_AUTHOR_FULL}</dt>
<dd class="search-result-date">{searchresults.POST_DATE}</dd>
<dd>{L_FORUM}{L_COLON} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a></dd>
<dd>{L_TOPIC}{L_COLON} <a href="{searchresults.U_VIEW_TOPIC}">{searchresults.TOPIC_TITLE}</a></dd>
<dd>{L_REPLIES}{L_COLON} <strong>{searchresults.TOPIC_REPLIES}</strong></dd>
<dd>{L_VIEWS}{L_COLON} <strong>{searchresults.TOPIC_VIEWS}</strong></dd>
+ <!-- EVENT search_results_postprofile_after -->
</dl>
<div class="postbody">
@@ -144,6 +147,7 @@
</div>
</div>
+ <!-- EVENT search_results_post_after -->
<!-- BEGINELSE -->
<div class="panel">
<div class="inner">
diff --git a/phpBB/styles/prosilver/template/simple_footer.html b/phpBB/styles/prosilver/template/simple_footer.html
index 10edece3cd..02e24ab796 100644
--- a/phpBB/styles/prosilver/template/simple_footer.html
+++ b/phpBB/styles/prosilver/template/simple_footer.html
@@ -4,11 +4,27 @@
<!-- IF TRANSLATION_INFO --><br />{TRANSLATION_INFO}<!-- ENDIF -->
<!-- IF DEBUG_OUTPUT --><br />{DEBUG_OUTPUT}<!-- ENDIF -->
</div>
+
+ <div id="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}" data-ajax-error-text-abort="{L_AJAX_ERROR_TEXT_ABORT}" data-ajax-error-text-timeout="{L_AJAX_ERROR_TEXT_TIMEOUT}" data-ajax-error-text-parsererror="{L_AJAX_ERROR_TEXT_PARSERERROR}">
+ <div id="darken">&nbsp;</div>
+ </div>
+ <div id="loading_indicator"></div>
+
+ <div id="phpbb_alert" class="phpbb_alert" data-l-err="{L_ERROR}" data-l-timeout-processing-req="{L_TIMEOUT_PROCESSING_REQ}">
+ <a href="#" class="alert_close"></a>
+ <h3 class="alert_title"></h3><p class="alert_text"></p>
+ </div>
+ <div id="phpbb_confirm" class="phpbb_alert">
+ <a href="#" class="alert_close"></a>
+ <div class="alert_text"></div>
+ </div>
</div>
<script type="text/javascript" src="{T_JQUERY_LINK}"></script>
<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write(unescape('%3Cscript src="{T_ASSETS_PATH}/javascript/jquery.js?assets_version={T_ASSETS_VERSION}" type="text/javascript"%3E%3C/script%3E'));</script><!-- ENDIF -->
+<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- INCLUDEJS forum_fn.js -->
+<!-- INCLUDEJS ajax.js -->
<!-- EVENT simple_footer_after -->
diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html
index f5e265ac16..48f6cc87da 100644
--- a/phpBB/styles/prosilver/template/simple_header.html
+++ b/phpBB/styles/prosilver/template/simple_header.html
@@ -24,6 +24,10 @@
<!-- DEFINE $POPUP = 1 -->
+<!-- EVENT simple_header_head_append -->
+
+{$STYLESHEETS}
+
</head>
<body id="phpbb" class="nojs {S_CONTENT_DIRECTION} {BODY_CLASS}">
diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html
index 6c96be864a..943774c6ec 100644
--- a/phpBB/styles/prosilver/template/ucp_agreement.html
+++ b/phpBB/styles/prosilver/template/ucp_agreement.html
@@ -10,6 +10,7 @@
*/
function change_language(lang_iso)
{
+ document.cookie = '{COOKIE_NAME}_lang=' + lang_iso + '; path={COOKIE_PATH}';
document.forms['register'].change_lang.value = lang_iso;
document.forms['register'].submit();
}
@@ -33,8 +34,10 @@
<div class="panel">
<div class="inner">
<div class="content">
- <h2>{SITENAME} - {L_REGISTRATION}</h2>
+ <h2 class="sitename-title">{SITENAME} - {L_REGISTRATION}</h2>
+ <!-- EVENT ucp_agreement_terms_before -->
<p><!-- IF S_SHOW_COPPA -->{L_COPPA_BIRTHDAY}<!-- ELSE -->{L_TERMS_OF_USE}<!-- ENDIF --></p>
+ <!-- EVENT ucp_agreement_terms_after -->
</div>
</div>
</div>
@@ -60,7 +63,7 @@
<div class="panel">
<div class="inner">
<div class="content">
- <h2>{SITENAME} - {AGREEMENT_TITLE}</h2>
+ <h2 class="sitename-title">{SITENAME} - {AGREEMENT_TITLE}</h2>
<p>{AGREEMENT_TEXT}</p>
<hr class="dashed" />
<p><a href="{U_BACK}" class="button2">{L_BACK}</a></p>
diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html
index ed39e80c12..4731683a80 100644
--- a/phpBB/styles/prosilver/template/ucp_attachments.html
+++ b/phpBB/styles/prosilver/template/ucp_attachments.html
@@ -38,7 +38,7 @@
<dl>
<dt>
<div class="list-inner">
- <a href="{attachrow.U_VIEW_ATTACHMENT}" class="topictitle">{attachrow.FILENAME}</a> ({attachrow.SIZE})<br />
+ <a href="{attachrow.U_VIEW_ATTACHMENT}" class="topictitle attachment-filename ellipsis-text" title="{attachrow.FILENAME}">{attachrow.FILENAME}</a> ({attachrow.SIZE})<br />
<!-- IF attachrow.S_IN_MESSAGE -->{L_PM}{L_COLON} <!-- ELSE -->{L_TOPIC}{L_COLON} <!-- ENDIF --><a href="{attachrow.U_VIEW_TOPIC}">{attachrow.TOPIC_TITLE}</a>
</div>
</dt>
diff --git a/phpBB/styles/prosilver/template/ucp_header.html b/phpBB/styles/prosilver/template/ucp_header.html
index 8ce2c54294..102ea5a3a0 100644
--- a/phpBB/styles/prosilver/template/ucp_header.html
+++ b/phpBB/styles/prosilver/template/ucp_header.html
@@ -1,6 +1,6 @@
<!-- INCLUDE overall_header.html -->
-<h2>{L_UCP}</h2>
+<h2 class="ucp-title">{L_UCP}</h2>
<div id="tabs">
<ul>
diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html
index f14e4708e7..81171e97b2 100644
--- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html
+++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html
@@ -33,27 +33,33 @@
<!-- END custom_fields -->
<!-- EVENT ucp_pm_viewmessage_custom_fields_after -->
-
- <!-- IF U_PM or U_EMAIL or U_JABBER -->
- <dd class="profile-contact">
- <ul class="profile-icons">
- <!-- EVENT ucp_pm_viewmessage_contact_fields_before -->
- <!-- IF U_PM --><li class="pm-icon"><a href="{U_PM}" title="{L_PRIVATE_MESSAGE}"><span>{L_PRIVATE_MESSAGE}</span></a></li><!-- ENDIF -->
- <!-- IF U_EMAIL --><li class="email-icon"><a href="{U_EMAIL}" title="{L_SEND_EMAIL_USER} {MESSAGE_AUTHOR}"><span>{L_SEND_EMAIL_USER} {MESSAGE_AUTHOR}</span></a></li><!-- ENDIF -->
- <!-- IF U_JABBER --><li class="jabber-icon"><a href="{U_JABBER}" onclick="popup(this.href, 550, 320); return false;" title="{L_JABBER}"><span>{L_JABBER}</span></a></li><!-- ENDIF -->
- <!-- BEGIN custom_fields -->
- <!-- IF custom_fields.S_PROFILE_CONTACT -->
- <li class="{custom_fields.PROFILE_FIELD_IDENT}-icon">
- <a href="<!-- IF custom_fields.PROFILE_FIELD_CONTACT -->{custom_fields.PROFILE_FIELD_CONTACT}<!-- ELSE -->{U_MESSAGE_AUTHOR}<!-- ENDIF -->">
- <span>{custom_fields.PROFILE_FIELD_NAME}</span>
- </a>
- </li>
- <!-- ENDIF -->
- <!-- END custom_fields -->
- <!-- EVENT ucp_pm_viewmessage_contact_fields_after -->
- </ul>
- </dd>
+ <!-- EVENT ucp_pm_viewmessage_contact_fields_before -->
+ <!-- IF .contact -->
+ <dd class="profile-contact">
+ <strong>{L_CONTACT_USER}{L_COLON}</strong>
+ <div class="dropdown-container dropdown-left">
+ <a href="#" class="dropdown-trigger"><span class="imageset icon_contact"></span></a>
+ <div class="dropdown hidden">
+ <div class="pointer"><div class="pointer-inner"></div></div>
+ <div class="dropdown-contents contact-icons">
+ <!-- BEGIN contact -->
+ {% set REMAINDER = contact.S_ROW_COUNT % 4 %}
+ <!-- DEFINE $S_LAST_CELL = ((REMAINDER eq 3) or (contact.S_LAST_ROW and contact.S_NUM_ROWS < 4)) -->
+ <!-- IF REMAINDER eq 0 -->
+ <div>
+ <!-- ENDIF -->
+ <a href="<!-- IF contact.U_CONTACT -->{contact.U_CONTACT}<!-- ELSE -->{contact.U_PROFILE_AUTHOR}<!-- ENDIF -->" title="{contact.NAME}"<!-- IF $S_LAST_CELL --> class="last-cell"<!-- ENDIF --><!-- IF contact.ID eq 'jabber' --> onclick="popup(this.href, 550, 320); return false;"<!-- ENDIF -->>
+ <span class="contact-icon {contact.ID}-icon"></span>
+ </a>
+ <!-- IF REMAINDER eq 3 or contact.S_LAST_ROW -->
+ </div>
+ <!-- ENDIF -->
+ <!-- END contact -->
+ </div>
+ </div>
+ </dd>
<!-- ENDIF -->
+ <!-- EVENT ucp_pm_viewmessage_contact_fields_after -->
</dl>
<div class="postbody">
diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html
index fc469eff36..b27003faab 100644
--- a/phpBB/styles/prosilver/template/ucp_register.html
+++ b/phpBB/styles/prosilver/template/ucp_register.html
@@ -7,6 +7,7 @@
*/
function change_language(lang_iso)
{
+ document.cookie = '{COOKIE_NAME}_lang=' + lang_iso + '; path={COOKIE_PATH}';
document.forms['register'].change_lang.value = lang_iso;
document.forms['register'].submit.click();
}
diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html
index 7372834dd3..6646f40f01 100644
--- a/phpBB/styles/prosilver/template/viewforum_body.html
+++ b/phpBB/styles/prosilver/template/viewforum_body.html
@@ -1,6 +1,6 @@
<!-- INCLUDE overall_header.html -->
<!-- IF U_MCP or U_ACP --><p class="responsive-center">[&nbsp;<!-- IF U_ACP --><a href="{U_ACP}" title="{L_ACP}" data-responsive-text="{L_ACP_SHORT}">{L_ACP}</a><!-- IF U_MCP -->&nbsp;|&nbsp;<!-- ENDIF --><!-- ENDIF --><!-- IF U_MCP --><a href="{U_MCP}" title="{L_MCP}" data-responsive-text="{L_MCP_SHORT}">{L_MCP}</a><!-- ENDIF -->&nbsp;]</p><!-- ENDIF -->
-<h2><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2>
+<h2 class="forum-title"><!-- EVENT viewforum_forum_name_prepend --><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a><!-- EVENT viewforum_forum_name_append --></h2>
<!-- IF FORUM_DESC or MODERATORS or U_MCP -->
<div>
diff --git a/phpBB/styles/prosilver/template/viewonline_body.html b/phpBB/styles/prosilver/template/viewonline_body.html
index 13f459b57f..553e322f92 100644
--- a/phpBB/styles/prosilver/template/viewonline_body.html
+++ b/phpBB/styles/prosilver/template/viewonline_body.html
@@ -1,6 +1,6 @@
<!-- INCLUDE overall_header.html -->
-<h2>{TOTAL_REGISTERED_USERS_ONLINE}</h2>
+<h2 class="viewonline-title">{TOTAL_REGISTERED_USERS_ONLINE}</h2>
<p>{TOTAL_GUEST_USERS_ONLINE}<!-- IF S_SWITCH_GUEST_DISPLAY --> &bull; <a href="{U_SWITCH_GUEST_DISPLAY}">{L_SWITCH_GUEST_DISPLAY}</a><!-- ENDIF --></p>
<ul class="linklist">
diff --git a/phpBB/styles/prosilver/template/viewonline_whois.html b/phpBB/styles/prosilver/template/viewonline_whois.html
index 8abd933efa..031f18afdc 100644
--- a/phpBB/styles/prosilver/template/viewonline_whois.html
+++ b/phpBB/styles/prosilver/template/viewonline_whois.html
@@ -1,6 +1,6 @@
<!-- INCLUDE simple_header.html -->
-<h2>{L_WHOIS}</h2>
+<h2 class="whois-title">{L_WHOIS}</h2>
<div class="panel">
<div class="inner">
diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html
index 649129923a..17c73b82f4 100644
--- a/phpBB/styles/prosilver/template/viewtopic_body.html
+++ b/phpBB/styles/prosilver/template/viewtopic_body.html
@@ -1,6 +1,6 @@
<!-- INCLUDE overall_header.html -->
<!-- IF U_MCP or U_ACP --><p class="responsive-center">[&nbsp;<!-- IF U_ACP --><a href="{U_ACP}" title="{L_ACP}" data-responsive-text="{L_ACP_SHORT}">{L_ACP}</a><!-- IF U_MCP -->&nbsp;|&nbsp;<!-- ENDIF --><!-- ENDIF --><!-- IF U_MCP --><a href="{U_MCP}" title="{L_MCP}" data-responsive-text="{L_MCP_SHORT}">{L_MCP}</a><!-- ENDIF -->&nbsp;]</p><!-- ENDIF -->
-<h2><!-- EVENT viewtopic_topic_title_prepend --><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2>
+<h2 class="topic-title"><!-- EVENT viewtopic_topic_title_prepend --><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a><!-- EVENT viewtopic_topic_title_append --></h2>
<!-- NOTE: remove the style="display: none" when you want to have the forum description on the topic body -->
<!-- IF FORUM_DESC --><div style="display: none !important;">{FORUM_DESC}<br /></div><!-- ENDIF -->
@@ -67,17 +67,19 @@
<div class="inner">
<div class="content">
- <h2>{POLL_QUESTION}</h2>
+ <h2 class="poll-title"><!-- EVENT viewtopic_body_poll_question_prepend -->{POLL_QUESTION}<!-- EVENT viewtopic_body_poll_question_append --></h2>
<p class="author">{L_POLL_LENGTH}<!-- IF S_CAN_VOTE and L_POLL_LENGTH --><br /><!-- ENDIF --><!-- IF S_CAN_VOTE --><span class="poll_max_votes">{L_MAX_VOTES}</span><!-- ENDIF --></p>
<fieldset class="polls">
<!-- BEGIN poll_option -->
+ <!-- EVENT viewtopic_body_poll_option_before -->
<dl class="<!-- IF poll_option.POLL_OPTION_VOTED -->voted<!-- ENDIF --><!-- IF poll_option.POLL_OPTION_MOST_VOTES --> most-votes<!-- ENDIF -->"<!-- IF poll_option.POLL_OPTION_VOTED --> title="{L_POLL_VOTED_OPTION}"<!-- ENDIF --> data-poll-option-id="{poll_option.POLL_OPTION_ID}">
<dt><!-- IF S_CAN_VOTE --><label for="vote_{poll_option.POLL_OPTION_ID}">{poll_option.POLL_OPTION_CAPTION}</label><!-- ELSE -->{poll_option.POLL_OPTION_CAPTION}<!-- ENDIF --></dt>
<!-- IF S_CAN_VOTE --><dd style="width: auto;" class="poll_option_select"><!-- IF S_IS_MULTI_CHOICE --><input type="checkbox" name="vote_id[]" id="vote_{poll_option.POLL_OPTION_ID}" value="{poll_option.POLL_OPTION_ID}"<!-- IF poll_option.POLL_OPTION_VOTED --> checked="checked"<!-- ENDIF --> /><!-- ELSE --><input type="radio" name="vote_id[]" id="vote_{poll_option.POLL_OPTION_ID}" value="{poll_option.POLL_OPTION_ID}"<!-- IF poll_option.POLL_OPTION_VOTED --> checked="checked"<!-- ENDIF --> /><!-- ENDIF --></dd><!-- ENDIF -->
<dd class="resultbar<!-- IF not S_DISPLAY_RESULTS --> hidden<!-- ENDIF -->"><div class="<!-- IF poll_option.POLL_OPTION_PCT < 20 -->pollbar1<!-- ELSEIF poll_option.POLL_OPTION_PCT < 40 -->pollbar2<!-- ELSEIF poll_option.POLL_OPTION_PCT < 60 -->pollbar3<!-- ELSEIF poll_option.POLL_OPTION_PCT < 80 -->pollbar4<!-- ELSE -->pollbar5<!-- ENDIF -->" style="width:{poll_option.POLL_OPTION_PERCENT_REL};">{poll_option.POLL_OPTION_RESULT}</div></dd>
<dd class="poll_option_percent<!-- IF not S_DISPLAY_RESULTS --> hidden<!-- ENDIF -->"><!-- IF poll_option.POLL_OPTION_RESULT == 0 -->{L_NO_VOTES}<!-- ELSE -->{poll_option.POLL_OPTION_PERCENT}<!-- ENDIF --></dd>
</dl>
+ <!-- EVENT viewtopic_body_poll_option_after -->
<!-- END poll_option -->
<dl class="poll_total_votes<!-- IF not S_DISPLAY_RESULTS --> hidden<!-- ENDIF -->">
@@ -113,8 +115,8 @@
<!-- BEGIN postrow -->
<!-- EVENT viewtopic_body_postrow_post_before -->
- <!-- IF postrow.S_FIRST_UNREAD --><a id="unread"></a><!-- ENDIF -->
- <div id="p{postrow.POST_ID}" class="post <!-- IF postrow.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF postrow.S_UNREAD_POST --> unreadpost<!-- ENDIF --><!-- IF postrow.S_POST_REPORTED --> reported<!-- ENDIF --><!-- IF postrow.S_POST_DELETED --> deleted<!-- ENDIF --><!-- IF postrow.S_ONLINE and not postrow.S_POST_HIDDEN --> online<!-- ENDIF -->">
+ <!-- IF postrow.S_FIRST_UNREAD --><a id="unread" data-url="{postrow.U_MINI_POST}"></a><!-- ENDIF -->
+ <div id="p{postrow.POST_ID}" class="post <!-- IF postrow.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF postrow.S_UNREAD_POST --> unreadpost<!-- ENDIF --><!-- IF postrow.S_POST_REPORTED --> reported<!-- ENDIF --><!-- IF postrow.S_POST_DELETED --> deleted<!-- ENDIF --><!-- IF postrow.S_ONLINE and not postrow.S_POST_HIDDEN --> online<!-- ENDIF --><!-- IF postrow.POSTER_WARNINGS --> warned<!-- ENDIF -->">
<div class="inner">
<dl class="postprofile" id="profile{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->>
@@ -129,6 +131,7 @@
<!-- IF postrow.POSTER_POSTS != '' --><dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> {postrow.POSTER_POSTS}</dd><!-- ENDIF -->
<!-- IF postrow.POSTER_JOINED --><dd class="profile-joined"><strong>{L_JOINED}{L_COLON}</strong> {postrow.POSTER_JOINED}</dd><!-- ENDIF -->
+ <!-- IF postrow.POSTER_WARNINGS --><dd class="profile-warnings"><strong>{L_WARNINGS}{L_COLON}</strong> {postrow.POSTER_WARNINGS}</dd><!-- ENDIF -->
<!-- IF postrow.S_PROFILE_FIELD1 -->
<!-- Use a construct like this to include admin defined profile fields. Replace FIELD1 with the name of your field. -->
@@ -143,26 +146,34 @@
<!-- END custom_fields -->
<!-- EVENT viewtopic_body_postrow_custom_fields_after -->
- <!-- IF not S_IS_BOT -->
- <!-- IF postrow.U_PM or postrow.U_EMAIL or postrow.U_JABBER -->
+ <!-- EVENT viewtopic_body_contact_fields_before -->
+ <!-- IF not S_IS_BOT and .postrow.contact -->
<dd class="profile-contact">
- <ul class="profile-icons">
- <!-- IF postrow.U_PM --><li class="pm-icon"><a href="{postrow.U_PM}" title="{L_PRIVATE_MESSAGE}"><span>{L_PRIVATE_MESSAGE}</span></a></li><!-- ENDIF -->
- <!-- IF postrow.U_EMAIL --><li class="email-icon"><a href="{postrow.U_EMAIL}" title="{L_SEND_EMAIL_USER} {postrow.POST_AUTHOR}"><span>{L_SEND_EMAIL_USER} {postrow.POST_AUTHOR}</span></a></li><!-- ENDIF -->
- <!-- IF postrow.U_JABBER --><li class="jabber-icon"><a href="{postrow.U_JABBER}" onclick="popup(this.href, 550, 320); return false;" title="{L_JABBER}"><span>{L_JABBER}</span></a></li><!-- ENDIF -->
- <!-- BEGIN custom_fields -->
- <!-- IF postrow.custom_fields.S_PROFILE_CONTACT -->
- <li class="{postrow.custom_fields.PROFILE_FIELD_IDENT}-icon">
- <a href="<!-- IF postrow.custom_fields.PROFILE_FIELD_CONTACT -->{postrow.custom_fields.PROFILE_FIELD_CONTACT}<!-- ELSE -->{postrow.U_POST_AUTHOR}<!-- ENDIF -->">
- <span>{postrow.custom_fields.PROFILE_FIELD_NAME}</span>
- </a>
- </li>
- <!-- ENDIF -->
- <!-- END custom_fields -->
- </ul>
+ <strong>{L_CONTACT_USER}{L_COLON}</strong>
+ <div class="dropdown-container dropdown-left">
+ <a href="#" class="dropdown-trigger"><span class="imageset icon_contact"></span></a>
+ <div class="dropdown hidden">
+ <div class="pointer"><div class="pointer-inner"></div></div>
+ <div class="dropdown-contents contact-icons">
+ <!-- BEGIN contact -->
+ {% set REMAINDER = postrow.contact.S_ROW_COUNT % 4 %}
+ <!-- DEFINE $S_LAST_CELL = ((REMAINDER eq 3) or (postrow.contact.S_LAST_ROW and postrow.contact.S_NUM_ROWS < 4)) -->
+ <!-- IF REMAINDER eq 0 -->
+ <div>
+ <!-- ENDIF -->
+ <a href="<!-- IF postrow.contact.U_CONTACT -->{postrow.contact.U_CONTACT}<!-- ELSE -->{postrow.contact.U_PROFILE_AUTHOR}<!-- ENDIF -->" title="{postrow.contact.NAME}"<!-- IF $S_LAST_CELL --> class="last-cell"<!-- ENDIF --><!-- IF postrow.contact.ID eq 'jabber' --> onclick="popup(this.href, 550, 320); return false;"<!-- ENDIF -->>
+ <span class="contact-icon {postrow.contact.ID}-icon"></span>
+ </a>
+ <!-- IF REMAINDER eq 3 or postrow.contact.S_LAST_ROW -->
+ </div>
+ <!-- ENDIF -->
+ <!-- END contact -->
+ </div>
+ </div>
+ </div>
</dd>
<!-- ENDIF -->
- <!-- ENDIF -->
+ <!-- EVENT viewtopic_body_contact_fields_after -->
</dl>
@@ -204,7 +215,7 @@
<!-- IF postrow.S_POST_UNAPPROVED -->
<form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}">
<p class="post-notice unapproved">
- <strong>{L_POST_UNAPPROVED}</strong>
+ <strong>{L_POST_UNAPPROVED_ACTION}</strong>
<input class="button2" type="submit" value="{L_DISAPPROVE}" name="action[disapprove]" />
<input class="button1" type="submit" value="{L_APPROVE}" name="action[approve]" />
<input type="hidden" name="post_id_list[]" value="{postrow.POST_ID}" />
@@ -214,7 +225,7 @@
<!-- ELSEIF postrow.S_POST_DELETED -->
<form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}">
<p class="post-notice deleted">
- <strong>{L_POST_DELETED}</strong>
+ <strong>{L_POST_DELETED_ACTION}</strong>
<input class="button2" type="submit" value="{L_DELETE}" name="action[disapprove]" />
<input class="button1" type="submit" value="{L_RESTORE}" name="action[restore]" />
<input type="hidden" name="post_id_list[]" value="{postrow.POST_ID}" />
diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css
index 3422af8b64..9ca04516cc 100644
--- a/phpBB/styles/prosilver/theme/buttons.css
+++ b/phpBB/styles/prosilver/theme/buttons.css
@@ -214,20 +214,53 @@ ul.profile-icons.responsive a.responsive-menu-link:before {
max-width: 40%;
}
+.contact-icons.dropdown-contents {
+ min-width: 0;
+ padding: 0;
+}
+
+.contact-icon {
+ background-repeat: no-repeat;
+ display: block;
+ height: 16px;
+ width: 16px;
+}
+.contact-icons a {
+ border-bottom: 1px dotted;
+ border-right: 1px dotted;
+ display: block;
+ float: left;
+ padding: 8px;
+}
+
+.contact-icons .last-cell {
+ border-right: none;
+}
+
+.contact-icons div:last-child a {
+ border-bottom: none;
+}
+
+.contact-icons div {
+ clear: left;
+}
+
+
/* Profile & navigation icons */
-.email-icon, .email-icon a { background: none top left no-repeat; }
-.aim-icon, .aim-icon a { background: none top left no-repeat; }
-.phpbb_aol-icon, .phpbb_aol-icon a { background: none top left no-repeat; }
-.yahoo-icon, .yahoo-icon a { background: none top left no-repeat; }
-.phpbb_yahoo-icon, .phpbb_yahoo-icon a { background: none top left no-repeat; }
-.web-icon, .web-icon a { background: none top left no-repeat; }
-.phpbb_website-icon, .phpbb_website-icon a { background: none top left no-repeat; }
-.msnm-icon, .msnm-icon a { background: none top left no-repeat; }
-.phpbb_wlm-icon, .phpbb_wlm-icon a { background: none top left no-repeat; }
-.icq-icon, .icq-icon a { background: none top left no-repeat; }
-.phpbb_icq-icon, .phpbb_icq-icon a { background: none top left no-repeat; }
-.jabber-icon, .jabber-icon a { background: none top left no-repeat; }
-.pm-icon, .pm-icon a { background: none top left no-repeat; }
+.pm-icon { background-position: 0 0; }
+.email-icon { background-position: -21px 0; }
+.jabber-icon { background-position: -80px 0; }
+.phpbb_icq-icon { background-position: -61px 0 ; }
+.phpbb_wlm-icon { background-position: -182px 0; }
+.phpbb_aol-icon { background-position: -244px 0; }
+.phpbb_website-icon { background-position: -40px 0; }
+.phpbb_youtube-icon { background-position: -98px 0; }
+.phpbb_facebook-icon { background-position: -119px 0; }
+.phpbb_google_plus-icon { background-position: -140px 0; }
+.phpbb_skype-icon { background-position: -161px 0; }
+.phpbb_twitter-icon { background-position: -203px 0; }
+.phpbb_yahoo-icon { background-position: -224px 0; }
+
.quote-icon, .quote-icon a { background: none top left no-repeat; }
/* Moderator icons */
diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css
index 30650e7411..f43dfcfcce 100644
--- a/phpBB/styles/prosilver/theme/colours.css
+++ b/phpBB/styles/prosilver/theme/colours.css
@@ -660,6 +660,10 @@ fieldset.polls dd div {
background-image: url("./en/icon_user_online.gif");
}
+dd.profile-warnings {
+ color: #BC2A4D;
+}
+
/*
--------------------------------------------------------------
Colours and backgrounds for buttons.css
@@ -710,6 +714,14 @@ Colours and backgrounds for buttons.css
background-image: url("images/buttons.png");
}
+.contact-icons a {
+ border-color: #DCDCDC;
+}
+
+.contact-icons a:hover {
+ background-color: #F2F6F9;
+}
+
/* Icon images
---------------------------------------- */
.icon-faq { background-image: url("./images/icon_faq.gif"); }
@@ -732,19 +744,8 @@ Colours and backgrounds for buttons.css
.icon-print { background-image: url("./images/icon_print.gif"); }
/* Profile & navigation icons */
-.email-icon, .email-icon a { background-image: url("./images/icon_contact_email.gif"); }
-.phpbb_aol-icon, .phpbb_aol-icon a { background-image: url("./images/icon_contact_aim.gif"); }
-.aim-icon, .aim-icon a { background-image: url("./images/icon_contact_aim.gif"); }
-.yahoo-icon, .yahoo-icon a { background-image: url("./images/icon_contact_yahoo.gif"); }
-.phpbb_yahoo-icon, .phpbb_yahoo-icon a { background-image: url("./images/icon_contact_yahoo.gif"); }
-.web-icon, .web-icon a { background-image: url("./images/icon_contact_www.gif"); }
-.phpbb_website-icon, .phpbb_website-icon a { background-image: url("./images/icon_contact_www.gif"); }
-.msnm-icon, .msnm-icon a { background-image: url("./images/icon_contact_msnm.gif"); }
-.phpbb_wlm-icon, .phpbb_wlm-icon a { background-image: url("./images/icon_contact_msnm.gif"); }
-.icq-icon, .icq-icon a { background-image: url("./images/icon_contact_icq.gif"); }
-.phpbb_icq-icon, .phpbb_icq-icon a { background-image: url("./images/icon_contact_icq.gif"); }
-.jabber-icon, .jabber-icon a { background-image: url("./images/icon_contact_jabber.gif"); }
-.pm-icon, .pm-icon a { background-image: url("./en/icon_contact_pm.gif"); }
+.contact-icon { background-image: url("./images/icons_contact.png"); }
+
.quote-icon, .quote-icon a { background-image: url("./en/icon_post_quote.gif"); }
ul.profile-icons.responsive a.responsive-menu-link { background-image: url("./images/icon_post_menu.png"); }
diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css
index 3d5a0a433d..94fad55ae9 100644
--- a/phpBB/styles/prosilver/theme/common.css
+++ b/phpBB/styles/prosilver/theme/common.css
@@ -261,7 +261,6 @@ a#logo:hover {
}
.navbar {
- padding: 0 10px;
padding: 5px 10px 5px 10px;
border-radius: 7px;
}
@@ -470,6 +469,11 @@ ul.linklist.bulletin li.no-bulletin:before {
border: 1px solid transparent;
border-radius: 5px;
padding: 9px 0 0;
+ margin-right: -500px;
+}
+
+.dropdown.live-search {
+ top: auto;
}
.dropdown-container.topic-tools {
@@ -485,6 +489,8 @@ ul.linklist.bulletin li.no-bulletin:before {
.dropdown-left .dropdown, .nojs .rightside .dropdown {
left: auto;
right: 0;
+ margin-left: -500px;
+ margin-right: 0;
}
.dropdown-button-control .dropdown {
diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css
index d27fb81fee..b66c841d7c 100644
--- a/phpBB/styles/prosilver/theme/content.css
+++ b/phpBB/styles/prosilver/theme/content.css
@@ -32,7 +32,7 @@ ul.topiclist dt, ul.topiclist dd {
ul.topiclist dt {
width: 100%;
- margin-right: -410px;
+ margin-right: -440px;
font-size: 1.1em;
}
@@ -49,7 +49,7 @@ ul.topiclist.two-columns dt {
}
ul.topiclist dt .list-inner {
- margin-right: 410px;
+ margin-right: 440px;
padding-left: 5px;
padding-right: 5px;
}
@@ -119,11 +119,11 @@ li.header dt, li.header dd {
li.header dt {
font-weight: bold;
width: 100%;
- margin-right: -410px;
+ margin-right: -440px;
}
li.header dt .list-inner {
- margin-right: 410px;
+ margin-right: 440px;
}
li.header dd {
@@ -181,6 +181,10 @@ dd.posts, dd.topics, dd.views, dd.extra, dd.mark {
font-size: 1.2em;
}
+dd.posts, dd.topics, dd.views {
+ width: 95px;
+}
+
/* List in forum description */
dl.icon dt ol,
dl.icon dt ul {
@@ -731,6 +735,24 @@ fieldset.polls dd div {
height: auto !important;
}
+dd.profile-warnings {
+ font-weight: bold;
+}
+
+dd.profile-contact {
+ overflow: visible;
+}
+
+.profile-contact .dropdown-container {
+ display: inline-block;
+ text-align: left;
+ width: 30px;
+}
+
+.profile-contact .icon_contact {
+ vertical-align: middle;
+}
+
.online {
background-image: none;
background-position: 100% 0;
@@ -779,6 +801,17 @@ div.dl_links {
display: inline-block;
}
+.attachment-filename {
+ width: 100%;
+}
+
+.ellipsis-text {
+ display: inline-block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
/* Show scrollbars for items with overflow on iOS devices
----------------------------------------*/
.postbody .content::-webkit-scrollbar, #topicreview::-webkit-scrollbar, #post_details::-webkit-scrollbar, .codebox code::-webkit-scrollbar, .attachbox dd::-webkit-scrollbar, .attach-image::-webkit-scrollbar, .dropdown-extended ul::-webkit-scrollbar {
diff --git a/phpBB/styles/prosilver/theme/en/stylesheet.css b/phpBB/styles/prosilver/theme/en/stylesheet.css
index 82b7df0830..d8ca2558e5 100644
--- a/phpBB/styles/prosilver/theme/en/stylesheet.css
+++ b/phpBB/styles/prosilver/theme/en/stylesheet.css
@@ -7,16 +7,10 @@ ul.profile-icons li.edit-icon { width: 42px; height: 20px; }
.online { background-image: url("./icon_user_online.gif"); }
/* Icon images */
-.pm-icon, .pm-icon a { background-image: url("./icon_contact_pm.gif"); }
.quote-icon, .quote-icon a { background-image: url("./icon_post_quote.gif"); }
.edit-icon, .edit-icon a { background-image: url("./icon_post_edit.gif"); }
/* EN Language Pack */
-.imageset.icon_contact_pm {
- background-image: url("./icon_contact_pm.gif");
- padding-left: 28px;
- padding-top: 20px;
-}
.imageset.icon_post_edit {
background-image: url("./icon_post_edit.gif");
padding-left: 42px;
diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css
index 88f2bd65c5..0c0a3e5ca9 100644
--- a/phpBB/styles/prosilver/theme/forms.css
+++ b/phpBB/styles/prosilver/theme/forms.css
@@ -96,7 +96,7 @@ fieldset.fields1 div {
}
/* Set it back to 0px for the reCaptcha divs: PHPBB3-9587 */
-fieldset.fields1 #recaptcha_widget_div div {
+fieldset.fields1 #recaptcha_widget_div div, fieldset.fields1 .live-search div {
margin-bottom: 0;
}
diff --git a/phpBB/styles/prosilver/theme/images/icon_contact.png b/phpBB/styles/prosilver/theme/images/icon_contact.png
new file mode 100644
index 0000000000..04e4d9ad17
--- /dev/null
+++ b/phpBB/styles/prosilver/theme/images/icon_contact.png
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/images/icon_contact_aim.gif b/phpBB/styles/prosilver/theme/images/icon_contact_aim.gif
deleted file mode 100644
index be039fcde2..0000000000
--- a/phpBB/styles/prosilver/theme/images/icon_contact_aim.gif
+++ /dev/null
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/images/icon_contact_email.gif b/phpBB/styles/prosilver/theme/images/icon_contact_email.gif
deleted file mode 100644
index caa3683005..0000000000
--- a/phpBB/styles/prosilver/theme/images/icon_contact_email.gif
+++ /dev/null
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/images/icon_contact_icq.gif b/phpBB/styles/prosilver/theme/images/icon_contact_icq.gif
deleted file mode 100644
index 48a09373eb..0000000000
--- a/phpBB/styles/prosilver/theme/images/icon_contact_icq.gif
+++ /dev/null
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/images/icon_contact_jabber.gif b/phpBB/styles/prosilver/theme/images/icon_contact_jabber.gif
deleted file mode 100644
index e335433e97..0000000000
--- a/phpBB/styles/prosilver/theme/images/icon_contact_jabber.gif
+++ /dev/null
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/images/icon_contact_msnm.gif b/phpBB/styles/prosilver/theme/images/icon_contact_msnm.gif
deleted file mode 100644
index e25469c3a5..0000000000
--- a/phpBB/styles/prosilver/theme/images/icon_contact_msnm.gif
+++ /dev/null
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/images/icon_contact_www.gif b/phpBB/styles/prosilver/theme/images/icon_contact_www.gif
deleted file mode 100644
index 83cee9728d..0000000000
--- a/phpBB/styles/prosilver/theme/images/icon_contact_www.gif
+++ /dev/null
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/images/icon_contact_yahoo.gif b/phpBB/styles/prosilver/theme/images/icon_contact_yahoo.gif
deleted file mode 100644
index 305f297fdb..0000000000
--- a/phpBB/styles/prosilver/theme/images/icon_contact_yahoo.gif
+++ /dev/null
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/images/icons_contact.png b/phpBB/styles/prosilver/theme/images/icons_contact.png
new file mode 100644
index 0000000000..f84abd36a5
--- /dev/null
+++ b/phpBB/styles/prosilver/theme/images/icons_contact.png
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/imageset.css b/phpBB/styles/prosilver/theme/imageset.css
index e6d306c7fd..6bc345889e 100644
--- a/phpBB/styles/prosilver/theme/imageset.css
+++ b/phpBB/styles/prosilver/theme/imageset.css
@@ -356,13 +356,14 @@ span.imageset {
padding-top: 20px;
}
+.imageset.icon_contact {
+ background-image: url("./images/icon_contact.png");
+ padding-left: 16px;
+ padding-top: 12px;
+}
+
/* English images for fallback */
-.imageset.icon_contact_pm {
- background-image: url("./en/icon_contact_pm.gif");
- padding-left: 28px;
- padding-top: 20px;
-}
.imageset.icon_post_edit {
background-image: url("./en/icon_post_edit.gif");
padding-left: 42px;
diff --git a/phpBB/styles/prosilver/theme/plupload.css b/phpBB/styles/prosilver/theme/plupload.css
index 8569eca662..f81064dbe6 100644
--- a/phpBB/styles/prosilver/theme/plupload.css
+++ b/phpBB/styles/prosilver/theme/plupload.css
@@ -74,3 +74,8 @@
height: 16px;
width: 16px;
}
+
+.file-name {
+ max-width: 65%;
+ vertical-align: bottom;
+}
diff --git a/phpBB/styles/prosilver/theme/tweaks.css b/phpBB/styles/prosilver/theme/tweaks.css
index 456bbf3479..9a8ed5d399 100644
--- a/phpBB/styles/prosilver/theme/tweaks.css
+++ b/phpBB/styles/prosilver/theme/tweaks.css
@@ -66,3 +66,8 @@ dd.option {
.icon-notification {
*z-index: 2;
}
+
+/* Fixes header-avatar aspect-ratio in IE8 */
+.header-avatar img {
+ height: 25px;
+}
diff --git a/phpBB/styles/subsilver2/style.cfg b/phpBB/styles/subsilver2/style.cfg
index c534c30bb9..8c62519738 100644
--- a/phpBB/styles/subsilver2/style.cfg
+++ b/phpBB/styles/subsilver2/style.cfg
@@ -18,8 +18,8 @@
# General Information about this style
name = subsilver2
copyright = © 2005 phpBB Group
-style_version = 3.1.0-b2
-phpbb_version = 3.1.0-b2
+style_version = 3.1.0-b3
+phpbb_version = 3.1.0-b3
# Defining a different template bitfield
# template_bitfield = lNg=
diff --git a/phpBB/styles/subsilver2/template/breadcrumbs.html b/phpBB/styles/subsilver2/template/breadcrumbs.html
index 09ee9a8606..646525c206 100644
--- a/phpBB/styles/subsilver2/template/breadcrumbs.html
+++ b/phpBB/styles/subsilver2/template/breadcrumbs.html
@@ -2,9 +2,11 @@
<table class="tablebg" width="100%" cellspacing="1" cellpadding="0" style="margin-top: 5px;">
<tr>
<td class="row1">
- <p class="breadcrumbs"><!-- IF U_SITE_HOME --><a href="{U_SITE_HOME}"{$MICRODATA}>{L_SITE_HOME}</a> <strong>&#187;</strong> <!-- ENDIF --><a href="{U_INDEX}"{$MICRODATA}>{L_INDEX}</a><!-- BEGIN navlinks --> &#187; <a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}>{navlinks.FORUM_NAME}</a><!-- END navlinks -->
+ <p class="breadcrumbs"><!-- IF U_SITE_HOME --><a href="{U_SITE_HOME}"{$MICRODATA}>{L_SITE_HOME}</a> <strong>&#187;</strong> <!-- ENDIF --><a href="{U_INDEX}"{$MICRODATA}>{L_INDEX}</a><!-- BEGIN navlinks --><!-- EVENT overall_header_navlink_prepend --> &#187; <a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}>{navlinks.FORUM_NAME}</a><!-- EVENT overall_header_navlink_append --><!-- END navlinks -->
<!-- EVENT overall_header_breadcrumb_append --></p>
+ <!-- EVENT overall_footer_timezone_before -->
<p class="datetime">{S_TIMEZONE}</p>
+ <!-- EVENT overall_footer_timezone_after -->
</td>
</tr>
</table>
diff --git a/phpBB/styles/subsilver2/template/index_body.html b/phpBB/styles/subsilver2/template/index_body.html
index ea4cc76171..cb67768b15 100644
--- a/phpBB/styles/subsilver2/template/index_body.html
+++ b/phpBB/styles/subsilver2/template/index_body.html
@@ -15,7 +15,14 @@
<!-- INCLUDE forumlist_body.html -->
<!-- IF not S_IS_BOT or U_TEAM -->
-<span class="gensmall"><!-- IF not S_IS_BOT --><a href="{U_DELETE_COOKIES}">{L_DELETE_COOKIES}</a><!-- ENDIF --><!-- IF not S_IS_BOT and U_TEAM --> | <!-- ENDIF --><!-- IF U_TEAM --><a href="{U_TEAM}">{L_THE_TEAM}</a><!-- ENDIF --></span><br />
+<span class="gensmall">
+ <!-- IF not S_IS_BOT --><a href="{U_DELETE_COOKIES}">{L_DELETE_COOKIES}</a><!-- ENDIF -->
+ <!-- IF not S_IS_BOT and U_TEAM --> | <!-- ENDIF -->
+ <!-- EVENT overall_footer_teamlink_before -->
+ <!-- IF U_TEAM --><a href="{U_TEAM}">{L_THE_TEAM}</a><!-- ENDIF -->
+ <!-- EVENT overall_footer_teamlink_after -->
+</span>
+<br />
<!-- ENDIF -->
<br clear="all" />
@@ -37,7 +44,13 @@
<!-- ELSE -->
<td class="row1" align="center" valign="middle"><img src="{T_THEME_PATH}/images/whosonline.gif" alt="{L_WHO_IS_ONLINE}" /></td>
<!-- ENDIF -->
- <td class="row1" width="100%"><span class="genmed">{TOTAL_USERS_ONLINE} ({L_ONLINE_EXPLAIN})<br />{RECORD_USERS}<br /><br />{LOGGED_IN_USER_LIST}</span></td>
+ <td class="row1" width="100%">
+ <span class="genmed">
+ <!-- EVENT index_body_block_online_prepend -->
+ {TOTAL_USERS_ONLINE} ({L_ONLINE_EXPLAIN})<br />{RECORD_USERS}<br /><br />{LOGGED_IN_USER_LIST}
+ <!-- EVENT index_body_block_online_append -->
+ </span>
+ </td>
</tr>
<!-- IF LEGEND -->
<tr>
@@ -56,7 +69,13 @@
</tr>
<tr>
<td class="row1" align="center" valign="middle"><img src="{T_THEME_PATH}/images/whosonline.gif" alt="{L_BIRTHDAYS}" /></td>
- <td class="row1" width="100%"><p class="genmed"><!-- IF .birthdays -->{L_CONGRATULATIONS}{L_COLON} <b><!-- BEGIN birthdays -->{birthdays.USERNAME}<!-- IF birthdays.AGE !== '' --> ({birthdays.AGE})<!-- ENDIF --><!-- IF not birthdays.S_LAST_ROW -->, <!-- ENDIF --><!-- END birthdays --></b><!-- ELSE -->{L_NO_BIRTHDAYS}<!-- ENDIF --></p></td>
+ <td class="row1" width="100%">
+ <p class="genmed">
+ <!-- EVENT index_body_block_birthday_prepend -->
+ <!-- IF .birthdays -->{L_CONGRATULATIONS}{L_COLON} <b><!-- BEGIN birthdays -->{birthdays.USERNAME}<!-- IF birthdays.AGE !== '' --> ({birthdays.AGE})<!-- ENDIF --><!-- IF not birthdays.S_LAST_ROW -->, <!-- ENDIF --><!-- END birthdays --></b><!-- ELSE -->{L_NO_BIRTHDAYS}<!-- ENDIF -->
+ <!-- EVENT index_body_block_birthday_append -->
+ </p>
+ </td>
</tr>
</table>
<!-- ENDIF -->
@@ -69,7 +88,13 @@
</tr>
<tr>
<td class="row1"><img src="{T_THEME_PATH}/images/whosonline.gif" alt="{L_STATISTICS}" /></td>
- <td class="row1" width="100%" valign="middle"><p class="genmed">{TOTAL_POSTS} | {TOTAL_TOPICS} | {TOTAL_USERS} | {NEWEST_USER}</p></td>
+ <td class="row1" width="100%" valign="middle">
+ <p class="genmed">
+ <!-- EVENT index_body_block_stats_prepend -->
+ {TOTAL_POSTS} | {TOTAL_TOPICS} | {TOTAL_USERS} | {NEWEST_USER}
+ <!-- EVENT index_body_block_stats_append -->
+ </p>
+ </td>
</tr>
</table>
diff --git a/phpBB/styles/subsilver2/template/memberlist_view.html b/phpBB/styles/subsilver2/template/memberlist_view.html
index 52f40707c0..4c8014a370 100644
--- a/phpBB/styles/subsilver2/template/memberlist_view.html
+++ b/phpBB/styles/subsilver2/template/memberlist_view.html
@@ -2,6 +2,8 @@
<div id="pagecontent">
+ <!-- EVENT memberlist_view_content_prepend -->
+
<form method="post" action="{S_PROFILE_ACTION}">
<table class="tablebg" width="100%" cellspacing="1">
diff --git a/phpBB/styles/subsilver2/template/search_results.html b/phpBB/styles/subsilver2/template/search_results.html
index 092779055d..ff34055b29 100644
--- a/phpBB/styles/subsilver2/template/search_results.html
+++ b/phpBB/styles/subsilver2/template/search_results.html
@@ -91,6 +91,7 @@
<!-- BEGIN searchresults -->
<tr class="row2">
+ <!-- EVENT search_results_post_before -->
<!-- IF searchresults.S_IGNORE_POST -->
<td class="gensmall" colspan="2" height="25" align="center">{searchresults.L_IGNORE_POST}</td>
<!-- ELSE -->
@@ -126,6 +127,7 @@
</td>
</tr>
<!-- ENDIF -->
+ <!-- EVENT search_results_post_after -->
<tr>
<td class="spacer" colspan="2"><img src="images/spacer.gif" height="1" alt="" /></td>
</tr>
diff --git a/phpBB/styles/subsilver2/template/simple_header.html b/phpBB/styles/subsilver2/template/simple_header.html
index 37a33415e9..36ac149691 100644
--- a/phpBB/styles/subsilver2/template/simple_header.html
+++ b/phpBB/styles/subsilver2/template/simple_header.html
@@ -9,6 +9,11 @@
<link rel="stylesheet" href="{T_STYLESHEET_LINK}" type="text/css" />
<link rel="stylesheet" href="{T_STYLESHEET_LANG_LINK}" type="text/css" />
+
+<!-- EVENT simple_header_head_append -->
+
+{$STYLESHEETS}
+
</head>
<body class="{S_CONTENT_DIRECTION} {BODY_CLASS}">
diff --git a/phpBB/styles/subsilver2/template/ucp_agreement.html b/phpBB/styles/subsilver2/template/ucp_agreement.html
index 054d25282f..fca7eb2368 100644
--- a/phpBB/styles/subsilver2/template/ucp_agreement.html
+++ b/phpBB/styles/subsilver2/template/ucp_agreement.html
@@ -10,6 +10,7 @@
*/
function change_language(lang_iso)
{
+ document.cookie = '{COOKIE_NAME}_lang=' + lang_iso + '; path={COOKIE_PATH}';
document.forms['register'].change_lang.value = lang_iso;
document.forms['register'].submit();
}
@@ -41,7 +42,9 @@
<td class="gen" align="center"><br />{L_COPPA_BIRTHDAY}<br /><br /><a href="{U_COPPA_NO}">{L_COPPA_NO}</a> :: <a href="{U_COPPA_YES}">{L_COPPA_YES}</a><br /><br /></td>
<!-- ELSE -->
<td>
+ <!-- EVENT ucp_agreement_terms_before -->
<span class="genmed"><br />{L_TERMS_OF_USE}<br /><br /></span>
+ <!-- EVENT ucp_agreement_terms_after -->
<div align="center">
<input class="btnlite" type="submit" id="agreed" name="agreed" value="{L_AGREE}" /><br /><br />
<input class="btnlite" type="submit" name="not_agreed" value="{L_NOT_AGREE}" />
diff --git a/phpBB/styles/subsilver2/template/ucp_register.html b/phpBB/styles/subsilver2/template/ucp_register.html
index 3392c557a2..1d55b952e5 100644
--- a/phpBB/styles/subsilver2/template/ucp_register.html
+++ b/phpBB/styles/subsilver2/template/ucp_register.html
@@ -7,6 +7,7 @@
*/
function change_language(lang_iso)
{
+ document.cookie = '{COOKIE_NAME}_lang=' + lang_iso + '; path={COOKIE_PATH}';
document.forms['register'].change_lang.value = lang_iso;
document.forms['register'].submit.click();
}
diff --git a/phpBB/styles/subsilver2/template/viewforum_body.html b/phpBB/styles/subsilver2/template/viewforum_body.html
index 44e8f30ce4..a7a130a8df 100644
--- a/phpBB/styles/subsilver2/template/viewforum_body.html
+++ b/phpBB/styles/subsilver2/template/viewforum_body.html
@@ -103,7 +103,7 @@
<!-- IF S_IS_POSTABLE or S_NO_READ_ACCESS -->
<div id="pageheader">
- <h2><a class="titles" href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2>
+ <h2><!-- EVENT viewforum_forum_name_prepend --><a class="titles" href="{U_VIEW_FORUM}">{FORUM_NAME}</a><!-- EVENT viewforum_forum_name_append --></h2>
<!-- IF MODERATORS -->
<p class="moderators"><!-- IF S_SINGLE_MODERATOR -->{L_MODERATOR}<!-- ELSE -->{L_MODERATORS}<!-- ENDIF -->{L_COLON} {MODERATORS}</p>
diff --git a/phpBB/styles/subsilver2/template/viewtopic_body.html b/phpBB/styles/subsilver2/template/viewtopic_body.html
index 307ed0f391..0c7900076b 100644
--- a/phpBB/styles/subsilver2/template/viewtopic_body.html
+++ b/phpBB/styles/subsilver2/template/viewtopic_body.html
@@ -15,7 +15,7 @@
<!-- ENDIF -->
<div id="pageheader">
- <h2><!-- EVENT viewtopic_topic_title_prepend --><a class="titles" href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2>
+ <h2><!-- EVENT viewtopic_topic_title_prepend --><a class="titles" href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a><!-- EVENT viewtopic_topic_title_append --></h2>
<!-- IF MODERATORS -->
<p class="moderators"><!-- IF S_SINGLE_MODERATOR -->{L_MODERATOR}<!-- ELSE -->{L_MODERATORS}<!-- ENDIF -->{L_COLON} {MODERATORS}</p>
@@ -72,13 +72,14 @@
<table cellspacing="0" cellpadding="4" border="0" align="center">
<tr>
- <td align="center"><span class="gen"><b>{POLL_QUESTION}</b></span><br /><span class="gensmall">{L_POLL_LENGTH}</span></td>
+ <td align="center"><span class="gen"><!-- EVENT viewtopic_body_poll_question_prepend --><b>{POLL_QUESTION}</b><!-- EVENT viewtopic_body_poll_question_append --></span><br /><span class="gensmall">{L_POLL_LENGTH}</span></td>
</tr>
<tr>
<td align="{S_CONTENT_FLOW_BEGIN}">
<table cellspacing="0" cellpadding="2" border="0">
<!-- BEGIN poll_option -->
<tr>
+ <!-- EVENT viewtopic_body_poll_option_before -->
<!-- IF S_CAN_VOTE -->
<td<!-- IF poll_option.POLL_OPTION_MOST_VOTES --> class="most-votes"<!-- ENDIF -->>
<!-- IF S_IS_MULTI_CHOICE -->
@@ -97,6 +98,7 @@
<td class="gensmall" valign="top"><b title="{L_POLL_VOTED_OPTION}">x</b></td>
<!-- ENDIF -->
<!-- ENDIF -->
+ <!-- EVENT viewtopic_body_poll_option_after -->
</tr>
<!-- END poll_option -->
</table>
@@ -139,7 +141,7 @@
<!-- IF postrow.S_POST_HIDDEN -->
<td class="gensmall" colspan="2" height="25" align="center">
- <!-- IF postrow.S_FIRST_UNREAD --><a name="unread"></a><!-- ENDIF -->
+ <!-- IF postrow.S_FIRST_UNREAD --><a id="unread" data-url="{postrow.U_MINI_POST}"></a><!-- ENDIF -->
<a name="p{postrow.POST_ID}"></a>
<!-- IF postrow.S_POST_HIDDEN -->
<!-- IF postrow.S_POST_DELETED -->
@@ -153,7 +155,7 @@
<!-- ELSE -->
<td align="center" valign="middle">
- <!-- IF postrow.S_FIRST_UNREAD --><a name="unread"></a><!-- ENDIF --><a name="p{postrow.POST_ID}"></a>
+ <!-- IF postrow.S_FIRST_UNREAD --><a id="unread" data-url="{postrow.U_MINI_POST}"></a><!-- ENDIF --><a name="p{postrow.POST_ID}"></a>
<b class="postauthor"<!-- IF postrow.POST_AUTHOR_COLOUR --> style="color: {postrow.POST_AUTHOR_COLOUR}"<!-- ENDIF -->>{postrow.POST_AUTHOR}</b>
</td>
<td width="100%" height="25">
@@ -202,6 +204,7 @@
<span class="postdetails">
<!-- IF postrow.POSTER_JOINED --><br /><b>{L_JOINED}{L_COLON}</b> {postrow.POSTER_JOINED}<!-- ENDIF -->
<!-- IF postrow.POSTER_POSTS != '' --><br /><b>{L_POSTS}{L_COLON}</b> {postrow.POSTER_POSTS}<!-- ENDIF -->
+ <!-- IF postrow.POSTER_WARNINGS --><br /><b>{L_WARNINGS}{L_COLON}</b> {postrow.POSTER_WARNINGS}<!-- ENDIF -->
<!-- IF postrow.S_PROFILE_FIELD1 -->
<!-- Use a construct like this to include admin defined profile fields. Replace FIELD1 with the name of your field. -->
diff --git a/phpBB/ucp.php b/phpBB/ucp.php
index eaa40a07a2..73eaeaa127 100644
--- a/phpBB/ucp.php
+++ b/phpBB/ucp.php
@@ -337,7 +337,7 @@ if (!$config['allow_topic_notify'] && !$config['allow_forum_notify'])
* @var p_master module Object holding all modules and their status
* @var mixed id Active module category (can be the int or string)
* @var string mode Active module
-* @since 3.1-A1
+* @since 3.1.0-a1
*/
$vars = array('module', 'id', 'mode');
extract($phpbb_dispatcher->trigger_event('core.ucp_display_module_before', compact($vars)));
diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php
index a7396f9c72..8da8a0cdcc 100644
--- a/phpBB/viewforum.php
+++ b/phpBB/viewforum.php
@@ -387,7 +387,7 @@ $sql_array = array(
*
* @event core.viewforum_get_topic_data
* @var array sql_array The SQL array to get the data of all topics
-* @since 3.1-A1
+* @since 3.1.0-a1
*/
$vars = array('sql_array');
extract($phpbb_dispatcher->trigger_event('core.viewforum_get_topic_data', compact($vars)));
@@ -582,7 +582,7 @@ if (sizeof($shadow_topic_list))
*
* @event core.viewforum_get_shadowtopic_data
* @var array sql_array SQL array to get the data of any shadowtopics
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('sql_array');
extract($phpbb_dispatcher->trigger_event('core.viewforum_get_shadowtopic_data', compact($vars)));
@@ -749,7 +749,7 @@ if (sizeof($topic_list))
$view_topic_url_params = 'f=' . $row['forum_id'] . '&amp;t=' . $topic_id;
$view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params);
- $topic_unapproved = ($row['topic_visibility'] == ITEM_UNAPPROVED && $auth->acl_get('m_approve', $row['forum_id']));
+ $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $row['forum_id']));
$posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $row['forum_id']));
$topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
@@ -819,7 +819,7 @@ if (sizeof($topic_list))
* @event core.viewforum_modify_topicrow
* @var array row Array with topic data
* @var array topic_row Template array with topic data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('row', 'topic_row');
extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topicrow', compact($vars)));
diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php
index 1738005786..52fd9f640c 100644
--- a/phpBB/viewonline.php
+++ b/phpBB/viewonline.php
@@ -101,6 +101,7 @@ if (!$show_guests)
switch ($db->sql_layer)
{
case 'sqlite':
+ case 'sqlite3':
$sql = 'SELECT COUNT(session_ip) as num_guests
FROM (
SELECT DISTINCT session_ip
@@ -143,7 +144,7 @@ $sql_ary = array(
* @var bool show_guests Do we display guests in the list
* @var int guest_counter Number of guests displayed
* @var array forum_data Array with forum data
-* @since 3.1-A1
+* @since 3.1.0-a1
* @change 3.1.0-a2 Added vars guest_counter and forum_data
*/
$vars = array('sql_ary', 'show_guests', 'guest_counter', 'forum_data');
@@ -351,7 +352,7 @@ while ($row = $db->sql_fetchrow($result))
* @var string location Page name to displayed in the list
* @var string location_url Page url to displayed in the list
* @var array forum_data Array with forum data
- * @since 3.1-A1
+ * @since 3.1.0-a1
* @change 3.1.0-a2 Added var forum_data
*/
$vars = array('on_page', 'row', 'location', 'location_url', 'forum_data');
diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index 9dc965240f..a0cd590e58 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -16,6 +16,7 @@ $phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
+include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
// Start session management
$user->session_begin();
@@ -266,7 +267,7 @@ if ($topic_data['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_appro
if ($post_id)
{
// are we where we are supposed to be?
- if ($topic_data['post_visibility'] == ITEM_UNAPPROVED && !$auth->acl_get('m_approve', $topic_data['forum_id']))
+ if (($topic_data['post_visibility'] == ITEM_UNAPPROVED || $topic_data['post_visibility'] == ITEM_REAPPROVE) && !$auth->acl_get('m_approve', $topic_data['forum_id']))
{
// If post_id was submitted, we try at least to display the topic as a last resort...
if ($topic_id)
@@ -999,10 +1000,20 @@ $sql_ary = array(
* @var string sort_dir Direction the posts are sorted by
* @var int start Pagination information
* @var array sql_ary The SQL array to get the data of posts and posters
-* @since 3.1-A1
+* @since 3.1.0-a1
* @change 3.1.0-a2 Added vars forum_id, topic_id, topic_data, post_list, sort_days, sort_key, sort_dir, start
*/
-$vars = array('forum_id', 'topic_id', 'topic_data', 'post_list', 'sort_days', 'sort_key', 'sort_dir', 'start', 'sql_ary');
+$vars = array(
+ 'forum_id',
+ 'topic_id',
+ 'topic_data',
+ 'post_list',
+ 'sort_days',
+ 'sort_key',
+ 'sort_dir',
+ 'start',
+ 'sql_ary',
+);
extract($phpbb_dispatcher->trigger_event('core.viewtopic_get_post_data', compact($vars)));
$sql = $db->sql_build_query('SELECT', $sql_ary);
@@ -1028,7 +1039,7 @@ while ($row = $db->sql_fetchrow($result))
{
$attach_list[] = (int) $row['post_id'];
- if ($row['post_visibility'] == ITEM_UNAPPROVED)
+ if ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE)
{
$has_attachments = true;
}
@@ -1075,7 +1086,7 @@ while ($row = $db->sql_fetchrow($result))
* @event core.viewtopic_post_rowset_data
* @var array rowset_data Array with the rowset data for this post
* @var array row Array with original user and post data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('rowset_data', 'row');
extract($phpbb_dispatcher->trigger_event('core.viewtopic_post_rowset_data', compact($vars)));
@@ -1098,6 +1109,7 @@ while ($row = $db->sql_fetchrow($result))
if ($poster_id == ANONYMOUS)
{
$user_cache_data = array(
+ 'user_type' => USER_IGNORE,
'joined' => '',
'posts' => '',
@@ -1131,7 +1143,7 @@ while ($row = $db->sql_fetchrow($result))
* @var array user_cache_data Array with the user's data
* @var int poster_id Poster's user id
* @var array row Array with original user and post data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('user_cache_data', 'poster_id', 'row');
extract($phpbb_dispatcher->trigger_event('core.viewtopic_cache_guest_data', compact($vars)));
@@ -1153,6 +1165,9 @@ while ($row = $db->sql_fetchrow($result))
$id_cache[] = $poster_id;
$user_cache_data = array(
+ 'user_type' => $row['user_type'],
+ 'user_inactive_reason' => $row['user_inactive_reason'],
+
'joined' => $user->format_date($row['user_regdate']),
'posts' => $row['user_posts'],
'warnings' => (isset($row['user_warnings'])) ? $row['user_warnings'] : 0,
@@ -1191,7 +1206,7 @@ while ($row = $db->sql_fetchrow($result))
* @var array user_cache_data Array with the user's data
* @var int poster_id Poster's user id
* @var array row Array with original user and post data
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('user_cache_data', 'poster_id', 'row');
extract($phpbb_dispatcher->trigger_event('core.viewtopic_cache_user_data', compact($vars)));
@@ -1364,6 +1379,13 @@ if ($bbcode_bitfield !== '')
$bbcode = new bbcode(base64_encode($bbcode_bitfield));
}
+// Get the list of users who can receive private messages
+$can_receive_pm_list = $auth->acl_get_list(array_keys($user_cache), 'u_readpm');
+$can_receive_pm_list = (empty($can_receive_pm_list) || !isset($can_receive_pm_list[0]['u_readpm'])) ? array() : $can_receive_pm_list[0]['u_readpm'];
+
+// Get the list of permanently banned users
+$permanently_banned_users = phpbb_get_banned_user_ids(array_keys($user_cache), false);
+
$i_total = sizeof($rowset) - 1;
$prev_post_id = '';
@@ -1582,6 +1604,31 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
!$row['post_edit_locked']
)));
+ // Can this user receive a Private Message?
+ $can_receive_pm = (
+ // They must be a "normal" user
+ $user_cache[$poster_id]['user_type'] != USER_IGNORE &&
+
+ // They must not be deactivated by the administrator
+ ($user_cache[$poster_id]['user_type'] != USER_INACTIVE || $user_cache[$poster_id]['user_inactive_reason'] != INACTIVE_MANUAL) &&
+
+ // They must be able to read PMs
+ in_array($poster_id, $can_receive_pm_list) &&
+
+ // They must not be permanently banned
+ !in_array($poster_id, $permanently_banned_users) &&
+
+ // They must allow users to contact via PM
+ (($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_')) || $user_cache[$poster_id]['allow_pm'])
+ );
+
+ $u_pm = '';
+
+ if ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && $can_receive_pm)
+ {
+ $u_pm = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;action=quotepost&amp;p=' . $row['post_id']);
+ }
+
//
$post_row = array(
'POST_AUTHOR_FULL' => ($poster_id != ANONYMOUS) ? $user_cache[$poster_id]['author_full'] : get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
@@ -1595,7 +1642,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
'POSTER_JOINED' => $user_cache[$poster_id]['joined'],
'POSTER_POSTS' => $user_cache[$poster_id]['posts'],
'POSTER_AVATAR' => $user_cache[$poster_id]['avatar'],
- 'POSTER_WARNINGS' => $user_cache[$poster_id]['warnings'],
+ 'POSTER_WARNINGS' => $auth->acl_get('m_warn') ? $user_cache[$poster_id]['warnings'] : '',
'POSTER_AGE' => $user_cache[$poster_id]['age'],
'POST_DATE' => $user->format_date($row['post_time'], false, ($view == 'print') ? true : false),
@@ -1621,7 +1668,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
'U_DELETE' => ($delete_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=delete&amp;f=$forum_id&amp;p={$row['post_id']}") : '',
'U_SEARCH' => $user_cache[$poster_id]['search'],
- 'U_PM' => ($poster_id != ANONYMOUS && $config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($user_cache[$poster_id]['allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;action=quotepost&amp;p=' . $row['post_id']) : '',
+ 'U_PM' => $u_pm,
'U_EMAIL' => $user_cache[$poster_id]['email'],
'U_JABBER' => $user_cache[$poster_id]['jabber'],
@@ -1642,7 +1689,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false,
'S_MULTIPLE_ATTACHMENTS' => !empty($attachments[$row['post_id']]) && sizeof($attachments[$row['post_id']]) > 1,
- 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED) ? true : false,
+ 'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) ? true : false,
'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,
@@ -1677,11 +1724,22 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
* @var array user_poster_data Poster's data from user cache
* @var array post_row Template block array of the post
* @var array topic_data Array with topic data
- * @since 3.1-A1
+ * @since 3.1.0-a1
* @change 3.1.0-a3 Added vars start, current_row_number, end, attachments
* @change 3.1.0-b3 Added topic_data array, total_posts
*/
- $vars = array('start', 'current_row_number', 'end', 'total_posts', 'row', 'cp_row', 'attachments', 'user_poster_data', 'post_row', 'topic_data');
+ $vars = array(
+ 'start',
+ 'current_row_number',
+ 'end',
+ 'total_posts',
+ 'row',
+ 'cp_row',
+ 'attachments',
+ 'user_poster_data',
+ 'post_row',
+ 'topic_data',
+ );
extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_post_row', compact($vars)));
$i = $current_row_number;
@@ -1694,11 +1752,46 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
// Dump vars into template
$template->assign_block_vars('postrow', $post_row);
+ $contact_fields = array(
+ array(
+ 'ID' => 'pm',
+ 'NAME' => $user->lang['PRIVATE_MESSAGES'],
+ 'U_CONTACT' => $u_pm,
+ ),
+ array(
+ 'ID' => 'email',
+ 'NAME' => $user->lang['SEND_EMAIL'],
+ 'U_CONTACT' => $user_cache[$poster_id]['email'],
+ ),
+ array(
+ 'ID' => 'jabber',
+ 'NAME' => $user->lang['JABBER'],
+ 'U_CONTACT' => $user_cache[$poster_id]['jabber'],
+ ),
+ );
+
+ foreach ($contact_fields as $field)
+ {
+ if ($field['U_CONTACT'])
+ {
+ $template->assign_block_vars('postrow.contact', $field);
+ }
+ }
+
if (!empty($cp_row['blockrow']))
{
foreach ($cp_row['blockrow'] as $field_data)
{
$template->assign_block_vars('postrow.custom_fields', $field_data);
+
+ if ($field_data['S_PROFILE_CONTACT'])
+ {
+ $template->assign_block_vars('postrow.contact', array(
+ 'ID' => $field_data['PROFILE_FIELD_IDENT'],
+ 'NAME' => $field_data['PROFILE_FIELD_NAME'],
+ 'U_CONTACT' => $field_data['PROFILE_FIELD_CONTACT'],
+ ));
+ }
}
}
@@ -1728,14 +1821,28 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
* @var int start Start item of this page
* @var int current_row_number Number of the post on this page
* @var int end Number of posts on this page
+ * @var int total_posts Total posts count
* @var array row Array with original post and user data
* @var array cp_row Custom profile field data of the poster
* @var array attachments List of attachments
* @var array user_poster_data Poster's data from user cache
* @var array post_row Template block array of the post
+ * @var array topic_data Array with topic data
* @since 3.1.0-a3
+ * @change 3.1.0-b3 Added topic_data array, total_posts
*/
- $vars = array('start', 'current_row_number', 'end', 'row', 'cp_row', 'attachments', 'user_poster_data', 'post_row');
+ $vars = array(
+ 'start',
+ 'current_row_number',
+ 'end',
+ 'total_posts',
+ 'row',
+ 'cp_row',
+ 'attachments',
+ 'user_poster_data',
+ 'post_row',
+ 'topic_data',
+ );
extract($phpbb_dispatcher->trigger_event('core.viewtopic_post_row_after', compact($vars)));
$i = $current_row_number;
@@ -1879,11 +1986,11 @@ $page_title = $topic_data['topic_title'] . ($start ? ' - ' . sprintf($user->lang
* You can use this event to modify the page title of the viewtopic page
*
* @event core.viewtopic_modify_page_title
-* @var string page_title Title of the index page
+* @var string page_title Title of the viewtopic page
* @var array topic_data Array with topic data
* @var int forum_id Forum ID of the topic
* @var int start Start offset used to calculate the page
-* @since 3.1-A1
+* @since 3.1.0-a1
*/
$vars = array('page_title', 'topic_data', 'forum_id', 'start');
extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_page_title', compact($vars)));