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();
}
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']);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With