Laravel checking records from user - php

i have this controller created. This is where i get all the ads (avisos) created from the users.
class AdController extends Controller
{
public function index(Request $request)
{
$page = $request->get('page',1);
$perPage = 15;
$offset = ($page * $perPage) - $perPage;
$avisos = Ad::select(['id','user_id','title','content','created_at','moderated_at'])
->WithNotModerate()
->orderBy('moderated_at', 'asc')
->paginate(15);
if($request->has('user_id'))
$avisos = Ad::select(['id','user_id','title','content','created_at','moderated_at'])
->WithNotModerate()
->where('user_id','like','%'.$request->user_id.'%')
->orderBy('moderated_at', 'asc')
->paginate(15);
if ($request->ajax()) {
return view('admin.avisos.data', ['avisos' => $avisos])->render();
}
return view('admin.avisos.index', compact('avisos'));
}
And here is where they are all rendered in my blade view, all ads from all users.
#foreach ($avisos as $aviso)
<tr>
<td>{{$aviso->id}}</td>
<td>{{$aviso->user_id}}</td>
<td>{{str_limit($aviso->title, 40)}}</div></td>
<td>{{str_limit($aviso->content, 40)}}</div></td>
<td>{{$aviso->created_at->diffForHumans()}}</td>
<td>{{$aviso->moderated_at}}</td>
</tr>
#endforeach
I want to check if the user has more than one ad 'created_at' in the past 15 days so i can add a class to the table row
I tried something like this
#foreach ($avisos as $aviso)
<?php
$date = \Carbon\Carbon::today()->subDays(15);
$already = DB::table('ads')
->where('user_id','=','$aviso->user_id')
->where('created_at' ,'=', date($date))
->get();
var_dump($already);
?>
<tr>
<td>{{$aviso->id}}</td>
<td>{{$aviso->user_id}}</td>
<td>{{str_limit($aviso->title, 40)}}</div></td>
<td>{{str_limit($aviso->content, 40)}}</div></td>
<td>{{$aviso->created_at->diffForHumans()}}</td>
<td>{{$aviso->moderated_at}}</td>
</tr>
#endforeach
Returns
object(Illuminate\Database\Eloquent\Collection)#3073 (1) { ["items":protected]=> array(0) { } } for each ad...

You are using the date function incorrectly. First argument of date excepts a valid format in form of a string, what your giving is a Carbon instance.
But because you already have an instance of Carbon, you don't need to use date. Format the Carbon instance instead to match what you have in the database.
You are also checking user_id against the string $aviso->user_id instead of the actual variable value.
There is a difference between '$aviso->user_id' and $aviso->user_id. Remove the single quotes to get the expected value.
$date = \Carbon\Carbon::today()->subDays(15);
$already = DB::table('ads')
->where('user_id','=',$aviso->user_id)
->where('created_at' ,'=', $date->format('Y-m-d H:i:s'))
->get();

Related

Adding a variable into a custom table in Laravel

I have a table which is a combination of 3 tables being passed to my blade file.
$late_books = Borrow::join('books', 'borrows.book_id', '=', 'books.id')
->join('borrowers', 'borrows.borrower_id', '=', 'borrowers.id')
->where('borrows.late_return_status', '=', 1)
->where('borrows.return_date', '=', null)
->get(['borrowers.borrower_name', 'borrowers.IC', 'borrowers.phone_no' ,'books.ISBN', 'books.book_title', 'books.year','books.author', 'books.publisher_name',
'borrows.issue_date', 'borrows.due_date']);
Within the blade file, i need to add a button which has the fines.
$due_date = \Carbon\Carbon::parse($late_books->first()->due_date);
$today = \Carbon\Carbon::now();
$result = $due_date->diffInDays($today);
$fine = $result * 5;
The fine should be specific to each book borrowed, the current way ive done it shows same fine for all books.
return view('admin.latereturn', compact('late_books', 'search', 'fine'));
Im sure this question has been asked in some form before but im not exactly sure what to search. Sorry if it's a duplicate.
If i get you
you can Defining An Accessor for appending attribute inside your model as the following:
class Borrow extends Model
{
protected $appends = ['fine'];
public function getFineAttribute()
{
$due_date = \Carbon\Carbon::parse($this->due_date);
$today = \Carbon\Carbon::now();
$result = $due_date->diffInDays($today);
$fine = $result * 5;
return $fine;
}
}
and you can access fine attribute inside your blade as $model_instance->fine
#foreach($late_books as $lb)
<span> {{$lb->fine}} </span>
#endforeach
I hope this helpful for you

Laravel find in DB where('week', $week) and where('user_id', $user_id) to find id

i am creating an app, where users can start a challange to see who loses the most weight.
There is 1 challange table, with an id, user_id(fk), weight and week. To display them in the front end per week i made a new array.
UserController:
public function index()
{
$users = User::all();
// get all challanges descending
$challanges = Challange::orderBy('week', 'DESC')->get();
// make an array for every [week] that has an array with ['user' => 'weight'] in user_id order
$weightArray = array();
// how long is the list depending on amount of weeks
$startweek = 1;
$endweek = Challange::max('week');
// go through every week
for ($i = $startweek; $i <= $endweek; $i++) {
// get weight foreach user and if no value set 0
foreach ($users as $user) {
// get challange values per week
$challenge = $user->challanges()->where('week', '=', $i)->get();
// if there is a challange
if (count($challenge) > 0) {
// set a weight value for that user *!!FIX make weigt alue unique!!*
$weightArray[$i][$user->id] = $challenge[0]->weight;
}
else {
// set 0 if no weight isset
$weightArray[$i][$user->id] = 0;
}
}
}
return view('dashboard', compact('users', 'weightArray'));
}
When a user is logged in and presses update there is a form that gives hidden input Auth::user()->id and week. The weight the user has to input himself. This returns a request, but now i don't know how i can match the week and user_id, to find the id where the weight needs to be updated.
ChallangeController:
public function update(Request $request)
{
$week = $request->week;
$challange = Challange::find($request->user_id)->where('week', $week);
dd($challange);
}
This returns: Error Call to a member function where() on null
Should i add the id in the array upfront? Or do i where('user_id', $user_id) and do another where on an array that returns?
I don't know what to do. Can somebody please help?
Wrong order. You should :
$challange = Challange::where('week', $week)
->where('user_id', $request->user_id)
->first();
// or
$challange = Challange::where([
'week' => $week,
'user_id' => $request->user_id
])->first();

How to change time zome in different tables in Laravel

Can you give an idea?
I have two tables in to postgresql DB.
The are filled with recods by two separate csv files. But the records of the first csv file are with local timestamp. The second csv file is with timestamps UTC.
So I need to change the time in local of the view in this table that is filled with records with timezone UTC. I used to deal with that problem before using laravel with this code in every page that I need to do that, for example:
date_default_timezone_set('Europe/Sofia');
The controller:
function getdata_chart(Request $request)
{
$start_date = date('d-m-Y 00:00:00');
$end_date = date('d-m-Y 23:59:59');
if($request->start_date != '' && $request->end_date != '')
{
// if user fill dates
$dateScope = array($request->start_date ." 00:00:00", $request->end_date ." 23:59:59");
} else {
// default load page - today
$dateScope = array($start_date, $end_date);
};
$students = MeasCanal::whereBetween('recordtime', $dateScope)
->selectRaw('recordtime')
->selectRaw('max(formattedvalue) filter (where fullname = \'Данни.Кота\') as iazovir')
->selectRaw('max(formattedvalue) filter (where fullname = \'Данни.Температура\') as temperatura350')
->where(function ($query) {
$query->where('fullname', 'like', "Язовир.Данни.Кота")
->orWhere('fullname', 'like', "ГСК_11_350.Данни.Температура");
})
->groupBy('recordtime')
->orderBy('recordtime')
->get();
return response()->json($students);
}
return response()->json($students);
}
Update your Model MeasCanal and add the following :
Import and use :
use Carbon\Carbon;
Add Function :
/**
* Get the user's recordtime.
*
* #param string $value
* #return string
*/
public function getRecordtimeAttribute($value)
{
return Carbon::parse($value)->timezone('Europe/Sofia')->toDateTimeString();
}
I'm not sure this is what you want but i think you can get the idea.
First Method,
You can use accessor;
public function getCustomTimestampAttribute($value)
{
// you can use your logic here to set your timezone by table
$timezone = 'Europe/Sofia';
return Carbon::parse($this->custom_timestamp)->timezone($timezone)->toDateTimeString();
}
then you can get the value like: $model->custom_timestamp
Second Method,
You can use map;
$customDates = $dates->map(function ($date, $key) {
$date->custom_timestamp = Carbon::parse($date->custom_timestamp)->timezone('Europe/Sofia')->toDateTimeString();
return $date;
});
EDIT
In your model(MeasCanal) set recordtime attribute;
public function getRecordtimeAttribute($value)
{
// you can use your logic here to set your timezone by table
$timezone = 'Europe/Sofia';
return Carbon::parse($this->recordtime)->timezone($timezone)->toDateTimeString();
}
then you can simply see the result after the query in your controller like
dd($students);
or even simpler to see:
dd($students->first()->recordtime); // first matched rows recordtime attr.
Note: you cant use accessors with raw queries you should use eloquent models btw.

