how to do code refactoring to reduce similar code in laravel? - php

Hello I am a newbie, I just started creating a project for quiz application.I have repeated code in my store and update
function,how can i reduce the duplication and write a cleaner code, any help will be appreciated
Thanks Nabeel
This is my store method
public function store(Quiz $quiz, QuestionRequest $request)
{
if($request->hasfile('image'))
{
$file=$request->file('image');
//Get File name with the extension
$fileWithExt = $file->getClientOriginalName();
//Get Just File Name
$filename = pathinfo($fileWithExt,PATHINFO_FILENAME);
//Get Just Extension
$extension = $file->getClientOriginalExtension();
//Filename to store
$nameoffile = $filename.'_'.time().'.'.$extension;
//Upload Image
$path = $file->move(public_path('images'),$nameoffile);
//$path = $file->storeAs('app/img/',$nameoffile);
$path = $nameoffile;
}
else
{
$path=null;
}
}
This is my update method
public function update(Quiz $quiz,QuestionRequest $request,Question $question)
{
if(is_null($question->imgpath))
{
if($request->hasfile('image'))
{
$file=$request->file('image');
//Get File name with the extension
$fileWithExt = $file->getClientOriginalName();
//Get Just File Name
$filename = pathinfo($fileWithExt,PATHINFO_FILENAME);
//Get Just Extension
$extension = $file->getClientOriginalExtension();
//Filename to store
$nameoffile = $filename.'_'.time().'.'.$extension;
//Upload Image
$path = $file->move(public_path('images'),$nameoffile);
$path = $nameoffile;
}
else
{
$path=null;
}
}
elseif(!empty($question->imgpath) && $request->hasfile('image'))
{
$file=$request->file('image');
$fileWithExt = $file->getClientOriginalName();
$filename = pathinfo($fileWithExt,PATHINFO_FILENAME);
$extension = $file->getClientOriginalExtension();
$nameoffile = $filename.'_'.time().'.'.$extension;
$path = $file->move(public_path('images'),$nameoffile);
$path = $nameoffile;
}
else
{
$path=$question->imgpath;
}

You can create a new trait or function in your model class and can use that in your controller . Like this
In your Quiz.php just create a new function called fileUpload()
php artisan fileUpload($data)
{
$file=$data;
//Get File name with the extension
$fileWithExt = $file->getClientOriginalName();
//Get Just File Name
$filename = pathinfo($fileWithExt,PATHINFO_FILENAME);
//Get Just Extension
$extension = $file->getClientOriginalExtension();
//Filename to store
$nameoffile = $filename.'_'.time().'.'.$extension;
//Upload Image
$path = $file->move(public_path('images'),$nameoffile);
$path = $nameoffile;
return $path;
}
And in your controller in store() and update() you can just do this
if(is_null($question->imgpath))
{
if($request->hasfile('image'))
{
$path = $quiz->fileUpload($request->file('image'));
}
else
{
$path=null;
}
}

Related

Failed to rename image and upload using storeAs in Laravel

I created a form to store article with an image , and generate a resized version as thumbnail from it.
I want the image to be renamed after the article slug and stored in the "public/img/articles-images " directory but i keep receiving : "Image source not readable" error
This is the image upload handler function in my controller :
private function handleRequest($request)
{
$data = $request->all();
if ($request->hasFile('image')) {
$image = $request->file('image');
$fileName = $request->slug;
$successUploaded = $image->storeAs('img/articles-images', $fileName);
if($successUploaded) {
$width = config('cms.image.thumbnail.width');
$height = config('cms.image.thumbnail.height');
$extension = $image->getClientOriginalExtension();
$thumbnail = str_replace(".{$extension}", "_thumb.{$extension}", $fileName);
Image::make('img/articles-images' . '/' . $fileName)
->resize($width, $height)
->save('img/articles-images' . '/' . $thumbnail);
}
$data['image'] = $fileName;
}
return $data;
}
storeAs() method, which receives the path, the file name, and the (optional) disk as its arguments :
$successUploaded = $request->file('image')->storeAs(
'images', $fileName
);
I solved it ! Apparently there was no need to storeAs() method at all , the new code is like below :
if ($request->hasFile('image')) {
$image = $request->file('image');
$fileName = $request->slug.'.' .$image->getClientOriginalExtension();
$destination = $this->uploadPath;
$successUploaded = $image->move($destination, $fileName);
// //

Update image from edit form Laravel

I want to edit the the blog form in Laravel. All other text information like Title, Body are successfully edited. But Image could not be updated. New image is not uploaded and image path is set as C:\xampp\tmp\php2030.tmp.
My Controller for edit.
public function update(Request $request, $id)
{
$requestData = $request->all();
$post = Post::findOrFail($id);
$post->update($requestData);
if ($request->hasFile('image'))
{
$file = $request->file('image');
$fileNameExt = $request->file('image')->getClientOriginalName();
$fileNameForm = str_replace(' ', '_', $fileNameExt);
$fileName = pathinfo($fileNameForm, PATHINFO_FILENAME);
$fileExt = $request->file('image')->getClientOriginalExtension();
$fileNameToStore = $fileName.'_'.time().'.'.$fileExt;
$pathToStore = public_path('media');
Image::make($file)->resize(600, 531)->save($pathToStore . DIRECTORY_SEPARATOR. $fileNameToStore);
$image = '/images/'.$fileNameToStore;
$post->save();
}
session()->flash('message', 'Successfully updated the post');
return redirect('/');
}
What is wrong with it?
When PHP receives a file upload, by default it writes it to a temporary directory like you're getting, and automatically deletes the file after the request has been handled.
What you need to do is move the uploaded file to a safe location.
Laravel 5.5 has a store method for file uploads that might be of interest.
public function update(Request $request, $id)
{
$requestData = $request->all();
$post = Post::findOrFail($id);
if ($request->hasFile('image')) {
$file = $request->file('image');
$fileNameExt = $request->file('image')->getClientOriginalName();
$fileNameForm = str_replace(' ', '_', $fileNameExt);
$fileName = pathinfo($fileNameForm, PATHINFO_FILENAME);
$fileExt = $request->file('image')->getClientOriginalExtension();
$fileNameToStore = $fileName.'_'.time().'.'.$fileExt;
$pathToStore = public_path('media');
Image::make($file)->resize(600, 531)->save($pathToStore . DIRECTORY_SEPARATOR. $fileNameToStore);
// UPDATE TEMPORARY IMAGE PATH WITH ACTUAL PATH
$requestData['image'] = "/media/{$fileNameToStore}";
}
$post->update($requestData);
session()->flash('message', 'Successfully updated the post');
return redirect('/');
}
Please, use the code below:
public function update(Request $request, $id)
{
$requestData = $request->all();
$post = Post::findOrFail($id);
$pathToStore = public_path('media');
if ($request->hasFile('image'))
{
$file = $request->file('image');
$rules = array('file' => 'required|mimes:png,gif,jpeg'); // 'required|mimes:png,gif,jpeg,txt,pdf,doc'
$validator = \Illuminate\Support\Facades\Validator::make(array('file'=> $file), $rules);
if($validator->passes())
{
$filename = $file->getClientOriginalName();
$extension = $file -> getClientOriginalExtension();
$picture = sha1($filename . time()) . '.' . $extension;
$upload_success = $file->move($pathToStore, $picture);
if($upload_success)
{
//if success, create thumb
$image = Image::make(sprintf($pathToStore.'/%s', $picture))->resize(600, 531)->save($pathToStore.'/thumb/'.$picture);
}
}
$requestData['image'] = "$pathToStore/{$picture}";
}
$post->update($requestData);
session()->flash('message', 'Successfully updated the post');
return redirect('/');
}

same hash multiple images

Well, I want to create only one hash for multiple files i upload so all those files will have the same hash so i can load all of them at once using that hash, but the problem is that in the store function hash changes for every file and i want it to stay the same for that upload
public function store(Request $request)
{
$picture = '';
$hash = substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 8);
if ($request->hasFile('images'))
{
$files = $request->file('images');
foreach($files as $file) {
$image = new Upload();
$filename = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$picture = date('His') .'.'. $extension;
$destinationPath = base_path() . '/public/storage';
$file->move($destinationPath, $picture);
$image->hash = $hash;
$image->file_name = $picture;
$image->path = '/storage/'.$picture;
$image->save($request->all());
return redirect('/a/'.$hash);
}
}
}
You can generate hash and place it in upload form hidden field. After upload just read $_POST['hash'] instead of generating it in store().

PHP file upload is creating filenames starting with "PHP" and with .tmp extension

I am using PHP (Symfony2) in my project which has image upload feature. Inside controller:
if ($request->isXmlHttpRequest() && $request->isMethod('POST')) {
$index=(int)$request->request->get('index');
$image_file = $request->files->get('shop_bundle_managementbundle_posttype')['images'][$index]['file'];
$image= new Image();
$image->setFile($image_file);
$image->setSubDir('hg');
$image->upload();
$em->persist($image);
$em->flush();
}
I use a class UploadFileMover that handle the file upload. I didn't write the following code but as I understand, an MD5 hash will be created from the original file name and used as filename. But the instance of UploadedFile contains a file name like "PHP"+number.tmp, not the original as stored in computer filesystem.
class UploadFileMover {
public function moveUploadedFile(UploadedFile $file, $uploadBasePath,$relativePath)
{
$originalName = $file->getFilename();
$targetFileName = $relativePath . DIRECTORY_SEPARATOR . $originalName;
$targetFilePath = $uploadBasePath . DIRECTORY_SEPARATOR . $targetFileName;
$ext = $file->getExtension();
$i=1;
while (file_exists($targetFilePath) && md5_file($file->getPath()) != md5_file($targetFilePath)) {
if ($ext) {
$prev = $i == 1 ? "" : $i;
$targetFilePath = $targetFilePath . str_replace($prev . $ext, $i++ . $ext, $targetFilePath);
} else {
$targetFilePath = $targetFilePath . $i++;
}
}
$targetDir = $uploadBasePath . DIRECTORY_SEPARATOR . $relativePath;
if (!is_dir($targetDir)) {
$ret = mkdir($targetDir, umask(), true);
if (!$ret) {
throw new \RuntimeException("Could not create target directory to move temporary file into.");
}
}
$file->move($targetDir, basename($targetFilePath));
return str_replace($uploadBasePath . DIRECTORY_SEPARATOR, "", $targetFilePath);
}
}
This class is instanciated when an image is uploaded. In other words, I have an Entity Image that has a method upload. Inside entity class:
public function upload()
{
if (null === $this->getFile()) {
return;
}
$uploadFileMover = new UploadFileMover();
$this->path = $uploadFileMover->moveUploadedFile($this->file, self::getUploadDir(),$this->subDir);
$this->file = null;
}
I var_dumped the filename all across the different steps but I cannot figure out where it is transformed to PHP16653.tmp.
Can it be related to an APACHE related configuration? Your help is appreciated. I really did a lot of research for similar issue in the web to no avail.
The problem was created by the line:
$originalName = $file->getFilename();
Use:
$originalName = $file->getClientOriginalName();
instead.

best way to do this im using resource and eloquent laravel 4

Any best way to do this will be gratefull
what this do is grab the input from a form and save it to the database.
public function update()
{
$file = Input::file('path');
$destinationPath = 'img/';
$filename = $file->getClientOriginalName();
// $extension =$file->getClientOriginalExtension();
$upload_success = Input::file('path')->move($destinationPath, $filename);
$photo = Photo::find($_POST['id']);
$photo->caption = $_POST['caption'];
$photo->path = $destinationPath . $filename;
$photo->save();
if( $upload_success ) {
return Redirect::to('photos/'.$_POST['id'].'/edit')->withInput()->with('success', 'Photo have been updated.');
} else {
return Response::json('error', 400);
}
}
this work just fine but i wonder if there a simplify way to do this like how i can get post data from the form send to update to update the photo information instead of me using the $_POST and get the id from the form parse into the update($id) ect. Thanks
You can use the Input class, instead of accessing the post directly.
I would probably re-write the function a little like this:
public function update()
{
$file = Input::file('path');
$destinationPath = 'img/';
$filename = $file->getClientOriginalName();
if( Input::file('path')->move($destinationPath, $filename) )
{
$photo = Photo::find(Input::get('id'));
$photo->caption = Input::get('caption');
$photo->path = $destinationPath . $filename;
$photo->save();
return Redirect::to('photos/'.$_POST['id'].'/edit')->withInput()->with('success', 'Photo have been updated.');
}
else
{
return Response::json('error', 400);
}
}
The other option is to extract some of this data directly into your Photo model, and do it in there.

Categories