Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
67 / 67 |
|
100.00% |
5 / 5 |
CRAP | |
100.00% |
1 / 1 |
mention_helper | |
100.00% |
67 / 67 |
|
100.00% |
5 / 5 |
15 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
inject_metadata | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
3 | |||
get_mentionable_groups | |
100.00% |
22 / 22 |
|
100.00% |
1 / 1 |
4 | |||
get_user_ids_for_group | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
4 | |||
get_mentioned_user_ids | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | /** |
3 | * |
4 | * This file is part of the phpBB Forum Software package. |
5 | * |
6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
7 | * @license GNU General Public License, version 2 (GPL-2.0) |
8 | * |
9 | * For full copyright and license information, please see |
10 | * the docs/CREDITS.txt file. |
11 | * |
12 | */ |
13 | |
14 | namespace phpbb\textformatter\s9e; |
15 | |
16 | use s9e\TextFormatter\Utils as TextFormatterUtils; |
17 | |
18 | class mention_helper |
19 | { |
20 | /** |
21 | * @var \phpbb\db\driver\driver_interface |
22 | */ |
23 | protected $db; |
24 | |
25 | /** |
26 | * @var \phpbb\auth\auth |
27 | */ |
28 | protected $auth; |
29 | |
30 | /** |
31 | * @var \phpbb\user |
32 | */ |
33 | protected $user; |
34 | |
35 | /** |
36 | * @var string Base URL for a user profile link, uses {USER_ID} as placeholder |
37 | */ |
38 | protected $user_profile_url; |
39 | |
40 | /** |
41 | * @var string Base URL for a group profile link, uses {GROUP_ID} as placeholder |
42 | */ |
43 | protected $group_profile_url; |
44 | |
45 | /** |
46 | * @var array Array of group IDs allowed to be mentioned by current user |
47 | */ |
48 | protected $mentionable_groups = null; |
49 | |
50 | /** |
51 | * Constructor |
52 | * |
53 | * @param \phpbb\db\driver\driver_interface $db |
54 | * @param \phpbb\auth\auth $auth |
55 | * @param \phpbb\user $user |
56 | * @param string $root_path |
57 | * @param string $php_ext |
58 | */ |
59 | public function __construct($db, $auth, $user, $root_path, $php_ext) |
60 | { |
61 | $this->db = $db; |
62 | $this->auth = $auth; |
63 | $this->user = $user; |
64 | $this->user_profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=viewprofile&u={USER_ID}', false); |
65 | $this->group_profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=group&g={GROUP_ID}', false); |
66 | } |
67 | |
68 | /** |
69 | * Inject dynamic metadata into MENTION tags in given XML |
70 | * |
71 | * @param string $xml Original XML |
72 | * @return string Modified XML |
73 | */ |
74 | public function inject_metadata($xml) |
75 | { |
76 | $profile_urls = [ |
77 | 'u' => $this->user_profile_url, |
78 | 'g' => $this->group_profile_url, |
79 | ]; |
80 | |
81 | return TextFormatterUtils::replaceAttributes( |
82 | $xml, |
83 | 'MENTION', |
84 | function ($attributes) use ($profile_urls) |
85 | { |
86 | if (isset($attributes['user_id'])) |
87 | { |
88 | $attributes['profile_url'] = str_replace('{USER_ID}', $attributes['user_id'], $profile_urls['u']); |
89 | } |
90 | else if (isset($attributes['group_id'])) |
91 | { |
92 | $attributes['profile_url'] = str_replace('{GROUP_ID}', $attributes['group_id'], $profile_urls['g']); |
93 | } |
94 | |
95 | return $attributes; |
96 | } |
97 | ); |
98 | } |
99 | |
100 | /** |
101 | * Get group IDs allowed to be mentioned by current user |
102 | * |
103 | * @return array |
104 | */ |
105 | protected function get_mentionable_groups() |
106 | { |
107 | if (is_array($this->mentionable_groups)) |
108 | { |
109 | return $this->mentionable_groups; |
110 | } |
111 | |
112 | $hidden_restriction = (!$this->auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) ? ' AND (g.group_type <> ' . GROUP_HIDDEN . ' OR (ug.user_pending = 0 AND ug.user_id = ' . (int) $this->user->data['user_id'] . '))' : ''; |
113 | |
114 | $query = $this->db->sql_build_query('SELECT', [ |
115 | 'SELECT' => 'g.group_id', |
116 | 'FROM' => [ |
117 | GROUPS_TABLE => 'g', |
118 | ], |
119 | 'LEFT_JOIN' => [[ |
120 | 'FROM' => [ |
121 | USER_GROUP_TABLE => 'ug', |
122 | ], |
123 | 'ON' => 'g.group_id = ug.group_id', |
124 | ]], |
125 | 'WHERE' => '(g.group_type <> ' . GROUP_SPECIAL . ' OR ' . $this->db->sql_in_set('g.group_name', ['ADMINISTRATORS', 'GLOBAL_MODERATORS']) . ')' . $hidden_restriction, |
126 | ]); |
127 | $result = $this->db->sql_query($query); |
128 | |
129 | $this->mentionable_groups = []; |
130 | |
131 | while ($row = $this->db->sql_fetchrow($result)) |
132 | { |
133 | $this->mentionable_groups[] = $row['group_id']; |
134 | } |
135 | |
136 | $this->db->sql_freeresult($result); |
137 | |
138 | return $this->mentionable_groups; |
139 | } |
140 | |
141 | /** |
142 | * Selects IDs of user members of a certain group |
143 | * |
144 | * @param array $user_ids Array of already selected user IDs |
145 | * @param int $group_id ID of the group to search members in |
146 | */ |
147 | protected function get_user_ids_for_group(&$user_ids, $group_id) |
148 | { |
149 | if (!in_array($group_id, $this->get_mentionable_groups())) |
150 | { |
151 | return; |
152 | } |
153 | |
154 | $query = $this->db->sql_build_query('SELECT', [ |
155 | 'SELECT' => 'ug.user_id, ug.group_id', |
156 | 'FROM' => [ |
157 | USER_GROUP_TABLE => 'ug', |
158 | GROUPS_TABLE => 'g', |
159 | ], |
160 | 'WHERE' => 'g.group_id = ug.group_id', |
161 | ]); |
162 | // Cache results for 5 minutes |
163 | $result = $this->db->sql_query($query, 300); |
164 | |
165 | while ($row = $this->db->sql_fetchrow($result)) |
166 | { |
167 | if ($row['group_id'] == $group_id) |
168 | { |
169 | $user_ids[] = (int) $row['user_id']; |
170 | } |
171 | } |
172 | |
173 | $this->db->sql_freeresult($result); |
174 | } |
175 | |
176 | /** |
177 | * Get a list of mentioned user IDs |
178 | * |
179 | * @param string $xml Parsed text |
180 | * @return int[] List of user IDs |
181 | */ |
182 | public function get_mentioned_user_ids($xml) |
183 | { |
184 | $ids = array(); |
185 | if (strpos($xml, '<MENTION ') === false) |
186 | { |
187 | return $ids; |
188 | } |
189 | |
190 | // Add IDs of users mentioned directly |
191 | $user_ids = TextFormatterUtils::getAttributeValues($xml, 'MENTION', 'user_id'); |
192 | $ids = array_merge($ids, array_map('intval', $user_ids)); |
193 | |
194 | // Add IDs of users mentioned as group members |
195 | $group_ids = TextFormatterUtils::getAttributeValues($xml, 'MENTION', 'group_id'); |
196 | foreach ($group_ids as $group_id) |
197 | { |
198 | $this->get_user_ids_for_group($ids, (int) $group_id); |
199 | } |
200 | |
201 | return $ids; |
202 | } |
203 | } |