Skip to content
This repository

save data to DB in the new index.php #957

Closed
danciu888 opened this Issue January 17, 2012 · 26 comments

7 participants

danciu888 Sunny Sahijwani chaudx vourexx sabatorio sahil cydo
danciu888

Hello,

I've read all the previous issues about saving data to sql and json errors, I've also read the numerous harsh replies that were given such as "the script was not intended for that" and so forth;

however,

I simply wanted to save into a DB the name of the uploaded pic, but every bit of PHP code I added to "index.php" (which handles the form) turned into a "SyntaxError: Unexpected token". I tried adding the code in the "handle_file_upload" function, at its end, just before returning the file object.

I would be really grateful if someone helped me, even though the script was intended for "enhancing the client-side file upload".

Thank you a million!

danciu888

Hi,

This is how I managed to add uploaded files to a DB, with no "SyntaxError" outputs.

First, add those two functions in the "php/index.php" (latest version of the script) file:

/*start sql insertion here*/
private function query($query) {
    $database = 'database';
    $host = 'localhost';
    $username = 'root';
    $password = 'password';
    $link = mysql_connect($host,$username,$password);
    if (!$link) {
       die(mysql_error());
    }
    $db_selected = mysql_select_db($database);
    if (!$db_selected) {
       die(mysql_error());
    }
    $result = mysql_query($query);
    return $result;
    mysql_close($link);
}

private function add_img($whichimg) {
    $this->user_name = $_SESSION['user_name']; // I used the following in order to add the pics to a certain user which was previously set with session on login
    $add_to_db = $this->query("INSERT INTO picturestable (picname,picusername) VALUES('$whichimg','$this->user_name')") or die(mysql_error());
    return $add_to_db;
}
/*end sql insertion here*/

ALSO, you need to add a line in the "handle_file_upload" function, at the end, BEFORE the last ELSE statement, BEFORE the close-bracket of "if (!$error && $file->name) {" (after "$file->delete_type = 'DELETE';") - the line you have to add is "$file->upload_to_db = $this->add_img($file->name);"

Both variables do not need escaping because it is not an user input - please correct me if I'm wrong.

Hope it helps,

Greets!

danciu888 danciu888 closed this January 18, 2012
Sunny Sahijwani

Hello,
When I tried the code at the position you mentioned then though I was able to save the file name and other details in database but after saving I get error "SyntaxError: JSON.parse: unexpected character". But if I refresh the page then thumbnails show up i.e. when user starts uploading then it shows this error though images are being saved properly and database insert statement has also executed successfully.. can you please suggest what I am doing wrong?

Thanks

danciu888

Please upload the code so I can take a look :)

Sunny Sahijwani

Hello,
Thanks for replying quickly. Please take a look at the index.php file I have mentioned its code below. I am really in need of a help. FYI, I have added my code between the single line comment like "// sunny code starts" and "// sunny code ends"

<?php
/*

error_reporting(E_ALL | E_STRICT);

class UploadHandler
{
private $options;

function __construct($options=null) {
    $this->options = array(
        'script_url' => $this->getFullUrl().'/'.basename(__FILE__),
        'upload_dir' => dirname(__FILE__).'/files/',
        'upload_url' => $this->getFullUrl().'/files/',
        'param_name' => 'files',
        // The php.ini settings upload_max_filesize and post_max_size
        // take precedence over the following max_file_size setting:
        'max_file_size' => null,
        'min_file_size' => 1,
        'accept_file_types' => '/.+$/i',
        'max_number_of_files' => null,
        // Set the following option to false to enable non-multipart uploads:
        'discard_aborted_uploads' => true,
        // Set to true to rotate images based on EXIF meta data, if available:
        'orient_image' => false,
        'image_versions' => array(
            // Uncomment the following version to restrict the size of
            // uploaded images. You can also add additional versions with
            // their own upload directories:
            /*
            'large' => array(
                'upload_dir' => dirname(__FILE__).'/files/',
                'upload_url' => dirname($_SERVER['PHP_SELF']).'/files/',
                'max_width' => 1920,
                'max_height' => 1200
            ),
            */
            'thumbnail' => array(
                'upload_dir' => dirname(__FILE__).'/thumbnails/',
                'upload_url' => $this->getFullUrl().'/thumbnails/',
                'max_width' => 80,
                'max_height' => 80
            )
        )
    );
    if ($options) {
        $this->options = array_replace_recursive($this->options, $options);
    }
}

