In Laravel I have a scenario in which different users can go to a view blade where they can see posts they have created.
At the minute I'm just passing in all the data, but I'm wondering how to pass data to a view depending on the user.
E.g if I'm a root user I get to see everything so like
Post::get()
Then
return view('someview', compact('post')
Which would return the posts
Essentially what Im trying is something like this...
if(user->role = their role) then you get query 1 else you get query 2
Do you think this is acheivable using conditional query scopes?
UPDATE
Is this a horrible solution?
if($user->department == "Loans")
{
echo "you are from loans FAM";
$articles = Article::where('department', '=', 'Loans')->get();
}
else if($user->department == "Digital")
{
echo "you are from digital FAM";
$articles = Article::where('department', '=', 'Digital')->get();
}
else if($user->department == "Consulting")
{
echo "you are from Consulting FAM";
$articles = Article::where('department', '=', 'Consulting')->get();
}
You could achieve that with a query scope if you wanted to. Something like this:
class Post extends Model
{
// ...
public function scopeByUser($query, User $user)
{
// If the user is not an admin, show only posts they've created
if (!$user->hasRole('admin')) {
return $query->where('created_by', $user->id);
}
return $query;
}
}
Then you can use it like this:
$posts = Post::byUser($user)->get();
In response to your update:
class Article extends Model
{
// ...
public function scopeByUser($query, User $user)
{
// If the user is not an admin, show articles by their department.
// Chaining another where(column, condition) results in an AND in
// the WHERE clause
if (!$user->hasRole('admin')) {
// WHERE department = X AND another_column = another_value
return $query->where('department', $user->department)
->where('another_column', 'another_value');
}
// If the user is an admin, don't add any extra where clauses, so everything is returned.
return $query;
}
}
You would use this in the same kind of way as above.
Article::byUser($user)->get();
Related
Inside the $get_user and $get_code queries they both have a group_id.
I have dd(); them Both and made 100% sure.
the $get_user query has multiple group_id's and the $get_code only has one group_id which is equal to one of the $get_user group_id's.
The goal at the moment is to create a group_id match query.
Get the code that has a group ID equal to one of the $get_user group_id's
public function getCodesViewQr($code_id)
{
$userid = Auth::id();
$get_user = GroupUser::all()->where('user_id',$userid);
$get_code = Code::all()->where('id',$code_id);
$group_match = GroupUser::where('group_id', $get_code->group_id);
$view['get_users'] = $get_user;
$view['get_codes'] = $get_code;
$view['group_matchs'] = $group_match;
return view('codes.view_qr_code', $view);
}
The group match query does not work. $get_code->group_id does not get the code group_id.
If there is a match then set $match equal to rue. else $match is False
$group_match = GroupUser::where('group_id', $get_code->group_id);
I'm using two Models Code and GroupUser
My Code table is like this :
-id
-group_id (This is the only on important right now)
-code_type
My GroupUser table is like this :
-id
-group_id (This is the only on important right now)
-user_id
-user_role
I have linked the Models
Inside my Code Model I have the relationship to GroupUser
public function group_user()
{
return $this->belongsto('App\GroupUser');
}
And Inside my GroupUser Model I have the relationship to Code
public function code()
{
return $this->belongsto('App\Code');
}
Inside My Code controller I have included my models.
use App\Code;
use App\GroupUser;
Hi guys so I had some help from a guy I work with and this is the solution he came up with. We made a few adjustments. all the Databases and results stayed the same. we just changed the method we used to get the results.
I really appreciate all the help from #linktoahref
public function view_code($random)
{
$code = Code::where('random', $random)->first();
$view['code'] = $code;
if ($code->code_type == 1)
{
// Its a coupon
if (!empty(Auth::user()))
{
// Someones is logged in
$user = Auth::user();
$view['user'] = $user;
$user_groups = GroupUser::where('user_id',$user->id)->pluck('group_id')->toArray();
if (in_array($code->group_id, $user_groups))
{
// The user is an admin of this code
return view('view_codes.coupon_admin', $view);
}else
{
// Save the code to that users account
return view('view_codes.generic_code', $view);
}
}else
{
// Anon
return view('view_codes.coupon_anon', $view);
}
}elseif ($code->code_type == 2)
{
// Voucher..
}else
{
// We don't know how to deal with that code type
}
}
$get_code = Code::find($code_id);
// Check if the code isn't null, else give a fallback to group_id
$group_id = 0;
if (! is_null($get_code)) {
$group_id = $get_code->group_id;
}
$group_match = GroupUser::where('group_id', $group_id)
->get();
$match = FALSE;
if ($group_match->count()) {
$match = TRUE;
}
I want to show variables value in blade file. Below is the controller code:-
public function ClientListReviews()
{
// to show client list get data from users booking table
$select_clientlist =
DB::table('users_booking')>where('service_provider', '=', 1)->get();
if(count($select_clientlist) > 0)
{
return view('client-database')->with($select_clientlist);
}
else
{
return view('client-database')->withMessage('No Details Found');
}
}
I want to show the values coming in $select_clientlist variable. Below is the code in my blade file:-
#foreach($select_clientlist as $clientlist)
{{$clientlist->firstname}}
#endforeach
And below is the route file code:-
Route::post('client_list_ajax','ClientDatabase\ClientdatabaseController#ClientListReviews');
I am receiving error.
What am I doing wrong?
Pass the variable using compact method
return View::make('myviewfolder.myview', compact('view1','view2','view3'));
view1,view2,view3 are variable names
Since you only pass the variable when there is records wrap your for each inside isset
if (isset($select_clientlist)) {
foreach($select_clientlist as $clientlist) {
}
}
your query should be like this . you may be forget SELECT statement
$select_clientlist = DB::table('users_booking')->select('*')->where('service_provider', '=', 1)->get();
Either use as
return view('client-database')->with('select_clientlist',$select_clientlist);
Or
return view('client-database',compact('select_clientlist'));
Also add in select_clientlist else part to prevent undefined error
public function ClientListReviews()
{
// to show client list get data from users booking table
$select_clientlist =
DB::table('users_booking')>where('service_provider', '=', 1)->get();
if(count($select_clientlist) > 0)
{
return view('client-database')->with('select_clientlist',$select_clientlist);
}
else
{
$select_clientlist = [];
return view('client-database')->with('select_clientlist',$select_clientlist)->withMessage('No Details Found');
}
}
OR check by isset($select_clientlist) in blade file
$__currentLoopData = isset($select_clientlist)?$select_clientlist:[];
Pass that variable to your view either way .. it should be a collection. If there are no records, it is just empty. The foreach wont run if its empty. Its as simple as that. No need to check if anything is set or is empty etc... just always pass that collection.
public function ClientListReviews()
{
$select_clientlist = DB::table('users_booking')->where('service_provider', 1)->get();
$view = view('client-database', compact('select_clientlist'));
if ($select_clientlist->isEmpty()) {
$view->with('message', 'No Details Found');
}
return $view;
}
I want to implement a system in my project that "alerts" users when there is a new comment on one of their posts.
I currently query all comments on the posts from the logged in user and put everything in an array and send it to my view.
Now my goal is to make an alert icon or something when there is a new item in this array. It doesn't have to be live with ajax just on page load is already good :)
So I've made a function in my UsersController where I get the comments here's my code
public function getProfileNotifications()
{
$uid = Auth::user()->id;
$projects = User::find($uid)->projects;
//comments
if (!empty($projects)) {
foreach ($projects as $project) {
$comments_collection[] = $project->comments;
}
}
if (!empty($comments_collection)) {
$comments = array_collapse($comments_collection);
foreach($comments as $com)
{
if ($com->from_user != Auth::user()->id) {
$ofdate = $com->created_at;
$commentdate = date("d M", strtotime($ofdate));
$comarr[] = array(
'date' => $ofdate,
$commentdate,User::find($com->from_user)->name,
User::find($com->from_user)->email,
Project::find($com->on_projects)->title,
$com->on_projects,
$com->body,
Project::find($com->on_projects)->file_name,
User::find($com->from_user)->file_name
);
}
}
} else {
$comarr = "";
}
}
Is there a way I can check on page load if there are new items in the array? Like keep a count and then do a new count and subtract the previous count from the new one?
Is this even a good way to apprach this?
Many thanks in advance! Any help is appreciated.
EDIT
so I added a field unread to my table and I try to count the number of unreads in my comments array like this:
$uid = Auth::user()->id;
$projects = User::find($uid)->projects;
//comments
if (!empty($projects)) {
foreach ($projects as $project) {
$comments_collection[] = $project->comments;
}
}
$unreads = $comments_collection->where('unread', 1);
dd($unreads->count());
But i get this error:
Call to a member function where() on array
Anyone any idea how I can fix this?
The "standard" way of doing this is to track whether the comment owner has "read" the comment. You can do that fairly easily by adding a "unread" (or something equivalent) flag.
When you build your models, you should define all their relationships so that stuff like this becomes relatively easy.
If you do not have relationships, you need to define something like the following:
In User
public function projects()
{
return $this->hasMany('App\Models\Project');
}
In Project
public function comments()
{
return $this->hasMany('App\Models\Comment');
}
Once you hav ethose relationshipt, you can do the following. Add filtering as you see fit.
$count = $user->projects()
->comments()
->where('unread', true)
->count();
This is then the number you display to the user. When they perform an action you think means they've acknowledged the comment, you dispatch an asynchronous request to mark the comment as read. A REST-ish way to do this might look something like the following:
Javascript, using JQuery:
jQuery.ajax( '/users/{userId}/projects/{projectId}/comments/{commentId}', {
method: 'patch'
dataType: 'json',
data: {
'unread': false
}
})
PHP, in patch method:
$comment = Comment::find($commentId);
$comment->update($patchData);
Keep in mind you can use Laravel's RESTful Resource Controllers to provide this behavior.
try this
$unreads = $project->comments()->where('unread', 1);
dd($unreads->count());
EDIT
My be Has Many Through relation will fit your needs
User.php
public function comments()
{
return $this->hasManyTrough('App\Project', 'App\Comment');
}
Project.php
public function comments()
{
return $this->hasMany('App\Comment');
}
then you can access comments from user directly
$user->comments()->where('unread', 1)->count();
or I recommend you define hasUnreadComments method in User
public function hasUnreadComments()
{
$return (bool) $this->comments()->where('unread', 1)->count();
}
P.S.
$uid = Auth::user()->id;
$projects = User::find($uid)->projects;
this code is horrible, this way much better
$projects = Auth::user()->projects;
I want to get a total user transaction (specific user) with relationship.
I've done it but i'm curious is my way is good approach.
//User Model
public function Transaction()
{
return $this->hasMany(Transaction::class);
}
//Merchant Model
public function Transaction()
{
return $this->hasMany(Transaction::class);
}
public function countTransaction()
{
return $this->hasOne(Transaction::class)
->where('user_id', Request::get('user_id'))
->groupBy('merchant_id');
}
public function getCountTransactionAttribute()
{
if ($this->relationLoaded('countTransaction'))
$this->load('countTransaction');
$related = $this->getRelation('countTransaction');
return ($related) ? (int)$related->total_transaction : 0;
}
//controller
$merchant = Merchant::with('countTransaction')->get();
What make me curious is part inside countTransaction. I put where where('user_id', Request::get('user_id')) directly inside the model.
is it good approach or any other way to get specific way?
expected result:
"merchant:"{
"name": "example"
"username" : "example"
"transactions": {
"count_transactions: "4" //4 came from a specific user.
}
}
I need to get the merchant data with the transaction count for specific user. This query is based on logged in user. so when a user access merchant page, they can see their transaction count for that merchant.
Thanks.
You really want to keep request data outside of your models (instead opting to pass it in). I'm also a little confused about why you have both a 'hasOne' for transactions, and a 'hasMany' for transactions within the merchant model.
I would probably approach the problem more like the below (untested, but along these lines). Again I'm not fully sure I understand what you need, but along these lines
// Merchant Model
public function transactions()
{
return $this->hasMany(Transaction::class);
}
public function countTransactionsByUser($userId)
{
return $this
->transactions()
->where('user_id', $userId)
->get()
->pluck('total_transaction')
->sum();
}
// Controller
$userId = request()->get('user_id');
// ::all() or however you want to reduce
// down the Merchant collection
//
$merchants = Merchant::all()->map(function($item, $key) {
$_item = $item->getAttributes();
$_item['transactions'] = [
'count_transactions' => $item->countTransactionsByUser($userId);
];
return $_item;
});
// Single total
// Find merchant 2, and then get the total transactions
// for user 2
//
$singleTotal = Merchant::find(2)
->countTransactionsByUser($userId);
I have a resource:
Route::resource('artists', 'ArtistsController');
For a particular url (domain.com/artists/{$id} or domain.com/artists/{$url_tag}), I can look at the individual page for a resource in the table artists. It is controlled by this function:
public function show($id)
{
if(!is_numeric($id)) {
$results = DB::select('select * from artists where url_tag = ?', array($id));
if(isset($results[0]->id) && !empty($results[0]->id)) {
$id = $results[0]->id;
}
}
else {
$artist = Artist::find($id);
}
$artist = Artist::find($id);
return View::make('artists.show', compact('artist'))
->with('fans', Fan::all())
->with('friendlikes', Fanartist::friend_likes())
->with('fan_likes', Fanartist::fan_likes());
}
What I would like to do is have all urls that are visited where the {$id} or the {$url_tag} don't exist int he table, to be rerouted to another page. For instance, if I typed domain.com/artists/jujubeee, and jujubee doesn't exist in the table in the $url_tag column, I want it rerouted to another page.
Any ideas on how to do this?
Thank you.
In your show method you may use something like this:
public function show($id)
{
$artist = Artist::find($id);
if($artist) {
return View::make('artists.show', compact('artist'))->with(...)
}
else {
return View::make('errors.notfound')->withID($id);
}
}
In your views folder create a folder named errors (if not present) and in this folder create a view named notfound.blade.php and in this view file you'll get the $id so you may show something useful with/without the id.
Alternatively, you may register a global NotFoundHttpException exception handler in your app/start/global.php file like this:
App::error(function(Symfony\Component\HttpKernel\Exception\NotFoundHttpException $e) {
// Use $e->getMessage() to get the message from the object
return View::make('errors.notfound')->with('exception', $e);
});
To redirect to another page have a look at the redirect methods available on the responses page of the Laravel docs.
This is how I would go about doing it and note that you can also simplify your database queries using Eloquent:
public function show($id)
{
if( ! is_numeric($id)) {
// Select only the first result.
$artist = Arist::where('url_tag', $id)->first();
}
else {
// Select by primary key
$artist = Artist::find($id);
}
// If no artist was found
if( ! $artist) {
// Redirect to a different page.
return Redirect::to('path/to/user/not/found');
}
return View::make('artists.show', compact('artist'))
->with('fans', Fan::all())
->with('friendlikes', Fanartist::friend_likes())
->with('fan_likes', Fanartist::fan_likes());
}