File Upload
<?php
/**
* ------------------------
* Handle Uploaded File
* ------------------------
* This file take a posted $_FILE and save it to an uploads directory.
* It will put it into a folder based on the user's Miva basket-id cookie.
* It will return JSON describing the result/status of the upload and paths to the uploaded file
*/
/**
* Constants
*/
// Store Settings
define('STORE_CODE', 'ABC');
define('STORE_BASKET_SESSION_ID', $_COOKIE['mm5-'.STORE_CODE.'-basket-id']);
define('STORE_EMAIL', 'contact@example.com');
// Upload Path
define('UPLOAD_FOLDER', 'uploads/');
define('DESTINATION_FOLDER', UPLOAD_FOLDER.STORE_BASKET_SESSION_ID.'/');
define('URL_BASE', $_SERVER['HTTP_ORIGIN'].dirname($_SERVER['SCRIPT_NAME']).'/' );
// File Size Helpers
define('KB', 1024);
define('MB', 1048576);
define('GB', 1073741824);
define('TB', 1099511627776);
/**
* Functions
*/
function is_valid_md5($md5 ='') {
return strlen($md5) == 32 && ctype_xdigit($md5);
}
function slugify($string)
{
return str_replace('’', '', strtolower(preg_replace('/[^A-Za-z0-9-_]+/', '-', trim($string))));
}
function make_upload_directory(){
if( !is_dir(DESTINATION_FOLDER) ){
if( !mkdir(DESTINATION_FOLDER) ) {
throw new RuntimeException('Error: Could not make upload directory. '.DESTINATION_FOLDER);
}
chmod(DESTINATION_FOLDER, 0775);
}
}
/**
* Main Upload Process
*/
header('Content-Type: application/json; charset=utf-8');
try
{
// Validate Session & Basket ID Cookie Value
if( !is_valid_md5(STORE_BASKET_SESSION_ID) )
{
throw new RuntimeException('Error: Invalid session.');
}
// Undefined | Multiple Files | $_FILES Corruption Attack
// If this request falls under any of them, treat it invalid.
if ( !isset($_FILES['file']['error']) || is_array($_FILES['file']['error']) ) {
throw new RuntimeException('Error: Invalid parameters.');
}
// Check $_FILES['file']['error'] value.
switch ($_FILES['file']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('Error: No file sent.');
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('Error: Exceeded filesize limit.');
default:
throw new RuntimeException('Error: Unknown errors.');
}
// You should also check filesize here.
if ($_FILES['file']['size'] > 5*MB) {
throw new RuntimeException('Uploaded file exceeded file-size limit. Please contact '.STORE_EMAIL.' for assistance if the issue persists.');
}
// DO NOT TRUST $_FILES['file']['mime'] VALUE
// Check MIME Type by yourself.
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (false === $ext = array_search(
$finfo->file($_FILES['file']['tmp_name']),
array(
'gif' => 'image/gif',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'png' => 'image/png'
// 'ai' => 'application/illustrator',
// 'bmp' => 'image/bmp',
// 'eps' => 'application/postscript',
// 'pdf' => 'application/pdf',
// 'tiff' => 'image/tiff'
),
true
)) {
throw new RuntimeException('Uplodated file-type format is not allowed. Please only upload: gif, jpeg, or png files. Please contact '.STORE_EMAIL.' for assistance if the issue persists.');
}
// You should name it uniquely too.
// DO NOT USE $_FILES['file']['name'] WITHOUT ANY VALIDATION !!
// $safe_filename = 'upload_'.md5($_FILES['file']['name']).'.'.$ext;
$safe_filename = 'upload_'.date('Y-m-d_H-i-s').'.'.$ext;
$destination_file = DESTINATION_FOLDER.$safe_filename;
$destination_url = URL_BASE.$destination_file;
make_upload_directory();
if (move_uploaded_file($_FILES['file']['tmp_name'], $destination_file) ) {
chmod($destination_file, 0775);
$result = array(
'uploaded' => true,
'message' => 'success',
'description' => 'File successfully uploaded!',
'file' => $destination_file,
'url' => $destination_url
);
echo json_encode($result);
} else {
throw new RuntimeException('Error: Failed to move uploaded file. Please contact '.STORE_EMAIL.' for assistance if the issue persists.');
}
}
catch (RuntimeException $e)
{
// Error Message Display
$result = array(
'uploaded' => false,
'message' => 'error',
'description' => $e->getMessage()
);
echo json_encode($result);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Uploader</title>
</head>
<body>
<form action="upload.php" method="POST" enctype="multipart/form-data">
File to Upload: <input type="file" name="file">
<button>Submit</button>
</form>
</body>
</html>