I'm using gridfs to store files in MongoDB. I'm facing a problem when I try to show the large pdf file in the browser, which is saved in gridfs. Large files don't show up in the browser, but small files does.
This is the service code
public function getIpFileByFileId() {
$request = $this->request;
$dm = $this->container->get('doctrine_mongodb')->getManager('patient');
$id = $request->get('fileId');
//get doc
$docIpMapping = $dm->getRepository('PatientDocumentsBundle:IPDocuments')->findOneBy([
'id' => $id
]);
$base64 = (base64_encode($docIpMapping->getFile()->getBytes()));
$response['data'] = $base64;
$response['msg'] = 'success';
return $response;
}
And this is the front end code
Ajax(path, data).success(function (result) {
$("#pdfDiv").html('<iframe style="width:100%;height:500px;" src="data:application/pdf;base64,' + result.data + '"></iframe>');
});
Does the code have any issues? How do I display large files in the front end?
Here is my suggestion, without open in new tab,
http://answerexpress.blogspot.com/2018/09/show-preview-of-pdf-file-saved-in.html
I'm having trouble on Creating and downloading Zip file
I see on this code on
http://laravelcode.com/post/how-to-create-zip-file-in-laravel-using-ziparchive
This is my controller
public function download(){
$FOLDERID = $_GET['id'];
$FILEPATH = *My Database Query*
$PATHTOFILE = public_path().'/images/';
$ZIPNAME = 'ZIPFILENAME.zip';
$ZIP = new ZipArchive;
if ($ZIP->open($PATHTOFILE.'/'.$ZIPNAME, ZipArchive::CREATE) === TRUE) {
$FILES = *My Database Query to get file*
foreach ($FILES as $FILE) {
$ZIP->addFile($FILE->File_Path , $FILE->File_Name);
}
$ZIP->close();
}
else{
return "NO FILES CREATED";
}
and I dont know what this one do
$HEADERS = array(
'Content-Type' => 'application/octet-stream',
);
And this one is for download the zip
if(file_exists($PATHTOFILE)){
return Response()->download($PATHTOFILE, $ZIPNAME, $HEADERS);
}else{
return "asd";
}
still didnt know what #HEADERS do
Im having trouble on Creating Zip File, The error always on the $ZIP->close();
It says
ZipArchive::close(): Read error: Bad file descriptor
can you guys help me which one i did wrong?
Thankyou in advance!
create route
Route::get('download-zip', 'ZipController#downloadZip');
step:2 Create Controller
add one new method for route. downloadZip() will generate new zip file and download as response, so let's add below:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use File;
use ZipArchive;
class ZipController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function downloadZip()
{
$zip = new ZipArchive;
$fileName = 'myNewFile.zip';
if ($zip->open(public_path($fileName), ZipArchive::CREATE) === TRUE)
{
$files = File::files(public_path('myFiles'));
foreach ($files as $key => $value) {
$relativeNameInZipFile = basename($value);
$zip->addFile($value, $relativeNameInZipFile);
}
$zip->close();
}
return response()->download(public_path($fileName));
}
}
IN my vue js ajax post am storing file like
$imagename = sha1(time()).".".$request->profile_pic->extension();
$path = $request->profile_pic->storeAs('public/images/users',$imagename);
$user = \Auth::user();
//remove old file and retain new one
if(\Storage::has($user->profile_pic)){
\Storage::delete($user->profile_pic);
}
$user->picture = $path;
$user->save();
THe above works and the image is saved in the storage/app/public/images/users which is okay
But the database field is saved as public/images/users so when accessing the value in the frontend its not found
After several tests i found out that in the database i need to save the file as
storage/images/users //note path is not starting with public
so i changed the
$user->picture="storage/images/users".$imagename;
But now after doing this the part that removes old file fails
if(\Storage::has($user->profile_pic)){
\Storage::delete($user->profile_pic);
}
How do i adjust the delete part to also work.
UPDATE FOR FULL CONTROLLER CODE
public function changeProfilePic(Request $request){
if ($request->hasFile('profile_pic')) {
$imagename = sha1(time()).".".$request->profile_pic->extension();
$path = $request->profile_pic->storeAs('public/images/users',$imagename);
$user = \Auth::user();
//remove old file and retain new one
if(\Storage::has($user->profile_pic)){
\Storage::delete($user->profile_pic);
}
$user->profile_pic = "storage/images/users".$imagename;
//if save fails delete the uploaded image
if($user->save()){
return response("true", 200);
}else {
\Storage::delete($path);
return response("false", 200);
}
}else{
return response("false", 200);
}
}
in mmy vue js during upload am using vue-image-crop-upload plugin
<image-uploader field="profile_pic"
...other stuff for plugin
url="/change-profile-picture"
langType="en"
:headers="headers"
img-format="png"></image-uploader>
laravel route
Route::post('/change-profile-picture', 'UserController#changeProfilePic');
This is the way i resolved it
After a quick check i found out that no matter what i try
Storage::has or Storage::exists
Aways returns false and `Storage::delete doesnt throw any error even if the file doesnt exists
Also a quick check on the file path i had to change the name stored on database from storage to public hence explde and implode
TRHe final code that works is
public function changeProfilePic(Request $request){
if ($request->hasFile('profile_pic')) {
$imagename = sha1(time()).".".$request->profile_pic->extension();
$path = $request->profile_pic->storeAs('public/images/users',$imagename);
$user = \Auth::user();
$olduserpicdata = explode("/",$user->profile_pic);
$olduserpicdata[0] = "public";
//remove old file and retain new one
Storage::delete(implode("/",$olduserpicdata));
$user->profile_pic = "storage/images/users/".$imagename;
//if save fails delete the uploaded image
if($user->save()){
return response("true", 200);
}else {
Storage::delete($path);
return response("false", 200);
}
}else{
return response("false", 200);
}
}
I have a data stream that I need to save in a PDF file and then store that file in an already existent directory, which is Documents/pdf. This directory is at the same level of src, app, web directories, and has all the permissions to write in it.
With my solution I always have the file saved under the web directory. I want the file to be under Documents/pdf. This is my controller:
/**
* #Route("/api/savePdf", name = "save_pdf")
* #Method("POST")
**/
public function savePdfAction(Request $request) {
$pdfPath = $this->get("kernel")->getRootDir() . '/../Documents/pdf/';
$data = $request->getContent();
$name = 'file.pdf';
$dateNow = new \DateTime('now');
$date = $dateNow->format('Y-m-d H-i-s');
$fileName = $date.$name;
try {
$fs = new Filesystem();
$fs->dumpFile($fileName, $data);
move_uploaded_file($fileName, $pdfPath.$fileName);
return new Response ("File saved correctly", 200, array('Content-Type' => 'application/json') );
}
catch(IOException $e) {
return new Response ("Error!", 500, array('Content-Type' => 'application/json'));
}
return new Response();
}
Don't use
move_uploaded_file
http://php.net/manual/en/function.move-uploaded-file.php
This function checks to ensure that the file designated by filename is a valid upload file (meaning that it was uploaded via PHP's HTTP POST upload mechanism).
I'm just guessing here but since you dump the content to a file yourself i don't think it does satisfy the move_uploaded_file usage condition.
Why don't you dump the content directly into the targetfolder and get rid of a manual move?
$fs->dumpFile($pdfPath.$fileName, $data);
should do the trick since your path is absolute anyways.
I am developing in Drupal and using the php code from the Google Drive SDK that is supposed to download a file:
/**
* Download a file's content.
*
* #param Google_DriveService $service Drive API service instance.
* #param File $file Drive File instance.
* #return String The file's content if successful, null otherwise.
*/
function downloadFile($service, $file) {
$downloadUrl = $file->getDownloadUrl();
if ($downloadUrl) {
$request = new Google_HttpRequest($downloadUrl, 'GET', null, null);
$httpRequest = Google_Client::$io->authenticatedRequest($request);
if ($httpRequest->getResponseHttpCode() == 200) {
return $httpRequest->getResponseBody();
} else {
// An error occurred.
return null;
}
} else {
// The file doesn't have any content stored on Drive.
return null;
}
}
It is returning a successful response code of 200 but I cannot tell that it has actually done anything. However, I can tell from observing my LAN connection status that something of the right size in bytes is being downloaded. I just don't know where it is ending up. I am using Acquia Dev Desktop so I am running the website on my PC, but I cannot find where in the website folder the downloaded file is ending up if it is indeed being stored. I then tried another function that I found here and got similar results. Can someone more familiar with this explain what is happening?
function GetFile($service, $fileId) {
$fileVars = null;
try {
/*
* Retrieve metadata for the file specified by $fileId.
*/
$file = $service->files->get($fileId);
$fileVars = get_object_vars($file);
/*
* Retrieve the file's content using download URL specified in metadata.
*/
$downloadUrl = $file->getDownloadUrl();
error_log('Download URL file from Drive: ' . $downloadUrl);
if ($downloadUrl) {
$request = new Google_HttpRequest($downloadUrl, 'GET', null, null);
$httpRequest = Google_Client::$io->authenticatedRequest($request);
error_log(print_r($httpRequest, 1));
if ($httpRequest->getResponseHttpCode() == 200) {
$content = $httpRequest->getResponseBody();
$fileVars['content'] = $content?($content):'';
} else {
// An error occurred.
return null;
}
} else {
// The file doesn't have any content stored on Drive.
return null;
}
} catch (apiServiceException $e) {
/*
* Log error and re-throw
*/
error_log('Error retrieving file from Drive: ' . $e->getMessage());
throw $e;
}
return json_encode($fileVars);
}
This method returns the following results:
{"alternateLink":"https:\/\/docs.google.com\/file\/d\/0B6ahcE1NPpIaMTJzcFRLMnNiYU0\/edit?usp=drivesdk","appDataContents":false,"createdDate":"2013-12-05T21:05:03.026Z","defaultOpenWithLink":null,"description":"Flashum mp4","downloadUrl":"https:\/\/doc-0g-50-docs.googleusercontent.com\/docs\/securesc\/apic76cj8gku48a9ogarn9khpku0s46q\/gc9ck66nc600ebdk0ak9f58gkthnnacm\/1386345600000\/08295678552528470768\/15372451357194678536\/0B6ahcE1NPpIaMTJzcFRLMnNiYU0?h=16653014193614665626&e=download&gd=true","editable":true,"embedLink":"https:\/\/video.google.com\/get_player?ps=docs&partnerid=30&docid=0B6ahcE1NPpIaMTJzcFRLMnNiYU0&BASE_URL=https:\/\/docs.google.com\/","etag":"\"maCRbN5nR56FjQPLihEiz9nzpho\/MTM4NjI3NzUwNDU1MA\"","explicitlyTrashed":null,"exportLinks":null,"fileExtension":"mp4","fileSize":"788456","headRevisionId":"0B6ahcE1NPpIaeVJ5b3RxdExvamlDdWNrcGFvWXdvaWg3VU5JPQ","iconLink":"https:\/\/ssl.gstatic.com\/docs\/doclist\/images\/icon_11_video_list.png","id":"0B6ahcE1NPpIaMTJzcFRLMnNiYU0","imageMediaMetadata":null,"indexableText":null,"kind":"drive#file","labels":{"hidden":false,"restricted":false,"starred":false,"trashed":false,"viewed":false},"lastModifyingUser":{"displayName":"C. David Young","isAuthenticatedUser":false,"kind":"drive#user","permissionId":"08295678552528470768","picture":{"url":"https:\/\/lh6.googleusercontent.com\/-tjPzr0pfd_4\/AAAAAAAAAAI\/AAAAAAAAAWc\/DZtQHXrxkgQ\/s64\/photo.jpg"}},"lastModifyingUserName":"C. David Young","lastViewedByMeDate":null,"md5Checksum":"00701d2dd7a1b99e8ebb68cf62305b0d","mimeType":"application\/video","modifiedByMeDate":null,"modifiedDate":"2013-12-05T21:05:04.550Z","openWithLinks":null,"originalFilename":"charlesdavidyoung#gmail.com#test.mp4","ownerNames":["C. David Young"],"owners":[{"displayName":"C. David Young","isAuthenticatedUser":false,"kind":"drive#user","permissionId":"08295678552528470768","picture":{"url":"https:\/\/lh6.googleusercontent.com\/-tjPzr0pfd_4\/AAAAAAAAAAI\/AAAAAAAAAWc\/DZtQHXrxkgQ\/s64\/photo.jpg"}}],"parents":[{"id":"0B6ahcE1NPpIaQlMyWFBPamZIeTA","isRoot":false,"kind":"drive#parentReference","parentLink":"https:\/\/www.googleapis.com\/drive\/v2\/files\/0B6ahcE1NPpIaQlMyWFBPamZIeTA","selfLink":"https:\/\/www.googleapis.com\/drive\/v2\/files\/0B6ahcE1NPpIaMTJzcFRLMnNiYU0\/parents\/0B6ahcE1NPpIaQlMyWFBPamZIeTA"}],"quotaBytesUsed":"788456","selfLink":"https:\/\/www.googleapis.com\/drive\/v2\/files\/0B6ahcE1NPpIaMTJzcFRLMnNiYU0","shared":true,"sharedWithMeDate":null,"thumbnail":null,"thumbnailLink":"https:\/\/lh4.googleusercontent.com\/Ja2DZ3vzXSTn7kY_xY8VmC2N7nCeBrbvnkr-lO4GbMuOmpETwLAYlaC7qr5fOpBTTQ=s220","title":"charlesdavidyoung#gmail.com#test.mp4","userPermission":{"additionalRoles":null,"authKey":null,"etag":"\"maCRbN5nR56FjQPLihEiz9nzpho\/8jq33BWTNkV1S9Wn1TTkFYEVpVc\"","id":"me","kind":"drive#permission","name":null,"photoLink":null,"role":"writer","selfLink":"https:\/\/www.googleapis.com\/drive\/v2\/files\/0B6ahcE1NPpIaMTJzcFRLMnNiYU0\/permissions\/me","type":"user","value":null,"withLink":null},"webContentLink":"https:\/\/docs.google.com\/uc?id=0B6ahcE1NPpIaMTJzcFRLMnNiYU0&export=download","webViewLink":null,"writersCanShare":true,"copyable":true,"content":null}
If you pass to your script a document id it should return you a download link under the field exportLinks. The fact that your exportLinks is null means that you cannot download the file (permissions?).