Laravel mail provide sender detail - php

I need to get my user email address along with form data in order to set ->from() in my mailable file
code
controller function
public function store(Request $request)
{
$request->validate([
'product' => 'required|string',
'email' => 'required|email',
'message' => 'required|string',
]);
$user = $request->user(); // need to add this
$inquery = new Inquery;
$inquery->user_id = $user->id;
$inquery->product = $request->input('product');
$inquery->email = $request->input('email');
$inquery->message = $request->input('message');
$inquery->save();
Mail::to('xyz#example.com')->send(new InquiryToAdmin($inquery));
}
Mailable file
class InquiryToAdmin extends Mailable
{
use Queueable, SerializesModels;
public $data;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from($user['email'])->subject('New Inquiry was sent')->view('emails.inquiry.admin');
}
}
NOTE:
What I need is to get ->from($user['email']) for that i need to send my $user from controller to mailable file (commented in code), the problem is I cannot set $user to be send to my mailable file.
Any idea?

try this
Mail::to('xyz#example.com')->send(new InquiryToAdmin($inquery,$user));
class InquiryToAdmin extends Mailable
{
use Queueable, SerializesModels;
public $data;
protected $user;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($data,$user)
{
$this->data = $data;
$this->user = $user;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from($this->user->email)->subject('New Inquiry was sent')->view('emails.inquiry.admin');
}
}

Related

How to dynamically define the subject of emails in mailable - Laravel

Here is the piece of code. My idea is that each email comes out with one of the values/entry ​​from one of my tables.
public function __construct($siniestro)
{
$this->siniestro = $siniestro;
$this->subject = {{ $siniestro->siniestro }};
}
[from this place I want to get my subject][1]
[1]: https://i.stack.imgur.com/D0PNO.png
this is all the code of my mailable
class ContactanosMailable extends Mailable
{
use Queueable, SerializesModels;
$this->subject = $siniestro->siniestro;
public $siniestro;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($siniestro)
{
$this->siniestro = $siniestro;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.contactanos');
}
}
If I can add something else just let me know, and I will.
I hope this can reach, it's getting complicated
I would do it like that :
class ContactanosMailable extends Mailable
{
use Queueable, SerializesModels;
public $siniestro;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($siniestro)
{
$this->siniestro = $siniestro;
// set the subject property
$this->subject = $siniestro->siniestro;
// or use the subject method
$this->subject($siniestro->siniestro);
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.contactanos');
}
}
using the subject() method looks cleaner but both works
public function build(){
$from_email = "test#mail.com";
$subject = "Account Request";
return $this->from($from_email)->subject($subject)->view('emails.contactanos')
;
}

why I can't store new column in laravel notification table?

any way every thing is save in data column
<?php
namespace App\Notifications;
class SendNotification extends Notification implements ShouldQueue
{
use Queueable;
public $message;
public $model_instance;
private $log;
/**
* Create a new notification instance.
*
* #param $message
* #param array $log
* #param Model $model_instance
*/
public function __construct($message, array $log = [],Model $model_instance = null )
{
$this->message = $message;
$this->log = $log;
$this->model_instance = $model_instance->id;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return [MicroserviceChannel::class, 'database'];
}
public function toMicroservice($notifiable)
{
return $this->message;
}
public function toDatabase($notifiable)
{
return $this->log;
}
public function toArray() {
return [
'group_id' => $this->model_instance
];
}
}
this is all of my notification class
but I add new column as group_id to this table
now nothing isn't store in data column
detailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetailsdetails
because it need more details :)
make sure add group_id in fillable in your model
toArray and toDatabase methods of notification classes must return a plain Array as explain here Formatting Database Notifications.
Just ensure toDatabase return a plain Array like toArray.
I can presume $this->id is the ID of the Model instance which the Notification is related to. So you must pass that model when you instanciate the notification class like this
$user->notify(new NotificationClass($model_instance));
Here I use $user->notify you can use any Model of classes which use Notifiable.
And in the NotificationClass you'll receive the $model_instance in the Constructor like this
class NotificationClass extends Notification {
public $model_instance;
public function __construct(Model $model_instance){
$this->model_instance = $model_instance;
}
public function toArray() {
return [
'group_id' => $this->model_instance->group_id;
];
}
}
You will have to pass the $group_id value when you call your notification like
$group_id=1;
$user->notify(new ActionsNotification($group_id));
and then in your created notification
protected $group_id;
public function __construct($group_id)
{
$this->group_id= $group_id;
}
public function toDatabase($notifiable)
{
return [
'group_id' => $this->group_id
];
}

