Laravel queue throws FatalThrowableError when trying to send mails - email

i am trying to send a mail on a named queue (registration.user) as soon as a new user registers in my laravel (5.7) application.
i have created a mailable and a job, the job is dispatched and is working fine util the queue starts running. the job is throwing an error and the stacktrace is pushed in the failed jobs table.
the job is as following:
<?php
namespace App\Jobs;
use App\Mail\testMail;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Mail;
class SendRegistrationMailJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* #var User
*/
private $user;
/**
* Create a new job instance.
*
* #param User $user
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
Mail::to($this->user->getAttribute('email'))->send(new testMail());
}
}
stacktrace (pastebin) (~ is where the project is)

it turned out to be a mistake I made while defining the queues, I just used the wrong syntax

Related

Laravel Mailable | ->from($this->input->mail)

I have created a
php artisan make:mail ContactFormFilledOut
which works nicely. But the only issue I have is that I cant access the the users mail to insert it to
->from('users-mail')
Im trying to get the users mail by doing this
$this->input->mail
but I get the error
Trying to get property 'mail' of non-object
so I tried also doing
$this->input['mail'].
This did not help either.
public function build()
{
return $this->view('mail.kontaktform')
->from($this->input->mail) // HERE IS THE ISSUE
->subject('Test subject');
}
Here we have all the code
class ContactFormFilledOut extends Mailable
{
use Queueable, SerializesModels;
public $input;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($input)
{
$this->input = $input;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('mail.kontaktform')
->from($this->input->mail) // HERE IS THE ISSUE
->subject('Test subject');
}
}
You can specify data which you want Laravel inject in in your constructor, In this case you want to have access to the email address of the user who is suppose to be the sender of that email. you can do that like this
use App\User;
class ContactFormFilledOut extends Mailable
{
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
/* ... */
}
Laravel will automaticaly inject the user who is authenticated and save it in the property user of the mailable.
You have that issue because Laravel doesn't know which object to inject when you add $input as parameter in the constructor of your mailable.
But you can overcome that is you instantiate munually the mailable and pass in the $input which can be any thing you want
$mailable = new ContactFromFilledOut($some_data);
$user = User::find(1);
Mail::to($user)
->send($mailable);

Add from and subject when sending mail using jobs and markdown

I am trying to change 'myemail#gmail.com' address to something like: no-reply#gmail.com and trying to add a custom address but I am unable to get it to work.
Which file do I add the subject and from?
my .env file
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=myemail#gmail.com
MAIL_PASSWORD=password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=no-reply#example.com
MAIL_FROM_NAME="Custom App Name"
controller code
dispatch(new JblockedUser($user));
jobs file
<?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\User;
use Carbon\Carbon;
use App\Mail\BlockedUser;
class JblockedUser implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $user;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$email = new BlockedUser($this->user);
Mail::to('example#gmail.com')->queue($email);
}
}
mail file
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class BlockedUser extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->markdown('emails.newsletter');
}
}
You can set the from and subject in your mailable build method. By default if no from address is provided, then laravel uses the global from address and name set in the config file. The default subject will be built using your mailable class name. In your case Blocked User would be the subject.
public function build()
{
return $this->from('no-reply#example.com')
->subject('Newsletter!!!')
->markdown('emails.newsletter');
}
Or if you need to specify the email and name.
public function build()
{
$from = [
'address' => 'no-reply#example.com',
'name' => 'Custom App Name'
];
return $this->from($from)
->subject('Newsletter!!!')
->markdown('emails.newsletter');
}
You might want to run php artisan config:clear in case your .env file changes aren't reflecting.

laravel : get Job id after retriving

