[ Index ] |
PHP Cross Reference of phpBB-3.1.12-deutsch |
[Summary view] [Print] [Text view]
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\plupload; 15 16 /** 17 * This class handles all server-side plupload functions 18 */ 19 class plupload 20 { 21 /** 22 * @var string 23 */ 24 protected $phpbb_root_path; 25 26 /** 27 * @var \phpbb\config\config 28 */ 29 protected $config; 30 31 /** 32 * @var \phpbb\request\request_interface 33 */ 34 protected $request; 35 36 /** 37 * @var \phpbb\user 38 */ 39 protected $user; 40 41 /** 42 * @var \phpbb\php\ini 43 */ 44 protected $php_ini; 45 46 /** 47 * @var \phpbb\mimetype\guesser 48 */ 49 protected $mimetype_guesser; 50 51 /** 52 * Final destination for uploaded files, i.e. the "files" directory. 53 * @var string 54 */ 55 protected $upload_directory; 56 57 /** 58 * Temporary upload directory for plupload uploads. 59 * @var string 60 */ 61 protected $temporary_directory; 62 63 /** 64 * Constructor. 65 * 66 * @param string $phpbb_root_path 67 * @param \phpbb\config\config $config 68 * @param \phpbb\request\request_interface $request 69 * @param \phpbb\user $user 70 * @param \phpbb\php\ini $php_ini 71 * @param \phpbb\mimetype\guesser $mimetype_guesser 72 */ 73 public function __construct($phpbb_root_path, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\user $user, \phpbb\php\ini $php_ini, \phpbb\mimetype\guesser $mimetype_guesser) 74 { 75 $this->phpbb_root_path = $phpbb_root_path; 76 $this->config = $config; 77 $this->request = $request; 78 $this->user = $user; 79 $this->php_ini = $php_ini; 80 $this->mimetype_guesser = $mimetype_guesser; 81 82 $this->set_default_directories(); 83 } 84 85 /** 86 * Plupload allows for chunking so we must check for that and assemble 87 * the whole file first before performing any checks on it. 88 * 89 * @param string $form_name The name of the file element in the upload form 90 * 91 * @return array|null null if there are no chunks to piece together 92 * otherwise array containing the path to the 93 * pieced-together file and its size 94 */ 95 public function handle_upload($form_name) 96 { 97 $chunks_expected = $this->request->variable('chunks', 0); 98 99 // If chunking is disabled or we are not using plupload, just return 100 // and handle the file as usual 101 if ($chunks_expected < 2) 102 { 103 return; 104 } 105 106 $file_name = $this->request->variable('name', ''); 107 $chunk = $this->request->variable('chunk', 0); 108 109 $this->user->add_lang('plupload'); 110 $this->prepare_temporary_directory(); 111 112 $file_path = $this->temporary_filepath($file_name); 113 $this->integrate_uploaded_file($form_name, $chunk, $file_path); 114 115 // If we are done with all the chunks, strip the .part suffix and then 116 // handle the resulting file as normal, otherwise die and await the 117 // next chunk. 118 if ($chunk == $chunks_expected - 1) 119 { 120 rename("{$file_path}.part", $file_path); 121 122 // Reset upload directories to defaults once completed 123 $this->set_default_directories(); 124 125 // Need to modify some of the $_FILES values to reflect the new file 126 return array( 127 'tmp_name' => $file_path, 128 'name' => $this->request->variable('real_filename', '', true), 129 'size' => filesize($file_path), 130 'type' => $this->mimetype_guesser->guess($file_path, $file_name), 131 ); 132 } 133 else 134 { 135 $json_response = new \phpbb\json_response(); 136 $json_response->send(array( 137 'jsonrpc' => '2.0', 138 'id' => 'id', 139 'result' => null, 140 )); 141 } 142 } 143 144 /** 145 * Fill in the plupload configuration options in the template 146 * 147 * @param \phpbb\cache\service $cache 148 * @param \phpbb\template\template $template 149 * @param string $s_action The URL to submit the POST data to 150 * @param int $forum_id The ID of the forum 151 * @param int $max_files Maximum number of files allowed. 0 for unlimited. 152 * 153 * @return null 154 */ 155 public function configure(\phpbb\cache\service $cache, \phpbb\template\template $template, $s_action, $forum_id, $max_files) 156 { 157 $filters = $this->generate_filter_string($cache, $forum_id); 158 $chunk_size = $this->get_chunk_size(); 159 $resize = $this->generate_resize_string(); 160 161 $template->assign_vars(array( 162 'S_RESIZE' => $resize, 163 'S_PLUPLOAD' => true, 164 'FILTERS' => $filters, 165 'CHUNK_SIZE' => $chunk_size, 166 'S_PLUPLOAD_URL' => htmlspecialchars_decode($s_action), 167 'MAX_ATTACHMENTS' => $max_files, 168 'ATTACH_ORDER' => ($this->config['display_order']) ? 'asc' : 'desc', 169 'L_TOO_MANY_ATTACHMENTS' => $this->user->lang('TOO_MANY_ATTACHMENTS', $max_files), 170 )); 171 172 $this->user->add_lang('plupload'); 173 } 174 175 /** 176 * Checks whether the page request was sent by plupload or not 177 * 178 * @return bool 179 */ 180 public function is_active() 181 { 182 return $this->request->header('X-PHPBB-USING-PLUPLOAD', false); 183 } 184 185 /** 186 * Returns whether the current HTTP request is a multipart request. 187 * 188 * @return bool 189 */ 190 public function is_multipart() 191 { 192 $content_type = $this->request->server('CONTENT_TYPE'); 193 194 return strpos($content_type, 'multipart') === 0; 195 } 196 197 /** 198 * Sends an error message back to the client via JSON response 199 * 200 * @param int $code The error code 201 * @param string $msg The translation string of the message to be sent 202 * 203 * @return null 204 */ 205 public function emit_error($code, $msg) 206 { 207 $json_response = new \phpbb\json_response(); 208 $json_response->send(array( 209 'jsonrpc' => '2.0', 210 'id' => 'id', 211 'error' => array( 212 'code' => $code, 213 'message' => $this->user->lang($msg), 214 ), 215 )); 216 } 217 218 /** 219 * Looks at the list of allowed extensions and generates a string 220 * appropriate for use in configuring plupload with 221 * 222 * @param \phpbb\cache\service $cache 223 * @param string $forum_id The ID of the forum 224 * 225 * @return string 226 */ 227 public function generate_filter_string(\phpbb\cache\service $cache, $forum_id) 228 { 229 $attach_extensions = $cache->obtain_attach_extensions($forum_id); 230 unset($attach_extensions['_allowed_']); 231 $groups = array(); 232 233 // Re-arrange the extension array to $groups[$group_name][] 234 foreach ($attach_extensions as $extension => $extension_info) 235 { 236 if (!isset($groups[$extension_info['group_name']])) 237 { 238 $groups[$extension_info['group_name']] = array(); 239 } 240 241 $groups[$extension_info['group_name']][] = $extension; 242 } 243 244 $filters = array(); 245 foreach ($groups as $group => $extensions) 246 { 247 $filters[] = sprintf( 248 "{title: '%s', extensions: '%s'}", 249 addslashes(ucfirst(strtolower($group))), 250 addslashes(implode(',', $extensions)) 251 ); 252 } 253 254 return implode(',', $filters); 255 } 256 257 /** 258 * Generates a string that is used to tell plupload to automatically resize 259 * files before uploading them. 260 * 261 * @return string 262 */ 263 public function generate_resize_string() 264 { 265 $resize = ''; 266 if ($this->config['img_max_height'] > 0 && $this->config['img_max_width'] > 0) 267 { 268 $resize = sprintf( 269 'resize: {width: %d, height: %d, quality: 85},', 270 (int) $this->config['img_max_width'], 271 (int) $this->config['img_max_height'] 272 ); 273 } 274 275 return $resize; 276 } 277 278 /** 279 * Checks various php.ini values and the maximum file size to determine 280 * the maximum size chunks a file can be split up into for upload 281 * 282 * @return int 283 */ 284 public function get_chunk_size() 285 { 286 $max = min( 287 $this->php_ini->get_bytes('upload_max_filesize'), 288 $this->php_ini->get_bytes('post_max_size'), 289 max(1, $this->php_ini->get_bytes('memory_limit')), 290 $this->config['max_filesize'] 291 ); 292 293 // Use half of the maximum possible to leave plenty of room for other 294 // POST data. 295 return floor($max / 2); 296 } 297 298 protected function temporary_filepath($file_name) 299 { 300 // Must preserve the extension for plupload to work. 301 return sprintf( 302 '%s/%s_%s%s', 303 $this->temporary_directory, 304 $this->config['plupload_salt'], 305 md5($file_name), 306 \filespec::get_extension($file_name) 307 ); 308 } 309 310 /** 311 * Checks whether the chunk we are about to deal with was actually uploaded 312 * by PHP and actually exists, if not, it generates an error 313 * 314 * @param string $form_name The name of the file in the form data 315 * 316 * @return null 317 */ 318 protected function integrate_uploaded_file($form_name, $chunk, $file_path) 319 { 320 $is_multipart = $this->is_multipart(); 321 $upload = $this->request->file($form_name); 322 if ($is_multipart && (!isset($upload['tmp_name']) || !is_uploaded_file($upload['tmp_name']))) 323 { 324 $this->emit_error(103, 'PLUPLOAD_ERR_MOVE_UPLOADED'); 325 } 326 327 $tmp_file = $this->temporary_filepath($upload['tmp_name']); 328 329 if (!phpbb_is_writable($this->temporary_directory) || !move_uploaded_file($upload['tmp_name'], $tmp_file)) 330 { 331 $this->emit_error(103, 'PLUPLOAD_ERR_MOVE_UPLOADED'); 332 } 333 334 $out = fopen("{$file_path}.part", $chunk == 0 ? 'wb' : 'ab'); 335 if (!$out) 336 { 337 $this->emit_error(102, 'PLUPLOAD_ERR_OUTPUT'); 338 } 339 340 $in = fopen(($is_multipart) ? $tmp_file : 'php://input', 'rb'); 341 if (!$in) 342 { 343 $this->emit_error(101, 'PLUPLOAD_ERR_INPUT'); 344 } 345 346 while ($buf = fread($in, 4096)) 347 { 348 fwrite($out, $buf); 349 } 350 351 fclose($in); 352 fclose($out); 353 354 if ($is_multipart) 355 { 356 unlink($tmp_file); 357 } 358 } 359 360 /** 361 * Creates the temporary directory if it does not already exist. 362 * 363 * @return null 364 */ 365 protected function prepare_temporary_directory() 366 { 367 if (!file_exists($this->temporary_directory)) 368 { 369 mkdir($this->temporary_directory); 370 371 copy( 372 $this->upload_directory . '/index.htm', 373 $this->temporary_directory . '/index.htm' 374 ); 375 } 376 } 377 378 /** 379 * Sets the default directories for uploads 380 * 381 * @return null 382 */ 383 protected function set_default_directories() 384 { 385 $this->upload_directory = $this->phpbb_root_path . $this->config['upload_path']; 386 $this->temporary_directory = $this->upload_directory . '/plupload'; 387 } 388 389 /** 390 * Sets the upload directories to the specified paths 391 * 392 * @param string $upload_directory Upload directory 393 * @param string $temporary_directory Temporary directory 394 * 395 * @return null 396 */ 397 public function set_upload_directories($upload_directory, $temporary_directory) 398 { 399 $this->upload_directory = $upload_directory; 400 $this->temporary_directory = $temporary_directory; 401 } 402 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |