3

I have a Command that is listening via Redis Pub/Sub. When a Publish is received, I want to call a controller method so that I can update the database.

However, I have not been able to find any solution on how to call a controller method with parameters from inside of the project but outside of the routes. The closest thing I have seen is something like:

    return redirect()->action(
        'TransactionController@assignUser', [
               'transId' => $trans_id,
               'userId' => $user_id
        ]);

My complete command that I've tried looks like this:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;

class RedisSubscribe extends Command
{

    protected $signature = 'redis:subscribe';

    protected $description = 'Subscribe to a Redis channel';

    public function handle()
    {
        Redis::subscribe('accepted-requests', function ($request) {

            $trans_array = json_decode($request);
            $trans_id = $trans_array->trans_id;
            $user_id = $trans_array->user_id;

            $this->assignUser($trans_id, $user_id);
        });
    }

    public function assignUser($trans_id, $user_id)
    {
         return redirect()->action(
            'TransactionController@assignUser', [
               'transId' => $trans_id,
               'userId' => $user_id
            ]);
    }
}

However, this does not seem to work. When I run this Command, I get an error that assignUser() cannot be found (even though it exists and is expecting two paramters). I am also not sure a "redirect" is really what I am after here.

Is there some other way to call a controller function in a Command, or some other way that would make this possible to do?

tereško
  • 58,060
  • 25
  • 98
  • 150
MintMelt
  • 139
  • 1
  • 2
  • 12
  • 1
    Just by the way, `$this` doesn't work because you are in Closure. This is why you get the not found error. – Vincent Decaux Jan 03 '19 at 19:45
  • @Vincent Decaux Oh you're right. If I don't include the $this, it does not seem to be able to find the method at all in the Command class. Is there a way I can redesign this so I can actually call a method while subscribed? – MintMelt Jan 03 '19 at 19:55

1 Answers1

10

If your controller does not have any required parameters, you can just create the controller as a new object, and call the function.

$controller = new TransactionController();
$controller->assignUser([
           'transId' => $trans_id,
           'userId' => $user_id
        ]);
aynber
  • 22,380
  • 8
  • 50
  • 63
  • 6
    If your controller does have dependencies, you could `resolve('App\Http\Controllers\TransactionController')` it instead – Mozammil Jan 03 '19 at 19:48
  • 1
    That worked great, thank you! On a side note, is this not the "recommended" way to do this? I feel like listening to a channel and updating the database via controller is a sensible thing to do, yet I found basically no information about it. Would making controller objects constantly cause performance over a long period of time? – MintMelt Jan 03 '19 at 21:45
  • No, it should not cause performance issues, but it really depends on the size of your controller. I don't know if it's the recommended way or not, but I use this method in a few of my commands and other places when I need to reuse functions and don't have them in a model or repository. – aynber Jan 04 '19 at 13:21