Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.49% covered (success)
96.49%
55 / 57
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
base_group
96.49% covered (success)
96.49%
55 / 57
50.00% covered (danger)
50.00%
2 / 4
16
0.00% covered (danger)
0.00%
0 / 1
 __construct
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
2.01
 get_groups
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
1 / 1
8
 query
n/a
0 / 0
n/a
0 / 0
0
 get_priority
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
95.65% covered (success)
95.65%
22 / 23
0.00% covered (danger)
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
14namespace phpbb\mention\source;
15
16use phpbb\auth\auth;
17use phpbb\config\config;
18use phpbb\db\driver\driver_interface;
19use phpbb\group\helper;
20
21abstract 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}