Laravel Websocket, and Queue Error (Serialization of 'Closure' is not allowed) - laravel

Im currently having a problem where I can't queue a job inside a websocket server, my objective is to fire a background job in a specified date and time
I'm having an error that says "An error has occurred: Serialization of 'Closure' is not allowed"
here's is my current code
<?php namespace App;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use App\Http\Controllers\WinIt;
use Cache;
use Carbon\Carbon;
use Session;
use Queue;
// Command Classes
use App\Commands\WinItInit;
class WebsocketServer implements MessageComponentInterface {
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
$this->clients->attach($conn);
// Fire event when current date and time reaches $datetime
$datetime = '2016-02-10 15:48:08';
$serialization = Queue::later($datetime, new WinItInit($conn, $this->clients));
}
}
// The command to fire
<?php namespace App\Commands\WinIt;
use App\Commands\Command;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldBeQueued;
// Class Aliases
use DB;
use Input;
use Queue;
use Request;
use Response;
use Session;
use URL;
use Illuminate\Http\Exception;
use Illuminate\Support\Facades\Artisan;
// Custom Classes
class WinItInit extends Command implements SelfHandling, ShouldBeQueued {
use InteractsWithQueue, SerializesModels;
private $from = null;
private $clients = null;
/**
* Create a new command instance.
*
* #return void
*/
public function __construct($from = null, $clients = null)
{
$this->from = $from;
$this->clients = $clients;
$this->type = 'sample';
}
/**
* Execute the command.
*
* #return void
*/
public function handle()
{
$data = array();
switch ($this->type)
{
case 'sample':
$datetime = date('Y-m-d H:i:s', time());
break;
}
foreach ($this->clients as $client)
{
$client->send(json_encode($data));
}
}
}

Related

Laravel problem passing variables from controller to mailer

I am having trouble passing variables from the controller to the mail fucntion I have tried to search it up on google but didn't find anything that works my goal is to get the variable from the form to the welcomemail.blade the current issue is that the variable doesnt get to my wlcomemail.php from the controller. the mailing part itself does work.
Controller code:
$email_data = array(
'first_name'=>'John',
'last_name'=>'Doe',
'email'=>'john#doe.com',
'password'=>'temp',
);
//Customer::create($data);
Mail::to($email_data['email'])->send(new welcomemail($email_data));
welcomemail.php code:
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class welcomemail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public $email_data;
public $example;
public function __construct()
{
$this->email_data = $email_data;
$this->example = 'example';
}
public function build()
{
return $this->markdown('emails.welcomemail');
}
}
blade code:
# Introduction
Welcome.
{{$email_data['first_name']}}
{{$example}}
#endcomponent
change this:
public function __construct()
{
$this->email_data = $email_data;
$this->example = 'example';
}
to:
public function __construct($email_data)
{
$this->email_data = $email_data;
$this->example = 'example';
}
now you have it in your mail class
it should work

Cannot declare class App\User, because the name is already in use Laravel

