Laravel - Pass uploaded filename to new function - php

I'm using Laravel 5.3 and need to upload an xml file and then submit the contents to an api. The client wants it as 2 buttons/user functions where the user should first upload the file and then with a second click submit the contents.
The uploading is working fine and the xml reading and submitting to api is also working properly. I just can't get my upload controller to pass the filename over to the submitting controller. There is no need to store the filename for future use and the processes will follow each other - ie user will upload one file and submit, then upload next file and submit.
Any help would be highly appreciated
upload function:
public function handleUpload(Request $request)
{
$file = $request->file('file');
$allowedFileTypes = config('app.allowedFileTypes');
$rules = [
'file' => 'required|mimes:'.$allowedFileTypes
];
$this->validate($request, $rules);
$fileName = $file->getClientOriginalName();
$destinationPath = config('app.fileDestinationPath').'/'.$fileName;
$uploaded = Storage::put($destinationPath, file_get_contents($file->getRealPath()));
if($uploaded) {
$file_Name = ($_FILES['file']['name']);
}
return redirect()->to('/upload');
}
submit function:
public function vendorInvoice()
{
$fileName = $file_Name;
$destinationPath = storage_path('app/uploads/');
$xml = file_get_contents($destinationPath.$fileName);
$uri = "some uri";
try {
$client = new Client();
$request = new Request('POST', $uri, [
'Authorization' => '$username',
'ContractID' => '$id',
'content-type' => 'application/xml'
],
$xml);
$response = $client->send($request);
}
catch (RequestException $re) {
//Exception Handling
echo $re;
}
}

Related

Uploading recording file stream to aws s3 in PHP is very slow

In my application I can record video and save it to aws s3 bucket using vueJS as front end and Laravel php as backend.
I am using ffmpeg to upload recording stream to s3 bucket.
1 min video taking 4 mins and
3 mins video taking 9 mins (Always not successfully uploaded, some times it fails)
Below is the code in backend.
public function video_upload(Request $request)
{
// Response Declaration
$response=array();
$response_code = 200;
$response['status'] = false;
$response['data'] = [];
// Validation
// TODO: Specify mimes:mp4,webm,ogg etc
$validator = Validator::make(
$request->all(), [
'file' => 'required',
]
);
if ($validator->fails()) {
$response['data']['validator'] = $validator->errors();
return response()->json($response);
}
try{
$file = $request->file('file');
//covert
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open($file);
$format = new X264();
$format->on('progress', function ($video, $format, $percentage) {
echo "$percentage % transcoded";
});
$video->save($format, 'output.mp4');
//end convert
$file_name = str_replace ('/', '', Hash::make(time())).'.mp4';
$file_folder = 'uploads/video/';
// Store the file to S3
// $store = Storage::disk('s3')->put($file_folder.$file_name, file_get_contents($file));
$store = Storage::disk('s3')->put($file_folder.$file_name, file_get_contents('output.mp4'));
if($store){
// Replace old file if exist
//delete the file from public folder
$file = public_path('output.mp4');
if (file_exists($file)) {
unlink($file);
}
if(isset($request->old_file)){
if(Storage::disk('s3')->exists($file_folder.basename($request->old_file))) {
Storage::disk('s3')->delete($file_folder.basename($request->old_file));
}
}
}
$response['status'] = true;
$response['data']= '/s3/'.$file_folder. $file_name;
}catch (\Exception $e) {
$response['data']['message']=$e->getMessage()."line".$e->getLine();
$response_code = 400;
}
return response()->json($response, $response_code);
}
I was researching on Transfer Acceleration and multipart upload but question is do i do from aws end or in backend.

Laravel malformed UTF-8 characters, possibly incorrectly encoded using image intervention

