From c66f4806e8912fb6a3fa0eed917f7db15cb455ca Mon Sep 17 00:00:00 2001 From: lavigor Date: Wed, 4 Jul 2018 00:47:38 +0300 Subject: [PATCH] [ticket/13713] Rework BBCode parameters PHPBB3-13713 --- phpBB/assets/javascript/editor.js | 2 +- phpBB/phpbb/mention/source/base_group.php | 2 +- phpBB/phpbb/mention/source/base_user.php | 2 +- phpBB/phpbb/notification/type/mention.php | 2 +- phpBB/phpbb/textformatter/s9e/factory.php | 4 +- .../textformatter/s9e/mention_helper.php | 140 +++++++++--------- 6 files changed, 77 insertions(+), 75 deletions(-) diff --git a/phpBB/assets/javascript/editor.js b/phpBB/assets/javascript/editor.js index 66f9fb3444..3514c09ed5 100644 --- a/phpBB/assets/javascript/editor.js +++ b/phpBB/assets/javascript/editor.js @@ -406,7 +406,7 @@ function getCaretPosition(txtarea) { rank = (data.rank) ? "" + data.rank + "" : ''; return "
  • " + avatar + "" + data.name + rank + "
  • "; }, - insertTpl: "[mention ${param}=${id}]${name}[/mention]", + insertTpl: "[mention=${type}:${id}]${name}[/mention]", limit: mentionNamesLimit, callbacks: { remoteFilter: function(query, callback) { diff --git a/phpBB/phpbb/mention/source/base_group.php b/phpBB/phpbb/mention/source/base_group.php index 592c6e0da2..da1acc6689 100644 --- a/phpBB/phpbb/mention/source/base_group.php +++ b/phpBB/phpbb/mention/source/base_group.php @@ -133,7 +133,7 @@ abstract class base_group implements source_interface $group_rank = phpbb_get_user_rank($groups[$group_id], false); $names['g' . $group_id] = [ 'name' => $groups[$group_id]['group_name'], - 'param' => 'group_id', + 'type' => 'g', 'id' => $group_id, 'avatar' => [ 'type' => 'group', diff --git a/phpBB/phpbb/mention/source/base_user.php b/phpBB/phpbb/mention/source/base_user.php index a78f995a75..bc1bcc0053 100644 --- a/phpBB/phpbb/mention/source/base_user.php +++ b/phpBB/phpbb/mention/source/base_user.php @@ -70,7 +70,7 @@ abstract class base_user implements source_interface $user_rank = $this->user_loader->get_rank($row['user_id'], true); $names['u' . $row['user_id']] = [ 'name' => $row['username'], - 'param' => 'user_id', + 'type' => 'u', 'id' => $row['user_id'], 'avatar' => [ 'type' => 'user', diff --git a/phpBB/phpbb/notification/type/mention.php b/phpBB/phpbb/notification/type/mention.php index 1161814dbe..21d4bf6f91 100644 --- a/phpBB/phpbb/notification/type/mention.php +++ b/phpBB/phpbb/notification/type/mention.php @@ -75,7 +75,7 @@ class mention extends \phpbb\notification\type\post 'ignore_users' => array(), ), $options); - $user_ids = $this->helper->get_mentioned_users($post['post_text']); + $user_ids = $this->helper->get_mentioned_ids($post['post_text']); $user_ids = array_unique($user_ids); diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 16bd63cf73..66c6b5132e 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -85,10 +85,8 @@ class factory implements \phpbb\textformatter\cache_interface 'list' => '[LIST type={HASHMAP=1:decimal,a:lower-alpha,A:upper-alpha,i:lower-roman,I:upper-roman;optional;postFilter=#simpletext} #createChild=LI]{TEXT}[/LIST]', 'li' => '[* $tagName=LI]{TEXT}[/*]', 'mention' => - "[MENTION - group_id={UINT;optional} + "[MENTION={PARSE=/^(?[ug]):(?\d+)$/} profile_url={URL;optional;postFilter=#false} - user_id={UINT;optional} ]{TEXT}[/MENTION]", 'quote' => "[QUOTE diff --git a/phpBB/phpbb/textformatter/s9e/mention_helper.php b/phpBB/phpbb/textformatter/s9e/mention_helper.php index fded9c5cd4..9e0cd65437 100644 --- a/phpBB/phpbb/textformatter/s9e/mention_helper.php +++ b/phpBB/phpbb/textformatter/s9e/mention_helper.php @@ -23,17 +23,17 @@ class mention_helper protected $db; /** - * @var string Base URL for a user profile link, uses {USER_ID} as placeholder + * @var string Base URL for a user profile link, uses {ID} as placeholder */ protected $user_profile_url; /** - * @var string Base URL for a group profile link, uses {GROUP_ID} as placeholder + * @var string Base URL for a group profile link, uses {ID} as placeholder */ protected $group_profile_url; /** - * @var array Array of users' and groups' colors for each cached ID + * @var array Array of users' and groups' colours for each cached ID */ protected $cached_colours = []; @@ -47,57 +47,61 @@ class mention_helper public function __construct($db, $root_path, $php_ext) { $this->db = $db; - $this->user_profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=viewprofile&u={USER_ID}', false); - $this->group_profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=group&g={GROUP_ID}', false); + $this->user_profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=viewprofile&u={ID}', false); + $this->group_profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=group&g={ID}', false); } /** - * Caches colors for specified user IDs and group IDs + * Returns SQL query data for colour SELECT request * - * @param array $user_ids - * @param array $group_ids + * @param string $type Name type ('u' for users, 'g' for groups) + * @param array $ids Array of IDs + * @return array Array of SQL SELECT query data for extracting colours for names */ - protected function get_colors($user_ids, $group_ids) + protected function get_colours_sql($type, $ids) { - $this->cached_colours = []; - $this->cached_colours['users'] = []; - $this->cached_colours['groups'] = []; - - if (!empty($user_ids)) + switch ($type) { - $query = $this->db->sql_build_query('SELECT', [ - 'SELECT' => 'u.user_colour, u.user_id', - 'FROM' => [ - USERS_TABLE => 'u', - ], - 'WHERE' => 'u.user_id <> ' . ANONYMOUS . ' - AND ' . $this->db->sql_in_set('u.user_type', [USER_NORMAL, USER_FOUNDER]) . ' - AND ' . $this->db->sql_in_set('u.user_id', $user_ids), - ]); - $result = $this->db->sql_query($query); - - while ($row = $this->db->sql_fetchrow($result)) - { - $this->cached_colours['users'][$row['user_id']] = $row['user_colour']; - } - - $this->db->sql_freeresult($result); + default: + case 'u': + return [ + 'SELECT' => 'u.user_colour as colour, u.user_id as id', + 'FROM' => [ + USERS_TABLE => 'u', + ], + 'WHERE' => 'u.user_id <> ' . ANONYMOUS . ' + AND ' . $this->db->sql_in_set('u.user_type', [USER_NORMAL, USER_FOUNDER]) . ' + AND ' . $this->db->sql_in_set('u.user_id', $ids), + ]; + case 'g': + return [ + 'SELECT' => 'g.group_colour as colour, g.group_id as id', + 'FROM' => [ + GROUPS_TABLE => 'g', + ], + 'WHERE' => $this->db->sql_in_set('g.group_id', $ids), + ]; } + } - if (!empty($group_ids)) + /** + * Caches colours for selected IDs of the specified type + * + * @param string $type Name type ('u' for users, 'g' for groups) + * @param array $ids Array of IDs + */ + protected function get_colours($type, $ids) + { + $this->cached_colours[$type] = []; + + if (!empty($ids)) { - $query = $this->db->sql_build_query('SELECT', [ - 'SELECT' => 'g.group_colour, g.group_id', - 'FROM' => [ - GROUPS_TABLE => 'g', - ], - 'WHERE' => $this->db->sql_in_set('g.group_id', $group_ids), - ]); + $query = $this->db->sql_build_query('SELECT', $this->get_colours_sql($type, $ids)); $result = $this->db->sql_query($query); while ($row = $this->db->sql_fetchrow($result)) { - $this->cached_colours['groups'][$row['group_id']] = $row['group_colour']; + $this->cached_colours[$type][$row['id']] = $row['colour']; } $this->db->sql_freeresult($result); @@ -112,36 +116,31 @@ class mention_helper */ public function inject_metadata($xml) { - $user_profile_url = $this->user_profile_url; - $group_profile_url = $this->group_profile_url; + $profile_urls = [ + 'u' => $this->user_profile_url, + 'g' => $this->group_profile_url, + ]; // TODO: think about optimization for caching colors. - $this->get_colors( - TextFormatterUtils::getAttributeValues($xml, 'MENTION', 'user_id'), - TextFormatterUtils::getAttributeValues($xml, 'MENTION', 'group_id') - ); + $this->cached_colours = []; + $this->get_colours('u', $this->get_mentioned_ids($xml, 'u')); + $this->get_colours('g', $this->get_mentioned_ids($xml, 'g')); return TextFormatterUtils::replaceAttributes( $xml, 'MENTION', - function ($attributes) use ($user_profile_url, $group_profile_url) + function ($attributes) use ($profile_urls) { - if (isset($attributes['user_id'])) + if (isset($attributes['type']) && isset($attributes['id'])) { - $attributes['profile_url'] = str_replace('{USER_ID}', $attributes['user_id'], $user_profile_url); + $type = $attributes['type']; + $id = $attributes['id']; - if (!empty($this->cached_colours['users'][$attributes['user_id']])) - { - $attributes['color'] = $this->cached_colours['users'][$attributes['user_id']]; - } - } - else if (isset($attributes['group_id'])) - { - $attributes['profile_url'] = str_replace('{GROUP_ID}', $attributes['group_id'], $group_profile_url); + $attributes['profile_url'] = str_replace('{ID}', $id, $profile_urls[$type]); - if (!empty($this->cached_colours['groups'][$attributes['group_id']])) + if (!empty($this->cached_colours[$type][$id])) { - $attributes['color'] = $this->cached_colours['groups'][$attributes['group_id']]; + $attributes['color'] = $this->cached_colours[$type][$id]; } } @@ -151,28 +150,33 @@ class mention_helper } /** - * Get a list of mentioned users + * Get a list of mentioned names * TODO: decide what to do with groups * - * @param string $xml Parsed text - * @return int[] List of user IDs + * @param string $xml Parsed text + * @param string $type Name type ('u' for users, 'g' for groups) + * @return int[] List of IDs */ - public function get_mentioned_users($xml) + public function get_mentioned_ids($xml, $type = 'u') { - $user_ids = array(); + $ids = array(); if (strpos($xml, 'loadXML($xml); $xpath = new \DOMXPath($dom); - foreach ($xpath->query('//MENTION/@user_id') as $user_id) + /** @var \DOMElement $mention */ + foreach ($xpath->query('//MENTION') as $mention) { - $user_ids[] = (int) $user_id->textContent; + if ($mention->getAttribute('type') === $type) + { + $ids[] = (int) $mention->getAttribute('id'); + } } - return $user_ids; + return $ids; } }