Laravel how to show video by it's id - laravel

So first of all I just started to work with laravel and overall with php. Right now I'm facing a problem where I don't know how to display specific video from my database. My User model:
class User extends Model implements Authenticatable{
use \Illuminate\Auth\Authenticatable;
public function videos() {
return $this->hasMany('App\Video');
}
}
My Video model:
class Video extends Model{
public function user() {
return $this->belongsTo('App\User');
}
}
Everything goes well when I loop through my videos to display them all in dashboard:
<div class="row" id="features">
#foreach($videos as $video)
<div class="col-sm-4 feature">
<div class="panel">
<div class="panel-heading">
<h3 class="panel-title video_name">{{ $video->video_name }}</h3>
</div>
<iframe width="320" height="250"
src="https://www.youtube.com/embed/{{ $video->video_url }}" allowfullscreen="allowfullscreen" mozallowfullscreen="mozallowfullscreen" msallowfullscreen="msallowfullscreen" oallowfullscreen="oallowfullscreen" webkitallowfullscreen="webkitallowfullscreen">
</iframe>
<div class="info">
<p>Posted by {{ $video->user->first_name }} on {{ $video->created_at }}</p>
<hr class="postInfo">
</div>
<p>{{ $video->description }} </p>
Continue to video
</div>
</div>
#endforeach
</div>
But At this point:
Continue to video
I open new route which is (http://localhost:8000/video/11/view) and in this case I want to display video where ID 11 is equal to my video_url
videos table code:
public function up(){
Schema::create('videos', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->text('video_name');
$table->text('video_url');
$table->text('description');
$table->integer('user_id');
});
}
Route:
Route::get('/video/{video_id}/view', [
'uses' => 'SignInController#ViewVideo',
'as' => 'view.video']);

Change the route to following..
Route::get('/video/{video}/view', [
'uses' => 'SignInController#ViewVideo',
'as' => 'view.video']);
In Controller..
public function ViewVideo(Video $video){
//any authorization logic...
return view('whatever',compact('video'));
}

As of Laravel 5.2 there is a thing called Implicit Route Model Binding You can read the docs about it here.
So in your example. You can change your route like this:
Route::get('/video/{video}/view', [
'uses' => 'SignInController#ViewVideo',
'as' => 'view.video'
]);
And in your Video controller's view method:
public functin view(App\Video $video) {
// Your logic
}

Related

Laravel 8 form select option dropdown problem

