<?php
define('MAX_FILE_SIZE_UPLOAD', 10000000); // 10Mb
header('Content-Type: application/json');
// Make sure file is not cached (as it happens for example on iOS devices)
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
function validationFail($result, $title = 'Invalid request.', $code = 400) {
header('HTTP/1.1 '.$code.' '.$title);
echo(json_encode(array(
'success' => false,
'result' => $result,
'error' => $title
)));
exit();
}
// We make sure no error occured
if (empty($_FILES['file']) || intval($_FILES['file']['error']) > 0) {
validationFail('bad_request', 'An error occured.');
}
// We only allow CSV files. Of course, you can adapt this to your need
if ($_FILES['file']['type'] !== 'text/csv') {
@unlink($_FILES['file']['tmp_name']);
validationFail('bad_request', 'Please upload a CSV file.');
}
$tmpName = $_FILES['file']['tmp_name'];
$tmpDirectory = ini_get('upload_tmp_dir') ? ini_get('upload_tmp_dir') : sys_get_temp_dir();
// Security verification
if (!is_uploaded_file($tmpName)) {
validationFail('bad_request', 'An error occured.');
}
// We start a session.
// This is required in order to track the sender of a file (not mix request)
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
if (isset($_SERVER['HTTP_CONTENT_RANGE']) && !empty($_SERVER['HTTP_CONTENT_RANGE']) && isset($_SERVER['CONTENT_LENGTH']) && is_numeric($_SERVER['CONTENT_LENGTH'])) {
// We get the size of the file uploaded from the client (real, final size)
$filesize = intval(substr($_SERVER['HTTP_CONTENT_RANGE'], strpos($_SERVER['HTTP_CONTENT_RANGE'], '/') + 1));
if ($filesize > MAX_FILE_SIZE_UPLOAD) {
validationFail('bad_request', 'File size allowed must be lower than 10Mb.');
}
if (isset($_SESSION['filename']) && is_file($tmpDirectory.'/'.$_SESSION['filename'])) {
file_put_contents($tmpDirectory.'/'.$_SESSION['filename'], fopen($tmpName, 'r'), FILE_APPEND);
unlink($tmpName); // We delete the file once we copied it, in order to not use unecessary storage
// We stop here if the file is not completely loaded
$currentSize = filesize($tmpDirectory.'/'.$_SESSION['filename']);
if ($currentSize < $filesize) {
exit('{"size": '.$currentSize.'}');
} else {
$tmpName = $tmpDirectory.'/'.$_SESSION['filename'];
}
} else {
$_SESSION['filename'] = uniqid().'.csv.part';
move_uploaded_file($tmpName, $tmpDirectory.'/'.$_SESSION['filename']);
exit('{"size": '.filesize($tmpDirectory.'/'.$_SESSION['filename']).'}');
}
}
// The file has been completely uploaded.
// You can do whatever you want now
// Like moving the file, which is located in $tmpName
// Note: don't use move_uploaded_file because the chuncked part created a new file and this function will fail.
rename($tmpName, dirname(__FILE__).'/files/'.uniqid().'.csv');
exit('{"success": true}');