my first query that gets all rows that contain both the user who requested friendship ( authenticated user id ) and inbound friendship ( inbound user id ). This works if I echo $rowsget, it echos the correct rows, the problem I'm having is that it will only loop through up to two usernames, once I take away the ability for it to loop through the profiles own username it will only loop through one row then stop, I have tried what some people have said to do but it now says this error message when I try to load the profile page, "Object of class Illuminate\Support\Collection could not be converted to int" Here is the code, any help is appreciated, I have been stuck on this for hours now.
Query
$rowsget = DB::table('friends')->where(function(Builder $query) use($uid) {
$query->where('requesteeid', $uid)
->orWhere('inboundid', $uid);
})
->where('approved', true)
->get();
$rowfetchfriend = [];
if(count($rowsget) > 0){
foreach($rowsget as $get) {
$getrequestee = $get->requesteeid;
$getinbound = $get->inboundid;
$rowfetchfriend += DB::table('users')->where('id', $getrequestee)-
>orWhere('id', $getinbound)->get(['id', 'avatar', 'username']);
}
Loop through usernames
foreach($rowfetchfriend as $loop) {
if($loop->id != $uid) { //make sure own user isnt displayed
echo $loop->username; // echo all usernames that are
}
}
}
Use this method (or the push() method) when adding to an array:
Instead of this:
$rowfetchfriend += DB::table('users')->where('id', $getrequestee)->orWhere('id', $getinbound)->get(['id', 'avatar', 'username']);
Try this:
$rowfetchfriend[] = DB::table('users')->where('id', $getrequestee)->get(['id', 'avatar', 'username']);
$rowfetchfriend[] = DB::table('users')->where('id', $getinbound)->get(['id', 'avatar', 'username']);
The class and its methods are listed here:
https://laravel.com/api/5.5/Illuminate/Support/Collection.html#method_count
You can use "push" method of laravel collection.
try this :
$rowfetchfriend = [];
if(count($rowsget) > 0) {
foreach($rowsget as $get) {
$getrequestee = $get->requesteeid;
$getinbound = $get->inboundid;
$temp = DB::table('users')->where('id', $getrequestee)->orWhere('id', $getinbound)->get(['id', 'avatar', 'username']);
array_push($rowfetchfriend, $temp->toArray());
}
}
and Loop through usernames :
for ($i=0; $i < count($rowfetchfriend); $i++) {
if($rowfetchfriend[$i][0]->id != $uid) { //make sure own user isnt displayed
echo $rowfetchfriend[$i][0]->username; // echo all usernames that are
}
}
I tested it and work correctly.
Related
I'm trying to create a pagination in my search result. I have one queries in my repository like:
public function getFilteredVehicles($id,$pax,$categories,$search_type,$from_date,$to_date)
{
$vehicles = Vehicle::whereHas('destinations', function($q) use($id){
$q->where('destination_id',$id)
->where('active',1);
})
->paginate(1);
if($search_type == 'disposal' || $search_type == 'pnd')
{
$vehicles = $vehicles->where('registered_location',$id);
}
if($categories)
{
$vehicles = $vehicles->where('vehicle_categoryid',$categories);
}
return $vehicles;
}
The returned result again needs to be processed via loop like:
public function calculateLocationAmount($vehicles,$fdate,$tdate,$destination_id)
{
$datetime1 = new DateTime($fdate);
$datetime2 = new DateTime($tdate);
$interval = $datetime1->diff($datetime2);
$days = $interval->format('%a');
$days = $days+1;
$nights = $days-1;
foreach ($vehicles as $key => $vehicle) {
# code...
$perday_rate = $vehicle->destinations->where('id',$destination_id)->first()->pivot->day_rate;
$pernight_rate = $vehicle->destinations->where('id',$destination_id)->first()->pivot->night_rate;
$day_rate = $perday_rate * $days;
$night_rate = $pernight_rate * $nights;
$total_amount = $day_rate + $night_rate;
$vehicle['total_amount'] = $total_amount;
$vehicle['availability'] = 'true';
if($vehicle->whereHas('unavailability', function($q) use($fdate,$tdate){
$q->whereRaw("? BETWEEN `from_date` AND `to_date`", [$fdate])
->orwhereRaw("? BETWEEN `from_date` AND `to_date`", [$tdate]);
})->count()>0){
$vehicle['availability'] = 'false';
}
}
return $vehicles;
}
This final result needs to be paginated. How can i do it?
Using foreach is changing the value to collection due to which links is not working. If i don't do paginate() or get(), for loop is not executed.
Kindly help.
You can paginate your initial query just as you have, then loop over the pagination object as if it was your regular collection or use $pagination->items()
You should also use nested with('relation') in your initial query to stop N+1 queries https://laravel.com/docs/8.x/eloquent-relationships#constraining-eager-loads
In a Laravel app, I'm trying to implement a structure where posts are fetched that have one or more of the tags that the user has access to. I wrote the code below to do that:
$query = new Posts();
if (count(Auth::user()->tags) > 0) {
$query = $query->whereHas('tags', function ($q) {
$i = 0;
foreach (Auth::user()->tags as $tag) {
if ($i == 0) {
$q->where('title', '=', $tag->title);
} else {
$q->orWhere('title', '=', $tag->title);
}
$i++;
}
});
}
$posts = $query->where('isTemplate', true)->orderBy($key, $order)->paginate(15);
This works, but feels off. So I'm wondering if there's a better way to do this?
#user4992124, Will this help you.
$query = Posts::query()
->where('isTemplate', true)
->orderBy($key, $order);
if (Auth::user()->tags->isNotEmpty()) {
$tags = Auth::user()
->tags
->pluck('title')
->toArray();
$query = $query->whereIn('tags', $tags);
}
$posts = $query->paginate(15);
I have coded a internal messenger system for the company I work for and I am trying to make things easier for myself by making a admin panel for this so it can control the usernames, passwords and groups.
Basically I am trying to select a user from the array using a url ?user=username which will then return the user information and allow it to be changed. The problem I am having is to get the url to select the username in the array.
The array is basic:
$users = array(
'0' => array(
'username' => 'test',
'password' => 'test123',
'group' => 'office',
),
Like this?:
<?php
// get username from URL (GET METHOD)
$username=$_GET["username"];
// $users has all the info
foreach ($users as $u) {
// find the target user
if ($u["username"] == $username) {
// do something with $u
var_dump($u);
}
}
?>
Did you tried to do this:
$user_name = $users[0]["username"];
Try this (not tested)
$u = null;
foreach($user as $user) {
if(isset($_GET['user']) && $user['username'] == $_GET['user']) {
$u = $user;
}
}
$u variable should contains yours user record.
Since it's an array i assume you have multiple indexes. I guess a simple 'find' function might work.
function findUser($searchData, $users, $searchField) {
$retObj = array();
foreach ($users as $user) {
if (isset($user[$searchField]) && $user[$searchField] == $searchData) {
$retObj['username'] = $user['username'];
$retObj['password'] = $user['password'];
$retObj['group'] = $user['group'];
break;
}
}
return $retObj;
}
EDIT: Added searchField so u can do same for password and group. Searchdata is the value u are searching
I have the following code:
$main = Main::with(['clients', 'events.orderitems' => function($query) {
$query->whereIn('order_id', function($query) {
$query->select('id')->from('orders')->where('orderPaid', 1)->orWhere('orderStatus', 3);
});
}])->where('id', $id)->first();
foreach($main->events as $dates) {
$all_paid = 0;
$all_pending = 0;
foreach($dates->orderitems as $item) {
if($item->orderPaid == 1) {
$all_paid = $all_paid + $item->quantity;
}
}
$dates->orderscount = $all_paid;
foreach($dates->orderitems as $item) {
if($item->orderStatus == 3) {
$all_pending = $all_pending + $item->quantity;
}
}
$dates->pendingcount = $all_pending;
}
Is there maybe an MYSQL way to Count the PAID orders and the orders with orderStatus == 3 in the SQL? I think, how I am doing it, it's way to messy and not very good for the performance.
So a "Main" has n-events which have n-orderItems.
I need to get to a "Main" Event, all the Events with all PAID and orderStatus == 3 items. How can I do that?
UPDATE - SOLUTION:
foreach($main->events as $dates) {
$dates->orderscount = OrderItems::where('events_id',$dates->id)->whereHas('orders', function($q) {
$q->where('orderPaid', 1);
})->sum('quantity');
$dates->pendingcount = OrderItems::where('events_id',$dates->id)->whereHas('orders', function($q) {
$q->where('orderStatus', 3);
})->sum('quantity');
}
Laravel has an aggregate method which does just that.
The same way you are using first to only get the first result of a query as in:
)->where('id', $id)->first();
to get the count you could use count()
DB::table('orders')->where('orderPaid', 1)->orWhere('orderStatus', 3)->count();
If you need the sum() of the products and not the count as in your title, you could for your particular example use:
$total_quantity = DB::table('orders')->where('orderPaid', 1)->orWhere('orderStatus', 3)->sum('quantity');
UPDATE:
As in your example to get both counts you would change you foreach to be something similar to:
foreach($main->events as $dates) {
$all_paid = DB::table('orders')->where('order_id',$dates->id)->where('orderPaid', 1)->count();
$all_pending = DB::table('orders')->where('order_id',$dates->id)->where('orderStatus', 3)->count();
$dates->orderscount = $all_paid;
$dates->pendingcount = $all_pending;
}
You can use sum() with your eloquent query in laravel. Check under the #Aggregates section here:
http://laravel.com/docs/4.2/queries
How to print certain properties in the model while returning data to user
I have Users model , which has Username, Password, Email
I can get all users username, email
Now i need to send Username and email to user
while trying to send data to the user as json from the following code
$models = Users::model()->findAll($criteria);
if(is_null($models)) {
$this->_sendResponse(200, sprintf('No users found'));
} else {
$rows = array();
foreach($models as $model)
{
$Users[] = $model->attributes;
}
$SandboxObj->_sendResponse(200, CJSON::encode($Users));
}
It shows like [{"Username":"foo","Email":"foo#foo.com","Password":"null"}]
I need to send like [{"Username":"foo","Email":"foo#foo.com"}]
How to do this in yii?
I know this question is already been answered and accepted but i do not like to teach people the lazy way of coding. there for, as a correction on Alireza Fallah's answer:
$models = Users::model()->findAll($criteria);
if(is_null($models)) {
$this->_sendResponse(200, sprintf('No users found'));
} else {
$userData = array();
foreach($models as $model)
{
$tempData = new StdClass;
$tempData->Username = $model->Username;
$tempData->Email= $model->Email;
$userData[] = $tempData;
}
$SandboxObj->_sendResponse(200, CJSON::encode($userData));
}
or as said before only query what you need in the first place, then you can be lazy all you want in the rest of your code.
Edit: another way of doing the foreach with less resources is :
foreach($models as &$model)
{
$tempData = new StdClass;
$tempData->Username = $model->Username;
$tempData->Email= $model->Email;
$model = $tempData;
}
and then you can use $models in stead of $userData
Do this :
$models = Users::model()->findAll($criteria);
if(is_null($models)) {
$this->_sendResponse(200, sprintf('No users found'));
} else {
$rows = array();
foreach($models as $model)
{
unset($model->attributes['Password']); //add this line
$Users[] = $model->attributes;
}
$SandboxObj->_sendResponse(200, CJSON::encode($Users));
}
Or simply don't select Password field in your query if you don't need it .