query results of signed in user in laravel - php

I currently have a ticket system built and I would like users to view the status of their Open and Closed tickets.
I can query the database and get all tickets to display, but I only want the logged in users tickets to show. How would I achieve this. Been at it a few days now and I'm at a loss.
What I have:
ROUTE (This returns a 404 due to the {ticketId}) / Note: If I remove the {ticketId} from the Route I get the Type error: *Too few arguments to function App\Http\Controllers\TicketsController::openTickets(), 0 passed and exactly 1 expected"*
Route::get('/tickets/open-tickets/{ticketId}','TicketsController#openTickets')->name('open-tickets');
TICKETS CONTROLLER
public function openTickets($ticketId){
$tickets=Classified::find($ticketId);
$ticketId = Auth::user('id');
$tickets = DB::table('tickets')->orderBy('st_id', 'DESC')->where('status', '=', 'OPEN')->where('user_id', '=', $id)->paginate(4);
return view('tickets.open-tickets',compact('tickets'));
Ticket MODEL
class Ticket extends Model
{
use Notifiable, HasPermissionsTrait;
protected $ticketId = 'st_id';
protected $guarded=[];
protected $dispatchesEvents = [
'created' => Events\NewTicket::class
];
}
WORKING QUERY TO DISPLAY ALL TICKETS
public function openTickets(){
$tickets = DB::table('tickets')->orderBy('st_id', 'DESC')->where('status', '=', 'OPEN')->paginate(4);
return view('tickets.open-tickets',compact('tickets'));
I should mention that I changed my id to st_id on the tickets table as I'm using the ID to display the ticket number like this 201804001
Again I'm just looking for a solution to have the logged in user view their tickets and NOT all tickets in the database.
Image of Tickets Table:

You already have a Ticket model but you're using the DB facade to query the tickets table.
Instead, associate Tickets with Users via a one-to-many relationship.
class Ticket extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
In your User class:
public function tickets()
{
return $this->hasMany(Ticket::class);
}
Now you can do $user->tickets()->where('status', 'OPEN')->get(); to get all the open tickets for that user.
Even further, you can add a scope to the Ticket model.
In your Ticket class:
public function scopeOpen($query)
{
return $query->where('status', 'OPEN');
}
This will allow you to make your queries more fluent:
$user->tickets()->open()->get();
To associate a ticket with a user, simply do something along the following lines:
$user->tickets()->save(new Ticket([
'status' => 'open',
'title' => 'Problem logging in',
'body' => 'Lorem ipsum dolor sit amet'
]));
For more information about Eloquent relationships (specifically one-to-many relationships), see the documentation here.
To list all of a user's open tickets, use the following route:
Route::get('tickets/open-tickets/', 'TicketsController#index');
To show an individual ticket, you'll want the following route:
Route::get('tickets/open-tickets/{ticket}', 'TicketsController#show')
Use the following methods in your TicketsController:
public function index()
{
// user() is a helper for Auth::user()
$tickets = user()->tickets()->open()->paginate(4);
return view('tickets.open-tickets', compact('tickets'));
}
public function show(Ticket $ticket)
{
// If the ticket does not belong to the logged in user, abort
if ($ticket->user_id != user()->id) {
abort(403, 'This is not your ticket');
}
return view('tickets.show', compact('ticket'));
}
You'll notice that the show method in your controller type-hints the Ticket model. This is called route-model binding, which is very useful and you can read more about that here.
It may seem like I'm overcomplicating things compared to your original code, but trust me, it's better to understand these things early on! They'll help you a whole lot during development.

Related

Can I somehow also get the usernames of the people who have commented on an image if I only have their ids in my comments table

My comments table has the following columns:
id, user_id, image_id, comment
Currently I'm getting all comments that belong to a specific image like this:
$comments = Comment::where('image_id', $id)->get();
And then I can easily display the comments on the view to which I pass the $comments variable. However, I can only display the id of the user who has posted the comment but that wouldn't make much sense so I'm trying to display the username instead.
Since I don't save the username of the user who has posted a comment in the comments table, I can't access it from $comments as of now. Is there a way to somehow add an extra key-value pair to $comments that would contain the username of the user based on his id?
Comment model:
class Comment extends Model
{
public function images(){
return $this->belongsTo('App\Image');
}
public function users(){
return $this->belongsTo('App\User');
}
}
User model:
class User extends Model implements Authenticatable
{
public function comments(){
return $this->hasMany('App\Comment');
}
}
I guess that you should have a table/model for the User objects.
If so, you can Eager Load the relationship. To accomplish this, define the relationship in your model:
app/Comment.php
public function users()
{
return $this->belongsTo(User::class);
}
Note: given that this is the reverse of a hasMany relationship (belongsTo), you should name this functions in singular: a Comment belongs to a unique User.
Then in your controller:
$comments = Comment::with('users')->where('image_id', $id)->get();
This will include the user object inside every comment. Of course, you can limit the user attributes returned to the view but you get te idea.
To know more about this, check the documentation.
Make a Join similar to connect both tables!
$comments = DB::table('comment')
->join('user', 'comment.user_id', '=', 'user.id')
->select('comment.*', 'user.name')
->where(image_id, $id)
->get();
A related question with eloquent specifics
How to join three table by laravel eloquent model

How to create a relationship between models for ticket system in laravel

I am trying to make a ticketing system and I am working on showing the tickets a user has. The way the relationship works now is that the tickets are assigned to a user who's then assigned to a campus. I actually need it to to be where the tickets are assigned to the campus since the campus is definite, and have a tech assigned to that campus. The tech should only see the tickets that belongs to the campus that the tech is assigned to.
In theory, it should work like if a user is changed or relocated then all that needs to be done is update the TechID column. Here is how the table relationship works currently:
Tickets (PK - TicketID, FK - CampusID)
Campus (PK - CampusID, FK - TechID)
User (PK - TechID)
I actually have a similar question that I asked before, but this was before I realized that the way it was structured before isn't the ideal setup.
Here is the link to the previous question: Previous Question
Here is my current controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Auth;
use App\User;
use App\Campus;
use App\Ticket;
class PagesController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
// Dashboard Page
public function index()
{
$user = User::with(['campuses' => function($query) {
$query->select(['TechID', 'CampusName']);
},'tickets'])->where('id', Auth::id())->first();
$campuses = Campus::all()->where('TechID', $user->id);
$tickets = Ticket::all()->where('CampusID', $campuses->pluck('CampusID'));
return view('home')->with([
'user' => $user,
'campuses'=>$campuses,
'tickets'=>$tickets]);
}
// Queue Page
public function Queue() {
return view('Pages.Queue');
}
// Reports Page
public function Reports() {
return view('Pages.Reports');
}
// Search Page
public function Search() {
return view('Pages.Search');
}
}
I was hoping this would work, but no tickets actually show up. The user can have more than one campus so I was wondering if maybe this is where things are messing up. Any help is much appreciated
I'd suggest doing the where before the all/get, so that the filtering is done on the database level instead of PHP -- all before where will have the database return all of the values, then use the Collection to filter the results. Also, the second query needs whereIn, since you're passing in an array of values:
$campuses = Campus::where('TechID', $user->id)->get();
$tickets = Ticket::whereIn('CampusID', $campuses->pluck('CampusID'))->get();

PHP Laravel 5.2: Eloquent relationship for subscriptions

I think I got a little stuck and I just need someone to clarify things. So what I got is a user system which includes subscriptions for people to "subscribe" to their content (as you already know it from FB, Twitter, YT etc).
My database model looks like this:
Users
id
username
Subsccriptions
id
user_id
sub_id
Currently I have one model for Users and one Model for Subscriptions. The model from the user:
public function subscriptions()
{
return $this->hasMany('App\Subscription');
}
In comparison, my subscription object:
public function user()
{
return $this->belongsTo('App\User');
}
So in my personal opinion this is a 1:many relationship. If I call the user object with User->subscriptions()->get() I can get the subscription and it's sub id, so I know who THE CURRENT user has subscribed.
People told me the opposite and it's supposed to be a many-to-many relationship. Did I do something wrong? Can I automatically convert the sub_id into a user through relationships in Eloquent?
// EDIT:
Here is the current code to receive my subscribers for a user
public function index()
{
$subs = Auth::user()->subscriptions()->get()->all();
$submodels = [];
foreach($subs as $sub) {
array_push($submodels,User::find($sub->sub_id));
}
return view('home', [
'subscriptions' => $submodels
]);
}
}

