Trying to upload an image and getting an error

Brilliant :slight_smile:

Something I’ve just noticed…  The OP has made over 900 posts, and yet this is in the ‘Newbie Questions’ forum.

Everyone learns in different ways and at different rates. Some people ask a lot of questions others need less help. Lets keep in mind that we are all different but share a common goal of wanting to develop with Corona.  

As always, you are at your own discretion when you choose to help answer questions and we are very grateful when you do, but calling developers out isn’t productive or helpful for the health of the community.

Thank you for understanding

Rob

Ordinarily I’d agree Rob and everyone needs a helping hand sometimes, but this particular poster doesn’t seem to be learning anything, or indeed interested in learning anything. He wants ready-made code and us (you in this case, since September) to do all the work. At least you’re being paid for it! :slight_smile:

None of the nuggets of wisdom dished out on other threads on various other projects is ever applied to the next problem, because it is ignored. The resulting solution is plugged in and if it works great, if it doesn’t, it’s back to the thread (or stackoverflow).

I will say no more on the subject as the message doesn’t seem to get across anyway, I’m off to housebuilder.com to ask how to do a loft conversion. Can’t be that hard, just chuck some wood and a hammer at it?

Is there anyway to keep people from posting on my posts or block them ?

yeah I didn’t post my php code because you said we should take care of this side first . But here it is ?

ini\_set('display\_errors', 1); ini\_set('display\_startup\_errors', 1); error\_reporting(E\_ALL); session\_start(); $con = new mysqli("localhost", "hashx10h\_brandon", "bigman23", "hashx10h\_hash"); if ($con-\>connect\_error) { die("Connection failed: " . $con-\>connect\_error); } \<?php $username = isset($\_SESSION['username']) ? $\_SESSION['username'] : ""; $info = date('Y-m-d\_H-i-s'); if(!empty($username)) { if (isset($\_FILES['fileToUpload'])) { $errors= array(); $file\_name = $\_FILES['fileToUpload']['name']; $file\_size = $\_FILES['fileToUpload']['size']; $width = 1500; $height = 1500; $file\_tmp = $\_FILES['fileToUpload']['tmp\_name']; $file\_type = $\_FILES['fileToUpload']['type']; $tmp = explode('.',$\_FILES['fileToUpload']['name']); $file\_ext=strtolower (end ($tmp)); $extensions= array("jpeg","jpg","png"); if(in\_array($file\_ext,$extensions)=== false){ $errors[]="extension not allowed, please choose a JPEG or PNG file."; } if ($file\_size \> 8097152) { $errors[] = 'File size must be 2 MB'; } if ($width \> 1500 || $height \> 1500) { echo"File is to large"; } if(empty($errors)==true) { move\_uploaded\_file($file\_tmp,"uploads/".date('Y-m-d\_H-i-s').$file\_name); $store = "UPDATE users SET userPic='".mysqli\_real\_escape\_string( $conn, date('Y-m-d\_H-i-s').$file\_name )."', date\_time='" . $info . "' WHERE username='".mysqli\_real\_escape\_string( $conn, $username )."'"; header('Location: http://localhost/interpage/profile.php'); if(mysqli\_query($conn, $store)) { } else { echo "Upload failed!"; } }else{ print\_r($errors); echo"Couldn't upload picture"; } }} else { echo "Invalid Username"; } ?\> \<?php $getimg = mysqli\_query($conn,"SELECT userPic, date\_time FROM users WHERE username='".mysqli\_real\_escape\_string( $conn, $username )."'"); $rows=mysqli\_fetch\_array($getimg); $img = $rows['userPic']; ?\>

This is code I just entered . I’ll try it now . (I posted because maybe you’ll catch something I won’t).

No, we can’t block people from posting on your posts. You don’t want that.

On your Corona side. This line appears to be incorrect too:

multipart:addFile("Image", path, "uploads/", userName .. ".jpg")

The third parameter isn’t a path, it appears to be a “MIME Type”. It should be “image/jpg” like in the example

multipart:addFile("Image", path, "image/jpg",&nbsp;userName ..&nbsp;".jpg")

I’ll have to look at the PHP later, but it looks like it has problems too.

Rob

UPDATED PHP CODE :

ini\_set('display\_errors', 1); ini\_set('display\_startup\_errors', 1); error\_reporting(E\_ALL); session\_start(); $con = new mysqli("localhost", "hashx10h\_brandon", "bigman23", "hashx10h\_hash"); if ($con-\>connect\_error) { die("Connection failed: " . $con-\>connect\_error); } $username = isset($\_SESSION['username']) ? $\_SESSION['username'] : ""; $info = date('Y-m-d\_H-i-s'); if(!empty($username)) { if (isset($\_FILES['fileToUpload'])) { $errors= array(); $file\_name = $\_FILES['fileToUpload']['name']; $file\_size = $\_FILES['fileToUpload']['size']; $width = 1500; $height = 1500; $file\_tmp = $\_FILES['fileToUpload']['tmp\_name']; $file\_type = $\_FILES['fileToUpload']['type']; $tmp = explode('.',$\_FILES['fileToUpload']['name']); $file\_ext=strtolower (end ($tmp)); $extensions= array("jpeg","jpg","png"); if(in\_array($file\_ext,$extensions)=== false){ $errors[]="extension not allowed, please choose a JPEG or PNG file."; } if ($file\_size \> 8097152) { $errors[] = 'File size must be 2 MB'; } if ($width \> 1500 || $height \> 1500) { echo"File is to large"; } if(empty($errors)==true) { move\_uploaded\_file($file\_tmp,"uploads/".date('Y-m-d\_H-i-s').$file\_name); $store = "UPDATE users SET userPic='".mysqli\_real\_escape\_string( $con, date('Y-m-d\_H-i-s').$file\_name )."', date\_time='" . $info . "' WHERE username='".mysqli\_real\_escape\_string( $con, $username )."'"; echo"uploaded"; if(mysqli\_query($con, $store)) { } else { echo "Upload failed!"; } }else{ print\_r($errors); echo"Couldn't upload picture"; } }} else { echo "Invalid Username"; } $getimg = mysqli\_query($con,"SELECT userPic, date\_time FROM users WHERE username='".mysqli\_real\_escape\_string( $con, $username )."'"); $rows = mysqli\_fetch\_array($getimg); $img = $rows['userPic'];

Also no errors are being printed in my php code 

Is this code any better ? 

 -- Selection completion listener local function onComplete( event ) local photo = event.target if photo then print( "photo w,h = " .. photo.width .. "," .. photo.height ) local multipart = MultipartFormData.new() local path = system.pathForFile( userName .. ".jpg", system.TemporaryDirectory ) multipart:addFile("Image", path, "image/jpg", userName .. ".jpg") local params = {} params.body = multipart:getBody() params.headers = multipart:getHeaders() -- Headers not valid until getBody() is called. network.request("https://http://hash.x10host.com/cgi-bin/hash/upload.php/services/imageupload?parameter=1", "POST", listener, params) end end local function pickPhoto( event ) media.selectPhoto( { mediaSource = media.SavedPhotosAlbum, listener = onComplete, origin = button.contentBounds, permittedArrowDirections = { "right" }, destination = { baseDir=system.TemporaryDirectory, filename= userName .. ".jpg" } }) end

Also the way the code it setup now, will it go into the uploads folder or sandbox ?

Passes nick some nails and a hammer… now if you could reply with the full code to build Canary Wharf that would be great!

I was just reading the docs and it says  Most existing scripts that accept file upload probably won’t work with network.upload() because they’re looking for an HTTP POSTform-based MIME multi-part upload format. 

Does that mean I have to change all of my POST’S to PUT ?

If you’re using the multipart mime library, you want to use POST. You’re not using network.upload().

The Corona side is almost there.  This line has an error in it:

network.request("https://http://hash.x10host.com/cgi-bin/hash/upload.php/services/imageupload?parameter=1", "POST", listener, params)

You can’t have https:// and http:// in the same URL. I don’t know if your server is an http: or https: server. You need to figure that out on your own.

Now looking at your PHP script, I don’t know what fields will actually be passed to it. However, you are running a script at the path:

/cgi-bin/hash/upload.php.

