Laravel uploading files and extension issue - php

I am trying to make store method where placing 2 different type of files - .pdf and .step.
First issue, that .pdf file is moved to wanted directory, but in database storing temporary location like C:\xampp\tmp\phpAA39.tmp etc...
At the start was same issue with .step files, but i tried to update my code and now it's not even storing path to database. Both files are placing to storage/models and storage/drawings how it should be, but .step files are saving as .txt by some reasons.
ProductController:
public function store(Order $order, Request $request){
$this->validate($request, [
'name'=>'required',
'drawing'=>'nullable|file',
'_3d_file'=>'nullable|file',
'quantity'=>'integer',
'unit_price'=>'required',
'discount'=>'nullable'
]);
if (request('drawing')) {
request('drawing')->store('drawings');
}
if (request('_3d_file')) {
request('_3d_file')->store('models');
}
// dd(request()->all());
$order->products()->create($request->all());
session()->flash('product-created', 'New product was added successfully');
return redirect()->route('order', $order);
}
Update:
Figured out, how to solve an extension and temp location stuff... but still don't understand why on my store method does not storing 3dfile path while with drawing is ok and code is exactly the same. Also on update method it stores path with no errors. Any thoughts?
public function store(Order $order){
$inputs = request()->validate([
'name'=>'required',
'drawing'=>'file',
'_3d_file'=>'file',
'quantity'=>'integer',
'unit_price'=>'required',
'discount'=>'nullable'
]);
if (request('drawing')) {
$filename = request('drawing')->getClientOriginalName();
$inputs['drawing'] = request('drawing')->storeAs('drawings', $filename);
}
if (request('_3d_file')) {
$filename = request('_3d_file')->getClientOriginalName();
$inputs['_3d_file'] = request('_3d_file')->storeAs('models', $filename);
}
//dd($inputs['_3d_file']);
$order->products()->create($inputs);
session()->flash('product-created', 'New product was added successfully');
return redirect()->route('order', $order);
}
update
public function update(Product $product){
$inputs = request()->validate([
'name'=>'required',
'drawing'=>'nullable|file',
'_3d_file'=>'nullable|file',
'quantity'=>'integer',
'unit_price'=>'required',
'discount'=>'nullable'
]);
if (request('drawing')) {
$filename = request('drawing')->getClientOriginalName();
$inputs['drawing'] = request('drawing')->storeAs('drawings', $filename);
$product->drawing = $inputs['drawing'];
}
if (request('_3d_file')) {
$filename = request('_3d_file')->getClientOriginalName();
$inputs['_3d_file'] = request('_3d_file')->storeAs('models', $filename);
$product->_3d_file = $inputs['_3d_file'];
}
$product->name = $inputs['name'];
$product->quantity = $inputs['quantity'];
$product->unit_price = $inputs['unit_price'];
$product->discount = $inputs['discount'];
$product->save();
session()->flash('product-updated', 'The product was updated successfully');
return redirect()->route('product', $product);
}

Related

Laravel problem store variables data in Database

In my database name files have columns id_message and file_path. File is stored in MyFiles/{id_message}.
Problem is how variables $idParameter and $pathFile save in database. No errors show.
function fileUpload(Request $request)
{
$request->validate([
'id_message' => 'required|min:6'
]);
$idParameter = $request->id_message=$request->id_message;
$result=$request->file('file_path')->store('MyFiles/'.$idParameter);
return ["result"=>$result];
$pathFile = getPathname('MyFiles/'.$idParameter);
$file = new File;
$file->id_message=$idParameter;
$file->file_path=$pathFile;
$file->save();
}
Remove return ["result"=>$result]; and add this into end.

Image update and remove old image on Laravel

