Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
14.58% |
14 / 96 |
|
25.00% |
2 / 8 |
CRAP | |
0.00% |
0 / 1 |
upload | |
14.58% |
14 / 96 |
|
25.00% |
2 / 8 |
269.28 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
get_data | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
prepare_form | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
6 | |||
process_form | |
0.00% |
0 / 53 |
|
0.00% |
0 / 1 |
90 | |||
prepare_form_acp | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
delete | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
20 | |||
get_template_name | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
can_upload | |
0.00% |
0 / 1 |
|
0.00% |
0 / 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\driver; |
15 | |
16 | use bantu\IniGetWrapper\IniGetWrapper; |
17 | use phpbb\config\config; |
18 | use phpbb\event\dispatcher_interface; |
19 | use phpbb\files\factory; |
20 | use phpbb\path_helper; |
21 | use phpbb\routing\helper; |
22 | use phpbb\storage\exception\storage_exception; |
23 | use phpbb\storage\storage; |
24 | |
25 | /** |
26 | * Handles avatars uploaded to the board. |
27 | */ |
28 | class upload extends \phpbb\avatar\driver\driver |
29 | { |
30 | /** |
31 | * @var helper |
32 | */ |
33 | private $routing_helper; |
34 | |
35 | /** |
36 | * @var storage |
37 | */ |
38 | protected $storage; |
39 | |
40 | /** |
41 | * @var dispatcher_interface |
42 | */ |
43 | protected $dispatcher; |
44 | |
45 | /** |
46 | * @var factory |
47 | */ |
48 | protected $files_factory; |
49 | |
50 | /** |
51 | * @var IniGetWrapper |
52 | */ |
53 | protected $php_ini; |
54 | |
55 | /** |
56 | * Construct a driver object |
57 | * |
58 | * @param config $config phpBB configuration |
59 | * @param string $phpbb_root_path Path to the phpBB root |
60 | * @param string $php_ext PHP file extension |
61 | * @param storage $storage phpBB avatar storage |
62 | * @param path_helper $path_helper phpBB path helper |
63 | * @param helper $routing_helper phpBB routing helper |
64 | * @param dispatcher_interface $dispatcher phpBB Event dispatcher object |
65 | * @param factory $files_factory File classes factory |
66 | * @param IniGetWrapper $php_ini ini_get() wrapper |
67 | */ |
68 | public function __construct(config $config, string $phpbb_root_path, string $php_ext, storage $storage, path_helper $path_helper, helper $routing_helper, dispatcher_interface $dispatcher, factory $files_factory, IniGetWrapper $php_ini) |
69 | { |
70 | $this->config = $config; |
71 | $this->phpbb_root_path = $phpbb_root_path; |
72 | $this->php_ext = $php_ext; |
73 | $this->storage = $storage; |
74 | $this->path_helper = $path_helper; |
75 | $this->routing_helper = $routing_helper; |
76 | $this->dispatcher = $dispatcher; |
77 | $this->files_factory = $files_factory; |
78 | $this->php_ini = $php_ini; |
79 | } |
80 | |
81 | /** |
82 | * {@inheritdoc} |
83 | */ |
84 | public function get_data($row) |
85 | { |
86 | return array( |
87 | 'src' => $this->routing_helper->route('phpbb_storage_avatar', ['file' => $row['avatar']]), |
88 | 'width' => $row['avatar_width'], |
89 | 'height' => $row['avatar_height'], |
90 | ); |
91 | } |
92 | |
93 | /** |
94 | * {@inheritdoc} |
95 | */ |
96 | public function prepare_form($request, $template, $user, $row, &$error) |
97 | { |
98 | if (!$this->can_upload()) |
99 | { |
100 | return false; |
101 | } |
102 | |
103 | $web_path = $this->path_helper->get_web_root_path(); |
104 | |
105 | $template->assign_vars([ |
106 | 'AVATAR_ALLOWED_EXTENSIONS' => implode(',', preg_replace('/^/', '.', $this->allowed_extensions)), |
107 | 'AVATAR_UPLOAD_SIZE' => $this->config['avatar_filesize'], |
108 | 'T_ASSETS_PATH' => $web_path . '/assets', |
109 | ]); |
110 | |
111 | return true; |
112 | } |
113 | |
114 | /** |
115 | * {@inheritdoc} |
116 | */ |
117 | public function process_form($request, $template, $user, $row, &$error) |
118 | { |
119 | if (!$this->can_upload()) |
120 | { |
121 | return false; |
122 | } |
123 | |
124 | /** @var \phpbb\files\upload $upload */ |
125 | $upload = $this->files_factory->get('upload') |
126 | ->set_error_prefix('AVATAR_') |
127 | ->set_allowed_extensions($this->allowed_extensions) |
128 | ->set_max_filesize($this->config['avatar_filesize']) |
129 | ->set_allowed_dimensions( |
130 | $this->config['avatar_min_width'], |
131 | $this->config['avatar_min_height'], |
132 | $this->config['avatar_max_width'], |
133 | $this->config['avatar_max_height']) |
134 | ->set_disallowed_content((isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false)); |
135 | |
136 | $upload_file = $request->file('avatar_upload_file'); |
137 | |
138 | if (empty($upload_file['name'])) |
139 | { |
140 | return false; |
141 | } |
142 | |
143 | /** @var \phpbb\files\filespec_storage $file */ |
144 | $file = $upload->handle_upload('files.types.form_storage', 'avatar_upload_file'); |
145 | |
146 | $prefix = $this->config['avatar_salt'] . '_'; |
147 | $file->clean_filename('avatar', $prefix, $row['id']); |
148 | |
149 | // If there was an error during upload, then abort operation |
150 | if (count($file->error)) |
151 | { |
152 | $file->remove($this->storage); |
153 | $error = $file->error; |
154 | return false; |
155 | } |
156 | |
157 | $filedata = array( |
158 | 'filename' => $file->get('filename'), |
159 | 'filesize' => $file->get('filesize'), |
160 | 'mimetype' => $file->get('mimetype'), |
161 | 'extension' => $file->get('extension'), |
162 | 'physical_filename' => $file->get('realname'), |
163 | 'real_filename' => $file->get('uploadname'), |
164 | ); |
165 | |
166 | /** |
167 | * Before moving new file in place (and eventually overwriting the existing avatar with the newly uploaded avatar) |
168 | * |
169 | * @event core.avatar_driver_upload_move_file_before |
170 | * @var array filedata Array containing uploaded file data |
171 | * @var \phpbb\files\filespec file Instance of filespec class |
172 | * @var string prefix Prefix for the avatar filename |
173 | * @var array row Array with avatar row data |
174 | * @var array error Array of errors, if filled in by this event file will not be moved |
175 | * @since 3.1.6-RC1 |
176 | * @changed 3.1.9-RC1 Added filedata |
177 | * @changed 3.2.3-RC1 Added file |
178 | */ |
179 | $vars = array( |
180 | 'filedata', |
181 | 'file', |
182 | 'prefix', |
183 | 'row', |
184 | 'error', |
185 | ); |
186 | extract($this->dispatcher->trigger_event('core.avatar_driver_upload_move_file_before', compact($vars))); |
187 | |
188 | unset($filedata); |
189 | |
190 | if (!count($error)) |
191 | { |
192 | // Move file and overwrite any existing image |
193 | $file->move_file($this->storage, true); |
194 | } |
195 | |
196 | // If there was an error during move, then clean up leftovers |
197 | $error = array_merge($error, $file->error); |
198 | if (count($error)) |
199 | { |
200 | $file->remove($this->storage); |
201 | return false; |
202 | } |
203 | |
204 | // Delete current avatar if not overwritten |
205 | $ext = substr(strrchr($row['avatar'], '.'), 1); |
206 | if ($ext && $ext !== $file->get('extension')) |
207 | { |
208 | $this->delete($row); |
209 | } |
210 | |
211 | return array( |
212 | 'avatar' => $row['id'] . '_' . time() . '.' . $file->get('extension'), |
213 | 'avatar_width' => $file->get('width'), |
214 | 'avatar_height' => $file->get('height'), |
215 | ); |
216 | } |
217 | |
218 | /** |
219 | * {@inheritdoc} |
220 | */ |
221 | public function prepare_form_acp($user) |
222 | { |
223 | return array( |
224 | 'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), |
225 | ); |
226 | } |
227 | |
228 | /** |
229 | * {@inheritdoc} |
230 | */ |
231 | public function delete($row) |
232 | { |
233 | $error = array(); |
234 | $prefix = $this->config['avatar_salt'] . '_'; |
235 | $ext = substr(strrchr($row['avatar'], '.'), 1); |
236 | $filename = $prefix . $row['id'] . '.' . $ext; |
237 | |
238 | /** |
239 | * Before deleting an existing avatar |
240 | * |
241 | * @event core.avatar_driver_upload_delete_before |
242 | * @var string prefix Prefix for the avatar filename |
243 | * @var array row Array with avatar row data |
244 | * @var array error Array of errors, if filled in by this event file will not be deleted |
245 | * @since 3.1.6-RC1 |
246 | * @changed 3.3.0-a1 Remove destination |
247 | */ |
248 | $vars = array( |
249 | 'prefix', |
250 | 'row', |
251 | 'error', |
252 | ); |
253 | extract($this->dispatcher->trigger_event('core.avatar_driver_upload_delete_before', compact($vars))); |
254 | |
255 | if (!count($error) && $this->storage->exists($filename)) |
256 | { |
257 | try |
258 | { |
259 | $this->storage->delete($filename); |
260 | return true; |
261 | } |
262 | catch (storage_exception $e) |
263 | { |
264 | // Fail is covered by return statement below |
265 | } |
266 | } |
267 | |
268 | return false; |
269 | } |
270 | |
271 | /** |
272 | * {@inheritdoc} |
273 | */ |
274 | public function get_template_name() |
275 | { |
276 | return 'ucp_avatar_options_upload.html'; |
277 | } |
278 | |
279 | /** |
280 | * Check if user is able to upload an avatar to a temporary folder |
281 | * |
282 | * @return bool True if user can upload, false if not |
283 | */ |
284 | protected function can_upload() |
285 | { |
286 | return (bool) $this->php_ini->getBool('file_uploads'); |
287 | } |
288 | } |