Codeigniter force_download() No output - codeigniter

Fast to explain, but I can't get it to work:
In this simple code, the function force_download simply doesn't make any output.
$this->load->helper('download');
$data = file_get_contents("upload/".$filename);
$name = $no_file;
force_download($name, $data);
Here I just get a white screen, but the file content is show (well you know, the strange codified content :) I think it is simple enough, I just want the file downloaded with no other effect, am I doing something wrong?

I think this is you should do..
$this->load->helper('download');
$path = file_get_contents(base_url()."yourpath/".$filename); // get file name
$name = "test.pdf"; // new name for your file
force_download($name, $path); // start download`
Hope this helps.
EDIT:
Make sure you have a file extension on the filename you supply for the first argument to force_download().
CodeIgniter uses this to set the MIME type, and it doesn't seem to work without.
ERROR: Name or Service not known.
Step1: Opening /etc/resolv.conf (my file was empty)
Step2: Add
nameserver 8.8.8.8
nameserver 8.8.4.4
options rotate
options timeout:3
This may help.

Related

Move a line from controller to new file and call it in laravel

ThisController in my local PC's Laravel, there is a line like this.
$result = shell_exec('C:\Users\mypc\AppData\Local\Programs\Python\Python37-32\python.exe test.py '. $text);
but, this is local PC path. so if I push to web server, I need to change to
$result = shell_exec('usr\bin\Python test.py '. $text);
So, I want to cut this line and paste into a new file, and I want to call this line from the new file via ThisContoroller. So, I can make the file to gitignore and I don't get conflict.
But I don't know how to do it. Do you have any suggestion? Thank you.
Regarding to ceejayoz's comment, yes, I could do with .env file.
With this thread's answer.

Laravel / Laravel-Excel missing forward slash in asset url

I am uploading excels in Laravel for processing with Laravel-Excel. I have the following issue:
When I do this:
$file = $request->file('file')->store('Questionnaires', ['disk' => 'public']);
$file = asset($file);
dd($file);
I get something as expected, like:
http://project.test/Questionnaires/filename.xlsx
However, when I pass $file that into Laravel-Excel thus:
$collection = Excel::toCollection(new QuestionnairesImport, $file);
I get this error:
File not found at path: http:/project.test/Questionnaires/filename.xlsx
This is missing a forward slash in the http:/ ie http://
What's going on?
OK, I solved this and am saving the answer here for my oown record and in case it is useful to someone else.
Disclaimer: I still don't know with who the error lay, so consider this a work around/ bug fix/ terrible idea - as you like.
I modified two core files in this way:
In the function readStream() in vendor/league/flysystem/src/adapter/local.php:
// original lines, removed:
//$location = $this->applyPathPrefix($path);
//$stream = fopen($location, 'rb');
// my addition (1 line):
$stream = fopen(asset($path), 'rb');
In the function readStream() in vendor/league/flysystem/src/filesystem.php:
// original line, removed:
//$this->assertPresent($path);
// my addition (1 line):
$path = str_replace('http:/a','http://a', $path);
In the first function it was failing because it couldn't open the path - a local prefix was being added in front of the web address.
In the second function, it couldn't assert the file as present because one of the forward slashes had been removed (still not quite sure how...). So I just did a string replace to put it back in ('a' is the first letter of my project name in APP_URL in .ENV - you need to change it to the first letter of your project for this to work.
This feels a horribly dirty way to do it, but it works. Hopefully I'll come across a better solution.

renaming a file before uploading to digital ocean spaces using laravel

To upload a file I use
Storage::disk('spaces')->putFile('uploads', $request->file, 'public');
The file is saved successfully on digital ocean spaces. But I want to rename it to something like this user_1_some_random_string.jpg. And then save it.
How can I do it?
The move method may be used to rename or move an existing file to a new location:
Storage::move('hodor/oldfile-name.jpg', 'hodor/newfile-name.jpg');
Also:
If you would not like a file name to be automatically assigned to your stored file, you may use the storeAs method, which receives the path, the file name, and the (optional) disk as its arguments:
$path = $request->file('avatar')->storeAs(
'avatars', $request->user()->id
);
More: https://laravel.com/docs/5.6/filesystem
try use rand()
$ext = $request->file('file')->getClientOriginalExtension();
$name = rand(11111,99999).'.'.$ext;
Storage::disk('spaces')->putFile('uploads', $name, 'public');
This is pretty old but I found an answer for anyone still looking.
You need to use the method putFileAs, as far as I can see
the first parameter is the bucket/location. I tested this and it will create a new folder if you use 'uploads/testz' it created the 'testz' in the uploads folder on spaces.
the second parameter is the request file object, in my case $request->file('file')
the third parameter is the filename that you WANT to store the file as. I tested and if you 'testz/<yourspecialfilename.extension>' it will create the same folder as in parameter 1, which suggests to me that the method concats param 1 and 3.
So the full snippet in my controller is
public function create(Request $request){ Storage::disk('spaces')->putFileAs('uploads/testz', $request->file('file'), 'mychosenfilename.mydesiredextension');
return redirect()->back();}

