Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting null value returned when using trait but var_dump in the class returns correct data

Tags:

php

Ok, stick with me here. I have a process that I need to follow and there are quite a few if statements that I have broken down into smaller classes instead of having one ugly switch or if/else statement. Basically, I call the handle method of a class, it figures out where we are in the process, instantiates the appropriate class which then builds the collection needed and returns it.

I have a model in which I am trying to get the nextAction for that particular record. The nextAction will have a name, date, timeRemaining and route keys returned as a collection. Here is the method within my FreeLook.php model:

public function nextAction()
{
    // handle basically just calls a handle method on the NextActionHandler class.
    return handle(new NextActionHandler($this));
}

The NextActionHandler class figures out where we are in the process. It does so by using a trait that I created named Actionable. Here is the NextActionHandler class:

class NextActionHandler
{
    use Actionable;

    protected $freeLook;

    public function __construct($freeLook)
    {
        $this->freeLook = $freeLook;
    }


    public function handle()
    {
        switch (true) {
            case $this->wantsSign() && !$this->signJobIsComplete():
                return handle(new SignNextAction($this->freeLook));
            case $this->wantsPaint() && !$this->paintJobIsComplete():
                return handle(new PaintNextAction($this->freeLook));
            case $this->needsToSubmitCoOp():
                return handle(new CoOpNextAction($this->freeLook));
            default:
                return handle(new DefaultNextAction($this->freeLook));
        }
    }
}

Here is some of the Actionable trait. I'm not putting all of it in here because it is really long. I contains a lot of the logic in order to figure out where we are in the process. One thing to note is that it does contain the logic to build the output of the collection that I am returning. (if you want the full Actionable code, go here)

    protected function needToChooseVendor()
    {
        $this->name = 'Choose Vendor';
        $this->duration = $this->freeLook->status->expected_duration;
        $this->calculateTimeRemaining();

        return $this->buildOutput();
    }

    protected function calculateTimeRemaining()
    {
        if ($this->duration) {
            $this->timeRemaining = Carbon::now()->diffInDays($this->date);
        }
    }

    protected function buildOutput()
    {
        return collect([
            'name' => $this->name,
            'date' => $this->date,
            'timeRemaining' => $this->timeRemaining,
            'route' => $this->route,
        ]);
    }

And finally, my DefaultNextAction class, which also uses the trait in order to construct the output and return it.

class DefaultNextAction
{

    use Actionable;

    public function __construct($freeLook)
    {
        $this->freeLook = $freeLook;
        $this->date = $freeLook->next_action_at;
    }

    public function handle()
    {
        return $this->returnDefaultNextAction();
    }

    protected function returnDefaultNextAction()
    {
        $this->name = $this->freeLook->status->name;
        $this->duration = $this->freeLook->status->expected_duration;
        $this->calculateTimeRemaining();
        $this->output = $this->buildOutput();

        return $this->output;
    }
}

So, when I do a dump & die in the returnDefaultNextAction method, I get the expected results. But, when I dump and die in my model, I always get null. What would be the cause of this? Since I am using a trait and traits cannot be instantiated, I thought that I was dealing with the same instance of the object and all should work.

Any ideas would be very helpful!

EDIT 1 Here is the handle method I am using to wrap around all of my objects.

if (!function_exists('handle')) {
    function handle($object)
    {
        if (!is_object($object)) {
            throw new Exception('An object must be passed to the handle method. This is not what happened.');
        }

        call_user_func([$object, 'handle']);
    }
}

EDIT 2 Even if I call my handle method like so in my model, I get the same null result:

 public function nextAction()
 {
    $nextAction = new NextActionHandler($this);

    return $nextAction->handle();
 }
like image 712
dericcain Avatar asked Oct 29 '22 15:10

dericcain


1 Answers

Your handle function isn't returning anything. Needs to be

if (!function_exists('handle')) {
    function handle($object)
    {
        if (!is_object($object)) {
            throw new Exception('An object must be passed to the handle method. This is not what happened.');
        }

        return call_user_func([$object, 'handle']);
    }
}
like image 60
deefour Avatar answered Nov 15 '22 06:11

deefour