Can we pass null to laravel resource - php

I have InitResource that return basic data like some app data like app name etc..
Now if user is logged in, I return resource with user data or without user data, but when the user is null or auth()->user() is null, I get some error:
Cant return id of null
public function __get($key)
{
return $this->resource->{$key};
}
And when user is logged it works like it should.
Logically I am trying to return resource without data, but can I use it with some "default values" ?
In resource I am checking:
$data = [
'appName' => config('app.name'),
'locale' => app()->getLocale(),
];
if($this->hasRole('basic')) {
$data['user'] = $this->only(['username', 'fullname', 'avatar']);
}
return $data;
Can this be done in resource? With passed null? Thanks

Related

Laravel 8: Checking user's data with database table does not work properly

I have created a two factor authentication system, and it redirects user to token.blade.php where he must enters the token that is going to be sent to his phone number and also stored at active_codes table.
Now I want to check if the user has entered the same token code that was stored at active_codes table which looks like this:
And then at the Controller, I tried this:
public function submit(Request $request)
{
$data = $request->validate([
'token' => 'required|min:6'
]);
if($data['token'] === auth()->user()->activeCode()->code){
dd('same');
}
}
But when I enter the same token, I get this error:
ErrorException Undefined property:
Illuminate\Database\Eloquent\Relations\HasMany::$code
so my question is how to check if the requested token code of user, is as same as the token code which is stored on the DB ?
Note: The relationship between User and ActiveCode Models is OneToMany.
User.php:
public function activeCode()
{
return $this->hasMany(ActiveCode::class);
}
ActiveCode.php:
public function user()
{
return $this->belongsTo(User::class);
}
Your solution is pretty easy, you are not doing ->first() or ->get(), so you are trying to access a model property on a HasMany class.
This code should be similar to:
auth()->user()->activeCode()->first()->code
But if you have more than 1 code, then you should do something like:
public function submit(Request $request)
{
$data = $request->validate([
'token' => 'required|min:6'
]);
if(auth()->user()->activeCode()->where('code', $data['token'])->exists()){
dd('same');
}
}

Eloquent query returns wrong data when when using union

I have in my code a union between public data and user specific data. What I want to achieve is that if there is no user logged in, I return data which public is true. In case that I have a user, I make another query where user_id is the logged in user. Everything works until I want to get a specific data id of a user that I shouldn't be allowed.
For example I have the data:
[
'id' => 1,
'user_id' => 1,
'public' => true,
],
[
'id' => 2,
'user_id' => 1,
'public' => false,
],
My current code:
public function getQuery() : Builder
{
$publicData = $this->model->where('public', true);
// $this->user is passed thought another method which is $request->user() result.
if (!isset($this->user)) {
return $publicData;
}
if ($this->user->isAdmin()) {
return $this->model->newQuery();
}
return $this->model
->where('user_id', $this->user->id)
->union($publicData);
}
Now we assume that $this->user->id is 10 and I try to fetch data that I am not allowed by id.
$data = $this->getQuery()
->where('id', 2)
->first();
In this situation, always the first public data, which in this case is id 1 will be returned and I expect to receive null.
I am not sure how to find a solution for this and I am not sure what am I missing. Currently I use Laravel 6
Potential problem in your code, it is using one query for union and result query.
You can try check this:
public function getQuery() : Builder
{
// HERE ADDED newQuery
$publicData = $this->model->newQuery()->where('public', true);
// $this->user is passed thought another method which is $request->user() result.
if (!isset($this->user)) {
return $publicData;
}
if ($this->user->isAdmin()) {
return $this->model->newQuery();
}
return $this->model
->where('user_id', $this->user->id)
->union($publicData);
}
But you recommend simplify your query, without using union, because union is unnecessary here, to example:
public function getQuery() : Builder
{
$query = $this->model->newQuery();
if ($this->user->isAdmin()) {
return $query;
}
return $query->where(function ($builder) {
$builder->where('public', true);
if (isset($this->user)) {
$builder->orWhere('user_id', $this->user->id);
}
});
}
In Laravel you get the logged in user id by auth()->id(). It seems you are trying to filter the results by the eloquents’ attached users, which will obviously return true for every row.

Redirect user to fill attributes if null