How use with() when also joining a table

I have the following tables (with only relevant fields):
devices
id
name
created_at
updated_at
device_reports
id
device_id
location
created_at
updated_at
I have a report with a number of filters on it that is already working, so I want to stick with the eloquent way of doing things. Here is Controller function:
public function devices(Request $request)
{
$devicesQuery = Device::with(['latestReport']);
if ($request->ajax())
{
if($request->input('start') && $request->input('start')!='')
{
$start_date = date('Y-m-d', strtotime($request->input('start')));
$end_date = date('Y-m-d', strtotime($request->input('end')));
$devicesQuery = $devicesQuery->lastReportBetween($start_date,$end_date);
}
$devices = $devicesQuery->paginate(10);
return Response::json(View::make('devices/table', array('devices' => $devices))->render());
}
}
The model's latestReport is defined as:
public function latestReport()
{
return $this->hasOne('App\Models\DeviceReport')->latest();
}
The model's function lastReportBetween is defined as:
public function scopeLastReportBetween($query, $start, $end)
{
$query = $query->join('device_reports AS dr', 'dr.device_id', '=', 'devices.id');
$query = $query->where('dr.id', '=', DB::raw('(SELECT max(dr2.id) FROM device_reports AS dr2 WHERE dr2.device_id = devices.id)'));
$query = $query->where(DB::raw("(IFNULL(dr.gps_time, dr.created_at))"), '>=', DB::raw("STR_TO_DATE('".$start."', '%Y-%m-%d')"));
$query = $query->where(DB::raw("(IFNULL(dr.gps_time, dr.created_at))"), '<=', DB::raw("STR_TO_DATE('".$end."', '%Y-%m-%d')"));
return $query;
}
When running the above with a start/end date selected, I get the correct records returned, but I don't get anything returned in "latestReport", but when I run the page without the date filters in place, it correctly returns the device information and the most recent report record in the latestReport class variable.
Can anyone help me understand how to change this code such that I do get the latestReport back when I also call the lastReportBetween function?
I figured out my problem. I should have been using "whereHas()" instead of manual joins and whatnot.
public function scopeLastReportBetween($query, $start, $end)
{
return $query->whereHas('latestReport', function($reportsQuery) use ($start, $end)
{
$reportsQuery->whereBetween('created_at', [$start, $end])
->where('device_reports.id', '=', DB::raw('(SELECT max(dr2.id) FROM device_reports AS dr2 WHERE dr2.device_id = device_reports.device_id)'));
});
}

