how can I order a list dynamically in laravel? - laravel

I try for a todo-list to be able to order the list via a filter so that can i have the list for today the list for tomorrow or the list of the week so i made my task controller able to take request et via the design pattern reposiory i take the request to do the eloquent request :
controller tasks :
class TaskController extends Controller
{
private $taskRepository;
public function __construct(TaskRepository $taskRepository)
{
$this->taskRepository = $taskRepository;
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(Request $request)
{
if(!empty($request)){
// dd($request);
$tasks = $this->taskRepository->all($request);
}else{
$tasks = $this->taskRepository->all();
}
return view('tasks.index', compact('tasks'));
}
}
taskrepository :
class TaskRepository implements RepositoryInterface
{
// model property on class instances
protected $task;
// Constructor to bind model to repo
public function __construct(Task $task)
{
$this->task = $task;
}
public function all(Request $request)
{
$sortBy = 'expired_at';
$order = Carbon::now();
$finish = null;
if($request)
{
if($request->has('today'))
{
$order = Carbon::today();
return Task::where($sortBy, $order)->get();
}
if($request->has('tomorow')){
$order = Carbon::tomorrow();
return Task::where($sortBy, $order)->get();
}
if($request->has('week'))
{
$order = Carbon::now()->startOfWeek();
$finish = Carbon::now()->endOfWeek();
return Task::whereBetween($sortBy, [$order, $finish])->get();
}
}else{
return Task::orderBy('order')->get();
}
}
to finish in my index i have form using the "get" method :
div>
<form action="{{ route('tasks.index') }}" class="flex justify-between items-center p-2">
<div>
<select name="orderByDate" id="">
#foreach(['today','tomorow', 'week'] as $orderDate)
<option value="{{ $orderDate }}">{{ ucfirst($orderDate) }}</option>
#endforeach
</select>
</div>
<div>
<button type="submit">Filter</button>
</div>
</form>
</div>
<ul class="my-5">
#foreach ($tasks as $task)
#if($task->order == 0)
<li class="flex text-red-600 justify-between p-2">
// task->name
// task-> date
// task-> edit
// task->delete
</li>
#else
<li class="flex justify-between items-center p-2">
// task->name
// task-> date
// task-> edit
// task->delete
</li>
#endif
#empty
<p>Pas de tâches aujourd'hui crée en une</p>
#endforelse
</ul>
#endsection
aparrently my foreach doesn't work with an array so if anyone have some lead to how should i approch this issue will be a live saver ?

Try this code for the repository function
public function all(Request $request)
{
$sortBy = 'expired_at';
$order = Carbon::now();
$finish = null;
if($request)
{
if($request->has('today'))
{
$order = Carbon::today();
return Task::query()->where($sortBy, $order)->orderBy($sortBy)->get();
}
if($request->has('tomorow')){
$order = Carbon::tomorrow();
return Task::query()->where($sortBy, $order)->orderBy($sortBy)->get();
}
if($request->has('week'))
{
$order = Carbon::now()->startOfWeek();
$finish = Carbon::now()->endOfWeek();
return Task::query()->whereBetween($sortBy, [$order, $finish])->orderBy($sortBy)->get();
}
}else{
return Task::query()->orderBy($sortBy)->get();
}
}

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: ErrorException Undefined variable: items

So i want to be able to view my cart on one of my pages. I can simply 'add to cart' and the value of the number of items in my cart will show on the top right corner of my page. When i go to click on the cart i receive this error:
ErrorException
Undefined variable: items.
I have the following code:
Cart.php:
class Cart {
public $items = null;
public $totalQty = 0;
public $totalPrice = 0;
public function __Construct($oldCart)
{
if ($oldCart) {
$this->$items = $oldCart->$items;
$this->$totalQty = $oldCart->$totalQty;
$this->$totalPrice = $oldCart->$totalPrice;
}
}
public function add($item, $id){
$storedItem = ['qty' => 0, 'price' => $item->price, 'item' => $item];
if($this->items) {
if (array_key_exists($id, $this->items)){
$storedItem = $this->items[$id];
}
}
$storedItem['qty'] ++;
$storedItem['price'] = $item->price * $storedItem['qty'];
$this->items[$id] = $storedItem;
$this->totalQty++;
$this->totalPrice += $item->price;
}
PostsController.php:
public function getCart() {
if (!Session::has('cart')) {
return view('posts.shopping-cart', ['post' => null]);
}
$oldCart = Session::get('cart');
$cart = new Cart($oldCart);
return view('posts.shopping-cart', ['post' => $cart->items, 'totalPrice'=> $cart->totalPrice]);
}
Payment.blade:
#if(Session::has('cart'))
<div class="row">
<div class="col-sm-6 col-md-6 col-md-offset-3 col-sm-0ffset-3">
<ul class="list-group">
#foreach($posts as $post)
<li class="list-group-item">
<span class="badge">{{ $post['qty']}}</span>
<strong>{{ $post['item']['title']}}</strong>
<span class="label label-success">{{$post['price']}}</span>
<div class="btn-group">
Web.api
Route::get('/shopping-cart', [ 'uses' => 'PostsController#getCart', 'as' => 'product.shoppingCart' ]);
But when i click on the my cart link that is in navbar.php:
<a class="nav-link " href="{{ route('product.shoppingCart')}}">Cart
Cart {{ Session::has('cart') ? Session::get('cart')->totalQty : ''}}
I then get the error undefined items variable
The error is on the constructor of the Cart class. You have put the dollar sign on the property names.
Just remove the dollar signs.
public function __Construct($oldCart)
{
if ($oldCart) {
$this->items = $oldCart->items;
$this->totalQty = $oldCart->totalQty;
$this->totalPrice = $oldCart->totalPrice;
}
}

How to restrict edit only on data display in the index in laravel

I have a problem with my edit.blade.php. In the show view, I have restricted it only on the users' logged in as you can see in my controller
public function index()
{
$animal = Auth::user()->animals;
return view('farms.index', compact('animal'));
}
And my index view
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Farm Dashboard</div>
<div class="card-body">
#if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
#endif
You are logged in! {{ Auth::user()->name }}
<br>
Add animal
#foreach( $animal as $animal)
<div class="row">
<div class="col-2">{{ $animal->id }}</div>
<div class="col-4">{{ $animal->type->category }}</div>
<div class="col-4">{{ $animal->created_at }}</div>
</div>
#endforeach
</div>
</div>
</div>
</div>
</div>
#endsection
But I still have a problem if I change in my url the id number of an object of another user I can still edit and update.
What can I change in my controller to prevent that
public function show($id)
{
$animal = Animal::query()->findOrFail($id);
return view('farms.show', compact('animal'));
}
/**
* Show the form for editing the specified resource.
*
* #param $id
* #return void
*/
public function edit($id)
{
$type = Type::all();
$user = Auth::user();
$animal = Animal::query()->findOrFail($id);
return view('farms.edit', compact('animal', 'type', 'user'));
}
/**
* Update the specified resource in storage.
*
* #param $id
* #return void
*/
public function update($id)
{
$animal = Animal::query()->findOrFail($id);
$animal->update($this->validateRequest());
return redirect('farms/' . $animal->id)->with('message', 'Animal Details Updated');
}
You can follow this basic/easy method
For Show
public function show($id)
{
try {
$user = auth()->user();
$animal = Animal::where('user_id', $user->id)->findOrFail($id);
return view('farms.show', compact('animal'));
} catch(\Exception $ex) {
//return exception or any other page
abort(404, 'Not allowed');
//or return back()->withErrors(['Not allowed']);
}
}
For edit
public function edit($id)
{
try {
$type = Type::all();
$user = auth()->user();
$animal = Animal::where('user_id', $user->id)->findOrFail($id);
return view('farms.edit', compact('animal', 'type', 'user'));
} catch(\Exception $ex) {
//return exception or any other page
}
}
For update
public function update($id)
{
try {
$user = auth()->user();
$animal = Animal::where('user_id', $user->id)->findOrFail($id);
$animal->update($this->validateRequest());
return redirect('farms/' . $animal->id)->with('message', 'Animal Details Updated'); //use route for redirect instead of url
} catch(\Exception $ex) {
//return exception or any other page
}
}
Use try catch for exception
Make sure you defined that animal has user_id
or
You can also manage this functionality with relationship
Larave Eloquent relationship
For standard practice, you can use laravel gate policy
Laravel policy via model

Laravel - Adding Filter to Maatwebsite Excel Export [duplicate]

This question already exists:
Laravel - Filtered Export to Excel using Maatwebsites is not working
Closed 3 years ago.
I want to export only filtered data in view blade. I am using Laravel 5.8 and Maatwebsite 3.1 and PHP 7.
Controller
public function userresponseReport(Request $request)
{
$data['title'] = 'User Response';
$userresponses = DB::table('user_response as g')
->select(
//DB::raw('DATE(g.created_at) as created_date'),
DB::raw('g.created_at as created_date'),
'g.msisdn',
'g.game_code',
'g.answer',
'g.answer_code',
'g.Amount_charged',
'g.payment_ref',
'g.status',
'g.user_channel'
)
->orderByRaw('g.created_at DESC');
$start_date = $request->start_date;
$end_date = $request->end_date;
$render=[];
if(isset($request->start_date) && isset($request->end_date))
{
$userresponses=$userresponses->whereBetween('created_at',[$start_date.' 00:00:00',$end_date.' 23:59:59']);
$render['start_date']=$request->start_date;
$render['end_date']=$request->end_date;
}elseif(isset($request->start_date))
{
$userresponses=$userresponses->where('created_at',$request->start_date);
$render['start_date']=$request->start_date;
}
if(isset($request->msisdn))
{
$userresponses=$userresponses->where('msisdn','like','%'.$request->msisdn.'%');
$render['msisdn']=$request->msisdn;
}
if(isset($request->game_code))
{
$userresponses=$userresponses->where('game_code','like','%'.$request->game_code.'%');
$render['game_code']=$request->game_code;
}
if(isset($request->user_channel))
{
$userresponses=$userresponses->where('user_channel','like','%'.$request->user_channel.'%');
$render['user_channel']=$request->user_channel;
}
$userresponses= $userresponses->orderBy('created_at','DESC');
$userresponses= $userresponses->paginate(15);
$userresponses= $userresponses->appends($render);
$data['userresponses'] = $userresponses;
return view('report.userresponseReport',$data);
}
public function exportuserresponse(Request $request)
{
return Excel::download(new UserresponseExport($request), 'userresponse.xlsx');
}
I went through the documentation and applied this:
Export folder: UserresponseExport
class UserresponseExport implements FromCollection, WithHeadings, ShouldAutoSize, WithEvents
{
use Exportable;
protected $request;
public function __construct($request)
{
$this->request = $request;
}
public function collection()
{
$userresponses = UserResponse::where('msisdn', 'like','%'.$this->request->msisdn)
->orWhere('game_code', 'like','%'.$this->request->game_code)
->orWhere('user_channel', 'like','%'.$this->request->user_channel)
->get();
$output = [];
foreach ($userresponses as $userresponse)
{
$output[] = [
$userresponse->created_at,
$userresponse->msisdn,
$userresponse->game_code,
$userresponse->answer,
$userresponse->user_channel,
];
}
return collect($output);
}
public function headings(): array
{
return [
'Date Created',
'MSISDN',
'game_code',
'Answer',
'Channel'
];
}
View
<div class="row" style="margin-bottom: 10px">
{{ Form::model(request(),['method'=>'get']) }}
<div class="col-sm-2">
{{ Form::text('msisdn',null,['class'=>'form-control','placeholder'=>'MSISDN']) }}
</div>
<div class="col-sm-2">
{{ Form::text('game_code',null,['class'=>'form-control','placeholder'=>'Game Code']) }}
</div>
<div class="col-sm-2">
{{ Form::text('user_channel',null,['class'=>'form-control','placeholder'=>'Channel']) }}
</div>
<div class="col-sm-2">
{{ Form::date('start_date',null,['class'=>'form-control','placeholder'=>'Date']) }}
</div>
<div class="col-sm-2">
{{ Form::date('end_date',null,['class'=>'form-control','placeholder'=>'Date']) }}
</div>
<div class="col-xs-2">
{{ Form::submit('Search',['class'=>'btn btn-warning']) }}
<i class="fa fa-file-excel-o"></i> Excel
</div>
{{ Form::close() }}
</div>
IThe export submit button is sending everything to Excel. How do I make it to send only the filtered data. Thanks
Update your UserresponseExport, follow this formate,
class UsersExport implements FromCollection, WithHeadings
{
use Exportable;
protected $request;
public function __construct($request)
{
$this->request = $request;
}
public function collection()
{
$users = User::where('name', 'like','%'.$this->request->name)->get();
$output = [];
foreach ($users as $user)
{
$output[] = [
$user->name,
];
}
return collect($output);
}
public function headings(): array
{
return [
'Name',
];
}
}
Make sure your query is corrct, check your query properly.

Display tests for lessons who belong to Courses

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.

Resources