PHP Custom Upload Problem

PHP Custom Upload Problem

gordonc200gordonc200 Posts: 39Questions: 7Answers: 0
edited June 2017 in Free community support

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

  • gordonc200gordonc200 Posts: 39Questions: 7Answers: 0

    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.

    Upload::inst( function ($file, $fId)
    

    I can't really get my head around it.

  • allanallan Posts: 63,205Questions: 1Answers: 10,415 Site admin

    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

  • gordonc200gordonc200 Posts: 39Questions: 7Answers: 0

    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

    //'ACL' => 'public-read'
    
    'ACL' => 'private'
    

    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!

  • gordonc200gordonc200 Posts: 39Questions: 7Answers: 0

    I've managed to sort this I think. All that was required was to add a return statement similar to the example code.

        } catch(S3Exception $e) {
            die("There was an error uploading that file.");
        }
        return $fId;
     } )
    
  • allanallan Posts: 63,205Questions: 1Answers: 10,415 Site admin
    Answer ✓

    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 the db method.

    Great to hear its running now!

    Regards,
    Allan

This discussion has been closed.