Laravel: Send slack notification after a scheduled task finished - laravel

I need to schedule a few tasks on an application built using Laravel and I would like to send a slack notification after those tasks are finished with the output.
Laravel provides an "after" hook (https://laravel.com/docs/5.8/scheduling#task-hooks) so I can do something like this:
$schedule->command('mycommand')
->daily()
->after(function () {
// How can I access the command's name and output from here?
});
I've tried with $this->output but $this points to App\Console\Kernel and it says Undefined property: App\Console\Kernel::$output. I've also tried to pass a parameter to the closure, but I think I need to specify a type, but I have no idea and the documentation is not very clear.
Anyone has any idea on how to do this?
Thanks in advance!

Assuming you have this in your command
$this->info('hello');
In your kernel, you can send the output to a temporary file and then read the file and send it
/** #var \Illuminate\Console\Scheduling\Event $command */
$command = $schedule->command('mycommand')
->daily()
->sendOutputTo('storage/app/logs.txt');
$command->after(function () use ($command) {
\Log::debug([$command->command, $command->output]);
\Log::debug(file_get_contents($command->output));
});
You will get
[2019-10-11 13:03:38] local.DEBUG: array (
0 => '\'/usr/bin/php7.3\' \'artisan\' command:name',
1 => 'storage/app/logs.txt',
)
[2019-10-11 13:03:38] local.DEBUG: hello
Maybe it would be the time to re-open this proposal https://github.com/laravel/ideas/issues/122#issuecomment-228215251

What kind of output does your command generate? is it command line or is just a variable you're trying to pass to the after()?
Alternativly in your handle() method of the command you can call the desired command after all the code has been excuted, you can even pass a parameter to the command.
You can do that by using Artisan
Artisan::call('*command_name_here*');

Related

Passing xml vallues from windows events as a variables

I appreciate any advice from Powershell wizards out there.
I am trying to setup an email alert that will be triggered on event but having problems passing values as a variable so I can use it later in the body and subject of an email.
I have a few lines of script that pulls an event and stores it as XML but have no luck converting the value to variable to call it later.
$event = wevtutil qe 'Microsoft-Windows-Base-Filtering-Engine-Connections/Operational' /rd:true /c:1 /q:"*[System[(EventID=2000)]]" /f:renderedxml
$xmlresults = [xml]$event
$eventDate = $xmlresults.event.system.timecreated.systemtime
$eventTime = get-date $eventDate -Format ('dd-MM-yyyy hh:mm:ss')
Now when calling $xmlresults.event.eventdata.data I can see all values in a table:
PS C:\Windows\system32> $xmlresults.Event.EventData.Data
Name #text
---- -----
ConnectionId 1324000000003942
MachineAuthenticationMethod 2
RemoteMachineAccount DOMAIN\COMPUTERNAME$
UserAuthenticationMethod 2
RemoteUserAcount DOMAIN\USERNAME$
RemoteIPAddress XXXX:XXXXX:XXXX:XXXX:XXXXX:XXX:XXXX
LocalIPAddress XXXXX:XXXX:XXXX:XXXX::1
TechnologyProviderKey {XXXXXX-XXXX-XXXXX-XXXX-XXXXXXXXXX}
IPsecTrafficMode 1
DHGroup 0
StartTime 2021-05-17T13:52:38.103Z
How do I store the values of RemoteMachineAccount and RemoteUserAccount as a variable so I can call upon it later in the script when composing email alert and log input by simply using something along the lines of $computer and $user?
Any help greatly appreciated.
If you just need a few specifically named properties, you can use the .Where({}) method to filter the nodes returned by the XML provider and grab the text from that specific property:
$RemoteMachineAccount = $xmlresults.Event.EventData.Data.Where({$_.Name -eq 'RemoteMachineAccount'}).InnerText
$RemoteUserAccount = $xmlresults.Event.EventData.Data.Where({$_.Name -eq 'RemoteUserAccount'}).InnerText
If you need to discover/use them dynamically, another option is to convert the node list into a hashtable:
$eventData = #{}
$xmlresults.Event.EventData.Data.ForEach({ $eventData[$_.Name] = $_.InnerText })
At which point you can dereference the individual property values by name:
$eventData["RemoteUserAccount"]

Git Bash console output breaks down when using Laravel Console choice method

I've a little problem with my console. When I use choice method from Laravel Console, the output totally breaks down. I wanted to google this but I can't find any solution. It's really annoying.
Anyone know how to fix this?
I'm using Git Bash provided by Git for Windows.
That Git bash is an emultion of unix console and it makes me able to use unix like commands. I don't want to stop using this.
Here is the console output
Give your group a name:
Something
Give your group a description (blank for skip):
>
Do you want to assign scopes to your new group? (y/n):
y
Select existing scope name: [0] Random [1] Exit (It's not a
scope)
0 0?[K
?[32mSelect existing scope name?[39m: [?[33m0?[39m] Random
[?[33m1?[39m] Exit (It's not a scope)
>
And the php code as below.
$name = $this->ask('Give your group a name');
$description = $this->ask('Give your group a description (blank for skip)');
$groups = app()->make(ScopeGroupRepository::class);
/** #var ScopeGroup $group */
$group = $groups->perform(new Create($name, $description));
$willCreateScopes = $this->answerToBoolean(
$this->ask('Do you want to assign scopes to your new group? (y/n)')
);
if(!$willCreateScopes) {
return $this->displayCreatedGroupInfo($group);
}
$scopes = app()->make(ScopeRepository::class);
/** #var Collection $unassigned */
$unassigned = $scopes->perform((new ShowAllUnassignedToGroup())->setGroupId($group->id));
if($willCreateScopes) {
do {
$scopes = $unassigned->map(function (Scope $scope){
return $scope->id;
})->toArray();
array_push($scopes, 'Exit (It\'s not a scope)');
// Here it breaks down
$selected = $this->choice('Select existing scope name', $scopes);
} while($selected !== 'Exit (It\'s not a scope)');
}
Thanks for help.

Laravel: detect if running migrations

I have setup some event listeners in which I would like to detect if I'm runnnig database migrations or a normal request/command.
Is there some way of knowing this? Global flag? Environment?
Thanks in advance.
You can check if the console is being used with App::runningInConsole() ... that might be sufficient depending on how you are running the migrations.
Update:
OK, after doing some more digging, it looks like you can hack your way to the info you need using the follow example:
if(app()->runningInConsole()) {
// we are running in the console
$argv = \Request::server('argv', null);
// :$ php artisan migrate:refresh -v
//
// gives:
//
// $argv = array (
// 0 => 'artisan',
// 1 => 'migrate:refresh',
// 2 => '-v',
// )
if($argv[0] == 'artisan' && \Illuminate\Support\Str::contains($argv[1],'migrate')) {
// we are running the artisan migrate command
}
}
Source: How to get the current console command in Laravel
Actually, Laravel fires several events while running migrations:
Illuminate\Database\Events\MigrationsStarted : A batch of migrations is about to be executed.
Illuminate\Database\Events\MigrationsEnded : A batch of migrations has finished executing.
Illuminate\Database\Events\MigrationStarted : A single migration is about to be executed.
Illuminate\Database\Events\MigrationEnded : A single migration has finished executing.
You can utilize this to do anything you want. For example:
// change default Log channel when running migrations
Event::listen(function (MigrationsStarted $event) {
config()->set('logging.default', 'migration');
});
In your case, you can set a key in your app config files like app.running_migrations and set it to true in the event listener.

Laravel Cron not auto run (Windows)

I use Cron (https://github.com/liebig/cron) for Laravel 4 to run specific task in specific time
I have this code in my Global.php
Event::listen('cron.collectJobs', function() {
Cron::add('example1', '* * * * *', function() {
$trip = new TripReminder();
$trip->checkDateAndSendEmail();
});
Cron::setRunInterval(1);
$report = Cron::run();
print_r ($report);
});
=>This Code use to Send an email to the customers in every minute (just demo and check)
in cmd, i run this command "php artisan cron:run"
It can run well, the email was sent also, but, it only run 1 times.
I don't know what i'm missing.
Please help !
Thank you !

PHP parse error in rss parse function

I have a client who needs a website urgently, but I have no access to information such as the control panel.
PHP Version is 4.4 Which is a pain as I'm used to 5.
The first problem is I keep getting:
Parse error: parse error, unexpected T_OBJECT_OPERATOR, expecting ')' in D:\hshome\*******\********\includes\functions.php on line 37
This is the function in question:
function read_rss($display=0,$url='') {
$doc = new DOMDocument();
$doc->load($url);
$itemArr = array();
foreach ($doc->getElementsByTagName('item') as $node) {
if ($display == 0) {
break;
}
$itemRSS = array(
'title'=>$node->getElementsByTagName('title')->item(0)->nodeValue,
'description'=>$node->getElementsByTagName('description')->item(0)->nodeValue,
'link'=>$node->getElementsByTagName('link')->item(0)->nodeValue);
array_push($itemArr, $itemRSS);
$display--;
}
return $itemArr;
}
And the line in question:
'title'=>$node->getElementsByTagName('title')->item(0)->nodeValue,
PHP4 does not support object dereferencing. So $obj->something()->something will not work. You need to do $tmp = $obj->something(); $tmp->something...
You can't do that in PHP 4.
Have to do something like
$nodes = $node->getElementsByTagName('title');
$item = $nodes->item(0);
$value = $item->nodeValue,
Try it and it will work.
You can't chain object calls in PHP 4. You're going to have to make each call separately to a variable and store it all.
$titleobj = $node->getElementsByTagName('title');
$itemobj = $titleobj->item(0);
$value = $itemobj->nodeValue;
...
'title'=>$value,
you'll have to do it on all those chained calls
As for .htaccess ... you need to talk to someone who controls the actual server. It sounds like .htaccess isn't allowed to change the setting you're trying to change.
You need to break down that line into individual variables. PHP 4 does not like -> following parentheses. Do this instead:
$title = $node->getElementsByTagName('title');
$title = $title->item(0);
$description = $node->getElementsByTagName('description');
$description = $description->item(0);
$link = $node->getElementsByTagName('link');
$link = $link->item(0);
$itemRSS = array(
'title'=>$title->nodeValue,
'description'=>$description->nodeValue,
'link'=>$link->nodeValue);
The two variable declarations for each may be redundant and condensed, I'm not sure how PHP4 will respond. You can try to condense them if you want.
DOMDocument is php 5 function.You cant use it.
you may need to use DOM XML (PHP 4) Functions

Resources