how may i get access to a job id in laravel 5.2?
regarding to this link i have tried getJobId() , but doesn't work.
ofcourse when i get a log using dd() thers is an id but probably its protected.so i cant access it.
#job: {#459
+"id": 233
+"queue": "offers"
+"payload": "{"job":"Illuminate\\Queue\\CallQueuedHandler#call","data":....}"
+"attempts": 50
+"reserved": 0
+"reserved_at": null
+"available_at": 1464615540
+"created_at": 1464615540
}
In the L5.3 you can get Job Id this way
inside your job class
<?php
namespace App\Jobs;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class ParseUniversityData implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
protected $user;
/**
* Create a new job instance.
*
* #param $userId
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Execute the job.
*
* #throws \Exception
* #return void
*/
public function handle()
{
$jobId = $this->job->getJobId(); // this how you can get job id
}
}
the method where you dispatch your job (in this example I'm using action method in my controller)
public function someExampleAction(Request $request)
{
$requestData = $request->all();
$job = (new someExampleJob(
$requestData['property'], $user
));
$jobId = dispatch($job); // this is variable job id
}
public function handle()
{
$jobid=$this->job->getJobId();
}
you can get the job id by this method

API Platform : No resource found for object of type "AppBundle\Document\article"

i'm using symfony2 API platform to generate an api from my mongodb database but i get this error :
hydra:description: "No resource found for object of type "AppBundle\Document\article"",
i have two mongo db documents user and article and each user has multiple articles so i'm trying to list all the users with all their articles titles so i can get something like this :
{
#id: "/user/53edb6200cf2400d584c2617",
#type: "user",
class: "de.freelancer.mongo.domain.User",
email: "feer#de.com",
displayname: "feer",
withnewsletter: false,
language: "de_DE",
active: true,
admin: false,
articles : ['article1','article2','article3']
}
here is my code :
user Document
<?php
namespace AppBundle\Document;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Dunglas\ApiBundle\Annotation\Iri;
use Symfony\Component\Validator\Constraints as Assert;
/**
#MongoDB\Document
#MongoDB\Document(collection="user")
/
class User{
/*
#MongoDB\Id(strategy="AUTO") */
private $id;
/**
#MongoDB\ReferenceMany(targetDocument="articles", mappedBy="user") */
private $articles;
public function __construct()
{
$this->articles = new ArrayCollection();
}
/**
*/
public function getArticles()
{
return $this->articles;
}
}
articles document
<?php
namespace AppBundle\Document;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Dunglas\ApiBundle\Annotation\Iri;
use Symfony\Component\Validator\Constraints as Assert;
/**
#MongoDB\Document
#MongoDB\Document(collection="article")
/
class article
{
/*
#MongoDB\Id(strategy="AUTO") */
private $id;
/**
#MongoDB\ReferenceOne(targetDocument="user", inversedBy="articles") */
private $user;
/**
*/
public function setUser(userProfile $user)
{
$this->user = $user;
return $this;
}
/**
*/
public function getUser() {
return $this->user;
}
}
can any one help me to get the list of the user articles
thanks
Every class managed by API Platform needs to be marked with the #ApiPlatform\Core\Annotation\ApiResource annotation (or the equivalent in YAML or XML).
And there is no native MongoDB support yet (but this is a work in progress).
You can still add MongoDB support by yourself using a custom data provider, but if you're a newcomer to API Platform, you should try to use Doctrine ORM and follow the official tutorial first: https://api-platform.com/docs/distribution/

Injecting the Service Manager to Build a Doctrine Repository in ZF2