How can i test mail sending using phpunit?

I have a mailable class which I use to send an email to users, which works fine. I want to write some phpunit test to check if the mail is actually sent. Unfortunately, I couldn't find a good explanation in the documentation.
My mailable class:
class UserInvite extends Mailable
{
use Queueable, SerializesModels;
public $user;
public $inviteMessage;
/**
* Create a new message instance.
*
* #param User $user
* #param string $inviteMessage
*/
public function __construct(User $user, string $inviteMessage)
{
$this->user = $user;
$this->inviteMessage = $inviteMessage;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.mail');
}
}
Test:
/** #test */
public function it_sends_invite()
{
Mail::fake();
$user = factory(User::class)->create();
$inviteMessage = 'test';
Mail::assertSent(new UserInvite($user, $inviteMessage));
}
Error:
ErrorException: Object of class App\Mail\UserInvite could not be converted to string
Solution:
/** #test */
public function it_sends_invite()
{
Mail::fake();
$user = factory(User::class)->create();
Mail::to($user)->send(new UserInvite($user, 'message'));
Mail::assertSent(UserInvite::class);
}
When testing for sent mails, you don't pass a whole mailable instance. PHPUnit wouldn't be able to compare a full object anyway. Instead, you just pass the fully qualified class name:
// use App\Mail\UserInvite;
Mail::assertSent(UserInvite::class);

Laravel Trying to get property of non-object when sending emails

I'm making a function that each time I add a comment to a Support ticket it sends an email to the user but I'm getting getting Trying to get property of non-object when I submit the comment this only happens if I'm logged out of the users account and only logged into the Admin user
AdminComment Controller Code
<?php
namespace App\Http\Controllers;
use App\Comment;
use App\Mailers\AppMailer;
use App\Ticket;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminCommentController extends Controller
{
public function postComment(Request $request, AppMailer $mailer)
{
$this->validate($request, [
'comment' => 'required',
]);
$comment = Comment::create([
'ticket_id' => $request->input('ticket_id'),
'user_id' => Auth::user()->id,
'comment' => $request->input('comment'),
]);
$mailer->sendTicketComments($comment->ticket->user, Auth::user(), $comment->ticket, $comment);
return redirect()->back()->with('warning', 'There was a problem sending your comment to the customer via email');
}
}
here is the Mailer Controller
<?php
namespace App\Mailers;
use App\Status;
use App\Ticket;
use Illuminate\Contracts\Mail\Mailer;
class AppMailer
{
protected $mailer;
/**
* email to send to.
*
* #var [type]
*/
protected $to;
/**
* Subject of the email.
*
* #var [type]
*/
protected $subject;
/**
* view template for email.
*
* #var [type]
*/
protected $view;
/**
* data to be sent along with the email.
*
* #var array
*/
protected $data = [];
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
/**
* Send Ticket information to the user.
*
* #param User $user
* #param Ticket $ticket
*
* #return method deliver()
*/
public function sendTicketInformation($user, Ticket $ticket)
{
$statuses = Status::all();
$this->to = $user->email;
$this->subject = "TechWiseDirect Support Ticket - [Reference #: $ticket->ticket_id]";
$this->view = 'users.emails.ticket_info';
$this->data = compact('user', 'ticket', 'statuses');
return $this->deliver();
}
/**
* Send Ticket Comments/Replies to Ticket Owner.
*
* #param User $ticketOwner
* #param User $user
* #param Ticket $ticket
* #param Comment $comment
*
* #return method deliver()
*/
public function sendTicketComments($ticketOwner, $user, Ticket $ticket, $comment)
{
$this->to = $ticketOwner->email;
$this->subject = "RE:[Ticket ID: $ticket->ticket_id]";
$this->view = 'users.emails.ticket_comments';
$this->data = compact('ticketOwner', 'user', 'ticket', 'comment');
return $this->deliver();
}
/**
* Do the actual sending of the mail.
*/
public function deliver()
{
$this->mailer->send($this->view, $this->data, function ($message) {
$message->from('test#test')
->to($this->to)->subject($this->subject);
});
}
}
the error happens for the Auth::user()->id I think. it's because you are logged out of your account. my guess is that you haven't used guard and only have one main user model defined for laravel.

