Argument 1 passed to Illuminate\Auth\Guard::login() must be an instance of Illuminate\Contracts\Auth\Authenticatable error in laravel 5 - authentication

I’m building a carpool app where its the intention that when a user registers they’re able to fill in they have a car however this car is in a table on its own.
When I try to create it with the field checkt I get this error:
Argument 1 passed to Illuminate\Auth\Guard::login() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of App\Cars given, called in /home/vagrant/Code/carpool-app-going-your-way/www/vendor/compiled.php on line 2078 and defined
Any ideas on how to fix it?
Here is my code:
registrar.php
public function create(array $data)
{
if (isset($_POST["ihaveacar"])){
return Cars::create([
'seats'=>$data['seats'],
'seats_taken'=>'0',
]);
}
return User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'screen_name' => $data['screen_name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'route' => $data['route'],
'state' => $data['state'],
'description' => $data['description'],
'license_since' => $data['license_since'],
]);
}
User.php
<?php namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends model implements AuthenticatableContract, CanResetPasswordContract{
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['first_name', 'last_name', 'screen_name', 'email', 'password', 'birthday', 'license_since', 'kilometers', 'state', 'route','image','description','soft_delete', 'is_admin'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
use SoftDeletes;
protected $dates = ['deletec_at', 'created_at', 'updated_at'];
}
Any ideas how to fix this?
Thanks in advance
Edit: all of a sudden it seems to be running without errors. I don’t get it.

you should extend Illuminate\Foundation\Auth\User
like
use Illuminate\Foundation\Auth\User as AuthUser;
class Member extends AuthUser
{
public $table='members';
protected $fillable = ['name', 'password','qq','phone'];
}

You're passing an instance of App\Cars to the registrar via the create() method. Remove all non-login logic from the registrar and only perform said logic after the authentication logic is actually complete.

You’re returning two different object types in your create() method. If the request has a parameter called ihaveacar then you return a Car instance, otherwise you return a User instance. You need to make your mind up what your create() method should actually return.

Related

laravel 8 - Spatie activity log v3 - call to undefined method App\Models\Report::user()

I am using spatie activity-log v3 to log activities done by users in the website.
In the User.php Model, I have the following code (which works correctly)
use App\Core\Traits\SpatieLogsActivity;
use Spatie\Activitylog\Traits\LogsActivity;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable implements MustVerifyEmail
{
use HasFactory, Notifiable;
use SpatieLogsActivity, LogsActivity;
use HasRoles;
/**
* Log all activities performed by the user.
*/
protected static $ignoreChangesAttributes = ['password'];
protected static $logAttributes = ['name', 'email', 'phone', 'avatar'];
protected static $spatieLogsActivity = ['name', 'email', 'phone', 'avatar'];
protected static $recordEvents = ['created', 'updated', 'deleted'];
protected static $logName = 'Users';
...
The code above, means I want spatie to track the 'name', 'email', 'phone', 'avatar' inputs when the user 'created', 'updated', 'deleted' them.
I am trying to implement the same functionality for another model: Report
namespace App\Models;
use App\Core\Traits\SpatieLogsActivity;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Report extends Model
{
use HasFactory;
use SpatieLogsActivity, LogsActivity;
use HasRoles;
/**
* Log all activities performed by the user.
*/
protected static $ignoreChangesAttributes = [''];
protected static $spatieLogsActivity = ['caseType', 'caseLocation'];
protected static $recordEvents = ['created', 'updated', 'deleted'];
protected static $logName = 'Reports & Cases';
When I do some changes in the Report form and refresh the audit log, it shows me an error:
However!, when I delete previously inserted data and refresh, the log will actually show:
I just added the block of code in Report Model
/**
* Get a fullname combination of first_name and last_name
*
* #return string
*/
public function getNameAttribute()
{
return "{$this->first_name} {$this->last_name}";
}
what I understood from the error is that the log cannot find the user aka causer of the events in the Report model.

Laravel 8 default RegisterController. Pass parameters in array

I'm trying to create a form for register a user with a Vue component.
I want to use the default routes generated by Auth::routes(); and the default "create" function by the default RegisterController from Laravel 8
This is the create() function I see on RegisterController but it doesn't seem the function that the route is calling.
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\Models\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
But this is the created route:
|POST| register| generated::RuTERdEs1GA9zWNu | App\Http\Controllers\Auth\RegisterController#register| web
Why do I have a create() function if the route points to "register"? What's the function this "register" is actually calling?
The register method is actually part of the Illuminate\Foundation\Auth\RegistersUsers; trait. This is where the validation is called, the user is created, the Registered event is fired and the user is logged in.
It was set up this way to abstract so that the bits your most likely to change are easily available but the other parts of the code which are more essentially/less likely to need updating aren't "cluttering" your controller.

Laravel 8 - Class 'Database/Factories/User' not found

I have this PostFactory.php file in database->factories directory:
<?php
namespace Database\Factories;
use App\Models\Post;
use Illuminate\Database\Eloquent\Factories\Factory;
class PostFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Post::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'user_id' => User::factory(),
'title' => $this->faker->sentence,
'message' => $this->faker->paragraph
];
}
}
Now, when I run this command
Post::factory()->create();
from the tinker
I got that error message
Class 'Database/Factories/User' not found
:( Is there anything I am missing?
You need to import the User Model.
For Laravel 8, Your PostFactory.php file should look like so;
<?php
namespace Database\Factories;
use App\Models\User;
use App\Models\Post;
use Illuminate\Database\Eloquent\Factories\Factory;
class PostFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Post::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'user_id' => User::factory(),
'title' => $this->faker->sentence,
'message' => $this->faker->paragraph
];
}
}
check laravel docs on writing factories for more info.
UPDATE:
As for the error here on prnt (picked it up in the comments), You will need to provide more information.
However to start you up consider checking your database for:
A post that does not have a user_id. I.e one that you might have added before adding the foreign key constraint and therefore does not belong to any user.
If that's the case consider removing it or use tinker to manually assign a foreign key(i.e associate the post with a user) then try and create factories again. As you are trying to enforce a required column to existing data that does not already have it.
FYI just run:
composer dump-autoload
It can be that the class is not autoloaded.
As i Also had same Issue .First i changed my factory name same as name of model . Like if we have Blog Model .. We will make BlogFactory . so it can find the name of factory .