The wrong record in my database is getting updated

im using laravel eloquent to update a record in a database table. Im passing in a parameter of 52 which is the id of the record I want to update (primary key).
I am printing the query to check which record its finding and its printing the record with the id of 13 and then when i check the table, id 13 has been updated.
protected $connection = 'sqlsrv';
protected $table = 'todo';
public $timestamps = false;
public static function complete($todoId, $userId)
{
$now = new DateTime();
$query = Self::join('todoTypes', 'todo.typeId', 'todoTypes.id')
->where('todoTypes.canComplete', 1)
->whereNull('todo.completedDate')
->find(52);
$query->where(function ($query) use ($now)
{
$query->whereNull('cancelDate')
->orWhere('cancelDate', '>', $now);
});
if ($query)
{
$query->completedDate = $now;
$query->save();
}
}
How about trying like this?
The query after using find did not make any sense since find returns the first object not a query builder instance.
public static function complete($todoId, $userId)
{
$now = new DateTime();
$object = Self::join('todoTypes', 'todo.typeId', 'todoTypes.id')
->where('todoTypes.canComplete', 1)
->whereNull('todo.completedDate')
->where(function ($query) use ($now) {
$query->whereNull('cancelDate')
->orWhere('cancelDate', '>', $now);
})->find(52);
if ($object) {
$object->completedDate = $now;
$object->save();
}
}
I have managed to fix this by just adding a select at the start
select('todo.id', 'todo.completedDate')
It seems it was getting the right row, but displaying the id as something else.
When I took out the join and the joins where clause, it worked. I suspect it was using the id of the joint row from the todoTypes table as that was 13.

Categories