Access Arguments Input via Artisan Console Command - php

I want to run my command like this
php artisan update:code --code=123
I want to get the code from first argument - I can't seems to find a way to do it on Laravel site.
<?php
namespace App\Console\Commands;
use App\User;
use Illuminate\Console\Command;
class updateCode extends Command
{
protected $signature = 'update:code {code}';
protected $description = 'Update Code ... ';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$code = $this->option('code');
$this->info($code);
$user = User::where('type','Admin')->first();
$user->code = bcrypt($code);
$user->active = 1;
$user->save();
$this->info($user);
}
}
I kept getting
The "--code" option does not exist.
Do I need to defind my option too ?
How can I just quickly access the first argument ?

{code} is for arguments. For options it is {--code} or {--code=}:
// option as switch:
protected $signature = 'update:code {--code}';
// option with value:
protected $signature = 'update:code {--code=}';

Just use
php artisan update:code 123

Related

irazasyed/telegram-bot-sdk get update object on commands

I was using irazasyed/telegram-bot-sdk for a Telegram bot in Laravel. I just wanted to access the update object on my StartCommand class and send a welcome message to a user with his name. The StartCommand class looks like this:
<?php
namespace App\TelegramCommands;
use Telegram\Bot\Commands\Command;
class StartCommand extends Command
{
protected $name = "start";
protected $description = "Lets you get started";
public function handle()
{
$this->replyWithMessage(['text' => 'Welcome ']);
}
}
And the route (which is inside api.php) is:
Route::post('/'.env('TELEGRAM_BOT_TOKEN').'/webhook', function (Request $request) {
$update = Telegram::commandsHandler(true);
return 'ok';
});
I just wanted to access users data when he sends /start command and replay with a message like, "Welcome [his name]". Thank you in advance.
I just have got the answer. It was mainly adding the following to the handle method of StartCommand class:
$update= $this->getUpdate();
So the final file will look like:
<?php
namespace App\TelegramCommands;
use Telegram\Bot\Commands\Command;
class StartCommand extends Command
{
protected $name = "start";
protected $description = "Lets you get started";
public function handle()
{
$update= $this->getUpdate();
$name = $update['message']['from']['first_name'];
$this->replyWithMessage(['text' => 'Welcome '.$name]);
}
}
A good tutorial is here

Laravel Command argument returns keyvalue pair insted of value

I've generate Laravel artisan command by php artisan make:command SomeCommand. Here is the entire command class SomeCommand.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class SomeCommand extends Command{
protected $signature = 'Call:SomeCommand {phone="8980131488"} {name="Kiran Maniya"}';
protected $description = 'This is a buggy Command';
public function __construct(){
parent::__construct();
}
public function handle(){
$args = $this->arguments();
$this->info($args['phone'].' '.$args['name']);
}
}
The issue is, when i call the command by php artisan Call:SomeCommand phone="8980151878" name="Anubhav Rane". It outputs the arguments with keypair value as name=Anubhav Rane & phone=8980151878. It should only output the values.
I also tried catching single values by $this->argument('phone') and $this->argument('name') but still it outputs the same.
The way you're passing the arguments is incorrect. Try this:
php artisan Call:SomeCommand 8980151878 'Anubhav Rane'

How can I schedule the pinging of routes within my application [duplicate]

In kohana framework I can call controller via command line using
php5 index.php --uri=controller/method/var1/var2
Is it possible to call controller I want in Laravel 5 via cli? If yes, how to do this?
There is no way so far (not sure if there will ever be). However you can create your own Artisan Command that can do that. Create a command CallRoute using this:
php artisan make:console CallRoute
For Laravel 5.3 or greater you need to use make:command instead:
php artisan make:command CallRoute
This will generate a command class in app/Console/Commands/CallRoute.php. The contents of that class should look like this:
<?php namespace App\Console\Commands;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Illuminate\Http\Request;
class CallRoute extends Command {
protected $name = 'route:call';
protected $description = 'Call route from CLI';
public function __construct()
{
parent::__construct();
}
public function fire()
{
$request = Request::create($this->option('uri'), 'GET');
$this->info(app()['Illuminate\Contracts\Http\Kernel']->handle($request));
}
protected function getOptions()
{
return [
['uri', null, InputOption::VALUE_REQUIRED, 'The path of the route to be called', null],
];
}
}
You then need to register the command by adding it to the $commands array in app/Console/Kernel.php:
protected $commands = [
...,
'App\Console\Commands\CallRoute',
];
You can now call any route by using this command:
php artisan route:call --uri=/route/path/with/param
Mind you, this command will return a response as it would be sent to the browser, that means it includes the HTTP headers at the top of the output.
I am using Laravel 5.0 and I am triggering controllers using this code:
$ php artisan tinker
$ $controller = app()->make('App\Http\Controllers\MyController');
$ app()->call([$controller, 'myMethodName'], []);
the last [] in the app()->call() can hold arguments such as [user_id] => 10 etc'
For Laravel 5.4:
php artisan make:command CallRoute
Then in app/Console/Commands/CallRoute.php:
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Http\Request;
class CallRoute extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'route:call {uri}';
/**
* The console command description.
*
* #var string
*/
protected $description = 'php artsian route:call /route';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$request = Request::create($this->argument('uri'), 'GET');
$this->info(app()->make(\Illuminate\Contracts\Http\Kernel::class)->handle($request));
}
}
Then in app/Console/Kernel.php:
protected $commands = [
'App\Console\Commands\CallRoute'
];
Call like: php artisan route:call /path
Laravel 5.7
Using tinker
// URL: http://xxx.test/calendar?filter[id]=1&anotherparam=2
$cc = app()->make('App\Http\Controllers\CalendarController');
app()->call([$cc, 'getCalendarV2'], ['filter[id]'=>1, 'anotherparam' => '2']);
You can do it in this way too. First, create the command using
php artisan command:commandName
Now in the handle of the command, call the controller and trigger the method.
Eg,
public function handle(){
$controller = new ControllerName(); // make sure to import the controller
$controller->controllerMethod();
}
This will actually do the work. Hope, this helps.
DEPENDENCY INJECTION WON'T WORK
To version 8 of laravel.
First step: type command in terminal
php artisan tinker
Secound step:
$instante = new MyController(null);
Or if argument by an instance of model, then, pass name model class.
Example:
$instante = new MyController(new MyModelHere());
Press enter.
Finally, call method with $instante->myMethod() here.
See:

