How to force laravel to wait until the end job? - php

my function in controller Calling parallel and i create a job for use queue in laravel Because parallel call causing the problem
I create queue as follows :
public function serve($id)
{
$this->dispatch(new OrderServeJob($id));
return response()->json(true);
}
and i run:
php artisan queue:work
But I have a problem with this method
I want laravel to wait until the queue ends up and then return response()->json(true)
and after redirect user to another address

If you want your job to be handled before the call ends you should use the syncdriver for your Job. You can do this customizing the Job connection to use in your job:
class OrderServeJob implements ShouldQueue {
public $connection = 'sync'; // <---
//
}
You can take a look a this (and others) queue configuration in your config/queue.php file:
'connections' => [
'sync' => [
'driver' => 'sync',
],
//
]
Check the Customizing The Queue & Connection section of the documentation.

You can use queue events. Explanation how to use in the documentation:
job Events laravel

U can add ->onConnection('sync') to ur job firing
$this->dispatch(new OrderServeJob($id))->onConnection('sync');

Related

execute global function automatically on running controller in yii2

We have web pages, where user will be redirected to $this->goHome(), if the session timeouts or user logouts. We have to destroy the all the session so, we have to add a function with destroying session. This function should be executed before running any action/controller in Yii2 i.e. similar to hooks in codeigniter. We have tried a helper function with destroying session and we have called the function as HomeHelper::getHelpDocUrlForCurrentPage(); in main.php layout, but the layout will be executed after running action in controller, it should work on running any controller as we have 100+ controllers. How this can be achieved, please suggest us in right way. Thanks in advance.
in
config/main.php
you could try using 'on beforeAction'
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'bootstrap' => [
'log',
....
],
'on beforeAction' => function($event){
// your code ..
} ,
'modules' => [
....
],
...
];
While #ScaisEdge solution would work I believe application config is not proper place to hold application logic.
You should use filters to achieve result you want.
First you need to implement filter with your logic. For example like this:
namespace app\components\filters;
class MyFilter extends yii\base\ActionFilter
{
public function beforeAction() {
// ... your logic ...
// beforeAction method should return bool value.
// If returned value is false the action is not run
return true;
}
}
Then you want to attach this filter as any other behavior to any controller you want to apply this filter on. Or you can attach the filter to application if you want to apply it for each action/controller. You can do that in application config:
return [
'as myFilter1' => \app\components\filters\MyFilter::class,
// ... other configurations ...
];
You might also take a look at existing core filters if some of them can help you.

How to over ride a Laravel class with my own?

So I am working with Laravel 5.2 and I trying to shift to SQS as my queue serice.
There was a bug in 5.2 in QueueSqs.php which was fixed here -> https://github.com/illuminate/queue/blob/5.6/SqsQueue.php in 5.6
Now I am not sure I can upgrade to 5.6 yet, because a lot of things are working with 5.2 and I don't want to break anything.
But I am sure I can somehow use this class in my code from 5.6 and tell Laravel to use it somehow. But I don't know how to.
I haven't checked if this worked back in Laravel 5 or in class extends, but in newer versions Laravel generally tries to resolve the class from its container and by binding the original FQNS of the class to your your custom SqsQueue, it instead returns yours everytime the original is used:
class AppServiceProvider extend ServiceProvider
{
public function register()
{
$this->app->bind(\Illuminate\Queue\SqsQueue::class, function ($app) {
return new CustomSqsQueue();
});
}
}
Well, actually, instead of overriding the original class and re-binding it for Laravel to use you could also add your own custom queue connector and use this instead of Laravels native SQS queue connector:
To add a new connector for the queue to use, open up a service provider and add the following code to the boot
public function register()
{
$manager = $this->app['queue'];
$manager->addConnector('sqs-custom', function() {
return new CustomSqsQueue;
});
}
Then, in the queue.php config, add a new connection based on the original SQS connection, but with the driver name you chose in the first parameter or addConnector in the service provider. The key of the array ist the name of the connection you use to define your queues:
'sqs-custom' => [
'driver' => 'sqs-custom',
'key' => 'your-public-key',
'secret' => 'your-secret-key',
'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id',
'queue' => 'your-queue-name',
'region' => 'us-east-1',
],
Again, this is untested but should be able to work in Laravel 5.2.

Target class [App\Listeners\CartUpdatedListener] does not exist

i want to configure events in choping cart uses LaravelShoppingcart package, i run cmd following php artisan make: listener CartUpdateListener, but it gives me error Target class [App \ Listeners \ CartUpdatedListener] does not exist.
EventServiceProvider.php
protected $listen = [
'cart.added' => [
'App\Listeners\CartUpdatedListener',
],
'cart.updated' => [
'App\Listeners\CartUpdatedListener',
],
'cart.removed' => [
'App\Listeners\CartUpdatedListener',
],
];
CartUpdateListener.php
/**
* Handle the event.
*
* #param object $event
* #return void
*/
public function handle($event)
{
dd("event was fired");
}
Your error tells us about CardUpdatedListener but your file name is CardUpdateListener (an extra 'd' in the word Update). Check it, or post full class code.
When you run an Artisan command, it bootstraps a Laravel app. Among a lot of things, event listeners are setup and they need to be constructed, but at this moment, your listener class does not exist yet. Follow these steps:
Remove everything from your listen property of EventServiceProvider
Run php artisan make:listener CartUpdatedListener
Refill your listen property

Laravel not publishing channels when called from api.php

I am trying to implement a chat system with Laravel using Redis, Node, and socket.io. Anyways, when i try to publish the messages to Redis, i can do that using the web url, but when i call it from the API endpoints i have made in api.php, i get nothing.
Here is how i am publishing the events to redis
public function index(){
$data = [
'event' => 'UserStuff',
'data' => [
'username'=>'Lord Haq'
]
];
Redis::publish('test-channel-3', json_encode($data));
return 'Hope this works!';
}
This is the route in api.php
Route::get('redis', 'RedisController#index');
I have no idea what is going on. Or what other should i put here. Any help will be appreciated. Oh and i have php artisan queue:listen running in the background.

run artisan command from php function

I want to run php artisan passport:client --password from function.
I tryed Artisan::call('passport:client'); and Artisan::command('passport:client'); but it return undefined command
Note: I have alredy install laravel passport and the command is working fine from the terminal
I have found it, in boot() method of the PassportServiceProvider there is a check that essentially prevent it being called from Artisan::call.
//PassportServiceProvider.php at line 37:
if ($this->app->runningInConsole()) {
$this->commands([
Console\InstallCommand::class,
Console\ClientCommand::class,
Console\KeysCommand::class,
]);
...
}
to make it work with general artisan command, we can register these commands ourselves. somewhere within the boot method of AuthServiceProvider maybe.
public function boot() {
$this->commands([
Console\InstallCommand::class,
Console\ClientCommand::class,
Console\KeysCommand::class,
]);
}
Now we can call Artisan::call('passport:install') or the other 2 commands.
From Laravel Docs
Route::get('/foo', function () {
$exitCode = Artisan::call('email:send', [
'user' => 1, '--queue' => 'default'
]);
//
});
Import this line on top.
use Illuminate\Support\Facades\Artisan;
And Enter line below for command
Artisan::call('passport:client --password')

Categories