Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
9.38% |
9 / 96 |
|
12.50% |
1 / 8 |
CRAP | |
0.00% |
0 / 1 |
| upload | |
9.38% |
9 / 96 |
|
12.50% |
1 / 8 |
317.72 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
| get_data | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
| 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 | } |