Different views based on user table information in Laravel 7 - php

I have a project in Laravel 7 that has a column in the user table called organ_id that has different numbers for different users (1,2,...)
Now I want to use organ_id inside my controller, which is as follows, and by using if, different information is given to each user according to the organ number.
ProductsController.php
namespace App\Http\Controllers;
use App\User;
use DB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
if (Auth::check())
{
$organ_id = Auth::user()->getId();
}
class ProductsController extends Controller
{
public function test(Request $request) {
if ($organ_id == 1) {
function orders(Request $request) {
$data = DB::table('products_1')
->orderBy('id', 'asc')
->paginate(14);
return view('products', compact('data'));
}
function posts(Request $request) {
$data = DB::table('posts')
->orderBy('id', 'asc')
->paginate(25);
return view('posts', compact('data'));
}
/*
other functions
.
.
.
*/
}
if ($organ_id == 2) {
function orders(Request $request) {
$data = DB::table('products_2')
->orderBy('id', 'asc')
->paginate(14);
return view('products', compact('data'));
}
function posts(Request $request) {
$data = DB::table('posts')
->orderBy('writer_id', 'asc')
->paginate(10);
return view('posts', compact('data'));
}
/*
other functions
.
.
.
*/
}
}
}
User.php
public function getId()
{
return $this->organ_id;
}
Since it is not possible to use if in the controller, I wrote the public function test() and put if inside this function.
Unfortunately, in this case, the browser can not find the orders function.

you can do that
$organ_id = User::where('id',auth()->user()->id)->pluck('organ_id')->first();
if ($organ_id == 1) {
//code
}

Related

Laravel how to get users by roles dynamically from api endpoint

How can I get the users based on which role they have in laravel? I have roles like for example "admin", "author", "editor" and I want to have a dynamic api-endpoint.
so in my api.php I have:
Route::get('users/{role}', "Api\UserController#role");
and my Controller looks like this:
public function show()
{
$user_role = User::whereHas(
'roles',
function ($q) {
$q->where('name', 'admin');
}
)->get();
return $user_role;
}
This works fine so far, but I want the endpoint to be dynamic, like if want all my editor users the endpoint should be api/users/editors etc. etc.
How can I achieve this?
public function show($role) //example: $role = 'admin'
{
return User::whereHas('roles', function ($q) use ($role) {
$q->where('name', $role);
})->get();
}
Your controller function should look like this:
public function show(Role $role)
{
$users = $role->users;
return $users;
}
And your Role Eloquent Model should have these methods:
public function users()
{
return $this->belongsToMany(User::class, 'user_role')
}
public function getRouteKeyName()
{
return 'name';
}

Filtering data with spatie query builder using trait

