Code: Select all
static public function getSubscribedEvents()
{
return array(
...
'core.text_formatter_s9e_configure_after' => 'configure_quotes'
);
}
...
public function configure_quotes($event)
{
// Add self::filter_quote() to filter the QUOTE tag that handles quotes
$event['configurator']->tags['QUOTE']->filterChain
->append(array(__CLASS__, 'filter_quote'));
}
static public function filter_quote(\s9e\TextFormatter\Parser\Tag $tag)
{
$tag->setAttribute('comment_url', 'anything');
return true;
}
configure_quotes()
Code: Select all
$attribute = $event['configurator']->tags['QUOTE']->attributes->add('comment_url');
$attribute->filterChain->append('#url');
Code: Select all
Fatal error: Uncaught exception 's9e\TextFormatter\Configurator\Exceptions\UnsafeTemplateException' with message 'Cannot assess the safety of unknown attribute 'comment_url'' in /apps/forums/phpBB/vendor/s9e/text-formatter/src/Configurator.php:6417 Stack trace: #0 /apps/forums/phpBB/vendor/s9e/text-formatter/src/Configurator.php(6462): s9e\TextFormatter\Configurator\TemplateChecks\AbstractDynamicContentCheck->checkAttribute(Object(DOMAttr), Object(s9e\TextFormatter\Configurator\Items\Tag), 'comment_url') #1 /apps/forums/phpBB/vendor/s9e/text-formatter/src/Configurator.php(6426): s9e\TextFormatter\Configurator\TemplateChecks\AbstractDynamicContentCheck->checkExpression(Object(DOMAttr), '@comment_url', Object(s9e\TextFormatter\Configurator\Items\Tag)) #2 /apps/forums/phpBB/vendor/s9e/text-formatter/src/Configurator.php(8287): s9e\TextFormatter\Configurator\TemplateChecks\AbstractDynamicContentCheck->checkAttributeNode(Object(DOMAttr), Object(s9e\TextFormatter\Configurator\Items\Tag)) #3 /apps/forums/phpBB/vendor/s9e/text-fo in /apps/forums/phpBB/vendor/s9e/text-formatter/src/Configurator.php on line 6417
Code: Select all
<?php
namespace site\comments\event;
/**
* @ignore
*/
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Comments Event listener.
*/
class main_listener implements EventSubscriberInterface
{
static public function getSubscribedEvents()
{
return array(
'core.viewtopic_assign_template_vars_before' => 'viewtopic_vars',
'core.viewtopic_modify_post_row' => 'viewtopic_post_vars',
'core.pagination_generate_page_link' => 'viewtopic_pagination',
'core.posting_modify_template_vars' => 'posting_vars',
'core.functions.redirect' => 'handle_redirects',
'core.text_formatter_s9e_configure_after' => 'configure_quotes'
);
}
/* @var \phpbb\controller\helper */
protected $helper;
/* @var \phpbb\template\template */
protected $template;
/* @var \phpbb\user */
protected $user;
/* @var \phpbb\cache\service */
protected $cache;
/* @var \phpbb\config\config */
protected $config;
/* @var \phpbb\request\request */
protected $request;
/** @var string phpEx */
protected $php_ext;
/**
* Constructor
*
* @param \phpbb\controller\helper $helper Controller helper object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
* @param \phpbb\cache\driver\driver_interface $cache Cache object
* @param \phpbb\config\config $config Config object
* @param \phpbb\request\request $request Request object
* @param string $php_ext phpEx
*/
public function __construct(\phpbb\controller\helper $helper, \phpbb\template\template $template, \phpbb\user $user, \phpbb\cache\service $cache, \phpbb\config\config $config, \phpbb\request\request $request, $php_ext)
{
$this->helper = $helper;
$this->template = $template;
$this->user = $user;
$this->cache = $cache;
$this->config = $config;
$this->request = $request;
$this->php_ext = $php_ext;
}
public function set_rank($row)
{
//
return $row;
}
/**
* Set topic-wide template variables for use
*
* @param \phpbb\event\data $event Event object
*/
public function viewtopic_vars($event)
{
// Available event vars: base_url, forum_id, post_id, quickmod_array, start, topic_data, topic_id, topic_tracking_info, total_posts, viewtopic_url
// Assign a proper start var
$this->template->assign_var('PAGE_START', $event['start']);
// Make template var for all user groups
$user_groups = group_memberships(false, $this->user->data['user_id']);
$staff_groups = array('GOD', 'News Writers', 'Editors');
foreach ($user_groups as $user_group) {
$group_name = get_group_name($user_group['group_id']);
$this->template->assign_var('S_GROUP_' . strtoupper(str_replace(' ', '_', $group_name)), true);
if (in_array($group_name, $staff_groups)) {
$this->template->assign_var('S_IS_STAFF', true);
}
}
}
/**
* Set topic-row template variables for use
*
* @param \phpbb\event\data $event Event object
*/
public function viewtopic_post_vars($event)
{
// Add custom title (and related img fields) if necessary
$row = $this->set_rank($event['post_row']);
// Add time w/zone offset
$row['POST_TIME'] = $event['row']['post_time'];
$row['POST_DATE_ISO8601'] = date('c', $event['row']['post_time']);
// Store user Premier status in cache
$row['IS_PREMIER'] = false;
$groups = $this->cache->get('post_row_groups_' . $row['POSTER_ID']);
if ($groups === false) {
$groups = group_memberships(false, $row['POSTER_ID']);
$this->cache->put('post_row_groups_' . $row['POSTER_ID'], $groups, 1000);
}
foreach ($groups as $group) {
if ($group['group_id'] == 10) {
$row['IS_PREMIER'] = true;
}
}
$event['post_row'] = $row;
}
function viewtopic_pagination($event)
{
$base_url = $event['base_url'];
$base_url = preg_replace("/.\/viewtopic.php\?style=11(.*)/", "?comments=1&style=11$1", $base_url);
$event['base_url'] = $base_url;
}
function posting_vars($event)
{
// Add URL of the article page if applicable
$vars = array();
$vars['CURRENT_URL_NONAPI'] = $this->request->server('REQUEST_URI');
$vars['CURRENT_URL_NONAPI_ENCODED'] = urlencode($this->request->server('REQUEST_URI'));
// For ESI requests from the front page
if($this->request->is_set('return_to')) {
$vars['CURRENT_URL'] = $this->request->variable('return_to', '');
$vars['CURRENT_URL_ENCODED'] = urlencode($this->request->variable('return_to', ''));
$vars['CURRENT_URL_BARE'] = parse_url($this->request->variable('return_to', ''), PHP_URL_HOST) . parse_url($this->request->variable('return_to', ''), PHP_URL_PATH);
$vars['CURRENT_MOBILE_URL'] = str_replace('http://', '', request_var('return_to', ''));
$vars['IS_JS'] = ($this->request->variable('js', false) ? true : false);
}
$vars['U_FORUM'] = generate_board_url() . '/';
if($this->request->is_set('view')) {
$vars['VIEW'] = $this->request->variable('view', '');
}
$action_string = "Leave your comment";
if($this->request->is_set('mode')) {
$vars['MODE'] = $this->request->variable('mode', '');
switch($this->request->variable('mode', '')) {
case 'reply':
break;
case 'quote':
$action_string = "Leave your reply";
break;
case 'edit':
$action_string = "Edit your comment";
break;
}
}
$vars['ACTION_STRING'] = $action_string;
$this->template->assign_vars($vars);
}
public function handle_redirects($event)
{
$url = $event['url'];
if($this->request->is_set('articleurl')) {
preg_match('#p=([0-9]+)#', $url, $p);
$url = "https://" . $this->request->variable('articleurl', '');
// For mobile stuff
if(strpos($this->request->variable('articleurl'), '#!') !== False) {
$url .= '&p=' . $p[1] . '&comment-' . $p[1];
}
else {
$url .= '?comments=1&post=' . $p[1] . '#comment-' . $p[1];
}
}
$event['url'] = $url;
}
public function configure_quotes($event)
{
$tag = $event['configurator']->tags['QUOTE'];
$attribute = $tag->attributes->add('comment_url');
$attribute->filterChain->append('#url');
$tag->filterChain
->append(array(__CLASS__, 'filter_quote'));
print_r($tag);
}
static public function filter_quote(\s9e\TextFormatter\Parser\Tag $tag)
{
$tag->setAttribute('comment_url', 'https://google.com/');
return true;
}
}
soviet9k wrote: ↑Thu Oct 26, 2017 1:21 pm However, placing it in the bbcode.html template still throws this error:
[/code]
At the time the[quote]
BBCode is created, thecomment_url
attribute doesn't exist, therefore the configurator treats it as unsafe if it's used in a sensitive context. Right now, the simplest workaround would be to change the template in the same event that creates the attribute. You can access the template as a string via$event['configurator']->tags['quote']->template
or as a DOMDocument like this. If you inspect the template you'll see that if different styles have different templates, they are implemented as axsl:choose
structure, so if you modify elements through DOM you should assume there could be more than one element that you want to modify.
There's no list of "safe" attributes, it depends on how they're filtered; URLs and numbers are safe to be used as a URL but most text isn't because it could be used with thejavascript:
pseudo-scheme to execute JavaScript. Unknown and unfiltered attributes are treated as unsafe. Those warnings are actually disabled on custom BBCodes because there's no interface in phpBB to check a BBCode's safety at the time it's created.
Code: Select all
public function text_formatter_s9e_render_before($event)
{
// Available vars: renderer, xml
if ($this->api != '1') {
return;
}
$event['renderer']->get_renderer()->setParameter('COMMENT_URL', $this->current_url_bare);
}
Code: Select all
<xsl:when test="@post_id">
<a href="https://{$COMMENT_URL}?comments=1&post={@post_id}#comment-{@post_id}" class="postlink">
<xsl:attribute name="target">_self</xsl:attribute>
<xsl:value-of select="@author"/>
</a>
</xsl:when>
Parsed at posting time, rendered dynamically. You can look at the post content in the db to get an idea of what information is stored.
I don't know what that means. Can you provide a concrete example of input/output?
I don't remember anything in the default style that used a target attribute. Check out this page if you're trying to modify a template: http://s9etextformatter.readthedocs.io/ ... _template/
An extension modifies the HTML?soviet9k wrote: ↑Sat Nov 04, 2017 4:35 pm When I inspect $event['html'] in core.text_formatter_s9e_render_after, it indeed includes the target="_self". Yay! However, that's not what appears in the final rendered text. I'm obviously missing some big piece of the puzzle here. If anyone has recommendations, please share.