Trying to implement update article in my update controller it seems works, but the problem is when I only want to update the post without uploading an image the old always getting remove which is it shouldn't.
here's my store function
public function store(Post $post)
{
$post->update($this->validateRequest());
$this->storeImage($post);
return redirect('post/'.$post->id)->with('success', 'New ariticle has been posted');
}
}
here's my validation
private function validateRequest()
{
return request()->validate([
'title'=> 'required',
'content' => 'required',
'image' => 'sometimes|image|max:5000',
]);
}
here's my update function
public function update(Post $post)
{
File::delete(public_path('storage/'.$post->image));
$post->update($this->validateRequest());
$this->storeImage($post);
return redirect('post/'.$post->id)->with('success', 'This post has
been Edited');
}
}
I've tried to add File::delete to my storeImage function and delete it from my update function, it fix the problem but the old image is not removed from directory
private function storeImage($post)
{
if (request()->has('image')){
File::delete(public_path('storage/'.$post->image))
$post->update([
'image' => request()->image->store('uploads', 'public'),
]);
$image = Image::make(public_path('storage/'.$post->image))->fit(750, 300);
$image->save();
}
}
Ok since I use model binding in my controller I don't have to find the id right?
so I change my update function which is basically Akhtar munir suggested, and turn out to be something like this. The image update work, it also remove the old image when I update it. But I have found another issue, the problem is when I edit article and title it didn't change like when I update it, I hope you can take look at this is this correct?
public function update(Post $post){
$this->validateRequest();
if(request()->hasFile('image') && request('image') != ''){
$imagePath = public_path('storage/'.$post->image);
if(File::exists($imagePath)){
unlink($imagePath);
}
$image = request()->file('image')->store('uploads', 'public');
$post->update([
'title' => request()->title,
'content' => request()->content,
'image' => $image,
]);
}
}
This is what I have done in one of my method. It may help you.
public function update(Request $request, $id)
{
if (UserDocument::where('id',$id)->exists()) {
$this->validateUserDocument($request);
if ($request->hasFile('doc_file') && $request->doc_file != '') {
$doc = UserDocument::where('id',$id)->first();
// dd($doc);
$file_path = storage_path().'/app/'.$doc['doc_file'];
//You can also check existance of the file in storage.
if(Storage::exists($file_path)) {
unlink($file_path); //delete from storage
// Storage::delete($file_path); //Or you can do it as well
}
$file = $request->file('doc_file')->store('documents'); //new file path
$doc->update([
'title' => $request->title,
'doc_file' => $file //new file path updated
]);
session()->flash('success','Document updated successfully!');
return redirect()->route('userdocs');
}
session()->flash('error','Empty file can not be updated!');
return redirect()->back();
}
session()->flash('error','Record not found!');
return redirect()->back();
}
In this code, I just simply want to clearify to you that I have stored image path in database, first I have retrieved that path and with that path I have found image in my local storage, delete it first and then update it with the new one. But make sure to store image path in database in both cases ofcourse with insert and update.
So finally you can also optimize your code like this, it will do the same thing as you expect, whether image and all data or only title and content.
public function update(Post $post){
$this->validateRequest();
$data = [
'title' => request()->title,
'content' => request()->content
];
if (request()->hasFile('image') && request('image') != '') {
$imagePath = public_path('storage/'.$post->image);
if(File::exists($imagePath)){
unlink($imagePath);
}
$image = request()->file('image')->store('uploads', 'public');
$data['image'] = $image;
//$post->update($data);
}
$post->update($data);
}
Try this one
private function storeImage($post)
{
if (request()->hasFile('image')){
$image_path = "/storage/".'prev_img_name'; // prev image path
if(File::exists($image_path)) {
File::delete($image_path);
}
$post->update([
'image' => request()->image->store('uploads', 'public'),
]);
$image = Image::make(public_path('storage/'.$post->image))->fit(750, 300);
$image->save();
}
}

How to make Laravel controller store file upload with a relationship

