"Method not accepted.")); exit(); } $database = new Database(); $db = $database->getConnection(); $auth = new Authenticator($db); $userId = $auth->authenticate(); // Check the image sharing is already enabled $settings = json_decode(file_get_contents(SETTINGS_STATIC_JSON_PATH)); if (!$settings->photoSharingEnabled) { // Sharing not yet enabled: check the user is an Admin $stmt = User::get($db, $userId); $user = $stmt->fetch(PDO::FETCH_ASSOC); if (!$user || !array_key_exists('admin', $user)) throw new Exception('unable to determine if user ' . $userId . ' is an admin'); if (!$user['admin']) { http_response_code(403); echo json_encode(array("error" => "User doesn't have permission to publish an image")); exit(); } } try { // Undefined | Multiple Files | $_FILES Corruption Attack // If this request falls under any of them, treat it invalid. if ( !isset($_FILES['image']['error']) || is_array($_FILES['image']['error']) ) { throw new InvalidArgumentException('Invalid parameters.'); } // Check $_FILES['image']['error'] value. switch ($_FILES['image']['error']) { case UPLOAD_ERR_OK: break; case UPLOAD_ERR_NO_FILE: throw new RuntimeException('No file sent.'); case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: throw new RuntimeException('Exceeded filesize limit.'); default: throw new RuntimeException('Unknown errors.'); } // DO NOT TRUST $_FILES['image']['mime'] VALUE !! // Check MIME Type by yourself. $finfo = new finfo(FILEINFO_MIME_TYPE); if (false === $ext = array_search( $finfo->file($_FILES['image']['tmp_name']), array( 'jpg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif', ), true )) { throw new RuntimeException('Invalid file format.'); } // Create upload directory (if not exists) $dir = GALLERY_UPLOAD_PATH; $dirRelPath = '../../' . $dir; // create new directory with 744 permissions if it does not exist yet // owner will be the user/group the PHP script is run under if ( !file_exists($dirRelPath) ) { if (!mkdir ($dirRelPath, 0744)) { throw new RuntimeException('Unable to create uploads folder: '.$dirRelPath); } } if ( !file_exists($_FILES['image']['tmp_name'])) { throw new RuntimeException('Failed not present in temp folder: '.$_FILES['image']['tmp_name']); } // Save original image $destFileName = sha1_file($_FILES['image']['tmp_name']); $destPath = sprintf('%s/%s.%s', $dirRelPath, $destFileName, $ext ); if (!move_uploaded_file( $_FILES['image']['tmp_name'], $destPath )) { throw new RuntimeException('Failed to move uploaded file to '.$destPath); } // Create distribution image $distDestPath = sprintf('%s/%s_dist.%s', $dirRelPath, $destFileName, $ext ); $retCodeThumb = exec('convert "'.$destPath.'" -auto-orient -resize '.GALLERY_ITEM_SIZE_DIST.'x'.GALLERY_ITEM_SIZE_DIST.' -quality 80 "'.$distDestPath.'"'); if ($retCodeThumb) throw new RuntimeException("Unable to create distribution image"); // Create thumb $thumbDestPath = sprintf('%s/%s_thumb.%s', $dirRelPath, $destFileName, $ext ); $retCodeThumb = exec('convert "'.$destPath.'" -auto-orient -resize '.GALLERY_ITEM_SIZE_THUMB.'x'.GALLERY_ITEM_SIZE_THUMB.' -quality 80 "'.$thumbDestPath.'"'); if ($retCodeThumb) throw new RuntimeException("Unable to create thumbnail"); // Create gallery item with uploaded photo (only dist and thumb paths are saved to db) $gi = []; $gi['imageUrl'] = sprintf('/%s/%s_dist.%s', $dir, $destFileName, $ext ); $gi['imageThumbUrl'] = sprintf('/%s/%s_thumb.%s', $dir, $destFileName, $ext ); $gi['likes ']= 0; $gi['description'] = ""; // TODO $gi['author'] = $userId; $db->beginTransaction(); if (!GalleryItem::create($db, $gi)){ throw new RuntimeException("Unable to create GalleryItem."); } // Retrieve inserted item $newGiId = $database->conn->lastInsertId(); $stmt = GalleryItem::readById($db, $userId, $newGiId); $row = $stmt->fetch(PDO::FETCH_ASSOC); if (!$row) throw new RuntimeException('Inserted row could not be found!'); $result=array( "success" => TRUE, "errorMessage" => "", "filename" => $destFileName, "filepath" => $destPath, "record" => GalleryItem::fromRow($row) ); $db->commit(); // set response code - 200 OK http_response_code(200); // show products data in json format echo json_encode($result); } catch (RuntimeException $e) { $err_item=array( "success" => FALSE, "errorMessage" => $e->getMessage(), "filename" => "", "filepath" => "", ); echo json_encode($err_item); } ?>