Best way to fill a roster schedule - php

Fellow programmers,
I got a roster application build in PHP with the framework : Laravel. And i have the following issue:
My application has : Users, Taskdate's, and TaskdateTime. Each user can get a TaskdateTime assigned to them. That TaskdateTime is a child of Taskdate. I want to populate a schedule where each user can see all their times. The schedule looks like this :
What i do in my application is : Fetch all users, Fetch all Taskdate's and according to the Taskdate's, fetch the TaskdateTime's for the right Taskdate. I do this in the following way :
$taskdates = Taskdate::with('users')->where_date($date)->get();
$employees = Usergroup::with(array('users', 'users.workdates'))->where('usergroup_title', '=', 'Employees')->first();
You can see that i fetch usergroups, with the relationship : Users and with the User->workdates relationship. Where the workdates returns the TaskdateTime objects as mentioned above.
Now in my view, i do this to populate it with data. And this seems like a lot of extra hassle and i think it could me much easier but i can't wrap my head around it. Anyway, this is the code :
<table id="plan" class="table table-bordered">
<thead>
<th></th>
#foreach($taskdates as $taskdate)
<th id="{{ $taskdate->id }}">{{ $taskdate->subject }}</th>
#endforeach
</thead>
<tbody>
#foreach($employees as $employee)
<tr id="{{ $employee->id }}">
<td>{{ $employee->name }}</td>
#foreach($taskdates as $taskdate)
<?php
$result = array_filter($employee->workdates, function($user) use ($taskdate){
return $user->id === $taskdate->id;
});
?>
#if( empty($result) )
<td></td>
#else
<td id="{{$result[key($result)]->pivot->id }}" style="{{ ($result[key($result)]->pivot->taskdate_isread) ? '' : 'font-weight:bold;'}}">
{{date('H:i', strtotime($result[key($result)]->pivot->taskdate_time))}}
</td>
#endif
#endforeach
</tr>
#endforeach
</tbody>
</table>
So i am filtering the whole workdates relationship of each user, if its hold the Taskdate id. And if it is empty, then don't echo anything.
The syntax of the HTML/PHP is in BLADE, so it might not seem correct PHP parsing, but it is.
Edit :
Question :
My code feels bloated. I don't think this is the most efficient way to achieve the result. What is your opinion on this? I like to be as efficient as possible.

Related

Laravel 6 in index blade how can I show only users who have roles and their roles in the table

In index.blade.php, I wrote these codes to show users who have roles
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Roles</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
#foreach($users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>{{ $user->roles }}</td>
<td>Show</td>
</tr>
#endforeach
</tbody>
And I wrote these codes in UserController,
$userId = \DB::table('role_user')->get()->pluck('user_id');
$users = User::find($userId);
return view('admin.index', compact('users'));
And I got these in the website:
[{"id":1,"name":"User Administrator","description":null,"created_at":"2021-11-23 03:06:49","updated_at":"2021-11-23 03:06:49","pivot":{"user_id":1,"role_id":1}}]
[{"id":2,"name":"Moderator","description":null,"created_at":"2021-11-23 03:06:49","updated_at":"2021-11-23 03:06:49","pivot":{"user_id":2,"role_id":2}}]
How can I only display the names in the table role column?
When calling user->roles, you're most likely calling towards a relation on your User model. This means that you're returning a collection. If you place a collection in curly braces in blade ({{ $user->roles }}), Laravel automatically calls toArray() on each model, and a json_encode on the result, which results in the JSON strings you end up seeing.
You only want the names, however, so it'd be better to grab those values and convert them to a string. An option of doing so is by plucking the name, and imploding the result:
implode(', ', $user->roles()->pluck('name')->toArray());
You have to call toArray() on the pluck() result, else you'll have a collection instead of an array, which implode does not work with.
If the user is logged in and his role is to be displayed, you can use this in your blade:
{{ Auth::user()->roles->pluck('name') }}
Or you would like to display the rools of another user, then you can do it as follows:
// in Controller fetch the user:
$user = User::find(42);
// in your Blade:
{{ $user->roles->pluck('name') }}
In this context, you have a number of methods that you can use:
roles
hasRole
hasAnyRole
hasAllRoles
getRoleNames

