aboutsummaryrefslogtreecommitdiff
blob: cdd28329db03a30642ab51f878e3a6f8c8d59e30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/

namespace phpbb;

/**
* User loader class
*
* This handles loading users from the database and
* storing in them in a temporary cache so we do not
* have to query the same user multiple times in
* different services.
*/
class user_loader
{
	/** @var \phpbb\db\driver\driver_interface */
	protected $db = null;

	/** @var string */
	protected $phpbb_root_path = null;

	/** @var string */
	protected $php_ext = null;

	/** @var string */
	protected $users_table = null;

	/**
	* Users loaded from the DB
	*
	* @var array Array of user data that we've loaded from the DB
	*/
	protected $users = array();

	/**
	* User loader constructor
	*
	* @param \phpbb\db\driver\driver_interface $db A database connection
	* @param string $phpbb_root_path Path to the phpbb includes directory.
	* @param string $php_ext php file extension
	* @param string $users_table The name of the database table (phpbb_users)
	*/
	public function __construct(\phpbb\db\driver\driver_interface $db, $phpbb_root_path, $php_ext, $users_table)
	{
		$this->db = $db;

		$this->phpbb_root_path = $phpbb_root_path;
		$this->php_ext = $php_ext;

		$this->users_table = $users_table;
	}

	/**
	* Load user helper
	*
	* @param array $user_ids
	*/
	public function load_users(array $user_ids)
	{
		$user_ids[] = ANONYMOUS;

		// Make user_ids unique and convert to integer.
		$user_ids = array_map('intval', array_unique($user_ids));

		// Do not load users we already have in $this->users
		$user_ids = array_diff($user_ids, array_keys($this->users));

		if (sizeof($user_ids))
		{
			$sql = 'SELECT *
				FROM ' . $this->users_table . '
				WHERE ' . $this->db->sql_in_set('user_id', $user_ids);
			$result = $this->db->sql_query($sql);

			while ($row = $this->db->sql_fetchrow($result))
			{
				$this->users[$row['user_id']] = $row;
			}
			$this->db->sql_freeresult($result);
		}
	}

	/**
	* Load a user by username
	*
	* Stores the full data in the user cache so they do not need to be loaded again
	* Returns the user id so you may use get_user() from the returned value
	*
	* @param string $username Raw username to load (will be cleaned)
	* @return int User ID for the username
	*/
	public function load_user_by_username($username)
	{
		$sql = 'SELECT *
			FROM ' . $this->users_table . "
			WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($username)) . "'";
		$result = $this->db->sql_query($sql);
		$row = $this->db->sql_fetchrow($result);
		$this->db->sql_freeresult($result);

		if ($row)
		{
			$this->users[$row['user_id']] = $row;

			return $row['user_id'];
		}

		return ANONYMOUS;
	}

	/**
	* Get a user row from our users cache
	*
	* @param int $user_id User ID of the user you want to retreive
	* @param bool $query Should we query the database if this user has not yet been loaded?
	* 						Typically this should be left as false and you should make sure
	* 						you load users ahead of time with load_users()
	* @return array|bool Row from the database of the user or Anonymous if the user wasn't loaded/does not exist
	* 						or bool False if the anonymous user was not loaded
	*/
	public function get_user($user_id, $query = false)
	{
		if (isset($this->users[$user_id]))
		{
			return $this->users[$user_id];
		}
		// Query them if we must (if ANONYMOUS is sent as the user_id and we have not loaded Anonymous yet, we must load Anonymous as a last resort)
		else if ($query || $user_id == ANONYMOUS)
		{
			$this->load_users(array($user_id));

			return $this->get_user($user_id);
		}

		return $this->get_user(ANONYMOUS);
	}

	/**
	* Get username
	*
	* @param int $user_id User ID of the user you want to retreive the username for
	* @param string $mode The mode to load (same as get_username_string). One of the following:
	* 			profile (for getting an url to the profile)
	* 			username (for obtaining the username)
	* 			colour (for obtaining the user colour)
	* 			full (for obtaining a html string representing a coloured link to the users profile)
	* 			no_profile (the same as full but forcing no profile link)
	* @param string $guest_username Optional parameter to specify the guest username. It will be used in favor of the GUEST language variable then.
	* @param string $custom_profile_url Optional parameter to specify a profile url. The user id get appended to this url as &amp;u={user_id}
	* @param bool $query Should we query the database if this user has not yet been loaded?
	* 						Typically this should be left as false and you should make sure
	* 						you load users ahead of time with load_users()
	* @return string
	*/
	public function get_username($user_id, $mode, $guest_username = false, $custom_profile_url = false, $query = false)
	{
		if (!($user = $this->get_user($user_id, $query)))
		{
			return '';
		}

		return get_username_string($mode, $user['user_id'], $user['username'], $user['user_colour'], $guest_username, $custom_profile_url);
	}

	/**
	* Get avatar
	*
	* @param int $user_id User ID of the user you want to retrieve the avatar for
	* @param bool $query Should we query the database if this user has not yet been loaded?
	* 						Typically this should be left as false and you should make sure
	* 						you load users ahead of time with load_users()
	* @param bool @lazy If true, will be lazy loaded (requires JS)
	* @return string
	*/
	public function get_avatar($user_id, $query = false, $lazy = false)
	{
		if (!($user = $this->get_user($user_id, $query)))
		{
			return '';
		}

		$row = array(
			'avatar'		=> $user['user_avatar'],
			'avatar_type'	=> $user['user_avatar_type'],
			'avatar_width'	=> $user['user_avatar_width'],
			'avatar_height'	=> $user['user_avatar_height'],
		);

		return phpbb_get_avatar($row, 'USER_AVATAR', false, $lazy);
	}

	/**
	* Get rank
	*
	* @param int $user_id User ID of the user you want to retreive the rank for
	* @param bool $query Should we query the database if this user has not yet been loaded?
	* 						Typically this should be left as false and you should make sure
	* 						you load users ahead of time with load_users()
	* @return array Array with keys 'rank_title', 'rank_img', and 'rank_img_src'
	*/
	public function get_rank($user_id, $query = false)
	{
		if (!($user = $this->get_user($user_id, $query)))
		{
			return '';
		}

		if (!function_exists('phpbb_get_user_rank'))
		{
			include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext);
		}

		$rank = array(
			'rank_title',
			'rank_img',
			'rank_img_src',
		);

		$user_rank_data = phpbb_get_user_rank($user, (($user['user_id'] == ANONYMOUS) ? false : $user['user_posts']));
		$rank['rank_title'] = $user_rank_data['title'];
		$rank['rank_img'] = $user_rank_data['img'];
		$rank['rank_img_src'] = $user_rank_data['img_src'];

		return $rank;
	}
}