Compare laravel query results - php

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;
}

Related

Laravel get conversation where users in array

I am making a messaging app, and i need to check if a conversation already exists that has a certain list of users (no more, no less). I have this model:
class Conversation{
public function users(){
return $this->belongsToMany('App\User');
}
public function messages(){
return $this->hasMany('App\Message');
}
}
I have these tables:
conversations:
id
user_id <- the owner of the conversation
users:
id
email
password
conversation_user:
id
conversation_id
user_id
I want to make a post request like this:
{
"users": [1,4,6], <- user ids
"message": "Some message"
}
If a conversation already exists with all and only users 1,4,6, the message should be added to that conversation to avoid having duplicate conversations in the database. Otherwise i will make a new conversation with the specified users.
This is the best i have been able to do so far:
$existing_conversation = $user->conversations()->whereHas('users',
function($query) use ($data){
$query->whereIn('user_id', $data['users']);
}
)->has('users', '=', count($data['users']));
But it just returns the conversations that has exactly the amount of users that was in the users array. It ignores the inner query..
Does anyone have an idea for this? :)
You can try the following query
$existing_conversation = $user->conversations()->wherePivotIn('user_id', $data['users'])->has('users', count($data['users'])->get();
Haven't tested, should work I think.
UPDATE
Not a very elegant solution, however it works. You can add some helper methods in your controller like
//Get user's conversations with no of users equal to count($data['users']);
protected function get_conversations_with_equal_users(User $user, array $user_ids)
{
return $user->conversations()
->wherePivotIn('user_id', $user_ids)
->has('users', '=', count($user_ids))
->get();
}
//Get the id of a user conversation with exactly same users as $data['users'] if it exists otherwise it will return 0;
protected function get_existing_conversation_id(User $user, array $user_ids)
{
$existing_conversation_id = 0;
$user_conversations_with_equal_users = $this->get_conversations_with_equal_users($user, $user_ids);
foreach($user_conversations_with_equal_users as $conv)
{
$ids = [];
foreach($conv->users as $user)
{
$ids[] = $user->id;
}
if($this->array_equal($user_ids, $ids))
{
$existing_conversation_id = $conv->id;
}
}
return $existing_conversation_id;
}
//Function to compare two arrays for equality.
protected function array_equal($a, $b) {
return (
is_array($a) && is_array($b) &&
count($a) == count($b) &&
array_diff($a, $b) === array_diff($b, $a)
);
}
The you can use the following in your controller to get the existing conversation for user (if it exists)
$existing_conversation_id = $this->get_existing_conversation_id($user, $data['users']);
if($existing_conversation_id)
{
$existing_conversation = Conversation::with('users')
->whereId($existing_conversation_id)
->get();
}

Laravel - query depending on user

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();

Laravel - Multi fields search form

I'm builind a form with laravel to search users, this form has multiple fields like
Age (which is mandatory)
Hobbies (optional)
What the user likes (optional)
And some others to come
For the age, the user can select in the list (18+, 18-23,23-30, 30+ etc...) and my problem is that i would like to know how i can do to combine these fields into one single query that i return to the view.
For now, i have something like this :
if(Input::get('like')){
$users = User::where('gender', $user->interested_by)->has('interestedBy', Input::get('like'))->get();
if(strlen(Input::get('age')) == 3){
$input = substr(Input::get('age'),0, -1);
if(Input::get('age') == '18+' || Input::get('age') == '30+' )
{
foreach ($users as $user)
{
if($user->age($user->id) >= $input){
$result[] = $user;
// On enregistre les users étant supérieur au if plus haut
}
else
$result = [];
}
return view('search.result', ['users' => $result]);
}
elseif (strlen(Input::get('age')) == 5) {
$min = substr(Input::get('age'), 0, -3);
$max = substr(Input::get('age'), -2);
$result = array();
foreach($users as $user)
{
if($user->age($user->id) >= $min && $user->age($user->id) <= $max)
$result[] = $user;
}
return view('search.result', ['users' => $result]);
}
}
else
$users = User::all();
And so the problem is that there is gonna be 2 or 3 more optional fields coming and i would like to query for each input if empty but i don't know how to do it, i kept the age at the end because it's mandatory but i don't know if it's the good thing to do.
Actually this code works for now, but if i had an other field i don't know how i can do to query for each input, i know that i have to remove the get in my where and do it at the end but i wanna add the get for the last query..
Edit: my models :
User.php
public function interestedBy()
{
return $this->belongsToMany('App\InterestedBy');
}
And the same in InterestedBy.php
class InterestedBy extends Model{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'interested_by';
public function users()
{
return $this->belongsToMany('App\User');
}
}
you can use query builer to do this as follow
$userBuilder = User::where(DB::raw('1')); //this will return builder object to continue with the optional things
// if User model object injected using ioc container $user->newQuery() will return blank builder object
$hobbies = Request::input('hobbies') // for laravel 5
if( !empty($hobbies) )
{
$userBuilder = $userBuilder->whereIn('hobbies',$hobbies) //$hobbies is array
}
//other fields so on
$users = $userBuilder->get();
//filter by age
$age = Request::input('age');
$finalRows = $users->filter(function($q) use($age){
return $q->age >= $age; //$q will be object of User
});
//$finalRows will hold the final collection which will have only ages test passed in the filter
A way you could possible do this is using query scopes (more about that here) and then check if the optional fields have inputs.
Here is an example
Inside your User Model
//Just a few simple examples to get the hang of it.
public function scopeSearchAge($query, $age)
{
return $query->where('age', '=', $age);
});
}
public function scopeSearchHobby($query, $hobby)
{
return $query->hobby()->where('hobby', '=', $hobby);
});
}
Inside your Controller
public function search()
{
$queryBuilder = User::query();
if (Input::has('age'))
{
$queryBuilder ->searchAge(Input::get('age'));
}
if (Input::has('hobby'))
{
$queryBuilder->searchHobby(Input::get('hobby'));
}
$users= $queryBuilder->get();
}