How to read a .docx file via PHP Word sample code in Codeigniter

Am trying to read a .docx file which is inside my project folder via PHP Word library. I have included autoloader like this :
include_once 'vendor/autoload.php'; in my controller.
CODE FOR FUNCTION IN CONTROLLER:
function test_phpword()
{
$a=base_url();
$path=$a."".'123.docx';
$source =$path;
echo date('H:i:s'), " Reading contents from `{$source}`";
$phpWord = \PhpOffice\PhpWord\IOFactory::load($source);
echo write($phpWord, basename(__FILE__, '.php'), $writers);
}
BUT GETTING ERROR LIKE BELOW:
06:18:42 Reading contents from http://localhost/myproject/123.docx
Fatal error: Uncaught Exception: Cannot find archive file. in /opt/lampp/htdocs/myproject/vendor/phpoffice/common/src/Common/XMLReader.php:51
Try this
Change
$path=$a."".'123.docx';
to
$path='123.docx';
And put 123.docx beside your php script file. make sure the two files are in the same place. Run your php script again.
If this helps and works fine you can check the file path and make proper change to your php program.
While loading the path, you have to give relative path to the doc file as shown below,
$random_name = 123.docx;
$contents = \PhpOffice\PhpWord\IOFactory::load('../uploads/'.$random_name);
I don't know whats your $base_url, but it will not work if it is absolute path like http://path/to/doc/file.
I have worked on it and tested. Hope it helps.

Laravel 5: How do you copy a local file to Amazon S3?

I'm writing code in Laravel 5 to periodically backup a MySQL database. My code thus far looks like this:
$filename = 'database_backup_'.date('G_a_m_d_y').'.sql';
$destination = storage_path() . '/backups/';
$database = \Config::get('database.connections.mysql.database');
$username = \Config::get('database.connections.mysql.username');
$password = \Config::get('database.connections.mysql.password');
$sql = "mysqldump $database --password=$password --user=$username --single-transaction >$destination" . $filename;
$result = exec($sql, $output); // TODO: check $result
// Copy database dump to S3
$disk = \Storage::disk('s3');
// ????????????????????????????????
// What goes here?
// ????????????????????????????????
I've seen solutions online that would suggest I do something like:
$disk->put('my/bucket/' . $filename, file_get_contents($destination . $filename));
However, for large files, isn't it wasteful to use file_get_contents()? Are there any better solutions?
There is a way to copy files without needing to load the file contents into memory using MountManager.
You will also need to import the following:
use League\Flysystem\MountManager;
Now you can copy the file like so:
$mountManager = new MountManager([
's3' => \Storage::disk('s3')->getDriver(),
'local' => \Storage::disk('local')->getDriver(),
]);
$mountManager->copy('s3://path/to/file.txt', 'local://path/to/output/file.txt');
You can always use a file resource to stream the file (advisable for large files) by doing something like this:
Storage::disk('s3')->put('my/bucket/' . $filename, fopen('path/to/local/file', 'r+'));
An alternative suggestion is proposed here. It uses Laravel's Storage facade to read the stream. The basic idea is something like this:
$inputStream = Storage::disk('local')->getDriver()->readStream('/path/to/file');
$destination = Storage::disk('s3')->getDriver()->getAdapter()->getPathPrefix().'/my/bucket/';
Storage::disk('s3')->getDriver()->putStream($destination, $inputStream);
You can try this code
$contents = Storage::get($file);
Storage::disk('s3')->put($newfile,$contents);
As Laravel document this is the easy way I found to copy data between two disks
Laravel has now putFile and putFileAs method to allow stream of file.
Automatic Streaming
If you would like Laravel to automatically manage
streaming a given file to your storage location, you may use the
putFile or putFileAs method. This method accepts either a
Illuminate\Http\File or Illuminate\Http\UploadedFile instance and will
automatically stream the file to your desired location:
use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
// Automatically generate a unique ID for file name...
Storage::putFile('photos', new File('/path/to/photo'));
// Manually specify a file name...
Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');
Link to doc: https://laravel.com/docs/5.8/filesystem (Automatic Streaming)
Hope it helps
Looking at the documentation the only way is using method put which needs file content. There is no method to copy file between 2 file systems so probably the solution you gave is at the moment the only one.
If you think about it, finally when copying file from local file system to s3, you need to have file content to put it in S3, so indeed it's not so wasteful in my opinion.
I solved it in the following way:
$contents = \File::get($destination);
\Storage::disk('s3')
->put($s3Destination,$contents);
Sometimes we don't get the data using $contents = Storage::get($file); - storage function so we have to give root path of the data using Laravel File instead of storage path using Storage.

Resources