How to run artisan command in bash script outside laravel? - laravel

I am using two frameworks i.e. Laravel and Symfony for two applications which are interlinked with each other. Both are having bash script.
Now, I want to write 'php artisan down' command in Symfony's bash script so that if I merge code to Symfony then both the applications gets down.
How can I write Laravel artisan command in Symfony framework?

It should work like any other command:
#!/bin/bash
php /full/project/path/artisan down
Just write the full path.

You can do this in your Symfony project using Symfony Console:
//in your symfony project
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
public function processCmd() {
$process = new Process('php /absolute/path/to/project/artisan down');
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
echo $process->getOutput();
}
Update:
Laravel also uses the same symfony's Console component!
So if you want to run something in Laravel, you can use the same code above.
Example:
//in your laravel project
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
public function processCmd() {
$process = new Process('supervisorctl stop all');
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
echo $process->getOutput();
}
P.S:
You can pass an array if you want to run multiple commands:
$process = new Process(array('ls', '-lsa'));

Related

Laravel: Show output of a console command inside a migration?

I created a command to do some data manipulation on a very large database table and as it takes fair enough time to complete, i took the benefits of progress bar plus echoing some information on the console.
to automate stuff and reduce human errors, i want to call my command inside a laravel migration using programmatically-executing-commands style and it works but the problem is it wont print any output from corresponding command inside the console
i think i should pass the current Output-buffer that artisan:migrate is using to the Artisan::call function to make it work but had no luck to access it inside the migration
any suggestions?
Expanding on #ettdro's answer, the Artisan::call method has the following signature:
Artisan::call(string $command, array $parameters = [], $outputBuffer = null);
As you can see, the method accepts an output buffer as its 3rd argument. You can pass that output buffer to the method and the command logs will show up on the console.
Here's an example:
<?php
use App\Console\Commands\YourConsoleCommand;
use Illuminate\Database\Migrations\Migration;
use Symfony\Component\Console\Output\ConsoleOutput;
class SomeDbMigration extends Migration
{
public function up()
{
$output = new ConsoleOutput();
Artisan::call(YourConsoleCommand::class, ['--some-option' => true], $output);
}
public function down()
{
$output = new ConsoleOutput();
Artisan::call(YourConsoleCommand::class, ['--some-option' => false], $output);
}
}
You could use ConsoleOutput provided by Symfony to print out in the console after calling Artisan command. Make sure to use it in your desired .php file like so use Symfony\Component\Console\Output\ConsoleOutput;.
You could have something like this:
$output = new ConsoleOutput();
$exitCode = Artisan::call('your call');
if ($exitCode == -1)
$output->writeln("<bg=red;options=bold>Error occured while migration rollback " . "Exit code: " . $exitCode ."</>");
else {
$output->writeln("<bg=blue;options=bold>Rollbacked successfully! Exit code: " . $exitCode ."</>");
}
See in my example you can also add colors to your text, that could be useful to have better visuals on errors and success, see more at this link: https://symfony.com/search?q=ConsoleOutput

No query results error using artisan with object instantiated in service provider

I have created a service provider which provides a class App\Path. This is loaded up through Eloquent using $request->getPathInfo()
$this->app->singleton(Path::class, function($app)
{
$request = $app->make(\Illuminate\Http\Request::class);
$path = Path::with(['template', 'parts'])->findOrFail($request->getPathInfo());
return $path;
});
The app works fine and as expected. However when I want to use Artisan I get the following error:
In Builder.php line 369:
No query results for model [App\Path] /
This prevents me from clearing caches, creating models etc. It seems that Laravel runs register() when running any artisan command and when this done, the request path is "/" which doesn't exist in the DB. Is there a better way to populate the Path object? The only way to solve this seems to add a dummy record for "/".
You can check whether the app is running from console and adjust its logic, for example:
$this->app->singleton(Path::class, function($app)
{
if ($app->runningInConsole()) {
return null;
}
$request = $app->make(\Illuminate\Http\Request::class);
$path = Path::with(['template', 'parts'])->findOrFail($request->getPathInfo());
return $path;
});

TestCase Laravel Custom Command returns empty response

I'm trying to test my custom command, but when I run it does not return anything. I do not know if it's a problem with my assertion. I'm using Laravel 5.6
class CommandsTest extends TestCase
{
//Command morty:bloquear_usuarios_demitidos
public function test_if_can_run_command_morty_bloquear_usuarios_demitidos()
{
$response = $this->artisan('morty:bloquear_usuarios_demitidos');
$response->assertContains('Executado');
}
}
phpunit test
I am not sure what you are expecting an artisan command to 'return'. They don't 'return' things, they just get executed. There could be an exit code, but that is it.
If you stop and look at the method you are calling artisan it returns an int. You can't expect anything other than an int which would be the exit code.
Laravel 5.6 API - InteractsWithConsole#artisan

Image:make(path) Image source not readable when i use artisan custom command

i hope you can help me with my problem.
I have a Laravel application and i wanna optimize all my images.
I use a controller for that, but i have a lot of images, and i get execution_maxim_time_exceed.
I think, the best way to do that is to creat an artisan command.
So, i creat my with php artisan make:command Name command:example.
After, I move my code from controller to handle() from artisan command.
I can use Storage:move($oldPath, $newPath), but i can't use Image:make($filePath).
My file storage is "storage/app/images/image.png" and filePath is 'images/image.png'
When i use the controller, the method isFilePath() from Intervention\Image\AbstractDecoder return true, but in artisan command return false.
Method isFilePath() call the function is_file()
public function isFilePath()
{
if (is_string($this->data)) {
try {
return is_file($this->data);
} catch (\Exception $e) {
return false;
}
}
return false;
}
Why i get false from the function is_file() with the same path for file in artisan command, and in controller i get true? (for the same path).
Thanks
Ok, i found the solution.
In the controller is_file('images/image.png') return true, but in the cli, i need to use the full path
so, in CLI i use 'storage/app/images/image.png'.

How check if a Laravel Console Command Exists?

I need to check if a Laravel Console Command exists and if it is in the protected command var to call them.
I need to call them from another Laravel console command. And I want to know if there are something like exists_command('mycommand:foo')
There are any way to achieve this?
Tested and working.
function command_exists($name)
{
return array_has(\Artisan::all(), $name);
}
if (command_exists('config:cache')) {
// success
}
Though #Sandeesh is right, we can check in this way:
function exists_command($name)
{
return array_key_exists($name, \Artisan::all());
}
if (exists_command('mycommand:foo')) {
// success
}
even in a shorter way,
function exists_command($name)
{
return $this->getApplication()->has($name);
}
php artisan list
Will bring up all possible artisan commands. There is a 'command' subsection with your own created commands.
You would call them as follows
php artisan command:MyCreatedCommand
Edit: To check if a command exists in your project you can use php class_exists function
if(class_exists('App\Console\Commands\MyCommandName')){
//Do whatever
}

Resources