function getFullUrl() {
    return
            (isset($_SERVER['HTTPS']) ? 'https://' : 'http://').
            (isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').
            (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].
            (isset($_SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] === 443 ||
            $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).
            substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
}

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 = $this->options['script_url']
            .'?file='.rawurlencode($file->name);
        $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':
            @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
            $src_img = @imagecreatefromgif($file_path);
            $write_image = 'imagegif';
            break;
        case 'png':
            @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
            @imagealphablending($new_img, false);
            @imagesavealpha($new_img, true);
            $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 trim_file_name($name, $type) {
    // Remove path information and dots around the filename, to prevent uploading
    // into different directories or replacing hidden system files.
    // Also remove control characters and spaces (\x00..\x20) around the filename:
    $file_name = trim(basename(stripslashes($name)), ".\x00..\x20");
    // Add missing file extension for known image types:
    if (strpos($file_name, '.') === false &&
        preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
        $file_name .= '.'.$matches[1];
    }
    return $file_name;
}

private function orient_image($file_path) {
    $exif = exif_read_data($file_path);
    $orientation = intval(@$exif['Orientation']);
    if (!in_array($orientation, array(3, 6, 8))) { 
        return false;
    }
    $image = @imagecreatefromjpeg($file_path);
    switch ($orientation) {
          case 3:
            $image = @imagerotate($image, 180, 0);
            break;
          case 6:
            $image = @imagerotate($image, 270, 0);
            break;
          case 8:
            $image = @imagerotate($image, 90, 0);
            break;
        default:
            return false;
    }
    $success = imagejpeg($image, $file_path);
    // Free up memory (imagedestroy does not delete files):
    @imagedestroy($image);
    return $success;
}

private function handle_file_upload($uploaded_file, $name, $size, $type, $error) {
    $file = new stdClass();
    $file->name = $this->trim_file_name($name, $type);
    $file->size = intval($size);
    $file->type = $type;
    $error = $this->has_error($uploaded_file, $file, $error);
    if (!$error && $file->name) {
        $file_path = $this->options['upload_dir'].$file->name;
        $append_file = !$this->options['discard_aborted_uploads'] &&
            is_file($file_path) && $file->size > filesize($file_path);
        clearstatcache();
        if ($uploaded_file && is_uploaded_file($uploaded_file)) {
            // multipart/formdata uploads (POST method uploads)
            if ($append_file) {
                file_put_contents(
                    $file_path,
                    fopen($uploaded_file, 'r'),
                    FILE_APPEND
                );
            } else {
                move_uploaded_file($uploaded_file, $file_path);
            }
        } else {
            // Non-multipart uploads (PUT method support)
            file_put_contents(
                $file_path,
                fopen('php://input', 'r'),
                $append_file ? FILE_APPEND : 0
            );
        }
        $file_size = filesize($file_path);
        if ($file_size === $file->size) {
                if ($this->options['orient_image']) {
                    $this->orient_image($file_path);
                }
            $file->url = $this->options['upload_url'].rawurlencode($file->name);
            foreach($this->options['image_versions'] as $version => $options) {
                if ($this->create_scaled_image($file->name, $options)) {
                    $file->{$version.'_url'} = $options['upload_url']
                        .rawurlencode($file->name);
                }
            }
        } else if ($this->options['discard_aborted_uploads']) {
            unlink($file_path);
            $file->error = 'abort';
        }
        $file->size = $file_size;
        $file->delete_url = $this->options['script_url']
            .'?file='.rawurlencode($file->name);
        $file->delete_type = 'DELETE';
        // sunny code starts
        $this->add_img($file->name);
        // sunny code ends
    } else {
        $file->error = $error;
    }
    return $file;
}

// sunny code starts
/*start sql insertion here*/

private function query($query) {
$database = 'dbname';
$host = 'localhost';
$username = 'root';
$password = '';
$link = mysql_connect($host,$username,$password);
if (!$link) {
die(mysql_error());
}
$db_selected = mysql_select_db($database);
if (!$db_selected) {
die(mysql_error());
}
$result = mysql_query($query);
return $result;
mysql_close($link);
}

private function add_img($whichimg) {
$this->user_name = $_SESSION['user_name']; // I used the following in order to add the pics to a certain user which was previously set with session on login
$this->user_name = 'hamra';
$add_to_db = $this->query("INSERT INTO tblphotos (filepath,name) VALUES('".$whichimg."','".$this->user_name."')") or die(mysql_error());
return $add_to_db;
}
/end sql insertion here/

// sunny code ends
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() {
    if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE') {
        return $this->delete();
    }
    $upload = isset($_FILES[$this->options['param_name']]) ?
        $_FILES[$this->options['param_name']] : null;
    $info = array();
    if ($upload && 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]
            );
        }
    } elseif ($upload || isset($_SERVER['HTTP_X_FILE_NAME'])) {
        $info[] = $this->handle_file_upload(
            isset($upload['tmp_name']) ? $upload['tmp_name'] : null,
            isset($_SERVER['HTTP_X_FILE_NAME']) ?
                $_SERVER['HTTP_X_FILE_NAME'] : (isset($upload['name']) ?
                    isset($upload['name']) : null),
            isset($_SERVER['HTTP_X_FILE_SIZE']) ?
                $_SERVER['HTTP_X_FILE_SIZE'] : (isset($upload['size']) ?
                    isset($upload['size']) : null),
            isset($_SERVER['HTTP_X_FILE_TYPE']) ?
                $_SERVER['HTTP_X_FILE_TYPE'] : (isset($upload['type']) ?
                    isset($upload['type']) : null),
            isset($upload['error']) ? $upload['error'] : null
        );
    }
    header('Vary: Accept');
    $json = json_encode($info);
    $redirect = isset($_REQUEST['redirect']) ?
        stripslashes($_REQUEST['redirect']) : null;
    if ($redirect) {
        header('Location: '.sprintf($redirect, rawurlencode($json)));
        return;
    }
    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;
}

