Symfony2 Filesystem - Save a stream of data in an existent directory - php

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.

Related

Symfony, how to read and upload epub file in google storage and read it

I work with "symfony/symfony": "~3.4", and "knplabs/gaufrette": "^0.3.0", for uploading media to google storage. But how to be with epub files, when I add epub file in body post request, I had file without name or path
epubUrl = {Symfony\Component\HttpFoundation\File\UploadedFile} [7]
test = false
originalName = "RU EJTOP epub r1 (2).epub"
mimeType = "application/octet-stream"
size = 0
error = 1
*SplFileInfo*pathName = ""
*SplFileInfo*fileName = ""
and action catch error
Warning: file_get_contents(): Filename cannot be empty
from upload function, because file_get_contents required some path
public function upload(
UploadedFile $file,
$target,
$allowedMimeTypesArray,
$name
) {
if (!$allowedMimeTypesArray) {
$allowedMimeTypesArray = self::$allowedMimeTypes;
}
// Check if the file's mime type is in the list of allowed mime types.
if (!in_array($file->getClientMimeType(), $allowedMimeTypesArray, true)) {
throw new \InvalidArgumentException(
sprintf(
'Files of type %s are not allowed.',
$file->getClientMimeType()
)
);
}
$y = file_get_contents($file->getPathname());
$this->storeFile($target, file_get_contents($file->getPathname()), $name);
return $name;
}
private function storeFile($target, $data, $name)
{
/** #var GoogleCloudStorage $fileSystem */
$fileSystem = $this->getFileSystem($target);
if (false === $fileSystem->write($name, $data)) {
throw new \Exception('Storing file failed');
}
}
how to upload epub file in google storage and then read it ?
and how it works with epub file in php ?
I found, php.ini upload_max_filesize after increase it - file uploaded with path and name and get contents and write go google storage. Because need follow errors in UploadedFile class

laravel - saving and accessing an uploaded file

I am studying some laravel code that I downloaded and I am getting some problem.
This supposed to be the functions to save,delete and download the files but the problem is.
The files are being saved in a folder named with a number on "storage\app\public\project-files\" (i.e. storage\app\public\project-files\11), both destroy and download methods are referencing different paths, I tried to change but didn't worked, download show FileNotFoundException and destroy just remove from the database but not from the folder
So is this code wrong? How It supposed to be?
I've read about using artisan:link but seems odd to me run this command every time I want upload a file to make a link
PS. I cheched the routes, so the methods are being called
Thanks
public function store(Request $request)
{
if ($request->hasFile('file')) {
$file = new ProjectFile();
$file->user_id = $this->user->id;
$file->project_id = $request->project_id;
$request->file->store('public/project-files/'.$request->project_id);
$file->filename = $request->file->getClientOriginalName();
$file->hashname = $request->file->hashName();
$file->size = $request->file->getSize();
$file->save();
$this->project = Project::find($request->project_id);
return view('project-files');
}
public function destroy($id)
{
$file = ProjectFile::find($id);
File::delete('storage/project-files/'.$file->project_id.'/'.$file->hashname);
ProjectFile::destroy($id);
$this->project = Project::find($file->project_id);
return view('project-files');
}
public function download($id) {
$file = ProjectFile::find($id);
return response()->download('storage/project-files/'.$file->project_id.'/'.$file->hashname);
}
You are storing files in storage so i assume you have uploaded image in the following path
project\storage\app\public\project-files
if this is the path then you can delete using
Storage::delete('public/project-files/1.JPG');
for Downlaoding file
$path= storage_path('app/public/project-files/3.JPG');
return response()->download($path);

Symfony2 API - Best way to import and save a CSV file

I need to create an API that receives via POST a .csv file that in a second moment has to be saved to the DB.
This is how I wrote the function:
/**
* #Route("/importCSV", name = "import_csv")
* #Method("POST")
**/
public function importCSVAction(Request $request) {
if ($this->getRequest()->files) {
$type = "csv";
$filename = date('Ymd').'-'.$type.'-filename';
$directory = $this->container->getParameter('kernel.root_dir') . '/../Documents';
$request = $this->get('request');
$data = $request->getContent();
try {
$fs = new Filesystem();
$fs->dumpFile($filename, $data);
move_uploaded_file($filename, $directory);
}
catch(IOException $e) {
return new Response ("File not saved!", 500, array('Content-Type' => 'application/json'));
}
return new Response($data);
}
else return new Response("Error!", 500, array('Content-Type' => 'application/json'));
}
1 One problem is that the file is saved under the web folder and not under Documents as I wanted.
Also, how can I check if the file I'm importing is a .csv file?
2 I searched on the web but I did not found many resources on this subject.
I just want to know if this is generally a correct way to save the .csv file.
Thanks!

Symfony - BinaryFileResponse returns a ResponseHeader, but no file

currently trying to serve a static PDF file that is not within the web directory ($reasons).
I applied
$filepath = $this->getTargetFile($level, $name);
$response = new BinaryFileResponse($filepath);
$response->headers->set('Content-Type', 'application/pdf');
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_INLINE,
$filename
);
return $response;
and Profiler shows that there is a Response with correct headers, but there is no document view and no download prompt whatsoever. Is there something I am missing?
/** Get target file */
public function getTargetFile($level, $name)
{
return $this->kernel->locateResource($staticPath . $level . '/' . $name);
}
Some nerves were spent, but:
I created a form via JavaScript and submitted the needed parameters into a new window (thanks to this), that made the job. If anyone has a "cleaner" solution, I'm open to suggestions :)