I am trying to store an uploaded file with a relationship to an Employee model. I am unable to retrieve the employee id after uploading the file to save it to the DB table as a foreign key.
Routes:
Route::resource('employees', 'EmployeesController');
Route::post('documents', 'DocumentsController#createdocument')
So I am on a URL that says http://localhost/public/employees/8 when I hit upload it redirects to http://localhost/public/documents and the file does upload but shows error when writing to DB.
Here is my code. How can I do it?
public function createdocument(Request $request, Employee $id)
{
$file = $request->file('file');
$allowedFileTypes = config('app.allowedFileTypes');
$maxFileSize = config('app.maxFileSize');
$rules = [
'file' => 'required|mimes:'.$allowedFileTypes.'|max:'.$maxFileSize
];
$this->validate($request, $rules);
$time = time(); // Generates a random string of 20 characters
$filename = ($time.'_'.($file->getClientOriginalName())); // Prepend the filename with
$destinationPath = config('app.fileDestinationPath').'/'.$filename;
$uploaded = Storage::put($destinationPath, file_get_contents($file->getRealPath()));
if($uploaded){
$employee = Employee::find($id);
$empdoc = new EmpDocuments();
$empdoc->name = $filename;
$empdoc->employee_id = $employee->id;
$empdoc->save();
}
return redirect('employees');
}
These are my models.
Employee.php
public function EmpDocuments()
{
return $this->hasMany('App\EmpDocuments');
}
public function createdocument(){
return $this->EmpDocuments()->create([
'name' => $filename,
'employee_id' => $id,
]);
}
EmpDocuments.php
public function Employee()
{
return $this->belongsTo('App\Employee');
}
With the above models and controller I am now getting error
General error: 1364 Field 'employee_id' doesn't have a default value (SQL: insert into empdocuments.
How do I capture the employee_id?
Managed to fix it, in case someone has similar problem. Ensure you pass the id with the route action for it to be capture in the next request.
Here is the final controller.
public function update(Request $request, $id)
{
$file = $request->file('file');
$allowedFileTypes = config('app.allowedFileTypes');
$maxFileSize = config('app.maxFileSize');
$rules = [
'file' => 'required|mimes:'.$allowedFileTypes.'|max:'.$maxFileSize
];
$this->validate($request, $rules);
$time = time(); // Generates a random string of 20 characters
$filename = ($time.'_'.($file->getClientOriginalName())); // Prepend the filename with
$destinationPath = config('app.fileDestinationPath').'/'.$filename;
$uploaded = Storage::put($destinationPath, file_get_contents($file->getRealPath()));
if($uploaded){
$employee = Employee::find($id);
$empdoc = new EmpDocuments();
$empdoc->name = $filename;
$employee->empdocuments()->save($empdoc);
return redirect('employees/' . $id . '#documents')->with('message','Document has been uploaded');
}
}
Do you have a relationship between Employee and EmpDocuments ??
If I am understanding well EmpDocuments belongsTO Employees right??
I'm trying to help but I need to understand, one employee can have many documents right?? but each document belongs to just one employee right??
If is like that you should make a relationship in your employee model,
` public function employeeDocuments(){
return $this->hasMany(EmpDocuments::class);
}`
Then in the same model
`public function createEmployeeDocuments(){
return $this->employeeDocuments()->create([
'your_db_fields' =>your file,
'your_db_fields' => your other some data,
]);
}`
The id will be inserted automatically
I hope I helped you!!
https://laravel.com/docs/5.3/eloquent-relationships
Are your fillable empty???
To use the Eloquent create method you need to set you fillable array to mass assignment. Try this, if is still not working tell me and I will try to do my best.
protected $fillable = [ 'employee_id', 'Your_db_field', 'Your_db_field', 'per_page', 'Your_db_field', 'Your_db_field' ];

Unable to upload images on laravel app to hostgator hosting

