Executing Artisan command with arguments - laravel

Currently i'm facing following problem:
I want to update my search index automatically after my database has been updated.
I've registered a saved() listener on my tables in AppServiceProvider:
\App\Customer::saved(function(\App\Customer $customer) {
// Update search index here
});
Inside the closure i try to call an Artisan command (scout:import) passing App\\Customer to the command. I've tried
Artisan::queue('scout:import', ['' => 'App\\\Customer']);
// Fails with message: Uninitialized string offset: 0
Artisan::queue('scout:import', ['model' => 'App\\\Customer']);
// Fails: Cannot redeclare class App\Customer
Artisan::queue('scout:import', ['App\\\Customer']);
// Fails: Not enough arguments (missing: "model")
I did'nt find information where to put the required arguments in the offical documentation.
I'm sure that it's dead simple (like everything in laravel) but i'm not able to get it done ...

The correct format is:
Artisan::queue('email:send', [
'user' => 1, '--queue' => 'default'
]);
As per: https://laravel.com/docs/5.3/artisan#programmatically-executing-commands
I'd say your middle example is probably closest, and is executing the command with the correct parameters, but there is something else going on under the surface.
EDIT
Just did a bit more digging, you need to refer to the signature of the Console command, which isn't actually apparent on the surface. In your case, you need to refer to this console command:
https://github.com/laravel/scout/blob/2.0/src/Console/ImportCommand.php
Note the signature is marked with {model}.
So your command would look like:
Artisan::queue('scout:import', ['model' => 'App\\\Customer']);
Another example using the controller make command, note that this time we using the signature segment {name}:
Artisan::call('make:controller', ['name'=>'FOOBAR']);
Again, there is probably an underlying issue here - you should try running the import command from the console/terminal directly to see if you get the same issue.

Try this:
\App\Customer::saved(function(\App\Customer $customer, $input) {
// Update search index here
});
Artisan::queue('scout:import {input}', ['App\\\Customer']);

You don't need to sync with algolia using an artisan call.
Refer to algolia documentation:
Algolia Laravel Doc
'Every time you modify a model, Laravel emits an event. Scout is listening for that event, informing your app to make an HTTP call to Algolia to update its index.
You don’t have anything else to do, use your searchable class the way you usually would do'

Related

In Laravel, why does "return response()->json([])" take 700 ms longer than "return []"

In Laravel, I can return from a controller like this:
return response()->json(["name" => "Bob"])
Or I can return like this:
return ["name" => "Bob"]
Both of these return the same thing, but the first one takes about 700ms longer. Does anybody know why and how to fix this?
Extra details: Laravel version 8. I'm using Sail (Docker) on my laptop.
More details: I measured the time of the request with Chrome developer tools. I went back and forth a number of times, between the two different ways, with consistent results.
If you want to see the project, here is a stripped down version of it: https://github.com/tkoop/slow_laravel_response
Upon inspecting your project, the package codeat3/blade-google-material-design-icons is the culprit. It depends on blade-ui-kit/blade-icons and according to the readme file, the problem is caching. You can either run php artisan icons:cache (it will still slow down the response by ~100ms) or disable Blade components (no noticeable slow down) if you don't need them:
php artisan vendor:publish --tag=blade-icons
# /config/blade-icons.php
return [
'components' => [
'disabled' => true,
],
];

How can I get Google Auth working with Laravel?