I want to add user address in address table and want to update the address_id in user table for that i'm using user model and address model, data is being saved in address table but when i use User model in Address Repository
use App\Models\User;
i get
Cannot declare class App\User, because the name is already in use
Here is my code :
<?php
namespace App\Repositories;
use App\Models\Addresses;
use App\Models\User;
use App\Contracts\AddressContract;
use Illuminate\Database\QueryException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Doctrine\Instantiator\Exception\InvalidArgumentException;
class AddressRepository extends BaseRepository implements AddressContract
{
/**
* AttributeRepository constructor.
* #param Attribute $model
*/
public function __construct(Addresses $model)
{
parent::__construct($model);
$this->model = $model;
}
public function addAddress(array $params)
{
try {
$Addresses = new Addresses($params);
$Addresses->save();
$addressId = $Addresses->id;
$userID=auth()->user()->id;
if($params['is_primary_address']==1)
{
User::where('id',$userID)->update(['address_id'=>$addressId]);
}
return $Addresses;
}
catch (QueryException $exception) {
throw new InvalidArgumentException($exception->getMessage());
}
}
}
ProductController.php
<?php
namespace App\Http\Controllers\Site;
use App\Contracts\AttributeContract;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Contracts\ProductContract;
use App\Contracts\AddressContract;
use Cart;
use Validator;
class ProductController extends Controller
{
protected $productRepository;
protected $attributeRepository;
protected $addressRepository;
public function __construct(ProductContract $productRepository, AttributeContract $attributeRepository, AddressContract $addressRepository)
{
$this->productRepository = $productRepository;
$this->attributeRepository = $attributeRepository;
$this->addressRepository = $addressRepository;
}
public function addUserAddress(Request $request)
{
$customer_name=$request->customer_name;
$customer_address=$request->customer_address;
$country=$request->country;
$city=$request->city;
$zip_code=$request->zip_code;
$state=$request->state;
$address_type=$request->address_type;
$is_primary_address=$request->primary_address;
$userID=auth()->user()->id;
$data=array('name'=>$customer_name,'address'=>$customer_address,'country'=>$country,'state'=>$state,'city'=>$city,'address_type'=>$address_type,'user_id'=>$userID,'is_primary_address'=>$is_primary_address);
$userAddress = $this->addressRepository->addAddress($data);
return redirect()->back()->with('message', 'Address Added');
}
}

How can I add condition on mail notification laravel?

I use laravel 5.3
My notication laravel like this :
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Notifications\Messages\BroadcastMessage;
class GuestRegistered extends Notification implements ShouldBroadcast, ShouldQueue
{
use Queueable;
private $data;
public function __construct($data)
{
$this->data = $data;
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new MailMessage)
->subject('test')
->greeting('Hi')
->line('Thanks')
->line('Your password : '.$this->data)
->action('Start Shopping', url('/'));
}
}
I want to add condition in toMail method
So if $this->data not exist then ->line('Your password : '.$this->data) not display or not executed
How can I do it?
Add a default value for the $data parameter in the constructor .
public function __construct($data = null)
{
$this->data = $data;
}
Then you can store the instance of MailMessage in a variable and use the if statement to add the line() you want.
public function toMail($notifiable)
{
$mailMessage = new MailMessage();
$mailMessage
->subject('test')
->greetings('Hi')
->line('Thanks');
if($this->data) {
$mailMessage->line('Your password: ' . $this->data);
}
$mailMessage->action('Start Shopping', url('/'));
return $mailMessage;
}

Creating Email queue in Laravel

Newsletter.php
<?php
namespace App\Mail;
use App\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Http\Request;
class Newsletter extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public $order;
public function __construct($order)
{
$this->order = $order;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('mail', $this->order)->subject($this->order['subject']);
}
}
SendReminderEmail.php
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Mail;
use App\Mail\Newsletter;
use App\User;
class SendReminderEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
public $order, $email;
public function __construct($order, $emails)
{
$this->order = $order;
$this->email = $emails;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
//for($i=0;$i<count($this->email);$i++)
Mail::to($this->email)->queue(new Newsletter($this->order));
}
}
Controller
public function sendSubMail(Request $request){
$data = ['text' => $request->input('message'), 'subject' => $request->input('subject')];
$emails = DB::table('emails')->get();
for ($i=0; $i < count($emails); $i++) {
try {
Mail::to($emails[$i])->queue(new Newsletter($data));
//dispatch((new Job)->onQueue('high'))
dispatch(new SendReminderEmail($data, $emails[$i]));
} catch (Exception $e) {
}
}
return view('emailSent', ['sub' => 'Emails successfully sent']);
}
Can anyone explain me how to create an Email queue in laravel. I tried many ways but none of them seems to work.
I'm trying to send email using queues. I have to send more than 1500 in the request. but the queue which I implemented doesnt seem to work. Please help.
Thanks in advance
Using Cron to send mail One Method

