Yoshi2889 /
SMF2.1
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * This file handles the uploading and creation of attachments |
||
| 5 | * as well as the auto management of the attachment directories. |
||
| 6 | * |
||
| 7 | * Simple Machines Forum (SMF) |
||
| 8 | * |
||
| 9 | * @package SMF |
||
| 10 | * @author Simple Machines http://www.simplemachines.org |
||
| 11 | * @copyright 2017 Simple Machines and individual contributors |
||
| 12 | * @license http://www.simplemachines.org/about/smf/license.php BSD |
||
| 13 | * |
||
| 14 | * @version 2.1 Beta 4 |
||
| 15 | */ |
||
| 16 | |||
| 17 | if (!defined('SMF')) |
||
| 18 | die('No direct access...'); |
||
| 19 | |||
| 20 | /** |
||
| 21 | * Check if the current directory is still valid or not. |
||
| 22 | * If not creates the new directory |
||
| 23 | * |
||
| 24 | * @return void|bool False if any error occurred |
||
| 25 | */ |
||
| 26 | function automanage_attachments_check_directory() |
||
| 27 | { |
||
| 28 | global $smcFunc, $boarddir, $modSettings, $context; |
||
| 29 | |||
| 30 | // Not pretty, but since we don't want folders created for every post. It'll do unless a better solution can be found. |
||
| 31 | if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'admin') |
||
| 32 | $doit = true; |
||
| 33 | elseif (empty($modSettings['automanage_attachments'])) |
||
| 34 | return; |
||
| 35 | elseif (!isset($_FILES)) |
||
| 36 | return; |
||
| 37 | elseif (isset($_FILES['attachment'])) |
||
| 38 | View Code Duplication | foreach ($_FILES['attachment']['tmp_name'] as $dummy) |
|
| 39 | if (!empty($dummy)) |
||
| 40 | { |
||
| 41 | $doit = true; |
||
| 42 | break; |
||
| 43 | } |
||
| 44 | |||
| 45 | if (!isset($doit)) |
||
| 46 | return; |
||
| 47 | |||
| 48 | $year = date('Y'); |
||
| 49 | $month = date('m'); |
||
| 50 | |||
| 51 | $rand = md5(mt_rand()); |
||
| 52 | $rand1 = $rand[1]; |
||
| 53 | $rand = $rand[0]; |
||
| 54 | |||
| 55 | if (!empty($modSettings['attachment_basedirectories']) && !empty($modSettings['use_subdirectories_for_attachments'])) |
||
| 56 | { |
||
| 57 | if (!is_array($modSettings['attachment_basedirectories'])) |
||
| 58 | $modSettings['attachment_basedirectories'] = $smcFunc['json_decode']($modSettings['attachment_basedirectories'], true); |
||
| 59 | $base_dir = array_search($modSettings['basedirectory_for_attachments'], $modSettings['attachment_basedirectories']); |
||
| 60 | } |
||
| 61 | else |
||
| 62 | $base_dir = 0; |
||
| 63 | |||
| 64 | if ($modSettings['automanage_attachments'] == 1) |
||
| 65 | { |
||
| 66 | if (!isset($modSettings['last_attachments_directory'])) |
||
| 67 | $modSettings['last_attachments_directory'] = array(); |
||
| 68 | if (!is_array($modSettings['last_attachments_directory'])) |
||
| 69 | $modSettings['last_attachments_directory'] = $smcFunc['json_decode']($modSettings['last_attachments_directory'], true); |
||
| 70 | if (!isset($modSettings['last_attachments_directory'][$base_dir])) |
||
| 71 | $modSettings['last_attachments_directory'][$base_dir] = 0; |
||
| 72 | } |
||
| 73 | |||
| 74 | $basedirectory = (!empty($modSettings['use_subdirectories_for_attachments']) ? ($modSettings['basedirectory_for_attachments']) : $boarddir); |
||
| 75 | //Just to be sure: I don't want directory separators at the end |
||
| 76 | $sep = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? '\/' : DIRECTORY_SEPARATOR; |
||
| 77 | $basedirectory = rtrim($basedirectory, $sep); |
||
| 78 | |||
| 79 | switch ($modSettings['automanage_attachments']) |
||
| 80 | { |
||
| 81 | case 1: |
||
| 82 | $updir = $basedirectory . DIRECTORY_SEPARATOR . 'attachments_' . (isset($modSettings['last_attachments_directory'][$base_dir]) ? $modSettings['last_attachments_directory'][$base_dir] : 0); |
||
| 83 | break; |
||
| 84 | case 2: |
||
| 85 | $updir = $basedirectory . DIRECTORY_SEPARATOR . $year; |
||
| 86 | break; |
||
| 87 | case 3: |
||
| 88 | $updir = $basedirectory . DIRECTORY_SEPARATOR . $year . DIRECTORY_SEPARATOR . $month; |
||
| 89 | break; |
||
| 90 | View Code Duplication | case 4: |
|
| 91 | $updir = $basedirectory . DIRECTORY_SEPARATOR . (empty($modSettings['use_subdirectories_for_attachments']) ? 'attachments-' : 'random_') . $rand; |
||
| 92 | break; |
||
| 93 | View Code Duplication | case 5: |
|
| 94 | $updir = $basedirectory . DIRECTORY_SEPARATOR . (empty($modSettings['use_subdirectories_for_attachments']) ? 'attachments-' : 'random_') . $rand . DIRECTORY_SEPARATOR . $rand1; |
||
| 95 | break; |
||
| 96 | default : |
||
| 97 | $updir = ''; |
||
| 98 | } |
||
| 99 | |||
| 100 | if (!is_array($modSettings['attachmentUploadDir'])) |
||
| 101 | $modSettings['attachmentUploadDir'] = $smcFunc['json_decode']($modSettings['attachmentUploadDir'], true); |
||
| 102 | if (!in_array($updir, $modSettings['attachmentUploadDir']) && !empty($updir)) |
||
| 103 | $outputCreation = automanage_attachments_create_directory($updir); |
||
| 104 | elseif (in_array($updir, $modSettings['attachmentUploadDir'])) |
||
| 105 | $outputCreation = true; |
||
| 106 | |||
| 107 | if ($outputCreation) |
||
|
0 ignored issues
–
show
|
|||
| 108 | { |
||
| 109 | $modSettings['currentAttachmentUploadDir'] = array_search($updir, $modSettings['attachmentUploadDir']); |
||
| 110 | $context['attach_dir'] = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']]; |
||
| 111 | |||
| 112 | updateSettings(array( |
||
| 113 | 'currentAttachmentUploadDir' => $modSettings['currentAttachmentUploadDir'], |
||
| 114 | )); |
||
| 115 | } |
||
| 116 | |||
| 117 | return $outputCreation; |
||
| 118 | } |
||
| 119 | |||
| 120 | /** |
||
| 121 | * Creates a directory |
||
| 122 | * |
||
| 123 | * @param string $updir The directory to be created |
||
| 124 | * |
||
| 125 | * @return bool False on errors |
||
| 126 | */ |
||
| 127 | function automanage_attachments_create_directory($updir) |
||
| 128 | { |
||
| 129 | global $smcFunc, $modSettings, $context, $boarddir; |
||
| 130 | |||
| 131 | $tree = get_directory_tree_elements($updir); |
||
| 132 | $count = count($tree); |
||
| 133 | |||
| 134 | $directory = attachments_init_dir($tree, $count); |
||
|
0 ignored issues
–
show
It seems like
$tree defined by get_directory_tree_elements($updir) on line 131 can also be of type false; however, attachments_init_dir() does only seem to accept array, did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new Loading history...
|
|||
| 135 | if ($directory === false) |
||
| 136 | { |
||
| 137 | // Maybe it's just the folder name |
||
| 138 | $tree = get_directory_tree_elements($boarddir . DIRECTORY_SEPARATOR . $updir); |
||
| 139 | $count = count($tree); |
||
| 140 | |||
| 141 | $directory = attachments_init_dir($tree, $count); |
||
|
0 ignored issues
–
show
It seems like
$tree defined by get_directory_tree_eleme...ORY_SEPARATOR . $updir) on line 138 can also be of type false; however, attachments_init_dir() does only seem to accept array, did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new Loading history...
|
|||
| 142 | if ($directory === false) |
||
| 143 | return false; |
||
| 144 | } |
||
| 145 | |||
| 146 | $directory .= DIRECTORY_SEPARATOR . array_shift($tree); |
||
| 147 | |||
| 148 | while (!@is_dir($directory) || $count != -1) |
||
| 149 | { |
||
| 150 | if (!@is_dir($directory)) |
||
| 151 | { |
||
| 152 | if (!@mkdir($directory, 0755)) |
||
| 153 | { |
||
| 154 | $context['dir_creation_error'] = 'attachments_no_create'; |
||
| 155 | return false; |
||
| 156 | } |
||
| 157 | } |
||
| 158 | |||
| 159 | $directory .= DIRECTORY_SEPARATOR . array_shift($tree); |
||
| 160 | $count--; |
||
| 161 | } |
||
| 162 | |||
| 163 | // Check if the dir is writable. |
||
| 164 | if (!smf_chmod($directory)) |
||
| 165 | { |
||
| 166 | $context['dir_creation_error'] = 'attachments_no_write'; |
||
| 167 | return false; |
||
| 168 | } |
||
| 169 | |||
| 170 | // Everything seems fine...let's create the .htaccess |
||
| 171 | if (!file_exists($directory . DIRECTORY_SEPARATOR . '.htaccess')) |
||
| 172 | secureDirectory($updir, true); |
||
| 173 | |||
| 174 | $sep = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? '\/' : DIRECTORY_SEPARATOR; |
||
| 175 | $updir = rtrim($updir, $sep); |
||
| 176 | |||
| 177 | // Only update if it's a new directory |
||
| 178 | if (!in_array($updir, $modSettings['attachmentUploadDir'])) |
||
| 179 | { |
||
| 180 | $modSettings['currentAttachmentUploadDir'] = max(array_keys($modSettings['attachmentUploadDir'])) + 1; |
||
| 181 | $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']] = $updir; |
||
| 182 | |||
| 183 | updateSettings(array( |
||
| 184 | 'attachmentUploadDir' => $smcFunc['json_encode']($modSettings['attachmentUploadDir']), |
||
| 185 | 'currentAttachmentUploadDir' => $modSettings['currentAttachmentUploadDir'], |
||
| 186 | ), true); |
||
| 187 | $modSettings['attachmentUploadDir'] = $smcFunc['json_decode']($modSettings['attachmentUploadDir'], true); |
||
| 188 | } |
||
| 189 | |||
| 190 | $context['attach_dir'] = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']]; |
||
| 191 | return true; |
||
| 192 | } |
||
| 193 | |||
| 194 | /** |
||
| 195 | * Called when a directory space limit is reached. |
||
| 196 | * Creates a new directory and increments the directory suffix number. |
||
| 197 | * |
||
| 198 | * @return void|bool False on errors, true if successful, nothing if auto-management of attachments is disabled |
||
| 199 | */ |
||
| 200 | function automanage_attachments_by_space() |
||
| 201 | { |
||
| 202 | global $smcFunc, $modSettings, $boarddir; |
||
| 203 | |||
| 204 | if (!isset($modSettings['automanage_attachments']) || (!empty($modSettings['automanage_attachments']) && $modSettings['automanage_attachments'] != 1)) |
||
| 205 | return; |
||
| 206 | |||
| 207 | $basedirectory = !empty($modSettings['use_subdirectories_for_attachments']) ? $modSettings['basedirectory_for_attachments'] : $boarddir; |
||
| 208 | // Just to be sure: I don't want directory separators at the end |
||
| 209 | $sep = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? '\/' : DIRECTORY_SEPARATOR; |
||
| 210 | $basedirectory = rtrim($basedirectory, $sep); |
||
| 211 | |||
| 212 | // Get the current base directory |
||
| 213 | if (!empty($modSettings['use_subdirectories_for_attachments']) && !empty($modSettings['attachment_basedirectories'])) |
||
| 214 | { |
||
| 215 | $base_dir = array_search($modSettings['basedirectory_for_attachments'], $modSettings['attachment_basedirectories']); |
||
| 216 | $base_dir = !empty($modSettings['automanage_attachments']) ? $base_dir : 0; |
||
| 217 | } |
||
| 218 | else |
||
| 219 | $base_dir = 0; |
||
| 220 | |||
| 221 | // Get the last attachment directory for that base directory |
||
| 222 | if (empty($modSettings['last_attachments_directory'][$base_dir])) |
||
| 223 | $modSettings['last_attachments_directory'][$base_dir] = 0; |
||
| 224 | // And increment it. |
||
| 225 | $modSettings['last_attachments_directory'][$base_dir]++; |
||
| 226 | |||
| 227 | $updir = $basedirectory . DIRECTORY_SEPARATOR . 'attachments_' . $modSettings['last_attachments_directory'][$base_dir]; |
||
| 228 | if (automanage_attachments_create_directory($updir)) |
||
| 229 | { |
||
| 230 | $modSettings['currentAttachmentUploadDir'] = array_search($updir, $modSettings['attachmentUploadDir']); |
||
| 231 | updateSettings(array( |
||
| 232 | 'last_attachments_directory' => $smcFunc['json_encode']($modSettings['last_attachments_directory']), |
||
| 233 | 'currentAttachmentUploadDir' => $modSettings['currentAttachmentUploadDir'], |
||
| 234 | )); |
||
| 235 | $modSettings['last_attachments_directory'] = $smcFunc['json_decode']($modSettings['last_attachments_directory'], true); |
||
| 236 | |||
| 237 | return true; |
||
| 238 | } |
||
| 239 | else |
||
| 240 | return false; |
||
| 241 | } |
||
| 242 | |||
| 243 | /** |
||
| 244 | * Split a path into a list of all directories and subdirectories |
||
| 245 | * |
||
| 246 | * @param string $directory A path |
||
| 247 | * |
||
| 248 | * @return array|bool An array of all the directories and subdirectories or false on failure |
||
| 249 | */ |
||
| 250 | function get_directory_tree_elements($directory) |
||
| 251 | { |
||
| 252 | /* |
||
| 253 | In Windows server both \ and / can be used as directory separators in paths |
||
| 254 | In Linux (and presumably *nix) servers \ can be part of the name |
||
| 255 | So for this reasons: |
||
| 256 | * in Windows we need to explode for both \ and / |
||
| 257 | * while in linux should be safe to explode only for / (aka DIRECTORY_SEPARATOR) |
||
| 258 | */ |
||
| 259 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') |
||
| 260 | $tree = preg_split('#[\\\/]#', $directory); |
||
| 261 | else |
||
| 262 | { |
||
| 263 | if (substr($directory, 0, 1) != DIRECTORY_SEPARATOR) |
||
| 264 | return false; |
||
| 265 | |||
| 266 | $tree = explode(DIRECTORY_SEPARATOR, trim($directory, DIRECTORY_SEPARATOR)); |
||
| 267 | } |
||
| 268 | return $tree; |
||
| 269 | } |
||
| 270 | |||
| 271 | /** |
||
| 272 | * Return the first part of a path (i.e. c:\ or / + the first directory), used by automanage_attachments_create_directory |
||
| 273 | * |
||
| 274 | * @param array $tree An array |
||
| 275 | * @param int $count The number of elements in $tree |
||
| 276 | * |
||
| 277 | * @return string|bool The first part of the path or false on error |
||
| 278 | */ |
||
| 279 | function attachments_init_dir(&$tree, &$count) |
||
| 280 | { |
||
| 281 | $directory = ''; |
||
| 282 | // If on Windows servers the first part of the path is the drive (e.g. "C:") |
||
| 283 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') |
||
| 284 | { |
||
| 285 | //Better be sure that the first part of the path is actually a drive letter... |
||
| 286 | //...even if, I should check this in the admin page...isn't it? |
||
| 287 | //...NHAAA Let's leave space for users' complains! :P |
||
| 288 | if (preg_match('/^[a-z]:$/i', $tree[0])) |
||
| 289 | $directory = array_shift($tree); |
||
| 290 | else |
||
| 291 | return false; |
||
| 292 | |||
| 293 | $count--; |
||
| 294 | } |
||
| 295 | return $directory; |
||
| 296 | } |
||
| 297 | |||
| 298 | /** |
||
| 299 | * Moves an attachment to the proper directory and set the relevant data into $_SESSION['temp_attachments'] |
||
| 300 | */ |
||
| 301 | function processAttachments() |
||
| 302 | { |
||
| 303 | global $context, $modSettings, $smcFunc, $txt, $user_info; |
||
| 304 | |||
| 305 | // Make sure we're uploading to the right place. |
||
| 306 | if (!empty($modSettings['automanage_attachments'])) |
||
| 307 | automanage_attachments_check_directory(); |
||
| 308 | |||
| 309 | if (!is_array($modSettings['attachmentUploadDir'])) |
||
| 310 | $modSettings['attachmentUploadDir'] = $smcFunc['json_decode']($modSettings['attachmentUploadDir'], true); |
||
| 311 | |||
| 312 | $context['attach_dir'] = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']]; |
||
| 313 | |||
| 314 | // Is the attachments folder actualy there? |
||
| 315 | if (!empty($context['dir_creation_error'])) |
||
| 316 | $initial_error = $context['dir_creation_error']; |
||
| 317 | elseif (!is_dir($context['attach_dir'])) |
||
| 318 | { |
||
| 319 | $initial_error = 'attach_folder_warning'; |
||
| 320 | log_error(sprintf($txt['attach_folder_admin_warning'], $context['attach_dir']), 'critical'); |
||
| 321 | } |
||
| 322 | |||
| 323 | if (!isset($initial_error) && !isset($context['attachments'])) |
||
| 324 | { |
||
| 325 | // If this isn't a new post, check the current attachments. |
||
| 326 | if (isset($_REQUEST['msg'])) |
||
| 327 | { |
||
| 328 | $request = $smcFunc['db_query']('', ' |
||
| 329 | SELECT COUNT(*), SUM(size) |
||
| 330 | FROM {db_prefix}attachments |
||
| 331 | WHERE id_msg = {int:id_msg} |
||
| 332 | AND attachment_type = {int:attachment_type}', |
||
| 333 | array( |
||
| 334 | 'id_msg' => (int) $_REQUEST['msg'], |
||
| 335 | 'attachment_type' => 0, |
||
| 336 | ) |
||
| 337 | ); |
||
| 338 | list ($context['attachments']['quantity'], $context['attachments']['total_size']) = $smcFunc['db_fetch_row']($request); |
||
| 339 | $smcFunc['db_free_result']($request); |
||
| 340 | } |
||
| 341 | else |
||
| 342 | $context['attachments'] = array( |
||
| 343 | 'quantity' => 0, |
||
| 344 | 'total_size' => 0, |
||
| 345 | ); |
||
| 346 | } |
||
| 347 | |||
| 348 | // Hmm. There are still files in session. |
||
| 349 | $ignore_temp = false; |
||
| 350 | if (!empty($_SESSION['temp_attachments']['post']['files']) && count($_SESSION['temp_attachments']) > 1) |
||
| 351 | { |
||
| 352 | // Let's try to keep them. But... |
||
| 353 | $ignore_temp = true; |
||
| 354 | // If new files are being added. We can't ignore those |
||
| 355 | View Code Duplication | foreach ($_FILES['attachment']['tmp_name'] as $dummy) |
|
| 356 | if (!empty($dummy)) |
||
| 357 | { |
||
| 358 | $ignore_temp = false; |
||
| 359 | break; |
||
| 360 | } |
||
| 361 | |||
| 362 | // Need to make space for the new files. So, bye bye. |
||
| 363 | if (!$ignore_temp) |
||
| 364 | { |
||
| 365 | View Code Duplication | foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) |
|
| 366 | if (strpos($attachID, 'post_tmp_' . $user_info['id']) !== false) |
||
| 367 | unlink($attachment['tmp_name']); |
||
| 368 | |||
| 369 | $context['we_are_history'] = $txt['error_temp_attachments_flushed']; |
||
| 370 | $_SESSION['temp_attachments'] = array(); |
||
| 371 | } |
||
| 372 | } |
||
| 373 | |||
| 374 | if (!isset($_FILES['attachment']['name'])) |
||
| 375 | $_FILES['attachment']['tmp_name'] = array(); |
||
| 376 | |||
| 377 | if (!isset($_SESSION['temp_attachments'])) |
||
| 378 | $_SESSION['temp_attachments'] = array(); |
||
| 379 | |||
| 380 | // Remember where we are at. If it's anywhere at all. |
||
| 381 | if (!$ignore_temp) |
||
| 382 | $_SESSION['temp_attachments']['post'] = array( |
||
| 383 | 'msg' => !empty($_REQUEST['msg']) ? $_REQUEST['msg'] : 0, |
||
| 384 | 'last_msg' => !empty($_REQUEST['last_msg']) ? $_REQUEST['last_msg'] : 0, |
||
| 385 | 'topic' => !empty($topic) ? $topic : 0, |
||
|
0 ignored issues
–
show
The variable
$topic seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?
This check looks for calls to This is most likely caused by the renaming of a variable or the removal of a function/method parameter. Loading history...
|
|||
| 386 | 'board' => !empty($board) ? $board : 0, |
||
|
0 ignored issues
–
show
The variable
$board seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?
This check looks for calls to This is most likely caused by the renaming of a variable or the removal of a function/method parameter. Loading history...
|
|||
| 387 | ); |
||
| 388 | |||
| 389 | // If we have an initial error, lets just display it. |
||
| 390 | if (!empty($initial_error)) |
||
| 391 | { |
||
| 392 | $_SESSION['temp_attachments']['initial_error'] = $initial_error; |
||
| 393 | |||
| 394 | // And delete the files 'cos they ain't going nowhere. |
||
| 395 | View Code Duplication | foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) |
|
| 396 | if (file_exists($_FILES['attachment']['tmp_name'][$n])) |
||
| 397 | unlink($_FILES['attachment']['tmp_name'][$n]); |
||
| 398 | |||
| 399 | $_FILES['attachment']['tmp_name'] = array(); |
||
| 400 | } |
||
| 401 | |||
| 402 | // Loop through $_FILES['attachment'] array and move each file to the current attachments folder. |
||
| 403 | View Code Duplication | foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) |
|
| 404 | { |
||
| 405 | if ($_FILES['attachment']['name'][$n] == '') |
||
| 406 | continue; |
||
| 407 | |||
| 408 | // First, let's first check for PHP upload errors. |
||
| 409 | $errors = array(); |
||
| 410 | if (!empty($_FILES['attachment']['error'][$n])) |
||
| 411 | { |
||
| 412 | if ($_FILES['attachment']['error'][$n] == 2) |
||
| 413 | $errors[] = array('file_too_big', array($modSettings['attachmentSizeLimit'])); |
||
| 414 | elseif ($_FILES['attachment']['error'][$n] == 6) |
||
| 415 | log_error($_FILES['attachment']['name'][$n] . ': ' . $txt['php_upload_error_6'], 'critical'); |
||
| 416 | else |
||
| 417 | log_error($_FILES['attachment']['name'][$n] . ': ' . $txt['php_upload_error_' . $_FILES['attachment']['error'][$n]]); |
||
| 418 | if (empty($errors)) |
||
| 419 | $errors[] = 'attach_php_error'; |
||
| 420 | } |
||
| 421 | |||
| 422 | // Try to move and rename the file before doing any more checks on it. |
||
| 423 | $attachID = 'post_tmp_' . $user_info['id'] . '_' . md5(mt_rand()); |
||
| 424 | $destName = $context['attach_dir'] . '/' . $attachID; |
||
| 425 | if (empty($errors)) |
||
| 426 | { |
||
| 427 | // The reported MIME type of the attachment might not be reliable. |
||
| 428 | // Fortunately, PHP 5.3+ lets us easily verify the real MIME type. |
||
| 429 | if (function_exists('mime_content_type')) |
||
| 430 | $_FILES['attachment']['type'][$n] = mime_content_type($_FILES['attachment']['tmp_name'][$n]); |
||
| 431 | |||
| 432 | $_SESSION['temp_attachments'][$attachID] = array( |
||
| 433 | 'name' => $smcFunc['htmlspecialchars'](basename($_FILES['attachment']['name'][$n])), |
||
| 434 | 'tmp_name' => $destName, |
||
| 435 | 'size' => $_FILES['attachment']['size'][$n], |
||
| 436 | 'type' => $_FILES['attachment']['type'][$n], |
||
| 437 | 'id_folder' => $modSettings['currentAttachmentUploadDir'], |
||
| 438 | 'errors' => array(), |
||
| 439 | ); |
||
| 440 | |||
| 441 | // Move the file to the attachments folder with a temp name for now. |
||
| 442 | if (@move_uploaded_file($_FILES['attachment']['tmp_name'][$n], $destName)) |
||
| 443 | smf_chmod($destName, 0644); |
||
| 444 | else |
||
| 445 | { |
||
| 446 | $_SESSION['temp_attachments'][$attachID]['errors'][] = 'attach_timeout'; |
||
| 447 | if (file_exists($_FILES['attachment']['tmp_name'][$n])) |
||
| 448 | unlink($_FILES['attachment']['tmp_name'][$n]); |
||
| 449 | } |
||
| 450 | } |
||
| 451 | else |
||
| 452 | { |
||
| 453 | $_SESSION['temp_attachments'][$attachID] = array( |
||
| 454 | 'name' => $smcFunc['htmlspecialchars'](basename($_FILES['attachment']['name'][$n])), |
||
| 455 | 'tmp_name' => $destName, |
||
| 456 | 'errors' => $errors, |
||
| 457 | ); |
||
| 458 | |||
| 459 | if (file_exists($_FILES['attachment']['tmp_name'][$n])) |
||
| 460 | unlink($_FILES['attachment']['tmp_name'][$n]); |
||
| 461 | } |
||
| 462 | // If there's no errors to this point. We still do need to apply some additional checks before we are finished. |
||
| 463 | if (empty($_SESSION['temp_attachments'][$attachID]['errors'])) |
||
| 464 | attachmentChecks($attachID); |
||
| 465 | } |
||
| 466 | // Mod authors, finally a hook to hang an alternate attachment upload system upon |
||
| 467 | // Upload to the current attachment folder with the file name $attachID or 'post_tmp_' . $user_info['id'] . '_' . md5(mt_rand()) |
||
| 468 | // Populate $_SESSION['temp_attachments'][$attachID] with the following: |
||
| 469 | // name => The file name |
||
| 470 | // tmp_name => Path to the temp file ($context['attach_dir'] . '/' . $attachID). |
||
| 471 | // size => File size (required). |
||
| 472 | // type => MIME type (optional if not available on upload). |
||
| 473 | // id_folder => $modSettings['currentAttachmentUploadDir'] |
||
| 474 | // errors => An array of errors (use the index of the $txt variable for that error). |
||
| 475 | // Template changes can be done using "integrate_upload_template". |
||
| 476 | call_integration_hook('integrate_attachment_upload', array()); |
||
| 477 | } |
||
| 478 | |||
| 479 | /** |
||
| 480 | * Performs various checks on an uploaded file. |
||
| 481 | * - Requires that $_SESSION['temp_attachments'][$attachID] be properly populated. |
||
| 482 | * |
||
| 483 | * @param int $attachID The ID of the attachment |
||
| 484 | * @return bool Whether the attachment is OK |
||
| 485 | */ |
||
| 486 | function attachmentChecks($attachID) |
||
| 487 | { |
||
| 488 | global $modSettings, $context, $sourcedir, $smcFunc; |
||
| 489 | |||
| 490 | // No data or missing data .... Not necessarily needed, but in case a mod author missed something. |
||
| 491 | if (empty($_SESSION['temp_attachments'][$attachID])) |
||
| 492 | $error = '$_SESSION[\'temp_attachments\'][$attachID]'; |
||
| 493 | |||
| 494 | elseif (empty($attachID)) |
||
| 495 | $error = '$attachID'; |
||
| 496 | |||
| 497 | elseif (empty($context['attachments'])) |
||
| 498 | $error = '$context[\'attachments\']'; |
||
| 499 | |||
| 500 | elseif (empty($context['attach_dir'])) |
||
| 501 | $error = '$context[\'attach_dir\']'; |
||
| 502 | |||
| 503 | // Let's get their attention. |
||
| 504 | if (!empty($error)) |
||
| 505 | fatal_lang_error('attach_check_nag', 'debug', array($error)); |
||
| 506 | |||
| 507 | // Just in case this slipped by the first checks, we stop it here and now |
||
| 508 | if ($_SESSION['temp_attachments'][$attachID]['size'] == 0) |
||
| 509 | { |
||
| 510 | $_SESSION['temp_attachments'][$attachID]['errors'][] = 'attach_0_byte_file'; |
||
| 511 | return false; |
||
| 512 | } |
||
| 513 | |||
| 514 | // First, the dreaded security check. Sorry folks, but this shouldn't be avoided. |
||
| 515 | $size = @getimagesize($_SESSION['temp_attachments'][$attachID]['tmp_name']); |
||
| 516 | if (isset($context['validImageTypes'][$size[2]])) |
||
| 517 | { |
||
| 518 | require_once($sourcedir . '/Subs-Graphics.php'); |
||
| 519 | if (!checkImageContents($_SESSION['temp_attachments'][$attachID]['tmp_name'], !empty($modSettings['attachment_image_paranoid']))) |
||
| 520 | { |
||
| 521 | // It's bad. Last chance, maybe we can re-encode it? |
||
| 522 | if (empty($modSettings['attachment_image_reencode']) || (!reencodeImage($_SESSION['temp_attachments'][$attachID]['tmp_name'], $size[2]))) |
||
| 523 | { |
||
| 524 | // Nothing to do: not allowed or not successful re-encoding it. |
||
| 525 | $_SESSION['temp_attachments'][$attachID]['errors'][] = 'bad_attachment'; |
||
| 526 | return false; |
||
| 527 | } |
||
| 528 | // Success! However, successes usually come for a price: |
||
| 529 | // we might get a new format for our image... |
||
| 530 | $old_format = $size[2]; |
||
| 531 | $size = @getimagesize($_SESSION['temp_attachments'][$attachID]['tmp_name']); |
||
| 532 | if (!(empty($size)) && ($size[2] != $old_format)) |
||
| 533 | { |
||
| 534 | if (isset($context['validImageTypes'][$size[2]])) |
||
| 535 | $_SESSION['temp_attachments'][$attachID]['type'] = 'image/' . $context['validImageTypes'][$size[2]]; |
||
| 536 | } |
||
| 537 | } |
||
| 538 | } |
||
| 539 | |||
| 540 | // Is there room for this sucker? |
||
| 541 | if (!empty($modSettings['attachmentDirSizeLimit']) || !empty($modSettings['attachmentDirFileLimit'])) |
||
| 542 | { |
||
| 543 | // Check the folder size and count. If it hasn't been done already. |
||
| 544 | if (empty($context['dir_size']) || empty($context['dir_files'])) |
||
| 545 | { |
||
| 546 | $request = $smcFunc['db_query']('', ' |
||
| 547 | SELECT COUNT(*), SUM(size) |
||
| 548 | FROM {db_prefix}attachments |
||
| 549 | WHERE id_folder = {int:folder_id} |
||
| 550 | AND attachment_type != {int:type}', |
||
| 551 | array( |
||
| 552 | 'folder_id' => $modSettings['currentAttachmentUploadDir'], |
||
| 553 | 'type' => 1, |
||
| 554 | ) |
||
| 555 | ); |
||
| 556 | list ($context['dir_files'], $context['dir_size']) = $smcFunc['db_fetch_row']($request); |
||
| 557 | $smcFunc['db_free_result']($request); |
||
| 558 | } |
||
| 559 | $context['dir_size'] += $_SESSION['temp_attachments'][$attachID]['size']; |
||
| 560 | $context['dir_files']++; |
||
| 561 | |||
| 562 | // Are we about to run out of room? Let's notify the admin then. |
||
| 563 | if (empty($modSettings['attachment_full_notified']) && !empty($modSettings['attachmentDirSizeLimit']) && $modSettings['attachmentDirSizeLimit'] > 4000 && $context['dir_size'] > ($modSettings['attachmentDirSizeLimit'] - 2000) * 1024 |
||
| 564 | || (!empty($modSettings['attachmentDirFileLimit']) && $modSettings['attachmentDirFileLimit'] * .95 < $context['dir_files'] && $modSettings['attachmentDirFileLimit'] > 500)) |
||
| 565 | { |
||
| 566 | require_once($sourcedir . '/Subs-Admin.php'); |
||
| 567 | emailAdmins('admin_attachments_full'); |
||
| 568 | updateSettings(array('attachment_full_notified' => 1)); |
||
| 569 | } |
||
| 570 | |||
| 571 | // // No room left.... What to do now??? |
||
| 572 | if (!empty($modSettings['attachmentDirFileLimit']) && $context['dir_files'] > $modSettings['attachmentDirFileLimit'] |
||
| 573 | || (!empty($modSettings['attachmentDirSizeLimit']) && $context['dir_size'] > $modSettings['attachmentDirSizeLimit'] * 1024)) |
||
| 574 | { |
||
| 575 | if (!empty($modSettings['automanage_attachments']) && $modSettings['automanage_attachments'] == 1) |
||
| 576 | { |
||
| 577 | // Move it to the new folder if we can. |
||
| 578 | if (automanage_attachments_by_space()) |
||
| 579 | { |
||
| 580 | rename($_SESSION['temp_attachments'][$attachID]['tmp_name'], $context['attach_dir'] . '/' . $attachID); |
||
| 581 | $_SESSION['temp_attachments'][$attachID]['tmp_name'] = $context['attach_dir'] . '/' . $attachID; |
||
| 582 | $_SESSION['temp_attachments'][$attachID]['id_folder'] = $modSettings['currentAttachmentUploadDir']; |
||
| 583 | $context['dir_size'] = 0; |
||
| 584 | $context['dir_files'] = 0; |
||
| 585 | } |
||
| 586 | // Or, let the user know that it ain't gonna happen. |
||
| 587 | else |
||
| 588 | { |
||
| 589 | if (isset($context['dir_creation_error'])) |
||
| 590 | $_SESSION['temp_attachments'][$attachID]['errors'][] = $context['dir_creation_error']; |
||
| 591 | else |
||
| 592 | $_SESSION['temp_attachments'][$attachID]['errors'][] = 'ran_out_of_space'; |
||
| 593 | } |
||
| 594 | } |
||
| 595 | else |
||
| 596 | $_SESSION['temp_attachments'][$attachID]['errors'][] = 'ran_out_of_space'; |
||
| 597 | } |
||
| 598 | } |
||
| 599 | |||
| 600 | // Is the file too big? |
||
| 601 | $context['attachments']['total_size'] += $_SESSION['temp_attachments'][$attachID]['size']; |
||
| 602 | View Code Duplication | if (!empty($modSettings['attachmentSizeLimit']) && $_SESSION['temp_attachments'][$attachID]['size'] > $modSettings['attachmentSizeLimit'] * 1024) |
|
| 603 | $_SESSION['temp_attachments'][$attachID]['errors'][] = array('file_too_big', array(comma_format($modSettings['attachmentSizeLimit'], 0))); |
||
| 604 | |||
| 605 | // Check the total upload size for this post... |
||
| 606 | if (!empty($modSettings['attachmentPostLimit']) && $context['attachments']['total_size'] > $modSettings['attachmentPostLimit'] * 1024) |
||
| 607 | $_SESSION['temp_attachments'][$attachID]['errors'][] = array('attach_max_total_file_size', array(comma_format($modSettings['attachmentPostLimit'], 0), comma_format($modSettings['attachmentPostLimit'] - (($context['attachments']['total_size'] - $_SESSION['temp_attachments'][$attachID]['size']) / 1024), 0))); |
||
| 608 | |||
| 609 | // Have we reached the maximum number of files we are allowed? |
||
| 610 | $context['attachments']['quantity']++; |
||
| 611 | |||
| 612 | // Set a max limit if none exists |
||
| 613 | if (empty($modSettings['attachmentNumPerPostLimit']) && $context['attachments']['quantity'] >= 50) |
||
| 614 | $modSettings['attachmentNumPerPostLimit'] = 50; |
||
| 615 | |||
| 616 | View Code Duplication | if (!empty($modSettings['attachmentNumPerPostLimit']) && $context['attachments']['quantity'] > $modSettings['attachmentNumPerPostLimit']) |
|
| 617 | $_SESSION['temp_attachments'][$attachID]['errors'][] = array('attachments_limit_per_post', array($modSettings['attachmentNumPerPostLimit'])); |
||
| 618 | |||
| 619 | // File extension check |
||
| 620 | if (!empty($modSettings['attachmentCheckExtensions'])) |
||
| 621 | { |
||
| 622 | $allowed = explode(',', strtolower($modSettings['attachmentExtensions'])); |
||
| 623 | foreach ($allowed as $k => $dummy) |
||
| 624 | $allowed[$k] = trim($dummy); |
||
| 625 | |||
| 626 | if (!in_array(strtolower(substr(strrchr($_SESSION['temp_attachments'][$attachID]['name'], '.'), 1)), $allowed)) |
||
| 627 | { |
||
| 628 | $allowed_extensions = strtr(strtolower($modSettings['attachmentExtensions']), array(',' => ', ')); |
||
| 629 | $_SESSION['temp_attachments'][$attachID]['errors'][] = array('cant_upload_type', array($allowed_extensions)); |
||
| 630 | } |
||
| 631 | } |
||
| 632 | |||
| 633 | // Undo the math if there's an error |
||
| 634 | if (!empty($_SESSION['temp_attachments'][$attachID]['errors'])) |
||
| 635 | { |
||
| 636 | if (isset($context['dir_size'])) |
||
| 637 | $context['dir_size'] -= $_SESSION['temp_attachments'][$attachID]['size']; |
||
| 638 | if (isset($context['dir_files'])) |
||
| 639 | $context['dir_files']--; |
||
| 640 | $context['attachments']['total_size'] -= $_SESSION['temp_attachments'][$attachID]['size']; |
||
| 641 | $context['attachments']['quantity']--; |
||
| 642 | return false; |
||
| 643 | } |
||
| 644 | |||
| 645 | return true; |
||
| 646 | } |
||
| 647 | |||
| 648 | /** |
||
| 649 | * Create an attachment, with the given array of parameters. |
||
| 650 | * - Adds any additional or missing parameters to $attachmentOptions. |
||
| 651 | * - Renames the temporary file. |
||
| 652 | * - Creates a thumbnail if the file is an image and the option enabled. |
||
| 653 | * |
||
| 654 | * @param array $attachmentOptions An array of attachment options |
||
| 655 | * @return bool Whether the attachment was created successfully |
||
| 656 | */ |
||
| 657 | function createAttachment(&$attachmentOptions) |
||
| 658 | { |
||
| 659 | global $modSettings, $sourcedir, $smcFunc, $context, $txt; |
||
| 660 | |||
| 661 | require_once($sourcedir . '/Subs-Graphics.php'); |
||
| 662 | |||
| 663 | // If this is an image we need to set a few additional parameters. |
||
| 664 | $size = @getimagesize($attachmentOptions['tmp_name']); |
||
| 665 | list ($attachmentOptions['width'], $attachmentOptions['height']) = $size; |
||
| 666 | |||
| 667 | // If it's an image get the mime type right. |
||
| 668 | if (empty($attachmentOptions['mime_type']) && $attachmentOptions['width']) |
||
| 669 | { |
||
| 670 | // Got a proper mime type? |
||
| 671 | View Code Duplication | if (!empty($size['mime'])) |
|
| 672 | $attachmentOptions['mime_type'] = $size['mime']; |
||
| 673 | |||
| 674 | // Otherwise a valid one? |
||
| 675 | elseif (isset($context['validImageTypes'][$size[2]])) |
||
| 676 | $attachmentOptions['mime_type'] = 'image/' . $context['validImageTypes'][$size[2]]; |
||
| 677 | } |
||
| 678 | |||
| 679 | // It is possible we might have a MIME type that isn't actually an image but still have a size. |
||
| 680 | // For example, Shockwave files will be able to return size but be 'application/shockwave' or similar. |
||
| 681 | if (!empty($attachmentOptions['mime_type']) && strpos($attachmentOptions['mime_type'], 'image/') !== 0) |
||
| 682 | { |
||
| 683 | $attachmentOptions['width'] = 0; |
||
| 684 | $attachmentOptions['height'] = 0; |
||
| 685 | } |
||
| 686 | |||
| 687 | // Get the hash if no hash has been given yet. |
||
| 688 | if (empty($attachmentOptions['file_hash'])) |
||
| 689 | $attachmentOptions['file_hash'] = getAttachmentFilename($attachmentOptions['name'], false, null, true); |
||
| 690 | |||
| 691 | // Assuming no-one set the extension let's take a look at it. |
||
| 692 | if (empty($attachmentOptions['fileext'])) |
||
| 693 | { |
||
| 694 | $attachmentOptions['fileext'] = strtolower(strrpos($attachmentOptions['name'], '.') !== false ? substr($attachmentOptions['name'], strrpos($attachmentOptions['name'], '.') + 1) : ''); |
||
| 695 | if (strlen($attachmentOptions['fileext']) > 8 || '.' . $attachmentOptions['fileext'] == $attachmentOptions['name']) |
||
| 696 | $attachmentOptions['fileext'] = ''; |
||
| 697 | } |
||
| 698 | |||
| 699 | // Last chance to change stuff! |
||
| 700 | call_integration_hook('integrate_createAttachment', array(&$attachmentOptions)); |
||
| 701 | |||
| 702 | // Make sure the folder is valid... |
||
| 703 | $tmp = is_array($modSettings['attachmentUploadDir']) ? $modSettings['attachmentUploadDir'] : $smcFunc['json_decode']($modSettings['attachmentUploadDir'], true); |
||
| 704 | $folders = array_keys($tmp); |
||
| 705 | if (empty($attachmentOptions['id_folder']) || !in_array($attachmentOptions['id_folder'], $folders)) |
||
| 706 | $attachmentOptions['id_folder'] = $modSettings['currentAttachmentUploadDir']; |
||
| 707 | |||
| 708 | $attachmentOptions['id'] = $smcFunc['db_insert']('', |
||
| 709 | '{db_prefix}attachments', |
||
| 710 | array( |
||
| 711 | 'id_folder' => 'int', 'id_msg' => 'int', 'filename' => 'string-255', 'file_hash' => 'string-40', 'fileext' => 'string-8', |
||
| 712 | 'size' => 'int', 'width' => 'int', 'height' => 'int', |
||
| 713 | 'mime_type' => 'string-20', 'approved' => 'int', |
||
| 714 | ), |
||
| 715 | array( |
||
| 716 | (int) $attachmentOptions['id_folder'], (int) $attachmentOptions['post'], $attachmentOptions['name'], $attachmentOptions['file_hash'], $attachmentOptions['fileext'], |
||
| 717 | (int) $attachmentOptions['size'], (empty($attachmentOptions['width']) ? 0 : (int) $attachmentOptions['width']), (empty($attachmentOptions['height']) ? '0' : (int) $attachmentOptions['height']), |
||
| 718 | (!empty($attachmentOptions['mime_type']) ? $attachmentOptions['mime_type'] : ''), (int) $attachmentOptions['approved'], |
||
| 719 | ), |
||
| 720 | array('id_attach'), |
||
| 721 | 1 |
||
| 722 | ); |
||
| 723 | |||
| 724 | // Attachment couldn't be created. |
||
| 725 | if (empty($attachmentOptions['id'])) |
||
| 726 | { |
||
| 727 | loadLanguage('Errors'); |
||
| 728 | log_error($txt['attachment_not_created'], 'general'); |
||
| 729 | return false; |
||
| 730 | } |
||
| 731 | |||
| 732 | // Now that we have the attach id, let's rename this sucker and finish up. |
||
| 733 | $attachmentOptions['destination'] = getAttachmentFilename(basename($attachmentOptions['name']), $attachmentOptions['id'], $attachmentOptions['id_folder'], false, $attachmentOptions['file_hash']); |
||
| 734 | rename($attachmentOptions['tmp_name'], $attachmentOptions['destination']); |
||
| 735 | |||
| 736 | // If it's not approved then add to the approval queue. |
||
| 737 | if (!$attachmentOptions['approved']) |
||
| 738 | $smcFunc['db_insert']('', |
||
| 739 | '{db_prefix}approval_queue', |
||
| 740 | array( |
||
| 741 | 'id_attach' => 'int', 'id_msg' => 'int', |
||
| 742 | ), |
||
| 743 | array( |
||
| 744 | $attachmentOptions['id'], (int) $attachmentOptions['post'], |
||
| 745 | ), |
||
| 746 | array() |
||
| 747 | ); |
||
| 748 | |||
| 749 | if (empty($modSettings['attachmentThumbnails']) || (empty($attachmentOptions['width']) && empty($attachmentOptions['height']))) |
||
| 750 | return true; |
||
| 751 | |||
| 752 | // Like thumbnails, do we? |
||
| 753 | if (!empty($modSettings['attachmentThumbWidth']) && !empty($modSettings['attachmentThumbHeight']) && ($attachmentOptions['width'] > $modSettings['attachmentThumbWidth'] || $attachmentOptions['height'] > $modSettings['attachmentThumbHeight'])) |
||
| 754 | { |
||
| 755 | if (createThumbnail($attachmentOptions['destination'], $modSettings['attachmentThumbWidth'], $modSettings['attachmentThumbHeight'])) |
||
|
0 ignored issues
–
show
|
|||
| 756 | { |
||
| 757 | // Figure out how big we actually made it. |
||
| 758 | $size = @getimagesize($attachmentOptions['destination'] . '_thumb'); |
||
| 759 | list ($thumb_width, $thumb_height) = $size; |
||
| 760 | |||
| 761 | View Code Duplication | if (!empty($size['mime'])) |
|
| 762 | $thumb_mime = $size['mime']; |
||
| 763 | elseif (isset($context['validImageTypes'][$size[2]])) |
||
| 764 | $thumb_mime = 'image/' . $context['validImageTypes'][$size[2]]; |
||
| 765 | // Lord only knows how this happened... |
||
| 766 | else |
||
| 767 | $thumb_mime = ''; |
||
| 768 | |||
| 769 | $thumb_filename = $attachmentOptions['name'] . '_thumb'; |
||
| 770 | $thumb_size = filesize($attachmentOptions['destination'] . '_thumb'); |
||
| 771 | $thumb_file_hash = getAttachmentFilename($thumb_filename, false, null, true); |
||
| 772 | $thumb_path = $attachmentOptions['destination'] . '_thumb'; |
||
| 773 | |||
| 774 | // We should check the file size and count here since thumbs are added to the existing totals. |
||
| 775 | if (!empty($modSettings['automanage_attachments']) && $modSettings['automanage_attachments'] == 1 && !empty($modSettings['attachmentDirSizeLimit']) || !empty($modSettings['attachmentDirFileLimit'])) |
||
| 776 | { |
||
| 777 | $context['dir_size'] = isset($context['dir_size']) ? $context['dir_size'] += $thumb_size : $context['dir_size'] = 0; |
||
| 778 | $context['dir_files'] = isset($context['dir_files']) ? $context['dir_files']++ : $context['dir_files'] = 0; |
||
| 779 | |||
| 780 | // If the folder is full, try to create a new one and move the thumb to it. |
||
| 781 | if ($context['dir_size'] > $modSettings['attachmentDirSizeLimit'] * 1024 || $context['dir_files'] + 2 > $modSettings['attachmentDirFileLimit']) |
||
| 782 | { |
||
| 783 | if (automanage_attachments_by_space()) |
||
| 784 | { |
||
| 785 | rename($thumb_path, $context['attach_dir'] . '/' . $thumb_filename); |
||
| 786 | $thumb_path = $context['attach_dir'] . '/' . $thumb_filename; |
||
| 787 | $context['dir_size'] = 0; |
||
| 788 | $context['dir_files'] = 0; |
||
| 789 | } |
||
| 790 | } |
||
| 791 | } |
||
| 792 | // If a new folder has been already created. Gotta move this thumb there then. |
||
| 793 | if ($modSettings['currentAttachmentUploadDir'] != $attachmentOptions['id_folder']) |
||
| 794 | { |
||
| 795 | rename($thumb_path, $context['attach_dir'] . '/' . $thumb_filename); |
||
| 796 | $thumb_path = $context['attach_dir'] . '/' . $thumb_filename; |
||
| 797 | } |
||
| 798 | |||
| 799 | // To the database we go! |
||
| 800 | $attachmentOptions['thumb'] = $smcFunc['db_insert']('', |
||
| 801 | '{db_prefix}attachments', |
||
| 802 | array( |
||
| 803 | 'id_folder' => 'int', 'id_msg' => 'int', 'attachment_type' => 'int', 'filename' => 'string-255', 'file_hash' => 'string-40', 'fileext' => 'string-8', |
||
| 804 | 'size' => 'int', 'width' => 'int', 'height' => 'int', 'mime_type' => 'string-20', 'approved' => 'int', |
||
| 805 | ), |
||
| 806 | array( |
||
| 807 | $modSettings['currentAttachmentUploadDir'], (int) $attachmentOptions['post'], 3, $thumb_filename, $thumb_file_hash, $attachmentOptions['fileext'], |
||
| 808 | $thumb_size, $thumb_width, $thumb_height, $thumb_mime, (int) $attachmentOptions['approved'], |
||
| 809 | ), |
||
| 810 | array('id_attach'), |
||
| 811 | 1 |
||
| 812 | ); |
||
| 813 | |||
| 814 | if (!empty($attachmentOptions['thumb'])) |
||
| 815 | { |
||
| 816 | $smcFunc['db_query']('', ' |
||
| 817 | UPDATE {db_prefix}attachments |
||
| 818 | SET id_thumb = {int:id_thumb} |
||
| 819 | WHERE id_attach = {int:id_attach}', |
||
| 820 | array( |
||
| 821 | 'id_thumb' => $attachmentOptions['thumb'], |
||
| 822 | 'id_attach' => $attachmentOptions['id'], |
||
| 823 | ) |
||
| 824 | ); |
||
| 825 | |||
| 826 | rename($thumb_path, getAttachmentFilename($thumb_filename, $attachmentOptions['thumb'], $modSettings['currentAttachmentUploadDir'], false, $thumb_file_hash)); |
||
|
0 ignored issues
–
show
It seems like
$thumb_file_hash defined by getAttachmentFilename($t...ame, false, null, true) on line 771 can also be of type false; however, getAttachmentFilename() does only seem to accept string, did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new Loading history...
|
|||
| 827 | } |
||
| 828 | } |
||
| 829 | } |
||
| 830 | |||
| 831 | return true; |
||
| 832 | } |
||
| 833 | |||
| 834 | /** |
||
| 835 | * Assigns the given attachments to the given message ID. |
||
| 836 | * |
||
| 837 | * @param $attachIDs array of attachment IDs to assign. |
||
| 838 | * @param $msgID integer the message ID. |
||
| 839 | * |
||
| 840 | * @return boolean false on error or missing params. |
||
| 841 | */ |
||
| 842 | function assignAttachments($attachIDs = array(), $msgID = 0) |
||
| 843 | { |
||
| 844 | global $smcFunc; |
||
| 845 | |||
| 846 | // Oh, come on! |
||
| 847 | if (empty($attachIDs) || empty($msgID)) |
||
| 848 | return false; |
||
| 849 | |||
| 850 | // "I see what is right and approve, but I do what is wrong." |
||
| 851 | call_integration_hook('integrate_assign_attachments', array(&$attachIDs, &$msgID)); |
||
| 852 | |||
| 853 | // One last check |
||
| 854 | if (empty($attachIDs)) |
||
| 855 | return false; |
||
| 856 | |||
| 857 | // Perform. |
||
| 858 | $smcFunc['db_query']('', ' |
||
| 859 | UPDATE {db_prefix}attachments |
||
| 860 | SET id_msg = {int:id_msg} |
||
| 861 | WHERE id_attach IN ({array_int:attach_ids})', |
||
| 862 | array( |
||
| 863 | 'id_msg' => $msgID, |
||
| 864 | 'attach_ids' => $attachIDs, |
||
| 865 | ) |
||
| 866 | ); |
||
| 867 | |||
| 868 | return true; |
||
| 869 | } |
||
| 870 | |||
| 871 | /** |
||
| 872 | * Gets an attach ID and tries to load all its info. |
||
| 873 | * |
||
| 874 | * @param int $attachID the attachment ID to load info from. |
||
| 875 | * |
||
| 876 | * @return mixed If succesful, it will return an array of loaded data. String, most likely a $txt key if there was some error. |
||
| 877 | */ |
||
| 878 | function parseAttachBBC($attachID = 0) |
||
| 879 | { |
||
| 880 | global $board, $modSettings, $context, $scripturl, $smcFunc; |
||
| 881 | |||
| 882 | // Meh... |
||
| 883 | if (empty($attachID)) |
||
| 884 | return 'attachments_no_data_loaded'; |
||
| 885 | |||
| 886 | // Make it easy. |
||
| 887 | $msgID = !empty($_REQUEST['msg']) ? (int) $_REQUEST['msg'] : 0; |
||
| 888 | |||
| 889 | // Perhaps someone else wants to do the honors? Yes, this also includes dealing with previews ;) |
||
| 890 | $externalParse = call_integration_hook('integrate_pre_parseAttachBBC', array($attachID, $msgID)); |
||
| 891 | |||
| 892 | // "I am innocent of the blood of this just person: see ye to it." |
||
| 893 | if (!empty($externalParse) && (is_string($externalParse) || is_array($externalParse))) |
||
| 894 | return $externalParse; |
||
| 895 | |||
| 896 | //Are attachments enable? |
||
| 897 | if (empty($modSettings['attachmentEnable'])) |
||
| 898 | return 'attachments_not_enable'; |
||
| 899 | |||
| 900 | // Previewing much? no msg ID has been set yet. |
||
| 901 | if (!empty($context['preview_message'])) |
||
| 902 | { |
||
| 903 | $allAttachments = getAttachsByMsg(0); |
||
| 904 | |||
| 905 | if (empty($allAttachments[0][$attachID])) |
||
| 906 | return 'attachments_no_data_loaded'; |
||
| 907 | |||
| 908 | $attachLoaded = loadAttachmentContext(0, $allAttachments); |
||
| 909 | |||
| 910 | $attachContext = $attachLoaded[$attachID]; |
||
| 911 | |||
| 912 | // Fix the url to point out to showAvatar(). |
||
| 913 | $attachContext['href'] = $scripturl . '?action=dlattach;attach=' . $attachID . ';type=preview'; |
||
| 914 | |||
| 915 | $attachContext['link'] = '<a href="' . $scripturl . '?action=dlattach;attach=' . $attachID . ';type=preview' . (empty($attachContext['is_image']) ? ';file' : '') . '">' . $smcFunc['htmlspecialchars']($attachContext['name']) . '</a>'; |
||
| 916 | |||
| 917 | // Fix the thumbnail too, if the image has one. |
||
| 918 | if (!empty($attachContext['thumbnail']) && !empty($attachContext['thumbnail']['has_thumb'])) |
||
| 919 | $attachContext['thumbnail']['href'] = $scripturl . '?action=dlattach;attach=' . $attachContext['thumbnail']['id'] . ';image;type=preview'; |
||
| 920 | |||
| 921 | return $attachContext; |
||
| 922 | } |
||
| 923 | |||
| 924 | // There is always the chance someone else has already done our dirty work... |
||
| 925 | // If so, all pertinent checks were already done. Hopefully... |
||
| 926 | if (!empty($context['current_attachments']) && !empty($context['current_attachments'][$attachID])) |
||
| 927 | return $context['current_attachments'][$attachID]; |
||
| 928 | |||
| 929 | // If we are lucky enough to be in $board's scope then check it! |
||
| 930 | if (!empty($board) && !allowedTo('view_attachments', $board)) |
||
| 931 | return 'attachments_not_allowed_to_see'; |
||
| 932 | |||
| 933 | // Get the message info associated with this particular attach ID. |
||
| 934 | $attachInfo = getAttachMsgInfo($attachID); |
||
| 935 | |||
| 936 | // There is always the chance this attachment no longer exists or isn't associated to a message anymore... |
||
| 937 | if (empty($attachInfo) || empty($attachInfo['msg'])) |
||
| 938 | return 'attachments_no_msg_associated'; |
||
| 939 | |||
| 940 | // Hold it! got the info now check if you can see this attachment. |
||
| 941 | if (!allowedTo('view_attachments', $attachInfo['board'])) |
||
| 942 | return 'attachments_not_allowed_to_see'; |
||
| 943 | |||
| 944 | $allAttachments = getAttachsByMsg($attachInfo['msg']); |
||
| 945 | $attachContext = $allAttachments[$attachInfo['msg']][$attachID]; |
||
| 946 | |||
| 947 | // No point in keep going further. |
||
| 948 | if (!allowedTo('view_attachments', $attachContext['board'])) |
||
| 949 | return 'attachments_not_allowed_to_see'; |
||
| 950 | |||
| 951 | // Load this particular attach's context. |
||
| 952 | if (!empty($attachContext)) |
||
| 953 | $attachLoaded = loadAttachmentContext($attachContext['id_msg'], $allAttachments); |
||
| 954 | |||
| 955 | // One last check, you know, gotta be paranoid... |
||
| 956 | else |
||
| 957 | return 'attachments_no_data_loaded'; |
||
| 958 | |||
| 959 | // This is the last "if" I promise! |
||
| 960 | if (empty($attachLoaded)) |
||
| 961 | return 'attachments_no_data_loaded'; |
||
| 962 | |||
| 963 | else |
||
| 964 | $attachContext = $attachLoaded[$attachID]; |
||
| 965 | |||
| 966 | // You may or may not want to show this under the post. |
||
| 967 | if (!empty($modSettings['dont_show_attach_under_post']) && !isset($context['show_attach_under_post'][$attachID])) |
||
| 968 | $context['show_attach_under_post'][$attachID] = $attachID; |
||
| 969 | |||
| 970 | // Last minute changes? |
||
| 971 | call_integration_hook('integrate_post_parseAttachBBC', array(&$attachContext)); |
||
| 972 | |||
| 973 | // Don't do any logic with the loaded data, leave it to whoever called this function. |
||
| 974 | return $attachContext; |
||
| 975 | } |
||
| 976 | |||
| 977 | /** |
||
| 978 | * Gets raw info directly from the attachments table. |
||
| 979 | * |
||
| 980 | * @param array $attachIDs An array of attachments IDs. |
||
| 981 | * |
||
| 982 | * @return array. |
||
| 983 | */ |
||
| 984 | function getRawAttachInfo($attachIDs) |
||
| 985 | { |
||
| 986 | global $smcFunc, $modSettings; |
||
| 987 | |||
| 988 | if (empty($attachIDs)) |
||
| 989 | return array(); |
||
| 990 | |||
| 991 | $return = array(); |
||
| 992 | |||
| 993 | $request = $smcFunc['db_query']('', ' |
||
| 994 | SELECT a.id_attach, a.id_msg, a.id_member, a.size, a.mime_type, a.id_folder, a.filename' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ', |
||
| 995 | COALESCE(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . ' |
||
| 996 | FROM {db_prefix}attachments AS a' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ' |
||
| 997 | LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)') . ' |
||
| 998 | WHERE a.id_attach IN ({array_int:attach_ids}) |
||
| 999 | LIMIT 1', |
||
| 1000 | array( |
||
| 1001 | 'attach_ids' => (array) $attachIDs, |
||
| 1002 | ) |
||
| 1003 | ); |
||
| 1004 | |||
| 1005 | if ($smcFunc['db_num_rows']($request) != 1) |
||
| 1006 | return array(); |
||
| 1007 | |||
| 1008 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 1009 | $return[$row['id_attach']] = array( |
||
| 1010 | 'name' => $smcFunc['htmlspecialchars']($row['filename']), |
||
| 1011 | 'size' => $row['size'], |
||
| 1012 | 'attachID' => $row['id_attach'], |
||
| 1013 | 'unchecked' => false, |
||
| 1014 | 'approved' => 1, |
||
| 1015 | 'mime_type' => $row['mime_type'], |
||
| 1016 | 'thumb' => $row['id_thumb'], |
||
| 1017 | ); |
||
| 1018 | $smcFunc['db_free_result']($request); |
||
| 1019 | |||
| 1020 | return $return; |
||
| 1021 | } |
||
| 1022 | |||
| 1023 | /** |
||
| 1024 | * Gets all needed message data associated with an attach ID |
||
| 1025 | * |
||
| 1026 | * @param int $attachID the attachment ID to load info from. |
||
| 1027 | * |
||
| 1028 | * @return array. |
||
| 1029 | */ |
||
| 1030 | function getAttachMsgInfo($attachID) |
||
| 1031 | { |
||
| 1032 | global $smcFunc; |
||
| 1033 | |||
| 1034 | if (empty($attachID)) |
||
| 1035 | return array(); |
||
| 1036 | |||
| 1037 | $request = $smcFunc['db_query']('', ' |
||
| 1038 | SELECT a.id_msg AS msg, m.id_topic AS topic, m.id_board AS board |
||
| 1039 | FROM {db_prefix}attachments AS a |
||
| 1040 | LEFT JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg) |
||
| 1041 | WHERE id_attach = {int:id_attach} |
||
| 1042 | LIMIT 1', |
||
| 1043 | array( |
||
| 1044 | 'id_attach' => (int) $attachID, |
||
| 1045 | ) |
||
| 1046 | ); |
||
| 1047 | |||
| 1048 | if ($smcFunc['db_num_rows']($request) != 1) |
||
| 1049 | return array(); |
||
| 1050 | |||
| 1051 | $row = $smcFunc['db_fetch_assoc']($request); |
||
| 1052 | $smcFunc['db_free_result']($request); |
||
| 1053 | |||
| 1054 | return $row; |
||
| 1055 | } |
||
| 1056 | |||
| 1057 | /** |
||
| 1058 | * Gets attachment info associated with a message ID |
||
| 1059 | * |
||
| 1060 | * @param int $msgID the message ID to load info from. |
||
| 1061 | * |
||
| 1062 | * @return array. |
||
| 1063 | */ |
||
| 1064 | function getAttachsByMsg($msgID = 0) |
||
| 1065 | { |
||
| 1066 | global $modSettings, $smcFunc; |
||
| 1067 | static $attached = array(); |
||
| 1068 | |||
| 1069 | if (!isset($attached[$msgID])) |
||
| 1070 | { |
||
| 1071 | $request = $smcFunc['db_query']('', ' |
||
| 1072 | SELECT |
||
| 1073 | a.id_attach, a.id_folder, a.id_msg, a.filename, a.file_hash, COALESCE(a.size, 0) AS filesize, a.downloads, a.approved, m.id_topic AS topic, m.id_board AS board, |
||
| 1074 | a.width, a.height' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ', |
||
| 1075 | COALESCE(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . ' |
||
| 1076 | FROM {db_prefix}attachments AS a' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ' |
||
| 1077 | LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)') . ' |
||
| 1078 | LEFT JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg) |
||
| 1079 | WHERE a.attachment_type = {int:attachment_type} |
||
| 1080 | '. (!empty($msgID) ? 'AND a.id_msg = {int:message_id}' : '') . '', |
||
| 1081 | array( |
||
| 1082 | 'message_id' => $msgID, |
||
| 1083 | 'attachment_type' => 0, |
||
| 1084 | 'is_approved' => 1, |
||
| 1085 | ) |
||
| 1086 | ); |
||
| 1087 | $temp = array(); |
||
| 1088 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 1089 | { |
||
| 1090 | View Code Duplication | if (!$row['approved'] && $modSettings['postmod_active'] && !allowedTo('approve_posts') && (!isset($all_posters[$row['id_msg']]) || $all_posters[$row['id_msg']] != $user_info['id'])) |
|
|
0 ignored issues
–
show
The variable
$all_posters does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
Loading history...
|
|||
| 1091 | continue; |
||
| 1092 | |||
| 1093 | $temp[$row['id_attach']] = $row; |
||
| 1094 | } |
||
| 1095 | $smcFunc['db_free_result']($request); |
||
| 1096 | |||
| 1097 | // This is better than sorting it with the query... |
||
| 1098 | ksort($temp); |
||
| 1099 | |||
| 1100 | $attached[$msgID] = $temp; |
||
| 1101 | } |
||
| 1102 | |||
| 1103 | return $attached; |
||
| 1104 | } |
||
| 1105 | |||
| 1106 | /** |
||
| 1107 | * This loads an attachment's contextual data including, most importantly, its size if it is an image. |
||
| 1108 | * It requires the view_attachments permission to calculate image size. |
||
| 1109 | * It attempts to keep the "aspect ratio" of the posted image in line, even if it has to be resized by |
||
| 1110 | * the max_image_width and max_image_height settings. |
||
| 1111 | * |
||
| 1112 | * @param int $id_msg ID of the post to load attachments for |
||
| 1113 | * @param array $attachments An array of already loaded attachments. This function no longer depends on having $topic declared, thus, you need to load the actual topic ID for each attachment. |
||
| 1114 | * @return array An array of attachment info |
||
| 1115 | */ |
||
| 1116 | function loadAttachmentContext($id_msg, $attachments) |
||
| 1117 | { |
||
| 1118 | global $modSettings, $txt, $scripturl, $sourcedir, $smcFunc; |
||
| 1119 | |||
| 1120 | if (empty($attachments) || empty($attachments[$id_msg])) |
||
| 1121 | return array(); |
||
| 1122 | |||
| 1123 | // Set up the attachment info - based on code by Meriadoc. |
||
| 1124 | $attachmentData = array(); |
||
| 1125 | $have_unapproved = false; |
||
| 1126 | if (isset($attachments[$id_msg]) && !empty($modSettings['attachmentEnable'])) |
||
| 1127 | { |
||
| 1128 | foreach ($attachments[$id_msg] as $i => $attachment) |
||
| 1129 | { |
||
| 1130 | $attachmentData[$i] = array( |
||
| 1131 | 'id' => $attachment['id_attach'], |
||
| 1132 | 'name' => preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', $smcFunc['htmlspecialchars']($attachment['filename'])), |
||
| 1133 | 'downloads' => $attachment['downloads'], |
||
| 1134 | 'size' => ($attachment['filesize'] < 1024000) ? round($attachment['filesize'] / 1024, 2) . ' ' . $txt['kilobyte'] : round($attachment['filesize'] / 1024 / 1024, 2) . ' ' . $txt['megabyte'], |
||
| 1135 | 'byte_size' => $attachment['filesize'], |
||
| 1136 | 'href' => $scripturl . '?action=dlattach;topic=' . $attachment['topic'] . '.0;attach=' . $attachment['id_attach'], |
||
| 1137 | 'link' => '<a href="' . $scripturl . '?action=dlattach;topic=' . $attachment['topic'] . '.0;attach=' . $attachment['id_attach'] . '">' . $smcFunc['htmlspecialchars']($attachment['filename']) . '</a>', |
||
| 1138 | 'is_image' => !empty($attachment['width']) && !empty($attachment['height']) && !empty($modSettings['attachmentShowImages']), |
||
| 1139 | 'is_approved' => $attachment['approved'], |
||
| 1140 | 'topic' => $attachment['topic'], |
||
| 1141 | 'board' => $attachment['board'], |
||
| 1142 | ); |
||
| 1143 | |||
| 1144 | // If something is unapproved we'll note it so we can sort them. |
||
| 1145 | if (!$attachment['approved']) |
||
| 1146 | $have_unapproved = true; |
||
| 1147 | |||
| 1148 | if (!$attachmentData[$i]['is_image']) |
||
| 1149 | continue; |
||
| 1150 | |||
| 1151 | $attachmentData[$i]['real_width'] = $attachment['width']; |
||
| 1152 | $attachmentData[$i]['width'] = $attachment['width']; |
||
| 1153 | $attachmentData[$i]['real_height'] = $attachment['height']; |
||
| 1154 | $attachmentData[$i]['height'] = $attachment['height']; |
||
| 1155 | |||
| 1156 | // Let's see, do we want thumbs? |
||
| 1157 | if (!empty($modSettings['attachmentThumbnails']) && !empty($modSettings['attachmentThumbWidth']) && !empty($modSettings['attachmentThumbHeight']) && ($attachment['width'] > $modSettings['attachmentThumbWidth'] || $attachment['height'] > $modSettings['attachmentThumbHeight']) && strlen($attachment['filename']) < 249) |
||
| 1158 | { |
||
| 1159 | // A proper thumb doesn't exist yet? Create one! |
||
| 1160 | if (empty($attachment['id_thumb']) || $attachment['thumb_width'] > $modSettings['attachmentThumbWidth'] || $attachment['thumb_height'] > $modSettings['attachmentThumbHeight'] || ($attachment['thumb_width'] < $modSettings['attachmentThumbWidth'] && $attachment['thumb_height'] < $modSettings['attachmentThumbHeight'])) |
||
| 1161 | { |
||
| 1162 | $filename = getAttachmentFilename($attachment['filename'], $attachment['id_attach'], $attachment['id_folder']); |
||
| 1163 | |||
| 1164 | require_once($sourcedir . '/Subs-Graphics.php'); |
||
| 1165 | if (createThumbnail($filename, $modSettings['attachmentThumbWidth'], $modSettings['attachmentThumbHeight'])) |
||
|
0 ignored issues
–
show
It seems like
$filename defined by getAttachmentFilename($a...ttachment['id_folder']) on line 1162 can also be of type false; however, createThumbnail() does only seem to accept string, did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new Loading history...
|
|||
| 1166 | { |
||
| 1167 | // So what folder are we putting this image in? |
||
| 1168 | View Code Duplication | if (!empty($modSettings['currentAttachmentUploadDir'])) |
|
| 1169 | { |
||
| 1170 | if (!is_array($modSettings['attachmentUploadDir'])) |
||
| 1171 | $modSettings['attachmentUploadDir'] = $smcFunc['json_decode']($modSettings['attachmentUploadDir'], true); |
||
| 1172 | $id_folder_thumb = $modSettings['currentAttachmentUploadDir']; |
||
| 1173 | } |
||
| 1174 | else |
||
| 1175 | { |
||
| 1176 | $id_folder_thumb = 1; |
||
| 1177 | } |
||
| 1178 | |||
| 1179 | // Calculate the size of the created thumbnail. |
||
| 1180 | $size = @getimagesize($filename . '_thumb'); |
||
| 1181 | list ($attachment['thumb_width'], $attachment['thumb_height']) = $size; |
||
| 1182 | $thumb_size = filesize($filename . '_thumb'); |
||
| 1183 | |||
| 1184 | // What about the extension? |
||
| 1185 | $thumb_ext = isset($context['validImageTypes'][$size[2]]) ? $context['validImageTypes'][$size[2]] : ''; |
||
| 1186 | |||
| 1187 | // Figure out the mime type. |
||
| 1188 | if (!empty($size['mime'])) |
||
| 1189 | $thumb_mime = $size['mime']; |
||
| 1190 | else |
||
| 1191 | $thumb_mime = 'image/' . $thumb_ext; |
||
| 1192 | |||
| 1193 | $thumb_filename = $attachment['filename'] . '_thumb'; |
||
| 1194 | $thumb_hash = getAttachmentFilename($thumb_filename, false, null, true); |
||
| 1195 | |||
| 1196 | // Add this beauty to the database. |
||
| 1197 | $attachment['id_thumb'] = $smcFunc['db_insert']('', |
||
| 1198 | '{db_prefix}attachments', |
||
| 1199 | array('id_folder' => 'int', 'id_msg' => 'int', 'attachment_type' => 'int', 'filename' => 'string', 'file_hash' => 'string', 'size' => 'int', 'width' => 'int', 'height' => 'int', 'fileext' => 'string', 'mime_type' => 'string'), |
||
| 1200 | array($id_folder_thumb, $id_msg, 3, $thumb_filename, $thumb_hash, (int) $thumb_size, (int) $attachment['thumb_width'], (int) $attachment['thumb_height'], $thumb_ext, $thumb_mime), |
||
| 1201 | array('id_attach'), |
||
| 1202 | 1 |
||
| 1203 | ); |
||
| 1204 | $old_id_thumb = $attachment['id_thumb']; |
||
| 1205 | if (!empty($attachment['id_thumb'])) |
||
| 1206 | { |
||
| 1207 | $smcFunc['db_query']('', ' |
||
| 1208 | UPDATE {db_prefix}attachments |
||
| 1209 | SET id_thumb = {int:id_thumb} |
||
| 1210 | WHERE id_attach = {int:id_attach}', |
||
| 1211 | array( |
||
| 1212 | 'id_thumb' => $attachment['id_thumb'], |
||
| 1213 | 'id_attach' => $attachment['id_attach'], |
||
| 1214 | ) |
||
| 1215 | ); |
||
| 1216 | |||
| 1217 | $thumb_realname = getAttachmentFilename($thumb_filename, $attachment['id_thumb'], $id_folder_thumb, false, $thumb_hash); |
||
|
0 ignored issues
–
show
It seems like
$thumb_hash defined by getAttachmentFilename($t...ame, false, null, true) on line 1194 can also be of type false; however, getAttachmentFilename() does only seem to accept string, did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new Loading history...
|
|||
| 1218 | rename($filename . '_thumb', $thumb_realname); |
||
| 1219 | |||
| 1220 | // Do we need to remove an old thumbnail? |
||
| 1221 | if (!empty($old_id_thumb)) |
||
| 1222 | { |
||
| 1223 | require_once($sourcedir . '/ManageAttachments.php'); |
||
| 1224 | removeAttachments(array('id_attach' => $old_id_thumb), '', false, false); |
||
| 1225 | } |
||
| 1226 | } |
||
| 1227 | } |
||
| 1228 | } |
||
| 1229 | |||
| 1230 | // Only adjust dimensions on successful thumbnail creation. |
||
| 1231 | if (!empty($attachment['thumb_width']) && !empty($attachment['thumb_height'])) |
||
| 1232 | { |
||
| 1233 | $attachmentData[$i]['width'] = $attachment['thumb_width']; |
||
| 1234 | $attachmentData[$i]['height'] = $attachment['thumb_height']; |
||
| 1235 | } |
||
| 1236 | } |
||
| 1237 | |||
| 1238 | if (!empty($attachment['id_thumb'])) |
||
| 1239 | $attachmentData[$i]['thumbnail'] = array( |
||
| 1240 | 'id' => $attachment['id_thumb'], |
||
| 1241 | 'href' => $scripturl . '?action=dlattach;topic=' . $attachment['topic'] . '.0;attach=' . $attachment['id_thumb'] . ';image', |
||
| 1242 | ); |
||
| 1243 | $attachmentData[$i]['thumbnail']['has_thumb'] = !empty($attachment['id_thumb']); |
||
| 1244 | |||
| 1245 | // If thumbnails are disabled, check the maximum size of the image. |
||
| 1246 | if (!$attachmentData[$i]['thumbnail']['has_thumb'] && ((!empty($modSettings['max_image_width']) && $attachment['width'] > $modSettings['max_image_width']) || (!empty($modSettings['max_image_height']) && $attachment['height'] > $modSettings['max_image_height']))) |
||
| 1247 | { |
||
| 1248 | if (!empty($modSettings['max_image_width']) && (empty($modSettings['max_image_height']) || $attachment['height'] * $modSettings['max_image_width'] / $attachment['width'] <= $modSettings['max_image_height'])) |
||
| 1249 | { |
||
| 1250 | $attachmentData[$i]['width'] = $modSettings['max_image_width']; |
||
| 1251 | $attachmentData[$i]['height'] = floor($attachment['height'] * $modSettings['max_image_width'] / $attachment['width']); |
||
| 1252 | } |
||
| 1253 | View Code Duplication | elseif (!empty($modSettings['max_image_width'])) |
|
| 1254 | { |
||
| 1255 | $attachmentData[$i]['width'] = floor($attachment['width'] * $modSettings['max_image_height'] / $attachment['height']); |
||
| 1256 | $attachmentData[$i]['height'] = $modSettings['max_image_height']; |
||
| 1257 | } |
||
| 1258 | } |
||
| 1259 | elseif ($attachmentData[$i]['thumbnail']['has_thumb']) |
||
| 1260 | { |
||
| 1261 | // If the image is too large to show inline, make it a popup. |
||
| 1262 | if (((!empty($modSettings['max_image_width']) && $attachmentData[$i]['real_width'] > $modSettings['max_image_width']) || (!empty($modSettings['max_image_height']) && $attachmentData[$i]['real_height'] > $modSettings['max_image_height']))) |
||
| 1263 | $attachmentData[$i]['thumbnail']['javascript'] = 'return reqWin(\'' . $attachmentData[$i]['href'] . ';image\', ' . ($attachment['width'] + 20) . ', ' . ($attachment['height'] + 20) . ', true);'; |
||
| 1264 | else |
||
| 1265 | $attachmentData[$i]['thumbnail']['javascript'] = 'return expandThumb(' . $attachment['id_attach'] . ');'; |
||
| 1266 | } |
||
| 1267 | |||
| 1268 | if (!$attachmentData[$i]['thumbnail']['has_thumb']) |
||
| 1269 | $attachmentData[$i]['downloads']++; |
||
| 1270 | } |
||
| 1271 | } |
||
| 1272 | |||
| 1273 | // Do we need to instigate a sort? |
||
| 1274 | if ($have_unapproved) |
||
| 1275 | usort($attachmentData, 'approved_attach_sort'); |
||
| 1276 | |||
| 1277 | return $attachmentData; |
||
| 1278 | } |
||
| 1279 | |||
| 1280 | ?> |
If you define a variable conditionally, it can happen that it is not defined for all execution paths.
Let’s take a look at an example:
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.
Available Fixes
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: