Send file from HTML form to AWS S3 Bucket - php

I'm taking the file from a html form and then uploading it to an AWS S3 bucket.
The following code finds the path of the file on my computer and then uploads it to S3:
$bucketname = 'we-sign-files';
$file_path = '/Users/dripz/Desktop/wesign/uploads/5f31fc30410c17.68431957.jpg';
$key = basename($file_path);
try {
$s3->putObject([
'Bucket' => $bucketname,
'Key' => $key,
'Body' => fopen($file_path, 'r')
]);
} catch (Aws\S3\Exception\S3Exception $e) {
echo $e->getMessage();
}
What code should I put in the $file_path = variable to take the image from the users' computer and then upload to S3?

Use file_get_contents:
file_get_contents($_FILES['uploadedfileFormField']['tmp_name']);
and then you don't need: fopen.
Try-catch and error handling you have to take care of.
$bucketname = 'we-sign-files';
$fileName = $_FILES['uploadedfileFormField']['tmp_name'];
$file_path = file_get_contents($fileName);
$key = basename($fileName);
try {
$s3->putObject([
'Bucket' => $bucketname,
'Key' => $key,
'Body' => $file_path
]);
} catch (Aws\S3\Exception\S3Exception $e) {
echo $e->getMessage();
}

Related

s3 presigned url updating but cloudfront url not updating image

