How to load object into Laravel 5.5 Mailable? - laravel

I'm trying to test a mailable class for a Laravel 5.5 application, and have seemingly followed all the directions here.
I've been trying to preview my mailable in the browser, but for some reason the object that I pass to my mailable class is not passing correctly, and is showing as null from inside the mailable class even though I can see that it exists outside of it.
Here is the function in my web.php file that I'm using to test the mailable in the browser:
Route::get('/testingMailable', function () {
$review = App\EvaluationReview::find(6);
return new App\Mail\StartReview($review);
});
The object is populating as it should above, but when I try to view it inside the mailable class, it is null:
<?php
namespace App\Mail;
use App\EvaluationReview;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class StartReview extends Mailable
{
use Queueable, SerializesModels;
public $review;
public function __construct(EvaluationReview $review)
{
$this->$review = $review;
dd($this->review);//is null
}
public function build()
{
return $this->from('test#test.com')->view('startReview');
}
}
Does anyone know why the object is not getting passed into the mailable class?

You have a typo in your code.
Change:
$this->$review = $review;
To:
$this->review = $review;

Related

Return value must be of type Laravel 10

I am working on a Laravel 10 project and trying to create a controller that displays records. However, I have run into a problem while attempting to do so :
App\Http\Controllers\StudentController::index(): Return value must be of type Illuminate\Http\Response, Illuminate\View\View returned
I have attached below what I have tried so far:
Student Controller
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Models\Student;
class StudentController extends Controller
{
public function index(): Response
{
$students = Student::all();
return view ('students.index')->with('students', $students);
}
If I remove the Response class, the code works, but I need to implement the Laravel 10 standard. I am unsure how to solve this issue. Can you please provide a solution?
Routes
Route::resource("/student", StudentController::class);
Laravel utilized all of the type-hinting features available in PHP at the time. However, many new features have been added to PHP in the subsequent years, including additional primitive type-hints, return types, and union types.
Release notes.
If you are using view function, you need to use the Illuminate\View\View class for type-hinting.
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
use App\Models\Student;
class StudentController extends Controller
{
public function index(): View
{
$students = Student::all();
return view('students.index')
->with('students', $students);
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Models\CatalogueModel;
use Illuminate\Contracts\View\View;
class StudentController extends Controller
{
public function index(): View
{
$data['students'] = Student::all();
return view('students.index')->with($data);
}
}

Laravel Mail: Markdown Email [ Class "Illuminate\Mail\Mailables\Content" not found ]

I am getting a super strange error when I am creating a markdown email with Laravel.
I have a simple Markdown email (code below), the issue is with line 43 at "return new Content("
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;
use Illuminate\Mail\Mailables\Envelope;
use App\Models\User;
class RegisteredUser extends Mailable
{
use Queueable, SerializesModels;
protected $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function content()
{
return new Content(
view: 'users.register.new',
with: [
'name' => $this->name,
],
);
}
public function build()
{
return $this->content();
// return $this->markdown('users.register.new');
}
}
The error I get is:
local.ERROR: Class "Illuminate\Mail\Mailables\Content" not found {"exception":"[object] (Error(code: 0): Class \"Illuminate\\Mail\\Mailables\\Content\" not found at www/app/Mail/RegisteredUser.php:43)
How is that possible? Shouldn't that be included with Laravel 9? (9.19)
How do I fix this?
Turns out the syntax I am using was introduced in Laravel 9.3 so I had to update Laravel using:
composer update.
PS. I was able to solve this from the help of Laravel's official discord group. Thank you <3

Laravel 8 Tests: PHPUnit error: Unknown formatter "unique"

I have written a test that involves a factory. When I execute the test, I get this error:
The data provider specified for Tests\Unit\ExampleTest::testTakePlace is invalid. InvalidArgumentException: Unknown formatter "unique" /var/www/html/api/vendor/fakerphp/faker/src/Faker/Generator.php:249
Expected result
This error should not be shown, I should be able to use $this->faker->unique().
How I tried to fix this problem
By reading the doc again and again (no difference was found) and by reading questions&answers on the Internet (only one question & only one answer were found: to extend Laravel's TestCase but the official documentation, as I mentionned it, says the contrary). (Laravel's TestCase is provided by use Illuminate\Foundation\Testing\TestCase;)
Question
Why doesn't it work and how to fix this bug?
Sources
Test sources
It extends PHPUnit\Framework\TestCase (not Laravel's TestCase) because the documentation says to extend it. Indeed: https://laravel.com/docs/8.x/testing#creating-and-running-tests . This is not the only part of the doc mentionning to extend it.
<?php
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use App\Models\Project;
class ExampleTest extends TestCase
{
/**
* #dataProvider provideTakePlaceData
*/
public function testTakePlace($project)
{
$response = $this->json('GET', '/controllerUserProject_takePlace', [
'project_id' => $project->id
]);
}
public function provideTakePlaceData() {
return [
Project::factory()->make()
];
}
}
Controller
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ControllerUserProject extends Controller
{
public function takePlace(Request $request, $project_id)
{
return;
}
}
The most important: the factory
<?php
namespace Database\Factories;
use App\Models\Project;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class ProjectFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Project::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'id' => $this->faker->unique()->numberBetween(1, 9000),
];
}
}
Change:
use PHPUnit\Framework\TestCase;
to:
use Tests\TestCase;
Why?
When your ExampleTest extends PHPUnit\Framework\TestCase Laravel app is never initialized in tests, and so you don't have access to Laravel features like factories.
The documentation tells you to extend PHPUnit\Framework\TestCase;, but it refers to Unit tests. Feature tests should extend Tests\TestCase. This is something pretty new. Until Laravel 5.8 both unit and feature tests were extending Tests\TestCase by default. I personally just define all tests as feature tests to avoid such issues.
The problem was due to the use of a dataProvider with the use of the factories. More precisely: PHPUnit data providers should not be used when Laravel factories are.
If you are using faker in Factories please make sure these are working correctly regardless (as per example try running Project::factory()->make(); within Laravel Tinker and see the results)
Second common issue (as mentioned above) is the class that you extend your Test with - see above
Third and frequently omitted one that's causing this error, is a missing parent constructor call in the setUp() - (if you use it)
<?php
namespace Tests\Unit;
use Tests\TestCase;
use App\Models\Project;
class ExampleTest extends TestCase
{
protected Project $project;
public function setUp(): void
{
parent::setUp();
$this->project = Project::factory()->make();
}
I think you need to use the WithFaker trait to use faker :
<?php
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use App\Models\Project;
use Illuminate\Foundation\Testing\WithFaker;
class ExampleTest extends TestCase
{
use WithFaker;
// ...
}

Problems trying to send email with Laravel 5.5

I made an API with Laravel and it is registering the data correctly
Now I'm trying to get this to trigger registration confirmation emails, however these are not going
I'm using Mailtrap for the tests
In .env I put like this:
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=291ac7fdcf52bb
MAIL_PASSWORD=610b2e5e9782d3
No Http/Mail/DataManifestMail.php tenho:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class DataManifestMail extends Mailable
{
use Queueable, SerializesModels;
protected $inputs;
public function __construct($inputs)
{
$this->inputs = $inputs;
}
public function build()
{
return $this->view('mails.data');
}
}
In views/mails/data.blade.php I only have one warning message:
<h1>Test e-mail</h1>
Then in my Http/Controller/ManifestationController.php I put it like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Manifestation;
use App\Mail\DataManifestationMail;
use Mail;
class ManifestationController extends Controller
{
private $manifestation;
public function __construct(Manifestation $manifestation)
{
$this->manifestation = $manifestation;
}
public function store(Request $request)
{
$nr = Manifestation::max('nrmanifestation');
$this->manifestation->nrmanifestation = $nr + 1;
$this->manifestation->dspass = $request->dspass;
$this->manifestation->eeemail = $request->eeemail;
$this->manifestation->address = $request->address;
$this->manifestation->name = $request->name;
$this->manifestation->latitude = $request->latitude;
$this->manifestation->longitude = $request->longitude;
$this->manifestation->save();
Mail::to('vazag#c1oramn.com')->send(new DataManifestationMail());
return response()->json([
'result' =>
$this->manifestation->nrmanifestation
]);
}
}
I have reread the documentation and my code several times and have not found any errors
What can it be?
There might be multiple reasons:
configuration is cached (use php artisan config:cache)
you used invalid mailtrap data (you should have log in laravel.log file)
your server has somehow blocked 2525 port
Also looking at your code it seems you miss passing $input parameter to constructor. You have:
public function __construct($inputs)
but you run:
->send(new DataManifestationMail());
without passing any value

Call to undefined method Illuminate\Notifications\Notification::send()

I am trying to make a notification system in my project.
These are the steps i have done:
1-php artisan notifications:table
2-php artisan migrate
3-php artisan make:notification AddPost
In my AddPost.php file i wrote this code:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class AddPost extends Notification
{
use Queueable;
protected $post;
public function __construct(Post $post)
{
$this->post=$post;
}
public function via($notifiable)
{
return ['database'];
}
public function toArray($notifiable)
{
return [
'data'=>'We have a new notification '.$this->post->title ."Added By" .auth()->user()->name
];
}
}
In my controller I am trying to save the data in a table and every thing was perfect.
This is my code in my controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
use App\User;
//use App\Notifications\Compose;
use Illuminate\Notifications\Notification;
use DB;
use Route;
class PostNot extends Controller
{
public function index(){
$posts =DB::table('_notification')->get();
$users =DB::table('users')->get();
return view('pages.chat',compact('posts','users'));
}
public function create(){
return view('pages.chat');
}
public function store(Request $request){
$post=new Post();
//dd($request->all());
$post->title=$request->title;
$post->description=$request->description;
$post->view=0;
if ($post->save())
{
$user=User::all();
Notification::send($user,new AddPost($post));
}
return redirect()->route('chat');
}
}
Everything was good until I changed this code:
$post->save();
to this :
if ($post->save())
{
$user=User::all();
Notification::send($user,new AddPost($post));
}
It started to show an error which is:
FatalThrowableError in PostNot.php line 41: Call to undefined method
Illuminate\Notifications\Notification::send()
How can i fix this one please??
Thanks.
Instead of:
use Illuminate\Notifications\Notification;
you should use
use Notification;
Now you are using Illuminate\Notifications\Notification and it doesn't have send method and Notification facade uses Illuminate\Notifications\ChannelManager which has send method.
Using this
use Illuminate\Support\Facades\Notification;
instead of this
use Illuminate\Notifications\Notification;
solved the problem for me.
Hope this helps someone.
using this is better
use Notification
Instead of
use Illuminate\Support\Facades\Notification
this makes the send() not accessible [#Notification Databse]

Resources