Check for a many to many relation when listing a resource

I'm implementing relationships in Eloquent, and I'm facing the following problem:
An article can have many followers (users), and a user can follow many articles (by follow I mean, the users get notifications when a followed article is updated).
Defining such a relationship is easy:
class User extends Eloquent {
public function followedArticles()
{
return $this->belongsToMany('Article', 'article_followers');
}
}
also
class Article extends Eloquent {
public function followers()
{
return $this->belongsToMany('User', 'article_followers');
}
}
Now, when listing articles I want to show an extra information about each article: if the current user is or is not following it.
So for each article I would have:
article_id
title
content
etc.
is_following (extra field)
What I am doing now is this:
$articles = Article::with(array(
'followers' => function($query) use ($userId) {
$query->where('article_followers.user_id', '=', $userId);
}
)
);
This way I have an extra field for each article: 'followers` containing an array with a single user, if the user is following the article, or an empty array if he is not following it.
In my controller I can process this data to have the form I want, but I feel this kind of a hack.
I would love to have a simple is_following field with a boolean (whether the user following the article).
Is there a simple way of doing this?
One way of doing this would be to create an accessor for the custom field:
class Article extends Eloquent {
protected $appends = array('is_following');
public function followers()
{
return $this->belongsToMany('User', 'article_followers');
}
public function getIsFollowingAttribute() {
// Insert code here to determine if the
// current instance is related to the current user
}
}
What this will do is create a new field named 'is_following' which will automatically be added to the returned json object or model.
The code to determine whether or not the currently logged in user is following the article would depend upon your application.
Something like this should work:
return $this->followers()->contains($user->id);