How to do file uploads with PHP and the Zend Framework?

I am using Zend Framework 1.9.6. I think I've got it pretty much figured out except for the end. This is what I have so far:
Form:
<?php
class Default_Form_UploadFile extends Zend_Form
{
public function init()
{
$this->setAttrib('enctype', 'multipart/form-data');
$this->setMethod('post');
$description = new Zend_Form_Element_Text('description');
$description->setLabel('Description')
->setRequired(true)
->addValidator('NotEmpty');
$this->addElement($description);
$file = new Zend_Form_Element_File('file');
$file->setLabel('File to upload:')
->setRequired(true)
->addValidator('NotEmpty')
->addValidator('Count', false, 1);
$this->addElement($file);
$this->addElement('submit', 'submit', array(
'label' => 'Upload',
'ignore' => true
));
}
}
Controller:
public function uploadfileAction()
{
$form = new Default_Form_UploadFile();
$form->setAction($this->view->url());
$request = $this->getRequest();
if (!$request->isPost()) {
$this->view->form = $form;
return;
}
if (!$form->isValid($request->getPost())) {
$this->view->form = $form;
return;
}
try {
$form->file->receive();
//upload complete!
//...what now?
$location = $form->file->getFileName();
var_dump($form->file->getFileInfo());
} catch (Exception $exception) {
//error uploading file
$this->view->form = $form;
}
}
Now what do I do with the file? It has been uploaded to my /tmp directory by default. Obviously that's not where I want to keep it. I want users of my application to be able to download it. So, I'm thinking that means I need to move the uploaded file to the public directory of my application and store the file name in the database so I can display it as a url.
Or set this as the upload directory in the first place (though I was running into errors while trying to do that earlier).
Have you worked with uploaded files before? What is the next step I should take?
Solution:
I decided to put the uploaded files into data/uploads (which is a sym link to a directory outside of my application, in order to make it accessible to all versions of my application).
# /public/index.php
# Define path to uploads directory
defined('APPLICATION_UPLOADS_DIR')
|| define('APPLICATION_UPLOADS_DIR', realpath(dirname(__FILE__) . '/../data/uploads'));
# /application/forms/UploadFile.php
# Set the file destination on the element in the form
$file = new Zend_Form_Element_File('file');
$file->setDestination(APPLICATION_UPLOADS_DIR);
# /application/controllers/MyController.php
# After the form has been validated...
# Rename the file to something unique so it cannot be overwritten with a file of the same name
$originalFilename = pathinfo($form->file->getFileName());
$newFilename = 'file-' . uniqid() . '.' . $originalFilename['extension'];
$form->file->addFilter('Rename', $newFilename);
try {
$form->file->receive();
//upload complete!
# Save a display filename (the original) and the actual filename, so it can be retrieved later
$file = new Default_Model_File();
$file->setDisplayFilename($originalFilename['basename'])
->setActualFilename($newFilename)
->setMimeType($form->file->getMimeType())
->setDescription($form->description->getValue());
$file->save();
} catch (Exception $e) {
//error
}
By default, files are uploaded to the system temporary directory, which means you'll to either :
use move_uploaded_file to move the files somewhere else,
or configure the directory to which Zend Framework should move the files ; your form element should have a setDestination method that can be used for that.
For the second point, there is an example in the manual :
$element = new Zend_Form_Element_File('foo');
$element->setLabel('Upload an image:')
->setDestination('/var/www/upload')
->setValueDisabled(true);
(But read that page : there are other usefull informations)
If you were to move the file to a public directory, anyone would be able to send a link to that file to anyone else and you have no control over who has access to the file.
Instead, you could store the file in the DB as a longblob and then use the Zend Framework to provide users access the file through a controller/action. This would let you wrap your own authentication and user permission logic around access to the files.
You'll need to get the file from the /tmp directory in order to save it to the db:
// I think you get the file name and path like this:
$data = $form->getValues(); // this makes it so you don't have to call receive()
$fileName = $data->file->tmp_name; // includes path
$file = file_get_contents($fileName);
// now save it to the database. you can get the mime type and other
// data about the file from $data->file. Debug or dump $data to see
// what else is in there
Your action in the controller for viewing would have your authorization logic and then load the row from the db:
// is user allowed to continue?
if (!AuthenticationUtil::isAllowed()) {
$this->_redirect("/error");
}
// load from db
$fileRow = FileUtil::getFileFromDb($id); // don't know what your db implementation is
$this->view->fileName = $fileRow->name;
$this->view->fileNameSuffix = $fileRow->suffix;
$this->view->fileMimeType = $fileRow->mime_type;
$this->view->file = $fileRow->file;
Then in the view:
<?php
header("Content-Disposition: attachment; filename=".$this->fileName.".".$this->fileNameSuffix);
header('Content-type: ".$this->fileMimeType."');
echo $this->file;
?>
$this->setAction('/example/upload')->setEnctype('multipart/form-data');
$photo = new Zend_Form_Element_File('photo');
$photo->setLabel('Photo:')->setDestination(APPLICATION_PATH ."/../public/tmp/upload");
$this->addElement($photo);

Categories