I am creating commenting system, now, I want to show user profile images in comment area.
I want to catch and show multiple images from laravel 5.8 public folder. Here is what I tried.
If user has a profile image, I want to show it. If not, I want to show
an avatar using vue avatar component. My images are stored in
public/uploads/profile.
Now I don't have any errors in my console. Also I can show user name and user comments.
Image name is stored in mysql.
comment.vue(first comment)
<div class="user" v-if="comment.user.image && comment.user.image.length > 0">
<span :v-for="(item, index) in comment.user.image">
<img :src="'uploads/' + 'profile' + '/' + item.image">
</span>
</div>
<div else class="user" >
<avatar :username="comment.user.name" :size="45"></avatar>
</div>
commentController.php
public function index(Post $post)
{
return $post->comments()->paginate(10);
}
public function show(Comment $comment)
{
return $comment->replies()->paginate(10);
}
public function store(Request $request, Post $post)
{
return auth()->user()->comments()->create([
'body' => $request->body,
'post_id' => $post->id,
'comment_id' => $request->comment_id
])->fresh();
}
profiles table
Schema::create('profiles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('user_id');
$table->string('image');
$table->string('gender');
$table->string('country');
$table->string('bod');
$table->string('instagram');
$table->string('description');
$table->timestamps();
});
In my VS code, uploads folder started turning red.
My solution is create a api route to show image. For example.
api.php
Route::get('profile/{fileName}', 'ProfileController#showImage');
ProfileController.php
class ProfileController {
...
public function showImage($fileName)
{
$path = public_path("/images/{$fileName}");
if (!\File::exists($path)) {
return response()->json(['message' => 'Image not found.'], 404);
}
$file = \File::get($path);
$type = \File::mimeType($path);
$response = \Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
}
}
And you image src will be /api/profile/{imageName}. This is my solution.
Related
I am performing a Blog application using laravel.. I want to track the count of the post view whenever a user view a particular blog post it should increment only once whether it is a registered user or non-registered users. ... And also want to display the most viewed blogs according to the view count.. Can anyone assist with the logic.
/ Table
Schema::create('posts', function(Blueprint $table)
{
$table->increments('id');
$table->text('body')
$table->integer('count');
...
$table->timestamps();
});
public function show($id)
{
$post = Post::find($id);
Post::update([
'count' => $post->count + 1
]);
return View::make('posts', compact('post'));
}
public function show($id)
{
$post = Post::find($id);
$post->update([
'count' => $post->count + 1
]);
return View::make('posts', compact('post'));
}
You have two requirements:
To increase view count for every view.
public function show($id)
{
$post = Post::find($id);
Post::update([
'count' => $post->count + 1
]);
return View::make('posts', compact('post'));
}
To display the most viewed blogs according to the view count
$post = Post::orderBy('count', 'DESC')->first();
Additionaly, To display the most viewed blogs list according to the view count,
$post = Post::orderBy('count', 'DESC')->get();
I have two models Batch and Notices. The foreign key is correctly formed and data is saved in the database. Now I can't show the data on my listing blade.
Notice Migration:
Schema::create('notices', function (Blueprint $table) {
$table->id();
$table->string('noticeTitle');
$table->string('noticeDesc');
$table->string('file')->nullable();
$table->unsignedBigInteger('batch_id');
$table->foreign('batch_id')->references('id')->on('batches');
$table->timestamps();
});
Batch Migration:
Schema::create('batches', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Data dump from db is:
"id" => 1
"noticeTitle" => "Quae ea est temporib"
"noticeDesc" => "<p>sa</p>"
"file" => null
"batch_id" => 2
"created_at" => "2020-07-27 16:09:52"
"updated_at" => "2020-07-27 16:09:52"
]
Notice model
public function batches()
{
return $this->belongsTo(Batch::class);
}
Batch Model
public function notice()
{
return $this->hasMany(Notice::class);
}
Notice controller
public function index(){
$notices = Notice::all();
return view('admin.notice.list')
->with('notices', $notices);
}
public function store(Request $request)
{
$this->validate($request, [
'noticeTitle' => 'required',
'noticeDesc' => 'required',
]);
$notice = new Notice;
$notice->noticeTitle = $request->input('noticeTitle');
$notice->noticeDesc = $request->input('noticeDesc');
$notice->batch_id = $request->input('targetedGroup');
if($request->hasFile('file')) {
$noticeTitle = $request->input('noticeTitle');
$filename = $request->file->getClientOriginalName();
$request->file->storeAs('public/noticeFile/additionalFiles', $noticeTitle.'_'.$filename);
$path = $noticeTitle.'_'.$filename;
$notice->file = $path;
}
try{
$notice->save();
Session::flash('success', 'Notice Saved');
return redirect()->route('notice.index');
}
catch (\Throwable $th){
Session::flash('danger', 'Something went wrong');
return redirect()->route('notice.index');
}
}
Now I want to get batch name from batch_id
First, you might want to change the function names of your relationships. Your notice has only one batch, so it should be public function batch() and a batch has several notices, so public function notices().
You can acces your relationships like any attribute, so in your blade:
#foreach($notices as $notice)
#php $batch = $notice->batch; #endphp
{{$batch->name}}
#endforeach
Or even shorter (if you don't plan on using the related batch for anything else)
#foreach($notices as $notice)
{{$notice->batch->name}}
#endforeach
This is all explained in the Laravel documentation: https://laravel.com/docs/7.x/eloquent-relationships
I have a controller that creates a new model then passes it to the view
public function fill_site_form($id, $step_id, $form_id){
$form = new FormEntry();
$form->site_id = $id;
$form->form_id = $form_id;
$form->step_id = $step_id;
$form->entry_json = Form::find($form_id)->form_json;
$form->save();
return view('sites.fill_site_form', ['form' => $form]);
}
I need it to only create one record in the db but it creates 2 records everytime I go to that route.
I have removed the ->save and then no records are inserted into the DB.
Any suggestions?
Edit:
Image of DB entries on the $form->save:
SCREENSHOT IMAGE LINK
The DB Schema:
Schema::create('form_entries', function (Blueprint $table) {
$table->increments('id');
$table->integer('site_id');
$table->integer('form_id');
$table->integer('step_id');
$table->text('entry_json', 600000);
$table->timestamps();
});
The code that receives the ajax from the sites.fill_site_form view
public function update_site_ajax($id, Request $request){
$entry = FormEntry::find($id);
$entry->entry_json = json_encode($request->form_json);
$entry->save();
return $request->all();
}
Front end AJAX code:
$('#submit_button').click((e)=>{
$.ajax({
type:'PATCH',
url:'/site/' + document.getElementById('form_id').value,
data: {'form_json' : renderer.userData},
success:function(data){
$.notify("Form successfully Updated!",
{
position:"top center",
className: 'success'
}
);
console.log('Response: ', data)
}
});
});
I couldn't get it working with Model::create or Model->save, So I resorted to Model::firstOrCreate which looks more stable, still would like to know why only on that model it creates two entries
Hi i'm trying to make a function that allows everyone to publish whatever they want but when the visitor is not a user his post photo's default will be a photo from my directory storage that holds the meaning of anonymous or something alike:
what is the SQL command line that allows me to do so?
My post migration table is:
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('username');
$table->string('body');
$table->boolean('valid')->default(0);
$table->string('photo',150)->nullable();
$table->timestamps();
});
My function store() is the following:
public function store(Request $request)
{
$post= new Post();
$post->title=$request->input('title');
$post->photo=$request->photo; //what do i change in this field?
$post->username=$request->input('username');
$post->body=$request->input('body');
$post->save();
return redirect ('/ed');
}
Any ideas would be appreciated, thank you
You can use this:
use Illuminate\Support\Facades\Auth;
if (Auth::check()) {
// The user is logged in...
$postPhoto = $request->photo
} else{
//photo from directory storage
$postPhoto = public_path('/images/default.jpg');
}
// store photo in the database
$post->photo = $postPhoto;
#Wellwisher is right! But you can also set a default value to the photo field at posts table (and that is if you not planning to change the image name).
$table->string('photo', 150)->default('avatar.jpg');
and you will overwrite (change) it in case user uploads a new image as his/her profile image.
I try to use dropzoneJS in order to upload multiple image for my products and so far I can save images in database, also in images folder but I have problem with getting product id to relate each image to products.
Here is what I have:
Databases
Products (where my products including info will save)
Images (where my images including product id will save screenshot provided )
Models
Product:
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
Image:
class Image extends Model
{
protected $fillable = ['name'];
public function imageable()
{
return $this->morphTo();
}
public function product()
{
return $this->belongsTo(Product::class);
}
}
Image Schema
public function up()
{
Schema::create('images', function (Blueprint $table) {
$table->increments('id');
$table->integer('imageable_id')->nullable();
$table->string('imageable_type')->nullable();
$table->string('name');
$table->timestamps();
});
}
ImageController
class ImageController extends Controller
{
public function dropzone()
{
return view('dropzone-view');
}
public function dropzoneStore(Request $request)
{
// works
$file = $request->file('file');
$filename = 'product' . '-' . time() . '.' . $file->getClientOriginalExtension();
$filePath = public_path('images/');
$request->file('file')->move($filePath, $filename);
return Image::create([
'name' => $filename,
'imageable_id' => $request->input('imageable_id'),
])->id;
}
}
Product Create (Blade)
// Form
{!! Form::open([ 'route' => [ 'dropzone.store' ], 'files' => true, 'enctype' => 'multipart/form-data', 'class' => 'dropzone mt-20', 'id' => 'my-awesome-dropzone' ]) !!}
<div class="fallback">
<input name="file" type="file" multiple />
</div>
<input type="hidden" name="imageIds[]" value="">
{{Form::close()}}
// Javascript
<script type="text/javascript">
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("form#my-awesome-dropzone", {
headers: {
"X-CSRF-TOKEN": $("meta[name='csrf-token']").attr("content")
},
acceptedFiles: ".jpeg,.jpg,.png,.gif",
dictDefaultMessage: "Drag an image here to upload, or click to select one",
maxFiles: 15, // Maximum Number of Files
maxFilesize: 8, // MB
addRemoveLinks: true,
});
myDropzone.on("success", function (response) {console.log(response.xhr.response); });
</script>
Any idea?
Code for controller:
class ImageController extends Controller
{
public function dropzone($id)
{
$product = Product::find($id);
return view('dropzone-view')
->withProduct($porduct);
}
public function dropzoneStore(Request $request)
{
// works
$file = $request->file('file');
$filename = 'product' . '-' . time() . '.' . $file->getClientOriginalExtension();
$filePath = public_path('images/');
$request->file('file')->move($filePath, $filename);
return Image::create([
'name' => $filename,
'imageable_id' => $request->input('imageable_id'),
])->id;
}
}
Code on blade view:
{!! Form::open([ 'route' => [ 'dropzone.store' ], 'files' => true, 'enctype' => 'multipart/form-data', 'class' => 'dropzone mt-20', 'id' => 'my-awesome-dropzone' ]) !!}
<div class="fallback">
<input name="imageable_id" type="hidden" value="{{$product->id}}" />
<input name="file" type="file" multiple />
</div>
{{Form::close()}}
Try this hope this should get you going. This is one of many way to make this thing work.
this is a morpic relation and this is how you get morphic relation
$post = App\Post::find(1);
foreach ($post->comments as $comment) {
//
}
read about it here polymorphic-relations
What i normally do is,
After you upload a picture, return the ID of the newly created image (you already do that in ImageController)
On your product page, in the dropzone 'success' callback you can read the the image ID and add it to an hidden array input field
In your controller you have to create the new product, and then after saving it , you can attach the images to the correct product, because now you have the id's of the images + the product instance has been made.