I am wanting to create a redirect feature as it stands right now my current function in my auth controller is if a film doesn't exist then it redirects to the page to create one. But I am wanting to change this now as this route is no longer needed. What I need instead is if a USER doesn't have an age or gender configured/set it redirects them to the user page /user with the new route name as user_update
Current function:
private function redirect(): RedirectResponse
{
if (!$this->user->film()->exists()) {
return redirect()->route('film_create');
}
return redirect()->route('home');
}
user model: the fields are set as constants with an array of values at the top of the model, e.g types of gender, age range
protected $fillable = [
'id',
'age',
'gender',
];
do you know how i can modify the function above to create an IF statement to check if these fields are set for the user or not if not redirect them to the /user page?
having trouble trying to find resources on how to do this.
I am now writing a test for this function but having a little trouble on doing it..
this is the current test
/**
* #test
* Create mocked user, send them to user page and assert they exists in database
*/
public function it_creates_user_on_redirect()
{
$email = 'foo#bar.com';
$this->mockSocialite($email);
$this->get(route('auth_callback'))
->assertLocation(route('film_create'));
$this->assertDatabaseHas('users', [
'email' => $email,
]);
}
How do i go about modifying this test to ensure that it covers the new function ? #Saly 3301
Should be straightforward
private function redirect(): RedirectResponse
{
if ($this->user->age || $this->user->gender) {
return redirect()->route('home');
}
return redirect()->route('user_update');
}
And here's the boolean logic in tinker
>>> NULL || NULL
=> false
>>> 25 || NULL
=> true
>>> NULL || 'female'
=> true
>>> 25 || 'female'
=> true
Hope this helps
Should be:
private function redirect(): RedirectResponse{
if (!($this->user->age && $this->user->gender)) {
return redirect()->route('user_update');
}
return redirect()->route('home');
}
Only if both fields are configured, you are redirected to 'home'

get the data of latest upload from created_at column

Below is my function in my controller.
public function getUserTimesheet($userId)
{
$user = User::find($userId);
if($user) {
$userTimesheets = $user->userTimesheets->where('created_at', '>=', Carbon::now()->month());
return response()->json([
"status" => true,
"data" => [
"user-timesheets" => $userTimesheets
]
], 200);
}
return response()->json([
"status" => false,
"message" => "User not found"
], 401);
}
I did create model for the same function.
Multiple timesheets will be uploaded for the same user but I want to return the data of latest upload. I have crated_at column in my respective database and want to compare it to get latest timesheet information by comparing months.
I am getting an error of call to a member function where() on null.
Am new to laravel and creating APIs. Thank you.
The error suggests that the userTimesheets relationship on the particular user is null. Check whether the user has any timesheets, if they have any check how the userTimesheets relationship is defined.

ROUTE PARAMETER DISAPPEAR AFTER SAVE DATA

Hi everyone I need help with this problem. I am programming an application using php with laravel framework. My current laravel framework version is 4.2.11
I have this route to handle POST & GET actions
Route::any("/myaccount2/ausersave/{code?}", array("as" => "ausersave",
"uses" => "PrivateController#ausersave"))->before('auth_admin');
When I use Get action with mydomain/myaccount2/ausersave/90
I get list all data ok. But when I post all data to save the url change to mydomain/myaccount2/ausersave (parameter 90 is missing)
I guest this change is before the data is saved because the {code?} or 90 parameter is missing.
So I was looking for a function that allowed my application to post data and keeps the old url (mydomain/myaccount2/ausersave/90)
I find this function Redirect::back() but some post don't recommend to use it
I will apreciate your help. Thanks
My controller function is:
public function ausersave($code = 'null') {
$messg = null;
if(Input::get("userid") != null && Input::get("personid") != null) {
return View::make('PrivateController.ausersave', array('message' =>'Ok',
'user' => null, 'children' => null));
}
else if(isset($code)) {
return View::make('PrivateController.ausersave',
$this->ausersaveGet($code) );
}
return View::make('PrivateController.ausersave',
array('message' => '', 'user' => null,
'children' => null));
}
$this->ausersaveGet($code) -> this function bring me data form database and return me an array with thosse values array('message' => '', 'user' => $user, 'children' => $children); where user has info about user and children is an array of data. All this data return ok.
I would try taking the the ? out of the route parameter. i.e. change this:
Route::any("/myaccount2/ausersave/{code?}", array(......
to this:
Route::any("/myaccount2/ausersave/{code}", array(......

Categories