public function delete() {
    $file_name = isset($_REQUEST['file']) ?
        basename(stripslashes($_REQUEST['file'])) : null;
    $file_path = $this->options['upload_dir'].$file_name;
    $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
    if ($success) {
        foreach($this->options['image_versions'] as $version => $options) {
            $file = $options['upload_dir'].$file_name;
            if (is_file($file)) {
                unlink($file);
            }
        }
    }
    header('Content-type: application/json');
    echo json_encode($success);
}

}

$upload_handler = new UploadHandler();

header('Pragma: no-cache');
header('Cache-Control: private, no-cache');
header('Content-Disposition: inline; filename="files.json"');
header('X-Content-Type-Options: nosniff');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: OPTIONS, HEAD, GET, POST, PUT, DELETE');
header('Access-Control-Allow-Headers: X-File-Name, X-File-Type, X-File-Size');

switch ($_SERVER['REQUEST_METHOD']) {
case 'OPTIONS':
break;
case 'HEAD':
case 'GET':
$upload_handler->get();
break;
case 'POST':
$upload_handler->post();
break;
case 'DELETE':
$upload_handler->delete();
break;
default:
header('HTTP/1.1 405 Method Not Allowed');
}

danciu888

Hello again,

$this->user_name = $_SESSION['user_name']; // I used the following in order to add the pics to a certain user which was previously set with session on login
$this->user_name = 'hamra';