How to test job arguments in Laravel?

How to test job arguments if Exception is thrown after job is dispatched. This test below returns green, but i found no way to test job arguments.
Code:
<?php
namespace Tests\Feature;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Tests\TestCase;
class SomeJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle() {}
}
class NothingTest extends TestCase
{
/** #test */
public function dispatch_test()
{
$this->expectException(\Exception::class);
$this->expectsJobs(SomeJob::class);
// job dispatched and Exception thrown afterwards
dispatch(new SomeJob("argument to test"));
throw new \Exception();
}
}
I actually ran into this earlier today myself. What I did to solve this issue was by using the withoutJobs() method instead. (Internally expectsJobs() calls this as well.) You can then assert against the dispatchedJobs property.
Because you are also 'expecting' and exception in your test you should wrap this in a callback and register it in a beforeApplicationDestroyed()
class SomeJob {
private $argument;
public function __construct($argument)
{
$this->argument = $argument;
}
}
class NothingTest extends TestCase
{
/** #test */
public function dispatch_test()
{
$this->expectException(\Exception::class);
$this->beforeApplicationDestroyed(function () {
// This part depends on how you would like to design this. You could
// use public properties, add a getter method on your job or use
// something like reflection to compare the properties.
$dispatchedJob = $this->dispatchedJobs[0];
$this->assertEquals(
'argument to test',
$this->getValue($dispatchedJob, 'argument')
);
});
// job dispatched and Exception thrown afterwards
dispatch(new SomeJob("argument to test"));
throw new \Exception();
}
protected function getValue($object, $name)
{
$ro = new \ReflectionObject($object);
$property = $ro->getProperty($name);
$property->setAccessible(true);
return $property->getValue($object);
}
}
ok. can test like this code below.
test looks nice, but you must use public properties and assign all arguments to the properties.
<?php
namespace Tests\Examples;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Tests\TestCase;
class SomeJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $arg1;
public $arg2;
public function __construct($arg1, $arg2)
{
$this->arg1 = $arg1;
$this->arg2 = $arg2;
}
public function handle() {}
}
class JobTest extends TestCase
{
/** #test */
public function dispatch_test()
{
$this->expectException(\Exception::class);
$this->expectsJobs(SomeJob::class);
$this->testJobInstance(SomeJob::class, function($job){
$this->assertEquals('arg1', $job->arg1);
$this->assertEquals('arg2', $job->arg2);
});
// job dispatched and Exception thrown afterwards
dispatch(new SomeJob("arg1", "arg2"));
throw new \Exception();
}
// will be pushed up to TestCase
protected function testJobInstance($class, callable $callback)
{
$this->beforeApplicationDestroyed(function () use($class, $callback) {
$job = collect($this->dispatchedJobs)->filter(function($job) use($class) {
return get_class($job) == $class;
})->first();
$callback($job);
});
}
}
Ok, the better way found...
I've made a helper function to dispatch jobs from IOC - it makes a lot easier to test jobs.
/**
* #param string | object $job
* #param array | null $args - associative array of arguments ['agr1' => 'value', 'arg2' => 2]
* #return mixed
*/
function dispatch_from_ioc($job, ? array $args)
{
if (is_string($job)) {
$job = app()->makeWith($job, $args);
}
return app(Dispatcher::class)->dispatch($job);
}
so now i can test job arguments like this:
/** #test */
public function test_jobs_arguments()
{
$this->app->bind(
RealJob::class,
function($app, $args){
// assertions against arguments
$this->assertEquals("argument", $args["arg"]);
$this->assertEquals([], $args["arg2"]);
return new FakeJob;
}
);
// System under test
dispatch_from_ioc(RealJob::class, ["arg" => "argument", "arg2" => []]);
}
Fake Job class
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class FakeJob extends Job
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct() {}
public function handle() {}
}
Does it makes sense? :)

Resources