Persisting Updated Objects in Symfony

I have a symfony application where I am attempting to update an entity in the database using a setter. However when I update the entity and call $this->em->flush() the entity is not persisted to the database.
Here is my service:
<?php
namespace AppBundle\Service;
use AppBundle\Exceptions\UserNotFoundException;
use Doctrine\ORM\EntityManager;
use AppBundle\Entity\User;
/**
* Class MyService
* #package AppBundle\Service
*/
class MyService extends BaseService {
/**
* #var EntityManager
*/
protected $em;
/**
* #var User
*/
protected $user;
/**
* MyService constructor.
* #param EntityManager $em
*/
public function __construct(EntityManager $em){
$this->em = $em;
}
/**
* See if a user email exists
* #param string $email
* #return bool
*/
public function checkEmailExists($email){
$this->user = $this->em
->getRepository('AppBundle:User')
->findOneBy(['email' => $email]);
return !(is_null($this->user));
}
/**
* add credit to a users account
* #param User $user
* #param integer $credit
*/
public function addCredit(User $user, $credit){
$user->addCredit($credit);
$this->em->flush();
}
/**
* add a credit to a users account
* #param $email
* #param $credit
*/
public function addCreditByEmail($email, $credit){
if(!($this->checkEmailExists($email))){
throw new UserNotFoundException(sprintf('User with email %s not found.', $email));
}
$this->addCredit($this->user, $credit);
}
}
Here is my test:
<?php
namespace AppBundle\Tests\Service;
use AppBundle\DataFixtures\ORM\PurchaseFixture;
use AppBundle\Entity\Vendor;
use AppBundle\Repository\OfferRepository;
use AppBundle\Tests\TestCase;
use AppBundle\Entity\Offer;
use AppBundle\DataFixtures\ORM\OfferFixture;
use AppBundle\DataFixtures\ORM\PaymentSystemFixture;
/**
* Class UserOfferServiceTest
* #package AppBundle\Tests\Service
*/
class MyServiceTest extends TestCase implements ServiceTestInterface
{
function __construct($name = null, array $data = [], $dataName = '')
{
$this->setFixtures([
'AppBundle\DataFixtures\ORM\CityFixture',
'AppBundle\DataFixtures\ORM\CountryFixture',
'AppBundle\DataFixtures\ORM\PaymentSystemFixture',
'AppBundle\DAtaFixtures\ORM\UserFixture',
]);
parent::__construct($name, $data, $dataName);
}
/**
* test the checkEmailExists() of app.vendor
*/
public function testCheckEmailExists(){
$myService = $this->getService();
$this->assertTrue($myService->checkEmailExists('user1#user1.com'));
$this->assertFalse($myService->checkEmailExists($this->fake()->safeEmail));
}
/**
* test the addCredit functionality
*/
public function testAddCredit(){
$myService = $this->getService();
$user = $this->getUser();
$this->assertEquals(0, $user->getCredit());
$toAdd = $this->fake()->numberBetween(1, 500);
$myService->addCredit($user, $toAdd);
$this->assertEquals($toAdd, $user->getCredit());
}
/**
* test the addCreditByEmail functionality
*/
public function testAddCreditByEmail(){
$myService = $this->getService();
$user = $this->getUser();
$email = $this->getUser()->getEmail();
$this->assertEquals(0, $user->getCredit());
$toAdd = $this->fake()->numberBetween(1, 500);
$myService->addCreditByEmail($email, $toAdd);
$updatedUser = $this->getEntityManager()
->getRepository('AppBundle:User')
->findOneBy(['email' => $email]);
$this->assertEquals($toAdd, $updatedUser->getCredit());
}
/**
* #return \AppBundle\Service\VendorService|object
*/
public function getService(){
$this->seedDatabase();
$this->client = $this->createClient();
return $this->client->getContainer()->get('app.admin_kiosk');
}
}
The testAddCredit() test passes (because I'm checking the same object), but the testAddCreditByEmail fails with the following error: 1) AppBundle\Tests\Service\MyServiceTest::testAddCreditByEmail
Failed asserting that null matches expected 149.
I've tried persisting the entity, flushing the entity (like: $this->em->flush($user)) all to no avail. Please let me know how I can fix this.
I found the issue.
In the test case I just had to refresh the entity by doing $this->getEntityManager()->refresh($user) (on the original $user entity). Thanks!

Categories