How do I modify this to upload multiple files? - php

My upload code is this. I submit the image to it with postdata. I want to make the file select box accept multiple picutes, and have it work on the backend. I can get the header location to work just fine on my own, but using an array of files has proved to be difficult, even though I've spent hours on stack overflow and google. I'd love it if somebody could show me how to do it.
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$browse = $_POST["browse"];
preg_match('/\.([a-zA-Z]+?)$/', $_FILES['userfile']['name'], $matches);
if(in_array(strtolower($matches[1]), $accepted)) {
if($_FILES['userfile']['size'] <= $maxsize) {
$newname = md5_file($_FILES['userfile']['tmp_name']).'.'.$matches[1];
$browse = $_POST["browse"];
if ($browse == "1") {
$filedir = 'img';
} else if ($browse == "2") {
$filedir = 'zega';
} else if ($browse == "3") {
$filedir = 'noimg';
} else if ($browse == "4") {
$filedir = 'adult';
} else if ($browse == "5") {
$filedir = 'temp';
} else {
$filedir = 'noimg';
}
move_uploaded_file($_FILES['userfile']['tmp_name'], $filedir.'/'.$newname);
$path = $filedir.'/'.$newname;
if (strpos($path,'jpg') !== false){
$img = imagecreatefromjpeg ($path);
imagejpeg ($img, $path, 100);
imagedestroy ($img);
} else if (strpos($path,'gif') !== false){
$img = imagecreatefromgif ($path);
imagegif ($img, $path, 100);
imagedestroy ($img);
} else if (strpos($path,'bmp') !== false){
$img = imagecreatefrombmp ($path);
imagebmp ($img, $path, 100);
imagedestroy ($img);
}
header("Location: index.php?p=uploaded&img=$newname");
} else
header("Location: index.php?p=error&num=2");
} else
header("Location: index.php?p=error&num=1");
}
?>

foreach($_FILES as $key_file=>$file_info){
//your code here instead $_FILES['userfile']['tmp_name'] use $file_info['tmp_name']
}

i wrote a class for uploads sometimes ago.
this class has ability to upload mutiple files at the same time(such as picture .etc).
it also has other ability such as :
-if you upload mutiple files with the same name it will automatically change their name
-you can add permitted types
-set maximum size of uploaded files
...
class Upload {
protected $_uploaded = array();
protected $_destination_upload_folder;
//Constraint
protected $_max_upload_size = 512000;
protected $_permitted_files = array('image/gif', 'image/png', 'image/jpg', 'image/jpeg', 'image/pjpeg');
protected $_error_messages = array();
protected $_renamed_file = false;
public function __construct($input_upload_path) {
if(!is_dir($input_upload_path) || !is_writable($input_upload_path)){
throw new Exception("$input_upload_path must be a valid,writable path!");
}
$this->_destination_upload_folder = $input_upload_path;
$this->_uploaded = $_FILES;
}
protected function checkError($fileName, $error){
switch ($error) {
case 0:
return true;
case 1:
case 2:
$this->_error_messages[] = "$fileName exceeds maximum file size : "
.$this->getMaxSize();
return true;
case 3:
$this->_error_messages[] = "Error while uploading $fileName.please try again.";
return false;
case 4:
$this->_error_messages[] = "No file selected.";
return false;
default:
$this->_error_messages[] = "System Error uploading $fileName.Please contact administrator.";
return false;
return false;
}
}
protected function checkSize($fileName, $size){
if($size == 0){
return false;
}else if($size > $this->_max_upload_size){
$this->_error_messages[] = "$fileName exceeds maximum size : ".
$this->_max_upload_size;
return false;
}else{
return true;
}
}
protected function checkType($fileName, $type){
if(!in_array($type, $this->_permitted_files)){
$this->_error_messages[] = 'This type of file is not allowed for uploading '
.'.please upload permitted files.';
return false;
}else{
return true;
}
}
public function checkName($input_file_name, $overwrite)
{
$input_file_name_without_spaces = str_replace(' ', '_', $input_file_name);
if($input_file_name_without_spaces != $input_file_name){
$this->_renamed_file = true;
}
if(!$overwrite){
$all_files_in_upload_directory = scandir($this->_destination_upload_folder);
if(in_array($input_file_name_without_spaces, $all_files_in_upload_directory)){
$dot_position = strrpos($input_file_name_without_spaces, '.');
if($dot_position){
$base = substr($input_file_name_without_spaces, 0, $dot_position);
$extension = substr($input_file_name_without_spaces, $dot_position);
}else{
$base = substr($input_file_name_without_spaces);
$extension = '';
}
$i = 1;
do{
$input_file_name_without_spaces = $base.'_'.$i++.$extension;
}while(in_array($input_file_name_without_spaces, $all_files_in_upload_directory));
$this->_renamed_file = true;
}
}
return $input_file_name_without_spaces;
}
protected function getMaxSize(){
return number_format(($this->_max_upload_size)/1024, 1).'kb';
}
protected function isValidMime($types)
{
$also_valid_mimes = array('application/pdf', 'text/plain', 'text/rtf');
$all_valid_mimes = array_merge($this->_permitted_files, $also_valid_mimes);
foreach($types as $type){
if(!in_array($type, $all_valid_mimes)){
throw new Exception("$type is not a valid permitted mime type!");
}
}
}
public function addPermittedType($input_type_name)
{
$input_type_name_array = (array)$input_type_name;
$this->isValidMime($input_type_name_array);
$this->_permitted_files = array_merge($this->_permitted_files, $input_type_name_array);
}
protected function processFile($fileName, $error, $size, $type, $tmp_name, $overwrite)
{
$check_upload_error = $this->checkError($fileName, $error);
if($check_upload_error){
$check_uploaded_file_type = $this->checkType($fileName, $type);
$check_uploaded_file_size = $this->checkSize($fileName, $size);
if($check_uploaded_file_type && $check_uploaded_file_size){
$new_uploaded_file_name = $this->checkName($fileName, $overwrite);
$upload_result = move_uploaded_file($tmp_name, $this->_destination_upload_folder.$new_uploaded_file_name);
if($upload_result){
$messages = $new_uploaded_file_name.' uploaded successfully! <br >';
if($this->_renamed_file){
$messages .= ' and renamed successfully!';
}
$this->_error_messages[] = $messages;
} else {
$this->_error_messages[] = 'Could`nt upload '.$fileName;
}
}
}
}
public function move($overwrite = FALSE){
$file = current($this->_uploaded);
if(is_array($file['name'])){
foreach($file['name'] as $index => $filename){
$this->_renamed_file = false;
$this->processFile($filename, $file['error'][$index],
$file['size'][$index], $file['type'][$index], $file['tmp_name'][$index], $overwrite);
}
}else{
$this->processFile($file['filename'], $file['error'], $file['size'], $file['type']
, $file['tmp_name'], $overwrite);
}
}
public function getErrorMessages(){
return $this->_error_messages;
}
public function setMaxSize($new_upload_size)
{
if(!is_numeric($new_upload_size) || $new_upload_size <= 0){
throw new Exception("new maximum upload size must a number!");
}
$this->_max_upload_size = (int)$new_upload_size;
}
}
$max_upload_size = 1024 * 1024;
if(isset($_POST['upload_button'])){
$destination_upload_folder = 'destination of upload folder here....';
require_once 'Upload class filename...';
try{
$upload = new Upload($destination_upload_folder);
$upload->setMaxSize($max_upload_size);
$upload->addPermittedType('application/pdf');
$upload->move(true);
$result = $upload->getErrorMessages();
}catch(Exception $e){
echo $e->getMessage();
}
}

Related

Limitting file upload on a User php

