Search code examples
laravel-artisanlaravel-5.5

Laravel: php artisan commands not running, unless I comment some code out


When I was trying to run a make:migration command, it returned an error.. trying to get property of non-object (with no further info). It seemed that artisan didn't succeed any commands at all

So I checked the laravel.log and it brought me to my custom html builder, the line in the construct.

class HtmlBuilder extends \Collective\Html\HtmlBuilder {

    use CreatesAdminMenu, CreatesButtons;

    /**
     * Slugs accesible by the user
     * @var array
     */
    public $accessibleSlugs;

    function __construct()
    {
        $this->accessibleSlugs = auth()->user()->accessibleSlugs;
    }

This code ran fine, also when I dd-ed auth()->user()->accessibleSlugs, I gave me a valid array. But only when I comment it out, the php artisan command runs fine again...

The Admin model behind it contains this method

public function getAccessibleSlugsAttribute()
{
    return static::$roleSlugs[$this->role];
}

Hopefully someone here can give me some direction to solve this.

EDIT: If someone is still intested... I did some more digging, running ['prop'] instead of '->prop' doesn't break artisan... by why :S!! So in my HtmlBuilder's construct:

function __construct()
{
    $this->accessibleSlugs = auth()->user()['accessibleSlugs']; //works!

    //$this->accessibleSlugs = auth()->user()->accessibleSlugs; //Break Artisan!
}

In a routeMiddleware I also access it like this: '->accessibleSlugs', and here it doesn't cause any problems :S


Solution

  • auth()->user()->accessibleSlugs should not work when running artisan commands; there is no authenticated user. It sounds really weird that there is a way it actually works for you. I think this is an error in your debugging; perhaps you did the debugging in a context of a web request where you were logged in.

    A full stack trace will probably show that you have an artisan command that instantiates the HtmlBuilder. This causes the issue because the artisan framework internally instantiates all artisan commands, even when they aren't invoked by you. You should defer the dependencies to the handle method where it will only occur if it is that specific command being invoked.

    The original problem will still persist; you have an artisan command that uses a HtmlBuilder, and the HtmlBuilder has assumptions on the application state (the authentication). You will probably need to either modify HtmlBuilder to support anonymous invocations, or modify the artisan command to accept a user-id to impersonate as a parameter. (Example: php artisan do:the-thing --user-id=1337)