Problem in reading file from server using laravel excel - php

I am trying to read an excel file from server. I want to get the data and turn it into an array.
Earlier I tried converting excel into an array and I succeeded. I used the following code.
$data = Excel::toArray(new Import, request('file') , 'public');
My import Class was
class Import implements ToModel,WithCalculatedFormulas
{
use Importable;
/**
* #param Collection $collection
*/
public function model(array $row)
{
}
}
And it was working perfectly. Now instead of submitting the file by a form; I need to read it from server. So I changed the code to,
$data = Excel::toArray(new Import, $file_url , 'public');
But now it is giving me error like below. (I changed the url to post here)
File not found at path:
http:/XXXX.YYY.com/temp_upload/1581488988_test.xlsx
I checked my server. The file is indeed there. Even, when I try to browse the URL it is downloading the correct file. But it isn't being read.

Related

Where does the console command save exported file

I'm using Laravel 5.8 and I tried creating a custom command like this:
php artisan make:command app exportappresults
And the Command goes like this:
protected $signature = 'app:exportappresults';
protected $description = 'Export App Exam Result Into Excel';
public function __construct()
{
parent::__construct();
}
public function handle()
{
return Excel::download(new TavanmandAppUserExamExport,'userexamlist.xlsx');
}
So as you can see I have used Laravel Excel and tried exporting data into Excel file.
Note that this code works fine in the Controller and can properly export an Excel file.
But now I don't know where does the exported excel file from the DB goes when I use the Console Command.
So if you know, please let me know...
Thanks.
Excel::download is used in HTTP controllers, to pass exported data to HTTP response. If you need to store file on disk, use Excel::store instead:
public function handle()
{
Excel::store(new TavanmandAppUserExamExport, 'userexamlist.xlsx');
}
File will be stored in default storage (disk), configured in laravel's config/filesystems.php, by default it's ./storage/app.
Also you may specify another disk as third argument of Excel::store method, see Storing exports on disk

Mock file in Storage to download in Laravel

Is there a way to mock a file using Laravels Storage::fake() method?
I have used https://laravel.com/docs/5.7/mocking#storage-fake as a base for my tests, which works fine for uploads. But my download tests are ugly as I have to run my upload route first every time with a mock upload UploadedFile::fake()->image('avatar.jpg'). Is there a way to skip that part and mock the file to exist directly in the fake storage system?
public function testAvatarUpload()
{
Storage::fake('avatars');
// This is the call I would like to change into a mocked existing uploaded file
$uploadResponse = $this->json('POST', '/avatar', [
'avatar' => UploadedFile::fake()->image('avatar.jpg')
]);
// Download the first avatar
$response = $this->get('/download/avatar/1');
$response->assertStatus(200);
}
I might be late here. but wanted to help others visiting this question to give an idea of implementing it.
Here is a sample with some assertions.
<?php
namespace Tests\Feature\Upload;
use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
class SampleDownloadTest extends TestCase
{
/**
* #test
*/
public function uploaded_file_downloads_correctly()
{
//keep a sample file inside projectroot/resources/files folder
//create a file from it
$exampleFile = new File(resource_path('files/test-file.png'))
//copy that file to projectroot/storage/app/uploads folder
Storage::putFileAs('/uploads', $exampleFile, 'test-file.png');
//make request to file download url to get file
$response = $this->get("/files/file/download/url");
//check whethe response was ok
$response->assertOk();
$response->assertHeader('Content-Type', 'image/png')
//check whether file exists in path
Storage::assertExists('/uploads/test-file.png');
//do some more assertions.....
//after test delete the file from storage path
Storage::delete('uploads/test-file.png');
//check whether file was deleted
Storage::assertMissing('/uploads/test-file.png');
}
}
Yes, you can use fake file storage feature of Laravel (mocking):
use Illuminate\Http\UploadedFile;
$file = UploadedFile::fake()->create('filename.ext', $sizeInKb)->store('filename.ext');
If you want to create a text/csv file with a specific content you can use this:
use Illuminate\Http\UploadedFile;
$header = 'a,b,c';
$row1 = 'x,y,z';
$row2 = 's,f,t';
$row3 = 'r,i,o';
$content = implode("\n", [$header, $row1, $row2, $row3]);
$file = UploadedFile::fake()->createWithContent('filename.ext', $content)->store('filename.ext');
You can find this methods definitions in Illuminate\Http\Testing\FileFactory
You could just create a new file directly or copy a specific test file for example:
use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
// for simple text files or if the content doesn't matter
Storage::disk('avatars')->put('avatar.jpg', 'some non-jpg content');
// if you need a specific file for your test
$file = new File(base_path('tests/resources/avatar.jpg'));
Storage::disk('avatars')->putFileAs('/', $file, 'avatar.jpg');
The latter function will take the $file and copy it under the given name avatar.jpg to the given directory / on the disk avatars. You can read more about it in the official documentation.
What you could use to solve that problem is fixtures. Laravel's testing framework is essentially PHPUnit, so I see no reason why it would not work.
define your test like so:
use Tests\TestCase;
class ExampleTest extends TestCase {
protected function setUp() {
parent::setUp();
Storage::fake('avatars');
$uploadResponse = $this->json('POST', '/avatar', [
'avatar' => UploadedFile::fake()->image('avatar.jpg')
]);
}
protected function tearDown() {
parent::tearDown();
}
public function testAvatarUpload() {
// Download the first avatar
$response = $this->get('/download/avatar/1');
$response->assertStatus(200);
}
}
setUp and tearDown get called, respectively, before and after each test in the class. So, before each test method, setUp will wipe the avatars fake disk and run the request. As there is nothing to do after a test (since Storage::fake() replaces the disk if it already exists), the method is empty; I left it here purely to make the example complete.
There's some pretty good documentation on here about this feature of PHPunit.
Regarding putting the file on there, once you have your setUp working correctly, there's nothing stopping you from throwing the file on it.

