Display tests for lessons who belong to Courses - laravel

I have Courses which has lessons, and each lesson has a test. I'm trying to display the test when a lesson is clicked.
I've created the models, controller and view and it doesn't seem to work.
Here is the model for the Lesson
public function course()
{
return $this->belongsTo(Course::class, 'course_id')->withTrashed();
}
public function test() {
return $this->hasOne('App\Test');
}
Here is the controller
public function show($id)
{
$course = Course::with( 'lessons')->with('activeLessons')->findOrFail($id);
$created_bies = \App\User::get()->pluck('name', 'id')->prepend(trans('global.app_please_select'), '');
$trainers = \App\User::get()->pluck('name', 'id');
// $test = \App\Test::where('course_id', $id)->get();
$lesson = \App\Lesson::where('course_id', $id)->get();
// $course_test = Course::with('tests')->findOrFail($id);
$user = User::find(1);
$user->name;
return view('admin.courses.showCourse', compact('course', 'test', 'lesson','course_test', 'previous_lesson', 'next_lesson','date', 'user'));
}
function view_tests($id)
{
$lessons = Lesson::findOrFail($id);
$lessons->test;
return view('admin.courses.test', compact('lessons'));
Here is the Route
Route::get('/test/{id}', 'EmployeeCoursesController#view_tests')->name('test.show');
And here is the Blade with the link to display the test
#foreach($course->activeLessons as $lesson)
<article class="lesson" >
<p></p>
<p></p>
{!! $loop->iteration!!}.
<div class="body" id="title"> {!!$loop->iteration!!}. <h4>{{ $lesson->title }}</div>
<p> {!! $lesson->short_description !!}</p>
<iframe width="420" height="315" src="{{ $lesson->video_link}}" frameborder="0" allowfullscreen></iframe>
</article>
#endforeach

The issue was on the test blade. The code works well.

Related

How to get user name from another table in laravel

Hello I want to get user names on my reply table, but there its shows me only user id, when I type $reply->user_id->name it shows me that error: "Attempt to read property "name" on int".
How can I fix it ?
there are my codes:
Ticket Model
public function replies() {
return $this->hasMany(Reply::class);
}
Reply Model
public function tickets() {
return $this->belongsTo(Tickets::class);
}
Tickets Controller
public function show($id) {
$user = Auth::user();
$tickets = Tickets::with('companies')->get();
$ticketscomp = Companies::with('tickets')->get();
$severities = Severities::with('tickets')->get();
$users = User::with('tickets')->get();
//$replies = DB::table('replies')->where('ticket_id', $id)->get();
// $articles = Reply::where('user_id', $id)->with('User')->get();
$ticketspage = Tickets::with('severities')->with('companies')->with('user')->with('replies')->findOrFail($id);
return view('tickets.ticket', compact('ticketspage'))->
with(['tickets'=> $tickets])->
with(['ticketscomp'=>$ticketscomp])->
with(['severities'=>$severities])->
with(['ticketspage'=>$ticketspage])->
with(['replies'=>$replies]);
//dd($reply_author->toArray());
}
Blade
#foreach ($replies as $reply)
<div class="NjBSH">
<div id="AuthorAndDate-1">
<span class="author">{{ $reply->user_id->name }}</span>
<span class="date"><span style="color: rgb(32, 33, 36);">{{ $reply->created_at }}</span><br></span>
</div>
<div class="kmSodw">
<span>{{ $reply->text }}</span>
</div>
</div>
#endforeach
Text, Created at showing also $reply->user_id but not this $reply->user_id->name.
Here is a complete solution using ELOQUENT:
Ticket Model
public function replies() {
return $this->hasMany(Reply::class);
}
Reply Model
public function ticket() {
return $this->belongsTo(Ticket::class);
}
public function user() {
return $this->belongsTo(User::class);
}
Tickets Controller:
public function show(Ticket $ticket) {
//Load all of the ticket relationships that we will be using
$ticket->load('replies.articles', 'replies.user', 'companies', 'severities');
//Assign the loaded ticket companies
$companies = $ticket->companies;
//Assign the loaded ticket severities
$severities = $ticket->severities;
//Assign the loaded ticket replies
$replies = $ticket->replies;
/*
You can acess the replies -> articles && user in a foreach loop, in php or blade
foreach($replies->articles as $article){
//$article->id
}
*/
return view('tickets.ticket', compact('ticket', 'companies', 'severities', 'replies'));
}
Blade
#foreach ($replies as $reply)
<div class="NjBSH">
<div id="AuthorAndDate-1">
<span class="author">{{ $reply->user->name }}</span>
<span class="date"><span style="color: rgb(32, 33, 36);">{{ $reply->created_at }}</span><br></span>
</div>
<div class="kmSodw">
<span>{{ $reply->text }}</span>
</div>
</div>
#endforeach

laravel livewire, how to pass the id or data to another component by click

I have two components Posts and Post, Posts show the posts and by clicking the image I want to show the data of clicked post in another component.
Posts class and component down below:
Component View:
<div class="post" x-data="{open:false}">
#foreach($posts as $post)
<div>
<h1>{{ $post->name }}</h1>
<h3>{{ $post->body }}</h3>
<img #click="open = !open" wire:click="showPost({{ $post->id }})" src="{{ $post->image }}" alt="">
</div>
#endforeach
<livewireL:post>
</div>
Component Class:
class Posts extends Component
{
public $posts, $post;
public function mount(){
$this->posts = Post::all();
}
public function showPost($id){
$post = Post::find($id);
$this->post = $post;
}
public function render()
{
return view('livewire.posts');
}
}
and this is the Post component and class that I want to show the clicked data in this component, I have tried $emit and many as documentation but no result.
Component view which I want to render that data:
<div x-show="open">
<h1>{{ $post->name }}</h1>
<h3>{{ $post->body }}</h3>
<img src="{{ $post->image }}">
</div>
Class which I want to pass data:
class Post extends Component
{
public $post;
public function mount($id)
{
$this->post = \App\Post::find($id);
}
public function render()
{
return view('livewire.post');
}
}
You have to use events to pass data from one component to another component like below.
Component A Blade:
<img #click="open = !open" wire:click="showPost({{ $post->id }})" src="{{ $post->image }}" alt="">
Component A Class:
public function showPost($id){
$post = Post::find($id);
$this->post = $post;
$this->emit('newPost', $post->id);
}
you can now catch that event from other livewire component like this:
Component B Class:
class Post extends Component
{
public $post;
protected $listeners = ['newPost'];
public function mount($id)
{
$this->post = \App\Post::find($id);
}
public function render()
{
return view('livewire.post');
}
public function newPost($postId)
{
// here u have the id in your other component.
}
}
you can achieve this other way also. You can pass the id from your component blade as well check this out.

Undefined variable when trying to use two loops

I have two functions
whatsnew()
and
perfume()
both has its own #foreach in different sub folders which i show them in one page.
problem is if one #foreach works the other show an error undefined variable
ps- this is my first time posting a question in SO .. sorry if its sloppy..
ProductController.php
//to show last 5 latest items
public function whatsnew(){
$cat_new = products::orderBy('id', 'desc')->take(5)->get();
return view('/home', compact('cat_new'));
}
//to show category
public function perfume(){
$perfume = products::where('category','LIKE','perfume')->get();
return view('/home', compact('perfume'));
}
Web.blade.php
Route::get('/', [
'uses' => 'ProductController#whatsnew',
'as' => 'db.whatsnew']);
Route::get('/', [
'uses' => 'ProductController#perfume',
'as' => 'db.perfume']);
perfume.blade.php
#foreach($perfume as $perfume_cat)
whatnew.blade.php
#foreach($cat_new as $row)
It looks like you are passing only 1 collection back to the view each time, which is probably why one or the other works.
If you change this:
public function whatsnew(){
$cat_new = products::orderBy('id', 'desc')->take(5)->get();
return view('/home', compact('cat_new'));
}
public function perfume(){
$perfume = products::where('category','LIKE','perfume')->get();
return view('/home', compact('perfume'));
}
to this:
public function whatsNew(){
$cat_new = products::orderBy('id', 'desc')->take(5)->get();
return $cat_new; // return the collection
}
public function perfume(){
$perfume = products::where('category','LIKE','perfume')->get();
return $perfume; // return the collection
}
// Create a new index function and pass both collections to your view
public function index() {
return view('index', [
'cat_new' => $this->whatsNew(),
'perfume' => $this->perfume(),
]);
}
Your web routes file can be:
Route::get('/', 'ProductController#index')->name('product.index');
Your index.blade.php
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<ol>
#foreach( $cat_new as $new )
<li>{{ $new->foo }}</li>
#endforeach
</ol>
</div>
</div>
<div class="card">
<div class="card-body">
<ol>
#foreach( $perfume as $p )
<li>{{ $p->bar }}</li>
#endforeach
</ol>
</div>
</div>
</div>
</div>
</div>
where foo and bar are whatever columns you are after.
//merge become one
public function perfume(){
$perfume = products::where('category','LIKE','perfume')->get();
$cat_new = products::orderBy('id', 'desc')->take(5)->get();
return view('/home', compact('perfume', 'cat_new'));
}

How to display multiple post in single blade by using two row(example starting post, expired_date post)

I have a category page and in this I want to display two types of box in single page, one is starting_post and old_post or expired. How can divide a single page in two part?
class FrontendController extends Controller
{
public function welcome()
{
// #TODO Refactor This Line
return view('welcome')
->with('title', Setting::first()->site_name)
->with('levels', Category::take(7)->get())
->with('levels', Category::take(7)->get())
->with('first_post', Post::orderBy('created_at','asc')->first())
->with('second_post', Post::orderBy('created_at', 'asc')->skip(1)->take(1)->get()->first())
->with('third_post', Post::orderBy('created_at','asc')->skip(2)->take(2)->get()->first())
->with('forth_post', Post::orderBy('created_at','asc')->skip(3)->take(3)->get()->first())
->with('HOME', Category::find(1))
->with('ABOUT US', Category::find(2))
->with('RESEARCH', Category::find(3))
->with('NEWS AND PUBLICATION', Category::find(4))
->with('EVENTS', Category::find(5))
->with('PEOPLE', Category::find(6))
->with('CONTACT US',Category::find(7));
}
public function singlePost($slug)
{
$post=Post::whereSlug($slug)->first();
return view('single')->with('post', $post)
->with('content', $post)
->with('levels', Category::take(7)->get());
}
public function category($slug)
{
$category=Category::whereSlug($slug)->firstOrFail();
return view($category->getTemplateFile())->with('category', $category)
->with('title',$category->name)
->with('levels', Category::take(7)->get());
}
public function events($slug)
{
$post = Post::where('slug', $slug)->first();
$coming_events = Post::where('id', '>', $post->id)->desc('id');
$past_events = Post::where('id', '<', $post->id)->asc('id');
return view('events_blade')
->with('post', $post)
->with('categories', Category::take(7)->get())
->with('next', Post::find($coming_events))
->with('prev', Post::find($past_events));
}
}
// View | blade
<div class="entry-meta">
<span>{{ \Carbon\Carbon::parse($post->date_time)->format('F j, Y') }}</span>
<div>
<h class="entry-title">
{{ $post->title }}</h3>
<div class="entry-content">
<a target="_blank" href="{{ asset("$post->
file") }}">
<p style="font-size: 18px;color: #468b10;"> {{ $post->content }}</p>
</a>
</div>
Change your events function like this. Issue with your query builder and you are incorrect setting values for view.
public function events($slug)
{
$post = Post::where('slug', $slug)->first();
$coming_events = Post::where('id', '>', $post->id)->orderBy('id', 'desc')->get();
$past_events = Post::where('id', '<', $post->id)->orderBy('id', 'asc')->get();
return view('events_blade')
->with('post', $post)
->with('categories', Category::take(7)->get())
->with('coming_events', $coming_events)
->with('past_events', $past_events);
}
And inside the events_blade.blade.php loop on these two variables separetly.
// show upcoming events.
#foreach($coming_events as $ce)
<div class="entry-meta">
...
<h3> {{ $ce->title }}</h3>
...
</div>
#endforeach
// show past events.
#foreach($past_events as $pe)
<div class="entry-meta">
...
<h3> {{ $pe->title }}</h3>
...
</div>
#endforeach
Check the laravel documentation to setting values for blade for more details.
try this
public function events($slug)
{
$post = Post::where('slug', $slug)->first();
$data['coming_events'] = Post::where('id', '>', $post->id)->orderBy('id', 'desc')->get();
$data['past_events'] = Post::where('id', '<', $post->id)->orderBy('id', 'asc')->get();
return view('events_blade', $data)
}
<div class="row">
<div class="col-sm-4">
<i>current events</i>
#foreach($coming_events as $new)
{{ $new->title}}
#endforeach
</div>
<div class="col-sm-4">
<i>Past events</i>
#foreach($past_events as $old)
{{ $old->title}}
#endforeach
</div>
</div>
then you have to do it this way:
public function events($slug)
{
$post= Post::where('slug', $slug)->first();
$data['post'] = Post::where('slug', $slug)->first();
$data['coming_events'] = Post::where('id', '>', $post->id)->orderBy('id', 'desc')->get();
$data['past_events'] = Post::where('id', '<', $post->id)->orderBy('id', 'asc')->get();
data['categories']=Category::take(7)->get();
return view('events_blade', $data)
}

How to Call/Display Foreach Loop after Login

I had problem on calling page inside Foreach Loop.Although It is Okay before I click Login, but when I'd try to login,only the html tag where loaded and foreach loop cannot... On my HomeController extends Controller
public function index()
{
return view('pages.welcome');
}
on where I call welcome page. and inside of it which is foreach loop.
<div class="row">
<div class="col-md-8">
#foreach ($posts as $post)
<div class="post">
<h3>{{ $post->title }}</h3>
<p>{{ substr($post->body, 0,300) }}
{{ strlen($post->body) > 300 ? "..." : " " }}</p>
Read More...
</div>
<hr>
#endforeach
</div>
</div>
And I think the problem is my route:
Route::get('/home', 'HomeController#index');
You haven't passed the $posts variable to the view.
Change
public function index()
{
return view('pages.welcome');
}
To something like this:
public function index()
{
$posts = \App\Post::all(); //Assuming your model is called "Post" in the App namespace
return view('pages.welcome', compact('posts'));
}
NOTE: compact('posts') is just a shortcut for ['posts'=>$posts]

Resources