Laravel image upload creating folder instead of file - image

When I try to upload image from the form , Laravel is creating directory out of image name. Here is my basic code:
$file = Input::file("image");
$file = $file->move(public_path(). "/img/".$file->getClientOriginalName());
//file name is IPC_diagram.png
When die and dump I got this:
'/var/www/php/frbit/l4blog/public/img/IPC_diagram.png/phpvEb9zk'
Now name of image is name of new folder and image is renamed to some random php string, and placed in that folder.
What is the problem. Maybe something related to Linux specific handling of files. Also I was looking into symfony code for this, and symfony is trying to crete new folder every time file is moved but I don't understand how it is related to my code.
Thanks for help.

Do not use dot. Use comma, like this:
$name = time() . $file->getClientOriginalName();
$file->move('uploads/posts/',$name);

Related

Laravel 5.5 Storage::url() doesn't return the desired url with S3

I'm using S3 for storage in my laravel 5.5 project
Everything is good and the images is stored in my bucket under my desired folder
using :
use Illuminate\Support\Facades\Storage;
$path = Storage::put($directory, $file, $permission);
$fullPath = config('filesystems.disks.s3.driver').
'.'.
config('filesystems.disks.s3.region').
'.amazonaws.com/'.
config('filesystems.disks.s3.bucket').
'/'.
$path;
the full path then will be like :
https://s3.us-east-2.amazonaws.com/iva-files/brands/logos/qweisiEC7H2SOV9ozjuOOBRxw399cTm2imnbJEXj.jpeg
I searched for better way to get my full url so I found:
Storage::url($path);
But it's returning path like :
https://ivasystem.signin.aws.amazon.com/console/brands/logos
What's wrong with my sinario ?
Try:
Storage::disk('s3')->url($filename)
As mentioned in the Official Laravel Documents
The path to the file will be returned by the putFile method so you can store the path, including the generated file name, in your database.
So you should always store file path & file name in database columns so that later on you can concatenate path & name to get fill url to the file.
In my project I am already doing this.

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.

Laravel downloads a file with unknown type

I am using Laravel 4. I allow users to upload a file, which is programmatically renamed with some number and stored. I also allow them to download the files, though I am supposed to rename their file from some funny number to their name, and download it.
My problem is, how can I change filename just before its downloaded?
My code:
return Response::download($pathToFile, $name);
When I do that, the file is downloaded with unknown format.
The second $name parameter, needs to include the full filename (including the file extension). The download method does not automatically detect the extension from the file path and append it to the name, so that needs to be done manually. Something like this will work:
return Response::download(
$pathToFile,
$name . '.' . pathinfo($pathToFile, PATHINFO_EXTENSION)
);

Laravel uploading a file to the right directory

I upload the files alright. Only it turns out that, in my case, the starting directory is Public, and that results that the files are accesible by everybody when they should be in the directories that are protected by previous authentication, that is, under App.
So, when I do this:
$file = Input::file('fichero');
$destinationPath = 'uploads/folder';
$file->move($destinationPath);
// Create model
$model = new Model;
$model->filename = $file->getClientOriginalName();
$model->destinationPath = $destinationPath;
The file is saved in here: localh.../myweb/public/
and that is outside the App parent folder where all my application files are.
I can imagine that the fact that is going to that directory is because it is taking the default in the configuration file, which is localhost/laravel/public/index.php/
so, writing something like
$file->move(base_path().'/uploadfolder/subdirectory/', $newname);
will start from what is fixed as base_path, but the base_path needs to be something like localhost/mywebname/public.
So, how do you write the path so that it goes to directories under App and not under Public?
I hope I am not asking a dumb question, but I have been trying for days and I have read the 3 related queries in here.
thank you
You may use:
app_path() // Path to the 'app' folder
app_path('controllers/admin') // Path to the 'app/controllers/admin' folder
This will return you local file system path, you should put your uploaded images in public/... folder.

Resources