I am doing an Instagram clone project and I have encountered a tricky problem because, there is no error really, but the app is not functioning like its supposed to. Basically, I have added a functionality to instagram web application, where the user can add a post. Once the user uploads the image and caption, the create post page is supposed to redirect back to their profile. Which it does, perfectly. But the problem is, the uploaded posts are not displaying on the profile. Here is how my index.blade looks like
<div class="d-flex">
<div style="padding-right: 25px;"><strong>153</strong> posts</div>
<div style="padding-right: 25px;"><strong>2M</strong> followers</div>
<div style="padding-right: 25px;"><strong>300</strong> following</div>
</div>
<div><strong>{{$user->profile->title}}</strong></div>
<div>{{$user->profile->description}}</div>
<div>{{$user->profile->url}}</div>
</div>
<div class="row pt-5">
#foreach($user->posts as $post)
<div class="col-4>
<img src="storage/{{ $post->image }}" class="w-100">
</div>
#endforeach
</div>
</div>
My PostsController
class PostsController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function create()
{
return view('posts.create');
}
public function store(Request $request)
{
$data = $request->validate([
//'another =>'', Tells laravel to ignore all other fields
'caption'=>'required',
'image'=> 'required' ,
]);
if($request->hasfile('image'))
{
$data = $request->file('image');
$extension = $data->getClientOriginalExtension();
$filename = time().'.'.$extension;
$data->storeAs('uploads/public/', $filename);
}
$data = Auth::user()->posts()->create([
'caption'=>$request->caption,
'image'=>$request->image,
]);
$data = Auth::id();
return redirect()->route('Profile.show', [$data]);
//goes ahead and grabs the authenticated user
}
}
My routes
Route::get('/p/create', [App\Http\Controllers\PostsController::class, 'create'])->name('posts.create');
Route::post('/p', [App\Http\Controllers\PostsController::class, 'store']);
Route::get('/Profile/{user}', [App\Http\Controllers\ProfilesController::class, 'index'])->name('Profile.show');
Related
In Laravel 7, I am have a task management app. I can upload tasks (posts if it were a blog) and images. I have a multiple image upload working as expected. When it comes time to delete a task, the task deletes just fine but the images are left in the database and in the disk which is public into a folder called task-images. Being new to Laravel, I am struggling on how to go about this. I tried to change the settings in the filesystem.php (which I will post with the commented out code) but that didn't change the location as I had expected. In the end, I want to be able to delete the multiple images when I delete a post and also click delete on an individual image and delete that from both db and disk. I am using resource controller for all my task routes. I have no idea how to go about this and the tutorials that I have found don't really address my specific issue. Any help would be greatly appreciated. Thank you in advance.
Here is my task controller at TaskController.php
<?php
namespace App\Http\Controllers;
use App\Task;
use App\Image;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
class TasksController extends Controller
{
public function index()
{
$tasks = Task::orderBy('created_at', 'desc')->paginate(10);
return view('/tasks')->with('tasks', $tasks);
}
public function create()
{
return view('tasks.create');
}
public function store(Request $request)
{
$this->validate($request, [
'task_name' => 'required',
'task_description' => 'required',
]);
// Create Task
$user = Auth::user();
$task = new Task();
$data = $request->all();
$task->user_id = $user->id;
$task = $user->task()->create($data);
if ($request->hasFile('images')) {
$files = $request->file('images');
foreach ($files as $file) {
$name = time() . '-' . $file->getClientOriginalName();
$name = str_replace(' ', '-', $name);
$file->move('task-images', $name);
$task->image()->create(['name' => $name]);
$images = new Image;
$images->name = $name;
}
}
$task->task_name = $request->input('task_name');
$task->task_description = $request->input('task_description');
$task->task_priority = $request->input('task_priority');
$task->task_assigned_by = $request->input('task_assigned_by');
$task->task_assigned_to = $request->input('task_assigned_to');
$task->task_to_be_completed_date = $request->input('task_to_be_completed_date');
$task->task_notes = $request->input('task_notes');
$task->task_status = $request->task_status;
$task->save();
return redirect('/home')->with('success', 'Task Created');
}
public function edit($id)
{
$task = Task::find($id);
return view('tasks.edit', ['task' => $task]);
}
public function update(Request $request, $id)
{
$this->validate($request, [
'task_name' => 'required',
'task_description' => 'required',
]);
$task = Task::find($id);
$task->task_name = $request->input('task_name');
$task->task_description = $request->input('task_description');
$task->task_priority = $request->input('task_priority');
$task->task_assigned_by = $request->input('task_assigned_by');
$task->task_assigned_to = $request->input('task_assigned_to');
$task->task_to_be_completed_date = $request->input('task_to_be_completed_date');
$task->task_notes = $request->input('task_notes');
$task->task_status = $request->input('task_status');
if ($request->hasFile('images')) {
$files = $request->file('images');
foreach ($files as $file) {
$name = time() . '-' . $file->getClientOriginalName();
$name = str_replace(' ', '-', $name);
$file->move('task-images', $name);
$task->image()->create(['name' => $name]);
}
}
$task->update();
return redirect('/home')->with('success', 'Task Updated');
}
public function show($id)
{
$task = Task::find($id);
return view('tasks.show')->with('task', $task);
}
public function destroy($id)
{
$task = Task::findOrFail($id);
// $image = '/task-images/' . $task->image;
Storage::delete($task->image);
$task->delete();
return redirect('home')->with('success', 'Task Deleted');
}
}
filesystem.php (just the disks section)
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
// 'root' => public_path('task-images'),
],
...
in my individual show template, show.blade.php complete in case there is a code conflict.
#extends('layouts.master')
#section('content')
<div class="container">
Go Back
<div class="card p-3">
<div class="row">
<div class="col-md-4 col-sm-12">
<h3>Task</h3>
<p>{{ $task->task_name }}</p>
<h3>Assigned On:</h3>
<p>{{ $task->created_at->format('m/d/Y') }}</p>
<h3>Assigned To:</h3>
<p>{{ $task->task_assigned_to }}</p>
</div>
<div class="col-md-4 col-sm-12">
<h3>Task Description</h3>
<p>{{ $task->task_description }}</p>
<h3>Priority</h3>
<p>{{ $task->task_priority }}</p>
<h3>Status</h3>
<p>{{ $task->task_status }}</p>
</div>
<div class="col-md-4 col-sm-12">
<h3>Test Environment Date:</h3>
<p>{{ $task->task_to_be_completed_date }}</p>
<h3>Notes</h3>
<p>{{ $task->task_notes }}</p>
<h3>Action</h3>
<div style="display: inline;">
<a href="/tasks/{{$task->id}}/edit" class="btn btn-sm btn-primary mr-2">
<i class="fa fa-edit"></i> Edit
</a>
</div>
<form style="display: inline;" action="/tasks/{{ $task->id }}" method="POST" class="">
#csrf
#method('DELETE')
<button type="submit" class="btn btn-danger btn-sm ml-1 mr-1">
<i class="fa fa-trash"></i> Delete
</button>
</form>
</div>
<div class="col-md-12">
<h5>Images</h5>
<hr />
<div class="row">
#if($task->image->count()>0)
#for($i=0; $i < count($images = $task->image()->get()); $i++)
<div class="col-lg-4 col-md-6 col-sm-12">
<img class="w-50 mb-2" src="/task-images/{{ $images[$i]['name'] }}" alt="">
<form style="display: inline;" action="/tasks/{{ $task->name }}" method="POST" class="">
#csrf
#method('DELETE')
<button type="submit" class="btn btn-danger btn-sm ml-1 mr-1">
<i class="fa fa-trash"></i> Delete
</button>
</form>
</div>
#endfor
#else
<p>No images found</p>
#endif
</div>
<br />
</div>
</div>
</div>
</div>
<!--Modal Start-->
<div id="lightbox" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog">
<button type="button" class="close hidden" data-dismiss="modal" aria-hidden="true">×</button>
<div class="modal-content">
<div class="modal-body">
<img class="w-100" src="" alt="" />
</div>
</div>
</div>
</div>
<!--Modal End-->
#endsection
#section('scripts')
<script>
$(document).ready(function() {
var $lightbox = $('#lightbox');
$('[data-target="#lightbox"]').on('click', function(event) {
var $img = $(this).find('img'),
src = $img.attr('src'),
alt = $img.attr('alt'),
css = {
'maxWidth': $(window).width() - 100,
'maxHeight': $(window).height() - 100
};
$lightbox.find('.close').addClass('hidden');
$lightbox.find('img').attr('src', src);
$lightbox.find('img').attr('alt', alt);
$lightbox.find('img').css(css);
});
$lightbox.on('shown.bs.modal', function (e) {
var $img = $lightbox.find('img');
$lightbox.find('.modal-dialog').css({'width': $img.width()});
$lightbox.find('.close').removeClass('hidden');
});
});
</script>
#endsection
In my Task model, Task.php, I have:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Image;
class Task extends Model
{
protected $fillable = [
'task_name', 'task_priority', 'task_assigned_to', 'task_assigned_by', 'task_description', 'task_to_be_completed_date', 'task_status',
'task_notes'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function image()
{
// return $this->hasMany('App\Image');
return $this->hasMany(Image::class);
}
}
and finally my Image Model Image.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Task;
class Image extends Model
{
protected $fillable = [
'task_id',
'name',
];
protected $uploads = '/task-images/';
public function getFileAttribute($image)
{
return $this->uploads . $image;
}
public function task()
{
// return $this->belongsTo('App\Task', 'task_id');
return $this->belongsTo(Task::class);
}
}
If I am missing something, please let me know so I can edit my question. Again, thank you in advance for helping me with this issue. I have been scratching my head all week on this one. Cheers.
Edit
After implementing boot functions in my model as suggested below, I received an error that an invalid argument was used for foreach. I ran a dd($task); and the following image shows the result.
Final Edit
The answer below worked for my situation. I did have to edit some things to finalize the resolution:
in Task.php I changed the foreach to the following.
foreach($task->image ?: [] as $image)
I had declared image and not image in my model and that was causing a problem. Adding the ternary operator also helped the code not throw any errors.
In my TasksController.php I changed both the update and create functions with the same ternary operator as follows:
if ($request->hasFile('images')) {
$files = $request->file('images');
foreach ($files ?: [] as $file) {
$name = time() . '-' . $file->getClientOriginalName();
$name = str_replace(' ', '-', $name);
$file->move('task-images', $name);
$task->image()->create(['name' => $name]);
}
}
I hope this helps anyone else having the same issue. Thanks to #GrumpyCrouton and #lagbox for their help in resolving this as well as #user3563950
Without them, I would still by stratching my head for another couple of weeks.
on your App\Image class, implement to boot function with the following;
use Illuminate\Support\Facades\Storage;
public static function boot() {
parent::boot();
self::deleting(function($image) {
Storage::delete(Storage::path($image->name));
});
}
Also implement the boot method in App\Task class
use Illuminate\Support\Facades\Storage;
public static function boot() {
parent::boot();
self::deleting(function($task) {
foreach($task->images as $image) {
$image->delete();
}
});
}
Now on your TaskController implement the destroy method as follows;
public function destroy($id)
{
$task = Task::findOrFail($id);
$task->delete();
return redirect('home')->with('success', 'Task Deleted');
}
As a bonus, learn Laravel model binding to ease the pain of finding an instance using findOrFail()
When I click on a particular product on the products page, it directed me to the single product page. Particular product ID also showing in the URL. But data won't be passed. My single product page doesn't show the particular product data.
This is my Controller.
SingleProductController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Product;
use App\Category;
class SingleProductController extends Controller
{
public function index(Product $product)
{
$arr['product'] = $product;
return view('singleproducts')->with($arr);
}
public function create()
{
//
}
public function store(Request $request)
{
//
}
public function show($id)
{
$product = Product::find($id);
return view ('singleproducts')->with(['product'=>$product]);
}
public function edit($id)
{
//
}
public function update(Request $request, $id)
{
//
}
public function destroy($id)
{
//
}
}
This is my blade file.
singleproducts.blade
#extends('layouts.singleproducts')
#section('content')
<h2 class="font-size-25 text-lh-1dot2">{{ $product ['prod_name'] }} </h2>
<div class="mb-4">
<div class="d-flex align-items-baseline">
<ins class="font-size-36 text-decoration-none">{{ $product ['prod_price'] }}</ins>
<del class="font-size-20 ml-2 text-gray-6">$2,299.00</del>
</div>
</div>
#endsection
This is my route.
web.php
Route::get('/singleproducts', 'SingleProductController#index')->name('singleproducts');
Route::get('/singleproducts/{id}', 'SingleProductController#show')->name('eachproduct');
Why my show function is not working?
route.php
Route::get('/singleproducts', 'SingleProductController#index')->name('singleproducts');
Route::get('/eachproduct/{id}', 'SingleProductController#show')->name('eachproduct');
Product List Page
#if (isset($products) && count($products) > 0)
#foreach ($products as $product)
<div class="blog_box_inner" style="cursor: pointer;" >
<h1 class="blog_inner_heading">
<a href="/eachproduct/{{$product['id']}}" class="blog_readmore_link">
{{$product['prod_name']}}
</a>
</h1>
</div>
#endforeach
#endif
Single page
<h2 class="font-size-25 text-lh-1dot2">{{ $product['prod_name']}} </h2>
Controller
public function index() {
$products = Product::orderBy('id', 'DESC')->get();
return view('')->with(compact('products'));
}
public function show($id) {
$product = Product::find($id);
return view('')->with(compact('product'));
}
Hope fully it will help to you easily.
Use like this
return view('singleproducts',compact('product'));
In your view use like this
<h2 class="font-size-25 text-lh-1dot2">{{ $product->prod_name }} </h2>
<ins class="font-size-36 text-decoration-none">{{ $product->prod_price }}</ins>
Try this
public function show(Product $product)
{
return view ('singleproducts', compact('product'));
}
and pass in route
Route::get('/eachproduct/{product}', 'SingleProductController#show')->name('eachproduct');
and in your view page get product data as
singleproducts.blade
#extends('layouts.singleproducts')
#section('content')
<h2 class="font-size-25 text-lh-1dot2">{{ $product->prod_name }} </h2>
<div class="mb-4">
<div class="d-flex align-items-baseline">
<ins class="font-size-36 text-decoration-none">{{ $product->prod_price }}</ins>
<del class="font-size-20 ml-2 text-gray-6">$2,299.00</del>
</div>
</div>
#endsection
It will auto find your product on base of id.
Question
Why my variable in ProfileController is not loaded in my blade(index2.blade.php)?
Error Message
Undefined variable: plus (View: /work/resources/views/stories/index2.blade.php)
My Codes
routes/web.php
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('login');
Route::match(['get','post','middleweare'=>'auth'], '/',
'StoriesController#index',
'StoriesController#store',
'ProfileController#index',
'ProfileController#store'
);
Route::match(['get','post','middleweare'=>'auth'], 'stories/create',
'StoriesController#add',
'StoriesController#upload'
);
Route::match(['get','post','middleweare'=>'auth'], 'profile/create',
'ProfileController#add',
'ProfileController#upload'
);
Route::group(['middleweare' => 'auth','name'=>'profile'], function () {
Route::get('/profile/edit', 'ProfileController#edit');
});
Route::get('/home', 'HomeController#index')->name('home');
Auth::routes();
app/Http/Controllers/ProfileController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\stories;
use App\History;
use App\Posts;
use Carbon\Carbon;
use Storage;
class ProfileController extends Controller
{
public function index(Request $request)
{
$plus = Posts::all();
return view('stories.index2', compact('plus'));
}
public function upload(Request $request)
{
$this->validate($request, [
'file' => [
'required',
'file',
'image',
'mimes:jpeg,png',
]
]);
if ($request->file('file')->isValid([])) {
$path = $request->file->store('public');
return view('stories.index2')->with('filename', basename($path));
} else {
return redirect()
->back()
->withInput()
->withErrors();
}
}
public function store(Request $request)
{
$d = new \DateTime();
$d->setTimeZone(new \DateTimeZone('Asia/Tokyo'));
$dir = $d->format('Y/m');
$path = sprintf('public/posts/%s', $dir);
$data = $request->except('_token');
foreach ($data['plus'] as $k => $v) {
$filename = '';
$posts = Posts::take(1)->orderBy('id', 'desc')->get();
foreach ($posts as $post) {
$filename = $post->id + 1 . '_' . $v->getClientOriginalName();
}
unset($post);
if ($filename == false) {
$filename = 1 . '_' . $v->getClientOriginalName();
}
$v->storeAs($path, $filename);
$post_data = [
'path' => sprintf('posts/%s/', $dir),
'name' => $filename
];
$a = new Posts();
$a->fill($post_data)->save();
}
unset($k, $v);
return redirect('/');
}
public function create(Request $request)
{
$this->validate($request, Profile::$rules);
$profile = new Profile;
$form = $request->all();
unset($form['_token']);
$profile->fill($form);
$profile->save();
return redirect('/');
}
public function add()
{
return view('profile.create2');
}
public function edit()
{
return view('profile.edit');
}
}
resources/views/stories/index2.blade.php
#extends('layouts.front2')
#section('title','mainpage')
#section('content')
<div class="profile">
<div class="profileimg">
#foreach ($plus as $pplus)
<img src="/storage/{{ $pplus->path . $pplus->name }}" style="height: 210px; width: 210px; border-radius: 50%;">
#endforeach
</div>
<div class="name">
#guest
<a class="nav-link2" href="{{ route('register')}}">{{ __('Create Accout!')}}</a>
#else
<a id="navbarDropdown" class="nav-link2" href="#" role="button">
{{Auth::user()->name}}<span class="caret"></span></a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
#csrf
</form>
</div>
#endguest
<div class="aboutme">
You can write your profile here!You can write your profile here!You can write your profile here!
You can write your profile here!You can write your profile here!You can write your profile here!
You can write your profile here!You can write your profile here!You can write your profile here!
You can write your profile here!You can write your profile here!You can write your profile here!
You can write your profile here!You can write your profile here!You can write your profile here!
</div>
</div>
<div class="new">
<div class="newtitle">
<h1>New</h1>
</div>
<div class="container1">
#foreach ($plus as $pplus)
<img src="/storage/{{ $pplus->path . $pplus->name }}" class="images" style="height: 150px; width: 150px; border-radius: 50%;">
#endforeach
<div class="more">
more...
</div>
</div>
</div>
<div class="stories">
<div class="titlestories">
<h1>Stories</h1>
</div>
<div class="container2">
<div class="titleclose">
<h2>#CloseFriends</h2>
</div>
<div class="titlefollow">
<h2>#Follows</h2>
</div>
</div>
</div>
{{ csrf_field() }}
#endsection
In your upload method, you're missing the $plus variable
Change it to this
public function upload(Request $request)
{
$this->validate($request, [
'file' => [
'required',
'file',
'image',
'mimes:jpeg,png',
]
]);
if ($request->file('file')->isValid([])) {
$path = $request->file->store('public');
$filename = basename($path);
$plus = Posts::all();
return view('stories.index2', compact('filename','plus'));
} else {
return redirect()
->back()
->withInput()
->withErrors();
}
}
return view('stories.index2, [ 'plus' => Posts::all() ]); should work.
So i was making a form that consists of three field, the title, thumbnail, and textarea(with texteditor) and it seems that it upload the image just fine since i notice that there is images that i had uploaded in my /public/image folder after i submit the form, but when i check the database the thumbnail field showed not the name of the file in the /public/image folder like 20190713125534.jpg but
C:\xampp\tmp\phpC18A.tmp
im confused i thought it doesn't upload the image at all, but as i explained earlier it does, so my question is how do i change the value of thumbnail field with the filename and how do i show the image in my view ?
this is my Blogcontroller.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Blog;
use Validator,Redirect,Response,File;
class BlogController extends Controller
{
public function index()
{
$blogs = Blog::get();
return view('post.post_textarea',[
'blogs' => $blogs
]);
}
public function store(Request $request)
{
Blog::create([
'name' => $request->name,
'message' => $request->message,
'thumbnail' => $request->thumbnail,
]);
if ($files = $request->file('thumbnail')) {
$destinationPath = 'public/image/'; // upload path
$profileImage = date('YmdHis') . "." . $files->getClientOriginalExtension();
$files->move($destinationPath, $profileImage);
$insert['thumbnail'] = "$profileImage";
}
return redirect()->back();
}
public function getFullPost($blog_id) {
$blogs = Blog::where('id', '=', $blog_id)->get();
return view('post.read')->with(compact('blogs'));
}
}
this is my view for the form
<form enctype="multipart/form-data" method="POST">
{{csrf_field()}}
<div class="form-group">
<h4 style="color: black;" >Judul</h4>
<br>
<input type="text" class="form-control" name="name">
</div>
<div class="form-group">
<h4 style="color: black;" >Thumbnail</h4>
<br>
<input type="file" name="thumbnail">
</div>
<div class="form-group">
<h4 style="color: black;" >Isi</h4>
<br>
<textarea class="form-control" name="message" id="" rows="10"></textarea>
</div>
<div class="form-group">
<button class="pull-right site-btn" type="submit" >Upload<img src="../public/asset/img/icons/double-arrow.png" alt="#"/></button>
</div>
</form>
and this is my view to display the data from database
#foreach ($blogs as $blog)
<div class="blog-item">
<div class="blog-thumb">
<img src="asset/img/blog/1.jpg" alt=""> ->this is where i was supposed to fetch the image
</div>
<div class="blog-text text-box text-white">
<div class="top-meta">{{ Carbon\Carbon::parse($blog->created_at)->format('d-m-Y') }} / di Rakitan</div>
<h3>{{ $blog->name }}</h3>
<p>{!! \Illuminate\Support\Str::words($blog->message, 30, '...') !!}</p>
Lanjutkan Baca <img src="asset/img/icons/double-arrow.png" alt="#"/>
</div>
</div>
#endforeach
try to add this in controller
$blog = new Blog;
$blog->name = $request->name;
$blog->message = $request->message;
if($request->hasFile('thumbnail')) {
$file = Input::file('thumbnail');
//getting timestamp
$timestamp = str_replace([' ', ':'], '-', Carbon::now()->toDateTimeString());
$name = $timestamp. '-' .$file->getClientOriginalName();
$file->move(public_path().'/images/', $name);
$blog->thumbnail = url('/images/' . $name);
}
$blog->save();
return back();
than in your view
#foreach ($blogs as $blog)
<div class="blog-item">
<div class="blog-thumb">
<img src="{{ $blog->thumbnail }}" alt=""> ->this is where i was supposed to fetch the image
</div>
<div class="blog-text text-box text-white">
<div class="top-meta">{{ Carbon\Carbon::parse($blog->created_at)->format('d-m-Y') }} / di Rakitan</div>
<h3>{{ $blog->name }}</h3>
<p>{!! \Illuminate\Support\Str::words($blog->message, 30, '...') !!}</p>
Lanjutkan Baca <img src="asset/img/icons/double-arrow.png" alt="#"/>
</div>
</div>
#endforeach
The problem with your code, I think in your store function, you did not save it correctly. Please see my code below to save link of your thumbnail into db.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Blog;
class BlogController extends Controller{
//some your function goes here
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$blog = new Blog;
$blog->name = $request->input('name');
$blog->message = $request->input('message');
$file = $request->file('your_thumbnail');
//make sure yo have image folder inside your public
$destination_path = 'image/';
$profileImage = date("Ymd").".".$file->getClientOriginalName();
$file->move($destination_path, $profileImage);
//save the link of thumbnail into myslq database
$blog->thumbnail = $destination_path . $profileImage;
$blog->save();
return redirect()->back();
}
}
In my application, a user can upload an image for their profile photo. How do I update a users photo and the delete the previously uploaded photo? This is what I have so far in the upload controller:
Photos Model
class Photos extends Eloquent {
protected $table = 'photos';
protected $fillable = array('user_id', 'location');
public function user (){
return $this->belongsTo('User');
}
}
user model
public function photos()
{
return $this->hasOne('photos');
}
Upload Controller
class UploadController extends \BaseController {
public function postUpload (){
$id = Auth::user()->id;
$input = Input::all();
$rules = array(
'photo' => 'required|image|max:500'
);
$validator = Validator::make($input, $rules);
if($validator->fails()){
return Redirect::to('user/profile/'.$id.'/edit')->withErrors($validator);
}
$extension = Input::file('photo')->getClientOriginalExtension();
$directory = public_path('/var/chroot/home/content/59/11581559/html/beta') . '/uploads/'.sha1($id);
$filename = sha1($id.time()).".{$extension}";
$upload_success = Input::file('photo')->move($directory, $filename);
Image::make(Input::file('photo')->getRealPath())->resize(300, 200)->save('foo.jpg');
if($upload_success){
$photo = new Photos(array(
'location' => URL::to('/uploads/'.sha1($id).'/'.$filename)
));
$photo->user_id = $id;
$photo->save();
Session::flash('success_photo', 'You have Successfully uploaded your profile photo!');
return Redirect::to('user/profile/'.$id.'/edit');
}
else{
Session::flash('status_error', 'An Error has occurred while uploading your photo. Please try again!');
}
return Redirect::to('user/profile/'.$id.'/edit');
}
}
View
<div class="col-lg-3">
<div class="panel panel-default">
<div class="panel-heading">
#if(Session::has('status_error'))
<div class="alert alert-error">
<a class="close" data-dismiss="alert" href="#" aria-hidden="true">×</a>
{{ implode('', $errors->all('<li class="error"><b>:status_error</b></li>')) }}
</div>
#endif
<span class="glyphicon glyphicon-exclamation-sign"></span> Upload a Photo
</div>
<div class="panel-body text-center">
#if($user->photos)
<img width="190" height="119" class="img-responsive img-thumbnail" src="{{$user->photos->location }}" alt="">
#endif
<div class="clearfix"></div>
<div class="btn-group mtop-20">
<button type="button" class="btn btn-primary" onclick="$('#upload_modal').modal({backdrop:'static'});">
<span class="glyphicon glyphicon-upload"></span>
</button>
</div>
</div>
<?php echo View::make('modals.photo-upload') ?>
</div><!-- end panel-default -->
</div><!-- col 3-->
Let's talk about what you're doing and work from there.
Uploading a Photo
- In your controller, you're uploading a photo.
- If the upload succeeds, you're storing the location of the photo on your server as well as the ID of the user to whom the photo belongs.
Updating a Photo
- In your controller, you're uploading a photo.
- If the upload succeeds, you're going to:
Get the location of the current file in the database.
$this->photo->where('user_id' , '=' , $the_user_id_in_question)
->get(array('location'));
Delete the file at that location using the delete() function in the FileSystem class (found here: https://github.com/laravel/framework/blob/master/src/Illuminate/Filesystem/Filesystem.php)
Update the user's photo location with the new one:
$this->photo->where('user_id' , '=' , $the_user_id_in_question)
->update('location' => $the_new_upload_location);
I hope that's what you're looking for. Cheers!