Am having problem here
I have two tables
Department table
with fields
id dept_code dept_name
I also have Persons table
with fields
id Persons_names Dept_name Position_held
I have a data entry form to enter data to the Persons_table
the problem am having is I want to create select option to get Dept_name From Department_table but am always getting undefined value error.
this is my form
{!! Form::open(['url' => 'persons_form/store']) !!}
{{ csrf_field() }}
<div class="form-row">
<div class="form-group col-md-6">
{{Form::label('FullNames', 'Fullnames')}}
{{Form::text('names', '',['class'=>'form-control','placeholder'=>'Persons Fullnames'])}}
</div>
<div class="form-group col-md-6">
{{Form::label('Department', 'Department')}}
#foreach ($depts as $dept)
{{
Form::select('department', $dept->department_name, null, ['class'=>'form-control','placeholder' => 'Select Department'])
}}
#endforeach
</div>
<div class="form-group col-md-12">
{{Form::label('Position', 'Position')}}
{{Form::text('level', '',['class'=>'form-control','placeholder'=>'Departmental Position'])}}
</div>
</div>
<div>
{{Form::submit('Save Data',['class'=>'btn btn-outline-primary text-center',])}}
</div>
{!! Form::close() !!}
this is my personsController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\People;
class PeopleController extends Controller
{
public function index()
{
$depts = DB::table('departments')->select('department_name')->get();
return view('strategic_plan.people_form', ['depts' => $depts]);
}
public function create()
{
$depts = DB::table('departments')->pluck('department_name');
}
public function store(Request $request)
{
$this->validate($request,[
'names'=>'required',
'department'=>'required',
'level' =>'required'
]);
$persons =new People;
$persons->names=$request->input('names');
$persons->department=$request->input('persons');
$persons->level=$request->input('level');
$dept->save();
return redirect('/people')->with('message','Person Added Succesifully');
}
public function show()
{
$persons = People::all()->sortByDesc("id");
return view('strategic_plan.people',compact('persons'));
}
public function edit($id)
{
}
public function update(Request $request, $id)
{
//
}
public function destroy($id)
{
//
}
}
When I try to open the Form am getting
$depts is undefined
Try using compact, And get #dd in your blade of $depts and share the code.
Use
return view('strategic_plan.people_form', ['depts' => $depts]);
instead of
return view('strategic_plan.people_form', compact('depts');
write it down

Livewire throwing error when using paginated data

So I am being given this error when trying to paginate my data and send it in to a view through a livewire component.
I am trying to get all posts and display at max 5 posts per page using pagination in laravel.
Livewire version: 2.3.1
Laravel version: 8.13.0
Error:
Livewire\Exceptions\PublicPropertyTypeNotAllowedException
Livewire component's [user-posts] public property [posts] must be of type: [numeric, string, array, null,
or boolean]. Only protected or private properties can be set as other types because JavaScript doesn't
need to access them.
My Component:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Post;
use Livewire\WithPagination;
class UserPosts extends Component
{
use WithPagination;
public $posts;
public $type;
protected $listeners = ['refreshPosts'];
public function delete($postId)
{
$post = Post::find($postId);
$post->delete();
$this->posts = $this->posts->except($postId);
}
public function render()
{
if($this->type == 'all')
$this->posts = Post::latest()->paginate(5);
else if($this->type == 'user')
$this->posts = Post::where('user_id',Auth::id())->latest()->paginate(5);
return view('livewire.user-posts', ['posts' => $this->posts]);
}
}
My Blade:
<div wire:poll.5s>
#foreach($posts as $post)
<div style="margin-top: 10px">
<div class="post">
<div class="flex justify-between my-2">
<div class="flex">
<h1>{{ $post->title }}</h1>
<p class="mx-3 py-1 text-xs text-gray-500 font-semibold"
style="margin: 17px 0 16px 40px">{{ $post->created_at->diffForHumans() }}</p>
</div>
#if(Auth::id() == $post->user_id)
<i class="fas fa-times text-red-200 hover:text-red-600 cursor-pointer"
wire:click="delete({{$post->id}})"></i>
#endif
</div>
<img src="{{ asset('image/banner.jpg') }}" style="height:200px;"/>
<p class="text-gray-800">{{ $post->text }}</p>
#livewire('user-comments', [
'post_id' => $post->id,
'type' => 'all'
],
key($post->id)
)
</div>
</div>
#endforeach
{{ $posts->links() }}
</div>
$posts should not be declared as a property in the Livewire component class, you passed the posts with the laravel view() helpers as data.
Remove the line
public $posts;
And replace $this->posts by $posts in the render function:
public function render()
{
if($this->type == 'all')
$posts = Post::latest()->paginate(5);
else if($this->type == 'user')
$posts = Post::where('user_id',Auth::id())->latest()->paginate(5);
return view('livewire.user-posts', ['posts' => $posts]);
}
}

Property [images] does not exist on this collection instance