Do you have a session with the name 'user_name' set? If not, remove that line and just let the next one. If yes (--remove the second line if you want the variable to be equal to whichever the session returns), have you added "session_start();" at the beginning of the index.php file, right after the php open tag?

Issues like those may trigger a syntax error imo.

Tell me whether this solved the issue! Greets! :)

Sunny Sahijwani

Hello,
Yes, this worked this time. My apologies, I don't know how but I forgot to put session_start on top. But this was unexpected to me, I happened to have seen that PHP does not through any error message or anything in return if the session is not on or if you try to access a variable that does not exists, it just goes empty... but now I feel that PHP was throwing some error message which was being collected as part of Json string.. is that right?

Thanks again :)

danciu888

Yes :)

Np, I'm glad that it worked :)

Sunny Sahijwani

Hello Danciu,
You have been very helpful to me in the integration. With your help and a little bit of brainstorming, I am able to save file names in database and submit additional data as well for every image that user uploads. But I am stuck on one thing, I am not sure how to show images after upload from database i.e. after user uploads then at present the system shows images from the folder whereas I want to show user the selected photos by taking there name from database. Can you please guide me?

Thank you very much

danciu888

Hi again :)

There is a "download" table in the html file in which I removed the Delete button and such, leaving only the file name (you can also leave the thumb - I didn't use that functionality so it had no point for me), size and an "uploaded" message.

I didn't modify the files in the script furthermore to avoid serious headaches.

So, after the script tables (both upload and download), I created a div which is set to visible with jquery after the upload is complete (...
modify jquery.fileupload.js at the "_onDone" function - line 484 in my script - and add at the end of it your jquery code - mine is:
$("#uploadedpicsh").show();
$("#uploadedpicsh").load('picsmanagerload.php');
...).
In that div you have to call a php script which reads your uploaded pics and everything else you need to do.

Need further help?

Greets!

Sunny Sahijwani

I am sorry, I could not follow you here. actually I want to use the same interface that jquery has, its good UI and I want to stick to it and by default just show the images by making DB query and showing the records. After this I will customize the delete function too and delete record from DB and then unlink file. For now, I tried to customize the get() function from php/index.php and I did something like this using DB class I have made:-
public function get() {
$file_name = isset($_REQUEST['file']) ?
basename(stripslashes($_REQUEST['file'])) : null;
$sql="select name,filepath from tblphotos ";
$this->query($sql);
$rows=$this->fetchRows();
foreach($rows as $row)
{
if ($row['filepath']) {
$info = $this->get_file_object($row['filepath']);
} else {
$info = $this->get_file_objects();
}
}
header('Content-type: application/json');
echo json_encode($info);
}

but it does not show anything by default. I did extended my DB class to the "UploadHandler"
Please help me.
Thanks

danciu888

shouldn't you have modified the post function instead? anyway, most of the php in there is json-encoded, do you really prefer getting headaches instead of creating a small php script + jquery function(s) that will work with the upload script?

Sunny Sahijwani

I can completely understand what you are saying must be correct, but since I am new to this, so asking such silly questions. Okay, so you are saying that I should change the code of post function and the json that it returns is the json code that it displays after file upload.. right? and in this place I can do the select query and fetch records and put them in json format and just return... am I right?
Please help me.

danciu888

that was just a wild guess, I don't know exactly whether it's that, something else or even something in the JS file - I haven't had the time to go that far, especially that I'm not a JSON expert so I commented some of the index.php file and created my own php that reads the uploaded files and my own jquery script that hides the current pic DIV on delete, refreshes the main div on picture upload etc.

Now that I go through index.php, I see that I commented the following function:

/*private function get_file_objects() {
    return array_values(array_filter(array_map(
        array($this, 'get_file_object'),
        scandir($this->options['upload_dir'])
    )));
}*/

also, the get_file_object function.

Try working around those two first and see what you'll get (imo, a LOT of JSON errors GRIN)

chaudx

sansphp, I read that you had managed to insert data for each image in mysql.
Could you tell me how you did it, show a piece of code or something?.
I also managed to insert the image name, but when I try to insert a description for each image, all the rows in mysql inserted the data provided for the first image.

thanks

Sunny Sahijwani

Hi Chaudx, Sure, I will send you detailed reply in about 12hours.
Thanks

chaudx

thanks, i look forward

Sunny Sahijwani

Hi Chaudx,
I am sorry for late reply, been really busy these days.
Anyways I have uploaded the whole code folder at http://www.digportfolio.com/multipleuploadamended_uploaded.zip (This link is active for 4days).

To also insert the description with each image I made below mentioned changes:-
a. Change in Javascript in index.php file: The change I made was to add the script to generate textbox corresponding to every image user selects. I did this in script id="template-upload" took a variable with j with value like 'title1', 'title2',.. so on. and with the code line

I am adding textbox to each image.
b. PHP work in PHP/index.php: In PHP I used session $_SESSION['count'] because while assigning name to textboxes I used the name like title1, title2.. in this case when user uploads lets say 4 pics, since after uploading value of K will not be zero because no refresh is taking place, so I used session similar to variable k in javascript. I am sure there must be another efficient way of doing this as well, but this served my purpose.
c. After saving the next thing was to list the images from database and I managed to do this from php/index.php file by changing a little script in function get_file_objects(), just replace the function scandir($this->options['upload_dir']) with the array of name of images like 'a.jpg', 'b.jpg' i.e. pull names like this from database and rest will work by itself.

I hope this helps. Feel free to let me know if I can help in any other way. I will try to be as quick as I can
Thanks
Sunny

chaudx

Hi sansphp:
Thanks for the help, great work!
I had something similar, but with common variables. Unfortunately, the problem appeared when you refresh the page.
With your code was the same, but I had not thought of using session variables.
Finally, I managed to do that when you refresh the page $ _SESSION ['count'] back to 0.
Obviously I would not have done it without your help and clear explanation you gave.

thank you very much

Sunny Sahijwani

Thank you, I am happy it worked for you.

vourexx

hello you can send me your code? becuase i work so hard so many days to do that but unsuccessful

Sunny Sahijwani

Hello Vourexx,
Please find below the link to download the setup I already shared before with Chaudx:-
http://www.digportfolio.com/multipleuploadamended_uploaded.zip (Active for coming 3 days)

Let me know if I can help in any other way.
Thanks
Sunny

Sunny Sahijwani

So now that we know how to save additional details but I am unable to find the way to show those additional details while loading images from database. Showing additional details of the image like Title that user gave to the image, category that user selected, etc. Please help.

Thanks

sabatorio

Hi Sunny,
I am quite new to this JSON stuff, please can you help me with your code cos I want to add description and probably image title to the database image...

You are great... Thanks a billion.

Sabatorio

Sunny Sahijwani

Hi Sabatorio,
Please find below the link to download the zip file.
http://www.digportfolio.com/multipleuploadamended_textarea.zip
This setup will allow you to browse multiple files and give you ability to specify the textbox and a textarea for every image you choose.
Hope this helps.
Sorry for the delay.
Thanks
Sunny

sahil

can any one customised it for joomla... ?

cydo
cydo commented August 22, 2012

thanks danciu888 for the code, i have successfully link and store uploaded file data into my database.

i have one problem left which is if i click on the delete button, except that the uploaded file being deleted, i also want it to be deleted off from the database respectively (depend on which file that i delete in random)
im still new to this json, php mysql things, im so gratefull if you can help me with a code here

thanks in advanced
cydo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.