Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
96.49% |
55 / 57 |
|
50.00% |
2 / 4 |
CRAP | |
0.00% |
0 / 1 |
| base_group | |
96.49% |
55 / 57 |
|
50.00% |
2 / 4 |
16 | |
0.00% |
0 / 1 |
| __construct | |
88.89% |
8 / 9 |
|
0.00% |
0 / 1 |
2.01 | |||
| get_groups | |
100.00% |
24 / 24 |
|
100.00% |
1 / 1 |
8 | |||
| query | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
| get_priority | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| get | |
95.65% |
22 / 23 |
|
0.00% |
0 / 1 |
5 | |||
| 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\mention\source; |
| 15 | |
| 16 | use phpbb\auth\auth; |
| 17 | use phpbb\config\config; |
| 18 | use phpbb\db\driver\driver_interface; |
| 19 | use phpbb\group\helper; |
| 20 | |
| 21 | abstract class base_group implements source_interface |
| 22 | { |
| 23 | /** @var driver_interface */ |
| 24 | protected $db; |
| 25 | |
| 26 | /** @var config */ |
| 27 | protected $config; |
| 28 | |
| 29 | /** @var helper */ |
| 30 | protected $helper; |
| 31 | |
| 32 | /** @var \phpbb\user */ |
| 33 | protected $user; |
| 34 | |
| 35 | /** @var auth */ |
| 36 | protected $auth; |
| 37 | |
| 38 | /** @var string */ |
| 39 | protected $phpbb_root_path; |
| 40 | |
| 41 | /** @var string */ |
| 42 | protected $php_ext; |
| 43 | |
| 44 | /** @var int */ |
| 45 | protected $cache_ttl = 0; |
| 46 | |
| 47 | /** @var array Fetched groups' data */ |
| 48 | protected $groups = null; |
| 49 | |
| 50 | /** |
| 51 | * base_group constructor. |
| 52 | * |
| 53 | * @param driver_interface $db |
| 54 | * @param config $config |
| 55 | * @param helper $helper |
| 56 | * @param \phpbb\user $user |
| 57 | * @param auth $auth |
| 58 | * @param string $phpbb_root_path |
| 59 | * @param string $phpEx |
| 60 | */ |
| 61 | public function __construct(driver_interface $db, config $config, helper $helper, \phpbb\user $user, auth $auth, string $phpbb_root_path, string $phpEx) |
| 62 | { |
| 63 | $this->db = $db; |
| 64 | $this->config = $config; |
| 65 | $this->helper = $helper; |
| 66 | $this->user = $user; |
| 67 | $this->auth = $auth; |
| 68 | $this->phpbb_root_path = $phpbb_root_path; |
| 69 | $this->php_ext = $phpEx; |
| 70 | |
| 71 | if (!function_exists('phpbb_get_user_rank')) |
| 72 | { |
| 73 | include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext); |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | /** |
| 78 | * Returns data for all board groups |
| 79 | * |
| 80 | * @return array Array of groups' data |
| 81 | */ |
| 82 | protected function get_groups(): array |
| 83 | { |
| 84 | if (is_null($this->groups)) |
| 85 | { |
| 86 | $query = $this->db->sql_build_query('SELECT', [ |
| 87 | 'SELECT' => 'g.*, ug.user_id as ug_user_id', |
| 88 | 'FROM' => [ |
| 89 | GROUPS_TABLE => 'g', |
| 90 | ], |
| 91 | 'LEFT_JOIN' => [ |
| 92 | [ |
| 93 | 'FROM' => [USER_GROUP_TABLE => 'ug'], |
| 94 | 'ON' => 'ug.group_id = g.group_id AND ug.user_pending = 0 AND ug.user_id = ' . (int) $this->user->data['user_id'], |
| 95 | ], |
| 96 | ], |
| 97 | ]); |
| 98 | // Cache results for 5 minutes |
| 99 | $result = $this->db->sql_query($query, 600); |
| 100 | |
| 101 | $this->groups = []; |
| 102 | while ($row = $this->db->sql_fetchrow($result)) |
| 103 | { |
| 104 | if ($row['group_type'] == GROUP_SPECIAL && !in_array($row['group_name'], ['ADMINISTRATORS', 'GLOBAL_MODERATORS']) || $row['group_type'] == GROUP_HIDDEN && !$this->auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel') && $row['ug_user_id'] != $this->user->data['user_id']) |
| 105 | { |
| 106 | // Skip the group that we should not be able to mention. |
| 107 | continue; |
| 108 | } |
| 109 | |
| 110 | $group_name = $this->helper->get_name($row['group_name']); |
| 111 | $this->groups['names'][$row['group_id']] = $group_name; |
| 112 | $this->groups[$row['group_id']] = $row; |
| 113 | $this->groups[$row['group_id']]['group_name'] = $group_name; |
| 114 | } |
| 115 | |
| 116 | $this->db->sql_freeresult($result); |
| 117 | } |
| 118 | return $this->groups; |
| 119 | } |
| 120 | |
| 121 | /** |
| 122 | * Builds a query for getting group IDs based on user input |
| 123 | * |
| 124 | * @param string $keyword Search string |
| 125 | * @param int $topic_id Current topic ID |
| 126 | * @return string Query ready for execution |
| 127 | */ |
| 128 | abstract protected function query(string $keyword, int $topic_id): string; |
| 129 | |
| 130 | /** |
| 131 | * {@inheritdoc} |
| 132 | */ |
| 133 | public function get_priority(array $row): int |
| 134 | { |
| 135 | // By default every result from the source increases the priority by a fixed value |
| 136 | return 1; |
| 137 | } |
| 138 | |
| 139 | /** |
| 140 | * {@inheritdoc} |
| 141 | */ |
| 142 | public function get(array &$names, string $keyword, int $topic_id): bool |
| 143 | { |
| 144 | // Grab all group IDs and cache them if needed |
| 145 | $result = $this->db->sql_query($this->query($keyword, $topic_id), $this->cache_ttl); |
| 146 | |
| 147 | $group_ids = []; |
| 148 | while ($row = $this->db->sql_fetchrow($result)) |
| 149 | { |
| 150 | $group_ids[] = $row['group_id']; |
| 151 | } |
| 152 | |
| 153 | $this->db->sql_freeresult($result); |
| 154 | |
| 155 | // Grab group data |
| 156 | $groups = $this->get_groups(); |
| 157 | |
| 158 | $matches = preg_grep('/^' . preg_quote($keyword) . '.*/i', $groups['names']); |
| 159 | $group_ids = array_intersect($group_ids, array_flip($matches)); |
| 160 | |
| 161 | $i = 0; |
| 162 | foreach ($group_ids as $group_id) |
| 163 | { |
| 164 | if ($i >= $this->config['mention_batch_size']) |
| 165 | { |
| 166 | // Do not exceed the names limit |
| 167 | return false; |
| 168 | } |
| 169 | |
| 170 | $group_rank = phpbb_get_user_rank($groups[$group_id], false); |
| 171 | array_push($names, [ |
| 172 | 'name' => $groups[$group_id]['group_name'], |
| 173 | 'type' => 'g', |
| 174 | 'id' => $group_id, |
| 175 | 'avatar' => $this->helper->get_avatar($groups[$group_id]), |
| 176 | 'rank' => (isset($group_rank['title'])) ? $group_rank['title'] : '', |
| 177 | 'priority' => $this->get_priority($groups[$group_id]), |
| 178 | ]); |
| 179 | |
| 180 | $i++; |
| 181 | } |
| 182 | |
| 183 | return true; |
| 184 | } |
| 185 | } |