I have a laravel project that has a image upload. I used image intervention library for uploading. The problem is i got a 500 error and saying Malformed UTF-8 characters, possibly incorrectly encoded. But when I look my directory for saving, the image was saved but the data was not saved to the database. Only the image was saved. Seems like the image save was successful but the request is not. What seems to be the problem?
Controller
public function store(Request $request)
{
$product = new Product;
$validator = \Validator::make($request->all(), [
'product_name' => 'required',
'barcode' => 'required|unique:products',
'price'=> 'required',
'category' => 'required',
'supplier' => 'required',
// 'image' => 'required|image64:jpeg,jpg,png'
]);
if ($validator->fails()) {
$errors = json_encode($validator->errors());
return response()->json([
'success' => false,
'message' => $errors
],422);
} else {
$product->barcode = $request->barcode;
$product->product_name = $request->product_name;
$product->price = $request->price;
$product->quantity = 0;
$product->category = $request->category;
$product->supplier_id = $request->supplier;
//image
$imageData = $request->image;
$fileName = time().'.'. explode('/', explode(':', substr($imageData, 0, strpos($imageData, ';'))) [1])[1];
$product->image = \Image::make($request->image)->save(public_path('img/').$fileName);
$product->save();
broadcast(new ProductsEvent(\Auth::user()->name, 'add', $product))->toOthers();
}
}
Vue component event when form is changed
onFileChange(e) {
let file = e.target.files[0];
console.log(file);
var reader = new FileReader();
reader.onloadend = (file)=>{this.image = reader.result}
reader.readAsDataURL(file);
},
It seems that problem is appearing in your $filename generation.
As long as you have the correct image saved the naming convention is all in your hands.
I'd recommend you to go with simpler approach like
$fileName = now()->timestamp . '_' . $imageData->name; and there would be no need for you to go fancy with the name of the file.
The value of the $imageData can not be predicted and all the operations you execute could lead to that problem.
The question has been already asked Laravel "Malformed UTF-8 characters, possibly incorrectly encoded", how to fix?
--- Edit ---
You can get the filename directly from your javascript as you do all the manipulation at that end so you could for example add this.name = file.name; to your sent data, then in your ajax you can send that data like so -
axios.post('/image/store',{
image: this.image,
imageName: this.name
}).then(response => {...});
in your backend $fileName = now()->timestamp . '_' . $request->imageName;
The problem was this line, I was saving the actual image object in the db.
$product->image = \Image::make($request->image)->save(public_path('img/').$fileName);
I changed it into
$imageData = $request->image;
$fileName = time().'.'. explode('/', explode(':', substr($imageData, 0, strpos($imageData, ';'))) [1])[1];
\Image::make($request->image)->save(public_path('img/').$fileName);
$product->image = $fileName;
$product->save();;

How to store data without multiple uploads "if i don't have a file want to upload"?

