Reputation: 3197
I am using the User class included with laravel 4. I am trying to store a new question that belongs to the user and the user needs to be logged in to create. when I call the questions controller action store I get the following error
Class User contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (Illuminate\Auth\UserInterface::getAuthPassword, Illuminate\Auth\Reminders\RemindableInterface::getReminderEmail)
I have read a bit on abstract methods in php and while I don't completely understand them the error itself gives two solutions to the problem, declare the class abstract of implement the remaing methods. I am guessing that since this is the model class that ships with laravel that the correct solution is not to change its declaration to abstract but to implement the remaining methods. How do I do this correctly in this case and going forward?
User Model
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends BaseModel implements UserInterface, RemindableInterface {
protected $guarded = [];
public static $rules = array(
'username' => 'required|unique:users|alpha_dash|min:4',
'password' => 'required|alpha_num|between:4,8|confirmed',
'password_confirmation'=>'required|alpha_num|between:4,8'
);
public function Questions($value='')
{
return $this->hasMany('Question');
}
/**
* 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');
/**
* 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;
}
}
Questions Controller
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function postStore()
{
$validation = Question::validate(Input::all());
if($validation->passes()) {
Question::create(array(
'question'=>Input::get('question'),
'user_id'=>Auth::user()->id
));
return Redirect::Route('home')
->with('message', 'Your question has been posted.');
} else {
return Redirect::to('user/register')->withErrors($validation)
->withInput();
}
}
edit 1: The error message includes '(Illuminate\Auth\UserInterface::getAuthPassword, Illuminate\Auth\Reminders\RemindableInterface::getReminderEmail)' these two methods are in my user.php as publice functions as you can see above, so do I need to do something else to 'implement' them?
edit 2:
Laravel Src UserInterface Class
<?php namespace Illuminate\Auth;
interface UserInterface {
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier();
/**
* Get the password for the user.
*
* @return string
*/
public function getAuthPassword();
}
laravel src RemindableInterface class
<?php namespace Illuminate\Auth\Reminders;
interface RemindableInterface {
/**
* Get the e-mail address where password reminders are sent.
*
* @return string
*/
public function getReminderEmail();
}
edit 3:
php.ini related to error reporting
; error_reporting
; Default Value: E_ALL & ~E_NOTICE
; Development Value: E_ALL | E_STRICT
; Production Value: E_ALL & ~E_DEPRECATED
error_reporting = E_ALL
; Eval the expression with current error_reporting(). Set to true if you want
; error_reporting(0) around the eval().
; http://php.net/assert.quiet-eval
;assert.quiet_eval = 0
basemodel class
<?php
class Basemodel extends Eloquent {
public static function validate($data) {
return Validator::make($data, static::$rules);
}
}
?>
edit 4;
Adding correct model class as it was when giving the error and how it is now with the fix
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class Question extends BaseModel implements UserInterface, RemindableInterface {
protected $guarded = [];
public static $rules = array(
'questions'=>'required|min:10|max:255',
//'solved'=>'in:0,1',
);
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'questions';
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = array('');
/**
* Get the unique identifier for the question.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
public function user()
{
return $this->belongsTo('User');
}
}
add this to fix
/**
* 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;
}
Upvotes: 0
Views: 10273
Reputation: 5151
Perhaps it's easiest to answer this with an example. Say I have the following classes:
abstract class ClassB {
public abstract function foo();
}
class ClassA extends ClassB {}
$a = new ClassA();
Running this code will result in the following error:
Fatal error: Class ClassA contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (ClassB::foo)
This means I'm missing an implementation of foo()
(defined in ClassB
) in ClassA
. Abstract methods can only be defined in abstract classes, and mean that any non-abstract derived class must expose a full implementation - which ClassA
doesn't in this case. The above example can be fixed by changing ClassA
to
class ClassA extends ClassB {
// implementation of abstract ClassB::foo().
public function foo() {
echo 'Hello!';
}
}
Back to your example. Your User
class extends BaseModel
. Depending on whether BaseModel
extends another abstract class, it will contain two methods defined as abstract
that your User
class is missing. You need to find these methods - my error message explicitly told me what I was missing - and implement them in User
.
Upvotes: 2