Where and how to set an SQL request for a form element?

I read a lot of things of things in the cookbook or on stackoverflow but I can't find something adapted and clearly explained about how to solve my problem.
I have an SQL request that allows me to find schools that teaches a specific subject. I need to set this SQL request so that when I load the page containing my form, the request is done and I see the result (a list of school) in a multi select form. My best guess is that I need to set it inside my controller, but then again, I'm not even sure of that since it's the first time that I need to do that
I don't know if I should show you any code, so ask if you need to see something!
Thank you in advance
edit Here is my formType
<?php
namespace MissionBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use SocieteBundle\Entity\Societe;
class PublicType extends AbstractType{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('public')
->add('ecolesDispo')
// My goal is to replace 'ecolesDispo' (that is currently a one-to-many)
// by my SQL request.
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MissionBundle\Entity\Mission'
));
}
}
Surely not in the controller. You need to use the "query_builder" attribute when you add the field to the form. Take a look at this example, from the Symfony cookbook : http://symfony.com/doc/current/reference/forms/types/entity.html#using-a-custom-query-for-the-entities
And you should translate your raw SQL query into DQL, so it's database-agnostic.
UPDATE about using a query builder with native SQL : http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/native-sql.html#the-nativequery-class
So something like this following piece of code should work (you'll have to edit some property names and fill the query though)
$builder->add('ecolesDispo', EntityType::class, array(
'class' => 'AppBundle:Ecole',
'query_builder' => function (EntityRepository $er) {
return $er->createNativeQuery('SELECT * FROM ecoles WHERE [...]');
},
'choice_label' => 'title',
));

Laravel 4 failing Auth::attempt with Hash replacement

I'm trying to do authentication in a Laravel4 project, but it always fails.
Since I'm only on PHP 5.3.4 I downloaded a replacement Hash package that uses SHA512 from https://github.com/robclancy/laravel4-hashing.
I already have a Users table (the Password field is pre-populated with SHA512 hashes, shared with another app) and my login auth method is:
Route::post('login', function()
{
$userdata = array(
'UserName' => 'SteB',
'password' => '1234'
);
if (Auth::attempt($userdata, true))
{
return Redirect::action('HomeController#Profile');
}
else
{
return Redirect::to('/')->with('login_errors', true);
}
});
I've also checked the SHA512 hash is correct using http://hash.online-convert.com/sha512-generator
This always fails (silently), any ideas why or how to debug it will be appreciated.
My Users table is:
UserID int, Identity PK
UserName varchar(24)
FullName varchar(32)
EMail varchar(64)
Password varchar(256)
This is in an existing SQL Server 2000 database, I'm getting User info out of the DB for an un-authenticated page, so I know the DB driver and connection is working ok.
User Model in Laravel:
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');
//protected $fillable = array('UserID', 'UserName', 'FullName');
/**
* 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()
{
/*Now all lowercase to match $userdata as suggested on SO*/
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->EMail;
}
}
UPDATE:
Just found this article: http://laravel.io/topic/20/hashing-in-laravel.
Looks like it's not doing things how I expected, a base64-encoded hash with random salt, I think.
So you need to change something in your model as well as the key you pass to attempt
class User extends Eloquent implements UserInterface
{
public function getAuthPassword()
{
return $this->Password;
}
// leave other code the same
}
And in your array you pass change it like follows.
$userdata = array( 'UserName' => 'SteB', 'password' => '1234');
The getAuthPassword() tells the Auth library your actual fieldname and setting the key in the userdata to all lowercase password tells the Auth library to hash that field.
I have no idea what your database structure looks like, but could it be that your username key isn't the same are you database column?
Maybe this will work:
$userdata = array(
'username' => 'SteB',
'password' => '1234'
);
Cheers.
EDIT: you can try all this etc, but I think I just proved myself wrong right after writing this.
This issue is to do with your database column naming and a restriction in Laravel I believe. Looking into Laravel's auth component I find a few areas where it specifically wants password or at least the string to contain that exact phrase. So your database needs to use the password column or you need to extend laravel to change some things.
Honestly, you should only ever use camel case or snake case with laravel. Issues can come up like this one when you use something it will never expect because there is no logical reason to use anything else.
So easy fix, use better column name.
Harder fix is extending the Auth component to allow for your Password field.