Im new to php please help me, I have a website and people can upload files like pdf, doc,xls and I want to limit the number of file upload. the user after login can see the upload page and upload his files but i want that the user can only upload files 3 times a day if he submitted 3 times in a day then it should not allow the user to upload more files it should give a message that you can not post more that 3 projects per day.
My files are: form.php and Uploadfile.php
<?php
use foundationphp\UploadFile;
session_start();
require_once 'src/foundationphp/UploadFile.php';
if (!isset($_SESSION['maxfiles'])) {
$_SESSION['maxfiles'] = ini_get('max_file_uploads');
$_SESSION['postmax'] = UploadFile::convertToBytes(ini_get('post_max_size'));
$_SESSION['displaymax'] = UploadFile::convertFromBytes($_SESSION['postmax']);
}
$max = 2000000;
$result = array();
if (isset($_POST['upload'])) {
$destination = __DIR__ . '/uploaded/';
try {
$upload = new UploadFile($destination);
$upload->setMaxSize($max);
// $upload->allowAllTypes();
$upload->upload();
$result = $upload->getMessages();
} catch (Exception $e) {
$result[] = $e->getMessage();
}
}
$error = error_get_last();
?>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File Uploads</title>
<link href="styles/form.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1>Uploading Files</h1>
<?php if ($result || $error) { ?>
<ul class="result">
<?php
if ($error) {
echo "<li>{$error['message']}</li>";
}
if ($result) {
foreach ($result as $message) {
echo "<li>$message</li>";
}
}?>
</ul>
<?php } ?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post" enctype="multipart/form-data">
<p>
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $max;?>">
<label for="filename">Select File:</label>
<input type="file" name="filename[]" id="filename" multiple
data-maxfiles="<?php echo $_SESSION['maxfiles'];?>"
data-postmax="<?php echo $_SESSION['postmax'];?>"
data-displaymax="<?php echo $_SESSION['displaymax'];?>">
</p>
<ul>
<li>Up to <?php echo $_SESSION['maxfiles'];?> files can be uploaded simultaneously.</li>
<li>Each file should be no more than <?php echo UploadFile::convertFromBytes($max);?>.</li>
<li>Combined total should not exceed <?php echo $_SESSION ['displaymax'];?>.</li>
</ul>
<p>
<input type="submit" name="upload" value="Upload File">
</p>
</form>
<script src="js/checkmultiple.js"></script>
</body>
</html>
And uploadfile.php
<?php
namespace foundationphp;
class UploadFile
{
protected $destination;
protected $messages = array();
protected $maxSize = 2102400;//51200; //50 KB
protected $permittedTypes = array(
'image/jpeg',
'image/pjpeg',
'image/gif',
'image/png',
'image/webp',
'application/pdf',
'application/rar',
'application/zip',
'application/x-zip',
'application/x-zip-compressed',
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.ms-powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/vnd.oasis.opendocument.spreadsheet',
'application/vnd.oasis.opendocument.presentation',
'application/vnd.oasis.opendocument.text'
);
protected $newName;
protected $typeCheckingOn = true;
protected $notTrusted = array('bin', 'cgi', 'exe', 'dmg', 'js', 'pl', 'php', 'py', 'sh');
protected $suffix = '.upload';
protected $renameDuplicates;
public function __construct($uploadFolder)
{
if (!is_dir($uploadFolder) || !is_writable($uploadFolder)) {
throw new \Exception("$uploadFolder must be a valid, writable folder.");
}
if ($uploadFolder[strlen($uploadFolder)-1] != '/') {
$uploadFolder .= '/';
}
$this->destination = $uploadFolder;
}
public function setMaxSize($bytes)
{
$serverMax = self::convertToBytes(ini_get('upload_max_filesize'));
if ($bytes > $serverMax) {
throw new \Exception('Maximum size cannot exceed server limit for individual files: ' . self::convertFromBytes($serverMax));
}
if (is_numeric($bytes) && $bytes > 0) {
$this->maxSize = $bytes;
}
}
public static function convertToBytes($val)
{
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
if (in_array($last, array('g', 'm', 'k'))){
switch ($last) {
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
}
return $val;
}
public static function convertFromBytes($bytes)
{
$bytes /= 1024;
if ($bytes > 1024) {
return number_format($bytes/1024, 1) . ' MB';
} else {
return number_format($bytes, 1) . ' KB';
}
}
public function allowAllTypes($suffix = null)
{
$this->typeCheckingOn = false;
if (!is_null($suffix)) {
if (strpos($suffix, '.') === 0 || $suffix == '') {
$this->suffix = $suffix;
} else {
$this->suffix = ".$suffix";
}
}
}
public function upload($renameDuplicates = true)
{
$this->renameDuplicates = $renameDuplicates;
$uploaded = current($_FILES);
if (is_array($uploaded['name'])) {
foreach ($uploaded['name'] as $key => $value) {
$currentFile['name'] = $uploaded['name'][$key];
$currentFile['type'] = $uploaded['type'][$key];
$currentFile['tmp_name'] = $uploaded['tmp_name'][$key];
$currentFile['error'] = $uploaded['error'][$key];
$currentFile['size'] = $uploaded['size'][$key];
if ($this->checkFile($currentFile)) {
$this->moveFile($currentFile);
}
}
} else {
if ($this->checkFile($uploaded)) {
$this->moveFile($uploaded);
}
}
}
public function getMessages()
{
return $this->messages;
}
protected function checkFile($file)
{
if ($file['error'] != 0) {
$this->getErrorMessage($file);
return false;
}
if (!$this->checkSize($file)) {
return false;
}
if ($this->typeCheckingOn) {
if (!$this->checkType($file)) {
return false;
}
}
$this->checkName($file);
return true;
}
protected function getErrorMessage($file)
{
switch($file['error']) {
case 1:
case 2:
$this->messages[] = $file['name'] . ' is too big: (max: ' .
self::convertFromBytes($this->maxSize) . ').';
break;
case 3:
$this->messages[] = $file['name'] . ' was only partially uploaded.';
break;
case 4:
$this->messages[] = 'No file submitted.';
break;
default:
$this->messages[] = 'Sorry, there was a problem uploading ' . $file['name'];
break;
}
}
protected function checkSize($file)
{
if ($file['size'] == 0) {
$this->messages[] = $file['name'] . ' is empty.';
return false;
} elseif ($file['size'] > $this->maxSize) {
$this->messages[] = $file['name'] . ' exceeds the maximum size for a file ('
. self::convertFromBytes($this->maxSize) . ').';
return false;
} else {
return true;
}
}
protected function checkType($file)
{
if (in_array($file['type'], $this->permittedTypes)) {
return true;
} else {
$this->messages[] = $file['name'] . ' is not permitted type of file.';
return false;
}
}
protected function checkName($file)
{
$this->newName = null;
$nospaces = str_replace(' ', '_', $file['name']);
if ($nospaces != $file['name']) {
$this->newName = $nospaces;
}
$nameparts = pathinfo($nospaces);
$extension = isset($nameparts['extension']) ? $nameparts['extension'] : '';
if (!$this->typeCheckingOn && !empty($this->suffix)) {
if (in_array($extension, $this->notTrusted) || empty($extension)) {
$this->newName = $nospaces . $this->suffix;
}
}
if ($this->renameDuplicates) {
$name = isset($this->newName) ? $this->newName : $file['name'];
$existing = scandir($this->destination);
if (in_array($name, $existing)) {
$i = 1;
do {
$this->newName = $nameparts['filename'] . '_' . $i++;
if (!empty($extension)) {
$this->newName .= ".$extension";
}
if (in_array($extension, $this->notTrusted)) {
$this->newName .= $this->suffix;
}
} while (in_array($this->newName, $existing));
}
}
}
protected function moveFile($file)
{
$filename = isset($this->newName) ? $this->newName : $file['name'];
$success = move_uploaded_file($file['tmp_name'], $this->destination . $filename);
if ($success) {
$result = $file['name'] . ' was uploaded successfully';
if (!is_null($this->newName)) {
$result .= ', and was renamed ' . $this->newName;
}
$result .= '.';
$this->messages[] = $result;
} else {
$this->messages[] = 'Could not upload ' . $file['name'];
}
}
}
Thanks/Regards,
Sam
You can use SQL to store the amount of files uploaded by each user. Then you can check in php if a user can upload another file or not with SQL queries.
EDIT:
Let's elaborate a little.
There can be 2 ways for achieving this:
a) server-side.
As you say, you have a login form. I suppose you have a database with usernames and passwords, right? So, you can add an 'uploads' table in your database with the timestamp of each upload and the username of the uploader.
Then, each time your PHP class is called, you can make a query to your database to see the amount of files the uploader has uploaded within the last 24 hours. If the number is <3 then your PHP class will allow him to upload another one. Else, your PHP class will echo the message you want.
b) client-side.
Each time a user uploads a file, the info about his uploads is stored in his localStorage. So, this info will be checked on 'upload' button click event and either he will be allowed to upload or not.
However, as I said, the info is stored in HIS localStorage, so, this method is bypassable by the user. I wouldn't recommend it.
Improve your upload function and add destination inside UploadFile class for better re-usability and security:
class UploadFile
{
protected $destination = __DIR__ . '/uploaded/';
protected $messages = array();
protected $maxSize = 2102400;//51200; //50 KB
protected $permittedTypes = array(
'image/jpeg',
'image/pjpeg',
'image/gif',
'image/png',
'image/webp',
'application/pdf',
'application/rar',
'application/zip',
'application/x-zip',
'application/x-zip-compressed',
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.ms-powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/vnd.oasis.opendocument.spreadsheet',
'application/vnd.oasis.opendocument.presentation',
'application/vnd.oasis.opendocument.text'
);
protected $newName;
protected $typeCheckingOn = true;
protected $notTrusted = array('bin', 'cgi', 'exe', 'dmg', 'js', 'pl', 'php', 'py', 'sh');
protected $suffix = '.upload';
protected $renameDuplicates;
public function __construct($uploadFolder)
{
if (!is_dir($uploadFolder) || !is_writable($uploadFolder)) {
throw new \Exception("$uploadFolder must be a valid, writable folder.");
}
if ($uploadFolder[strlen($uploadFolder)-1] != '/') {
$uploadFolder .= '/';
}
$this->destination = $uploadFolder;
}
public function setMaxSize($bytes)
{
$serverMax = self::convertToBytes(ini_get('upload_max_filesize'));
if ($bytes > $serverMax) {
throw new \Exception('Maximum size cannot exceed server limit for individual files: ' . self::convertFromBytes($serverMax));
}
if (is_numeric($bytes) && $bytes > 0) {
$this->maxSize = $bytes;
}
}
public static function convertToBytes($val)
{
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
if (in_array($last, array('g', 'm', 'k'))){
switch ($last) {
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
}
return $val;
}
public static function convertFromBytes($bytes)
{
$bytes /= 1024;
if ($bytes > 1024) {
return number_format($bytes/1024, 1) . ' MB';
} else {
return number_format($bytes, 1) . ' KB';
}
}
public function allowAllTypes($suffix = null)
{
$this->typeCheckingOn = false;
if (!is_null($suffix)) {
if (strpos($suffix, '.') === 0 || $suffix == '') {
$this->suffix = $suffix;
} else {
$this->suffix = ".$suffix";
}
}
}
public function upload($renameDuplicates = true)
{
$fi = new FilesystemIterator($this->destination, FilesystemIterator::SKIP_DOTS);
$totalFiles = iterator_count($fi);
if ($totalFiles <= 3){
$this->renameDuplicates = $renameDuplicates;
$uploaded = current($_FILES);
if (is_array($uploaded['name'])) {
foreach ($uploaded['name'] as $key => $value) {
$currentFile['name'] = $uploaded['name'][$key];
$currentFile['type'] = $uploaded['type'][$key];
$currentFile['tmp_name'] = $uploaded['tmp_name'][$key];
$currentFile['error'] = $uploaded['error'][$key];
$currentFile['size'] = $uploaded['size'][$key];
if ($this->checkFile($currentFile)) {
$this->moveFile($currentFile);
}
}
} else {
if ($this->checkFile($uploaded)) {
$this->moveFile($uploaded);
}
}
} else {
die('You can not post more that 3 projects per day!'); //Improve this to a thrown or stuff;
}
}
public function getMessages()
{
return $this->messages;
}
protected function checkFile($file)
{
if ($file['error'] != 0) {
$this->getErrorMessage($file);
return false;
}
if (!$this->checkSize($file)) {
return false;
}
if ($this->typeCheckingOn) {
if (!$this->checkType($file)) {
return false;
}
}
$this->checkName($file);
return true;
}
protected function getErrorMessage($file)
{
switch($file['error']) {
case 1:
case 2:
$this->messages[] = $file['name'] . ' is too big: (max: ' .
self::convertFromBytes($this->maxSize) . ').';
break;
case 3:
$this->messages[] = $file['name'] . ' was only partially uploaded.';
break;
case 4:
$this->messages[] = 'No file submitted.';
break;
default:
$this->messages[] = 'Sorry, there was a problem uploading ' . $file['name'];
break;
}
}
protected function checkSize($file)
{
if ($file['size'] == 0) {
$this->messages[] = $file['name'] . ' is empty.';
return false;
} elseif ($file['size'] > $this->maxSize) {
$this->messages[] = $file['name'] . ' exceeds the maximum size for a file ('
. self::convertFromBytes($this->maxSize) . ').';
return false;
} else {
return true;
}
}
protected function checkType($file)
{
if (in_array($file['type'], $this->permittedTypes)) {
return true;
} else {
$this->messages[] = $file['name'] . ' is not permitted type of file.';
return false;
}
}
protected function checkName($file)
{
$this->newName = null;
$nospaces = str_replace(' ', '_', $file['name']);
if ($nospaces != $file['name']) {
$this->newName = $nospaces;
}
$nameparts = pathinfo($nospaces);
$extension = isset($nameparts['extension']) ? $nameparts['extension'] : '';
if (!$this->typeCheckingOn && !empty($this->suffix)) {
if (in_array($extension, $this->notTrusted) || empty($extension)) {
$this->newName = $nospaces . $this->suffix;
}
}
if ($this->renameDuplicates) {
$name = isset($this->newName) ? $this->newName : $file['name'];
$existing = scandir($this->destination);
if (in_array($name, $existing)) {
$i = 1;
do {
$this->newName = $nameparts['filename'] . '_' . $i++;
if (!empty($extension)) {
$this->newName .= ".$extension";
}
if (in_array($extension, $this->notTrusted)) {
$this->newName .= $this->suffix;
}
} while (in_array($this->newName, $existing));
}
}
}
protected function moveFile($file)
{
$filename = isset($this->newName) ? $this->newName : $file['name'];
$success = move_uploaded_file($file['tmp_name'], $this->destination . $filename);
if ($success) {
$result = $file['name'] . ' was uploaded successfully';
if (!is_null($this->newName)) {
$result .= ', and was renamed ' . $this->newName;
}
$result .= '.';
$this->messages[] = $result;
} else {
$this->messages[] = 'Could not upload ' . $file['name'];
}
}
}
I think you have a user table in you DB. just add a new attribute upload_day_count...
At every upload you check if the number is at 3 if not then you allow the upload and icrement the attribute value for this user. Day +1 at 00h01min you run a cron Job to reset all values for all users.

Restrict ".php" File upload

I am making basic photo hosting, just to upload images and resize them.
Everything works fine, I also have added accept="image/*" for my File upload button, but it is still possible to upload other files. So in my PHP code I check whether it is image or other file, so if it is not image, I basically remove it. But I have a problem. If user uploads "index.php" file, my index file on server will be overwritten and as my code should do, it removes "index.php" so. basically self destruction.
Is there way to restrict file upload before file is actually uploaded on server?
Or at least, is there way to change root directory of file that is
uploaded?
I don't think that JavaScript or HTML restriction will do anything, because "hackermans" can change it easily in inspect element.
class Upload {
private $destinationPath;
private $errorMessage;
private $extensions;
private $allowAll;
private $maxSize;
private $uploadName;
private $seqnence;
private $imageSeq;
public $name = 'Uploader';
public $useTable = false;
function setDir($path) {
$this->destinationPath = $path;
$this->allowAll = false;
}
function allowAllFormats() {
$this->allowAll = true;
}
function setMaxSize($sizeMB) {
$this->maxSize = $sizeMB * (1024 * 1024);
}
function setExtensions($options) {
$this->extensions = $options;
}
function setSameFileName() {
$this->sameFileName = true;
$this->sameName = true;
}
function getExtension($string) {
$ext = "";
try {
$parts = explode(".", $string);
$ext = strtolower($parts[count($parts) - 1]);
} catch (Exception $c) {
$ext = "";
}
return $ext;
}
function setMessage($message) {
$this->errorMessage = $message;
}
function getMessage() {
return $this->errorMessage;
}
function getUploadName() {
return $this->uploadName;
}
function setSequence($seq) {
$this->imageSeq = $seq;
}
function getRandom() {
return strtotime(date('Y-m-d H:i:s')) . rand(1111, 9999) . rand(11, 99) . rand(111, 999);
}
function sameName($true) {
$this->sameName = $true;
}
function uploadFile($fileBrowse) {
$result = false;
$size = $_FILES[$fileBrowse]["size"];
$name = $_FILES[$fileBrowse]["name"];
$ext = $this->getExtension($name);
if (!is_dir($this->destinationPath)) {
$this->setMessage("Destination folder is not a directory ");
} else if (!is_writable($this->destinationPath)) {
$this->setMessage("Destination is not writable !");
} else if (empty($name)) {
$this->setMessage("File not selected ");
} else if ($size > $this->maxSize) {
$this->setMessage("Too large file !");
} else if ($this->allowAll || (!$this->allowAll && in_array($ext, $this->extensions))) {
if ($this->sameName == false) {
$this->uploadName = $this->imageSeq . "-" . substr(md5(rand(1111, 9999)), 0, 8) . $this->getRandom() . rand(1111, 1000) . rand(99, 9999) . "." . $ext;
} else {
$this->uploadName = $name;
}
if (move_uploaded_file($_FILES[$fileBrowse]["tmp_name"], $this->destinationPath . $this->uploadName)) {
$result = true;
} else {
$this->setMessage("Upload failed , try later !");
}
} else {
$this->setMessage("Invalid file format !");
}
return $result;
}
function deleteUploaded() {
unlink($this->destinationPath . $this->uploadName);
}
}
How to use it :
function callMe(){
$uploader = new Upload();
$directory = "NAMEDIR"
if(!is_dir($directory)){
mkdir($directory);
}
$uploader->setDir($directory);
$uploader->setExtensions(array('jpg','jpeg','png','gif')); //allowed extensions list//
$uploader->setMaxSize(.5); //set max file size to be allowed in MB//
$uploader->sameName(true);
if($uploader->uploadFile('file')){ //txtFile is the filebrowse element name //
$image = $uploader->getUploadName(); //get uploaded file name, renames on upload//
echo json_encode(array("success"=>true,"message"=>"Success Add","image"=>$directory.$image,"image_upload"=>$image));
}else{//upload failed
echo json_encode(array("success"=>false,"message"=>$uploader->getMessage(),"image"=>""));
}
}
callMe();

Combining PHP classes, not populating array

I've got 3 different classes (class Thumbnail in Thumbnail.php, class Upload in Upload.php and class ThumbnailUpload in ThumbnailUpload.php) all in the same namespace (PhotoProject). Currently, it will load an image, create a thumbnail and store both in selected directory, but it will not store the information requested into a database. If you look in the code snippet of blog_insert.php, once it gets to calling $loader->collectFilenames to be assigned to $names, nothing is ever stored in $names[]. I've did a var_dump, and $names is always empty. Any suggestions? Below are the code snippets.
class Upload {
protected $collectednames = [];
protected $typeCheckingOn = true;
protected $notTrusted = ['bin', 'cgi', 'exe', 'js'];
protected $newName;
protected $destination;
protected $max = 8388608;
protected $messages = [];
protected $permitted = [
'image/gif',
'image/png',
'image/jpg'
];
...
public function collectFilenames() {
return $this->collectednames;
}
blog_insert.php
<?php
use PhotoProject\ThumbnailUpload;
require_once '../includes/connection.php';
$conn = dbConnect();
if (isset($_POST['insert'])) {
$OK = false;
$stmt = $conn->stmt_init();
// if a file has been uploaded, process it
if(isset($_POST['upload_new']) && $_FILES['image']['error'] == 0) {
$imageOK = false;
require_once '../PhotoProject/ThumbnailUpload.php';
$loader = new ThumbnailUpload('path to store images');
$loader->setThumbDestination('path to store thumbnail');
$loader->upload();
$names = $loader->collectFilenames();
// $names will be an empty array if the upload failed
if ($names) {
$sql = 'INSERT INTO images (filename, caption) VALUES (?, ?)';
Class Thumbnail
<?php
namespace PhotoProject;
class Thumbnail {
protected $original;
protected $originalwidth;
protected $originalheight;
protected $basename;
protected $thumbwidth;
protected $thumbheight;
protected $maxSize = 350;
protected $canProcess = false;
protected $imageType;
protected $destination;
protected $suffix = '_thb';
protected $messages = [];
public function __construct($image) {
if (is_file($image) && is_readable($image)) {
$details = getimagesize($image);
} else {
$details = null;
$this->messages[] = "Cannot open $image.";
}
// if getimagesize() returns an array, it looks like an image
if (is_array($details)) {
$this->original = $image;
$this->originalwidth = $details[0];
$this->originalheight = $details[1];
$this->basename = pathinfo($image, PATHINFO_FILENAME);
// check the MIME type
$this->checkType($details['mime']);
} else {
$this->messages[] = "$image doesn't appear to be an image.";
}
}
public function setDestination($destination) {
if (is_dir($destination) && is_writable($destination)) {
// get last character
$last = substr($destination, -1);
// add a trailing slash if missing
if ($last == '/' || $last == '\\') {
$this->destination = $destination;
} else {
$this->destination = $destination . DIRECTORY_SEPARATOR;
}
} else {
$this->messages[] = "Cannot write to $destination.";
}
}
public function setMaxSize($size) {
if (is_numeric($size) && $size > 0) {
$this->maxSize = abs($size);
} else {
$this->messages[] = 'The value for setMaxSize() must be a positive number.';
$this->canProcess = false;
}
}
public function setSuffix($suffix) {
if (preg_match('/^\w+$/', $suffix)) {
if (strpos($suffix, '_') !== 0) {
$this->suffix = '_' . $suffix;
} else {
$this->suffix = $suffix;
}
} else {
$this->suffix = '';
}
}
public function create() {
if ($this->canProcess && $this->originalwidth != 0) {
$this->calculateSize($this->originalwidth, $this->originalheight);
$this->createThumbnail();
} elseif ($this->originalwidth == 0) {
$this->messages[] = 'Cannot determine size of ' . $this->original;
}
}
public function getMessages() {
return $this->messages;
}
protected function checkType($mime) {
$mimetypes = ['image/jpeg', 'image/png', 'image/gif'];
if (in_array($mime, $mimetypes)) {
$this->canProcess = true;
// extract the characters after 'image/'
$this->imageType = substr($mime, 6);
}
}
protected function calculateSize($width, $height) {
if ($width <= $this->maxSize && $height <= $this->maxSize) {
$ratio = 1;
} elseif ($width > $height) {
$ratio = $this->maxSize/$width;
} else {
$ratio = $this->maxSize/$height;
}
$this->thumbwidth = round($width * $ratio);
$this->thumbheight = round($height * $ratio);
}
protected function createImageResource() {
if ($this->imageType == 'jpeg') {
return imagecreatefromjpeg($this->original);
} elseif ($this->imageType == 'png') {
return imagecreatefrompng($this->original);
} elseif ($this->imageType == 'gif') {
return imagecreatefromgif($this->original);
}
}
protected function createThumbnail() {
$resource = $this->createImageResource();
$thumb = imagecreatetruecolor($this->thumbwidth, $this->thumbheight);
imagecopyresampled($thumb, $resource, 0, 0, 0, 0, $this->thumbwidth,
$this->thumbheight, $this->originalwidth, $this->originalheight);
$newname = $this->basename . $this->suffix;
if ($this->imageType == 'jpeg') {
$newname .= '.jpg';
$success = imagejpeg($thumb, $this->destination . $newname, 100);
} elseif ($this->imageType == 'png') {
$newname .= '.png';
$success = imagepng($thumb, $this->destination . $newname, 0);
} elseif ($this->imageType == 'gif') {
$newname .= '.gif';
$success = imagegif($thumb, $this->destination . $newname);
}
if ($success) {
$this->messages[] = "$newname created successfully.";
} else {
$this->messages[] = "Couldn't create a thumbnail for " .
basename($this->original);
}
imagedestroy($resource);
imagedestroy($thumb);
}
}
Class ThumbnailUpload
<?php
namespace PhotoProject;
use PhotoProject\Upload;
require_once 'Upload.php';
require_once 'Thumbnail.php';
class ThumbnailUpload extends Upload {
protected $thumbDestination;
protected $deleteOriginal;
protected $suffix = '_thb';
public function __construct($path, $deleteOriginal = false) {
parent::__construct($path);
$this->thumbDestination = $path;
$this->deleteOriginal = $deleteOriginal;
}
/*
** Setter method for the thumbnail destination
*/
public function setThumbDestination($path) {
if (!is_dir($path) || !is_writable($path)) {
throw new \Exception("$path must be a valid, writable directory.");
}
$this->thumbDestination = $path;
}
public function setThumbSuffix($suffix) {
if (preg_match('/\w+/', $suffix)) {
if (strpos($suffix, '_') !== 0) {
$this->suffix = '_' . $suffix;
} else {
$this->suffix = $suffix;
}
} else {
$this->suffix = '';
}
}
public function allowAllTypes() {
$this->typeCheckingOn = true;
}
protected function createThumbnail($image) {
$thumb = new Thumbnail($image);
$thumb->setDestination($this->thumbDestination);
$thumb->setSuffix($this->suffix);
$thumb->create();
$messages = $thumb->getMessages();
$this->messages = array_merge($this->messages, $messages);
}
protected function moveFile($file) {
$filename = isset($this->newName) ? $this->newName : $file['name'];
$success = move_uploaded_file($file['tmp_name'],
$this->destination . $filename);
if ($success) {
// add a message only if the original image is not deleted
if (!$this->deleteOriginal) {
$result = $file['name'] . ' was uploaded successfully';
if (!is_null($this->newName)) {
$result .= ', and was renamed ' . $this->newName;
}
$this->messages[] = $result;
}
// create a thumbnail from the uploaded image
$this->createThumbnail($this->destination . $filename);
// delete the uploaded image if required
if ($this->deleteOriginal) {
unlink($this->destination . $filename);
}
} else {
$this->messages[] = 'Could not upload ' . $file['name'];
}
}
}
Class Upload
<?php
namespace PhotoProject;
class Upload {
protected $collectednames = [];
protected $typeCheckingOn = true;
protected $notTrusted = ['bin', 'cgi', 'exe', 'js'];
protected $newName;
protected $renameDuplicates;
protected $destination;
protected $max = 8388608;
protected $messages = [];
protected $permitted = [
'image/gif',
'image/png',
'image/jpg'
];
public function __construct($path) {
if (!is_dir($path) || !is_writable($path)) {
throw new \Exception("$path must be a valid, writable directory.");
}
$this->destination = $path;
}
public function setMaxSize($num) {
if (is_numeric($num) && $num > 0) {
$this->max = (int) $num;
}
}
public function allowAllTypes() {
$this->typeCheckingOn = false;
if (!$suffix) {
$this->suffix = ''; // empty string
}
}
public function upload($renameDuplicates = true) {
$this->renameDuplicates = $renameDuplicates;
$uploaded = current($_FILES);
if (is_array($uploaded['name'])) {
// deal with multiple uploads
foreach ($uploaded['name'] as $key => $value) {
$currentFile['name'] = $uploaded['name'][$key];
$currentFile['type'] = $uploaded['type'][$key];
$currentFile['tmp_name'] = $uploaded['tmp_name'][$key];
$currentFile['error'] = $uploaded['error'][$key];
$currentFile['size'] = $uploaded['size'][$key];
if ($this->checkFile($currentFile)) {
$this->moveFile($currentFile);
}
}
} else {
if ($this->checkFile($uploaded)) {
$this->moveFile($uploaded);
}
}
}
public function getMessages() {
return $this->messages;
}
public function collectFilenames() {
return $this->collectednames;
}
public function getMaxSize() {
return number_format($this->max/1024, 1) . ' KB';
}
protected function checkFile($file) {
$accept = true;
if ($file['error'] != 0) {
$this->getErrorMessage($file);
// stop checking if no file submitted
if ($file['error'] == 4) {
return false;
} else {
$accept = false;
}
}
if (!$this->checkSize($file)) {
$accept = false;
}
if ($this->typeCheckingOn) {
if (!$this->checkType($file)) {
$accept = false;
}
}
if ($accept) {
$this->checkName($file);
}
return $accept;
return true;
}
protected function checkName($file) {
$this->newName = null;
$nospaces = str_replace(' ', '_', $file['name']);
if ($nospaces != $file['name']) {
$this->newName = $nospaces;
}
$extension = pathinfo($nospaces, PATHINFO_EXTENSION);
if (!$this->typeCheckingOn && !empty($this->suffix)) {
if (in_array($extension, $this->notTrusted) || empty($extension)) {
$this->newName = $nospaces . $this->suffix;
}
}
if ($this->renameDuplicates) {
$name = isset($this->newName) ? $this->newName : $file['name'];
$existing = scandir($this->destination);
if (in_array($name, $existing)) {
// rename file
$basename = pathinfo($name, PATHINFO_FILENAME);
$extension = pathinfo($name, PATHINFO_EXTENSION);
$i = 1;
do {
$this->newName = $basename . '_' . $i++;
if (!empty($extension)) {
$this->newName .= ".$extension";
}
} while (in_array($this->newName, $existing));
}
}
}
protected function getErrorMessage($file) {
switch($file['error']) {
case 1:
case 2:
$this->messages[] = $file['name'] . ' is too big: (max: ' .
$this->getMaxSize() . ').';
break;
case 3:
$this->messages[] = $file['name'] . ' was only partially
uploaded.';
break;
case 4:
$this->messages[] = 'No file submitted.';
break;
default:
$this->messages[] = 'Sorry, there was a problem uploading ' .
$file['name'];
break;
}
}
protected function checkSize($file) {
if ($file['error'] == 1 || $file['error'] == 2 ) {
return false;
} elseif ($file['size'] == 0) {
$this->messages[] = $file['name'] . ' is an empty file.';
return false;
} elseif ($file['size'] > $this->max) {
$this->messages[] = $file['name'] . ' exceeds the maximum size
for a file (' . $this->getMaxSize() . ').';
return false;
} else {
return true;
}
}
protected function checkType($file) {
if (in_array($file['type'], $this->permitted)) {
return true;
} else {
if (!empty($file['type'])) {
$this->messages[] = $file['name'] . ' is not permitted type of file.';
return false;
}
}
}
protected function moveFile($file) {
$filename = isset($this->newName) ? $this->newName : $file['name'];
$success = move_uploaded_file($file['tmp_name'],
$this->destination . $filename);
if ($success) {
// add the amended filename to the array of uploaded files
$this->filenames[] = $filename;
$result = $file['name'] . ' was uploaded successfully';
if (!is_null($this->newName)) {
$result .= ', and was renamed ' . $this->newName;
}
$this->messages[] = $result;
} else {
$this->messages[] = 'Could not upload ' . $file['name'];
}
}
}

Multiple uploads to multiple folders - PHP

I am attempting to upload multiple files into multiple folders. Unfortunately, with little success.
Any help would be greatly appreciated
I have two form fields:
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $max; ?>" />
<input name="menu" type="file" class="input_event noBorder" title="Upload Menu" />
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $max; ?>" />
<input name="img" type="file" class="input_event noBorder" title="Upload Img" />
I would like to use one for uploading images, and the other to upload pdf's and/or word docs.
I would also like for these two files to be saved into their corresponding folders (/imgs and /docs).
Some things i have tried
have tried to have two of these, each pointing to the correct path
have tried multiple classes to handle each file
have added array brackets to the input name field (ex: name="menu[]")
I imagine i need to change somethings in the class itself; however i am learning php and this class is cobbled together from 3 books, dozens of Google searches, and a few posts i found here on stack.
Exactly what i need to change is still far beyond me.
Relevant portion of on-page PHP code:
$max = 400000;
if (isset($_POST['submit'])) { //MAIN IF STATEMENT
$destination = './uploads/menus_up/';
try {
$upload = new Upload_File($destination);
$upload->move();
$result = $upload->getMessages();
} catch (Exception $e) {
echo $e->getMessage();
}
Upload class:
class Upload_File {
protected $_uploaded = array();
protected $_destination;
protected $_max = 400000;
protected $_messages = array();
protected $_permitted = array('image/gif',
'image/jpeg',
'image/pjpeg',
'image/png');
protected $_renamed = false;
public function __construct($path) {
if (!is_dir($path) || !is_writable($path)) {
throw new Exception("$path must be a valid, writable directory.");
}
$this->_destination = $path;
$this->_uploaded = $_FILES;
}
public function getMaxSize() {
return number_format($this->_max/1024, 1) . 'kB';
}
public function setMaxSize($num) {
if (!is_numeric($num)) {
throw new Exception("Maximum size must be a number.");
}
$this->_max = (int) $num;
}
public function move($overwrite = false) {
$field = current($this->_uploaded);
if (is_array($field['name'])) {
foreach ($field['name'] as $number => $filename) {
// process multiple upload
$this->_renamed = false;
$this->processFile($filename, $field['error'][$number], $field['size'][$number], $field['type'][$number], $field['tmp_name'][$number], $overwrite);
}
} else {
$this->processFile($field['name'], $field['error'], $field['size'], $field['type'], $field['tmp_name'], $overwrite);
}
}
public function getMessages() {
return $this->_messages;
}
protected function checkError($filename, $error) {
switch ($error) {
case 0:
return true;
case 1:
case 2:
$this->_messages[] = "$filename exceeds maximum size: " . $this->getMaxSize();
return true;
case 3:
$this->_messages[] = "Error uploading $filename. Please try again.";
return false;
case 4:
$this->_messages[] = 'No file selected.';
return false;
default:
$this->_messages[] = "System error uploading $filename. Contact webmaster.";
return false;
}
}
protected function checkSize($filename, $size) {
if ($size == 0) {
return false;
} elseif ($size > $this->_max) {
$this->_messages[] = "$filename exceeds maximum size: " . $this->getMaxSize();
return false;
} else {
return true;
}
}
protected function checkType($filename, $type) {
if (empty($type)) {
return false;
} elseif (!in_array($type, $this->_permitted)) {
$this->_messages[] = "$filename is not a permitted type of file.";
return false;
} else {
return true;
}
}
public function addPermittedTypes($types) {
$types = (array) $types;
$this->isValidMime($types);
$this->_permitted = array_merge($this->_permitted, $types);
}
protected function isValidMime($types) {
$alsoValid = array('image/tiff',
'application/pdf',
'application/msword');
$valid = array_merge($this->_permitted, $alsoValid);
foreach ($types as $type) {
if (!in_array($type, $valid)) {
throw new Exception("$type is not a permitted MIME type");
}
}
}
protected function checkName($name, $overwrite) {
$nospaces = str_replace(' ', '_', $name);
if ($nospaces != $name) {
$this->_renamed = true;
}
if (!$overwrite) {
$existing = scandir($this->_destination);
if (in_array($nospaces, $existing)) {
$dot = strrpos($nospaces, '.');
if ($dot) {
$base = substr($nospaces, 0, $dot);
$extension = substr($nospaces, $dot);
} else {
$base = $nospaces;
$extension = '';
}
$i = 1;
do {
$nospaces = $base . '_' . $i++ . $extension;
} while (in_array($nospaces, $existing));
$this->_renamed = true;
}
}
return $nospaces;
}
protected function processFile($filename, $error, $size, $type, $tmp_name, $overwrite) {
$OK = $this->checkError($filename, $error);
if ($OK) {
$sizeOK = $this->checkSize($filename, $size);
$typeOK = $this->checkType($filename, $type);
if ($sizeOK && $typeOK) {
$name = $this->checkName($filename, $overwrite);
$success = move_uploaded_file($tmp_name, $this->_destination . $name);
if ($success) {
$message = "$filename uploaded successfully";
if ($this->_renamed) {
$message .= " and renamed $name";
}
$this->_messages[] = $message;
} else {
$this->_messages[] = "Could not upload $filename";
}
}
}
}
}//END CLASS....Upload_Menu
Striped down class
protected $_uploaded = array();
protected $_destination;
protected $_max = 400000;
protected $_messages = array();
protected $_permitted = array('image/gif',
'image/jpeg',
'image/pjpeg',
'image/png');
protected $_renamed = false;
public function __construct($path) {
if (!is_dir($path) || !is_writable($path)) {
throw new Exception("$path must be a valid, writable directory.");
}
$this->_destination = $path;
$this->_uploaded = $_FILES;
}
public function move() {
$field = current($this->_uploaded);
$success = move_uploaded_file($field['tmp_name'], $this->_destination . $field['name']);
if ($success) {
$this->_messages[] = $field['name'] . ' uploaded successfully';
} else {
$this->_messages[] = 'Could not upload ' . $field['name'];
}
}
public function getMessages() {
return $this->_messages;
}
I would take a slightly different approach: Send a specific file to the constructor when you create your object like:
$upload = new Upload_File($_FILES['menu'], $destination);
Then you have all the information you need in your class and you don't have to access global variables from within your class.
You can then loop over your $_FILES array to add every file or put that in a different class.
It would require some rewriting in the class but it would make it more flexible and it would meet your needs.
SOLVED
So...for anyone who may come across this in the future, here is a less than elegant, but ultimately effective solution.
pathinfo($string, PATHINFO_EXTENSION) FTW!
I add a sorting mechanism to my processFile method and Wallah!
protected function processFile($filename, $error, $size, $type, $tmp_name, $overwrite) {
$OK = $this->checkError($filename, $error);
if ($OK) {
$sizeOK = $this->checkSize($filename, $size);
$typeOK = $this->checkType($filename, $type);
if ($sizeOK && $typeOK) {
$name = $this->checkName($filename, $overwrite);
/************************ADDED HERE************************************/
if (pathinfo($filename, PATHINFO_EXTENSION) == 'pdf' || 'doc' || 'docx'){
$this->_destination = './uploads/menus_up/';
if (pathinfo($filename, PATHINFO_EXTENSION) == 'png' || 'jpeg' || 'gif'){
$this->_destination = './uploads/eventBG_up/';
/**********************************************************************/
$success = move_uploaded_file($tmp_name, $this->_destination . $name);
if ($success) {
$message = "$filename uploaded successfully";
if ($this->_renamed) {
$message .= " and renamed $name";
}
$this->_messages[] = $message;
} else {
$this->_messages[] = "Could not upload $filename";
}
}
}
}
}
}

jQuery and PHP Remote Upload

I need help with a Remote Upload Script that has a page named 'uploadHandler.php'. I need to create a Remote Upload Script with jQuery PHP File Upload (jQuery File Upload). I would like to upload through this script a file that comes from a different server by entering only the URL. How can this be done?
Let me explain. I have a form that sends a request to uploadHandler.php when a user uploads a file from his computer. The problem is that the type is 'multipart/form-data' so I cannot upload via URL. I tried to put a URL but the system returns
[{"name":"","size":0,"type":null,"error":"File received has zero size."}]
So, what should I do to make sure that the file is processed by uploadHandler.php and then stored correctly? I had thought to download the file from the server and then upload it to do so treated. But how? I enclose the contents of uploadHandler.php for those who want to read it. Thank you in advance for your help, and I apologize for the grammar and vocabulary wrong: I'm not English.
class uploadHandler
{
private $options;
function __construct($options = null)
{
// get accepted file types
$acceptedFileTypes = getAcceptedFileTypes();
$this->options = array(
'script_url' => $_SERVER['PHP_SELF'],
'upload_dir' => _CONFIG_FILE_STORAGE_PATH,
'upload_url' => dirname($_SERVER['PHP_SELF']) . '/files/',
'param_name' => 'files',
'delete_hash' => '',
// The php.ini settings upload_max_filesize and post_max_size
// take precedence over the following max_file_size setting:
'max_file_size' => $this->get_max_upload_size(),
'min_file_size' => 1,
'accept_file_types' => COUNT($acceptedFileTypes) ? ('/(\.|\/)(' . str_replace(".", "", implode("|", $acceptedFileTypes)) . ')$/i') : '/.+$/i',
'max_number_of_files' => null,
'discard_aborted_uploads' => true,
'image_versions' => array(
'thumbnail' => array(
'upload_dir' => dirname(__FILE__) . '/thumbnails/',
'upload_url' => dirname($_SERVER['PHP_SELF']) . '/thumbnails/',
'max_width' => 80,
'max_height' => 80
)
)
);
if ($options)
{
$this->options = array_replace_recursive($this->options, $options);
}
}
private function get_max_upload_size()
{
// Initialize current user
$Auth = Auth::getAuth();
// max allowed upload size
$maxUploadSize = SITE_CONFIG_FREE_USER_MAX_UPLOAD_FILESIZE;
if ($Auth->loggedIn())
{
// check if user is a premium/paid user
if ($Auth->level != 'free user')
{
$maxUploadSize = SITE_CONFIG_PREMIUM_USER_MAX_UPLOAD_FILESIZE;
}
}
// if php restrictions are lower than permitted, override
$phpMaxSize = getPHPMaxUpload();
if ($phpMaxSize < $maxUploadSize)
{
$maxUploadSize = $phpMaxSize;
}
return $maxUploadSize;
}
private function get_file_object($file_name)
{
$file_path = $this->options['upload_dir'] . $file_name;
if (is_file($file_path) && $file_name[0] !== '.')
{
$file = new stdClass();
$file->name = $file_name;
$file->size = filesize($file_path);
$file->url = $this->options['upload_url'] . rawurlencode($file->name);
foreach ($this->options['image_versions'] as $version => $options)
{
if (is_file($options['upload_dir'] . $file_name))
{
$file->{$version . '_url'} = $options['upload_url']
. rawurlencode($file->name);
}
}
$file->delete_url = '~d?' . $this->options['delete_hash'];
$file->info_url = '~i?' . $this->options['delete_hash'];
$file->delete_type = 'DELETE';
return $file;
}
return null;
}
private function get_file_objects()
{
return array_values(array_filter(array_map(
array($this, 'get_file_object'), scandir($this->options['upload_dir'])
)));
}
private function create_scaled_image($file_name, $options)
{
$file_path = $this->options['upload_dir'] . $file_name;
$new_file_path = $options['upload_dir'] . $file_name;
list($img_width, $img_height) = #getimagesize($file_path);
if (!$img_width || !$img_height)
{
return false;
}
$scale = min(
$options['max_width'] / $img_width, $options['max_height'] / $img_height
);
if ($scale > 1)
{
$scale = 1;
}
$new_width = $img_width * $scale;
$new_height = $img_height * $scale;
$new_img = #imagecreatetruecolor($new_width, $new_height);
switch (strtolower(substr(strrchr($file_name, '.'), 1)))
{
case 'jpg':
case 'jpeg':
$src_img = #imagecreatefromjpeg($file_path);
$write_image = 'imagejpeg';
break;
case 'gif':
$src_img = #imagecreatefromgif($file_path);
$write_image = 'imagegif';
break;
case 'png':
$src_img = #imagecreatefrompng($file_path);
$write_image = 'imagepng';
break;
default:
$src_img = $image_method = null;
}
$success = $src_img && #imagecopyresampled(
$new_img, $src_img, 0, 0, 0, 0, $new_width, $new_height, $img_width, $img_height
) && $write_image($new_img, $new_file_path);
// Free up memory (imagedestroy does not delete files):
#imagedestroy($src_img);
#imagedestroy($new_img);
return $success;
}
private function has_error($uploaded_file, $file, $error)
{
if ($error)
{
return $error;
}
if (!preg_match($this->options['accept_file_types'], $file->name))
{
return 'acceptFileTypes';
}
if ($uploaded_file && is_uploaded_file($uploaded_file))
{
$file_size = filesize($uploaded_file);
} else
{
$file_size = $_SERVER['CONTENT_LENGTH'];
}
if ($this->options['max_file_size'] && (
$file_size > $this->options['max_file_size'] ||
$file->size > $this->options['max_file_size'])
)
{
return 'maxFileSize';
}
if ($this->options['min_file_size'] &&
$file_size < $this->options['min_file_size'])
{
return 'minFileSize';
}
if (is_int($this->options['max_number_of_files']) && (
count($this->get_file_objects()) >= $this->options['max_number_of_files'])
)
{
return 'maxNumberOfFiles';
}
return $error;
}
private function handle_file_upload($uploaded_file, $name, $size, $type, $error)
{
$fileUpload = new stdClass();
$fileUpload->name = basename(stripslashes($name));
$fileUpload->size = intval($size);
$fileUpload->type = $type;
$fileUpload->error = null;
$extension = end(explode(".", $fileUpload->name));
$fileUpload->error = $this->has_error($uploaded_file, $fileUpload, $error);
if (!$fileUpload->error)
{
if (strlen(trim($fileUpload->name)) == 0)
{
$fileUpload->error = 'Filename not found.';
}
}
elseif (intval($size) == 0)
{
$fileUpload->error = 'File received has zero size.';
}
elseif (intval($size) > $this->options['max_file_size'])
{
$fileUpload->error = 'File received is larger than permitted.';
}
if (!$fileUpload->error && $fileUpload->name)
{
if ($fileUpload->name[0] === '.')
{
$fileUpload->name = substr($fileUpload->name, 1);
}
$newFilename = MD5(microtime());
// figure out upload type
$file_size = 0;
// select server from pool
$uploadServerId = getAvailableServerId();
$db = Database::getDatabase(true);
$uploadServerDetails = $db->getRow('SELECT * FROM file_server WHERE id = ' . $db->quote($uploadServerId));
// override storage path
if(strlen($uploadServerDetails['storagePath']))
{
$this->options['upload_dir'] = $uploadServerDetails['storagePath'];
if (substr($this->options['upload_dir'], strlen($this->options['upload_dir']) - 1, 1) == '/')
{
$this->options['upload_dir'] = substr($this->options['upload_dir'], 0, strlen($this->options['upload_dir']) - 1);
}
$this->options['upload_dir'] .= '/';
}
// move remotely via ftp
if($uploadServerDetails['serverType'] == 'remote')
{
// connect ftp
$conn_id = ftp_connect($uploadServerDetails['ipAddress'], $uploadServerDetails['ftpPort'], 30);
if($conn_id === false)
{
$fileUpload->error = 'Could not connect to file server '.$uploadServerDetails['ipAddress'];
}
// authenticate
if(!$fileUpload->error)
{
$login_result = ftp_login($conn_id, $uploadServerDetails['ftpUsername'], $uploadServerDetails['ftpPassword']);
if($login_result === false)
{
$fileUpload->error = 'Could not authenticate with file server '.$uploadServerDetails['ipAddress'];
}
}
// create the upload folder
if(!$fileUpload->error)
{
$uploadPathDir = $this->options['upload_dir'] . substr($newFilename, 0, 2);
if(!ftp_mkdir($conn_id, $uploadPathDir))
{
// Error reporting removed for now as it causes issues with existing folders. Need to add a check in before here
// to see if the folder exists, then create if not.
// $fileUpload->error = 'There was a problem creating the storage folder on '.$uploadServerDetails['ipAddress'];
}
}
// upload via ftp
if(!$fileUpload->error)
{
$file_path = $uploadPathDir . '/' . $newFilename;
clearstatcache();
if ($uploaded_file && is_uploaded_file($uploaded_file))
{
// initiate ftp
$ret = ftp_nb_put($conn_id, $file_path, $uploaded_file,
FTP_BINARY, FTP_AUTORESUME);
while ($ret == FTP_MOREDATA)
{
// continue uploading
$ret = ftp_nb_continue($conn_id);
}
if ($ret != FTP_FINISHED)
{
$fileUpload->error = 'There was a problem uploading the file to '.$uploadServerDetails['ipAddress'];
}
else
{
$file_size = filesize($uploaded_file);
#unlink($uploaded_file);
}
}
}
// close ftp connection
ftp_close($conn_id);
}
// move into local storage
else
{
// create the upload folder
$uploadPathDir = $this->options['upload_dir'] . substr($newFilename, 0, 2);
#mkdir($uploadPathDir);
$file_path = $uploadPathDir . '/' . $newFilename;
clearstatcache();
if ($uploaded_file && is_uploaded_file($uploaded_file))
{
move_uploaded_file($uploaded_file, $file_path);
}
$file_size = filesize($file_path);
}
// check filesize uploaded matches tmp uploaded
if ($file_size === $fileUpload->size)
{
$fileUpload->url = $this->options['upload_url'] . rawurlencode($fileUpload->name);
// insert into the db
$fileUpload->size = $file_size;
$fileUpload->delete_url = '~d?' . $this->options['delete_hash'];
$fileUpload->info_url = '~i?' . $this->options['delete_hash'];
$fileUpload->delete_type = 'DELETE';
// create delete hash, make sure it's unique
$deleteHash = md5($fileUpload->name . getUsersIPAddress() . microtime());
$existingFile = file::loadByDeleteHash($deleteHash);
while ($existingFile != false)
{
$deleteHash = md5($fileUpload->name . getUsersIPAddress() . microtime());
$existingFile = file::loadByDeleteHash($deleteHash);
}
// store in db
$db = Database::getDatabase(true);
$dbInsert = new DBObject("file", array("originalFilename", "shortUrl", "fileType", "extension", "fileSize", "localFilePath", "userId", "totalDownload", "uploadedIP", "uploadedDate", "statusId", "deleteHash", "serverId"));
$dbInsert->originalFilename = $fileUpload->name;
$dbInsert->shortUrl = 'temp';
$dbInsert->fileType = $fileUpload->type;
$dbInsert->extension = $extension;
$dbInsert->fileSize = $fileUpload->size;
$dbInsert->localFilePath = str_replace($this->options['upload_dir'], "", $file_path);
// add user id if user is logged in
$dbInsert->userId = NULL;
$Auth = Auth::getAuth();
if ($Auth->loggedIn())
{
$dbInsert->userId = (int) $Auth->id;
}
$dbInsert->totalDownload = 0;
$dbInsert->uploadedIP = getUsersIPAddress();
$dbInsert->uploadedDate = sqlDateTime();
$dbInsert->statusId = 1;
$dbInsert->deleteHash = $deleteHash;
$dbInsert->serverId = $uploadServerId;
if (!$dbInsert->insert())
{
$fileUpload->error = 'abort';
}
// create short url
$tracker = 1;
$shortUrl = file::createShortUrlPart($tracker . $dbInsert->id);
$fileTmp = file::loadByShortUrl($shortUrl);
while ($fileTmp)
{
$shortUrl = file::createShortUrlPart($tracker . $dbInsert->id);
$fileTmp = file::loadByShortUrl($shortUrl);
$tracker++;
}
// update short url
file::updateShortUrl($dbInsert->id, $shortUrl);
// update fileUpload with file location
$file = file::loadByShortUrl($shortUrl);
$fileUpload->url = $file->getFullShortUrl();
$fileUpload->delete_url = $file->getDeleteUrl();
$fileUpload->info_url = $file->getInfoUrl();
$fileUpload->stats_url = $file->getStatisticsUrl();
$fileUpload->short_url = $shortUrl;
}
else if ($this->options['discard_aborted_uploads'])
{
//#TODO - made ftp compatible
#unlink($file_path);
#unlink($uploaded_file);
if(!isset($fileUpload->error))
{
$fileUpload->error = 'maxFileSize';
}
}
}
return $fileUpload;
}
public function get()
{
$file_name = isset($_REQUEST['file']) ?
basename(stripslashes($_REQUEST['file'])) : null;
if ($file_name)
{
$info = $this->get_file_object($file_name);
} else
{
$info = $this->get_file_objects();
}
header('Content-type: application/json');
echo json_encode($info);
}
public function post()
{
$upload = isset($_FILES[$this->options['param_name']]) ?
$_FILES[$this->options['param_name']] : array(
'tmp_name' => null,
'name' => null,
'size' => null,
'type' => null,
'error' => null
);
$info = array();
if (is_array($upload['tmp_name']))
{
foreach ($upload['tmp_name'] as $index => $value)
{
$info[] = $this->handle_file_upload($upload['tmp_name'][$index],
isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'][$index],
isset($_SERVER['HTTP_X_FILE_SIZE']) ? $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'][$index],
isset($_SERVER['HTTP_X_FILE_TYPE']) ? $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'][$index],
$upload['error'][$index]
);
}
} else
{
$info[] = $this->handle_file_upload($upload['tmp_name'],
isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'],
isset($_SERVER['HTTP_X_FILE_SIZE']) ? $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'],
isset($_SERVER['HTTP_X_FILE_TYPE']) ? $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'],
$upload['error']
);
}
header('Vary: Accept');
if (isset($_SERVER['HTTP_ACCEPT']) &&
(strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false))
{
header('Content-type: application/json');
} else
{
header('Content-type: text/plain');
}
echo json_encode($info);
}
}
$upload_handler = new uploadHandler();
header('Pragma: no-cache');
header('Cache-Control: private, no-cache');
header('Content-Disposition: inline; filename="files.json"');
// check we are receiving the request from this script
if (!checkReferrer())
{
// exit
header('HTTP/1.0 400 Bad Request');
exit();
}
switch ($_SERVER['REQUEST_METHOD'])
{
case 'HEAD':
case 'GET':
$upload_handler->get();
break;
case 'POST':
$upload_handler->post();
break;
default:
header('HTTP/1.0 405 Method Not Allowed');
}
You need downloader. Not uploader. You want to download a file to your server from another server. To achieve that from PHP, you can use cUrl or file_get_contents. In the form, just take the URL and when the form is submitted, download the file from that URL to your server using cUrl or file_get_contents().

Categories