Notification Images cannot be found when triggered by an command/schedule - laravel

When I trigger a notification via a controller the MailMessage sends with no issue, all imaged contained.
However when the same notification is triggered via a schedule item that calls a console command the images cannot be found.

You haven't shown any code, but I have been bitten by something similar also so I think I know what you are talking about.
If your APP_URL includes a directory (eg http://localhost/myproject), and you use asset() to reference images in your views, the generated references will work fine when the view is generated from a browser request, but not from a queue, a scheduled job, or from CLI in general. From the CLI, the directory part of your APP_URL is lost in the generated references, and your images will be broken.
This is a known problem in Laravel that comes from Symfony. It looks like it has just been fixed, a month ago: https://github.com/laravel/framework/issues/14139
UPDATE
Here's a concrete example of the issue. I'm using Laravel 5.2 (though according to the issue above it was fixed in 5.4 at the end of August, so appears right up to recent versions) and sending a transactional email when a user does something on the site. I updated my email view to dump out some values.
Browser request, real-time mail, with Mail::send(), and QUEUE_DRIVER=sync:
env('APP_URL') http://localhost/myproject // OK
config('app.url') http://localhost/myproject // OK
asset('/images/foo.png') http://localhost/myproject/images/foo.png // OK
These values are all correct, and the URLs generated by asset() shows my email images correctly.
CLI request, queued mail, with Mail::queue(), and QUEUE_DRIVER=database:
env('APP_URL') http://localhost/myproject // OK
config('app.url') http://localhost/myproject // OK
asset('/images/foo.png') http://localhost/images/foo.png // xxxx
Note myproject/ is missing from the URL generated by asset(). All images references in my email are broken, images don't show up.
Short of upgrading to a version of Laravel where this is fixed, all you can do is not use asset() in any view that will be generated from CLI, and instead manually specify asset paths:
config('app.url') . '/images/' . $product->image
Side note - as #Desh901 pointed out in the comments, env() should never be used outside of config files:
If you execute the config:cache command during your deployment process, you should be sure that you are only calling the env function from within your configuration files.

Related

Laravel Nova Tag field results in 404 on production

I seriously cannot wrap my head around this.
Locally the tag field of Laravel Nova 4.0 works like a charm (https://nova.laravel.com/docs/4.0/resources/fields.html#tag-field). On production it results in a 404 page on the resource-detail page.
Everything seems to be the same. Same laravel nova version (4.20.2), same data, same other packages.
I've narrowed it down to this call being sent on production:
Request URL: https://api.foodinfluencersunited.nl/nova-api/tags/23a1f0b3-eaac-45c3-b6da-7c1acda08f9d/preview
Which is not sent locally. This call should either not be sent on production (since the tagField has "withPreview" off, or at least it should be sent to:
Request URL: https://api.foodinfluencersunited.nl/nova-api/roles/23a1f0b3-eaac-45c3-b6da-7c1acda08f9d/preview
Since the uuid which is sent is the UUID of a Role-resource.
Does anyone have any idea where I should search for the solution?
I'm trying to at least get the error locally as well.
Imported the production data to local server and made sure that everything else is similar.
It appeared I had out-of-date js on one of my production servers. php artisan nova:publish did not run automatically on one of them. That solved my issue.

Akeneo v6.x Community Edition: "This url is not allowed" on Event subscriptiion

I want to bind Akeneo 6 Community Edition Events API to a Laravel application, making this latter able to act on the creation of an Akeneo product within Akeneo, for example. In other words, when a user creates a product in Akeneo, Akeneo sends a message to Laravel.
So I've followed this doc: https://help.akeneo.com/pim/serenity/articles/manage-event-subscription.html#activate which says to create a Destination Flow Connection, and then to activate the Events subscription within. Then I have to type the URL of Laravel that will receive the message sent by Akeneo in the Akeneo field URL. Then I can click on the button "TEST" in Akeneo and each time it shows an error "This url is not allowed." .
After having created a POST Laravel route named receive_akeneo_events, I've tried to type the following URL:
http://127.0.0.1:80/receive_akeneo_events
http://0.0.0.0:80/receive_akeneo_events
http://localhost:80/receive_akeneo_events
http://laravel.test:80/receive_akeneo_events (after having added laravel.test as an entry in my /etc/hosts at the same line than localhost)
The same URLs without indicating the port and/or The same URLs in HTTPS.
None works. "This url is not allowed." is still displayed for each of these URLs.
Is it a Laravel problem, i.e.: should this route not be POST or should it be configured to return a particular HTTP code, since it's the target of an events triggering system (the one of Akeneo)?
Or is it an Akeneo problem or just a bad URL format?
Finally I modified the code of Akeneo CE by removing the exclusion of localhost in a PHP Array called BLACKCLIST and by removing the condition that excludes IP from Private ranges. Both modifications were done in the adequat Symfony validator's script caller.
Moreover, of course I've also done something about Laravel route's CSRF protection, see the Laravel doc to know what: https://laravel.com/docs/9.x/csrf .
Now it works.

MPDF in Laravel can't output (inline) pdf

I am doing below code in Laravel 5.5 with mpdf 8.0
$mpdf = new \Mpdf\Mpdf();
$mpdf->WriteHTML('Hello World');
$mpdf->Output("test","I");
It outputs gibberish/garbage values, seemingly showing pdf file in raw form.
Some findings
If I use $mpdf->Output($reportPath, 'F'); (saving it to file) and the opening that. It opens the file as expected.
If I place die(); after $mpdf->Output("test","I"); it shows the document.
My suspicion is, it has something something to do with Content-type:application/pdf not being set by default but I have also tried using header("Content-type:application/pdf"); before Output but of no use. it is still showing Content-Type: text/html; charset=UTF-8 in response header in Network tab of chrome (also tried Firefox).
Some back-story
It used to work on php7.3 just fine, but I have to update it to php7.4 due to some library and multiple application on a single server scenario.
Also start using a sub-domain for my application instead of placing the directories after the domain.
I'm looking for
A solution that doesn't require me to place die; at the end of output.
Or some clue in on why this has started happening or/and perhaps why I need to place die; after Output.
Any other solution.
The goal is to provide some ref. for people encountering same issues in future, since I have spent hours and haven't anything that specifically address such issue.
Ok, so I found out that I can't just rely on $this->mpdf->Output('test.pdf',"I") to output my result (though it was working previously with the same line) to the browser.
Because for some reason it has started to send Content-Type:text/html value in Content-Type header so I had to change that.
Solution
I did it as below:
return response($this->mpdf->Output('test.pdf',"I"),200)->header('Content-Type','application/pdf');

Why can't Laravel access .env vars after four seconds of load time

My Laravel site uses SoapClient to access another site during an page load (with performs about 6 seconds of data processing before the soap call.) I noticed sometimes the SoapClient switches to non-wsdl mode and the process errors out. I discovered this was happening because the SoapClient was passed a NULL for its first constructor parameter (the URI of the WSDL file). I though this was strange, because this value came directly from the .env file. The site was having no trouble connecting to the database, so the .env file had to be working. I set up a function that access .env variables repeatedly during the page load, using env(...). During a Soap error, I discovered around the four second mark, the site lost access to the .env vars. Before that point, the information was accessible. After that point, calls to env() returned NULL. This may be related to other page request (possibly repeat calls to the same page, requesting the same process.) Also, I just upgraded php to 7.4.13 (xampp with 64 bit thread support: php-7.4.13-Win32-vc15-x64.) Has anyone seen this before, and has a way to address this issue?
EDIT ====
The SoapClient was created in a model, and the env() function was used to access the environmental vars. I have learned that env() should not be used anywhere but config files. This may explain my problem.
I have never seen this problem. But an approach might be to load env variable into a config variable and use that instead. For example: create extra.php file in the config directory like this:
<?php
return [
'api_url' => env('API_URL'),
];
And use it like this:
config('extra.api_url');
// Instead of env('API_URL')
Hope it works.

Testing Vue.js components- Laravel Testing

I am looking at testing some Vue.js components, as part of a Laravel application. So, I have a component that is used in a blade template and makes a GET request during the mounted lifecycle hook. Say this request takes 800 ms. Is it possible to use phpunit in this situation- to check the resulting HTML after said request?
I tried using sleep(1) (yes, probably a horrible idea), to give the request time to finish up (not 100% on this methodology), but the expected text was not available on the page after this brief sleep.
Here is what I am hoping to do:
$this->actingAs($user)
->visit('/teams/' . $team->slug . '/players'); // request is made when this route is hit.
$this->see('There are currently no players for this team.')
->see('There are currently no temporary players for this team.');
The see() calls resulted in error- the HTML was not present. I also checked- through the HTML output by phpunit on error, and all that is available in the HTML is what is inside of the blade template- the Vue component is not rendered at the point in which the see() call is made.
I suppose I am after some advice or direction.
I appreciate that this may not be what you're after or even compatible based on the version of Laravel you're using but have you heard about Laravel Dusk in the latest version (5.4).
https://laravel.com/docs/5.4/dusk

Resources