Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
76 / 76 |
|
100.00% |
14 / 14 |
CRAP | |
100.00% |
1 / 1 |
manager | |
100.00% |
76 / 76 |
|
100.00% |
14 / 14 |
37 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
register_avatar_drivers | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
get_driver | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
6 | |||
load_enabled_drivers | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 | |||
get_all_drivers | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
get_enabled_drivers | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
clean_row | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
5 | |||
clean_driver_name | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
prepare_driver_name | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
is_enabled | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
get_avatar_settings | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
localize_errors | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
handle_avatar_delete | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
3 | |||
prefix_avatar_columns | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 |
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\avatar; |
15 | |
16 | class manager |
17 | { |
18 | /** |
19 | * phpBB configuration |
20 | * @var \phpbb\config\config |
21 | */ |
22 | protected $config; |
23 | |
24 | /** |
25 | * phpBB event dispatcher |
26 | * @var \phpbb\event\dispatcher_interface |
27 | */ |
28 | protected $phpbb_dispatcher; |
29 | |
30 | /** |
31 | * Array that contains a list of enabled drivers |
32 | * @var array|false |
33 | */ |
34 | protected static $enabled_drivers = false; |
35 | |
36 | /** |
37 | * Array that contains all available avatar drivers which are passed via the |
38 | * service container |
39 | * @var array |
40 | */ |
41 | protected $avatar_drivers; |
42 | |
43 | /** |
44 | * Default avatar data row |
45 | * @var array |
46 | */ |
47 | protected static $default_row = array( |
48 | 'avatar' => '', |
49 | 'avatar_type' => '', |
50 | 'avatar_width' => 0, |
51 | 'avatar_height' => 0, |
52 | ); |
53 | |
54 | /** |
55 | * Construct an avatar manager object |
56 | * |
57 | * @param \phpbb\config\config $config phpBB configuration |
58 | * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher phpBB event dispatcher |
59 | * @param array $avatar_drivers Avatar drivers passed via the service container |
60 | */ |
61 | public function __construct(\phpbb\config\config $config, \phpbb\event\dispatcher_interface $phpbb_dispatcher, $avatar_drivers) |
62 | { |
63 | $this->config = $config; |
64 | $this->phpbb_dispatcher = $phpbb_dispatcher; |
65 | $this->register_avatar_drivers($avatar_drivers); |
66 | } |
67 | |
68 | /** |
69 | * Register avatar drivers |
70 | * |
71 | * @param array $avatar_drivers Service collection of avatar drivers |
72 | */ |
73 | protected function register_avatar_drivers($avatar_drivers) |
74 | { |
75 | if (!empty($avatar_drivers)) |
76 | { |
77 | foreach ($avatar_drivers as $driver) |
78 | { |
79 | $this->avatar_drivers[$driver->get_name()] = $driver; |
80 | } |
81 | } |
82 | } |
83 | |
84 | /** |
85 | * Get the driver object specified by the avatar type |
86 | * |
87 | * @param string $avatar_type Avatar type; by default an avatar's service container name |
88 | * @param bool $load_enabled Load only enabled avatars |
89 | * |
90 | * @return object|null Avatar driver object |
91 | */ |
92 | public function get_driver($avatar_type, $load_enabled = true) |
93 | { |
94 | if (self::$enabled_drivers === false) |
95 | { |
96 | $this->load_enabled_drivers(); |
97 | } |
98 | |
99 | $avatar_drivers = ($load_enabled) ? self::$enabled_drivers : $this->get_all_drivers(); |
100 | |
101 | // Legacy stuff... |
102 | switch ($avatar_type) |
103 | { |
104 | case AVATAR_GALLERY: |
105 | $avatar_type = 'avatar.driver.local'; |
106 | break; |
107 | |
108 | case AVATAR_UPLOAD: |
109 | $avatar_type = 'avatar.driver.upload'; |
110 | break; |
111 | } |
112 | |
113 | if (!isset($avatar_drivers[$avatar_type])) |
114 | { |
115 | return null; |
116 | } |
117 | |
118 | /* |
119 | * There is no need to handle invalid avatar types as the following code |
120 | * will cause a ServiceNotFoundException if the type does not exist |
121 | */ |
122 | $driver = $this->avatar_drivers[$avatar_type]; |
123 | |
124 | return $driver; |
125 | } |
126 | |
127 | /** |
128 | * Load the list of enabled drivers |
129 | * This is executed once and fills self::$enabled_drivers |
130 | */ |
131 | protected function load_enabled_drivers() |
132 | { |
133 | if (!empty($this->avatar_drivers)) |
134 | { |
135 | self::$enabled_drivers = array(); |
136 | foreach ($this->avatar_drivers as $driver) |
137 | { |
138 | if ($this->is_enabled($driver)) |
139 | { |
140 | self::$enabled_drivers[$driver->get_name()] = $driver->get_name(); |
141 | } |
142 | } |
143 | asort(self::$enabled_drivers); |
144 | } |
145 | } |
146 | |
147 | /** |
148 | * Get a list of all avatar drivers |
149 | * |
150 | * As this function will only be called in the ACP avatar settings page, it |
151 | * doesn't make much sense to cache the list of all avatar drivers like the |
152 | * list of the enabled drivers. |
153 | * |
154 | * @return array Array containing a list of all avatar drivers |
155 | */ |
156 | public function get_all_drivers() |
157 | { |
158 | $drivers = array(); |
159 | |
160 | if (!empty($this->avatar_drivers)) |
161 | { |
162 | foreach ($this->avatar_drivers as $driver) |
163 | { |
164 | $drivers[$driver->get_name()] = $driver->get_name(); |
165 | } |
166 | asort($drivers); |
167 | } |
168 | |
169 | return $drivers; |
170 | } |
171 | |
172 | /** |
173 | * Get a list of enabled avatar drivers |
174 | * |
175 | * @return array Array containing a list of the enabled avatar drivers |
176 | */ |
177 | public function get_enabled_drivers() |
178 | { |
179 | if (self::$enabled_drivers === false) |
180 | { |
181 | $this->load_enabled_drivers(); |
182 | } |
183 | |
184 | return self::$enabled_drivers ?: []; |
185 | } |
186 | |
187 | /** |
188 | * Strip out user_, group_, or other prefixes from array keys |
189 | * |
190 | * @param array $row User data or group data |
191 | * @param string $prefix Prefix of data keys (e.g. user), should not include the trailing underscore |
192 | * |
193 | * @return array User or group data with keys that have been |
194 | * stripped from the preceding "user_" or "group_" |
195 | * Also the group id is prefixed with g, when the prefix group is removed. |
196 | */ |
197 | public static function clean_row($row, $prefix = '') |
198 | { |
199 | // Upon creation of a user/group $row might be empty |
200 | if (empty($row)) |
201 | { |
202 | return self::$default_row; |
203 | } |
204 | |
205 | $output = []; |
206 | foreach ($row as $key => $value) |
207 | { |
208 | $key = preg_replace("#^(?:{$prefix}_)#", '', (string) $key); |
209 | $output[$key] = $value; |
210 | } |
211 | |
212 | if ($prefix === 'group' && isset($output['id'])) |
213 | { |
214 | $output['id'] = 'g' . $output['id']; |
215 | } |
216 | |
217 | return $output; |
218 | } |
219 | |
220 | /** |
221 | * Clean driver names that are returned from template files |
222 | * Underscores are replaced with dots |
223 | * |
224 | * @param string $name Driver name |
225 | * |
226 | * @return string Cleaned driver name |
227 | */ |
228 | public static function clean_driver_name($name) |
229 | { |
230 | return str_replace(array('\\', '_'), '.', $name); |
231 | } |
232 | |
233 | /** |
234 | * Prepare driver names for use in template files |
235 | * Dots are replaced with underscores |
236 | * |
237 | * @param string $name Clean driver name |
238 | * |
239 | * @return string Prepared driver name |
240 | */ |
241 | public static function prepare_driver_name($name) |
242 | { |
243 | return str_replace('.', '_', $name); |
244 | } |
245 | |
246 | /** |
247 | * Check if avatar is enabled |
248 | * |
249 | * @param object $driver Avatar driver object |
250 | * |
251 | * @return bool True if avatar is enabled, false if it's disabled |
252 | */ |
253 | public function is_enabled($driver) |
254 | { |
255 | $config_name = $driver->get_config_name(); |
256 | |
257 | return (bool) $this->config["allow_avatar_{$config_name}"]; |
258 | } |
259 | |
260 | /** |
261 | * Get the settings array for enabling/disabling an avatar driver |
262 | * |
263 | * @param object $driver Avatar driver object |
264 | * |
265 | * @return array Array of configuration options as consumed by acp_board |
266 | */ |
267 | public function get_avatar_settings($driver) |
268 | { |
269 | $config_name = $driver->get_config_name(); |
270 | |
271 | return array( |
272 | 'allow_avatar_' . $config_name => array('lang' => 'ALLOW_' . strtoupper(str_replace('\\', '_', $config_name)), 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), |
273 | ); |
274 | } |
275 | |
276 | /** |
277 | * Replace "error" strings with their real, localized form |
278 | * |
279 | * @param \phpbb\user phpBB User object |
280 | * @param array $error Array containing error strings |
281 | * Key values can either be a string with a language key or an array |
282 | * that will be passed to vsprintf() with the language key in the |
283 | * first array key. |
284 | * |
285 | * @return array Array containing the localized error strings |
286 | */ |
287 | public function localize_errors(\phpbb\user $user, $error) |
288 | { |
289 | foreach ($error as $key => $lang) |
290 | { |
291 | if (is_array($lang)) |
292 | { |
293 | $lang_key = array_shift($lang); |
294 | $error[$key] = vsprintf($user->lang($lang_key), $lang); |
295 | } |
296 | else |
297 | { |
298 | $error[$key] = $user->lang("$lang"); |
299 | } |
300 | } |
301 | |
302 | return $error; |
303 | } |
304 | |
305 | /** |
306 | * Handle deleting avatars |
307 | * |
308 | * @param \phpbb\db\driver\driver_interface $db phpBB dbal |
309 | * @param \phpbb\user $user phpBB user object |
310 | * @param array $avatar_data Cleaned user data containing the user's |
311 | * avatar data |
312 | * @param string $table Database table from which the avatar should be deleted |
313 | * @param string $prefix Prefix of user data columns in database |
314 | * @return void |
315 | */ |
316 | public function handle_avatar_delete(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $avatar_data, $table, $prefix) |
317 | { |
318 | if ($driver = $this->get_driver($avatar_data['avatar_type'])) |
319 | { |
320 | $driver->delete($avatar_data); |
321 | } |
322 | |
323 | $result = $this->prefix_avatar_columns($prefix, self::$default_row); |
324 | |
325 | $sql = 'UPDATE ' . $table . ' |
326 | SET ' . $db->sql_build_array('UPDATE', $result) . ' |
327 | WHERE ' . $prefix . 'id = ' . (int) $avatar_data['id']; |
328 | $db->sql_query($sql); |
329 | |
330 | // Make sure we also delete this avatar from the users |
331 | if ($prefix === 'group_') |
332 | { |
333 | $result = $this->prefix_avatar_columns('user_', self::$default_row); |
334 | |
335 | $sql = 'UPDATE ' . USERS_TABLE . ' |
336 | SET ' . $db->sql_build_array('UPDATE', $result) . " |
337 | WHERE user_avatar = '" . $db->sql_escape($avatar_data['avatar']) . "'"; |
338 | $db->sql_query($sql); |
339 | } |
340 | |
341 | /** |
342 | * Event is triggered after user avatar has been deleted |
343 | * |
344 | * @event core.avatar_manager_avatar_delete_after |
345 | * @var \phpbb\user user phpBB user object |
346 | * @var array avatar_data Normalised avatar-related user data |
347 | * @var string table Table to delete avatar from |
348 | * @var string prefix Column prefix to delete avatar from |
349 | * @since 3.2.4-RC1 |
350 | */ |
351 | $vars = array('user', 'avatar_data', 'table', 'prefix'); |
352 | extract($this->phpbb_dispatcher->trigger_event('core.avatar_manager_avatar_delete_after', compact($vars))); |
353 | } |
354 | |
355 | /** |
356 | * Prefix avatar columns |
357 | * |
358 | * @param string $prefix Column prefix |
359 | * @param array $data Column data |
360 | * |
361 | * @return array Column data with prefixed column names |
362 | */ |
363 | public function prefix_avatar_columns($prefix, $data) |
364 | { |
365 | foreach ($data as $key => $value) |
366 | { |
367 | $data[$prefix . $key] = $value; |
368 | unset($data[$key]); |
369 | } |
370 | |
371 | return $data; |
372 | } |
373 | } |