aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--phpBB/includes/acp/acp_bbcodes.php5
-rw-r--r--phpBB/includes/acp/acp_forums.php33
-rw-r--r--phpBB/includes/utf/utf_tools.php43
-rw-r--r--phpBB/language/en/acp/posting.php1
-rw-r--r--phpBB/phpbb/auth/provider/oauth/oauth.php11
-rw-r--r--phpBB/phpbb/console/command/extension/enable.php11
-rw-r--r--phpBB/styles/prosilver/template/mcp_topic.html2
-rw-r--r--phpBB/styles/prosilver/template/posting_review.html2
-rw-r--r--phpBB/styles/prosilver/template/posting_topic_review.html2
-rw-r--r--phpBB/styles/prosilver/template/viewtopic_body.html2
-rw-r--r--tests/functional/download_test.php2
-rw-r--r--tests/functional/feed_test.php6
-rw-r--r--tests/functional/posting_test.php4
-rw-r--r--tests/functional/prune_shadow_topic_test.php2
-rw-r--r--tests/functional/visibility_softdelete_test.php4
15 files changed, 85 insertions, 45 deletions
diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php
index 5360ab0f7b..a67f3c54f9 100644
--- a/phpBB/includes/acp/acp_bbcodes.php
+++ b/phpBB/includes/acp/acp_bbcodes.php
@@ -211,11 +211,6 @@ class acp_bbcodes
$test = $data['bbcode_tag'];
}
- if (!preg_match('%\\[' . $test . '[^]]*].*?\\[/' . $test . ']%s', $bbcode_match))
- {
- trigger_error($user->lang['BBCODE_OPEN_ENDED_TAG'] . adm_back_link($this->u_action), E_USER_WARNING);
- }
-
if (strlen($data['bbcode_tag']) > 16)
{
trigger_error($user->lang['BBCODE_TAG_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING);
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index 9044cd0e97..e3979632c2 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -986,10 +986,20 @@ class acp_forums
$errors[] = $user->lang['FORUM_NAME_EMPTY'];
}
- // No Emojis
+ /**
+ * Replace Emojis and other 4bit UTF-8 chars not allowed by MySql to UCR / NCR.
+ * Using their Numeric Character Reference's Hexadecimal notation.
+ */
+ $forum_data_ary['forum_name'] = utf8_encode_ucr($forum_data_ary['forum_name']);
+
+ /**
+ * This should never happen again.
+ * Leaving the fallback here just in case there will be the need of it.
+ */
if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $forum_data_ary['forum_name'], $matches))
{
$character_list = implode('<br>', $matches[0]);
+
$errors[] = $user->lang('FORUM_NAME_EMOJI', $character_list);
}
@@ -1423,8 +1433,8 @@ class acp_forums
* This event may be triggered, when a forum is deleted
*
* @event core.acp_manage_forums_move_children
- * @var int from_id If of the current parent forum
- * @var int to_id If of the new parent forum
+ * @var int from_id Id of the current parent forum
+ * @var int to_id Id of the new parent forum
* @var array errors Array of errors, should be strings and not
* language key.
* @since 3.1.0-a1
@@ -1529,8 +1539,8 @@ class acp_forums
* Event when we move content from one forum to another
*
* @event core.acp_manage_forums_move_content
- * @var int from_id If of the current parent forum
- * @var int to_id If of the new parent forum
+ * @var int from_id Id of the current parent forum
+ * @var int to_id Id of the new parent forum
* @var bool sync Shall we sync the "to"-forum's data
* @var array errors Array of errors, should be strings and not
* language key. If this array is not empty,
@@ -1576,6 +1586,19 @@ class acp_forums
$db->sql_query($sql);
}
+ /**
+ * Event when content has been moved from one forum to another
+ *
+ * @event core.acp_manage_forums_move_content_after
+ * @var int from_id Id of the current parent forum
+ * @var int to_id Id of the new parent forum
+ * @var bool sync Shall we sync the "to"-forum's data
+ *
+ * @since 3.2.9-RC1
+ */
+ $vars = array('from_id', 'to_id', 'sync');
+ extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_content_after', compact($vars)));
+
if ($sync)
{
// Delete ghost topics that link back to the same forum then resync counters
diff --git a/phpBB/includes/utf/utf_tools.php b/phpBB/includes/utf/utf_tools.php
index 89de454427..bb155aeae5 100644
--- a/phpBB/includes/utf/utf_tools.php
+++ b/phpBB/includes/utf/utf_tools.php
@@ -418,24 +418,43 @@ function utf8_recode($string, $encoding)
}
/**
-* Replace all UTF-8 chars that are not in ASCII with their NCR
-*
-* @param string $text UTF-8 string in NFC
-* @return string ASCII string using NCRs for non-ASCII chars
-*/
+ * Replace some special UTF-8 chars that are not in ASCII with their UCR.
+ * using their Numeric Character Reference's Hexadecimal notation.
+ *
+ * Doesn't interfere with Japanese or Cyrillic etc.
+ * Unicode character visualization will depend on the character support
+ * of your web browser and the fonts installed on your system.
+ *
+ * @see https://en.wikibooks.org/wiki/Unicode/Character_reference/1F000-1FFFF
+ *
+ * @param string $text UTF-8 string in NFC
+ * @return string ASCII string using NCR for non-ASCII chars
+ */
+function utf8_encode_ucr($text)
+{
+ return preg_replace_callback('/[\\xF0-\\xF4].../', 'utf8_encode_ncr_callback', $text);
+}
+
+/**
+ * Replace all UTF-8 chars that are not in ASCII with their NCR
+ * using their Numeric Character Reference's Hexadecimal notation.
+ *
+ * @param string $text UTF-8 string in NFC
+ * @return string ASCII string using NCRs for non-ASCII chars
+ */
function utf8_encode_ncr($text)
{
return preg_replace_callback('#[\\xC2-\\xF4][\\x80-\\xBF]{1,3}#', 'utf8_encode_ncr_callback', $text);
}
/**
-* Callback used in encode_ncr()
-*
-* Takes a UTF-8 char and replaces it with its NCR. Attention, $m is an array
-*
-* @param array $m 0-based numerically indexed array passed by preg_replace_callback()
-* @return string A HTML NCR if the character is valid, or the original string otherwise
-*/
+ * Callback used in utf8_encode_ncr() and utf8_encode_ucr()
+ *
+ * Takes a UTF-8 char and replaces it with its NCR. Attention, $m is an array
+ *
+ * @param array $m 0-based numerically indexed array passed by preg_replace_callback()
+ * @return string A HTML NCR if the character is valid, or the original string otherwise
+ */
function utf8_encode_ncr_callback($m)
{
return '&#' . utf8_ord($m[0]) . ';';
diff --git a/phpBB/language/en/acp/posting.php b/phpBB/language/en/acp/posting.php
index 1e1c5554e1..1667aa6011 100644
--- a/phpBB/language/en/acp/posting.php
+++ b/phpBB/language/en/acp/posting.php
@@ -56,7 +56,6 @@ $lang = array_merge($lang, array(
'BBCODE_INVALID_TAG_NAME' => 'The BBCode tag name that you selected already exists.',
'BBCODE_INVALID' => 'Your BBCode is constructed in an invalid form.',
- 'BBCODE_OPEN_ENDED_TAG' => 'Your custom BBCode must contain both an opening and a closing tag.',
'BBCODE_TAG' => 'Tag',
'BBCODE_TAG_TOO_LONG' => 'The tag name you selected is too long.',
'BBCODE_TAG_DEF_TOO_LONG' => 'The tag definition that you have entered is too long, please shorten your tag definition.',
diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php
index 0d94acfbca..e3f8394bba 100644
--- a/phpBB/phpbb/auth/provider/oauth/oauth.php
+++ b/phpBB/phpbb/auth/provider/oauth/oauth.php
@@ -216,10 +216,15 @@ class oauth extends \phpbb\auth\provider\base
$this->service_providers[$service_name]->set_external_service_provider($service);
$unique_id = $this->service_providers[$service_name]->perform_auth_login();
- // Check to see if this provider is already assosciated with an account
+ /**
+ * Check to see if this provider is already associated with an account.
+ *
+ * Enforcing a data type to make data contains strings and not integers,
+ * so values are quoted in the SQL WHERE statement.
+ */
$data = array(
- 'provider' => $service_name_original,
- 'oauth_provider_id' => $unique_id
+ 'provider' => (string) $service_name_original,
+ 'oauth_provider_id' => (string) $unique_id
);
$sql = 'SELECT user_id FROM ' . $this->auth_provider_oauth_token_account_assoc . '
diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php
index f007009aa0..504b5546b3 100644
--- a/phpBB/phpbb/console/command/extension/enable.php
+++ b/phpBB/phpbb/console/command/extension/enable.php
@@ -46,9 +46,11 @@ class enable extends command
$extension = $this->manager->get_extension($name);
- if (!$extension->is_enableable())
+ if (($enableable = $extension->is_enableable()) !== true)
{
- $io->error($this->user->lang('CLI_EXTENSION_NOT_ENABLEABLE', $name));
+ $message = !empty($enableable) ? $enableable : $this->user->lang('CLI_EXTENSION_NOT_ENABLEABLE', $name);
+ $message = is_array($message) ? implode(PHP_EOL, $message) : $message;
+ $io->error($message);
return 1;
}
@@ -69,10 +71,7 @@ class enable extends command
}
else
{
- $enableable = $this->manager->get_extension($name)->is_enableable();
- $message = !empty($enableable) ? $enableable : $this->user->lang('CLI_EXTENSION_ENABLE_FAILURE');
- $message = is_array($message) ? implode(PHP_EOL, $message) : $message;
- $io->error($message, $name);
+ $io->error($this->user->lang('CLI_EXTENSION_ENABLE_FAILURE', $name));
return 1;
}
}
diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html
index 090e24041e..889cab8b83 100644
--- a/phpBB/styles/prosilver/template/mcp_topic.html
+++ b/phpBB/styles/prosilver/template/mcp_topic.html
@@ -118,7 +118,7 @@
<!-- EVENT mcp_topic_postrow_post_details_before -->
<p class="author">
- <a href="#pr{postrow.POST_ID}" title="{postrow.MINI_POST}">
+ <a href="{postrow.U_MINI_POST}" title="{postrow.MINI_POST}">
<i class="icon fa-file fa-fw icon-lightgray icon-tiny" aria-hidden="true"></i><span class="sr-only">{postrow.MINI_POST}</span>
</a> {L_POSTED} {postrow.POST_DATE} {L_POST_BY_AUTHOR} {% EVENT mcp_topic_post_author_full_prepend %}<strong>{postrow.POST_AUTHOR_FULL}</strong>{% EVENT mcp_topic_post_author_full_append %}<!-- IF postrow.U_MCP_DETAILS --> [ <a href="{postrow.U_MCP_DETAILS}">{L_POST_DETAILS}</a> ]<!-- ENDIF -->
</p>
diff --git a/phpBB/styles/prosilver/template/posting_review.html b/phpBB/styles/prosilver/template/posting_review.html
index 033a88485e..e5d285e7bf 100644
--- a/phpBB/styles/prosilver/template/posting_review.html
+++ b/phpBB/styles/prosilver/template/posting_review.html
@@ -13,7 +13,7 @@
<!-- ENDIF -->
<div class="postbody" id="ppr{post_review_row.POST_ID}">
- <h3><a href="#ppr{post_review_row.POST_ID}">{post_review_row.POST_SUBJECT}</a></h3>
+ <h3><a href="{post_review_row.U_MINI_POST}">{post_review_row.POST_SUBJECT}</a></h3>
<p class="author">
<!-- IF S_IS_BOT -->
<span><i class="icon fa-file fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{post_review_row.MINI_POST}</span></span>
diff --git a/phpBB/styles/prosilver/template/posting_topic_review.html b/phpBB/styles/prosilver/template/posting_topic_review.html
index 8faece3447..209dadf327 100644
--- a/phpBB/styles/prosilver/template/posting_topic_review.html
+++ b/phpBB/styles/prosilver/template/posting_topic_review.html
@@ -24,7 +24,7 @@
<!-- ENDIF -->
<div class="postbody" id="pr{topic_review_row.POST_ID}">
- <h3><a href="#pr{topic_review_row.POST_ID}">{topic_review_row.POST_SUBJECT}</a></h3>
+ <h3><a href="{topic_review_row.U_MINI_POST}">{topic_review_row.POST_SUBJECT}</a></h3>
<!-- IF (topic_review_row.POSTER_QUOTE and topic_review_row.DECODED_MESSAGE) or topic_review_row.U_MCP_DETAILS -->
<ul class="post-buttons">
diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html
index f77b99dc29..9bfa07e52b 100644
--- a/phpBB/styles/prosilver/template/viewtopic_body.html
+++ b/phpBB/styles/prosilver/template/viewtopic_body.html
@@ -224,7 +224,7 @@
<div id="post_content{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->>
<!-- EVENT viewtopic_body_post_subject_before -->
- <h3 <!-- IF postrow.S_FIRST_ROW -->class="first"<!-- ENDIF -->><!-- IF postrow.POST_ICON_IMG --><img src="{T_ICONS_PATH}{postrow.POST_ICON_IMG}" width="{postrow.POST_ICON_IMG_WIDTH}" height="{postrow.POST_ICON_IMG_HEIGHT}" alt="{postrow.POST_ICON_IMG_ALT}" title="{postrow.POST_ICON_IMG_ALT}" /> <!-- ENDIF --><a href="#p{postrow.POST_ID}">{postrow.POST_SUBJECT}</a></h3>
+ <h3 <!-- IF postrow.S_FIRST_ROW -->class="first"<!-- ENDIF -->><!-- IF postrow.POST_ICON_IMG --><img src="{T_ICONS_PATH}{postrow.POST_ICON_IMG}" width="{postrow.POST_ICON_IMG_WIDTH}" height="{postrow.POST_ICON_IMG_HEIGHT}" alt="{postrow.POST_ICON_IMG_ALT}" title="{postrow.POST_ICON_IMG_ALT}" /> <!-- ENDIF --><a href="{postrow.U_MINI_POST}">{postrow.POST_SUBJECT}</a></h3>
<!-- DEFINE $SHOW_POST_BUTTONS = (postrow.U_EDIT or postrow.U_DELETE or postrow.U_REPORT or postrow.U_WARN or postrow.U_INFO or postrow.U_QUOTE) -->
<!-- EVENT viewtopic_body_post_buttons_list_before -->
diff --git a/tests/functional/download_test.php b/tests/functional/download_test.php
index e2f1d065be..3d4f316d72 100644
--- a/tests/functional/download_test.php
+++ b/tests/functional/download_test.php
@@ -55,7 +55,7 @@ class phpbb_functional_download_test extends phpbb_functional_test_case
// Test creating a reply
$post2 = $this->create_post($this->data['forums']['Download #1'], $post['topic_id'], 'Re: Download Topic #1-#2', 'This is a test post posted by the testing framework.', array('upload_files' => 1));
- $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
+ $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
$this->assertContains('Re: Download Topic #1-#2', $crawler->filter('html')->text());
$this->data['posts']['Re: Download Topic #1-#2'] = (int) $post2['post_id'];
diff --git a/tests/functional/feed_test.php b/tests/functional/feed_test.php
index a3cdfb336d..24ddca9c64 100644
--- a/tests/functional/feed_test.php
+++ b/tests/functional/feed_test.php
@@ -337,7 +337,7 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
// Test creating a reply
$post2 = $this->create_post($this->data['forums']['Feeds #news'], $post['topic_id'], 'Re: Feeds #news - Topic #2', 'This is a test post posted by the testing framework.');
- $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
+ $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
self::assertContains('Re: Feeds #news - Topic #2', $crawler->filter('html')->text());
$this->data['posts']['Re: Feeds #news - Topic #2'] = (int) $post2['post_id'];
@@ -493,7 +493,7 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
// Test creating a reply
$post2 = $this->create_post($this->data['forums']['Feeds #1'], $post['topic_id'], 'Re: Feeds #1 - Topic #2', 'This is a test post posted by the testing framework.');
- $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
+ $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
self::assertContains('Re: Feeds #1 - Topic #2', $crawler->filter('html')->text());
$this->data['posts']['Re: Feeds #1 - Topic #2'] = (int) $post2['post_id'];
@@ -1222,7 +1222,7 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
// Test creating a reply with 1 missing attachment
$post2 = $this->create_post($this->data['forums']['Feeds #1'], $this->data['topics']['Feeds #1 - Topic #3'], 'Re: Feeds #1 - Topic #3-1', 'This is a test post posted by the testing framework. [attachment=0]Attachment #0[/attachment]');
- $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
+ $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
self::assertContains('Re: Feeds #1 - Topic #3-1', $crawler->filter('html')->text());
$this->data['posts']['Re: Feeds #1 - Topic #3-1'] = (int) $post2['post_id'];
diff --git a/tests/functional/posting_test.php b/tests/functional/posting_test.php
index 764376a945..7150f20a9d 100644
--- a/tests/functional/posting_test.php
+++ b/tests/functional/posting_test.php
@@ -29,7 +29,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
// Test creating a reply with bbcode
$post2 = $this->create_post(2, $post['topic_id'], 'Re: Test Topic 1', 'This is a test [b]post[/b] posted by the testing framework.');
- $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
+ $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
$this->assertContains('This is a test post posted by the testing framework.', $crawler->filter('html')->text());
// Test quoting a message
@@ -161,7 +161,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
{
$this->set_quote_depth($quote_depth);
- $post = $this->create_post(2, $topic['topic_id'], 'Re: Test Topic 1', $text);
+ $post = $this->create_post(2, $topic['topic_id'], "Re: Test Topic 1#$quote_depth", $text);
$url = "viewtopic.php?p={$post['post_id']}&sid={$this->sid}";
$crawler = self::request('GET', $url);
diff --git a/tests/functional/prune_shadow_topic_test.php b/tests/functional/prune_shadow_topic_test.php
index 39bf223f93..1d4bb02a95 100644
--- a/tests/functional/prune_shadow_topic_test.php
+++ b/tests/functional/prune_shadow_topic_test.php
@@ -77,7 +77,7 @@ class phpbb_functional_prune_shadow_topic_test extends phpbb_functional_test_cas
// Test creating a reply
$post2 = $this->create_post($this->data['forums']['Prune Shadow'], $this->post['topic_id'], 'Re: Prune Shadow #1-#2', 'This is a test post posted by the testing framework.');
- $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
+ $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
$this->assertContains('Re: Prune Shadow #1-#2', $crawler->filter('html')->text());
$this->data['posts']['Re: Prune Shadow #1-#2'] = (int) $post2['post_id'];
diff --git a/tests/functional/visibility_softdelete_test.php b/tests/functional/visibility_softdelete_test.php
index 6450c00c1e..fd994361a5 100644
--- a/tests/functional/visibility_softdelete_test.php
+++ b/tests/functional/visibility_softdelete_test.php
@@ -97,7 +97,7 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_
// Test creating a reply
$post2 = $this->create_post($this->data['forums']['Soft Delete #1'], $post['topic_id'], 'Re: Soft Delete Topic #1-#2', 'This is a test post posted by the testing framework.');
- $crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}");
+ $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
$this->assertContains('Re: Soft Delete Topic #1-#2', $crawler->filter('html')->text());
$this->data['posts']['Re: Soft Delete Topic #1-#2'] = (int) $post2['post_id'];
@@ -114,7 +114,7 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_
// Test creating another reply
$post3 = $this->create_post($this->data['forums']['Soft Delete #1'], $post['topic_id'], 'Re: Soft Delete Topic #1-#3', 'This is another test post posted by the testing framework.');
- $crawler = self::request('GET', "viewtopic.php?t={$post3['topic_id']}&sid={$this->sid}");
+ $crawler = self::request('GET', "viewtopic.php?p={$post3['post_id']}&sid={$this->sid}");
$this->assertContains('Re: Soft Delete Topic #1-#3', $crawler->filter('html')->text());
$this->data['posts']['Re: Soft Delete Topic #1-#3'] = (int) $post3['post_id'];