Your script is trying to write to a folder named:

/cgi-bin/hash/upload/

which I do not know if it exists but I can’t see any web host allowing you to write arbitrary files into the /cgi-bin path. No one here can help you with the server side unless you are willing to give them access to your server and probably pay them to help you.

Rob

Oh wait . The cgi-bin path is where the upload.php script is . I have a separate folder called uploads for the images uploaded in my corona project folder .

Is this better ? 

network.request("http://hash.x10host.com/cgi-bin/hash/upload.php?parameter=1", "POST", listener, params)

Does this 

        local path = system.pathForFile( userName … “.jpg”, system.TemporaryDirectory )

        multipart:addFile(“Image”, path, “image/jpg”, userName … “.jpg”)

send any jpg image the user tries to upload in the sandbox ?

Do you understand the workflow that you’re trying to do?

  1. Let the user select a picture from their camera roll.

  2. Copy that picture to system.TemporaryDirectory and name it based on whatever you have in the variable userName with a .jpg extension.

  3. Setup data to be sent to your web server using the multipart library

  4. Send the data using network.request()

  5. A script in your CGI-BIN folder on your web server receives the upload

  6. You potentially have to base64 decode the image file.

  7. in that script save the image to a folder on your web server (not your Corona app) that you have permissions to write the file to.

So when you say any jpg image in the sandbox, the answer is no. It can only send a file named after the value in userName with a .jpg extension. But your user can pick any photo out of their camera roll and save it to your sandbox. So from that perspective sure, but it will overwrite whatever userName.jpg is on the server so you will only have one file there.

The only one of those I am able to accomplish is letting the user select the photo from their camera role . When the user clicks on the picture it just goes back to the app and nothing happens . 

The app is an instagram like app which means they can upload as many pictures as they want, which is not what I am trying to do now . Now I am trying to let them upload one profile picture whenever they want .

This might get you closer to your goal if you want to check it out. I haven’t gotten the multipart form upload part to work, but the image is being saved to the sandbox ok and is ready to be uploaded:

[lua]

local photo – holds the photo object

local PHOTO_FUNCTION = media.PhotoLibrary – or media.SavedPhotosAlbum?

local tmpDirectory = system.TemporaryDirectory

local photoGroup

local localPhotoFileName=“test.jpg”

local btn_selectFromGallery


– prepare the image for upload by saving it to the sandbox temporary directory


local function prepImageForUpload()

     print( “saving”…localPhotoFileName )

     --save the image to the local app sandbox

     display.save(photoGroup, localPhotoFileName, tmpDirectory)

     print( “pic saved in temp directory, uploading now” )

     --finally upload the pic

     uploadPic()-- this would be your custom local function, needs work

end


– Executes after the user selects a pic from the gallery (or cancels)


local handleDoneSelectingPic= function(event)

     photo = event.target

     print(“done selecting pic”)

  

     if photo then

          print( “picSelected” )

          photoGroup = display.newGroup()

          --this shows it on the screen too

          photoGroup:insert(photo)

          photoGroup:scale(.3,.3)

          photoGroup.x = display.contentWidth/2

          photoGroup.y = display.contentWidth/2-100

          localPhotoFileName=“photoSelected”…math.random(100000, 999999)…".jpg"

          --save image after delay so that not in gallery picker and it has time to actually be rendered on the screen 

          timer.performWithDelay( 500, prepImageForUpload )   

     else

          print( “No Image Selected” )

     end

end


– btn handler that opens the gallery


local btn_selectFromGallery

local function selectFromGalleryBtn_handler( event )

     – Delay a bit to allow the display to display refresh before calling the Photo Picker, then open it

     timer.performWithDelay( 100, function() media.selectPhoto( { listener = handleDoneSelectingPic, mediaSource = PHOTO_FUNCTION } ) end )

     return true

end


— just the selectFromGallery button


btn_selectFromGallery=display.newImage(“images/btn_uploadPics.png”,centerX,450) 

    btn_selectFromGallery:addEventListener(“tap”, selectFromGalleryBtn_handler)

    sceneGroup:insert(btn_selectFromGallery)

[/lua]