Mark
Mark

Reputation: 3197

laravel abstract method fatal exception error

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

Answers (1)

George Brighton
George Brighton

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

Related Questions