I have a problem when I want to save a new data I don't want to upload file too but I have to code multiple uploads in my public function store. I want to add file when I open edit form and uploaded. what should I do?
I have tried to set validation to set but when I submit error Undefined variable: data.
public function store(Request $request)
{
$request->validate([
'employee_sid' => 'required',
'employee_npk' => 'required',
'employee_name' => 'required',
'file_uploads' => 'nullable',
'file_uploads.*' => 'file|image|mimes:pdf,jpg,jpeg,png',
]);
if($request->file('file_uploads'))
{
foreach($request->file('file_uploads') as $file)
{
$name = $file->getClientOriginalName();
$path = 'public/file/'.$request->employee_name;
$file->move($path, $name);
$data[] = $name;
}
}
$sid = new Sid;
$sid->employee_sid = $request->employee_sid;
$sid->employee_npk = $request->employee_npk;
$sid->employee_name = $request->employee_name;
$sid->file_uploads = json_encode($data);
$sid->save();
I expect when I submit that data without the file_uploads it will. but error
Undefined variable: data.
You are defining the $data variable inside an if, so if the condition is false, the $data variable will be not defined. One possible fix could be:
$sid = new Sid;
$sid->employee_sid = $request->employee_sid;
$sid->employee_npk = $request->employee_npk;
$sid->employee_name = $request->employee_name;
$sid->file_uploads = isset($data)? json_encode($data): null;
$sid->save();

File Upload into the Application folder - Zend framework 3

i want to upload a file from the form into my Application folder(public/img/clientes/).
my form file upload field:
$this->add(array(
'name' => 'foto',
'attributes' => array(
'type' => 'file',
),
'options' => array(
'label' => 'Logo da empresa:',
),
));
my add action function on the controller:
public function addAction()
{
$form = new ClienteForm();
if ($this->getRequest()->isPost()) {
$data = $this->params()->fromPost();
$form->setData($data);
if ($form->isValid()) {
$data = $form->getData();
$name = $data['foto'];
if(isset($name)){
if(!empty($name)){
$location = __DIR__."../../../public/img/clientes/";
if(!move_uploaded_file($name, $location)){
return $this->redirect()->toRoute('home');
}
}
}
$this->clienteManager->addNewCliente($data);
return $this->redirect()->toRoute('clientes');
}
}
return new ViewModel([
'form' => $form
]);
}
I cant seam to find the reason for this not to workIf anyone could help me with a solution here i would be incredibly grateful.
Hope everything is self-descriptive here. Just the upload location is a bit strange. As every request is handled through index.php by ZF and this file uses chdir(dirname(__DIR__)) method to go to upper level, so everything is relative to the application root. That's why we can access directly public/img/clientes, in this case. But the recommendation set it via the configuration in module.config.php. And make it available using ServiceManager.
Make sure your upload directory has a right permission.
...
if ($this->getRequest()->isPost()) {
// Merge data thus
$data = array_merge_recursive(
$this->getRequest()->getPost()->toArray(),
$this->getRequest()->getFiles()->toArray()
);
$form->setData($data);
if ($form->isValid()) {
$data = $form->getData();
// Upload path
$location = "public/img/clientes/";
// A bit validation of uploaded file
$allowedExtension = array('jpg', 'jpeg', 'png');
$extension = explode('.', $data['foto']['name']);
$extension = end($extension);
$fileName = time() . '.' . $extension;
// Check if everything is OK!
if (0 === $data['foto']['error'] && in_array($extension, $allowedExtension)) {
move_uploaded_file($data['foto']['tmp_name'], $location . $fileName);
} else {
echo 'Something went wrong!';
}
}
}
...

Laravel image upload validation

I am trying to validate uploaded files using laravel validation but am having issues.
Here is my code:
$this->validate($request, [
'image' =>'mimetypes:image/jpeg,image/png,image/gif',
]);
$avatar = $request->file('image');
$fileName = time(). '.' . $avatar->getClientOriginalExtension();
Image::make($avatar)->resize(300,300)->save( public_path('uploads/avatar/' . $fileName));
$user = Auth::user();
$user->avatar = $fileName;
$user->save();
The issue is when I use a bmp file, I get this error:
Gd error
I am using the Intervention image package. I would rather not switch to the imagick driver.
Any ideas?
Looking at the Intervention package code, you can see two implementations to the processBmp function:
Intervention/Image/Gd/Encoder.php:
protected function processBmp()
{
throw new \Intervention\Image\Exception\NotSupportedException(
"BMP format is not supported by Gd Driver."
);
}
Intervention/Image/Imagick/Encoder.php:
protected function processBmp()
{
$format = 'bmp';
$compression = \Imagick::COMPRESSION_UNDEFINED;
$imagick = $this->image->getCore();
$imagick->setFormat($format);
$imagick->setImageFormat($format);
$imagick->setCompression($compression);
$imagick->setImageCompression($compression);
return $imagick->getImagesBlob();
}
So I think it's safe to say that you can't do it with the GD driver, only with imagick.
Simply use "intervention/image": "~2" or change your driver to Imagick. It is a known issue that GD does not natively support BMP. You can check the issue page on github for details.
Why you don`t use Laravel custom rule for image image?
$this->validate($request, [
'image' =>'image',
]);
hope this solution will fix your error, please try with below logic
public function postUpload(Request $request)
{
$input = $request->all();
$rules = array(
'uploadFile' => 'image|max:8000'
);
$validation = Validator::make($input, $rules);
if ($validation->fails())
{
return array(
'validation_failed' => true,
'errors' => $validation->errors()->toArray()
);
}
$file = $request->uploadFile;
$destinationPath = 'uploads/img';
// Get real extension according to mime type
$ext = $file->extension();
// Hash processed file name, including the real extension
$hashname = date('H.i.s').'-'.md5($request->_token).'.'.$ext;
$upload_success = $request->uploadFile->storeAs($destinationPath, $hashname);
Image::configure(array('driver' => 'imagick'));
$img = Image::make(storage_path() . '/app/uploads/img/' . $hashname);
$img->resize(230, null, function ($constraint) {
$constraint->aspectRatio();
});
$img->save(storage_path() . '/app/uploads/lowres/' .$hashname ,80);
$user_image = new User_images();
$user_image->id_user = Auth::user()->id;
$user_image->handler = $hashname;
$user_image->save();
return array('status' => 'success','message'=> 'Image has been uploaded successfully','file_path'=>'/uploads/'.$hashname);

Categories