Hey guys so I made a route:
Route::get('/dashboard/{user}', [DashboardController::class, 'show'])->name('dashboard.show');
My controller is
public function show($id)
{
return view('dashboard.profile')->with('name',User::where($id));
}
How do pass it into the view? so I get only data from the current user / userid
You can simplify it to this by using route model binding:
public function show(User $user)
{
return view('dashboard.profile', [ 'user' => $user ]);
}
You Can Do This:
public function show(User $user)
{
return view('dashboard.profile', [ 'user' => $user ]);
}
Or :
public function show($id)
{
$user = User::findOrFail($id);
return view('dashboard.profile', [ 'user' => $user ]);
}
Or :
public function show($id)
{
$user = User::where("id",$id)->first();
return view('dashboard.profile', [ 'user' => $user ]);
}
If You Need Authenticated user use :
auth()->user
Related
How to pass a variable($test) from store to index? because I would like to display a variable in my index.blade
public function index()
{
return view('users.index', [
'users' => User::all()
]);
}
public function store(Request $request)
{
$user = new User($request->all());
$user->save();
$test = "test";
return redirect('users');
}
To resolve your problem you may edit your code like below:
index function:
public function index($test=null)
{
return view('users.index', [
'users' => User::all(),
'test' => $test
]);
}
store function:
public function store(Request $request)
{
$user = new User($request->all());
$user->save();
$test = "test";
return redirect(route('users.index', compact('test')));
}
N.B: for storing your user I don't recommend to you mass assignment (new User($request->all())) when you create a new user especially if you have a password or token to store there.
This is how I would make such a function
Controller code
public function store(RegistrationStoreRequest $request){
$user = User::create($request->validated());
Auth::login($user);
return redirect()->home();
}
This is my Request form code
public function rules()
{
return [
'name' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed'
];
}
You have two options:
Create a value mutator:
public function setPasswordAttribute($value) {
$this->attributes['password'] = Hash::make($value);
}
however you need to ensure you never prehash the password.
Hash in controller
public function store(RegistrationStoreRequest $request){
$user = User::create(array_merge(Arr::except($request->validated(), 'password'), [ 'password' => Hash::make($request->password) ]));
Auth::login($user);
return redirect()->home();
}
The easiest and most clean way is to use a custom cast for password field, first create UserPasswordCast.php class:
<?php
//app/Casts/UserPasswordCast.php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Support\Facades\Hash;
class UserPasswordCast implements CastsAttributes
{
public function get($model, $key, $value, $attributes)
{
return $value;
}
public function set($model, $key, $value, $attributes)
{
//return hashed value
return Hash::make($value);
}
}
Suggested location:
app/Casts/UserPasswordCast.php
Then update your 'user' model to use this cast, add "$casts" array or update it if existed:
use App\Casts\UserPasswordCast;
...
protected $casts = [
...
'password' => UserPasswordCast::class
];
That's it, you don't have to worry about password again
Just save your user model as it:
public function store(RegistrationStoreRequest $request)
{
$user = User::create($request->validated());
Auth::login($user);
return redirect()->home();
}
For more info please check:
https://laravel.com/docs/8.x/eloquent-mutators#custom-casts
=>create method function add in User.php(Model).
public static function create($user, $request)
{
if (isset($request->name)) {
$user->name = $request->name;
}
if (isset($request->email)) {
$user->email = $request->email;
}
if (isset($request->password)) {
$user->password = bcrypt($request->password);
}
if (isset($request->confirmpassword)) {
$user->confirmpassword = $request->confirmpassword;
}
$user->save();
return $user;
}
=>New user create with validate your all request field.
public function store(RegistrationStoreRequest $request){
$user = User::create(New User,$request);
Auth::login($user);
return redirect()->home();
}
Please try this code it is working.
I'm facing login page again and again when try to go to the homepage. I didn't add any middleware to homepage route but still I'm facing this issue.
My Login Controller
protected $redirectTo = '/';
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function redirectToProvider()
{
return Socialite::driver(request()->provider)->redirect();
}
public function handleProviderCallback()
{
$provider = request()->provider;
$providerUser = Socialite::driver($provider)->user();
if($providerUser->getEmail() == null) {
$user = User::where($provider . '_id', $providerUser->getId())->first();
} else {
$user = User::where('email', $providerUser->getEmail())->first();
}
if($user && $user->$provider . '_id' == null) {
dd('test');
$user->update([$provider . '_id' => $providerUser->getId()]);
}
if(!$user) {
$user = User::create([
'email' => $providerUser->getEmail(),
'name' => $providerUser->getName(),
$provider . '_id' => $providerUser->getId(),
]);
}
auth()->login($user, true);
return redirect($this->redirectTo);
// $user->token;
}
public function showLoginForm()
{
session()->put('previousUrl', url()->previous());
return view('auth.login');
}
public function redirectTo()
{
return str_replace(url('/'), '', session()->get('previousUrl', '/'));
}
I don't know the issue is in controller or in routes.
Routes
Route::get('/', 'WelcomePageController#index')->name('welcome');
Auth::routes();
Route::get('/login/{provider}', 'Auth\LoginController#redirectToProvider');
Route::get('/login/{provider}/callback', 'Auth\LoginController#handleProviderCallback');
I can visit the homepage only when I logged in but I want to see it as a guest.
The home route is protected, you can see this in construct method of HomeController. To make it unprotected, try to comment the line in constrct method.
To prevent errors in home view, you have to edit this view too.
I am trying to setup my policy for users. However I keep on getting an error of:
Too few arguments to function App\Policies\UserPolicy::update(), 1 passed in /vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php on line 481 and exactly 2 expected (View: /resources/views/users/index.blade.php)
ErrorException /app/Policies/UserPolicy.php 20
which is on the UserPolicy#update function
When I am logged in as super_admin, it works fine but it throws this error whenever I am logged in as a user of different role.
Below is my current implementation:
UserPolicy
class UserPolicy
{
use HandlesAuthorization;
public function update(User $user, User $userEdit) {
if ($user->id == $userEdit->id) {
return true;
}
return $user->can('update_user');
}
public function before($user, $ability) {
if ($user->hasRole('super_admin')) {
return true;
}
}
}
UsersController
class UsersController extends Controller {
public function __construct() {
$this->middleware('auth');
}
public function edit(User $user) {
$this->authorize('update', $user);
return view('users.edit', [
'user' => User::with('roles', 'level')->find($user->id),
'surveys' => \App\Survey::all(),
]);
}
public function update(UserRequest $request, User $user) {
$this->authorize('update', $user);
$request->save();
session()->flash('success', 'User successfully updated');
// means user is editing his own profile
if (auth()->id() == $user->id) {
return redirect('/dashboard');
} else {
return redirect('/users');
}
}
}
UserRequest
class UserRequest extends FormRequest {
public function authorize() {
return true;
}
public function rules() {
switch ($this->method()) {
case 'POST':
return [
'name' => 'required|string',
'email' => 'required|string|email|max:255|unique:users',
'role' => 'required|exists:roles,id',
'level' => 'required|string',
];
break;
case 'PATCH':
return [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users,email,'.$this->user->id,
'role' => 'sometimes|exists:roles,id',
'level' => 'sometimes|string',
'password' => 'nullable|sometimes|string|min:6|confirmed'
];
break;
default:
break;
}
}
public function save() {
switch (request()->method()) {
case 'POST':
$this->createUser();
break;
case 'PATCH':
$this->updateUser();
break;
default:
break;
}
}
protected function createUser() {
// random generate password
$password = str_random(8);
$user = User::create([
'name' => request('name'),
'email' => request('email'),
'level_id' => request('level'),
'password' => Hash::make($password),
]);
$user->assignRoleById(request('role'));
Mail::to($user)->send(new WelcomeMail($user, $password));
}
protected function updateUser() {
$user = User::findOrFail($this->user->id);
$user->name = request('name');
$user->email = request('email');
if (request('password') != '') {
$user->password = Hash::make(request('password'));
}
if (request('level') != '') {
$user->level_id = request('level');
}
$user->update();
if (request('role') != '') {
$user->roles()->sync([request('role')]);
}
}
}
AuthServiceProvider
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
\App\User::class => \App\Policies\UserPolicy::class,
];
/**
* Register any authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
foreach ($this->getPermissions() as $permission) {
Gate::define($permission->name, function($user) use ($permission) {
return $user->hasRole($permission->roles);
});
}
}
protected function getPermissions() {
return Permission::with('roles')->get();
}
}
In my views file I'm calling
#can('update', App\User::class)
<!-- html code --!>
#endcan
instead of
#can('update', $user)
<!-- html code --!>
#endcan
I was not passing the user instance into the function which was causing the error.
In UserRequest you haven't given any parameters when you call $user->update();. The update() function requires for a UserRequest instance, as well as a User.
Give this a try: $user->update(request()->all(), $user)
Edit:
I would just move the following...
$this->authorize('update', $user);
$request->save();
session()->flash('success', 'User successfully updated');
// means user is editing his own profile
if (auth()->id() == $user->id) {
return redirect('/dashboard');
} else {
return redirect('/users');
}
...to the updateUser() function.
I am using Socialite for user logins and I would like to set a remember_token to remember the user when they login through Socialite.
Right now I have the following service to create or log the user in:
class SocialAccountService {
public function createOrGetUser(ProviderUser $providerUser) {
$account = SocialAccount::whereProvider('google')
->whereProviderUserId($providerUser->getId())
->first();
if ($account) {
return $account->user;
} else {
$account = new SocialAccount([
'provider_user_id' => $providerUser->getId(),
'provider' => 'google'
]);
$user = User::whereEmail($providerUser->getEmail())->first();
if (!$user) {
$user = User::create([
'email' => $providerUser->getEmail(),
'name' => $providerUser->getName()
]);
}
$account->user()->associate($user);
$account->save();
return $user;
}
}
}
It is called with the following controller:
class AuthController extends Controller {
public function logout() {
Auth::logout();
return redirect('/');
}
public function redirectToGoogle() {
return Socialite::driver('google')->redirect();
}
public function handleGoogleCallback(SocialAccountService $service) {
$user = $service->createOrGetUser(Socialite::driver('google')->user());
auth()->login($user);
return redirect('/');
}
}
The issue is that when the user comes back they are not remembered and automatically logged in. How can I do this with Socialite?
According to the documentation, passing true as the second argument of login() will set the remember token.
// Login and "remember" the given user... Auth::login($user, true);
The Auth facade and auth() helper function access the same object.