Post data with file upload Rest

For my rest API build with symfony, I have an entity Product with an image.
With Postman I try to post this entity and upload this file, I use form-data like I see on many post, with Content-Type form-data/multipart and without.
POSTMAN
But my file doesn't appear in the body request. When I dump it I have only four parameters without " url_image " ?
What is the problem ? How can I fix it ?
if you are doing:
public function someAction(Request $request) {
$file = $request->get('url_image');
// or
$file = $request->request->get('url_image');
}
then you are doing it wrong, instead do:
public function someAction(Request $request) {
/** #var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $request->files->get('url_image');
}
the uploaded files are not exactly in the request body
When you upload a file via the method you described above, the file contents are not in the request body, but in the request's files parameter bag.
You can fetch them in your controller like this:
public function someControllerMethod(Request $request)
{
$img = $request->files->get('url_image');
}
What you will be getting is an instance of UploadedFile. I recommend you to check the docs to learn how to work with it.
You will usually move to a location in your file system or opening it as a stream and send it to a cloud storage provider.
Cheers!

Display/Download a file from server using Symfony2 and jQuery

Using Symfony2.0 and jQuery
My application generates and stores PDF outside the ./www folder as it is private information (comercial invoices for the purchases within my shop).
I am trying and not getting to allow the customer to download their invoices at any time.
I found this article, but at the beginning it talks about how to get them from the "public" ./www folder. At the end, it offers a piece of code, but I think it is not supported by my version of Symfony:
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class OfflineToolController extends Controller
{
/**
* #return BinaryFileResponse
*/
public function downloadAction()
{
$path = $this->get('kernel')->getRootDir(). "/../downloads/";
$file = $path.'my_file.zip'; // Path to the file on the server
$response = new BinaryFileResponse($file);
// Give the file a name:
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT,'my_file_name.zip');
return $response;
}
}
This is the case: How to create a link to download generated documents in symfony2?
Any idea of how to do this?

Handling plupload file uploads in Symfony 2

I'm trying to write a controller to accept file uploads from the Plupload plugin. As an added bit of fun, the uploads are coming from a different URL so I have to set the Access-Control-Allow-Origin header myself. So far I've done that like so:
/**
* #Route("/frontEnd/file/upload.{_format}")
*/
public function upload(Request $request) {
$response = new Response();
$response->setContent(json_encode(array('hello' => 'world')));
$response->setStatusCode(200);
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->send();
}
which seems to work. When I submit the uploads using plupload I see the XHR requests hit Symfony and the JSON is returned. However, I have no idea how to handle the actual file and move it into a directory.
I did a var_dump() on $_POST and it only returned the following:
array(1) {
["name"]=>
string(21) "wallpaper-2873928.jpg"
}
The upload is definitely being sent as I can see the file's bytes being part of the request payload with developer tools. Do I need to use Symfony's own components to handle the upload? If so, how? The Symfony documentation only seems to cover uploading from a file upload form.
First of all, try to use the Symfony2 way of accessing request parameters. You can get more information in the book.
When uploading a file, Symfony2 automatically creates an instance of UploadedFile for you and puts it in a FileBag in the request object.
You can access the files in your controller like this:
$files = $request->files;
Like said previously, these are temporary files. To upload them in a user defined directory, use the move method on the object.
$directory = //...
foreach ($files as $uploadedFile) {
$name = //...
$file = $uploadedFile->move($directory, $name);
}
The variable $files now contains an instance of File.
On the other hand, you can also use a bundle that supports the Plupload uploader. I'd recommend the OneupUploaderBundle. (Note: I'm the main developer of this bundle, I guess this needs to be added).

Categories