response()->file() does not find files located at storage/app - laravel

This works perfectly:
return Storage::download('my_documents','test.pdf');
This doesn't work ("file not found error"):
return response()->file('/storage/app/my_documents/test.pdf');
How exactly do I have to define the path for the second approach?
I want to show the file directly in the browser. Can Storage class offers that functionality?
Please share solutions for Laravel 8+.
Thanks.

You must provide an absolute path to the file() method. You can use
storage_path() as configured in your config/filesystems.php file.
return response()->file(storage_path('app/my_documents/test.pdf'));
This should also work:
return response(file(storage_path('app/my_documents/test.pdf'));
Note: If you ever use the app/public folder, make sure you don't forget to create a symbolic link to your app public folder:
php artisan storage:link

For file return need to specify full path like below.For example in this case file exist in storage/app/public/pdf/1621869239k9y3aBE.pdf
return response()->file(storage_path('app/public/pdf/1621869239k9y3aBE.pdf'));
file() method accept two parameter like below
/**
* Return the raw contents of a binary file.
*
* #param \SplFileInfo|string $file
* #param array $headers
* #return \Symfony\Component\HttpFoundation\BinaryFileResponse
*/
public function file($file, array $headers = []);

Yes, Storage facade class has this functionality.
You can use method response instead of download. This sends a file directly to the browser instead of download.
In your case it will look like this:
return Storage::response('my_documents','test.pdf');

Related

How to replace phpdocs with new attributes in php 8

I am using laravel. I need to know how phpdoc can be written in php 8 with attibutes.
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
//Some code
return [];
}
Can someone please explain how the above code can be written with attributes.
I believe you have misunderstood what Attributes are for, and how they related to doc blocks. There are two common uses of doc blocks (comments marked with /** ... */):
To document the code (hence the name "doc block"), in a mostly-standardised way which can be read by various tools, including documentation generators and IDEs.
To add machine-readable annotations to the code, for use with libraries and frameworks that can automatically generate behaviour based on those. For instance, an ORM might use an annotation of #TableName('Foo') to link a class to a particular database table, and generate appropriate SQL.
The example you've shown is of the first usage. What you have written is still the correct way of writing documentation.
PHP 8's native Attributes replace the second usage. It's up to the library what Attributes to look for, but an ORM that previously looked for #TableName('Foo') in a docblock might now look for #[TableName('Foo')] as a native Attribute instead.
There is a great automatic refractoring tool called rector. It will make your life so much easier. Install it, then create a rector.php file at the root directory that should look like something like this:
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Doctrine\Set\DoctrineSetList;
use Rector\Symfony\Set\SensiolabsSetList;
use Rector\Symfony\Set\SymfonySetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/src',
__DIR__ . '/tests'
]);
$rectorConfig->sets([
DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES,
SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES,
SensiolabsSetList::FRAMEWORK_EXTRA_61,
]);
};
There are plenty of configuration options that you can find in the docs.
When you are done, just run the refractoring tool:
vendor/bin/rector process src

Generate files with laravel command

I need to create a number of files in a specific format. So I planned to create a generate command by extending GeneratorCommand. I want to create view files and view-config files in application root directory.
The problem is, I did not find any official doc to do so. There are some article in the web, which suggests to use getDefaultNamespace method to set the path like the following. I was following the steps suggested at https://laravelpackage.com/06-artisan-commands.html#creating-a-generator-command. But I want to create files in root dir not into app dir. When i remove the $rootNamespace form the method it does not create files.
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace.'\Actions';
}
how can i create a command to generate files in specific directories in the application?
The class GeneratorCommand has a protected method rootNamespace. If I understand correctly, it returns the root ouf your application.
So you should be able to override the method getNamespace like so:
/**
* Get the full namespace for a given class, without the class name.
*
* #param string $name
* #return string
*/
protected function getNamespace($name)
{
$rootNamespace = trim($this->rootNamespace(), '\\');
return $this->getDefaultNamespace($rootNamespace);
}
NOTE
You can see a working example in one of my open source projects.

want to delete file from both database n folder but not deleting form folder

public function deletePublication($publication_id=null){
if(!empty($publication_id)){
Publication::where(['publication_id'=>$publication_id])->delete();
return redirect()->back()->with('flash_message_success','Publication Deleted Successfully..');
}
}
by this code I'm unable to delete files from by folder which is inside public/files but files are deleted from database.Can You help me how can I delete files from both?
very simple try this
use Illuminate\Support\Facades\Storage;
public function deletePublication($publication_id=null)
{
if(!empty ($publication_id))
{
$publication_path = Db::table('publications')
->where('publication_id','=',$publication_id)
->value('publication_file');
Storage::delete($publication_path);
DB::table('publications')->where('publication_id', '=', $publication_id)- >delete();
return redirect()
->back()
->with('flash_message_success','Publication Deleted');
}
}
path it must be different in your table.
To know more about visit File system Laravel
What is your code to create a publication? What you did to create a publication (including the uploading of file), you also have to do the reverse (which is delete the file).
Laravel has a good documentation, you can refer to this link on how to delete files/directory: https://laravel.com/docs/5.6/filesystem.
You just added the code to remove a file from Database. Need to remove the file from a folder, try below code
$filePath = 'public/files';
unlink($filePath);
Please read details of unlink() function
http://php.net/manual/en/function.unlink.php
You can also try from laravel to remove the file, please review the link from laravel documentation
https://laravel.com/docs/5.6/filesystem#deleting-files

Return file name with laravel 5.4

I want to return the files names of a dir called public/uploads. I used Storage::allFiles and Storage::files, but only return an empty array.
Storage works only for storage directory. If you want to use it, you'll need to create a symbolic link.
Use File facade instead:
File::files(public_path('uploads'));

Move or copy a file from the request to multiple locations

I'm using Laravel and taking in input and file uploads. This page takes changes that users want to make to an order. The end goal is to take this input and apply it to multiple orders.
I can reuse the input for each of the orders. But what would be a good way for me to copy that file in the request to multiple directories? For example, as in the documentation, I originally have: $request->file('photo')->move($destinationPath, $fileName); which works fine for one order. But now that I want to apply it to many orders, I can't move that same file from the request anymore since it doesn't exist.
And it looks like the UploadedFile object doesn't have a copy() method. Any ideas would be appreciated. Thank you.
Do not depend on component too much. Keep it simple
$request->file('photo')->move($destination_path, $file_name);
//Add DIRECTORY_SEPARATOR between path and filename if needed
copy($destination_path.$file_name, $new_path.$new_file_name);
If I may make a suggestion assuming these files are going to stay the same (you aren't allowing your users to modify these files by order), I think it makes sense to store one copy of the file on the server and use a database table to determine which orders that file belongs to and manage it all in the table. You may need to create a files table and an file_order table and give it a many to many relationship to your orders table but in the end, if these files are allowed to be large, could save you a lot of space and in my opinion, make it easier to manage.
In Laravel, look at the vendor\laravel\framework\src\Illuminate\Filesystem\Filesystem.php , and I hope you'll get the everything of file, how they manage the files.
How to copy a file, move a file, delete a file everything is described clearly in that.
For copy a file in Laravel, there function is:
/**
* Copy a file to a new location.
*
* #param string $path
* #param string $target
* #return bool
*/
public function copy($path, $target)
{
return copy($path, $target);
}
I think there's nothing to say now.
Just use that
File::copy('file_name_with_full_path', 'target_directory_where_copy');
Hope, it might be helpful for you.

Resources