I've been searching all around the net to try to fix this problem. Changed the code in my controllersfolder multiple times and still no solution. I changed the permissions of my img folder and products folder to 777 and still no success.
This is the structure of my folders on my FTP cyberduck:
-->app_base/ ( Has Everything from the base laravel folder EXCEPT the /public/ folder)
-->[some other folders...]
-->public_html/
-->daveswebapp.us/ (name of my website. Has all the content of my base public/folder)
-->img
-->products
[empty folder]
This is the error I receive each time I try to upload new product images in my admin panel:
Intervention \ Image \ Exception \ NotWritableException
Can't write image data to path (/home2/ecuanaso/app_base/bootstrap/img/products/1417822656.jpg)
PRODUCTS CONTROLLER CODE:
<?php
class ProductsController extends BaseController {
public function __construct() {
parent::__construct();
$this->beforeFilter('csrf', array('on'=>'post'));
$this->beforeFilter('admin');
}
public function getIndex() {
$categories = array();
foreach(Category::all() as $category) {
$categories[$category->id] = $category->name;
}
return View::make('products.index')
->with('products', Product::all())
->with('categories', $categories);
}
public function postCreate() {
$validator = Validator::make(Input::all(), Product::$rules);
if ($validator->passes()) {
$product = new Product;
$product->category_id = Input::get('category_id');
$product->title = Input::get('title');
$product->description = Input::get('description');
$product->price = Input::get('price');
$image = Input::file('image');
$filename = time() . '.' . $image->getClientOriginalExtension();
$path = public_path('img/products/' . $filename);
Image::make($image->getRealPath())->resize(468, 249)->save($path);
$product->image = 'img/products/'.$filename;
$product->save();
return Redirect::to('admin/products/index')
->with('message', 'Product Created');
}
return Redirect::to('admin/products/index')
->with('message', 'Something went wrong')
->withErrors($validator)
->withInput();
}
public function postDestroy() {
$product = Product::find(Input::get('id'));
if ($product) {
File::delete('public/'.$product->image);
$product->delete();
return Redirect::to('admin/products/index')
->with('message', 'Product Deleted');
}
return Redirect::to('admin/products/index')
->with('message', 'Something went wrong, please try again');
}
public function postToggleAvailability() {
$product = Product::find(Input::get('id'));
if ($product) {
$product->availability = Input::get('availability');
$product->save();
return Redirect::to('admin/products/index')->with('message', 'Product Updated');
}
return Redirect::to('admin/products/index')->with('message', 'Invalid Product');
}
}
Images should go into public folder and not in app directory in your code you are trying to move the image into app directoy but defining directory address with public_path the following code uploads an image into your public/uploads folder which is then accessible via visiting yourdomain.com/img.jpg
//create two empty variables outside of conditional statement because we gonna access them later on
$filename = "";
$extension = "";
//check if you get a file from input, assuming that the input box is named photo
if (Input::hasFile('photo'))
{
//create an array with allowed extensions
$allowedext = array("png","jpg","jpeg","gif");
/get the file uploaded by user
$photo = Input::file('photo');
//set the destination path assuming that you have chmod 777 the upoads folder under public directory
$destinationPath = public_path().'/uploads';
//generate a random filename
$filename = str_random(12);
//get the extension of file uploaded by user
$extension = $photo->getClientOriginalExtension();
//validate if the uploaded file extension is allowed by us in the $allowedext array
if(in_array($extension, $allowedext ))
{
//everything turns to be true move the file to the destination folder
$upload_success = Input::file('photo')->move($destinationPath, $filename.'.'.$extension);
}
Not sure if a a solution goes here but I figured it out after days of seaching.
I was saving the file into the wrong directory. took out the public from ->save method
I changed
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products/'.$filename);
to:
Image::make($image->getRealPath())->resize(468, 249)->save('img/products/'.$filename);

How to modify Input::all() data in laravel 4?

I use Laravel 4 and my store function in controller is :
public function store()
{
$validation = new Services\Validators\Speaker;
if($validation->passes())
{
$file = Input::file('image');
$imageName = time().'_'.$file->getClientOriginalName();
$file->move('photos/',$imageName);
$input = Input::all();
$speaker = $this->speaker->create(Input::all());
return Redirect::route('speaker.index');
}
The uploaded photo is moved to the specified place and named correctly. But in the database, the image file name is not correctly saved. "C:\xampp\tmp\php2B7D.tmp" this kind of data is saved. I want to save image name and path. Any ideas. Thanks in advance.
I found solution. here the code
public function store()
{
$validation = new Services\Validators\Speaker;
if($validation->passes())
{
$file = Input::file('image');
$imageName = time().'_'.$file->getClientOriginalName();
$file->move('photos/',$imageName);
$input = array('name'=>Input::get('name'),
'image'=> 'photos/'.$imageName,
'desc'=>Input::get('desc')
);
$speaker = $this->speaker->create($input);
return Redirect::route('speaker.index');
}

Categories