In Laravel 5.8, I have a custom attribute to recover the avatar via Gravatar. This is an attribute in the User model.
/**
* #return string
*/
public function getAvatarAttribute()
{
return sprintf('%s%s%s', 'https://secure.gravatar.com/avatar/', md5(strtolower(trim($this->email))), '?s=200');
}
I have a belongsTo/hasMany relationship in the Post/User model.
Post model:
/**
* #return BelongsTo
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
User model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* #var string
*/
protected $table = 'users';
/**
* #var array
*/
protected $fillable = [
'username',
'email',
'password',
'api_token',
];
/**
* #var array
*/
protected $hidden = [
'password',
'remember_token',
'api_token',
];
/**
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
'admin' => 'boolean',
];
/**
* #return string
*/
public function getRouteKeyName()
{
return 'username';
}
/**
* #return HasMany
*/
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
/**
* #return string
*/
public function getAvatarAttribute()
{
return sprintf('%s%s%s', 'https://secure.gravatar.com/avatar/', md5(strtolower(trim($this->email))), '?s=200');
}
}
I pass the post by the URL of the route:
Route::get('post/{post}', 'BlogController#post');
I would like to retrieve the avatar attribute via post. Only, I recover a null. And I do not understand where it comes from.
public function post(Post $post)
{
dd($post->user); // user model without appends attributes
dd($post->user->avatar); // null
}
I found the problem, I used User from Illuminate (Illuminate\Foundation\Auth\User) instead my User model.
Related
I'm trying to put some sessions in my project and it's working fine when I'm logged out. But when I'm logged in as an Admin I'm getting the following error:
Call to undefined method App\User::admin()
this is my routes
Route::resource('/create','PagesController#showCreate')->middleware(IsAdmin::class);
Route::get('/users','UserController#index')->middleware(IsAdmin::class);
Route::get('/verify','UserController#userVerify')->middleware(IsAdmin::class);
this is my User model
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
* protected $table = 'users';
*public $primaryKey ='id';
* #var array
*/
protected $fillable = [
'name', 'email', 'password','userType',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
'admin' => 'boolean',
];
public function posts(){
return $this->hasMany('App\Post');
}
public function isAdmin()
{
return $this->admin;
}
}
and this is my IsAdmin class
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class IsAdmin
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
{
if ( Auth::check() && Auth::user()->admin() )
{
return $next($request);
}
return redirect('home');
}
}
}
And every time I try to redirect to other routes I get the same error except for the dashboard
Change if statement in your IsAdmin class:
if ( Auth::check() && Auth::user()->isAdmin() )
I'm trying to write a unit test on my user model that tests if the soft deleted record is still present in the database.
/**
* check if users are soft deleted only
*
* #return void
*/
public function testUserIsSoftDeleted()
{
$user = factory(User::class)->create();
$user->delete();
$this->assertSoftDeleted('users', $user->toArray());
}
This test runs fine until I add a custom attribute to the model.
<?php
namespace App;
use Laravel\Passport\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use OwenIt\Auditing\Contracts\Auditable;
class User extends Authenticatable implements MustVerifyEmail, Auditable
{
use HasApiTokens, Notifiable, SoftDeletes, HasRoles, \OwenIt\Auditing\Auditable;
protected $guard_name = 'web';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'email', 'password', 'active', 'activation_token', 'email_verified_at'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token', 'activation_token'
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* The attributes that should be added to the JSON response
*
* #var array
*/
protected $appends = ['md5_email'];
/**
* Convert email address into md5 string
*
* #var string
*/
public function getMd5EmailAttribute()
{
return md5(strtolower(trim($this->email)));
}
}
When I run the test I get the following error.
How do I include custom attributes in the Found array?
To skip md5_email from the query, assign the toArray result to an array and unset the md5_email
Something like
public function testUserIsSoftDeleted()
{
$user = factory(User::class)->create();
$user->delete();
$userInfoArray = $user->toArray()
// This should skip md5_email getting added to the query
unset($userInfoArray["md5_email"])
$this->assertSoftDeleted('users', $userInfoArray);
}
As stated by Cerlin the md5_email attribute in not present in the database, that's why you get the error. You have many options to make the test pass. You might simply unset the md5_email from the user array or, for the sake of clarity, rewrite your test as follow:
/**
* check if users are soft deleted only
*
* #return void
*/
public function testUserIsSoftDeleted()
{
$user = factory(User::class)->create();
$user->delete();
$this->assertSoftDeleted('users', $user->only('id', 'name', 'email'));
}
I am creating a user profile page and I want to retrieve the data from my User model and UserProfile model. But I have a problem in getting the result. Here's what I did:
User model
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'username',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/*
public function isAdmin() {
return $this->admin;
}
*/
public function profile() {
return $this->hasOne('App\UserProfile');
}
}
UserProfile model
class UserProfile extends Model
{
protected $table = 'user_profile';
protected $fillable = [
'phone',
'address'
];
public function user() {
return $this->belongsTo('App\User');
}
}
Then I access the relation in my ProfileController
public function getProfile($username) {
$user = User::with('user_profile')->where('username', $username)->get();
dd($user);
}
And I got this error:
Call to undefined relationship [user_profile] on model [App\User].
The user_profile is my table name
Use proper relationship name:
$user = User::with('profile')->where('username', $username)->first();
Also, in this case you should use the first() method to get an user object.
After I update my laravel using composer update, I got this
"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException",
"message":"Class User contains 3 abstract methods and must therefore be declared abstract or implement the remaining methods (Illuminate\\Auth\\UserInterface::setRememberToken, Illuminate\\Auth\\UserInterface::getRememberTokenName, Illuminate\\Auth\\Reminders\\RemindableInterface::getReminderEmail)",
"file":"D:\app\\models\\User.php",
"line":54
error when authenticating.
This error happened because of the latest commit.
You can check the upgrade documentation here, to fix this issue.
As stated, add the following to your User.php model class:
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
This is what worked for me by adding the below to app/User
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* #return array
*/
public function getJWTCustomClaims()
{
return [];
}
Example app/User
<?php
namespace App;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* #return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* #return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
I am creating an api with Laravel 4.1. For authentication I wanted to use Laravel Basic auth. Every time I fill the input fields, it doesn't let me in. It just clear the input and popup the form again. I am not sure what I am doing wrong. I am not using migration for creating users table. This is just a basic route:
Route::get('admin', function()
{
return "authenticated";
})->before('auth.basic');
This is my filter:
Route::filter('auth.basic', function()
{
return Auth::basic('username');
});
This is my User Model:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'pivot');
/**
* #var array
*/
protected $guarded = array('id', 'created_at', 'updated_at', 'is_admin');
protected $fillable = array('username', 'password', 'name_first', 'name_middle', 'name_last', 'email', 'address', 'city', 'state', 'zip_code', 'country', 'phone', 'title', 'profile_image', 'status');
/**
* #var array
*/
public static $rules = array();
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
}
Why don't you try
Route::get('admin', array( 'before' => 'auth.basic' ,function()
{
return "authenticated";
}));
Your passwords need to be hashed in your database.