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.html47
-rw-r--r--phpBB/adm/style/acp_logs.html2
-rw-r--r--phpBB/adm/style/acp_users_prefs.html10
-rw-r--r--phpBB/adm/style/admin.css14
-rw-r--r--phpBB/assets/javascript/core.js363
-rwxr-xr-xphpBB/bin/phpbbcli.php3
-rw-r--r--phpBB/common.php31
-rw-r--r--phpBB/composer.json5
-rw-r--r--phpBB/composer.lock619
-rw-r--r--phpBB/config/console.yml12
-rw-r--r--phpBB/config/profilefields.yml1
-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.md313
-rw-r--r--phpBB/feed.php7
-rw-r--r--phpBB/includes/acp/acp_attachments.php22
-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.php110
-rw-r--r--phpBB/includes/functions_acp.php8
-rw-r--r--phpBB/includes/functions_admin.php80
-rw-r--r--phpBB/includes/functions_compatibility.php46
-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.php3
-rw-r--r--phpBB/includes/functions_posting.php89
-rw-r--r--phpBB/includes/functions_privmsgs.php7
-rw-r--r--phpBB/includes/functions_upload.php2
-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/info/ucp_auth_link.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.php87
-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.php2
-rw-r--r--phpBB/install/install_convert.php3
-rw-r--r--phpBB/install/install_install.php60
-rw-r--r--phpBB/install/schemas/schema_data.sql4
-rw-r--r--phpBB/language/en/acp/attachments.php9
-rw-r--r--phpBB/language/en/acp/board.php6
-rw-r--r--phpBB/language/en/acp/common.php14
-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.php13
-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.php9
-rw-r--r--phpBB/language/en/viewtopic.php2
-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/db/migrate.php128
-rw-r--r--phpBB/phpbb/content_visibility.php74
-rw-r--r--phpBB/phpbb/controller/provider.php2
-rw-r--r--phpBB/phpbb/db/driver/sqlite3.php375
-rw-r--r--phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php40
-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/timezone.php45
-rw-r--r--phpBB/phpbb/db/migrator.php15
-rw-r--r--phpBB/phpbb/db/tools.php636
-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.php2
-rw-r--r--phpBB/phpbb/feed/post_base.php39
-rw-r--r--phpBB/phpbb/feed/topic.php2
-rw-r--r--phpBB/phpbb/feed/topic_base.php2
-rw-r--r--phpBB/phpbb/log/log.php54
-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.php36
-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.html8
-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_footer.html3
-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.html2
-rw-r--r--phpBB/styles/prosilver/template/memberlist_search.html16
-rw-r--r--phpBB/styles/prosilver/template/memberlist_view.html13
-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.html8
-rw-r--r--phpBB/styles/prosilver/template/posting_layout.html4
-rw-r--r--phpBB/styles/prosilver/template/posting_pm_header.html3
-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/ucp_agreement.html7
-rw-r--r--phpBB/styles/prosilver/template/ucp_footer.html3
-rw-r--r--phpBB/styles/prosilver/template/ucp_header.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_pm_message_header.html12
-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.html48
-rw-r--r--phpBB/styles/prosilver/template/viewtopic_topic_tools.html4
-rw-r--r--phpBB/styles/prosilver/theme/bidi.css6
-rw-r--r--phpBB/styles/prosilver/theme/buttons.css80
-rw-r--r--phpBB/styles/prosilver/theme/colours.css33
-rw-r--r--phpBB/styles/prosilver/theme/common.css12
-rw-r--r--phpBB/styles/prosilver/theme/content.css14
-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
-rwxr-xr-x[-rw-r--r--]phpBB/styles/prosilver/theme/images/icon_print.gifbin424 -> 204 bytes
-rw-r--r--phpBB/styles/prosilver/theme/images/icon_sendemail.gifbin531 -> 303 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/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/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.html6
-rw-r--r--phpBB/ucp.php2
-rw-r--r--phpBB/viewforum.php8
-rw-r--r--phpBB/viewonline.php5
-rw-r--r--phpBB/viewtopic.php135
237 files changed, 5819 insertions, 1676 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 82fb229fae..5d35666fdd 100644
--- a/phpBB/adm/style/acp_attachments.html
+++ b/phpBB/adm/style/acp_attachments.html
@@ -378,7 +378,7 @@
<fieldset class="tabulated">
<legend>{L_TITLE}</legend>
- <div class="pagination">
+ <div class="pagination top-pagination">
<!-- IF .pagination or TOTAL_FILES -->
{L_NUMBER_FILES}{L_COLON} {TOTAL_FILES} &bull; {L_TOTAL_SIZE}{L_COLON} {TOTAL_SIZE}
<!-- IF .pagination -->
@@ -389,13 +389,14 @@
<!-- ENDIF -->
</div>
+<!-- IF .attachments -->
<table class="table1 zebra-table">
<thead>
<tr>
<th>{L_FILENAME}</th>
<th>{L_POSTED}</th>
- <th>{L_FILESIZE}</th>
- <th>{L_DELETE}</th>
+ <th class="centered-text">{L_FILESIZE}</th>
+ <th class="centered-text">{L_MARK}</th>
</tr>
</thead>
<tbody>
@@ -406,25 +407,19 @@
<!-- ELSE --><a href="{attachments.U_FILE}" style="font-weight: bold;">{attachments.REAL_FILENAME}</a><br /><!-- IF attachments.COMMENT -->{attachments.COMMENT}<br /><!-- ENDIF -->{attachments.L_DOWNLOAD_COUNT}<br />{L_TOPIC}{L_COLON} <a href="{attachments.U_VIEW_TOPIC}">{attachments.TOPIC_TITLE}</a><!-- ENDIF -->
</td>
<td>{attachments.FILETIME}<br />{L_POST_BY_AUTHOR} {attachments.ATTACHMENT_POSTER}</td>
- <td>{attachments.FILESIZE}</td>
- <td><input type="checkbox" class="radio" name="delete[{attachments.ATTACH_ID}]" /></td>
+ <td class="centered-text">{attachments.FILESIZE}</td>
+ <td class="centered-text"><input type="checkbox" class="radio" name="delete[{attachments.ATTACH_ID}]" /></td>
</tr>
<!-- END attachments -->
- <tr class="row4">
- <td colspan="3">&nbsp;</td>
- <td class="small"><a href="#" onclick="marklist('attachments', 'delete', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('attachments', 'delete', false); return false;">{L_UNMARK_ALL}</a></td>
- </tr>
</tbody>
</table>
+<!-- ELSE -->
+ <div class="errorbox">
+ <p>{L_NO_ATTACHMENTS}</p>
+ </div>
+<!-- ENDIF -->
<!-- IF TOTAL_FILES -->
- <fieldset class="display-options">
- {L_DISPLAY_LOG}{L_COLON} &nbsp;{S_LIMIT_DAYS}&nbsp;{L_SORT_BY}{L_COLON} {S_SORT_KEY} {S_SORT_DIR}
- <input class="button2" type="submit" value="{L_GO}" name="sort" />
- </fieldset>
-
- <hr />
-
<div class="pagination">
{L_NUMBER_FILES}{L_COLON} {TOTAL_FILES} &bull; {L_TOTAL_SIZE}{L_COLON} {TOTAL_SIZE}
<!-- IF .pagination -->
@@ -435,10 +430,22 @@
</div>
<!-- ENDIF -->
- <p class="submit-buttons">
- <input class="button1" type="submit" id="submit" name="submit" value="{L_SUBMIT}" />&nbsp;
- <input class="button2" type="reset" id="reset" name="reset" value="{L_RESET}" />
- </p>
+ <fieldset class="display-options">
+ {L_DISPLAY_LOG}{L_COLON} &nbsp;{S_LIMIT_DAYS}&nbsp;{L_SORT_BY}{L_COLON} {S_SORT_KEY} {S_SORT_DIR}
+ <input class="button2" type="submit" value="{L_GO}" name="sort" />
+ </fieldset>
+
+ <hr />
+
+<!-- IF .attachments -->
+ <fieldset class="quick">
+ <input class="button2" type="submit" name="submit" value="{L_DELETE_MARKED}" /><br />
+ <p class="small">
+ <a href="#" onclick="marklist('attachments', 'delete', true); return false;">{L_MARK_ALL}</a> &bull;
+ <a href="#" onclick="marklist('attachments', 'delete', false); return false;">{L_UNMARK_ALL}</a>
+ </p>
+ </fieldset>
+<!-- ENDIF -->
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/adm/style/acp_logs.html b/phpBB/adm/style/acp_logs.html
index 592b5bbc16..9343b9b509 100644
--- a/phpBB/adm/style/acp_logs.html
+++ b/phpBB/adm/style/acp_logs.html
@@ -13,7 +13,7 @@
</fieldset>
<!-- IF .pagination -->
-<div class="pagination" style="float: right; margin: 15px 0 2px 0">
+<div class="pagination top-pagination">
<!-- INCLUDE pagination.html -->
</div>
<!-- ENDIF -->
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 22bbf404ea..6f2d65afc0 100644
--- a/phpBB/adm/style/admin.css
+++ b/phpBB/adm/style/admin.css
@@ -102,6 +102,10 @@ hr {
height: 1px;
}
+.centered-text {
+ text-align: center;
+}
+
.small {
font-size: 0.85em;
}
@@ -1126,11 +1130,14 @@ input.langvalue, textarea.langvalue {
}
optgroup, select {
+ background-color: #FAFAFA;
+ border: 1px solid #666666;
font-family: Verdana, Helvetica, Arial, sans-serif;
font-size: 0.85em;
font-weight: normal;
font-style: normal;
cursor: pointer;
+ padding: 1px;
vertical-align: middle;
width: auto;
color: #000;
@@ -1238,7 +1245,7 @@ fieldset.display-options {
border: none;
background-color: transparent;
text-align: center;
- font-size: 0.75em;
+ font-size: 0.85em;
}
fieldset.display-options select, fieldset.display-options input, fieldset.display-options label {
@@ -1663,11 +1670,16 @@ input.button1:focus, input.button2:focus {
/* Pagination
---------------------------------------- */
.pagination {
+ font-size: .85em;
height: 1%; /* IE tweak (holly hack) */
width: auto;
text-align: right;
margin-top: 5px;
+}
+
+.top-pagination {
float: right;
+ margin: 15px 0 2px 0;
}
.rtl .pagination {
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index ac866f7c78..f461d5a175 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,278 @@ 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();
+ }
+});
+
/**
* Hide the optgroups that are not the selected timezone
*
@@ -542,6 +833,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 +1214,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 +1235,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 +1408,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() {
diff --git a/phpBB/bin/phpbbcli.php b/phpBB/bin/phpbbcli.php
index 49f4ca13e7..02d6b88943 100755
--- a/phpBB/bin/phpbbcli.php
+++ b/phpBB/bin/phpbbcli.php
@@ -22,6 +22,7 @@ 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_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 +31,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 2941293e81..a55733b3c0 100644
--- a/phpBB/composer.json
+++ b/phpBB/composer.json
@@ -3,7 +3,6 @@
"You MUST update the clean-vendor-dir target in build/build.xml",
"accordingly when adding or upgrading dependencies."
],
- "minimum-stability": "beta",
"require": {
"lusitanian/oauth": "0.2.*",
"symfony/config": "2.3.*",
@@ -17,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 c0eb7afcbb..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": "cc83663b780856890f787b9b4d6ea474",
+ "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"
],
@@ -108,17 +108,17 @@
},
{
"name": "symfony/config",
- "version": "v2.3.4",
+ "version": "v2.3.12",
"target-dir": "Symfony/Component/Config",
"source": {
"type": "git",
"url": "https://github.com/symfony/Config.git",
- "reference": "65a927c15ca5a911ba2fa277a5457fa8129505b0"
+ "reference": "91faa2d4944d0c8a94d5b73cb7ccfb219aee9d21"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Config/zipball/65a927c15ca5a911ba2fa277a5457fa8129505b0",
- "reference": "65a927c15ca5a911ba2fa277a5457fa8129505b0",
+ "url": "https://api.github.com/repos/symfony/Config/zipball/91faa2d4944d0c8a94d5b73cb7ccfb219aee9d21",
+ "reference": "91faa2d4944d0c8a94d5b73cb7ccfb219aee9d21",
"shasum": ""
},
"require": {
@@ -136,14 +136,16 @@
"Symfony\\Component\\Config\\": ""
}
},
- "notification-url": "http://packagist.org/downloads/",
+ "notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -152,21 +154,21 @@
],
"description": "Symfony Config Component",
"homepage": "http://symfony.com",
- "time": "2013-08-06 05:49:23"
+ "time": "2014-03-31 10:15:50"
},
{
"name": "symfony/console",
- "version": "v2.3.6",
+ "version": "v2.3.12",
"target-dir": "Symfony/Component/Console",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
- "reference": "f880062d56edefb25b36f2defa65aafe65959dc7"
+ "reference": "df17996d37eb113a5675ca4cc2ac45f4fc057cb7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Console/zipball/f880062d56edefb25b36f2defa65aafe65959dc7",
- "reference": "f880062d56edefb25b36f2defa65aafe65959dc7",
+ "url": "https://api.github.com/repos/symfony/Console/zipball/df17996d37eb113a5675ca4cc2ac45f4fc057cb7",
+ "reference": "df17996d37eb113a5675ca4cc2ac45f4fc057cb7",
"shasum": ""
},
"require": {
@@ -196,7 +198,9 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -205,21 +209,21 @@
],
"description": "Symfony Console Component",
"homepage": "http://symfony.com",
- "time": "2013-09-25 06:04:15"
+ "time": "2014-03-01 17:25:29"
},
{
"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": {
@@ -230,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": {
@@ -245,14 +248,16 @@
"Symfony\\Component\\Debug\\": ""
}
},
- "notification-url": "http://packagist.org/downloads/",
+ "notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -261,21 +266,21 @@
],
"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",
- "version": "v2.3.4",
+ "version": "v2.3.12",
"target-dir": "Symfony/Component/DependencyInjection",
"source": {
"type": "git",
"url": "https://github.com/symfony/DependencyInjection.git",
- "reference": "3678aa969e5bfeb8515a1f3047c63e8104723f5c"
+ "reference": "41e9e2078e8edf261c11be478300c8fcddb64e30"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/3678aa969e5bfeb8515a1f3047c63e8104723f5c",
- "reference": "3678aa969e5bfeb8515a1f3047c63e8104723f5c",
+ "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/41e9e2078e8edf261c11be478300c8fcddb64e30",
+ "reference": "41e9e2078e8edf261c11be478300c8fcddb64e30",
"shasum": ""
},
"require": {
@@ -301,14 +306,16 @@
"Symfony\\Component\\DependencyInjection\\": ""
}
},
- "notification-url": "http://packagist.org/downloads/",
+ "notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -317,21 +324,21 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "http://symfony.com",
- "time": "2013-07-25 17:13:25"
+ "time": "2014-03-27 18:14:33"
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.3.4",
+ "version": "v2.3.12",
"target-dir": "Symfony/Component/EventDispatcher",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
- "reference": "41c9826457c65fa3cf746f214985b7ca9cba42f8"
+ "reference": "15645237c6ff70e74a28e8836362d82492765055"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/41c9826457c65fa3cf746f214985b7ca9cba42f8",
- "reference": "41c9826457c65fa3cf746f214985b7ca9cba42f8",
+ "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/15645237c6ff70e74a28e8836362d82492765055",
+ "reference": "15645237c6ff70e74a28e8836362d82492765055",
"shasum": ""
},
"require": {
@@ -362,7 +369,9 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -371,21 +380,21 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com",
- "time": "2013-07-21 12:12:18"
+ "time": "2014-02-11 10:29:24"
},
{
"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": {
@@ -394,7 +403,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.3-dev"
+ "dev-master": "2.4-dev"
}
},
"autoload": {
@@ -402,14 +411,16 @@
"Symfony\\Component\\Filesystem\\": ""
}
},
- "notification-url": "http://packagist.org/downloads/",
+ "notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -418,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": {
@@ -452,14 +466,16 @@
"Symfony/Component/HttpFoundation/Resources/stubs"
]
},
- "notification-url": "http://packagist.org/downloads/",
+ "notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -468,21 +484,21 @@
],
"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",
- "version": "v2.3.4",
+ "version": "v2.3.12",
"target-dir": "Symfony/Component/HttpKernel",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpKernel.git",
- "reference": "9d35da40f07bbe7a4f8dfbc41555d2b69de674bf"
+ "reference": "48d61b3622ca35dd924b167441a9810ad55906ce"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/9d35da40f07bbe7a4f8dfbc41555d2b69de674bf",
- "reference": "9d35da40f07bbe7a4f8dfbc41555d2b69de674bf",
+ "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/48d61b3622ca35dd924b167441a9810ad55906ce",
+ "reference": "48d61b3622ca35dd924b167441a9810ad55906ce",
"shasum": ""
},
"require": {
@@ -523,14 +539,16 @@
"Symfony\\Component\\HttpKernel\\": ""
}
},
- "notification-url": "http://packagist.org/downloads/",
+ "notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -539,21 +557,21 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "http://symfony.com",
- "time": "2013-08-27 08:58:24"
+ "time": "2014-04-03 05:42:39"
},
{
"name": "symfony/routing",
- "version": "v2.3.4",
+ "version": "v2.3.12",
"target-dir": "Symfony/Component/Routing",
"source": {
"type": "git",
"url": "https://github.com/symfony/Routing.git",
- "reference": "69af3f07dbf3ae93dd513dbc373f561cb2e7f143"
+ "reference": "08afcafd9af22a24a8055669f85d63b863c4711b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Routing/zipball/69af3f07dbf3ae93dd513dbc373f561cb2e7f143",
- "reference": "69af3f07dbf3ae93dd513dbc373f561cb2e7f143",
+ "url": "https://api.github.com/repos/symfony/Routing/zipball/08afcafd9af22a24a8055669f85d63b863c4711b",
+ "reference": "08afcafd9af22a24a8055669f85d63b863c4711b",
"shasum": ""
},
"require": {
@@ -581,14 +599,16 @@
"Symfony\\Component\\Routing\\": ""
}
},
- "notification-url": "http://packagist.org/downloads/",
+ "notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -597,21 +617,21 @@
],
"description": "Symfony Routing Component",
"homepage": "http://symfony.com",
- "time": "2013-08-23 15:14:07"
+ "time": "2014-03-28 10:34:27"
},
{
"name": "symfony/yaml",
- "version": "v2.3.4",
+ "version": "v2.3.12",
"target-dir": "Symfony/Component/Yaml",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
- "reference": "5a279f1b5f5e1045a6c432354d9ea727ff3a9847"
+ "reference": "3acf34f6993db3d873fa77ac2cb6e595db00b88d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Yaml/zipball/5a279f1b5f5e1045a6c432354d9ea727ff3a9847",
- "reference": "5a279f1b5f5e1045a6c432354d9ea727ff3a9847",
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/3acf34f6993db3d873fa77ac2cb6e595db00b88d",
+ "reference": "3acf34f6993db3d873fa77ac2cb6e595db00b88d",
"shasum": ""
},
"require": {
@@ -635,7 +655,9 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -644,7 +666,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "http://symfony.com",
- "time": "2013-08-24 15:26:22"
+ "time": "2014-03-04 16:04:39"
},
{
"name": "twig/twig",
@@ -674,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",
@@ -743,7 +768,9 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
}
],
"description": "A simple PHP Web Scraper",
@@ -1005,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": {
@@ -1059,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/",
@@ -1120,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": {
@@ -1160,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": {
@@ -1209,7 +1241,7 @@
"keywords": [
"template"
],
- "time": "2012-10-31 18:15:28"
+ "time": "2014-01-30 17:20:04"
},
{
"name": "phpunit/php-timer",
@@ -1257,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": {
@@ -1303,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/",
@@ -1377,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/",
@@ -1426,20 +1466,287 @@
"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",
- "version": "1.5.0RC4",
+ "version": "1.5.2",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "146a9b54e4adeaca0a3ae073e0a8a03570d6cc43"
+ "reference": "a76a39b317ce8106abe6264daa505e24e1731860"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/146a9b54e4adeaca0a3ae073e0a8a03570d6cc43",
- "reference": "146a9b54e4adeaca0a3ae073e0a8a03570d6cc43",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/a76a39b317ce8106abe6264daa505e24e1731860",
+ "reference": "a76a39b317ce8106abe6264daa505e24e1731860",
"shasum": ""
},
"require": {
@@ -1496,7 +1803,7 @@
"phpcs",
"standards"
],
- "time": "2013-09-26 00:14:02"
+ "time": "2014-02-04 23:49:58"
},
{
"name": "symfony/browser-kit",
@@ -1542,7 +1849,9 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -1589,7 +1898,9 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -1646,7 +1957,9 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -1693,7 +2006,9 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -1740,7 +2055,9 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
"name": "Symfony Community",
@@ -1755,7 +2072,7 @@
"aliases": [
],
- "minimum-stability": "beta",
+ "minimum-stability": "stable",
"stability-flags": [
],
diff --git a/phpBB/config/console.yml b/phpBB/config/console.yml
index a4aae75e40..3d57c257dd 100644
--- a/phpBB/config/console.yml
+++ b/phpBB/config/console.yml
@@ -34,6 +34,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/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..18beb1c64a 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
@@ -454,6 +637,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 +764,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 +801,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 +827,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 +937,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 c31a6b6b1d..0c4cc32fdb 100644
--- a/phpBB/feed.php
+++ b/phpBB/feed.php
@@ -37,7 +37,7 @@ if (!empty($config['feed_http_auth']) && request_var('auth', '') == 'http')
}
$auth->acl($user->data);
-$user->setup();
+$user->setup('viewtopic');
// Initial var setup
$forum_id = request_var('f', 0);
@@ -73,9 +73,6 @@ if ($feed === false)
trigger_error('NO_FEED');
}
-// Get attachments for this feed
-$feed->fetch_attachments();
-
// Open Feed
$feed->open();
@@ -111,7 +108,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'], ((isset($row['post_attachment']) && $row['post_attachment']) ? $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 f68fd76587..1aaf1f9c09 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),
@@ -1115,11 +1114,6 @@ class acp_attachments
if ($stats_error)
{
$error[] = $stats_error;
-
- // Show option to resync stats
- $this->template->assign_vars(array(
- 'S_ACTION_OPTIONS' => $auth->acl_get('a_board'),
- ));
}
$template->assign_vars(array(
@@ -1292,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)
@@ -1306,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.
*/
@@ -1317,11 +1311,19 @@ 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']))
{
- return $this->user->lang('FILES_STATS_WRONG', (int) $stats['num_files'], get_formatted_filesize($stats['upload_dir_size']));
+ $u_resync = $this->u_action . '&amp;action=stats';
+
+ return $this->user->lang(
+ 'FILES_STATS_WRONG',
+ (int) $stats['num_files'],
+ get_formatted_filesize($stats['upload_dir_size']),
+ '<a href="' . $u_resync . '">',
+ '</a>'
+ );
}
return false;
}
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 69f7c3f162..3480a338c0 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -1005,24 +1005,6 @@ function phpbb_get_timezone_identifiers($selected_timezone)
}
/**
-* Pick a timezone
-*
-* @param string $default A timezone to select
-* @param boolean $truncate Shall we truncate the options text
-*
-* @return string Returns the options for timezone selector only
-*
-* @deprecated
-*/
-function tz_select($default = '', $truncate = false)
-{
- global $user;
-
- $timezone_select = phpbb_timezone_select($user, $default, $truncate);
- return $timezone_select['tz_select'];
-}
-
-/**
* Options to pick a timezone and date/time
*
* @param \phpbb\user $user Object of the current user
@@ -2022,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)));
@@ -2344,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.
@@ -2358,71 +2341,23 @@ 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)
- {
- $redirect .= '?';
- }
-
- // Strip vars...
- if ($strip_vars !== false && strpos($redirect, '?') !== false)
+ if ($strip_vars !== false)
{
- 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 = $phpbb_path_helper->strip_url_params($redirect, $strip_vars, false);
}
- return str_replace('&', '&amp;', $redirect);
+ return $redirect . ((strpos($redirect, '?') === false) ? '?' : '');
}
/**
@@ -2712,7 +2647,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;
@@ -3849,6 +3783,16 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
if (defined('IN_INSTALL') || defined('DEBUG') || isset($auth) && $auth->acl_get('a_'))
{
$msg_text = $log_text;
+
+ // If this is defined there already was some output
+ // So let's not break it
+ if (defined('IN_DB_UPDATE'))
+ {
+ echo '<div class="errorbox">' . $msg_text . '</div>';
+
+ $db->sql_return_on_error(true);
+ phpbb_end_update($cache, $config);
+ }
}
if ((defined('IN_CRON') || defined('IMAGE_OUTPUT')) && isset($db))
@@ -4045,7 +3989,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 (
@@ -4735,7 +4679,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)));
@@ -4911,12 +4855,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,
@@ -4927,9 +4869,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'),
@@ -4946,7 +4889,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'],
@@ -5100,7 +5042,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)));
@@ -5208,7 +5150,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 d72f89b6ac..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;
@@ -2581,20 +2604,6 @@ function phpbb_cache_moderators($db, $cache, $auth)
}
/**
-* Cache moderators. Called whenever permissions are changed
-* via admin_permissions. Changes of usernames and group names
-* must be carried through for the moderators table.
-*
-* @deprecated 3.1
-* @return null
-*/
-function cache_moderators()
-{
- global $db, $cache, $auth;
- return phpbb_cache_moderators($db, $cache, $auth);
-}
-
-/**
* View log
*
* @param string $mode The mode defines which log_type is used and from which log the entry is retrieved
@@ -2744,20 +2753,6 @@ function phpbb_update_foes($db, $auth, $group_id = false, $user_id = false)
}
/**
-* Removes moderators and administrators from foe lists.
-*
-* @deprecated 3.1
-* @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore
-* @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore
-* @return null
-*/
-function update_foes($group_id = false, $user_id = false)
-{
- global $db, $auth;
- return phpbb_update_foes($db, $auth, $group_id, $user_id);
-}
-
-/**
* Lists inactive users
*/
function view_inactive_users(&$users, &$user_count, $limit = 0, $offset = 0, $limit_days = 0, $sort_by = 'user_inactive_time DESC')
@@ -2913,6 +2908,7 @@ function get_database_size()
break;
case 'sqlite':
+ case 'sqlite3':
global $dbhost;
if (file_exists($dbhost))
@@ -2929,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';
@@ -2938,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_compatibility.php b/phpBB/includes/functions_compatibility.php
index 164dd4cb99..c2db53f86c 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -116,3 +116,49 @@ function phpbb_clean_path($path)
return $phpbb_path_helper->clean_path($path);
}
+
+/**
+* Pick a timezone
+*
+* @param string $default A timezone to select
+* @param boolean $truncate Shall we truncate the options text
+*
+* @return string Returns the options for timezone selector only
+*
+* @deprecated
+*/
+function tz_select($default = '', $truncate = false)
+{
+ global $user;
+
+ $timezone_select = phpbb_timezone_select($user, $default, $truncate);
+ return $timezone_select['tz_select'];
+}
+
+/**
+* Cache moderators. Called whenever permissions are changed
+* via admin_permissions. Changes of usernames and group names
+* must be carried through for the moderators table.
+*
+* @deprecated 3.1
+* @return null
+*/
+function cache_moderators()
+{
+ global $db, $cache, $auth;
+ return phpbb_cache_moderators($db, $cache, $auth);
+}
+
+/**
+* Removes moderators and administrators from foe lists.
+*
+* @deprecated 3.1
+* @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore
+* @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore
+* @return null
+*/
+function update_foes($group_id = false, $user_id = false)
+{
+ global $db, $auth;
+ return phpbb_update_foes($db, $auth, $group_id, $user_id);
+}
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 be066de0f0..04efcb7b2e 100644
--- a/phpBB/includes/functions_module.php
+++ b/phpBB/includes/functions_module.php
@@ -398,6 +398,7 @@ class p_master
'cfg_([a-z0-9_]+)' => '(int) $config[\'\\1\']',
'request_([a-zA-Z0-9_]+)' => '$request->variable(\'\\1\', false)',
'ext_([a-zA-Z0-9_/]+)' => 'array_key_exists(\'\\1\', $phpbb_extension_manager->all_enabled())',
+ 'authmethod_([a-z0-9_\\\\]+)' => '($config[\'auth_method\'] === \'\\1\')',
);
/**
@@ -409,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..547ea69e81 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -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_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/info/ucp_auth_link.php b/phpBB/includes/ucp/info/ucp_auth_link.php
index ee88b15ea8..3a34232d28 100644
--- a/phpBB/includes/ucp/info/ucp_auth_link.php
+++ b/phpBB/includes/ucp/info/ucp_auth_link.php
@@ -19,7 +19,7 @@ class ucp_auth_link_info
'title' => 'UCP_AUTH_LINK',
'version' => '1.0.0',
'modes' => array(
- 'auth_link' => array('title' => 'UCP_AUTH_LINK_MANAGE', 'auth' => '', 'cat' => array('UCP_PROFILE')),
+ 'auth_link' => array('title' => 'UCP_AUTH_LINK_MANAGE', 'auth' => 'authmethod_oauth', 'cat' => array('UCP_PROFILE')),
),
);
}
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..3219771c93 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,81 @@ 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_'))
+ // 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 = ($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'));
+ if (!$can_ignore_allow_pm)
{
- $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);
+ $sql .= ' OR user_allow_pm = 0';
+ }
- $removed = false;
- while ($row = $db->sql_fetchrow($result))
+ $result = $db->sql_query($sql);
+
+ $removed_no_pm = $removed_no_permission = false;
+ while ($row = $db->sql_fetchrow($result))
+ {
+ if (!$can_ignore_allow_pm && !$row['user_allow_pm'])
{
- $removed = true;
- unset($address_list['u'][$row['user_id']]);
+ $removed_no_pm = true;
}
- $db->sql_freeresult($result);
+ else
+ {
+ $removed_no_permission = true;
+ }
+
+ 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)
+ // 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)
+ {
+ unset($address_list['u'][$cannot_read]);
+ }
+
+ $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 bad51e2fe3..6c9eeb6a75 100644
--- a/phpBB/install/database_update.php
+++ b/phpBB/install/database_update.php
@@ -169,6 +169,8 @@ header('Content-type: text/html; charset=UTF-8');
<?php
+define('IN_DB_UPDATE', true);
+
/**
* @todo firebird/mysql update?
*/
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 db8156a831..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...
@@ -1674,6 +1712,18 @@ class install_install extends module
$db->sql_freeresult($result);
$_module->move_module_by($row, 'move_down', 4);
+
+ // Move OAuth module 5 down...
+ $sql = 'SELECT *
+ FROM ' . MODULES_TABLE . "
+ WHERE module_basename = 'ucp_auth_link'
+ AND module_class = 'ucp'
+ AND module_mode = 'auth_link'";
+ $result = $db->sql_query($sql);
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ $_module->move_module_by($row, 'move_down', 5);
}
// And now for the special ones
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/attachments.php b/phpBB/language/en/acp/attachments.php
index c7d68d29c2..6ca2865383 100644
--- a/phpBB/language/en/acp/attachments.php
+++ b/phpBB/language/en/acp/attachments.php
@@ -107,6 +107,9 @@ $lang = array_merge($lang, array(
'EXT_GROUP_REAL_MEDIA' => 'Real Media',
'EXT_GROUP_WINDOWS_MEDIA' => 'Windows Media',
+ 'FILES_GONE' => 'Some of the attachments you selected for deletion do not exist. They may have been already deleted. Attachments that did exist were deleted.',
+ 'FILES_STATS_WRONG' => 'Your file statistics are likely inaccurate and need to be resynchronised. Actual values: number of attachments = %1$d, total size of attachments = %2$s.<br />Click %3$shere%4$s to resynchronise them.',
+
'GO_TO_EXTENSIONS' => 'Go to extension management screen',
'GROUP_NAME' => 'Group name',
@@ -130,6 +133,7 @@ $lang = array_merge($lang, array(
'NOT_ALLOWED_IN_PM' => 'Only allowed in posts',
'NOT_ALLOWED_IN_PM_POST' => 'Not allowed',
'NOT_ASSIGNED' => 'Not assigned',
+ 'NO_ATTACHMENTS' => 'No attachments found for this period.',
'NO_EXT_GROUP' => 'None',
'NO_EXT_GROUP_NAME' => 'No group name entered',
'NO_EXT_GROUP_SPECIFIED' => 'No extension group specified.',
@@ -143,8 +147,9 @@ $lang = array_merge($lang, array(
'ORDER_ALLOW_DENY' => 'Allow',
'ORDER_DENY_ALLOW' => 'Deny',
- 'REMOVE_ALLOWED_IPS' => 'Remove or un-exclude <em>allowed</em> IPs/hostnames',
- 'REMOVE_DISALLOWED_IPS' => 'Remove or un-exclude <em>disallowed</em> IPs/hostnames',
+ 'REMOVE_ALLOWED_IPS' => 'Remove or un-exclude <em>allowed</em> IPs/hostnames',
+ 'REMOVE_DISALLOWED_IPS' => 'Remove or un-exclude <em>disallowed</em> IPs/hostnames',
+ 'RESYNC_FILES_STATS_CONFIRM' => 'Are you sure you wish to resynchronise file statistics?',
'SEARCH_IMAGICK' => 'Search for Imagemagick',
'SECURE_ALLOW_DENY' => 'Allow/Deny list',
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 5794a7c833..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',
@@ -241,9 +240,6 @@ $lang = array_merge($lang, array(
'EXPORT_DOWNLOAD' => 'Download',
'EXPORT_STORE' => 'Store',
- 'FILES_GONE' => 'Some of the attachments you selected for deletion do not exist. They may have been already deleted. Attachments that did exist were deleted.',
- 'FILES_STATS_WRONG' => 'Your files statistics are probably inaccurate and need to be resynchronised. Actual values: number of attachments = %1$d, total size of attachments = %2$s.',
-
'GENERAL_OPTIONS' => 'General options',
'GENERAL_SETTINGS' => 'General settings',
'GLOBAL_MASK' => 'Global permission mask',
@@ -286,8 +282,6 @@ $lang = array_merge($lang, array(
'REMIND' => 'Remind',
'RESYNC' => 'Resynchronise',
- 'RESYNC_FILES_STATS' => 'Resynchronise files statistics',
- 'RESYNC_FILES_STATS_EXPLAIN' => 'Recalculates the total number and size of files attached to posts and private messages.',
'SELECT_ANONYMOUS' => 'Select anonymous user',
'SELECT_OPTION' => 'Select option',
@@ -388,7 +382,6 @@ $lang = array_merge($lang, array(
'RESET_ONLINE' => 'Reset most users ever online',
'RESET_ONLINE_CONFIRM' => 'Are you sure you wish to reset the most users ever online counter?',
'RESET_ONLINE_SUCCESS' => 'Most users ever online reset',
- 'RESYNC_FILES_STATS_CONFIRM' => 'Are you sure you wish to resynchronise files statistics?',
'RESYNC_POSTCOUNTS' => 'Resynchronise post counts',
'RESYNC_POSTCOUNTS_EXPLAIN' => 'Only existing posts will be taken into consideration. Pruned posts will not be counted.',
'RESYNC_POSTCOUNTS_CONFIRM' => 'Are you sure you wish to resynchronise post counts?',
@@ -557,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',
@@ -570,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',
@@ -684,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',
@@ -696,7 +688,7 @@ $lang = array_merge($lang, array(
'LOG_REFERER_INVALID' => '<strong>Referer validation failed</strong><br />»Referer was “<em>%1$s</em>”. The request was rejected and the session killed.',
'LOG_RESET_DATE' => '<strong>Board start date reset</strong>',
'LOG_RESET_ONLINE' => '<strong>Most users online reset</strong>',
- 'LOG_RESYNC_FILES_STATS' => '<strong>Files statistics resynchronised</strong>',
+ 'LOG_RESYNC_FILES_STATS' => '<strong>File statistics resynchronised</strong>',
'LOG_RESYNC_POSTCOUNTS' => '<strong>User post counts resynchronised</strong>',
'LOG_RESYNC_POST_MARKING' => '<strong>Dotted topics resynchronised</strong>',
'LOG_RESYNC_STATS' => '<strong>Post, topic and user statistics resynchronised</strong>',
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..aac4f2516e 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',
),
@@ -1370,7 +1373,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 40c8bd9f8e..3419d34e7a 100644
--- a/phpBB/language/en/ucp.php
+++ b/phpBB/language/en/ucp.php
@@ -412,6 +412,8 @@ $lang = array_merge($lang, array(
'PM_SENTBOX' => 'Sent messages',
'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',
@@ -602,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',
@@ -625,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/language/en/viewtopic.php b/phpBB/language/en/viewtopic.php
index b566f4b5c0..afbad5a0d6 100644
--- a/phpBB/language/en/viewtopic.php
+++ b/phpBB/language/en/viewtopic.php
@@ -58,7 +58,7 @@ $lang = array_merge($lang, array(
1 => 'Last edited by %2$s on %3$s, edited %1$d time in total.',
2 => 'Last edited by %2$s on %3$s, edited %1$d times in total.',
),
- 'EMAIL_TOPIC' => 'Email friend',
+ 'EMAIL_TOPIC' => 'Email topic',
'ERROR_NO_ATTACHMENT' => 'The selected attachment does not exist anymore.',
'FILE_NOT_FOUND_404' => 'The file <strong>%s</strong> does not exist.',
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/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/provider.php b/phpBB/phpbb/controller/provider.php
index 9df8130210..2c7493f64c 100644
--- a/phpBB/phpbb/controller/provider.php
+++ b/phpBB/phpbb/controller/provider.php
@@ -46,7 +46,7 @@ class provider
// 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')
+ ->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/auth_provider_oauth2.php b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php
new file mode 100644
index 0000000000..692647dcde
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php
@@ -0,0 +1,40 @@
+<?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 auth_provider_oauth2 extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v310\auth_provider_oauth',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(
+ array($this, 'update_auth_link_module_auth'),
+ )),
+ );
+ }
+
+ public function update_auth_link_module_auth()
+ {
+ $sql = 'UPDATE ' . MODULES_TABLE . "
+ SET module_auth = 'authmethod_oauth'
+ WHERE module_class = 'ucp'
+ AND module_basename = 'ucp_auth_link'
+ AND module_mode = 'auth_link'
+ AND module_auth = ''";
+ $this->db->sql_query($sql);
+ }
+}
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/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 3d480b7e1c..a983ed91b5 100644
--- a/phpBB/phpbb/db/tools.php
+++ b/phpBB/phpbb/db/tools.php
@@ -34,6 +34,12 @@ class tools
var $dbms_type_map = array();
/**
+ * Is the used MS SQL Server a SQL Server 2000?
+ * @var bool
+ */
+ protected $is_sql_server_2000;
+
+ /**
* Get the column types for every database we support
*
* @return array
@@ -251,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',
@@ -293,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).
@@ -383,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':
@@ -561,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;
@@ -598,6 +642,7 @@ class tools
case 'mysql_40':
case 'sqlite':
+ case 'sqlite3':
$table_sql .= "\n);";
$statements[] = $table_sql;
break;
@@ -716,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;
@@ -1134,6 +1179,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "SELECT sql
FROM sqlite_master
WHERE type = 'table'
@@ -1267,6 +1313,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "PRAGMA index_list('" . $table_name . "');";
$col = 'name';
break;
@@ -1287,6 +1334,7 @@ class tools
case 'oracle':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
@@ -1371,6 +1419,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "PRAGMA index_list('" . $table_name . "');";
$col = 'name';
break;
@@ -1384,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;
}
@@ -1412,6 +1461,7 @@ class tools
case 'firebird':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
@@ -1623,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
{
@@ -1764,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;
}
@@ -1846,50 +1898,46 @@ class tools
case 'mssql':
case 'mssqlnative':
- $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version";
- $result = $this->db->sql_query($sql);
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
+ // We need the data here
+ $old_return_statements = $this->return_statements;
+ $this->return_statements = true;
- // Remove default constraints
- if ($row['mssql_version'][0] == '8') // SQL Server 2000
- {
- // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx
- // Deprecated in SQL Server 2005
- $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000)
- SET @drop_default_name =
- (SELECT so.name FROM sysobjects so
- JOIN sysconstraints sc ON so.id = sc.constid
- WHERE object_name(so.parent_obj) = '{$table_name}'
- AND so.xtype = 'D'
- AND sc.colid = (SELECT colid FROM syscolumns
- WHERE id = object_id('{$table_name}')
- AND name = '{$column_name}'))
- IF @drop_default_name <> ''
- BEGIN
- SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']'
- EXEC(@cmd)
- END";
- }
- else
- {
- $sql = "SELECT dobj.name AS def_name
- FROM sys.columns col
- LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D')
- WHERE col.object_id = object_id('{$table_name}')
- AND col.name = '{$column_name}'
- AND dobj.name IS NOT NULL";
- $result = $this->db->sql_query($sql);
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
+ $indexes = $this->mssql_get_existing_indexes($table_name, $column_name);
- if ($row)
+ // Drop any indexes
+ $recreate_indexes = array();
+ if (!empty($indexes))
+ {
+ foreach ($indexes as $index_name => $index_data)
{
- $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']';
+ $result = $this->sql_index_drop($table_name, $index_name);
+ $statements = array_merge($statements, $result);
+ if (sizeof($index_data) > 1)
+ {
+ // Remove this column from the index and recreate it
+ $recreate_indexes[$index_name] = array_diff($index_data, array($column_name));
+ }
}
}
+ // Drop default value constraint
+ $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name);
+ $statements = array_merge($statements, $result);
+
+ // Remove the column
$statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']';
+
+ if (!empty($recreate_indexes))
+ {
+ // Recreate indexes after we removed the column
+ foreach ($recreate_indexes as $index_name => $index_data)
+ {
+ $result = $this->sql_create_index($table_name, $index_name, $index_data);
+ $statements = array_merge($statements, $result);
+ }
+ }
+
+ $this->return_statements = $old_return_statements;
break;
case 'mysql_40':
@@ -1906,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;
}
@@ -1996,6 +2038,7 @@ class tools
case 'oracle':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name;
break;
}
@@ -2102,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);
@@ -2150,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';
@@ -2180,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;
@@ -2223,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;
@@ -2314,6 +2355,7 @@ class tools
break;
case 'sqlite':
+ case 'sqlite3':
$sql = "PRAGMA index_info('" . $table_name . "');";
$col = 'name';
break;
@@ -2333,6 +2375,7 @@ class tools
case 'oracle':
case 'postgres':
case 'sqlite':
+ case 'sqlite3':
$row[$col] = substr($row[$col], strlen($table_name) + 1);
break;
}
@@ -2371,53 +2414,46 @@ class tools
case 'mssql':
case 'mssqlnative':
+ // We need the data here
+ $old_return_statements = $this->return_statements;
+ $this->return_statements = true;
+
+ $indexes = $this->mssql_get_existing_indexes($table_name, $column_name);
+
+ // Drop any indexes
+ if (!empty($indexes))
+ {
+ foreach ($indexes as $index_name => $index_data)
+ {
+ $result = $this->sql_index_drop($table_name, $index_name);
+ $statements = array_merge($statements, $result);
+ }
+ }
+
+ // Drop default value constraint
+ $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name);
+ $statements = array_merge($statements, $result);
+
+ // Change the column
$statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql'];
if (!empty($column_data['default']))
{
- $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version";
- $result = $this->db->sql_query($sql);
- $row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
+ // Add new default value constraint
+ $statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $this->db->sql_escape($column_data['default']) . ' FOR [' . $column_name . ']';
+ }
- // Using TRANSACT-SQL for this statement because we do not want to have colliding data if statements are executed at a later stage
- if ($row['mssql_version'][0] == '8') // SQL Server 2000
- {
- $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000)
- SET @drop_default_name =
- (SELECT so.name FROM sysobjects so
- JOIN sysconstraints sc ON so.id = sc.constid
- WHERE object_name(so.parent_obj) = '{$table_name}'
- AND so.xtype = 'D'
- AND sc.colid = (SELECT colid FROM syscolumns
- WHERE id = object_id('{$table_name}')
- AND name = '{$column_name}'))
- IF @drop_default_name <> ''
- BEGIN
- SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']'
- EXEC(@cmd)
- END
- SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]'
- EXEC(@cmd)";
- }
- else
+ if (!empty($indexes))
+ {
+ // Recreate indexes after we changed the column
+ foreach ($indexes as $index_name => $index_data)
{
- $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000)
- SET @drop_default_name =
- (SELECT dobj.name FROM sys.columns col
- LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D')
- WHERE col.object_id = object_id('{$table_name}')
- AND col.name = '{$column_name}'
- AND dobj.name IS NOT NULL)
- IF @drop_default_name <> ''
- BEGIN
- SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']'
- EXEC(@cmd)
- END
- SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]'
- EXEC(@cmd)";
+ $result = $this->sql_create_index($table_name, $index_name, $index_data);
+ $statements = array_merge($statements, $result);
}
}
+
+ $this->return_statements = $old_return_statements;
break;
case 'mysql_40':
@@ -2493,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);
@@ -2539,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';
@@ -2551,4 +2583,230 @@ class tools
return $this->_sql_run_sql($statements);
}
+
+ /**
+ * Get queries to drop the default constraints of a column
+ *
+ * We need to drop the default constraints of a column,
+ * before being able to change their type or deleting them.
+ *
+ * @param string $table_name
+ * @param string $column_name
+ * @return array Array with SQL statements
+ */
+ protected function mssql_get_drop_default_constraints_queries($table_name, $column_name)
+ {
+ $statements = array();
+ if ($this->mssql_is_sql_server_2000())
+ {
+ // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx
+ // Deprecated in SQL Server 2005
+ $sql = "SELECT so.name AS def_name
+ FROM sysobjects so
+ JOIN sysconstraints sc ON so.id = sc.constid
+ WHERE object_name(so.parent_obj) = '{$table_name}'
+ AND so.xtype = 'D'
+ AND sc.colid = (SELECT colid FROM syscolumns
+ WHERE id = object_id('{$table_name}')
+ AND name = '{$column_name}')";
+ }
+ else
+ {
+ $sql = "SELECT dobj.name AS def_name
+ FROM sys.columns col
+ LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D')
+ WHERE col.object_id = object_id('{$table_name}')
+ AND col.name = '{$column_name}'
+ AND dobj.name IS NOT NULL";
+ }
+
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']';
+ }
+ $this->db->sql_freeresult($result);
+
+ return $statements;
+ }
+
+ /**
+ * Get a list with existing indexes for the column
+ *
+ * @param string $table_name
+ * @param string $column_name
+ * @return array Array with Index name => columns
+ */
+ protected function mssql_get_existing_indexes($table_name, $column_name)
+ {
+ $existing_indexes = array();
+ if ($this->mssql_is_sql_server_2000())
+ {
+ // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx
+ // Deprecated in SQL Server 2005
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name
+ FROM sysindexes ix
+ INNER JOIN sysindexkeys ixc
+ ON ixc.id = ix.id
+ AND ixc.indid = ix.indid
+ INNER JOIN syscolumns cols
+ ON cols.colid = ixc.colid
+ AND cols.id = ix.id
+ WHERE ix.id = object_id('{$table_name}')
+ AND cols.name = '{$column_name}'";
+ }
+ else
+ {
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name
+ FROM sys.indexes ix
+ INNER JOIN sys.index_columns ixc
+ ON ixc.object_id = ix.object_id
+ AND ixc.index_id = ix.index_id
+ INNER JOIN sys.columns cols
+ ON cols.column_id = ixc.column_id
+ AND cols.object_id = ix.object_id
+ WHERE ix.object_id = object_id('{$table_name}')
+ AND cols.name = '{$column_name}'";
+ }
+
+ $result = $this->db->sql_query($sql);
+ $existing_indexes = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $existing_indexes[$row['phpbb_index_name']] = array();
+ }
+ $this->db->sql_freeresult($result);
+
+ if (empty($existing_indexes))
+ {
+ return array();
+ }
+
+ if ($this->mssql_is_sql_server_2000())
+ {
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name
+ FROM sysindexes ix
+ INNER JOIN sysindexkeys ixc
+ ON ixc.id = ix.id
+ AND ixc.indid = ix.indid
+ INNER JOIN syscolumns cols
+ ON cols.colid = ixc.colid
+ AND cols.id = ix.id
+ WHERE ix.id = object_id('{$table_name}')
+ AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes));
+ }
+ else
+ {
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name
+ FROM sys.indexes ix
+ INNER JOIN sys.index_columns ixc
+ ON ixc.object_id = ix.object_id
+ AND ixc.index_id = ix.index_id
+ INNER JOIN sys.columns cols
+ ON cols.column_id = ixc.column_id
+ AND cols.object_id = ix.object_id
+ WHERE ix.object_id = object_id('{$table_name}')
+ AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes));
+ }
+
+ $result = $this->db->sql_query($sql);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name'];
+ }
+ $this->db->sql_freeresult($result);
+
+ return $existing_indexes;
+ }
+
+ /**
+ * Is the used MS SQL Server a SQL Server 2000?
+ *
+ * @return bool
+ */
+ protected function mssql_is_sql_server_2000()
+ {
+ if ($this->is_sql_server_2000 === null)
+ {
+ $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version";
+ $result = $this->db->sql_query($sql);
+ $properties = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+ $this->is_sql_server_2000 = $properties['mssql_version'][0] == '8';
+ }
+
+ 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/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..8e6490923d 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()
diff --git a/phpBB/phpbb/feed/post_base.php b/phpBB/phpbb/feed/post_base.php
index c797d6a8ca..de98f446f3 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();
@@ -49,41 +49,4 @@ abstract class post_base extends \phpbb\feed\base
. (($this->is_moderator_approve_forum($row['forum_id']) && $row['post_visibility'] !== ITEM_APPROVED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : '');
}
}
-
- 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..fb49aa65cc 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()
diff --git a/phpBB/phpbb/feed/topic_base.php b/phpBB/phpbb/feed/topic_base.php
index 7e28e67b82..e8639a6fa6 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';
diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php
index 44fba06d9d..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)));
@@ -643,9 +665,23 @@ class log implements \phpbb\log\log_interface
$operations = array();
foreach ($this->user->lang as $key => $value)
{
- if (substr($key, 0, 4) == 'LOG_' && preg_match($keywords_pattern, $value))
+ if (substr($key, 0, 4) == 'LOG_')
{
- $operations[] = $key;
+ if (is_array($value))
+ {
+ foreach ($value as $plural_value)
+ {
+ if (preg_match($keywords_pattern, $plural_value))
+ {
+ $operations[] = $key;
+ break;
+ }
+ }
+ }
+ else if (preg_match($keywords_pattern, $value))
+ {
+ $operations[] = $key;
+ }
}
}
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..f8e473dcad 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;
diff --git a/phpBB/posting.php b/phpBB/posting.php
index ed1268e84b..cfd6524e62 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
@@ -1558,10 +1573,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 46f738aa3a..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">
@@ -24,16 +24,12 @@
</div>
</div>
-
-
-<div class="clear"></div>
-
<!-- BEGIN faq_block -->
<div class="panel <!-- IF faq_block.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF -->">
<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_footer.html b/phpBB/styles/prosilver/template/mcp_footer.html
index e5768bdc6b..89ce7c34ab 100644
--- a/phpBB/styles/prosilver/template/mcp_footer.html
+++ b/phpBB/styles/prosilver/template/mcp_footer.html
@@ -1,9 +1,8 @@
</div>
- <div class="clear"></div>
</div>
- <span class="corners-bottom"><span></span></span></div>
+ </div>
</div>
<!-- INCLUDE overall_footer.html -->
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..dd5e27a10e 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 -->
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 57d6fe0911..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 -->">
@@ -50,14 +52,14 @@
<!-- ENDIF -->
</dl>
- <span class="clear"></span></div>
+ </div>
</div>
<!-- EVENT memberlist_view_contact_before -->
<div class="panel bg2">
<div class="inner">
- <div class="column1">
+ <div class="column1">
<h3>{L_CONTACT_USER} {USERNAME}</h3>
<dl class="details">
@@ -103,7 +105,8 @@
<!-- EVENT memberlist_view_user_statistics_after -->
</dl>
</div>
- <span class="clear"></span></div>
+
+ </div>
</div>
<!-- EVENT memberlist_view_contact_after -->
@@ -115,7 +118,7 @@
<div class="postbody"><div class="signature standalone">{SIGNATURE}</div></div>
- <span class="clear"></span></div>
+ </div>
</div>
<!-- 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 d10976c0da..804fa5b2aa 100644
--- a/phpBB/styles/prosilver/template/navbar_header.html
+++ b/phpBB/styles/prosilver/template/navbar_header.html
@@ -6,15 +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 U_EMAIL_TOPIC --><li class="rightside"><a href="{U_EMAIL_TOPIC}" title="{L_EMAIL_TOPIC}" class="sendemail">{L_EMAIL_TOPIC}</a></li><!-- ENDIF -->
- <!-- IF U_EMAIL_PM --><li class="rightside"><a href="{U_EMAIL_PM}" title="{L_EMAIL_PM}" class="sendemail">{L_EMAIL_PM}</a></li><!-- ENDIF -->
- <!-- IF U_PRINT_TOPIC --><li class="rightside"><a href="{U_PRINT_TOPIC}" title="{L_PRINT_TOPIC}" accesskey="p" class="print">{L_PRINT_TOPIC}</a></li><!-- ENDIF -->
- <!-- IF U_PRINT_PM --><li class="rightside"><a href="{U_PRINT_PM}" title="{L_PRINT_PM}" accesskey="p" class="print">{L_PRINT_PM}</a></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_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_header.html b/phpBB/styles/prosilver/template/posting_pm_header.html
index 114b361e9a..dea50b5daf 100644
--- a/phpBB/styles/prosilver/template/posting_pm_header.html
+++ b/phpBB/styles/prosilver/template/posting_pm_header.html
@@ -76,7 +76,6 @@
</dl>
</div>
<!-- ENDIF -->
-
- <div class="clear"></div>
+
<!-- ENDIF -->
</fieldset>
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/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_footer.html b/phpBB/styles/prosilver/template/ucp_footer.html
index ea546f7a82..f2f1a68db3 100644
--- a/phpBB/styles/prosilver/template/ucp_footer.html
+++ b/phpBB/styles/prosilver/template/ucp_footer.html
@@ -1,9 +1,8 @@
</div>
- <div class="clear"></div>
</div>
- <span class="corners-bottom"><span></span></span></div>
+ </div>
</div>
<!-- IF S_COMPOSE_PM -->
<div>{S_FORM_TOKEN}</div>
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_message_header.html b/phpBB/styles/prosilver/template/ucp_pm_message_header.html
index a6ef3fc7dd..840eba4c83 100644
--- a/phpBB/styles/prosilver/template/ucp_pm_message_header.html
+++ b/phpBB/styles/prosilver/template/ucp_pm_message_header.html
@@ -15,6 +15,18 @@
</div>
<!-- ENDIF -->
+ <!-- IF not S_IS_BOT and U_PRINT_PM -->
+ <div class="dropdown-container dropdown-button-control topic-tools">
+ <span title="{L_PM_TOOLS}" class="dropdown-trigger dropdown-select dropdown-select-icon tools-icon"><span></span></span>
+ <div class="dropdown hidden">
+ <div class="pointer"><div class="pointer-inner"></div></div>
+ <ul class="dropdown-contents">
+ <!-- IF U_PRINT_PM --><li class="small-icon icon-print"><a href="{U_PRINT_PM}" title="{L_PRINT_PM}" accesskey="p">{L_PRINT_PM}</a></li><!-- ENDIF -->
+ </ul>
+ </div>
+ </div>
+ <!-- ENDIF -->
+
<!-- IF TOTAL_MESSAGES or S_VIEW_MESSAGE -->
<ul class="linklist">
<li class="rightside pagination">
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..ed45835da6 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 -->">
@@ -143,26 +145,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>
diff --git a/phpBB/styles/prosilver/template/viewtopic_topic_tools.html b/phpBB/styles/prosilver/template/viewtopic_topic_tools.html
index fcce2267c4..89f34d1b3a 100644
--- a/phpBB/styles/prosilver/template/viewtopic_topic_tools.html
+++ b/phpBB/styles/prosilver/template/viewtopic_topic_tools.html
@@ -1,4 +1,4 @@
-<!-- IF not S_IS_BOT and (U_WATCH_TOPIC or U_BOOKMARK_TOPIC or U_BUMP_TOPIC or S_HAS_ATTACHMENTS or S_DISPLAY_TOPIC_TOOLS) -->
+<!-- IF not S_IS_BOT and (U_WATCH_TOPIC or U_BOOKMARK_TOPIC or U_BUMP_TOPIC or S_HAS_ATTACHMENTS or U_EMAIL_TOPIC or U_PRINT_TOPIC or S_DISPLAY_TOPIC_TOOLS) -->
<div class="dropdown-container dropdown-button-control topic-tools">
<span title="{L_TOPIC_TOOLS}" class="dropdown-trigger dropdown-select dropdown-select-icon tools-icon"><span></span></span>
<div class="dropdown hidden">
@@ -20,6 +20,8 @@
</li>
<!-- ENDIF -->
<!-- IF U_BUMP_TOPIC --><li class="small-icon icon-bump"><a href="{U_BUMP_TOPIC}" title="{L_BUMP_TOPIC}" data-ajax="true">{L_BUMP_TOPIC}</a></li><!-- ENDIF -->
+ <!-- IF U_EMAIL_TOPIC --><li class="small-icon icon-sendemail"><a href="{U_EMAIL_TOPIC}" title="{L_EMAIL_TOPIC}">{L_EMAIL_TOPIC}</a></li><!-- ENDIF -->
+ <!-- IF U_PRINT_TOPIC --><li class="small-icon icon-print"><a href="{U_PRINT_TOPIC}" title="{L_PRINT_TOPIC}" accesskey="p">{L_PRINT_TOPIC}</a></li><!-- ENDIF -->
<!-- IF S_HAS_ATTACHMENTS -->
<li class="small-icon icon-download">
<a class="dropdown-toggle-submenu" href="{U_DOWNLOAD_ALL_ATTACHMENTS}" title="{L_DOWNLOAD_ALL_ATTACHMENTS}">{L_DOWNLOAD_ALL_ATTACHMENTS}</a>
diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css
index 850726db89..0d5e1cf829 100644
--- a/phpBB/styles/prosilver/theme/bidi.css
+++ b/phpBB/styles/prosilver/theme/bidi.css
@@ -552,12 +552,6 @@ ul.linklist li.small-icon > a, ul.linklist li.breadcrumbs span:first-child > a {
margin: 0 1px 0 5px;
}
-/* Sub-header (navigation bar)
---------------------------------------------- */
-.rtl a.print, .rtl a.sendemail {
- text-align: right;
-}
-
/* Icon images
---------------------------------------- */
.rtl .small-icon {
diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css
index 93c325e416..9ca04516cc 100644
--- a/phpBB/styles/prosilver/theme/buttons.css
+++ b/phpBB/styles/prosilver/theme/buttons.css
@@ -101,27 +101,6 @@
.dropdown-visible .dropdown-select.tools-icon:before,
.nojs .dropdown-container:hover .dropdown-select.tools-icon:before { background-position: -80px -20px; }
-/* Sub-header (navigation bar)
---------------------------------------------- */
-a.print, a.sendemail {
- display: block;
- overflow: hidden;
- height: 18px;
- text-indent: -5000px;
- text-align: left;
- background-repeat: no-repeat;
-}
-
-a.print {
- background-image: none;
- width: 22px;
-}
-
-a.sendemail {
- background-image: none;
- width: 22px;
-}
-
/* Icon images
---------------------------------------- */
.small-icon {
@@ -235,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 5f6ca4929c..39f28b4774 100644
--- a/phpBB/styles/prosilver/theme/colours.css
+++ b/phpBB/styles/prosilver/theme/colours.css
@@ -665,14 +665,6 @@ fieldset.polls dd div {
Colours and backgrounds for buttons.css
-------------------------------------------------------------- */
-a.print {
- background-image: url("./images/icon_print.gif");
-}
-
-a.sendemail {
- background-image: url("./images/icon_sendemail.gif");
-}
-
.buttons div a, .dropdown-select {
border-color: #C7C3BF;
background-color: #FFFFFF;
@@ -718,6 +710,14 @@ a.sendemail {
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"); }
@@ -736,21 +736,12 @@ a.sendemail {
.icon-pm { background-image: url("./images/icon_pm.gif"); }
.icon-download { background-image: url("./images/icon_download.gif"); }
.icon-mark { background-image: url("./images/icon_mark.gif"); }
+.icon-sendemail { background-image: url("./images/icon_sendemail.gif"); }
+.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 15ac63ca90..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;
}
@@ -433,11 +432,11 @@ ul.linklist.bulletin li:before {
}
ul.linklist.bulletin li:first-child:before, ul.linklist.bulletin li.rightside:last-child:before {
- display: none;
+ content: none;
}
ul.linklist.bulletin li.no-bulletin:before {
- display: none;
+ content: none;
}
.responsive-menu:before {
@@ -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..dc6ab9aef3 100644
--- a/phpBB/styles/prosilver/theme/content.css
+++ b/phpBB/styles/prosilver/theme/content.css
@@ -731,6 +731,20 @@ fieldset.polls dd div {
height: auto !important;
}
+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;
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/icon_print.gif b/phpBB/styles/prosilver/theme/images/icon_print.gif
index a71dfdde70..e464e304ea 100644..100755
--- a/phpBB/styles/prosilver/theme/images/icon_print.gif
+++ b/phpBB/styles/prosilver/theme/images/icon_print.gif
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/images/icon_sendemail.gif b/phpBB/styles/prosilver/theme/images/icon_sendemail.gif
index f6b8aa10e1..92a39c8af9 100644
--- a/phpBB/styles/prosilver/theme/images/icon_sendemail.gif
+++ b/phpBB/styles/prosilver/theme/images/icon_sendemail.gif
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/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/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..6ac4e0ea33 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>
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..84040af2bb 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']),
@@ -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)));