Laravel Object queries - 3 tables

I have three tables like this:
**Users**
id
**Posts**
id
user_id
**Favorites**
id
user_id
post_id
Currently, I made it so when I query my posts for display, it pulls all the related user data who created the post with that row which is great! But what I'm trying to do now is also add to see if the user Authorized (Logged in) has favorited the post (row) so I can display to that they already favorited it. I don't want to re-query for every post (i think its called the N+1 problem?). I'm using Laravel4
Post model
class Post extends Eloquent{
public function user(){
return $this->belongsTo('User');
}
User model
public function posts(){
return $this->hasMany('Post');
}
PostsController
public function index()
{
$posts = Post::with('user')->paginate(25);
return View::make('index', compact('posts'));
}
Step 1. Add favorites relationship in Post model.
public function favorites() {
return $this->hasMany('Favorite');
}
When querying the Model.
$auth_user_id = Auth::user()->id;
$posts = Post::with(array('user', 'favorites' => function($query) use ($auth_user_id){
$query->where('user_id', '=', $auth_user_id);
}))->get();
For more information refer to the eager load constraints,
http://laravel.com/docs/eloquent#eager-loading
Adding a many-to-many relationship using the favorites table as pivot would be one approach.
Add favorites relationship in User model:
public function favorites() {
return $this->belongsToMany('Post', 'favorites');
}
You should then be able to get all favorites by simply accessing
Auth::user()->favorites
To find whether the current post is a favorite, use
$isFavorite = Auth::user()->favorites->has($post->id);

Categories