How to submit data to multiple tables in the same form

I have 2 tables: listings and listings_specifications
Listings table
id
type
status
location
specifications_id
Listings_specifications table
id
listing_id
swimming_pool
water_well
I need to select the specifications (checkboxes) on the same form with which I add a listing. I have created all the forms, views, models, controllers but I think I got some logic wrong.
Listing.php model
protected $table = 'listings';
public function contact()
{
return $this->BelongsTo('contacts');
}
public function specifications()
{
return $this->BelongsTo('listings_specifications');
}
Specification.php model
protected $table = 'listings_specifications';
public function listings()
{
return $this->BelongsTo('listings');
}
ListingsController.php (where the data gets saved in the database)
$listing = new Listing;
$contact = new Contact;
$listing->status = Input::get('status');
$listing->listingfor = Input::get('listingfor');
$listing->propertystatus = Input::get('propertystatus');
$listing->propertytype = Input::get('propertytype');
$listing->userid = Auth::user()->id;
$listing->location = Input::get('location');
$listing->contact_id = $contact_id;
$listing->save();
$specifications = Specification::find($id);
if( $listings->save() ) {
$specifications = new Specification;
$specifications->listing_id = $id;
$specifications->swimming_pool = Input::get('swimming_pool');
$specifications->water_front = Input::get('water_front');
$specifications->save();
}
I'm getting this error: Undefined variable: id
Where did I go wrong?
Thank you
It looks like you have some logic errors.
First of all, you are never setting $id anywhere, but that's okay because you really don't need it.
Remove the $specifications = Specification::find($id); line because that's not doing anything.
Then change your last section to something like this...
if( $listings->save() ) {
$specifications = new Specification;
$specifications->swimming_pool = Input::get('swimming_pool');
$specifications->water_front = Input::get('water_front');
$listing->specifications()->save($specifications);
}
$listing->specifications()->save($specifications); will automatically save the new specification with the correct listing_id for you.
Modify your Listing model's specifications relationship to...
public function specifications()
{
return $this->hasMany('Specification');
}
I'm assuming here one listing can have many specifications. If not, you can easily just change that to a hasOne.
You use $id in the line $specifications = Specification::find($id); but you don't define it before.

How to reroute to another view when a resource doesn't exist in a table (Laravel 4)

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());
}

Categories