'Target Laravelista is not instantiable

I'm trying to post a comment to my news post using the Laravelista\Comments but I got this error: Target [Laravelista\Comments\CommentControllerInterface] is not instantiable.

It was working just fine before, and I didn't change anything except the interface design. Not long after I couldn't post a comments anymore. This is the package I'm using https://github.com/laravelista/comments

Tried adding Laravelista\Comments\ServiceProvider::class, to the config\app.php but it didn't do any change.

Is there any solutions?



Solution 1:[1]

So on Laravel 9 there seems to be an issue getting with $this->middleware('auth'); in the constructor in the vendor CommentController. A workaround that is working for me is to basically create a custom controller and move the middleware('auth') to the actual routes instead.

  1. extend the vendor CommentController
  2. Copy the original constructor from there into your new comment controller but remove $this->middleware('auth');
  3. Copy/paste the store, update, destroy, and reply functions from CommentService in the vendor folder into your new controller.
  4. update the config (config\comments.php) to point to your new controller, example controller' => 'App\Http\Controllers\CustomCommentsController',
  5. copy the routes from vendor into your routes file and chain the middleware('auth') to each route there.
  6. Note: I have not tested this with guest commenting enable.

Controller:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Laravelista\Comments\Comment;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Config;
use Spatie\Honeypot\ProtectAgainstSpam;
use Illuminate\Support\Facades\Validator;
use Laravelista\Comments\CommentController;

class CustomCommentsController extends CommentController 
{
    public function __construct()
    {
        if (Config::get('comments.guest_commenting') == true) {
            $this->middleware('auth')->except('store');
            $this->middleware(ProtectAgainstSpam::class)->only('store');
        } else {
            // $this->middleware('auth');
        }
    }

    public function store(Request $request)
    {
        // If guest commenting is turned off, authorize this action.
        if (Config::get('comments.guest_commenting') == false) {
            Gate::authorize('create-comment', Comment::class);
        }

        // Define guest rules if user is not logged in.
        if (!Auth::check()) {
            $guest_rules = [
                'guest_name' => 'required|string|max:255',
                'guest_email' => 'required|string|email|max:255',
            ];
        }

        // Merge guest rules, if any, with normal validation rules.
        Validator::make($request->all(), array_merge($guest_rules ?? [], [
            'commentable_type' => 'required|string',
            'commentable_id' => 'required|string|min:1',
            'message' => 'required|string'
        ]))->validate();

        $model = $request->commentable_type::findOrFail($request->commentable_id);

        $commentClass = Config::get('comments.model');
        $comment = new $commentClass;

        if (!Auth::check()) {
            $comment->guest_name = $request->guest_name;
            $comment->guest_email = $request->guest_email;
        } else {
            $comment->commenter()->associate(Auth::user());
        }

        $comment->commentable()->associate($model);
        $comment->comment = $request->message;
        $comment->approved = !Config::get('comments.approval_required');
        $comment->save();

        return $comment;
    }

    /**
     * Handles updating the message of the comment.
     * @return mixed the configured comment-model
     */
    public function update(Request $request, Comment $comment)
    {
        Gate::authorize('edit-comment', $comment);

        Validator::make($request->all(), [
            'message' => 'required|string'
        ])->validate();

        $comment->update([
            'comment' => $request->message
        ]);

        return $comment;
    }

    /**
     * Handles deleting a comment.
     * @return mixed the configured comment-model
     */
    public function destroy(Comment $comment): void
    {
        Gate::authorize('delete-comment', $comment);

        if (Config::get('comments.soft_deletes') == true) {
            $comment->delete();
        } else {
            $comment->forceDelete();
        }
    }

    /**
     * Handles creating a reply "comment" to a comment.
     * @return mixed the configured comment-model
     */
    public function reply(Request $request, Comment $comment)
    {
        Gate::authorize('reply-to-comment', $comment);

        Validator::make($request->all(), [
            'message' => 'required|string'
        ])->validate();

        $commentClass = Config::get('comments.model');
        $reply = new $commentClass;
        $reply->commenter()->associate(Auth::user());
        $reply->commentable()->associate($comment->commentable);
        $reply->parent()->associate($comment);
        $reply->comment = $request->message;
        $reply->approved = !Config::get('comments.approval_required');
        $reply->save();

        return $reply;
    }

}

Routes:

Route::post('comments', [Config::get('comments.controller'), 'store'])->middleware('auth')->name('comments.store');
Route::post('comments/{comment}', Config::get('comments.controller') . '@reply')->middleware('auth')->name('comments.reply');
Route::delete('comments/{comment}', Config::get('comments.controller') . '@destroy')->middleware('auth')->name('comments.destroy');
Route::put('comments/{comment}', Config::get('comments.controller') . '@update')->middleware('auth')->name('comments.update');

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1