PHP Custom Upload Problem
PHP Custom Upload Problem
I have a script to upload files to AWS S3 which works fine. This file is in the same folder as my datatables script which also works perfectly well. However, when I change the datatables script to a custom upload function it will not work. I'm wondering where I'm going wrong.
I have been at this all afternoon but can't work it out!
My Datatables script (with other irrelevant fields removed for clarity) is as follows.
<?php
/*
* Editor server script for DB table drawings
* Created by http://editor.datatables.net/generator
*/
use Aws\S3\Exception\S3Exception;
include("lib/DataTables.php");
// Alias Editor classes so they are easy to use
use
DataTables\Editor,
DataTables\Editor\Field,
DataTables\Editor\Format,
DataTables\Editor\Mjoin,
DataTables\Editor\Options,
DataTables\Editor\Upload,
DataTables\Editor\Validate;
// Build our Editor instance and process the data coming from _POST
Editor::inst($db, 'drawings', 'id')
->fields(
Field::inst('drawings.fId')
->setFormatter( 'Format::ifEmpty', null )
->upload(
//Upload::inst( function ($_SERVER['DOCUMENT_ROOT'].'/filepath/__ID__.__EXTN__') {
Upload::inst( function ($file, $fId) {
require 'start.php';
//File details
$name = $file['name'];
$tmp_name = $file['tmp_name'];
$extension = explode('.', $name);
$extension = strtolower(end($extension));
//var_dump($extension);
//Temp details
$key = md5(uniqid());
$tmp_file_name = "{$key}.{$extension}";
$tmp_file_path = "/actual/file/path/{$tmp_file_name}";
//var_dump($tmp_file_path);
//Move the file
move_uploaded_file($tmp_name, $tmp_file_path);
try {
$s3->putObject([
'Bucket' => $config['s3']['bucket'],
'Key' => "uploads/{$name}",
'Body' => fopen($tmp_file_path, 'rb'),
//'ACL' => 'public-read'
]);
//remove the file
unlink($tmp_file_path);
} catch(S3Exception $e) {
die("There was an error uploading that file.");
}
} )
->db( 'files', 'fId', array(
'files.fileName' => Upload::DB_FILE_NAME,
'files.fileSize' => Upload::DB_FILE_SIZE,
'files.webPath' => "NotEntered",
'files.systemPath' => "NotEntered",
'files.s3FilePath' => "NotEntered"
) )
->validator( function ( $file ) {
return $file['size'] >= 104857600 ?
"Files must be smaller than 100Mb" :
null;
} )
->allowedExtensions( array( 'png', 'jpg', 'gif', 'pdf' ), "Please upload an allowed file type" )
),
Field::inst('files.fId')
->validator('Validate::notEmpty')
)
->leftJoin('files', 'files.fId', '=', 'drawings.fId')
->process($_POST)
->json();
The script I have in the same folder which works standalone and I'm trying to adapt to work in datatables is as follows
<?php
/**
* Created by PhpStorm.
* User: gordon
* Date: 28/06/17
* Time: 16:30
*/
use Aws\S3\Exception\S3Exception;
require 'start.php';
if(isset($_FILES['file'])) {
$file = $_FILES['file'];
//File details
$name = $file['name'];
$tmp_name = $file['tmp_name'];
$extension = explode('.', $name);
$extension = strtolower(end($extension));
//var_dump($extension);
//Temp details
$key = md5(uniqid());
$tmp_file_name = "{$key}.{$extension}";
$tmp_file_path = "/files/{$tmp_file_name}";
//var_dump($tmp_file_path);
//Move the file
move_uploaded_file($tmp_name, $tmp_file_path);
try {
$s3->putObject([
'Bucket' => $config['s3']['bucket'],
'Key' => "uploads/{$name}",
'Body' => fopen($tmp_file_path, 'rb'),
//'ACL' => 'public-read'
]);
//remove the file
unlink($tmp_file_path);
} catch(S3Exception $e) {
die("There was an error uploading that file.");
}
}
<?php
>
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name = "file">
<input type="submit" value="Upload">
</form>
</body>
</html>
Any help or pointers would be welcomed.
This question has an accepted answers - jump to answer
Answers
To be clear the problem I have is not in writing to the database, that's all fine, it's the actual uploading of the file. I'm not sure what the function arguments represent from the information posted from the datatables editor file uploader.
I can't really get my head around it.
Hi,
The two parameters being passed in are:
$file
- The file information that PHP's_FILES
global has about the uploaded file. Note that although the PHP documentation refers to$_FILES['userfile']['name']
- the array given here just has the final properties - i.e.['name']
since the function is called on a per file basis (if multiple files were uploaded).$fId
- The id being returned by the newly inserted row into the database (useful for renaming the file so you can reference it later).When you stay that there is a problem with it - is there a specific error message that is happening? The one thing that stands out for me is that I don't see where
$config
is being defined - is that in the required script or in the host script? It might be a scoping issue if the latter.Are there any error messages shown in the server's error log? Or anything shown in the response from the server to the upload request (which you will be able to see in your browser's Network inspector tools)?
Thanks,
Allan
Hi Allan
The config is required in the start file. It's setup per the following
https://youtu.be/HDxCDdZFh9g?t=2m18s
I know that this works as I have the basic upload system this series of tutorials goes on to create working. The upload.php file/form sits and works in the same folder as the datatables php. I just need to cobble the php from the upload.php into the custom upload in my datatables script.
I'm not getting any records in the server error logs but I am getting the message "A server error occurred while uploading the file" on my datatables editor form under the file upload field.
Having just messed around more to try and get information to you it would seem the files are now actually uploading. The one thing I had changed was
This is a setting for the file on S3. The default is private and so I'd just commented out setting an it but explicitly stating it seems to make a difference.
Unfortunately however I'm still getting the server error message and editor is telling me no file has been upload when it actually has.
I can't help but feel I'm a line or two of code away here!
I've managed to sort this I think. All that was required was to add a return statement similar to the example code.
I should have spotted that myself - I was even thinking about it when writing the description of those two parameters. The idea is that if you weren't using the built in
db
method, you can generate the id some other way and have the custom action return it. But by that token it also needs to be returned even when you do use thedb
method.Great to hear its running now!
Regards,
Allan