How do I inject the service manager into a Doctrine repository to allow me to retrieve the Doctrine Entity Manager?
I using the ZF2-Commons DoctrineORMModule and are trying to implement the repository example listed in the Doctrine Tutorial (bottom of tutorial in link below):
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html
However, I keep getting a message "Fatal error: Call to a member function get() on a non-object in C:\zendProject\zf2 ... ", which suggests that I do not have a working instance of the service locator.
My Doctrine repository looks like this:
namespace Calendar\Repository;
use Doctrine\ORM\EntityRepository,
Calendar\Entity\Appointment,
Calendar\Entity\Diary;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ApptRepository extends EntityRepository implements ServiceLocatorAwareInterface
{
protected $services;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->services = $serviceLocator;
}
public function getServiceLocator()
{
return $this->services;
}
public function getUserApptsByDate()
{
$dql = "SELECT a FROM Appointment a";
$em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$query = $em()->createQuery($dql);
return $query->getResult();
}
}
I then want to call this in my controller using the following pattern:
$diary = $em->getRepository('Calendar\Entity\Appointment')->getUserApptsByDate();
EDIT: The attached link suggests that I may need to convert the class to a service,
https://stackoverflow.com/a/13508799/1325365
However, if this is the best route, how would I then make my Doctrine Entity aware of the service. At the moment I include an annotation in the doc block pointing to the class.
#ORM\Entity (repositoryClass="Calendar\Repository\ApptRepository")
The way i approach things is this:
First i register a Service for each entity. This is done inside Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
'my-service-entityname' => 'My\Factory\EntitynameServiceFactory',
)
);
}
Next thing would be to create the factory class src\My\Factory\EntitynameServiceFactory.php. This is the part where you inject the EntityManager into your Entity-Services (not into the entity itself, the entity doesn't need this dependency at all)
This class looks something like this:
<?php
namespace My\Factory;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;
use My\Service\EntitynameService;
class EntitynameServiceFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$service = new EntitynameService();
$service->setEntityManager($serviceLocator->get('Doctrine\ORM\EntityManager'));
return $service;
}
}
Next thing in line is to create the src\My\Service\EntitynameService.php. And this is actually the part where you create all the getter functions and stuff. Personally i extend these Services from a global DoctrineEntityService i will first give you the code for the EntitynameService now. All this does is to actually get the correct repository!
<?php
namespace My\Service;
class EntitynameService extends DoctrineEntityService
{
public function getEntityRepository()
{
if (null === $this->entityRepository) {
$this->setEntityRepository($this->getEntityManager()->getRepository('My\Entity\Entityname'));
}
return $this->entityRepository;
}
}
This part until here should be quite easy to understand (i hope), but that's not all too interesting yet. The magic is happening at the global DoctrineEntityService. And this is the code for that!
<?php
namespace My\Service;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceManager;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
class DoctrineEntityService implements
ServiceManagerAwareInterface,
EventManagerAwareInterface
{
protected $serviceManager;
protected $eventManager;
protected $entityManager;
protected $entityRepository;
/**
* Returns all Entities
*
* #return EntityRepository
*/
public function findAll()
{
$this->getEventManager()->trigger(__FUNCTION__ . '.pre', $this, array('entities' => $entities));
$entities = $this->getEntityRepository()->findAll();
$this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array('entities' => $entities));
return $entities;
}
public function find($id) {
return $this->getEntityRepository()->find($id);
}
public function findByQuery(\Closure $query)
{
$queryBuilder = $this->getEntityRepository()->createQueryBuilder('entity');
$currentQuery = call_user_func($query, $queryBuilder);
// \Zend\Debug\Debug::dump($currentQuery->getQuery());
return $currentQuery->getQuery()->getResult();
}
/**
* Persists and Entity into the Repository
*
* #param Entity $entity
* #return Entity
*/
public function persist($entity)
{
$this->getEventManager()->trigger(__FUNCTION__ . '.pre', $this, array('entity'=>$entity));
$this->getEntityManager()->persist($entity);
$this->getEntityManager()->flush();
$this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array('entity'=>$entity));
return $entity;
}
/**
* #param \Doctrine\ORM\EntityRepository $entityRepository
* #return \Haushaltportal\Service\DoctrineEntityService
*/
public function setEntityRepository(EntityRepository $entityRepository)
{
$this->entityRepository = $entityRepository;
return $this;
}
/**
* #param EntityManager $entityManager
* #return \Haushaltportal\Service\DoctrineEntityService
*/
public function setEntityManager(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
return $this;
}
/**
* #return EntityManager
*/
public function getEntityManager()
{
return $this->entityManager;
}
/**
* Inject an EventManager instance
*
* #param EventManagerInterface $eventManager
* #return \Haushaltportal\Service\DoctrineEntityService
*/
public function setEventManager(EventManagerInterface $eventManager)
{
$this->eventManager = $eventManager;
return $this;
}
/**
* Retrieve the event manager
* Lazy-loads an EventManager instance if none registered.
*
* #return EventManagerInterface
*/
public function getEventManager()
{
return $this->eventManager;
}
/**
* Set service manager
*
* #param ServiceManager $serviceManager
* #return \Haushaltportal\Service\DoctrineEntityService
*/
public function setServiceManager(ServiceManager $serviceManager)
{
$this->serviceManager = $serviceManager;
return $this;
}
/**
* Get service manager
*
* #return ServiceManager
*/
public function getServiceManager()
{
return $this->serviceManager;
}
}
So what does this do? This DoctrineEntityService pretty much is all what you globally need (to my current experience). It has the fincAll(), find($id) and the findByQuery($closure)
Your next question (hopefully) would only be "How to use this from my controller now?". It's as simple as to call your Service, that you have set up in the first step! Assume this code in your Controllers
public function someAction()
{
/** #var $entityService \my\Service\EntitynameService */
$entityService = $this->getServiceLocator()->get('my-service-entityname');
// A query that finds all stuff
$allEntities = $entityService->findAll();
// A query that finds an ID
$idEntity = $entityService->find(1);
// A query that finds entities based on a Query
$queryEntity = $entityService->findByQuery(function($queryBuilder){
/** #var $queryBuilder\Doctrine\DBAL\Query\QueryBuilder */
return $queryBuilder->orderBy('entity.somekey', 'ASC');
});
}
The function findByQuery() would expect an closure. The $queryBuilder (or however you want to name that variable, you can choose) will be an instance of \Doctrine\DBAL\Query\QueryBuilder. This will always be tied to ONE Repository though! Therefore entity.somekey the entity. will be whatever repository you are currently working with.
If you need access to the EntityManager you'd either only instantiate only the DoctrineEntityService or call the $entityService->getEntityManager() and continue from there.
I don't know if this approach is overly complex or something. When setting up a new Entity/EntityRepository, all you need to do is to add a new Factory and a new Service. Both of those are pretty much copy paste with two line change of code in each class.
I hope this has answered your question and given you some insight of how work with ZF2 can be organized.
As long as you extend the Doctrine\ORM\EntityRepository, you have immediate access to the entity manager by calling EntityRepository::getEntityManager() or the $_em attribute. The inheritence from the Doctrine\ORM\EntityRepository class allow you to do so.
Your method should now look like this:
public function getUserApptsByDate()
{
$dql = "SELECT a FROM Appointment a";
$em = $this->getEntityManager();// Or $em=$this->_em;
$query = $em()->createQuery($dql);
return $query->getResult();
}
I always keep in mind that access to my data should go from the web front (Zend MVC, Service Manager) to the persistence layer (Doctrine). My persistence (entities, repositories...) layer should not refer to the web front or neither know that it exists. If my system is doing the inverse at some level, then probably I'm doing something wrong.
Happy end of year