I am running into a problem with s3.
I allow the user to upload images on my website.
When an image is uploaded it stores in s3 and I use the [cloudfront] cdn to display the image.
But now i'm allowing the user to rotate the image. The user clicks the rotate button and the image rotates 90deg and stores back into s3. when I use s3 presigned url it shows that the image has rotated but when I use [cloudfront] url it still shows me the old image.
heres my code
$rotated = 0;
$fileName = $_POST['file'];
$originalFileName = $_POST['file'];
$keyName = basename($fileName);
//Creating a presigned URL
$cmd = $s3->getCommand('GetObject', [
'Bucket' => $bucketName,
'Key' => "uploads/" . $keyName,
]);
$request = $s3->createPresignedRequest($cmd, '+20 minutes');
// Get the actual presigned-url
$presignedUrl = (string)$request->getUri();
$img = basename($originalFileName);
// For this, I would generate a unqiue random string for the key name. But you can do whatever.
$keyName = 'uploads/' . $img;
$pathInS3 = 'https://<cloudfront_distribution_url>/' . $keyName;
$fileName = $pathInS3;
$degrees = 90;
$url = $fileName;
file_put_contents("../../../../uploads/" . $img, file_get_contents($url));
$source = imagecreatefromjpeg($fileName);
$rotate = imagerotate($source, $degrees, 0);
imagejpeg($rotate, "../../../../uploads/" . $img . "");
// Add it to S3
try {
// Uploaded:
$file = $originalFileName;
$s3->deleteObject(
array(
'Bucket' => $bucketName,
'Key' => $keyName
)
);
$s3->putObject(
array(
'Bucket' => $bucketName,
'Key' => $keyName,
'SourceFile' => "../../../../" . $file,
'StorageClass' => 'REDUCED_REDUNDANCY'
)
);
} catch (S3Exception $e) {
die('Error:' . $e->getMessage());
} catch (Exception $e) {
die('Error:' . $e->getMessage());
}
//here when I use presigned url it gives me back a url where the image has rotated but when using the $pathInS3 url which is the cloudfront url the image has not been rotated
echo $pathInS3;
on my cloudfront distribution I have created an invalidation.
All my images are stores in a folder called uploads/
so I created an invalidation for my folder uploads
which looks like this
uploads/
but this doesn't seem to work.
I then created an invalidation for everything
/*
also seems to not work.
Would love advice or help on how I can go about fixing this.
Thanks,
Arnav.

convert base64 to real image and save in a folder php

I found the below php file upload from the web and it worked fine till i designed a web application in angular 4 which a photo before being upload will have to be cropped. When the image is cropped, it saves the cropped image in a base64 format, now my problem is how i can configure my current php script to convert the base64 image to a real image
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(array('status' => false));
exit;
}
$path = '../myapp/img_folder/';
if (isset($_FILES['file'])) {
$originalName = $_FILES['file']['name'];
$ext = '.'.pathinfo($originalName, PATHINFO_EXTENSION);
$generatedName = md5($_FILES['file']['tmp_name']).$ext;
$filePath = $path.$generatedName;
if (!is_writable($path)) {
echo json_encode(array(
'status' => false,
'msg' => 'Destination directory not writable.'
));
exit;
}
if (move_uploaded_file($_FILES['file']['tmp_name'], $filePath)) {
echo json_encode(array(
'status' => true,
'originalName' => $originalName,
'generatedName' => $generatedName
));
}
}
else {
echo json_encode(
array('status' => false, 'msg' => 'No file uploaded.')
);
exit;
}
Here is the solution for your problem. Tested and Working Properly.
$encoded = "encoded---text---here===";
$file = fopen("mypicture.png", "w"); //(you can put jpg, png or any other extension)
fwrite($file, base64_decode($encoded));
fclose($file);

zip folder and download in codeigniter

public function folderdownload(){
try{
$this->load->library('zip');
$this->load->helper('file');
$where = array(
'file_perm_id'=>$this->input->post('id'));
$this->load->model('fetch_model');
$file_path = $this->fetch_model->getalldata($this->folderpath,$this->master,$where);
$path = ##$file_path[0]->folder_path ;
$files = get_filenames($path);
// when i used print_r($files); to verify that i can see the files i can see it from here
foreach($files as $f){
if (is_file($path . $f))
$this->zip->add_data($f, file_get_contents($path . $f));
}
ob_end_clean();
$this->zip->download(date('m-d-Y'));
}catch(Exception $e){
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
I have this controller that once the use click the download button it download all the files within the folder but when I open it it says that the archieve is either unknown format or damaged. please help hoiw can I download files and zip it this is in codeigniter. thanks anyone
public function folderdownload(){
try{
$this->load->library('zip');
$this->load->helper('file');
$where = array(
'file_perm_id'=>$this->input->get('id'));
$this->load->model('fetch_model');
$file_path = $this->fetch_model->getalldata($this->folderpath,$this->master,$where);
$path =$file_path[0]->folder_path ;
$finallink = ($_SERVER['DOCUMENT_ROOT'] . "/cobacfms/" . $path);
$this->zip->read_dir(($finallink), false);
$this->zip->download(date('m-d-Y'));
}catch(Exception $e){
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
This is the solution to my problem
Your zip file creation is having issue.
I would suggest you to first check you content availability and then create zip file and at last download it.
To create ZIP file
$sourcePath = 'uploads/sourceDirectory';
$targetPath = 'uploads/destDirectory';
if (file_exists($sourcePath)){
if(!copy($sourcePath, $targetPath)){ //Copy file source to destination directory
return ['status' => false, 'msg' => 'File missing'];
}
}
if (file_exists($targetPath)){ // check target directory
$this->zip->read_dir($targetPath,False); // read target directory
if(!$this->zip->archive($targetPath.'.zip')){ // zip target directory
return ['status' => false, 'msg' => 'Zip file creation Failed!'];
}else{
return ['status' => false, 'msg' => 'Zip file Created'];
}
}

Laravel download file from S3 route (not open in browser)

I have the following route that will load a file from the given URL, I need this to actually download the file (mp4, jpg, pdf) rather than open in the browsers in built viewer.
// Download from CDN Route
Route::get('cdn/{url}', function($url)
{
return Redirect::away($url);
})->where('url', '(.*)');
All files are stored externally so apparently Resource::download() wouldn't actually work.
All I have available to me is the Amazon URL: https://mybucket.s3.amazonaws.com/folder/filename.pdf
Any suggestions on how to force the browser to download the file from S3?
In my case simple anchor link is downloading the file ...
file name
Try this code.
Update composer with flysystem
$path = 'https://mybucket.s3.amazonaws.com/folder/filename.pdf';
if(Storage::disk('s3')->has($path)){
$data = Storage::disk('s3')->get($path);
$getMimeType = Storage::disk('s3')->getMimetype($path);
$newFileName = 'filename.pdf';
$headers = [
'Content-type' => $getMimeType,
'Content-Disposition'=>sprintf('attachment; filename="%s"', $newFileName)
];
return Response::make($data, 200, $headers);
}
pari answer download empty file.
$s3Client = AWS::createClient('s3');
$stream = $s3Client->getObject(
[
'Bucket' => 'bucket name',
'Key' => 'filename',
'SaveAs' => '/tmp'.filename
]);
return response($stream['Body'], 200)->withHeaders([
'Content-Type' => $stream['ContentType'],
'Content-Length' => $stream['ContentLength'],
'Content-Disposition' => 'attachment; filename="' .{filename with extention} . '"'
]);
How can we download a video with an external link from another server. It's not s3. It's a normal server, files are there, but it doesn't work. I have written this code
$filename = $video->video_id;
$tempFile = tempnam(sys_get_temp_dir(), $filename);
// dd($tempFile);
copy($video->path, $tempFile);
header("Content-Disposition: attachment; filename = ".$filename);
header("X-Accel-Redirect: ".$filename);
return response()->download($tempFile, $filename);

Cannot upload .doc file with google drive sdk

I can upload .docx file to google drive from my apps, but when i tried to upload .doc file, this error appeared :
An error occurred: Error calling POST https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart&key=AIzaSyCm1WqPp05lBRjKSpxdtHjS8lz6WLeoWlU: (400) Invalid mime type provided
That error appeared too when I uploaded .ppt .xls file. The documentation says we can store any MIME type in Google Drive. What's wrong here? Anybody knows?
This is my upload function :
function insertFile($title, $description, $parentId, $mimeType, $filename) {
$file = new DriveFile();
$file->setTitle($title);
$file->setDescription($description);
$file->setMimeType($mimeType);
if ($parentId != null) {
$parent = new ParentReference();
$parent->setId($parentId);
$file->setParents(array($parent));
}
try {
$data = file_get_contents($filename);
$createdFile = $this->service->files->insert($file, array(
'data' => $data,
'mimeType' => $mimeType,
));
return $createdFile;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
[UPDATE] I'm using CI and this is my function in controller that calls insertFile function :
function upload() {
$title = $this->input->post('title');
$description = $this->input->post('description');
$parentId = $this->input->post('parentId');
if ($_FILES["file"]["error"] > 0) {
echo "Error: " . $_FILES["file"]["error"] . "<br>";
} else {
$driveHandler = new DriveHandler($_SESSION['credentials']);
$driveHandler->BuildService($_SESSION['credentials']);
$ext = substr(strrchr($_FILES["file"]["name"],'.'),1);
if($title === ""){
$fileTitle = $_FILES["file"]["name"];
} else {
$fileTitle = "$title.$ext";
}
$driveHandler->insertFile($fileTitle, $description, $parentId, $_FILES["file"]["type"], $_FILES["file"]["tmp_name"]);
}
When I try to use var_dump($mimeType) for .docx file, the result is :
string(71) "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
and for .doc file :
string(20) ""application/msword""
Based on the results, I found the problem. There is an additional double quote in $mimeType for .doc file. So I try to change my code like this :
$data = file_get_contents($filename);
$mime = str_replace('"', "", $mimeType);
$createdFile = $this->service->files->insert($file, array(
'data' => $data,
'mimeType' => $mime,
));
It now works.
Rather than just replacing double quotes, you can use a negative character class in regular expression with preg_replace() to replace any non alphanumeric, /, or . characters.
$mimeType = preg_replace("~[^a-zA-Z0-9/\.]*~", "", $mimeType);

Categories