I have UserController which has this function to upload users avatar:
public function update_avatar(Request $request){
if($request->hasFile('avatar')){
$avatar = $request->file('avatar');
$filename = time() . '.' . $avatar->getClientOriginalExtension();
Image::make($avatar)->fit(300, 300)->save( public_path('/uploads/avatars/' . $filename ) );
$user = Auth::user();
$user->avatar = $filename;
$user->save();
}
return redirect()->back()
->with(['success' => 'Profile picture updated!']);
}
Now, each user can make and edit his links (Kind of like Linktree) and I want to add an option where they can upload a custom icon for their links. This is the code which I came up with and it successfully uploads my file to desired path but it fails to write it to Links Table. Here is the code:
public function custom_icon(Request $request){
if($request->hasFile('icon')){
$uploaded_icon = $request->file('icon');
$filename = time() . '.' . $uploaded_icon->getClientOriginalExtension();
Image::make($uploaded_icon)->fit(300, 300)->save( public_path('/img/icons/' . $filename ) );
$link = Auth::user()->link()
$link->icon = $filename;
$link->save();
}
return redirect()->back()
->with(['success' => 'Custom icon uploaded!']);
}
Now, I am new to coding and I have no idea how to add similar code like this to LinkController
$user = Auth::user();
I tried a few things but nothing works. This is one example:
$link = Auth::user()->link()
Note that the link edit page is opened by links id so maybe I am failing to add a good route?
Here is web.php
Route::get('/links', [LinkController::class, 'index']);
Route::get('/links/new', [LinkController::class, 'create'])->middleware('verified');
Route::post('/links/new', [LinkController::class, 'store']);
Route::get('/links/{link}', [LinkController::class, 'edit']);
Route::post('/links/{link}', [LinkController::class, 'update']);
Route::delete('/links/{link}', [LinkController::class, 'destroy']);
Route::post('/links/{link}', [LinkController::class, 'custom_icon']);
User model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable implements MustVerifyEmail
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'username',
'name',
'email',
'password',
'tittle',
'bio',
'bio_show',
'bio_on',
'bio_off',
'background_color',
'button_border_radius',
'button_text_color',
'button_color',
'text_color',
'editable_link',
'vcard_prefix',
'vcard_first_name',
'vcard_middle_name',
'vcard_last_name',
'vcard_suffix',
'vcard_email',
'vcard_second_email',
'vcard_personal_number',
'vcard_work_number',
'vcard_company',
'vcard_job',
'vcard_address',
'vcard_website',
'vcard_second_website',
'vcard_show',
'vcard_on',
'vcard_off'
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
public function links()
{
return $this->hasMany(Link::class);
}
public function visits()
{
return $this->hasManyThrough(Visit::class, Link::class);
}
public function getRouteKeyName() {
return 'username';
}
}
The Auth::user() returns you the User model. With the code Auth::user()->link() you call the link() method in your User model. But there is no such method in your User model.
If you want to get the last Link, you can add a method like this in your User model:
public function link() {
return $this->hasOne(Link::class)->latestOfMany();
}
Related
I'm building a laravel project which is a community platform, so it's gonna need a follower logic (pretty similar to twitter, instagram, etc).
I already created the logic for authentication and profile, but, when researching and writing the code for the followers state and check if the user is following someone, i got the functions on my model, which now is something like:
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
'phone',
'description',
'profilepicture',
'status',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function following()
{
return $this->belongsToMany('App\Models\User', 'followers', 'follower_user_id', 'user_id')->withTimestamps();
}
public function isFollowing(User $user)
{
return !is_null($this->following()->where('user_id', $user->id)->first());
}
}
And on my Profile Controller, I have:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class Profile extends Controller
{
public function show($id)
{
$user = User::where('id', $id)->firstOrFail();
$me = Auth::user();
$is_edit_profile = (Auth::id() == $user->id);
$is_follow_button = (!$is_edit_profile) && (!$me->isFollowing($user));
return view('profile', ['user' => $user, 'is_edit_profile' => $is_edit_profile, 'is_follow_button' => $is_follow_button]);
}
}
But VSCode says that i have a undefined method isFollowing in my controller, in the line:
$is_follow_button = (!$is_edit_profile) && (!$me->isFollowing($user));
Someone have a clue of why is this happening?
I'm using Laravel 8.
It's one of my first big projects, so previously sorry for any rookie mistake.
Thanks for your time and help!
Auth::user() returns an object of type Illuminate\Contracts\Auth\Authenticatable which does not implement isFollowing
Option 1 : You can add #var annotation to specify the type of your object
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class Profile extends Controller
{
public function show($id)
{
$user = User::where('id', $id)->firstOrFail();
/** #var User $me */
$me = Auth::user();
$is_edit_profile = (Auth::id() == $user->id);
$is_follow_button = (!$is_edit_profile) && (!$me->isFollowing($user));
return view('profile', ['user' => $user, 'is_edit_profile' => $is_edit_profile, 'is_follow_button' => $is_follow_button]);
}
}
Option 2 : You can extends the Auth facade by creating a new facade with the expected return type :
namespace App\Extensions\Facades;
use App\Models\User;
/**
* #method static User user()
*/
class Auth extends \Illuminate\Support\Facades\Auth
{
}
And then you can use this facade instead of the previous one
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Extensions\Facades\Auth;
use App\Models\User;
class Profile extends Controller
{
public function show($id)
{
$user = User::where('id', $id)->firstOrFail();
$me = Auth::user();
$is_edit_profile = (Auth::id() == $user->id);
$is_follow_button = (!$is_edit_profile) && (!$me->isFollowing($user));
return view('profile', ['user' => $user, 'is_edit_profile' => $is_edit_profile, 'is_follow_button' => $is_follow_button]);
}
}
I'm trying to generate a token to authenticate users in my Controller the following way:
namespace App\Http\Controllers\API;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class AuthController extends Controller
{
public function login()
{
if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
$user = Auth::user();
$success['token'] = $user->createToken('myApp')->accessToken;
dd($success['token']);
}
}
Currently, I'm just trying to print out the token. And this is my User's model:
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
//use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Hash;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
const USER_FIRST_NAME_FIELD = "first_name";
const USER_LAST_NAME_FIELD = "last_name";
const USER_PREFERRED_NAME_FIELD = "preferred_name";
const USER_EMAIL_FIELD = "email";
const USER_EMAIL_VERIFIED_AT_FIELD = "email_verified_at";
const USER_PASSWORD_FIELD = "password";
const USER_REMEMBER_TOKEN_FIELD = "remember_token";
const USER_RECEIVE_NEWSLETTER_FIELD= "receive_newsletter";
const USER_ACTIVE_FIELD = "active";
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
self::USER_FIRST_NAME_FIELD,
self::USER_LAST_NAME_FIELD,
self::USER_PREFERRED_NAME_FIELD,
self::USER_EMAIL_FIELD,
self::USER_PASSWORD_FIELD,
self::USER_RECEIVE_NEWSLETTER_FIELD,
self::USER_ACTIVE_FIELD,
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
self::USER_PASSWORD_FIELD,
self::USER_REMEMBER_TOKEN_FIELD
];
/**
* Automatically creates password hash when password is submitted
*
* #param string $password
* #return void
*/
public function setPasswordAttribute(string $password) : void
{
$this->attributes['password'] = Hash::make($password);
}
}
As you can see I'm using HasApiTokens, Notifiable traits and nonetheless I'm getting an error from my controller saying:
Call to undefined method App\User::createToken()
Passport is installed and configured correctly.
Here's something weird:
When registering an user (I'm using a separate controller and also using a service) a token is created successfully:
Here's my controller:
<?php
namespace App\Http\Controllers\API;
use App\Services\UserService;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Http\Requests\RegisterUserRequest;
class UserController extends Controller
{
private $user;
public function __construct(UserService $user)
{
$this->user = $user;
}
public function store(RegisterUserRequest $request) : JsonResponse
{
// TODO: verify message on error
$user = $this->user->register($request->validated());
$token = $user->createToken('MyApp')->accessToken;
dd($token);
return response()->json(['status' => 201, 'user_id' => $user->id]);
}
}
Here's my service:
<?php
namespace App\Services;
use App\Models\User;
use App\Services\BaseServiceInterface;
class UserService implements BaseServiceInterface
{
public function register(array $formValues) : User
{
// 'terms and conditions' should not be saved into the db, hence it's removed
unset($formValues['terms_conditions']);
return User::create($formValues);
}
}
and here's my model again:
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
//use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Hash;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
const USER_FIRST_NAME_FIELD = "first_name";
const USER_LAST_NAME_FIELD = "last_name";
const USER_PREFERRED_NAME_FIELD = "preferred_name";
const USER_EMAIL_FIELD = "email";
const USER_EMAIL_VERIFIED_AT_FIELD = "email_verified_at";
const USER_PASSWORD_FIELD = "password";
const USER_REMEMBER_TOKEN_FIELD = "remember_token";
const USER_RECEIVE_NEWSLETTER_FIELD= "receive_newsletter";
const USER_ACTIVE_FIELD = "active";
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
self::USER_FIRST_NAME_FIELD,
self::USER_LAST_NAME_FIELD,
self::USER_PREFERRED_NAME_FIELD,
self::USER_EMAIL_FIELD,
self::USER_PASSWORD_FIELD,
self::USER_RECEIVE_NEWSLETTER_FIELD,
self::USER_ACTIVE_FIELD,
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
self::USER_PASSWORD_FIELD,
self::USER_REMEMBER_TOKEN_FIELD
];
As I told you, when creating a user the token is being generated correctly.
I'd say that Auth::user() is not calling my Model directly, but I don't know for sure that's what is happening.
Any idea why?
Thanks
Since your guard is returning the wrong User model, App\User, you should check your auth configuration, 'config/auth.php'. In the providers array adjust any provider, usually users, that is using the App\User model to App\Models\User instead.
'providers' => [
'users' => [
'driver' => 'eloquent',
// 'model' => App\User::class,
'model' => App\Models\User::class,
],
...
],
in my case, i missed to use Trait HasApiTokens
thats why laravel was unable to create tokens.
just open User.php
afetr name space include
use Laravel\Passport\HasApiTokens;
then inside class
use HasApiTokens
Pls note : I am using laravel 7.
So, this is not the right way to do it but it's working at the moment:
<?php
namespace App\Http\Controllers\API;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\API\BaseController;
class AuthController extends BaseController
{
public function login()
{
if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
$authenticated_user = \Auth::user();
$user = User::find($authenticated_user->id);
dd($user->createToken('myApp')->accessToken);
}
dd('here');
}
}
Now I'm seeing the token.
I wanna do it the right way so I still would appreciate if any one could help me.
Thanks
you can let the auth.basic middleware do the authentication for you, by calling it in the construct method:
public function __construct()
{
$this->middleware('auth.basic');
}
Then generate the access token for the currently authenticated user, and return the user information along with the access token:
public function login()
{
$Accesstoken = Auth::user()->createToken('Access Token')->accessToken;
return Response(['User' => Auth::user(), 'Access Token' => $Accesstoken]);
}
Now the Controller will look like this:
<?php
namespace App\Http\Controllers\API;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\API\BaseController;
class AuthController extends BaseController
{
/**
* Instantiate a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth.basic');
}
public function login()
{
$Accesstoken = Auth::user()->createToken('Access Token')->accessToken;
return Response(['User' => Auth::user(), 'Access Token' => $Accesstoken]);
}
}
i have updated laravel 6 to 8 & i am using sanctum for API auth.
This works for me when i want to get token for API auth.
in User model
use Laravel\Sanctum\HasApiTokens;
and use the traits in function
use HasApiTokens
Model/User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Hash;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'name',
'email',
'password',
'status'
];
/**
* The attributes that should be hidden for serialization.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function setPasswordAttribute($input)
{
if ($input) {
$this->attributes['password'] = app('hash')->needsRehash($input) ? Hash::make($input) : $input;
}
}
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function scopeActive($query){
return $query->where('status', 'ACTIVE');
}
}
I'm having some problems trying to return a view with the user address.
I don't know if the real problem is in my controller or in my models. I'd like to know the correct way to return a user with his address creating a relationship with the models.
Address Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Address extends Model {
protected $fillable = ['name','last_name','street_address','street_address2', 'country', 'city', 'state-province', 'phone-number', 'phone-number2', 'address-type'];
public function user() {
return $this->hasOne('App\User');
}
}
User Model
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'first_name', 'last_name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function address() {
return $this->belongsTo('App\Address');
}
}
In the UserController, I'm using the method getAddress, but I really don't know how to get the user address and how to create a user with that relation.
UserController
namespace App\Http\Controllers;
use App\User;
use App\Address;
use Illuminate\Http\Request;
use App\Http\Requests;
use Auth;
class UserController extends Controller
{
public function userProfile() {
$user = Auth::user();
return view('user.profile', ['user' => $user]);
}
public function userAccount(User $user) {
$user = Auth::user();
return view('user.account', compact('user'));
}
public function nameUpdate(User $user)
{
$this->validate(request(), [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255'
]);
$user->first_name = request('first_name');
$user->last_name = request('last_name');
$user->save();
return redirect()->back();
}
public function emailUpdate(User $user)
{
$this->validate(request(), [
'email' => 'required|string|email|max:255|unique:users',
]);
$user->email = request('email');
$user->save();
return redirect()->back();
}
public function passwordUpdate(User $user) {
$this->validate(request(), [
'password' => 'required|min:8|confirmed',
]);
$user->password = bcrypt(request('password'));
$user->save();
return redirect()->back();
}
public function getAddress() {
$user=Auth::user();
$adress = $user->adress;
}
}
First of all you must reverse the relationship so that the address belongs to the user. If a user can have multiple addresses then a user cannot belong to each of those addresses. The addresses must belong to the user.
In the address table you will need a user_id column to start with.
User.php
public function addresses()
{
return $this->hasMany(Address::class);
}
Address.php
public function user()
{
return $this->belongsTo(User::class);
}
Then you can simply get all the addresses like so:
foreach(Auth::user()->addresses as $address){
//You can now access your address here
}
Your current controller:
public function getAddresses() {
$user = Auth::user();
$addresses = $user->addresses;
return $addresses;
}
In a blade file you could do something like:
#foreach(Auth::user()->addresses as $address){
<li>{{ $address->column_name }}</li>
}
I got HTTP ERROR 500 after putting using models in the routes file.
Here is the routes file code:
use App\User;
use App\Address;
Route::get('/hesham', function () {
return view('welcome');
});
Route::get('/insert', function(){
$user = User::findOrFail(1);
$address = Address::create([
'name'=>'1234 Housten av New York',
'user_id' => $user->id
])
$user->address()->save($address);
});
Home Route is working fine, but /insert is giving 500 ERROR
Here is the user model
User.php
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
/**
* 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',
];
}
public function address(){
return $this->hasOne('App\Address');
}
Here is the Address model
Address.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Address extends Model
{
//
}
public function user(){
return $this->belongsTo('App\User');
}
public function address(){
return $this->hasOne('App\Address');
}
and conversely:
public function user(){
return $this->belongsTo('App\User');
}
To associate an address with a user, do this:
Address::create([
'name'=>'1234 Housten av New York',
'user_id' => $user->id
])
edit
try this:
$address = new Address();
$address->user_id = $user_id;
$address->name = '1234 Housten av New York'
$address->save();
I need to display my users table data in the index.blade.php file, but when I visit the index view it displays an empty page, it does not display the variables data, which I need. (No errors are displayed.)
index.blade.php
#if(isset($users))
#foreach($users as $use)
<h1>{{$use->username}}</h1>
#endforeach
#endif
UsersController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Auth;
use App\User;
use App\Http\Requests;
class UserController extends Controller
{
public function index()
{
$users = User::userr()->get();
// $users = User::all();
return view('users.index')->withUser($users);
//dd($users);
}
}
User.php Model
<?php
namespace App;
use Auth;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'username', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function getAvatarUrl()
{
return "http://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email))) . "?d=mm&s=40";
}
public function scopeUserr($query)
{
return $query->where('username',Auth::user()->id);
}
}
Can You give me some solutions?
May be you have to check if the data passed to your blade,
and try to use
$model = App\Flight::findOrFail(1);
return view('page',compact('var'));
check this
http://www.snippetcase.com/snippet/27/Bind+and+Display+data+in+blade+page+for+laravel