Laravel Variable Not Passing Through

I'm an absolute beginner and I'm trying to do a CRUD in Laravel, but I can not figure it out why my variables aren't being passed over to the view so I can have a dynamic display of them in the table.
My "routes" work fine.
Then my controller
public function getHome()
{
$results = Crud::index();
return view('pages/home', ['results' => $results]);
}
Calls my "Crud" model
class Crud extends Model
{
public static function index()
{
return $results = DB::table('data')
->whereNotNull('id')
->get();
}
}
And goes to my view as seen in the controller
#extends('main')
#section('title', '| Home')
#section('content')
<div class="container">
#include ('partials/_jumbotron')
<table class="table table-inverse">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
#if(!empty($results))
#foreach($results as $result)
<tr>
<td scope="row">$result->$id</th>
<td>$result->$first_name</td>
<td>$result->$last_name</td>
<td>$result->$username</td>
</tr>
#endforeach
#endif
</tbody>
</table>
</div>
#endsection
Thanks for the help in advance...I'm losing my mind
And sorry If I wasn't specific enough..
Edit1: I did as you say, but I'm still not outputing data to my table? Is there anything else wrong in the stated code or is the bug somewhere deeper?
Edit2: Thanks everyone for the pointed out mistakes - blade {{ }} and object properties
$object->propertie not $object->$propertie
When I fixed those mistakes which were obviously denying the output I remembered that I have an empty database.. Case Closed - Thanks everyone for the help
You're not printing the variables. You're printing literals.
If you want to print the variables (echo them) in blade files, you need to wrap them in curly brackets. Also there's not $ when you want to display an object attribute. Like that:
#foreach($results as $result)
<tr>
<td scope="row">{{ $result->id }}</th>
<td>{{ $result->first_name }}</td>
<td>{{ $result->last_name }}</td>
<td>{{ $result->username }}</td>
</tr>
#endforeach
I am a beginner too, I thought maybe you might want to try this as well
public function getHome()
{
$results = Crud::index();
return view('pages/home', compact('results'));
}
But before anything else make sure if your code is actually returning your data from DB using
dd($results)
The first of all cleaner will be using laravel with function for example
return view('pages/home')->with('results', $results);
Next you try to get $result->$first_name it didint working becouse first_name is not variable, laravel return object so you can get first_name like that:
{{$result->first_name}}

Display total amount for a charity in Laravel 5.2

I have a charity_donations table which holds a charity_id, amount donated for that charity, among other fields. This is how it looks.
What I need to do is I need to groupBy each charity ID, then count how much money was donated for that particular charity. And most importantly, I need to display that in a view.
Some thing like this:
Charity ID | Total
1 | $1,200
....
I have tried this,
$displayPerCharity = CharityDonation::select(DB::Raw('charity_id, COUNT(*) as count'))->groupBy('charity_id')->get();
dd($displayPerCharity);
That counts the charity IDs, then gives me the total for each charity. But I need total amount for each charity, then display in view.
Got it!
$displayPerCharity = DB::table('charity_donations')
->select(DB::raw('SUM(amount) as charity_amount, charity_id'))
->groupBy('charity_id')
->orderBy('charity_amount', 'desc')
->get();
Then in view:
#foreach ($displayPerCharity as $group)
<h1> Charity ID {{ $group->charity_id }} received {{ $group->charity_amount }}</h1>
#endforeach
Well how you display it is entirely up to how you want it to look.
If you're just stuck on how to get each charity ID and amount out, then you can just do this with a foreach loop.
Here's an example using a Bootstrap responsive table. This assumes that after you have run your query you have passed it on to the view as a variable called $displayPerCharity.
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Charity ID</th>
<th>Amount ($)</th>
</tr>
</thead>
<tbody>
#foreach($displayPerCharity as $display)
<tr>
<td>{{ $display->charity_id }}</td>
<td>{{ $display->charity_amount }}</td>
</tr>
#endforeach
</tbody>
</table>
</div>

