Check if token expired in Laravel - php

I have table tokens with columns: user_id, token, expires_at.
Example:
I have token: 12345, for me, and he expires at: 2018-06-05
When I generate new token, I generate up to 7 days..
How I can check this in model?
I tryied do with scope in model:
public function scopeExpired($query) {
return $this->where('expires_at', '<=', Carbon::now())->exists();
}
But not working. Always false..

I've always done stuff like this the following way. Note that you need the expires_at field as an attribute on your model.
// Probably on the user model, but pick wherever the data is
public function tokenExpired()
{
if (Carbon::parse($this->attributes['expires_at']) < Carbon::now()) {
return true;
}
return false;
}
Then from wherever you can call:
$validToken = $user->tokenExpired();
// Or realistically
if ($user->tokenExpired()) {
// Do something
}

Related

Laravel : Condition on route

I have an application using Laravel in backend.
In web.php, I'm defining the following route :
Route::get('/customize/{id}', function () {
if (Profile::where('user_id', User::find(4))) {
return true;
}
return false;
});
Basically I want for example when user_id = 4, return true. {id} is the id of the profile. So if the profile has as user_id of 4, the link will return true, else it's false.
For some reason whatever the value I'm setting in user::find() it returns true.
Example of the profile table :
Try this code:
Route::get('/customize/{id}', function () {
if (Profile::where('user_id', User::find(4))->first()) {
return true;
}
return false;
});
By adding first() you will select only one record or null, the result will be true or false.
Try it first
Hope it will helps
You write a subquery which is User::find(4) it will give you an collection object and in your main query you need to check is it exit or not with where condition. So from you need to get id from from your object User::find(4)->id then it can match with user_id;
Route::get('/customize/{id}', function () {
if (Profile::query()->where('user_id','=', User::query()->find(1)->id)->exists()) {
return 'true';
}
return 'false';
});
I just like to add, that Route::fallback() only handles the GET method:
public function fallback($action)
{
$placeholder = 'fallbackPlaceholder';
return $this->addRoute(
'GET', "{{$placeholder}}", $action
)->where($placeholder, '.*')->fallback();
}
If you want to build a fallback for any other HTTP method, than you would have to use an other way:
Route::any('{fallbackPlaceholder}', $action)->where(
'fallbackPlaceholder', '.*'
)->fallback();

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 relationship count()

I want to get a total user transaction (specific user) with relationship.
I've done it but i'm curious is my way is good approach.
//User Model
public function Transaction()
{
return $this->hasMany(Transaction::class);
}
//Merchant Model
public function Transaction()
{
return $this->hasMany(Transaction::class);
}
public function countTransaction()
{
return $this->hasOne(Transaction::class)
->where('user_id', Request::get('user_id'))
->groupBy('merchant_id');
}
public function getCountTransactionAttribute()
{
if ($this->relationLoaded('countTransaction'))
$this->load('countTransaction');
$related = $this->getRelation('countTransaction');
return ($related) ? (int)$related->total_transaction : 0;
}
//controller
$merchant = Merchant::with('countTransaction')->get();
What make me curious is part inside countTransaction. I put where where('user_id', Request::get('user_id')) directly inside the model.
is it good approach or any other way to get specific way?
expected result:
"merchant:"{
"name": "example"
"username" : "example"
"transactions": {
"count_transactions: "4" //4 came from a specific user.
}
}
I need to get the merchant data with the transaction count for specific user. This query is based on logged in user. so when a user access merchant page, they can see their transaction count for that merchant.
Thanks.
You really want to keep request data outside of your models (instead opting to pass it in). I'm also a little confused about why you have both a 'hasOne' for transactions, and a 'hasMany' for transactions within the merchant model.
I would probably approach the problem more like the below (untested, but along these lines). Again I'm not fully sure I understand what you need, but along these lines
// Merchant Model
public function transactions()
{
return $this->hasMany(Transaction::class);
}
public function countTransactionsByUser($userId)
{
return $this
->transactions()
->where('user_id', $userId)
->get()
->pluck('total_transaction')
->sum();
}
// Controller
$userId = request()->get('user_id');
// ::all() or however you want to reduce
// down the Merchant collection
//
$merchants = Merchant::all()->map(function($item, $key) {
$_item = $item->getAttributes();
$_item['transactions'] = [
'count_transactions' => $item->countTransactionsByUser($userId);
];
return $_item;
});
// Single total
// Find merchant 2, and then get the total transactions
// for user 2
//
$singleTotal = Merchant::find(2)
->countTransactionsByUser($userId);

Laravel Eloquent: Append queries

Is it possible to "append" queries in Laravel?
For example like so in this example code:
function crunchNumbersForToday()
{
return $this->crunchSomeInformationInRange(Payments::where('created_at', Carbon::now()));
}
function crunchNumbersInRange($range)
{
$paymentsToCrunch = Payment::where('state', 'payed')->append($range)->get();
// Work with the payments
}
So in this case the where of the created_at field would be appended to the query where state equals payed. Which would make something like: where created_at = '2015-07-08 12:00' AND state = payed.
I think you could create a scope.
For your code that would be (in your Payment model):
function scopeToday($query)
{
return $query->where('created_at', Carbon::now());
}
function scopeNumbersInRange($query)
{
return $query->where('state', 'payed');
// Work with the payments
}
And then call it elsewhere in your code like:
Payment::numbersInRange()->today()->get();
Edit:
You can make them dynamic too:
function scopeDate($query, $date)
{
return $query->where('created_at', $date);
}
...
Payment::numersInRange()->date(Carbon::now())->get();
And so on. This way you can keep chaining scopes.

Protect routes dynamically, based on id (laravel, pivot table)

This topic has been discussed a lot here, but I don't get it.
I would like to protect my routes with pivot tables (user_customer_relation, user_object_relation (...)) but I don't understand, how to apply the filter correctly.
Route::get('customer/{id}', 'CustomerController#getCustomer')->before('customer')
now I can add some values to the before filter
->before('customer:2')
How can I do this dynamically?
In the filter, I can do something like:
if(!User::hasAccessToCustomer($id)) {
App::abort(403);
}
In the hasAccessToCustomer function:
public function hasCustomer($id) {
if(in_array($id, $this->customers->lists('id'))) {
return true;
}
return false;
}
How do I pass the customer id to the filter correctly?
You can't pass a route parameter to a filter. However you can access route parameters from pretty much everywhere in the app using Route::input():
$id = Route::input('id');
Optimizations
public function hasCustomer($id) {
if($this->customers()->find($id)){
return true;
}
return false;
}
Or actually even
public function hasCustomer($id) {
return !! $this->customers()->find($id)
}
(The double !! will cast the null / Customer result as a boolean)
Generic approach
Here's a possible, more generic approach to the problem: (It's not tested though)
Route::filter('id_in_related', function($route, $request, $relationName){
$user = Auth::user();
if(!$user->{$relationName}()->find($route->parameter('id')){
App::abort(403);
}
});
And here's how you would use it:
->before('id_in_related:customers')
->before('id_in_related:objects')
// and so on

Categories