I put logic from my function index() of UserController in trait taht i created:
public function index()
{
$this->authorize('view', Auth::user());
$users = QueryBuilder::for(User::class)
->allowedIncludes('kids','roles','articles','recordings')
->allowedFilters('first_name', 'last_name', 'email')
->get();
return UserResource::collection($users);
}
and this is my trait :
<?php
namespace App\Http\Traits;
use App\Models\User;
use Spatie\QueryBuilder\QueryBuilder;
trait Filterable
{
public function filter()
{
$users = QueryBuilder::for(User::class)
->allowedIncludes('kids','roles','articles','recordings')
->allowedFilters('first_name', 'last_name', 'email')
->get();
return $users;
}
}
So now my function index() looks like this:
use Filterable;
public function index()
{
$this->authorize('view', Auth::user());
$users = $this->filter();
return UserResource::collection($users);
Now when i do this in my postman
{{url}}/api/users?filter[first_name]=anna
it works and it returns anna from my database but when I try
{{url}}/api/users?include=roles
it return every user from database but does not include roles.
Can somebody help me with this?
This is taken straight from the github page: https://github.com/spatie/laravel-query-builder#custom-filters
Custom filters
use Spatie\QueryBuilder\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;
class FiltersUserPermission implements Filter
{
public function __invoke(Builder $query, $value, string $property) : Builder
{
return $query->whereHas('permissions', function (Builder $query) use ($value) {
$query->where('name', $value);
});
}
}
use Spatie\QueryBuilder\Filter;
// GET /users?filter[permission]=createPosts
$users = QueryBuilder::for(User::class)
->allowedFilters(Filter::custom('permission', FiltersUserPermission::class))
->get();
// $users will contain all users that have the `createPosts` permission

Extracting relational data in laravel

I'm trying to build a small application in laravel 5.4 where I'm having a contacts table, companies table, interactions table and users table each with their respective models. An Interaction is being created by the User where there are client_contact, contact, user participating. Each client_contact and contact shares the same model and belongs to a company which have type in their column for example Investor, Research, Corporate etc. Now I'm trying to generate a report where interaction done by a user with Investors. First of all let me show you my models:
User Model:
class User extends Authenticatable
{
use HasApiTokens, Notifiable, SoftDeletes;
public function interactions()
{
return $this->hasMany('App\Interaction');
}
public function clients()
{
//Each user has been assigned a particular client
return $this->belongsToMany('App\Company', 'company_user', 'user_id', 'company_id');
}
}
Contacts Model:
class Contact extends Model
{
use SoftDeletes, DataViewer;
public function company()
{
return $this
->belongsToMany('App\Company', 'company_contact','contact_id', 'company_id')->withTimestamps();
}
public function interactions()
{
return $this->belongsToMany('App\Interaction', 'contact_interaction','contact_id', 'interaction_id');
}
public function clientInteractions()
{
return $this->belongsToMany('App\Interaction', 'contact_client_interaction','contact_id', 'interaction_id');
}
}
Company Model:
class Company extends Model
{
use SoftDeletes, DataViewer;
public function contacts()
{
return $this->belongsToMany('App\Contact', 'company_contact', 'company_id','contact_id');
}
public function users()
{
return $this->belongsToMany('App\User', 'company_user', 'company_id', 'user_id')->withTimestamps();
}
}
Interaction Model:
class Interaction extends Model
{
use SoftDeletes;
public function stellarParticipants()
{
return $this->belongsToMany('App\User')->withTimestamps();
}
public function clientsAssociation()
{
return $this->belongsToMany('App\Contact', 'contact_client_interaction', 'interaction_id', 'contact_id')->withPivot('company_id')->withTimestamps();
}
public function contactsAssociation()
{
return $this->belongsToMany('App\Contact', 'contact_interaction', 'interaction_id', 'contact_id')->withPivot('company_id')->withTimestamps();
}
public function user()
{
return $this->belongsTo('App\User');
}
}
Now in my ReportController: I'm doing something like this:
public function getAnalystInvestor(Request $request)
{
$user = User::find($request->id);
$interactions = Interaction::whereHas('contactsAssociation', function ($query3) {
$query3->whereHas('company', function ($query4) {
$query4->where('type', 'like', '%'.'Investor'.'%');
});
})->whereHas('user', function ($query1) use($user) {
$query1->where('name', '=', $user->name);
})->orWhereHas('stellarParticipants', function ($query2) use($user) {
$query2->where('name', '=', $user->name);
})
->orderBy('created_at', 'desc')
->take(50)
->with(['contactsAssociation', 'clientsAssociation', 'stellarParticipants'])
->get();
return response()->json(['interactions' => $interactions], 200);
}
But I'm unable to get the desired results, still some of the data are displaying which is not investors. I also tried:
$interactions = Interaction::whereHas('user', function ($query1) use($user) {
$query1->where('name', '=', $user->name);
})->orWhereHas('stellarParticipants', function ($query2) use($user) {
$query2->where('name', '=', $user->name);
})->whereHas('contactsAssociation', function ($query3) {
$query3->whereHas('company', function ($query4) {
$query4->where('type', 'like', '%'.'Investor'.'%');
});
})
Where user filters are assigned first but its not displaying as desired. Help me out with this.
You should be able to chain your query, similar to this:
$cfs = \App\Service::with('items', 'required_services', 'supported_services')
->where(function ($query) {
$query->where('stm', 11)
->orWhere('stm', 17)
->orWhere('stm', 31);
})
->where('lifecycle_id', '!=', 12)
->where('type', 'Customer Facing')
->orderBy('service_full_name')
->get();
I don't really understand the report you are developing, but hopefully this helps you.

Laravel Eloquent - list of parent from a collection

I can get the list of Likes that User 1 did on a Media from Store 1
$medias = User::find(1)->likes()->with('media')->whereHas('media', function($q) {
$q->where('store_id', '=', 1);
})->get();
But i need to retrieve the list of medias, so i tried
$medias = User::find(1)->likes()->with('media')->whereHas('media', function($q) {
$q->where('store_id', '=', 1);
})->get()->media;
But then i get
Undefined property: Illuminate\Database\Eloquent\Collection::$media
class User extends Model
{
public function likes()
{
return $this->hasMany('App\Like');
}
}
class Media extends Model
{
public function store()
{
return $this->belongsTo('App\Store');
}
public function likes()
{
return $this->hasMany('App\Like');
}
}
class Like extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
public function media()
{
return $this->belongsTo('App\Media');
}
}
This is because you get media separate for each like. You should use:
$likes = User::find(1)->likes()->with('media')->whereHas('media', function($q) {
$q->where('store_id', '=', 1);
})->get();
foreach ($likes as $like) {
$media = $like->media;
// now you can do something with your media
}
EDIT
If you want to get only media, you should add to your User model the following relationship:
public function medias()
{
return $this->hasManyThrough('App\Media','App\Like');
}
Now to get your media, you should do :
$medias = User::find(1)->medias()->where('store_id', '=', 1)->get();
Made it work with
$store->medias()->whereHas('likes', function($q) use($user) {
return $q->where('user_id', '=', $user->id);
});