I'd like to know if there's an easy fix for this error that I'm getting while trying to add support for Google sign-in to my website, since I can only reproduce it while on a Laravel-based environment. Vanilla PHP applications do run just fine.
This is my relevant code:
if ($request->has('googleToken')) {
$client = new Google_Client(['client_id' => env('GOOGLE_PLATFORM_CLIENT_ID') ]);
$payload = $client->verifyIdToken($credentials['googleToken']);
if (!$payload) {
return response([ 'error' => 'Invalid token, please try using form-based authentication.' ], Response::HTTP_FAILED_DEPENDENCY);
}
$user['googleToken'] = $credentials['googleToken'];
}
I know I'm doing too relaxed validations, but please just focus on the fact that I'm just testing and I plan to change this code in the near future.
The code above, receives its data through an Axios PUT request from the frontend with the payload looking like this:
{
googleToken: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE5ZmUyYTdiNjc5NTIzOTYwNmNhMGE3NTA3OTRhN2JkOWZkOTU5NjEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiNTkyODkzNjE3ODYzLXRscDdvaDByaTk2dTZxZGxrOXYwbHAyanQyNDlkdDNsLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiNTkyODkzNjE3ODYzLXRscDdvaDByaTk2dTZxZGxrOXYwbHAyanQyNDlkdDNsLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE1NTg0MDg0NTE2OTMxOTQzODU..."
mailAddress: "user#mail.com"
}
The problem is that the payload would simply return false. I decided to try to investigate the issue, so I went to the definition of verifyIdToken contained within Google_Client and, from there, jumped over to the function that finally returns to its parent, which is verifyIdToken from the class Verify.
Inside of that class, there's a pretty loose try/catch block in which I decided to try adding a generic exception case so that I could quickly print the error message for debugging. I did, and this is the output I got:
OpenSSL unable to verify data: error:0909006C:PEM routines:get_name:no start line
This is what's failing internally, and from this point on, I don't really have an idea about how to proceed since the error feels very cryptic, or at least it's not in my field of knowledge.
The OpenSSL error you quoted indicates that your client was not able to read any/further PEM-encoded data. Refer to https://www.openssl.org/docs/man1.1.1/man3/PEM_read.html.
OpenSSL unable to verify data: error:0909006C:PEM routines:get_name:no start line
Here,
'PEM routines' represents the library within OpenSSL
'get_name' is the function
'no start line' is the reason
Is you client able to access the necessary certificates/keys?

Laravel - OutputStyle from jobs

I'm running into issues with allowing a Laravel job to interact with the console output.
At the moment I am passing in the OutputStyle from a Command to the Job constructor and assigning it.
I have seen the InteractsWithIO trait but if I use that by itself without assigning the OutputStyle from the command then it says it is null.
Call to a member function title() on null
I have also tried setting $this->output from the container using
$this->output = resolve(OutputStyle::class);
This fails with a
Target [Symfony\Component\Console\Input\InputInterface] is not instantiable while building [Illuminate\Console\OutputStyle].
I've also ran into issues with PHPUnit tests that run through this job. The output from the class is displayed in the test output.
.......................Processing element 1 for "Section"
.......
What's the best way to handle outputting to the console within Laravel that also works with PHPUnit?
Putting the following code in a Service Provider works:
$this->app->bind('console.output', function () {
return new OutputStyle(
new StringInput(''),
new StreamOutput(fopen('php://stdout', 'w'))
);
});
I am then able to say, in my Job,
$this->output = resolve('console.output');
Which gives access to all the methods such as title, section, and table.

View::make in Phpunit

I've a function that returns a View::make($string). I want to test that this function did indeed return an instance of View object. $string points to a file that does exist.
When I try to run this function within Phpunit it doesn't seem to finish. How can I test in Phpunit that a View object was created?
Laravel has helper methods specifically designed for testing views.
Some of them include:
$response = $this->get('/path/to-your-route');
$response->assertViewIs($value);
$response->assertViewHas($key, $value = null);
$response->assertViewHasAll(array $data);
$response->assertViewMissing($key);
More info can be found here: https://laravel.com/docs/5.5/http-tests#available-assertions
If you need to assert that something is an instance of something else, you can try the following:
$this->assertInstanceOf($expected, $actual);
When you provide invalid string the view object will not be created and will throw an exception. Not sure what you have in your function that prevents the exception, but the way to go around this issue, is to include this line in the failing test:
$this->expectException(InvalidArgumentException::class);
The issue stemmed down from usage of var_dump as I wanted to see the object in question. As nothing was presented in output, I assumed that had to do with View::make rather than outputting the object to the console.

Queued Events in Laravel 4: Event::flusher() method not found

According to the Laravel 4 Documentation on queued Events, I tried to register an event flusher this way:
Event::flusher('foo.bar', function($data)
{
Mail::send(array('emails.notification', 'emails.notification_text'), array('content' => $data), function($message)
{
$message
->to('email#example.com', 'My Name')
->bcc('test#example.com')
->subject('Message from Listener');
});
});
But I am getting the following error upon loading of the script:
Call to undefined method Illuminate\Events\Dispatcher::flusher()
I also couldn't find this method in the source codes of L4. But when I change this from Event::flusher() to Event::listen(), everything works as expected.
So my guess is, that the documentation isn't up to date and the Event::flusher() method has been dropped, since Event::listen() does the same work. Or are there any differences between those two methods and I have an error in my code?
You may need to update your libraries using:
$ composer update
If that doesn't work, let us know what your composer.json file looks like - you might be using a beta version if the framework. It was updated very often before the first stable release.

Resources