Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.20% covered (success)
90.20%
46 / 51
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
base_user
90.20% covered (success)
90.20%
46 / 51
66.67% covered (warning)
66.67%
2 / 3
17.27
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 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
88.37% covered (warning)
88.37%
38 / 43
0.00% covered (danger)
0.00%
0 / 1
14.31
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\config\config;
17use phpbb\db\driver\driver_interface;
18use phpbb\user_loader;
19
20abstract class base_user implements source_interface
21{
22    /** @var driver_interface */
23    protected $db;
24
25    /** @var config */
26    protected $config;
27
28    /** @var user_loader */
29    protected $user_loader;
30
31    /** @var string */
32    protected $phpbb_root_path;
33
34    /** @var string */
35    protected $php_ext;
36
37    /** @var int */
38    protected $cache_ttl = 0;
39
40    /**
41     * base_user constructor.
42     *
43     * @param driver_interface $db
44     * @param config $config
45     * @param user_loader $user_loader
46     * @param string $phpbb_root_path
47     * @param string $phpEx
48     */
49    public function __construct(driver_interface $db, config $config, user_loader $user_loader, string $phpbb_root_path, string $phpEx)
50    {
51        $this->db = $db;
52        $this->config = $config;
53        $this->user_loader = $user_loader;
54        $this->phpbb_root_path = $phpbb_root_path;
55        $this->php_ext = $phpEx;
56
57        if (!function_exists('phpbb_get_user_rank'))
58        {
59            include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext);
60        }
61    }
62
63    /**
64     * Builds a query based on user input
65     *
66     * @param string $keyword  Search string
67     * @param int    $topic_id Current topic ID
68     * @return string Query ready for execution
69     */
70    abstract protected function query(string $keyword, int $topic_id): string;
71
72    /**
73     * {@inheritdoc}
74     */
75    public function get_priority(array $row): int
76    {
77        // By default every result from the source increases the priority by a fixed value
78        return 1;
79    }
80
81    /**
82     * {@inheritdoc}
83     */
84    public function get(array &$names, string $keyword, int $topic_id): bool
85    {
86        $fetched_all = false;
87        $keyword = utf8_clean_string($keyword);
88
89        $i = 0;
90        $users = [];
91        $user_ids = [];
92
93        // Grab all necessary user IDs and cache them if needed
94        if ($this->cache_ttl)
95        {
96            $result = $this->db->sql_query($this->query($keyword, $topic_id), $this->cache_ttl);
97
98            while ($i < $this->config['mention_batch_size'])
99            {
100                $row = $this->db->sql_fetchrow($result);
101
102                if (!$row)
103                {
104                    $fetched_all = true;
105                    break;
106                }
107
108                if (!empty($keyword) && strpos($row['username_clean'], $keyword) !== 0)
109                {
110                    continue;
111                }
112
113                $i++;
114                $users[] = $row;
115                $user_ids[] = $row['user_id'];
116            }
117
118            // Determine whether all usernames were fetched in current batch
119            if (!$fetched_all)
120            {
121                $fetched_all = true;
122
123                while ($row = $this->db->sql_fetchrow($result))
124                {
125                    if (!empty($keyword) && strpos($row['username_clean'], $keyword) !== 0)
126                    {
127                        continue;
128                    }
129
130                    // At least one username hasn't been fetched - exit loop
131                    $fetched_all = false;
132                    break;
133                }
134            }
135        }
136        else
137        {
138            $result = $this->db->sql_query_limit($this->query($keyword, $topic_id), $this->config['mention_batch_size'], 0);
139
140            while ($row = $this->db->sql_fetchrow($result))
141            {
142                $users[] = $row;
143                $user_ids[] = $row['user_id'];
144            }
145
146            // Determine whether all usernames were fetched in current batch
147            if (count($user_ids) < $this->config['mention_batch_size'])
148            {
149                $fetched_all = true;
150            }
151        }
152
153        $this->db->sql_freeresult($result);
154
155        // Load all user data with a single SQL query, needed for ranks and avatars
156        $this->user_loader->load_users($user_ids);
157
158        foreach ($users as $user)
159        {
160            $user_rank = $this->user_loader->get_rank($user['user_id']);
161            array_push($names, [
162                'name'        => $this->user_loader->get_username($user['user_id'], 'username'),
163                'type'        => 'u',
164                'id'        => $user['user_id'],
165                'avatar'    => $this->user_loader->get_avatar($user['user_id']),
166                'rank'        => (isset($user_rank['rank_title'])) ? $user_rank['rank_title'] : '',
167                'priority'    => $this->get_priority($user),
168            ]);
169        }
170
171        return $fetched_all;
172    }
173}