1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-07-30 21:40:43 +02:00

Merge pull request #3623 from s9e/ticket/10620

[ticket/10620] Quote improvements
This commit is contained in:
Tristan Darricau
2015-07-07 09:46:36 +02:00
20 changed files with 381 additions and 49 deletions

View File

@@ -77,7 +77,12 @@ class factory implements \phpbb\textformatter\cache_interface
'quote' =>
"[QUOTE
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}
user_id={UINT;optional}
author={PARSE=/^\\[url=(?'url'.*?)](?'author'.*)\\[\\/url]$/i}
author={PARSE=/^\\[url](?'author'(?'url'.*?))\\[\\/url]$/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'];
$fragments['quote_username_open'] = str_replace(
'{USERNAME}',
'<xsl:choose>
<xsl:when test="@url">' . str_replace('{DESCRIPTION}', '{USERNAME}', $fragments['url']) . '</xsl:when>
<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>';
// Replace the regular quote template with the extended quote template if available
if (isset($fragments['quote_extended']))
{
$templates['quote'] = $fragments['quote_extended'];
}
// The [attachment] BBCode uses the inline_attachment template to output a comment that
// is post-processed by parse_attachments()

View 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;
}
);
}
}

View File

@@ -28,6 +28,11 @@ class renderer implements \phpbb\textformatter\renderer_interface
*/
protected $dispatcher;
/**
* @var quote_helper
*/
protected $quote_helper;
/**
* @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)));
}
/**
* 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
*
@@ -214,6 +229,10 @@ class renderer implements \phpbb\textformatter\renderer_interface
*/
public function render($xml)
{
if (isset($this->quote_helper))
{
$xml = $this->quote_helper->inject_metadata($xml);
}
$renderer = $this;
/**

View File

@@ -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
*
* @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, "\\'") . "'";
$doubleQuoted = '"' . addcslashes($str, '\\"') . '"';
@@ -61,12 +67,13 @@ class utils implements \phpbb\textformatter\utils_interface
if (isset($attributes['author']))
{
// Add the author as the BBCode's default attribute
$quote .= '=' . $this->enquote($attributes['author']);
$quote .= '=' . $this->format_attribute_value($attributes['author']);
unset($attributes['author']);
}
ksort($attributes);
foreach ($attributes as $name => $value)
{
$quote .= ' ' . $name . '=' . $this->enquote($value);
$quote .= ' ' . $name . '=' . $this->format_attribute_value($value);
}
$quote .= ']';
$newline = (strlen($quote . $text . '[/quote]') > 80 || strpos($text, "\n") !== false) ? "\n" : '';