PLease I need help figuring out this problem, I have two model Event and EventImages with One-To-Many relationsip, each event can have multiple images, so I want to be able to loop through Events using the images method from the Event Model and display each event with one image from multiple images of that event on the index page, and make each image a link to the show page where there is Carousel that will display all the images belonging to that event. I keep getting this error
Property [images] does not exist on this collection instance.
This is the Event Model
class Event extends Model
{
protected $fillable = ['title', 'date', 'time', 'venue', 'body'];
public function images()
{
return $this->hasMany('App\EventImage');
}
}
Event migration
public function up()
{
Schema::create('events', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('date');
$table->string('time');
$table->string('venue');
$table->mediumText('body');
$table->timestamps();
});
}
This is EventImage Model
class EventImage extends Model
{
protected $fillable = ['images', 'caption','event_id'];
public function event()
{
return $this->belongsTo('App\Event');
}
}
EventImage migration
public function up()
{
Schema::create('event_images', function (Blueprint $table) {
$table->id();
$table->string('images');
$table->string('caption');
$table->integer('event_id')->unsigned();
$table->foreign('event_id')->references('id')->on('events')
->onDelete('cascade');
$table->timestamps();
});
}
This is the EventController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Event;
use App\EventImage;
class EventController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$events = Event::all();
$imageEvents = $events->images->take(1);
return view('events.index', compact('events', $events, 'imageEvents',
$imageEvents));
}
This is the view
<div class="container">
<div class="tab_">
<ul>
<li>Recent Events</li>
<li>All Events</li>
</ul>
<section id="section1">
<div class="col s12 m7 s7">
#foreach ($events as $k => $event)
#if ($k % 2 == 0)
<div class="card horizontal">
<div class="card-image">
{{-- <img src="{{asset('images/amber-heard-7031-
2560x1600_1598312173.jpg')}}" class="fadeIn"> --}}
#foreach ($imageEvents as $imageEvent)
<a href=""><img class="img-fluid d-block card-img" style
="width:100%" src="{{asset('storage/images')}}/{{$imageEvent->images}}"
alt="">
</a>
#endforeach
</div>
<div class="card-stacked">
<div class="card-content">
<span class="card-title">{{$event->title}}</span>
<p>{{$event->body}}
</p>
</div>
<div class="card-action">
This is a link
</div>
</div>
</div>
</div>
<div class="col s12 m7">
#else
<div class="card horizontal" id="fadedfx">
<div class="card-stacked">
<div class="card-content">
<span class="card-title">{{$event->title}}</span>
<p>{{$event->body}}
</p>
</div>
<div class="card-action">
This is a link
</div>
</div>
<div class="card-image">
<a href=""><img class="img-fluid d-block card-img" style
="width:100%" src="{{asset('storage/images')}}/{{$imageEvent->images}}"
alt=""></a>
</div>
</div>
#endif
#endforeach
</div>
This is the Route
**Route::resource('events', 'EventController', [
'names'=> [
'index' => 'eventdex',
'create' => 'createvent',
'store' => 'storevent',
'show' => 'showevent',
'edit' => 'editevent',
'update' => 'updateevent',
'destroy' => 'destroyevent'
]
]);**
But when I make this changes to the EventController and save it
public function index(Request $request)
{
$events = Event::all();
$event = Event::find(49);
$imageEvents = $event->images->take(1);
return view('events.index', compact('events', $events, 'imageEvents',
$imageEvents));
}
it works fine except is not dynamic, I had to put in the event id the find method, and only one image show for all the events.

How to send variable from blade to controller without changing the url

In blade I have a list of books. I want to choose a specific book to show its information. And to do so I want to send with href the id of the book to my controller passing through route.
For example i have
<div class="body text-center">
<h6><b>{{($book->getName())}}</b></h6>
</div>
In href I want to add $bookId = $book->id and the route name so I can call the route with the specific name which calls a method in a controller which can use the variable $bookId
Route::get('/infromation','Books\BookController#index')->name('info');
Here's two propositions:
The first one is to use spatie/laravel-sluggable to have the book name in the URL
The second one is to access the book without changing the URL with a POST request
Using spatie/laravel-sluggable
The slug will be generated automatically from name when the book is created.
your-migration.php
Schema::create('books', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('slug')->unique()->index();
$table->string('name');
// ...
$table->timestamps();
});
web.php
// Change the URIs as you want. `{book}` is mandatory to retrieve the book though.
Route::get('/books','Books\BookController#index')->name('book.index');
Route::get('/books/{book}','Books\BookController#show')->name('book.show');
Book.php
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
class Book extends Model
{
use HasSlug;
protected $guarded = [];
public function getSlugOptions()
{
// Adapt with what you want
return SlugOptions::create()
->generateSlugsFrom('name')
->saveSlugsTo('slug')
->doNotGenerateSlugsOnUpdate();
}
public function getRouteKeyName()
{
return 'slug';
}
}
BookController.php
class BookController extends Controller
{
public function index()
{
return view('book.index');
}
public function show(Book $book)
{
// $book is retrieving using Model Binding: https://laravel.com/docs/5.8/routing#route-model-binding
return view('book.show', compact('book'));
}
}
index.blade.php
<div class="body text-center">
<a href="{{ route('book.show', $book) }}">
<h6><b>{{ $book->getName() }}</b></h6>
</a>
</div>
Using POST request (URI does not change) and without SLUG
I wouldn't recommend using this for the user experience.
The user cannot bookmark the book or share the link with someone else
When refreshing the page, it will prompt to the user if he want to re-submit the form request
web.php
Route::get('/books','Books\BookController#index')->name('book.index');
Route::post('/books','Books\BookController#show')->name('book.show');
BookController.php
class BookController extends Controller
{
public function index()
{
return view('book.index');
}
public function show()
{
$book = Book::findOrFail(request('book_id'));
return view('book.show', compact('book'));
}
}
index.blade.php
<div class="body text-center">
<form action="{{ route('book.show') }}" method="POST">
#csrf
<input type="hidden" value="{{ $book->id }}" name="book_id">
<h6>
<button type="submit">
<b>{{ $book->getName() }}</b>
</button>
</h6>
</form>
</div>
You can remove the default button style to make it looks like a link
https://stackoverflow.com/a/45890842/8068675
You can try like this
<form action="/BookName/information/<?php echo $book->id; ?>" method="post">
<div class="body text-center">
<input type="hidden" name="book_id" value="{{ $book->id }}">
<a href="/information/<?php echo $book->id; ?>">
<button type="submit" name="book_information" class="btn btn-primary">
<h6>
<b>{{($book->getName())}}</b>
</h6>
</button>
</div>
</form>
// make route like this
Route::post('/BookName/information/{id}','Books\BookController#index');
// Access the that id in controller
public function index(Request $request)
{
echo $request->book_id;
}

Reorder menu items without affecting database id

I have a menu in my Laravel application which lists tags. I want to be able to add more tags and change their order, but I don't want to affect the underlying database ids for each tag. Because that would break any data I have already associated with them. So I thought I add an extra column to my database called 'display_order' like so:
Database:
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->integer('display_order');
$table->string('name');
$table->timestamps();
});
Now I want to create a view to let the user change the value of the display_order field. Initially I show a page which prints each tag and its display_order and allows the user to update the value in a text field:
Controller:
public function showTagsOrder()
{
$tags = Tag::all()->sortBy('display_order');
return view('menu.tags', compact('tags'));
}
Route:
Route::get('/menu/tags', ['as' => 'menu_tags', 'uses' => 'MenuOrderController#showTagsOrder']);
View:
{!! Form::open(['action' => 'MenuOrderController#updateTagsOrder']) !!}
#foreach($tags->chunk(18) as $chunk)
<div class="col">
#foreach($chunk as $tag)
<p><label>{!! $tag->name !!}</label><input type="text" name="tag_array[{!! $tag->id !!}]" value="{!! $tag->display_order !!}" class="numeric" />
#endforeach
</div>
#endforeach
<p>{!! Form::submit('Submit') !!}
{!! Form::close() !!}
When the form is submitted I then have the following function in my controller:
public function updateTagsOrder(TagsMenuRequest $request)
{
$i = 1;
foreach($request->tag_array as $tag_value)
{
$tag = new Tag;
$tag = Tag::find($i);
$tag->display_order = $tag_value;
$tag->save();
$i++;
}
flash()->overlay('The order of tags in the menu has been udpated!', 'Congratulations');
return redirect('/');
}
But this doesn't work. How would I rewrite this so I assigned the correct value for display_order to each tag. I'd be very grateful for your help.
foreach($request->tag_array as $tag_id => $tag_value)
{
$tag = Tag::find($tag_id);
$tag->display_order = $tag_value;
$tag->save();
}

Resources