PHP Decoded Base64 PDF Upload To CMIS Server - php

I am developing a REST API using Laravel 5.1 that has use case as following: receive a base 64 decoded PDF, and return a workspace ID of a Document Management System (DMS) from the uploaded file. The DMS service that I use in this case is Alfresco.
Current Condition
The application succeed to receive base 64 string and decode it to a file. I store the decoded file into system temporary directory, and try to upload it to the Alfresco. I have previously built function that receive a file from a form request to be stored in the Alfresco, and it works. Here is the declaration and parameters stated in the function:
public static function uploadDocument(
$doc, // <-- Okay by form request, not okay by the API decoded file
$user, // credential
$password, // credential
$params = array() // array that contains ACE
)
{
However, when I tried to use the same function with different document source, it failed. By different document source, I mean the source comes from the decoded base 64, and can be seen as follow:
// Decrypt base64
$fileData = base64_decode($request->input('file'));
// Save the decoded file to a temp directory
$tmpDir = sys_get_temp_dir();
$fileName = $request->input("fileName");
$pdfFile = fopen("$tmpDir/$fileName", 'w');
fwrite ($pdfFile, $fileData);
// Upload the decrypted file to the Alfresco
$alfUsername = Config::get('alfresco.CMIS_BROWSER_USER');
$alfPassword = Config::get('alfresco.CMIS_BROWSER_PASSWORD');
$assignees = ['assignees' => []];
$alfObjId = Alfresco::uploadDocument(
$pdfFile,
$alfUsername,
$alfPassword,
$assignees
);
fclose ($pdfFile);
The Error
Call to a member function getClientOriginalName() on resource
That refers to this line:
$uniqueFileName = $alfresco
->getUniqueFileName([
'path' => $path,
'filename' => $doc->getClientOriginalName(), // <-- This line
'session' => $session
]);
Error screenshot
The Question
Can one uploads a decoded base 64 file to another service without using temporary file?
How can I convert the decoded file into a multipart form request or similar, in order that my upload function could consume?
Thank you.

Well, sure you can call other service without saving a temporary file. If the file is already in memory as a string you could use curl to send a new request sending the string as data. Using curl to create a request you could set the content type header to multipart form data

Related

Laravel - Create PDF file from raw content - JSON API

I am trying to create a temporarily PDF file from raw PDF string.
This is my input, which is sent through an API (JSON):
{
"name": "pdffilename.pdf",
"content": "%PDF-1.2 [.......]%%EOF"
}
The "content" string is the actual PDF raw data string.
Now this is my controller, that handles the API request:
/**
* Function to convert a PDF file to text
*/
public function PDFtoText(Request $request)
{
$name = $request->name;
$content = $request->content;
//Save PDF file on the server (temp files).
$pdf = Storage::disk('local')->put('/temp_files/' . $name, $content);
return response()->json([
'result' => "Success"
], 200);
}
An actual file is created in the temp_files folder, with the name pdffilename.pdf. However I cannot open the file, as it says the file is "corrupt".
What am I doing wrong here?
the best way to save the content of the document or file is using the base64_encode function, this transform de content in base64 encode. Then when you need this content the unique process you need to do is to call the base64_decode function. I tried and works fine for me. Any questions only write me.

How to build same browser response for all types of files with laravel

Goal: When client requests to see a file from server, i want the client's browser to ask what to do (open or download file). How can i build that?
So far i have methods like those:
public static function getFileContent($fullpath){
//yes, i can get both file and its extension
$file = File::get($fullpath);
$mimeType = File::extension($fullpath);
$response = Response::make($file, 200, array('content-type'=>$mimeType));
return $response;
}
and the other method calls the above
$path = $instance->the_file_path_on_the_database;
return MyClass::getFileContent($path);
In this case, if the uploaded file is PDF, png, jpeg etc. browser automatically opens the file, which is okay.
But when it comes to the *.xlsx or *.docx, browser asks me what to do but the file name isn't as the same as what i have stored on the database and it has no extension. Also the file is automatically renamed as the route's name.
Thanks in advance.
according to the docs
The download method may be used to generate a response that forces the
user's browser to download the file at the given path. The download
method accepts a file name as the second argument to the method, which
will determine the file name that is seen by the user downloading the
file. Finally, you may pass an array of HTTP headers as the third
argument to the method:
return response()->download($pathToFile);
return response()->download($pathToFile, $name, $headers);

Laravel Download from S3 To Local

I am trying to download a file that I stored on S3 to my local Laravel installation to manipulate it. Would appreciate some help.
I have the config data set up correctly because I am able to upload it without any trouble. I am saving it in S3 with following pattern "user->id / media->id.mp3" --> note the fact that I am not just dumping files on S3, I am saving them in directories.
After successfully uploading the file to S3 I update the save path in my DB to show "user->id / media->id.mp3", not some long public url (is that wrong)?
When I later go back to try and download the file I am getting a FileNotFoundException at S3. I'm doing this.
$audio = Storage::disk('s3')->get($media->location);
The weird thing is that in the exception it shows the resource that it cannot fetch but when I place that same url in a browser it displays the file without any trouble at all. Why can't the file system get the file?
I have tried to do a "has" check before the "get" and the has check comes up false.
Do I need to save the full public URL in the database for this to work? I tried that and it didn't help. I feel like I am missing something very simple and it is making me crazy!!
Late answer but important for others,
$s3_file = Storage::disk('s3')->get(request()->file);
$s3 = Storage::disk('public');
$s3->put("./file_name.tif", $s3_file);
The response of $s3_file will be a stream, you can save that stream data to file using Laravel put file method, you will find this stream file in storage/public directory.
You can give your Content-Type as desired and Content-Disposition as 'attachment' because your files are coming from S3 and you have to download it as an attachment.
$event_data = $this->ticket->where('user_id', $user_id)->first();
$data = $event_data->pdf;
$get_ticket = 'tickets/'. $data;
$file_name = "YOUR_DESIRED_NAME.pdf";
$headers = [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="'. $file_name .'"',
];
return \Response::make(Storage::disk('s3')->get($get_ticket), 200, $headers);
Say, you have AWS S3 as your default storage.
And you want to download my_file.txt from S3 to my_laravel_project\storage\app\my_file.txt
And you want to make it a one-liner
Storage::disk('local')->put('my_file.txt', Storage::get('my_file.txt'));

Sending binary file content using JSON

I've written a REST interface for my ownCloud app. I've method getFileFromRemote($path) which should return a JSON object with the file content.
Unfortunately this only works when the file that I've specified in $path is a plaintext file. When I try to call the method for an image or PDF the status code is 200 but the response is empty. For returning the file contents I use file_get_contents for retrieving the content.
Note: I know ownCloud has a WebDAV interface, but I want to solve this with REST only.
EDIT
This is the code server side (ownCloud):
public function synchroniseDown($path)
{
$this->_syncService->download(array($path));//get latest version
$content = file_get_contents($this->_homeFolder.urldecode($path));
return new DataResponse(['path'=>$path, 'fileContent'=>$content]);
}
The first line retrieves downloades the content on the ownCloud server and works completely.
You probably have to base64_encode your file content to make json_encode/decode handle it properly:
return new DataResponse([
'path'=>$path,
'fileContent' => base64_encode($content) // convert binary data to alphanum
]);
and then when receiving file via second side, you will have to always:
$fileContent = base64_decode($response['fileContent']);
It's only one, but ones of easiest way to handle that. Btw, sooner or later you will find that Mime-Type would be useful in response.

Server code to accept file uploaded from intel XDK

Currently I'm creating an app using IntelXDK to upload image from devices to my server.
The problem currently I'm encountering is, how to code my backend so that it can receive the upload file from mobile device?
In PHP, I only know that the file upload requires:
<input type="file" name="file" />
then use $FILES["file"] to save it into storage
And is almost similar in .Net as well.
But I'm still couldn't think of how to receive the file once it is uploaded via mobile.
Would be great if someone share or advise the missing part (.Net and PHP).
In ASP.net server side use webservice receive in byte format and save that as you want.
Code sample refrence link http://www.codeproject.com/Articles/22985/Upload-Any-File-Type-through-a-Web-Service
[WebMethod]
public string UploadFile(byte[] f, string fileName)
{
// the byte array argument contains the content of the file
// the string argument contains the name and extension
// of the file passed in the byte array
try
{
// instance a memory stream and pass the
// byte array to its constructor
MemoryStream ms = new MemoryStream(f);
// instance a filestream pointing to the
// storage folder, use the original file name
// to name the resulting file
FileStream fs = new FileStream
(System.Web.Hosting.HostingEnvironment.MapPath
("~/TransientStorage/") +
fileName, FileMode.Create);
// write the memory stream containing the original
// file as a byte array to the filestream
ms.WriteTo(fs);
// clean up
ms.Close();
fs.Close();
fs.Dispose();
// return OK if we made it this far
return "OK";
}
catch (Exception ex)
{
// return the error message if the operation fails
return ex.Message.ToString();
}
}
}
}
For more information about uploading files to a server: https://software.intel.com/en-us/node/493213
If you are aware of ASP.NET Web API 2, have a look at this sample:
http://aspnet.codeplex.com/sourcecontrol/latest#Samples/WebApi/FileUploadSample/
Also, check these ones:
http://damienbod.wordpress.com/2014/03/28/web-api-file-upload-single-or-multiple-files/
http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2
http://www.c-sharpcorner.com/UploadFile/2b481f/uploading-a-file-in-Asp-Net-web-api/
Check these SO links:
How To Accept a File POST
File upload Jquery WebApi
I think, with above links, you will be surely able to create service that intakes file uploaded from a form.
Hope it helps you...
All the best...

Categories