Laravel - paginated model sort link in blade view

In laravel 5.2 I have a paginated table of a model.
#CityController
public function index(Request $request){
$cities = City::orderBy('name');
return view('pages.city.index', ["cities" => $cities ->paginate(25)]);
}
This works fine, but when I try to sort the results inside the blade view does not work.
#index.blade.php
<table>
<thead>
<tr class="sui-columnheader">
<th class="sui-headercell" data-field="Id">
Id
</th>
</thead>
<tbody class="list">
#foreach ($cities as $city)
<tr class="sui-row">
<td class="sui-cell id">{!! $city->id !!}</td>
</tr>
</tbody>
</table>
When I click the sort button just reloads the page but no sort is applied.
Is because of the "orderBy" clause?
How can I make it work and defaults to order by name?
Am I missing something?
Something like this perhaps. You would want to make sure you limit what can be passed to that orderBy. A URL like "...something?sort=blah" would cause orderBy('blah'), which your table doesn't have, which will cause a DB error.
public function index(Request $request)
{
$cities = City::orderBy($request->input('sort', 'name'))->paginate(25);
return view('pages.city.index', ['cities' => $cities]);
}
{{ $cities->appends(Request::query())->render() }}
Just giving you a functional example, though you will have to adjust based on your own rules.
The appends is just allowing you to continue to paginate based on the current sorting, by passing the sort option via the query string of the pagination links.
Update:
Using your example where there is a default, but imagining there can be more than just 1 other field to sort by:
$sort = trim($request->input('sort'));
// if it is in the acceptable array use it, otherwise default to 'name'
$sort = in_array($sort, ['id', ...]) ? $sort : 'name';
$cities = City::orderBy($sort)->paginate(25);
<table>
<tr>
<th>ID</th>
<th>NAME</th>
...
</tr>
#foreach ($cities as $city)
<tr>
<td>{{ $city->id }}</td>
<td>{{ $city->name }}</td>
...
</tr>
#endforeach
...
{{ $cities->appends(Request::query())->render() }}
Just an example, you can do this how you would like.

How do I pass a variable from a link to a controller in laravel?

So I have a page setup with a table of items. In each row there is a link. When the link is clicked I want to pass the ID of them through to the controller so I can pass it on to another view. Although I can't figure out how to do this.
This is the code in my item view
#foreach($items as $item)
<tr>
<td>{{$item->title}}</td>
<td>{{$item->genre}}</td>
<td>{{$item->description}}</td>
<td>View</td>
</tr>
#endforeach
As you can see there is a link which leads me to the rent view. In the controller this is all I have.
public function rent()
{
return view('rent');
}
Any help would be appreciated thanks.
I'd probably do it something like this.
#foreach($items as $item)
<tr>
<td>{{$item->title}}</td>
<td>{{$item->genre}}</td>
<td>{{$item->description}}</td>
<td>View</td>
</tr>
#endforeach
And then inside your controller you can accept the the value you are passing.
public function rent($value)
{
return View::make('new-view')->with('value', $value);
}
and then inside your new-view.blade.php
<p> The value I passed is: {{ $value }} </p>
Read more about Laravel url helpers here https://laravel.com/docs/5.1/helpers#urls
You can use route() helper:
#foreach($items as $item)
<tr>
<td>{{ $item->title }}</td>
<td>{{ $item->genre }</td>
<td>{{ $item->description }}</td>
<td>View</td>
</tr>
#endforeach
As alternative you can use link to action:
{{ action('RentController#profile', ['id' => $item->someId]); }}
And sometimes it's useful to use url() helper:
{{ echo url('rent', [$item->someId]) }}
More on these helpes here.
If you're using Laravel 5 with Laravel Collective installed or you're on Laravel 4, you can use these constructions to generate URLs with parameters.
PS: If you're using tables for layout, don't do it. You should learn DIVs, because it's really easy now to build cool layout with DIVs using Bootstrap framework which is built-in Laravel.

Categories