How to get laravel command arguments outside command, e.g. in service provider?

I can get arguments in command with this code:
$this->argument();
But how to get arguments outside ?
If I look at source of argument() function I see :
public function argument($key = null)
{
if (is_null($key)) {
return $this->input->getArguments();
}
return $this->input->getArgument($key);
}
I want to detect when command "php artisan migrate:refresh --seed" is running because I want some part of code in models run at localhost enviroment but not in localhost enviroment during seeding...
Mechanism how laravel gets command arguments is pretty complicated. I can detect if app is running in console with \App::runningInConsole() but there is no function which will get arguments, something like :
if(\App::runningInConsole()){
$args = \App::getConsoleArguments(); // doesn't exist :(
}
but $_SERVER['argv'] can be usefull here, when "php artisan migrate:refresh --seed" is running in $_SERVER['argv'] is this array:
Array
(
[0] => artisan
[1] => migrate:refresh
[2] => --seed
)
so I can use this code:
if( ! empty($_SERVER['argv'][2] ) && $_SERVER['argv'][2] == '--seed'){
//
}
I has the same problem building a Laravel SAAS app on AWS, in base to this project I modify my ServiceProvider for this:
<?php
namespace App\Providers;
use Illuminate\Console\Events\ArtisanStarting;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\EventDispatcher\EventDispatcher;
class MultitenantServiceProvider extends ServiceProvider{
protected $consoleDispatcher = false;
protected $commands_with_tenant = [
'migrate', 'migrate:refresh', 'migrate:install', 'migrate:reset', 'migrate:rollback',
'migrate:status', 'passport:client', 'passport:install', 'passport:keys'
];
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot(){
if( $this->app->runningInConsole() ){
$this->registerTenantOption();
$this->verifyTenantOption();
}
// Multitenant re-configure in case of HTTP request
}
/**
* Register any application services.
*
* #return void
*/
public function register(){
$this->app->singleton('multitenant', function ($app){
// Register your Multitenant
});
}
protected function registerTenantOption(){
$this->app['events']->listen(ArtisanStarting::class, function($event){
$definition = $event->artisan->getDefinition();
$definition->addOption(
new InputOption('--tenant', null, InputOption::VALUE_OPTIONAL, 'The tenant subdomain the command should be run for. Use * or all for every tenant.')
);
$event->artisan->setDefinition($definition);
$event->artisan->setDispatcher($this->getConsoleDispatcher());
});
}
protected function verifyTenantOption(){
$this->getConsoleDispatcher()->addListener(ConsoleEvents::COMMAND, function(ConsoleCommandEvent $event){
if( in_array($event->getCommand()->getName() , $this->commands_with_tenant) ){
$tenant = $event->getInput()->getParameterOption('--tenant', null);
if (!is_null($tenant)){
if ($tenant == 'all'){
// Do something with 'all'
}
else{
// Do something with $tenant
}
}
else{
$event->getOutput('<error>This command need that specified a tenant client</error>');
$event->disableCommand();
}
}
});
}
protected function getConsoleDispatcher(){
if (!$this->consoleDispatcher){
$this->consoleDispatcher = app(EventDispatcher::class);
}
return $this->consoleDispatcher;
}
In this class, there is an array with the commands that are needed to verify and use a multitenant config.

Use specific ServiceProvider in Laravel 4

Laravel 4 ships with the php artisan routes command. This shows a list of registered routes on the command line. Instead of showing the registered routes on the command line, I would like to get its values within a controller.
The following method does exactly what I want:
Illuminate\Foundation\Console\RoutesCommand()
Unfortunately this is a protected method, so it doesn't work when I try something like this:
$rc = new Illuminate\Foundation\Console\RoutesCommand(new Illuminate\Routing\Router);
print_r($rc->getRoutes());
How can I access this method to display the registered routes in my Laravel 4 app?
Or even better; how can I access methods of any autoloaded service provider?
You can get all routes like this:
$routes = App::make('router')->getRoutes();
foreach($routes as $name => $route)
{
//do your stuff
}
I believe you would have to create a class that extends Illuminate\Foundation\Console\RoutesCommand and then you can run the method using print_r($this->getRoutes());
Here is a sample of how you can call an Artisan command from inside a Controller:
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\Output;
use Illuminate\Console\Application as ConsoleApplication;
class MyOutput extends Output {
protected $contents = '';
protected function doWrite($message, $newline)
{
$this->contents .= $message . ($newline ? "\n" : '');
}
public function __toString()
{
return $this->contents;
}
}
class MyController extends BaseController {
public function getRoutes()
{
$app = app();
$app->loadDeferredProviders();
$artisan = ConsoleApplication::start($app);
$command = $artisan->find('routes');
$input = new ArrayInput(array('command' => 'routes'));
$output = new MyOutput();
$command->run($input, $output);
return '<pre>' . $output . '</pre>';
}
}
In this case, the Artisan command is routes and we are not passing any parameter to it.

Categories