Laravel 4.1 eager loading

I'm having trouble on the eager loading.
Let's say I have models of Members, TrainingCategory, TrainingCategoryResult and Registration
Member Model:
public function registration() {
return $this->hasMany('Registration', 'member_id');
}
public function trainingResults(){
return $this->hasMany('trainingResult', 'member_id');
}
public function trainingCategoryResults() {
return $this->hasMany('TrainingCategoryResult', 'member_id');
}
TrainingCategory Model:
public function trainings() {
return $this->hasMany('Training', 'id');
}
public function trainingCategoryResults() {
return $this->hasMany('trainingCategoryResult', 'category_id');
}
TraningCategoryResult Model:
public function category() {
return $this->belongsTo('TrainingCategory', 'id');
}
public function member() {
return $this->belongsTo('Member', 'id');
}
Registration Model:
public function course() {
return $this->belongsTo('Course', 'course_id');
}
public function member() {
return $this->belongsTo('Member', 'id');
}
I am trying to eager load all the registration info and its related info including the TraningCategoryResult info but I not sure how to get that TraningCategoryResult which required two foreign keys (category_id and member_id), is there any way to do that?
Here is my code atm:
$members= Member::where(function($query) use ($id, $site) {
$query
->where('id', '=', $id)
->where('site', '=', $site);
});
$members= $members
->with('registration.course',
'registration.course.traningCategories',
->get(['member.id']);
Thank you.
This will not work Member::with('categoryResult')->with('registration')->get()
You can make a new relation in Member Model
public function categoryResult()
{
return $this->belongsTo('Category')->with('Registration');
}
//and then call
Member::with('categoryResult')->get();
You could use a few options to achieve that:
OPTION 1: create a variable relationship
Change your relation in the Member model
public function trainingCategoryResults($category_id = null) {
if(empty($category_id))
return $this->hasMany('TrainingCategoryResult', 'member_id');
else
return $this->hasMany('TrainingCategoryResult', 'member_id')
->where('category_id', $category_id);
}
The code above might have limitations and it doesn't take advantage of many laravel features, but it will work.
OPTION 2: Access from relationship
You can keep everything as is, and load as follow:
$members= Member::where(function($query) use ($id, $site) {
$query
->where('id', '=', $id)
->where('site', '=', $site);
})
->where('id', $member_id) // set the id of the memeber
->with(array(
'traningCategoryResults' => function($q)use($category_id){
$q->where('category_id', $category_id); // This makes sure you get only desired results
}
))
In this way you will have only what you need, assuming you know the $category_id

Categories