mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-28 06:08:52 +00:00
Merge pull request #3623 from s9e/ticket/10620
[ticket/10620] Quote improvements
This commit is contained in:
commit
d54aa190f1
20 changed files with 381 additions and 49 deletions
|
@ -111,7 +111,6 @@ function bbfontstyle(bbopen, bbclose) {
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea.focus();
|
textarea.focus();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -167,7 +166,7 @@ function attachInline(index, filename) {
|
||||||
/**
|
/**
|
||||||
* Add quote text to message
|
* Add quote text to message
|
||||||
*/
|
*/
|
||||||
function addquote(post_id, username, l_wrote) {
|
function addquote(post_id, username, l_wrote, attributes) {
|
||||||
var message_name = 'message_' + post_id;
|
var message_name = 'message_' + post_id;
|
||||||
var theSelection = '';
|
var theSelection = '';
|
||||||
var divarea = false;
|
var divarea = false;
|
||||||
|
@ -177,6 +176,9 @@ function addquote(post_id, username, l_wrote) {
|
||||||
// Backwards compatibility
|
// Backwards compatibility
|
||||||
l_wrote = 'wrote';
|
l_wrote = 'wrote';
|
||||||
}
|
}
|
||||||
|
if (typeof attributes !== 'object') {
|
||||||
|
attributes = {};
|
||||||
|
}
|
||||||
|
|
||||||
if (document.all) {
|
if (document.all) {
|
||||||
divarea = document.all[message_name];
|
divarea = document.all[message_name];
|
||||||
|
@ -213,7 +215,8 @@ function addquote(post_id, username, l_wrote) {
|
||||||
|
|
||||||
if (theSelection) {
|
if (theSelection) {
|
||||||
if (bbcodeEnabled) {
|
if (bbcodeEnabled) {
|
||||||
insert_text('[quote="' + username + '"]' + theSelection + '[/quote]');
|
attributes.author = username;
|
||||||
|
insert_text(generateQuote(theSelection, attributes));
|
||||||
} else {
|
} else {
|
||||||
insert_text(username + ' ' + l_wrote + ':' + '\n');
|
insert_text(username + ' ' + l_wrote + ':' + '\n');
|
||||||
var lines = split_lines(theSelection);
|
var lines = split_lines(theSelection);
|
||||||
|
@ -222,8 +225,61 @@ function addquote(post_id, username, l_wrote) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
/**
|
||||||
|
* Create a quote block for given text
|
||||||
|
*
|
||||||
|
* Possible attributes:
|
||||||
|
* - author: author's name (usually a username)
|
||||||
|
* - post_id: post_id of the post being quoted
|
||||||
|
* - user_id: user_id of the user being quoted
|
||||||
|
* - time: timestamp of the original message
|
||||||
|
*
|
||||||
|
* @param {!string} text Quote's text
|
||||||
|
* @param {!Object} attributes Quote's attributes
|
||||||
|
* @return {!string} Quote block to be used in a new post/text
|
||||||
|
*/
|
||||||
|
function generateQuote(text, attributes) {
|
||||||
|
text = text.replace(/^\s+/, '').replace(/\s+$/, '');
|
||||||
|
var quote = '[quote';
|
||||||
|
if (attributes.author) {
|
||||||
|
// Add the author as the BBCode's default attribute
|
||||||
|
quote += '=' + formatAttributeValue(attributes.author);
|
||||||
|
delete attributes.author;
|
||||||
|
}
|
||||||
|
for (var name in attributes) {
|
||||||
|
if (attributes.hasOwnProperty(name)) {
|
||||||
|
var value = attributes[name];
|
||||||
|
quote += ' ' + name + '=' + formatAttributeValue(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
quote += ']';
|
||||||
|
var newline = ((quote + text + '[/quote]').length > 80 || text.indexOf('\n') > -1) ? '\n' : '';
|
||||||
|
quote += newline + text + newline + '[/quote]';
|
||||||
|
|
||||||
|
return quote;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format given string to be used as an attribute value
|
||||||
|
*
|
||||||
|
* Will return the string as-is if it can be used in a BBCode without quotes. Otherwise,
|
||||||
|
* it will use either single- or double- quotes depending on whichever requires less escaping.
|
||||||
|
* Quotes and backslashes are escaped with backslashes where necessary
|
||||||
|
*
|
||||||
|
* @param {!string} str Original string
|
||||||
|
* @return {!string} Same string if possible, escaped string within quotes otherwise
|
||||||
|
*/
|
||||||
|
function formatAttributeValue(str) {
|
||||||
|
if (!/[ "'\\\]]/.test(str)) {
|
||||||
|
// Return as-is if it contains none of: space, ' " \ or ]
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
var singleQuoted = "'" + str.replace(/[\\']/g, '\\$&') + "'",
|
||||||
|
doubleQuoted = '"' + str.replace(/[\\"]/g, '\\$&') + '"';
|
||||||
|
|
||||||
|
return (singleQuoted.length < doubleQuoted.length) ? singleQuoted : doubleQuoted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function split_lines(text) {
|
function split_lines(text) {
|
||||||
|
|
|
@ -44,6 +44,13 @@ services:
|
||||||
- @text_formatter.s9e.factory
|
- @text_formatter.s9e.factory
|
||||||
- @dispatcher
|
- @dispatcher
|
||||||
|
|
||||||
|
text_formatter.s9e.quote_helper:
|
||||||
|
class: phpbb\textformatter\s9e\quote_helper
|
||||||
|
arguments:
|
||||||
|
- @user
|
||||||
|
- %core.root_path%
|
||||||
|
- %core.php_ext%
|
||||||
|
|
||||||
text_formatter.s9e.renderer:
|
text_formatter.s9e.renderer:
|
||||||
class: phpbb\textformatter\s9e\renderer
|
class: phpbb\textformatter\s9e\renderer
|
||||||
arguments:
|
arguments:
|
||||||
|
@ -53,6 +60,7 @@ services:
|
||||||
- @text_formatter.s9e.factory
|
- @text_formatter.s9e.factory
|
||||||
- @dispatcher
|
- @dispatcher
|
||||||
calls:
|
calls:
|
||||||
|
- [configure_quote_helper, [@text_formatter.s9e.quote_helper]]
|
||||||
- [configure_smilies_path, [@config, @path_helper]]
|
- [configure_smilies_path, [@config, @path_helper]]
|
||||||
- [configure_user, [@user, @config, @auth]]
|
- [configure_user, [@user, @config, @auth]]
|
||||||
|
|
||||||
|
|
|
@ -1193,6 +1193,8 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
|
||||||
'MESSAGE' => $message,
|
'MESSAGE' => $message,
|
||||||
'DECODED_MESSAGE' => $decoded_message,
|
'DECODED_MESSAGE' => $decoded_message,
|
||||||
'POST_ID' => $row['post_id'],
|
'POST_ID' => $row['post_id'],
|
||||||
|
'POST_TIME' => $row['post_time'],
|
||||||
|
'USER_ID' => $row['user_id'],
|
||||||
'U_MINI_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . '#p' . $row['post_id'],
|
'U_MINI_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . '#p' . $row['post_id'],
|
||||||
'U_MCP_DETAILS' => ($auth->acl_get('m_info', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&mode=post_details&f=' . $forum_id . '&p=' . $row['post_id'], true, $user->session_id) : '',
|
'U_MCP_DETAILS' => ($auth->acl_get('m_info', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=main&mode=post_details&f=' . $forum_id . '&p=' . $row['post_id'], true, $user->session_id) : '',
|
||||||
'POSTER_QUOTE' => ($show_quote_button && $auth->acl_get('f_reply', $forum_id)) ? addslashes(get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username'])) : '',
|
'POSTER_QUOTE' => ($show_quote_button && $auth->acl_get('f_reply', $forum_id)) ? addslashes(get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username'])) : '',
|
||||||
|
|
|
@ -2100,6 +2100,8 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode
|
||||||
'S_IN_POST_MODE' => $in_post_mode,
|
'S_IN_POST_MODE' => $in_post_mode,
|
||||||
|
|
||||||
'MSG_ID' => $row['msg_id'],
|
'MSG_ID' => $row['msg_id'],
|
||||||
|
'MESSAGE_TIME' => $row['message_time'],
|
||||||
|
'USER_ID' => $row['user_id'],
|
||||||
'U_VIEW_MESSAGE' => "$url&f=$folder_id&p=" . $row['msg_id'],
|
'U_VIEW_MESSAGE' => "$url&f=$folder_id&p=" . $row['msg_id'],
|
||||||
'U_QUOTE' => (!$in_post_mode && $auth->acl_get('u_sendpm') && $author_id != ANONYMOUS) ? "$url&mode=compose&action=quote&f=" . $folder_id . "&p=" . $row['msg_id'] : '',
|
'U_QUOTE' => (!$in_post_mode && $auth->acl_get('u_sendpm') && $author_id != ANONYMOUS) ? "$url&mode=compose&action=quote&f=" . $folder_id . "&p=" . $row['msg_id'] : '',
|
||||||
'U_POST_REPLY_PM' => ($author_id != $user->data['user_id'] && $author_id != ANONYMOUS && $auth->acl_get('u_sendpm')) ? "$url&mode=compose&action=reply&f=$folder_id&p=" . $row['msg_id'] : '')
|
'U_POST_REPLY_PM' => ($author_id != $user->data['user_id'] && $author_id != ANONYMOUS && $auth->acl_get('u_sendpm')) ? "$url&mode=compose&action=reply&f=$folder_id&p=" . $row['msg_id'] : '')
|
||||||
|
|
|
@ -941,9 +941,18 @@ function compose_pm($id, $mode, $action, $user_folders = array())
|
||||||
{
|
{
|
||||||
$message_link = '';
|
$message_link = '';
|
||||||
}
|
}
|
||||||
|
$quote_attributes = array(
|
||||||
|
'author' => $quote_username,
|
||||||
|
'time' => $post['message_time'],
|
||||||
|
'user_id' => $post['author_id'],
|
||||||
|
);
|
||||||
|
if ($action === 'quotepost')
|
||||||
|
{
|
||||||
|
$quote_attributes['post_id'] = $post['msg_id'];
|
||||||
|
}
|
||||||
$quote_text = $phpbb_container->get('text_formatter.utils')->generate_quote(
|
$quote_text = $phpbb_container->get('text_formatter.utils')->generate_quote(
|
||||||
censor_text($message_parser->message),
|
censor_text($message_parser->message),
|
||||||
array('author' => $quote_username)
|
$quote_attributes
|
||||||
);
|
);
|
||||||
$message_parser->message = $message_link . $quote_text . "\n\n";
|
$message_parser->message = $message_link . $quote_text . "\n\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,12 @@ class factory implements \phpbb\textformatter\cache_interface
|
||||||
'quote' =>
|
'quote' =>
|
||||||
"[QUOTE
|
"[QUOTE
|
||||||
author={TEXT1;optional}
|
author={TEXT1;optional}
|
||||||
|
post_id={UINT;optional}
|
||||||
|
post_url={URL;optional;postFilter=#false}
|
||||||
|
profile_url={URL;optional;postFilter=#false}
|
||||||
|
time={UINT;optional}
|
||||||
url={URL;optional}
|
url={URL;optional}
|
||||||
|
user_id={UINT;optional}
|
||||||
author={PARSE=/^\\[url=(?'url'.*?)](?'author'.*)\\[\\/url]$/i}
|
author={PARSE=/^\\[url=(?'url'.*?)](?'author'.*)\\[\\/url]$/i}
|
||||||
author={PARSE=/^\\[url](?'author'(?'url'.*?))\\[\\/url]$/i}
|
author={PARSE=/^\\[url](?'author'(?'url'.*?))\\[\\/url]$/i}
|
||||||
author={PARSE=/(?'url'https?:\\/\\/[^[\\]]+)/i}
|
author={PARSE=/(?'url'https?:\\/\\/[^[\\]]+)/i}
|
||||||
|
@ -471,24 +476,11 @@ class factory implements \phpbb\textformatter\cache_interface
|
||||||
|
|
||||||
$templates['li'] = $fragments['listitem'] . '<xsl:apply-templates/>' . $fragments['listitem_close'];
|
$templates['li'] = $fragments['listitem'] . '<xsl:apply-templates/>' . $fragments['listitem_close'];
|
||||||
|
|
||||||
$fragments['quote_username_open'] = str_replace(
|
// Replace the regular quote template with the extended quote template if available
|
||||||
'{USERNAME}',
|
if (isset($fragments['quote_extended']))
|
||||||
'<xsl:choose>
|
{
|
||||||
<xsl:when test="@url">' . str_replace('{DESCRIPTION}', '{USERNAME}', $fragments['url']) . '</xsl:when>
|
$templates['quote'] = $fragments['quote_extended'];
|
||||||
<xsl:otherwise>{USERNAME}</xsl:otherwise>
|
}
|
||||||
</xsl:choose>',
|
|
||||||
$fragments['quote_username_open']
|
|
||||||
);
|
|
||||||
|
|
||||||
$templates['quote'] =
|
|
||||||
'<xsl:choose>
|
|
||||||
<xsl:when test="@author">
|
|
||||||
' . $fragments['quote_username_open'] . '<xsl:apply-templates/>' . $fragments['quote_close'] . '
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
' . $fragments['quote_open'] . '<xsl:apply-templates/>' . $fragments['quote_close'] . '
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>';
|
|
||||||
|
|
||||||
// The [attachment] BBCode uses the inline_attachment template to output a comment that
|
// The [attachment] BBCode uses the inline_attachment template to output a comment that
|
||||||
// is post-processed by parse_attachments()
|
// is post-processed by parse_attachments()
|
||||||
|
|
81
phpBB/phpbb/textformatter/s9e/quote_helper.php
Normal file
81
phpBB/phpbb/textformatter/s9e/quote_helper.php
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This file is part of the phpBB Forum Software package.
|
||||||
|
*
|
||||||
|
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||||
|
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||||
|
*
|
||||||
|
* For full copyright and license information, please see
|
||||||
|
* the docs/CREDITS.txt file.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpbb\textformatter\s9e;
|
||||||
|
|
||||||
|
class quote_helper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string Base URL for a post link, uses {POST_ID} as placeholder
|
||||||
|
*/
|
||||||
|
protected $post_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Base URL for a profile link, uses {USER_ID} as placeholder
|
||||||
|
*/
|
||||||
|
protected $profile_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \phpbb\user
|
||||||
|
*/
|
||||||
|
protected $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param \phpbb\user $user
|
||||||
|
* @param string $root_path
|
||||||
|
* @param string $php_ext
|
||||||
|
*/
|
||||||
|
public function __construct(\phpbb\user $user, $root_path, $php_ext)
|
||||||
|
{
|
||||||
|
$this->post_url = append_sid($root_path . 'viewtopic.' . $php_ext, 'p={POST_ID}#p{POST_ID}');
|
||||||
|
$this->profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=viewprofile&u={USER_ID}');
|
||||||
|
$this->user = $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject dynamic metadata into QUOTE tags in given XML
|
||||||
|
*
|
||||||
|
* @param string $xml Original XML
|
||||||
|
* @return string Modified XML
|
||||||
|
*/
|
||||||
|
public function inject_metadata($xml)
|
||||||
|
{
|
||||||
|
$post_url = $this->post_url;
|
||||||
|
$profile_url = $this->profile_url;
|
||||||
|
$user = $this->user;
|
||||||
|
|
||||||
|
return \s9e\TextFormatter\Utils::replaceAttributes(
|
||||||
|
$xml,
|
||||||
|
'QUOTE',
|
||||||
|
function ($attributes) use ($post_url, $profile_url, $user)
|
||||||
|
{
|
||||||
|
if (isset($attributes['post_id']))
|
||||||
|
{
|
||||||
|
$attributes['post_url'] = str_replace('{POST_ID}', $attributes['post_id'], $post_url);
|
||||||
|
}
|
||||||
|
if (isset($attributes['time']))
|
||||||
|
{
|
||||||
|
$attributes['date'] = $user->format_date($attributes['time']);
|
||||||
|
}
|
||||||
|
if (isset($attributes['user_id']))
|
||||||
|
{
|
||||||
|
$attributes['profile_url'] = str_replace('{USER_ID}', $attributes['user_id'], $profile_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $attributes;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,11 @@ class renderer implements \phpbb\textformatter\renderer_interface
|
||||||
*/
|
*/
|
||||||
protected $dispatcher;
|
protected $dispatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var quote_helper
|
||||||
|
*/
|
||||||
|
protected $quote_helper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \s9e\TextFormatter\Renderer
|
* @var \s9e\TextFormatter\Renderer
|
||||||
*/
|
*/
|
||||||
|
@ -112,6 +117,16 @@ class renderer implements \phpbb\textformatter\renderer_interface
|
||||||
extract($dispatcher->trigger_event('core.text_formatter_s9e_renderer_setup', compact($vars)));
|
extract($dispatcher->trigger_event('core.text_formatter_s9e_renderer_setup', compact($vars)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the quote_helper object used to display extended information in quotes
|
||||||
|
*
|
||||||
|
* @param quote_helper $quote_helper
|
||||||
|
*/
|
||||||
|
public function configure_quote_helper(quote_helper $quote_helper)
|
||||||
|
{
|
||||||
|
$this->quote_helper = $quote_helper;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically set the smilies path based on config
|
* Automatically set the smilies path based on config
|
||||||
*
|
*
|
||||||
|
@ -214,6 +229,10 @@ class renderer implements \phpbb\textformatter\renderer_interface
|
||||||
*/
|
*/
|
||||||
public function render($xml)
|
public function render($xml)
|
||||||
{
|
{
|
||||||
|
if (isset($this->quote_helper))
|
||||||
|
{
|
||||||
|
$xml = $this->quote_helper->inject_metadata($xml);
|
||||||
|
}
|
||||||
$renderer = $this;
|
$renderer = $this;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -35,16 +35,22 @@ class utils implements \phpbb\textformatter\utils_interface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return given string between quotes
|
* Format given string to be used as an attribute value
|
||||||
*
|
*
|
||||||
* Will use either single- or double- quotes depending on whichever requires less escaping.
|
* Will return the string as-is if it can be used in a BBCode without quotes. Otherwise,
|
||||||
|
* it will use either single- or double- quotes depending on whichever requires less escaping.
|
||||||
* Quotes and backslashes are escaped with backslashes where necessary
|
* Quotes and backslashes are escaped with backslashes where necessary
|
||||||
*
|
*
|
||||||
* @param string $str Original string
|
* @param string $str Original string
|
||||||
* @return string Escaped string within quotes
|
* @return string Same string if possible, escaped string within quotes otherwise
|
||||||
*/
|
*/
|
||||||
protected function enquote($str)
|
protected function format_attribute_value($str)
|
||||||
{
|
{
|
||||||
|
if (!preg_match('/[ "\'\\\\\\]]/', $str))
|
||||||
|
{
|
||||||
|
// Return as-is if it contains none of: space, ' " \ or ]
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
$singleQuoted = "'" . addcslashes($str, "\\'") . "'";
|
$singleQuoted = "'" . addcslashes($str, "\\'") . "'";
|
||||||
$doubleQuoted = '"' . addcslashes($str, '\\"') . '"';
|
$doubleQuoted = '"' . addcslashes($str, '\\"') . '"';
|
||||||
|
|
||||||
|
@ -61,12 +67,13 @@ class utils implements \phpbb\textformatter\utils_interface
|
||||||
if (isset($attributes['author']))
|
if (isset($attributes['author']))
|
||||||
{
|
{
|
||||||
// Add the author as the BBCode's default attribute
|
// Add the author as the BBCode's default attribute
|
||||||
$quote .= '=' . $this->enquote($attributes['author']);
|
$quote .= '=' . $this->format_attribute_value($attributes['author']);
|
||||||
unset($attributes['author']);
|
unset($attributes['author']);
|
||||||
}
|
}
|
||||||
|
ksort($attributes);
|
||||||
foreach ($attributes as $name => $value)
|
foreach ($attributes as $name => $value)
|
||||||
{
|
{
|
||||||
$quote .= ' ' . $name . '=' . $this->enquote($value);
|
$quote .= ' ' . $name . '=' . $this->format_attribute_value($value);
|
||||||
}
|
}
|
||||||
$quote .= ']';
|
$quote .= ']';
|
||||||
$newline = (strlen($quote . $text . '[/quote]') > 80 || strpos($text, "\n") !== false) ? "\n" : '';
|
$newline = (strlen($quote . $text . '[/quote]') > 80 || strpos($text, "\n") !== false) ? "\n" : '';
|
||||||
|
|
|
@ -32,7 +32,10 @@ interface utils_interface
|
||||||
* Create a quote block for given text
|
* Create a quote block for given text
|
||||||
*
|
*
|
||||||
* Possible attributes:
|
* Possible attributes:
|
||||||
* - author
|
* - author: author's name (usually a username)
|
||||||
|
* - post_id: post_id of the post being quoted
|
||||||
|
* - user_id: user_id of the user being quoted
|
||||||
|
* - time: timestamp of the original message
|
||||||
*
|
*
|
||||||
* @param string $text Quote's text
|
* @param string $text Quote's text
|
||||||
* @param array $attributes Quote's attributes
|
* @param array $attributes Quote's attributes
|
||||||
|
|
|
@ -1603,7 +1603,12 @@ if ($generate_quote)
|
||||||
{
|
{
|
||||||
$message_parser->message = $phpbb_container->get('text_formatter.utils')->generate_quote(
|
$message_parser->message = $phpbb_container->get('text_formatter.utils')->generate_quote(
|
||||||
censor_text($message_parser->message),
|
censor_text($message_parser->message),
|
||||||
array('author' => $post_data['quote_username'])
|
array(
|
||||||
|
'author' => $post_data['quote_username'],
|
||||||
|
'post_id' => $post_data['post_id'],
|
||||||
|
'time' => $post_data['post_time'],
|
||||||
|
'user_id' => $post_data['poster_id'],
|
||||||
|
)
|
||||||
);
|
);
|
||||||
$message_parser->message .= "\n\n";
|
$message_parser->message .= "\n\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,41 @@
|
||||||
<!-- BEGIN quote_username_open --><blockquote><div><cite>{USERNAME} {L_WROTE}{L_COLON}</cite><!-- END quote_username_open -->
|
<!-- BEGIN quote_username_open --><blockquote><div><cite>{USERNAME} {L_WROTE}{L_COLON}</cite><!-- END quote_username_open -->
|
||||||
<!-- BEGIN quote_open --><blockquote class="uncited"><div><!-- END quote_open -->
|
<!-- BEGIN quote_open --><blockquote class="uncited"><div><!-- END quote_open -->
|
||||||
<!-- BEGIN quote_close --></div></blockquote><!-- END quote_close -->
|
<!-- BEGIN quote_close --></div></blockquote><!-- END quote_close -->
|
||||||
|
<!-- BEGIN quote_extended -->
|
||||||
|
<blockquote>
|
||||||
|
<xsl:if test="not(@author)">
|
||||||
|
<xsl:attribute name="class">uncited</xsl:attribute>
|
||||||
|
</xsl:if>
|
||||||
|
<div>
|
||||||
|
<xsl:if test="@author">
|
||||||
|
<cite>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="@url">
|
||||||
|
<a href="{@url}" class="postlink"><xsl:value-of select="@author"/></a>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="@profile_url">
|
||||||
|
<a href="{@profile_url}"><xsl:value-of select="@author"/></a>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="@author"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of select="$L_WROTE"/>
|
||||||
|
<xsl:value-of select="$L_COLON"/>
|
||||||
|
<xsl:if test="@post_url">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<a href="{@post_url}" data-post-id="{@post_id}" onclick="if(document.getElementById(hash.substr(1)))href=hash">↑</a>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="@date">
|
||||||
|
<div class="responsive-hide"><xsl:value-of select="@date"/></div>
|
||||||
|
</xsl:if>
|
||||||
|
</cite>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
</div>
|
||||||
|
</blockquote>
|
||||||
|
<!-- END quote_extended -->
|
||||||
|
|
||||||
<!-- BEGIN code_open --><div class="codebox"><p>{L_CODE}{L_COLON} <a href="#" onclick="selectCode(this); return false;">{L_SELECT_ALL_CODE}</a></p><pre><code><!-- END code_open -->
|
<!-- BEGIN code_open --><div class="codebox"><p>{L_CODE}{L_COLON} <a href="#" onclick="selectCode(this); return false;">{L_SELECT_ALL_CODE}</a></p><pre><code><!-- END code_open -->
|
||||||
<!-- BEGIN code_close --></code></pre></div><!-- END code_close -->
|
<!-- BEGIN code_close --></code></pre></div><!-- END code_close -->
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
<!-- ENDIF -->
|
<!-- ENDIF -->
|
||||||
<!-- IF topic_review_row.POSTER_QUOTE and topic_review_row.DECODED_MESSAGE -->
|
<!-- IF topic_review_row.POSTER_QUOTE and topic_review_row.DECODED_MESSAGE -->
|
||||||
<li>
|
<li>
|
||||||
<a href="#postingbox" onclick="addquote({topic_review_row.POST_ID}, '{topic_review_row.POSTER_QUOTE}', '{LA_WROTE}');" title="{L_QUOTE} {topic_review_row.POST_AUTHOR}" class="button icon-button quote-icon">
|
<a href="#postingbox" onclick="addquote({topic_review_row.POST_ID}, '{topic_review_row.POSTER_QUOTE}', '{LA_WROTE}', {post_id:{topic_review_row.POST_ID},time:{topic_review_row.POST_TIME},user_id:{topic_review_row.USER_ID}});" title="{L_QUOTE} {topic_review_row.POST_AUTHOR}" class="button icon-button quote-icon">
|
||||||
<span>{L_QUOTE} {topic_review_row.POST_AUTHOR}</span>
|
<span>{L_QUOTE} {topic_review_row.POST_AUTHOR}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<!-- IF history_row.U_QUOTE or history_row.MESSAGE_AUTHOR_QUOTE -->
|
<!-- IF history_row.U_QUOTE or history_row.MESSAGE_AUTHOR_QUOTE -->
|
||||||
<ul class="post-buttons">
|
<ul class="post-buttons">
|
||||||
<li>
|
<li>
|
||||||
<a <!-- IF history_row.U_QUOTE -->href="{history_row.U_QUOTE}"<!-- ELSE -->href="#postingbox" onclick="addquote({history_row.MSG_ID}, '{history_row.MESSAGE_AUTHOR_QUOTE}', '{LA_WROTE}');"<!-- ENDIF --> title="{L_QUOTE} {history_row.MESSAGE_AUTHOR}" class="button icon-button quote-icon">
|
<a <!-- IF history_row.U_QUOTE -->href="{history_row.U_QUOTE}"<!-- ELSE -->href="#postingbox" onclick="addquote({history_row.MSG_ID}, '{history_row.MESSAGE_AUTHOR_QUOTE}', '{LA_WROTE}', {time:{history_row.MESSAGE_TIME},user_id:{history_row.USER_ID}});"<!-- ENDIF --> title="{L_QUOTE} {history_row.MESSAGE_AUTHOR}" class="button icon-button quote-icon">
|
||||||
<span>{L_QUOTE} {history_row.MESSAGE_AUTHOR}</span>
|
<span>{L_QUOTE} {history_row.MESSAGE_AUTHOR}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -486,6 +486,11 @@ blockquote.uncited {
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blockquote cite > div {
|
||||||
|
float: right;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
/* Code block */
|
/* Code block */
|
||||||
.codebox {
|
.codebox {
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
|
|
|
@ -75,7 +75,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
|
||||||
public function test_quote()
|
public function test_quote()
|
||||||
{
|
{
|
||||||
$text = 'Test post </textarea>"\' &&amp;';
|
$text = 'Test post </textarea>"\' &&amp;';
|
||||||
$expected = '[quote="admin"]' . $text . '[/quote]';
|
$expected = "(\\[quote=admin[^\\]]*\\]\n" . preg_quote($text) . "\n\\[/quote\\])";
|
||||||
|
|
||||||
$this->login();
|
$this->login();
|
||||||
$topic = $this->create_topic(2, 'Test Topic 1', 'Test topic');
|
$topic = $this->create_topic(2, 'Test Topic 1', 'Test topic');
|
||||||
|
@ -83,7 +83,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
|
||||||
|
|
||||||
$crawler = self::request('GET', "posting.php?mode=quote&f=2&t={$post['topic_id']}&p={$post['post_id']}&sid={$this->sid}");
|
$crawler = self::request('GET', "posting.php?mode=quote&f=2&t={$post['topic_id']}&p={$post['post_id']}&sid={$this->sid}");
|
||||||
|
|
||||||
$this->assertContains($expected, $crawler->filter('textarea#message')->text());
|
$this->assertRegexp($expected, $crawler->filter('textarea#message')->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,10 +93,10 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
|
||||||
{
|
{
|
||||||
$text = '0[quote]1[quote]2[/quote]1[/quote]0';
|
$text = '0[quote]1[quote]2[/quote]1[/quote]0';
|
||||||
$expected = array(
|
$expected = array(
|
||||||
0 => '[quote="admin"]0[quote]1[quote]2[/quote]1[/quote]0[/quote]',
|
0 => '0[quote]1[quote]2[/quote]1[/quote]0',
|
||||||
1 => '[quote="admin"]00[/quote]',
|
1 => '00',
|
||||||
2 => '[quote="admin"]0[quote]11[/quote]0[/quote]',
|
2 => '0[quote]11[/quote]0',
|
||||||
3 => '[quote="admin"]0[quote]1[quote]2[/quote]1[/quote]0[/quote]',
|
3 => '0[quote]1[quote]2[/quote]1[/quote]0',
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->login();
|
$this->login();
|
||||||
|
@ -109,7 +109,10 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
|
||||||
{
|
{
|
||||||
$this->set_quote_depth($quote_depth);
|
$this->set_quote_depth($quote_depth);
|
||||||
$crawler = self::request('GET', $quote_url);
|
$crawler = self::request('GET', $quote_url);
|
||||||
$this->assertContains($expected_text, $crawler->filter('textarea#message')->text());
|
$this->assertRegexp(
|
||||||
|
"(\\[quote=admin[^\\]]*\\]\n?" . preg_quote($expected_text) . "\n?\\[/quote\\])",
|
||||||
|
$crawler->filter('textarea#message')->text()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,22 +69,36 @@ class phpbb_functional_private_messages_test extends phpbb_functional_test_case
|
||||||
|
|
||||||
public function test_quote_post()
|
public function test_quote_post()
|
||||||
{
|
{
|
||||||
$text = 'Test post';
|
$text = 'Test post';
|
||||||
$expected = '[quote="admin"]' . $text . '[/quote]';
|
|
||||||
|
|
||||||
$this->login();
|
$this->login();
|
||||||
$topic = $this->create_topic(2, 'Test Topic 1', 'Test topic');
|
$topic = $this->create_topic(2, 'Test Topic 1', 'Test topic');
|
||||||
$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', $text);
|
||||||
|
|
||||||
|
$expected = '(\\[quote=admin post_id=' . $post['post_id'] . ' time=\\d+ user_id=2\\]' . $text . '\\[/quote\\])';
|
||||||
|
|
||||||
$crawler = self::request('GET', 'ucp.php?i=pm&mode=compose&action=quotepost&p=' . $post['post_id'] . '&sid=' . $this->sid);
|
$crawler = self::request('GET', 'ucp.php?i=pm&mode=compose&action=quotepost&p=' . $post['post_id'] . '&sid=' . $this->sid);
|
||||||
|
|
||||||
$this->assertContains($expected, $crawler->filter('textarea#message')->text());
|
$this->assertRegexp($expected, $crawler->filter('textarea#message')->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_quote_pm()
|
||||||
|
{
|
||||||
|
$text = 'This is a test private message sent by the testing framework.';
|
||||||
|
$expected = "(\\[quote=admin time=\\d+ user_id=2\\]\n" . $text . "\n\\[/quote\\])";
|
||||||
|
|
||||||
|
$this->login();
|
||||||
|
$message_id = $this->create_private_message('Test', $text, array(2));
|
||||||
|
|
||||||
|
$crawler = self::request('GET', 'ucp.php?i=pm&mode=compose&action=quote&p=' . $message_id . '&sid=' . $this->sid);
|
||||||
|
|
||||||
|
$this->assertRegexp($expected, $crawler->filter('textarea#message')->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_quote_forward()
|
public function test_quote_forward()
|
||||||
{
|
{
|
||||||
$text = 'This is a test private message sent by the testing framework.';
|
$text = 'This is a test private message sent by the testing framework.';
|
||||||
$expected = "[quote=\"admin\"]\n" . $text . "\n[/quote]";
|
$expected = "[quote=admin]\n" . $text . "\n[/quote]";
|
||||||
|
|
||||||
$this->login();
|
$this->login();
|
||||||
$message_id = $this->create_private_message('Test', $text, array(2));
|
$message_id = $this->create_private_message('Test', $text, array(2));
|
||||||
|
|
|
@ -476,11 +476,21 @@ class phpbb_test_case_helpers
|
||||||
{
|
{
|
||||||
$lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx);
|
$lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx);
|
||||||
$lang = new \phpbb\language\language($lang_loader);
|
$lang = new \phpbb\language\language($lang_loader);
|
||||||
$user = new \phpbb\user($lang, '\phpbb\datetime');
|
|
||||||
|
$user = $this->test_case->getMockBuilder('\phpbb\user')
|
||||||
|
->setConstructorArgs(array($lang, '\phpbb\datetime'))
|
||||||
|
->setMethods(array('format_date'))
|
||||||
|
->getMock();
|
||||||
|
$user->expects($this->test_case->any())
|
||||||
|
->method('format_date')
|
||||||
|
->will($this->test_case->returnCallback(__CLASS__ . '::format_date'));
|
||||||
|
|
||||||
|
$user->date_format = 'Y-m-d H:i:s';
|
||||||
$user->optionset('viewcensors', true);
|
$user->optionset('viewcensors', true);
|
||||||
$user->optionset('viewflash', true);
|
$user->optionset('viewflash', true);
|
||||||
$user->optionset('viewimg', true);
|
$user->optionset('viewimg', true);
|
||||||
$user->optionset('viewsmilies', true);
|
$user->optionset('viewsmilies', true);
|
||||||
|
$user->timezone = new \DateTimeZone('UTC');
|
||||||
$container->set('user', $user);
|
$container->set('user', $user);
|
||||||
}
|
}
|
||||||
$user->add_lang('common');
|
$user->add_lang('common');
|
||||||
|
@ -490,6 +500,14 @@ class phpbb_test_case_helpers
|
||||||
$user->style = array('style_id' => 1);
|
$user->style = array('style_id' => 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create and register a quote_helper
|
||||||
|
$quote_helper = new \phpbb\textformatter\s9e\quote_helper(
|
||||||
|
$container->get('user'),
|
||||||
|
$phpbb_root_path,
|
||||||
|
$phpEx
|
||||||
|
);
|
||||||
|
$container->set('text_formatter.s9e.quote_helper', $quote_helper);
|
||||||
|
|
||||||
// Create and register the text_formatter.s9e.parser service and its alias
|
// Create and register the text_formatter.s9e.parser service and its alias
|
||||||
$parser = new \phpbb\textformatter\s9e\parser(
|
$parser = new \phpbb\textformatter\s9e\parser(
|
||||||
$cache,
|
$cache,
|
||||||
|
@ -515,6 +533,7 @@ class phpbb_test_case_helpers
|
||||||
$auth = ($container->has('auth')) ? $container->get('auth') : new \phpbb\auth\auth;
|
$auth = ($container->has('auth')) ? $container->get('auth') : new \phpbb\auth\auth;
|
||||||
|
|
||||||
// Calls configured in services.yml
|
// Calls configured in services.yml
|
||||||
|
$renderer->configure_quote_helper($quote_helper);
|
||||||
$renderer->configure_smilies_path($config, $container->get('path_helper'));
|
$renderer->configure_smilies_path($config, $container->get('path_helper'));
|
||||||
$renderer->configure_user($user, $config, $auth);
|
$renderer->configure_user($user, $config, $auth);
|
||||||
|
|
||||||
|
@ -528,4 +547,15 @@ class phpbb_test_case_helpers
|
||||||
|
|
||||||
return $container;
|
return $container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mocked replacement for \phpbb\user::format_date()
|
||||||
|
*
|
||||||
|
* @param integer $gmepoch unix timestamp
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static public function format_date($gmepoch)
|
||||||
|
{
|
||||||
|
return gmdate('Y-m-d H:i:s', $gmepoch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,13 +229,40 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case
|
||||||
'<blockquote><div><cite><a href="http://example.org" class="postlink">http://example.org</a> wrote:</cite>...</div></blockquote>'
|
'<blockquote><div><cite><a href="http://example.org" class="postlink">http://example.org</a> wrote:</cite>...</div></blockquote>'
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'[quote="http://example.org"]...[/quote]',
|
'[quote=http://example.org]...[/quote]',
|
||||||
'<blockquote><div><cite><a href="http://example.org" class="postlink">http://example.org</a> wrote:</cite>...</div></blockquote>'
|
'<blockquote><div><cite><a href="http://example.org" class="postlink">http://example.org</a> wrote:</cite>...</div></blockquote>'
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
"[quote]\nThis is a long quote that is definitely going to exceed 80 characters\n[/quote]\n\nFollowed by a reply",
|
"[quote]\nThis is a long quote that is definitely going to exceed 80 characters\n[/quote]\n\nFollowed by a reply",
|
||||||
"<blockquote class=\"uncited\"><div>\nThis is a long quote that is definitely going to exceed 80 characters\n</div></blockquote>\n\nFollowed by a reply"
|
"<blockquote class=\"uncited\"><div>\nThis is a long quote that is definitely going to exceed 80 characters\n</div></blockquote>\n\nFollowed by a reply"
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'[quote=Username post_id=123]...[/quote]',
|
||||||
|
'<blockquote><div><cite>Username wrote: <a href="phpBB/viewtopic.php?p=123#p123" data-post-id="123" onclick="if(document.getElementById(hash.substr(1)))href=hash">↑</a></cite>...</div></blockquote>'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
// Users are not allowed to submit their own URL for the post
|
||||||
|
'[quote="Username" post_url="http://fake.example.org"]...[/quote]',
|
||||||
|
'<blockquote><div><cite>Username wrote:</cite>...</div></blockquote>'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'[quote=Username time=58705871]...[/quote]',
|
||||||
|
'<blockquote><div><cite>Username wrote:<div class="responsive-hide">1971-11-11 11:11:11</div></cite>...</div></blockquote>'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'[quote=Username user_id=123]...[/quote]',
|
||||||
|
'<blockquote><div><cite><a href="phpBB/memberlist.php?mode=viewprofile&u=123">Username</a> wrote:</cite>...</div></blockquote>'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
// Users are not allowed to submit their own URL for the profile
|
||||||
|
'[quote=Username profile_url=http://fake.example.org]...[/quote]',
|
||||||
|
'<blockquote><div><cite>Username wrote:</cite>...</div></blockquote>'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
// From phpbb_textformatter_s9e_utils_test::test_generate_quote()
|
||||||
|
'[quote=\'[quote="foo"]\']...[/quote]',
|
||||||
|
'<blockquote><div><cite>[quote="foo"] wrote:</cite>...</div></blockquote>'
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,11 +98,15 @@ class phpbb_textformatter_s9e_utils_test extends phpbb_test_case
|
||||||
array('foo')
|
array('foo')
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'[quote="foo"]..[/quote] [quote="bar"]..[/quote]',
|
'[quote=foo]..[/quote] [quote]..[/quote]',
|
||||||
|
array('foo')
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'[quote=foo]..[/quote] [quote=bar]..[/quote]',
|
||||||
array('foo', 'bar')
|
array('foo', 'bar')
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'[quote="foo"].[quote="baz"]..[/quote].[/quote] [quote="bar"]..[/quote]',
|
'[quote=foo].[quote=baz]..[/quote].[/quote] [quote=bar]..[/quote]',
|
||||||
array('foo', 'bar')
|
array('foo', 'bar')
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -169,7 +173,37 @@ class phpbb_textformatter_s9e_utils_test extends phpbb_test_case
|
||||||
'post_id' => 123,
|
'post_id' => 123,
|
||||||
'url' => 'http://example.org'
|
'url' => 'http://example.org'
|
||||||
),
|
),
|
||||||
'[quote="user" post_id="123" url="http://example.org"]...[/quote]',
|
'[quote=user post_id=123 url=http://example.org]...[/quote]',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'...',
|
||||||
|
array('author' => ' '),
|
||||||
|
'[quote=" "]...[/quote]',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'...',
|
||||||
|
array('author' => 'foo bar'),
|
||||||
|
'[quote="foo bar"]...[/quote]',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'...',
|
||||||
|
array('author' => '\\'),
|
||||||
|
'[quote="\\\\"]...[/quote]',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'...',
|
||||||
|
array('author' => '[quote="foo"]'),
|
||||||
|
'[quote=\'[quote="foo"]\']...[/quote]',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'...',
|
||||||
|
array('author' => '""'),
|
||||||
|
'[quote=\'""\']...[/quote]',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'...',
|
||||||
|
array('author' => "''"),
|
||||||
|
'[quote="\'\'"]...[/quote]',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'This is a long quote that is definitely going to exceed 80 characters',
|
'This is a long quote that is definitely going to exceed 80 characters',
|
||||||
|
|
Loading…
Add table
Reference in a new issue