using Cache in cronjobs with Laravel artisan - php

I am in need of some help. I want to use Laravel Cache class:
class Uploadcatalogfiles_Task
{
public function run($arguments)
{
error_reporting(0);
$uploadFlag = Cache::get('upload_is_working');
if ($uploadFlag == 1) {
echo date('Y-m-d H:i:s '),'BIT: CACHE SHOT!.',"\n";
die;
} else {
Cache::put('upload_is_working',1,60);
}
And $uploadFlag is always empty. Seems like Cache is always empty.
What am I doing wrong?
Thanks.

This sounds similar (tho not a duplicate) to this question.
Assuming your cron job is running an artisan command, you likely have an issue where you haven't defined which environment to use when using Laravel's worker.
The docs say to use:
php artisan command:your_command
But you likely want to define a specific environment, like any artisan command, to pull in the right database and cache connections:
php artisan command:your_command --env=production
So, your cron job might look something like this:
* * * * * /usr/bin/php /var/www/example.com/public/artisan command:your_command

Related

Laravel Task schedule with cron column in database

I have a "reportSchedule" model which contains the report name and a cron_request column such as */15 * * * *.
I want to be able to adjust the cron within the database and affect the times which the report is requested. For example, the following is working from directly within the console/Kernel.php:
ReportSchedule::all()->each(function(ReportSchedule $reportSchedule) use($schedule){
if(isset($reportSchedule->cron_request)){
$schedule->call(function() use ($reportSchedule) {
ReportRequestNow::dispatch($reportSchedule);
})->cron($reportSchedule->cron_request);
}
});
However, having the model called from directly within the kernel causes other issues. For example database migrations now do not work and errors are thrown when caching the routes or running route:list. In general, it does not seem to like it!
So my idea was either create a seeder job or put this into its own schedule, however neither work.
// Doesnt work - the every minute schuedle is called but ReportRequestNow is never reached.
$schedule->call(function() use($schedule){
ReportSchedule::all()->each(function(ReportSchedule $reportSchedule) use($schedule){
if(isset($reportSchedule->cron_request)){
$schedule->call(function() use ($reportSchedule) {
ReportRequestNow::dispatch($reportSchedule);
})->cron($reportSchedule->cron_request);
}
});
})->everyMinute();
// Also does not work
$schedule->job(new ReportScheduleSeeder(), 'high')->everyMinute();
Can anyone suggest a why this does not work or how to get it working?
However, having the model called from directly within the kernel
causes other issues. For example database migrations now do not work
and errors are thrown when caching the routes or running route:list.
In general, it does not seem to like it!
Seems that there's some syntax errors (maybe some classes aren't listed in use?)
Have you checked laravel and PHP logs? Most likely there will be some explanations.

Why Laravel keeps calling schedule() with every Artisan Command?

I have one table called dc_user_meta and I've created one artisan command and scheduled it in kernel.php. Just after cloning the repository, when I try to run PHP artisan migrate, I get this error.
[Illuminate\Database\QueryException]
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'database.dc_user_meta' doesn't exist (SQL: select * from `dc_user_met
a` where `meta_key` = usage_in_days)
Not only php artisan migrate but I am unable to run any artisan command at all! I don't know why PHP keeps calling schedule method every time I try to execute any artisan command.
Here in this case, What I can do to solve this error is put the cover over my logic in schedule method just like this.
if(Schema::hasTable('dc_user_meta')){
// Code here
}
But I don't think it's good in Long run. What's the right way to solve this error?
UPDATE:
I just tried covering call to command in kernel.php just like this but still no success!
if(Schema::hasTable('dc_user_meta')){
$schedule->command('usage:update')->daily();
}
UPDATE:
I got the solution. But I don't think it's the answer to the question. It solves my problem but I don't think it's standard Solution. I just covered by Command login just like this.
if(Schema::hasTable('dc_user_meta')){
// Command Logic
}
Any specific answer to why Laravel calls schedule() with every artisan command and how to solve the error in a standard way if something like this happens!
Technically the schedule method ist called via the constructor of Illuminate\Foundation\Console\Kernel ( This is the parent class of app\Console\Kernel.php)
So every time the console Kernel is instantiated, the schedule() method gets executed.
Let's see what gets executed in which scenario ( $schedule->call() can be replaced with $schedule->command() or $schedule->exec()):
protected function schedule(Schedule $schedule)
{
// everything that is inside the schedule function is executed everytime the console kernel is booted.
// gets exectuted every time
\App\User::where('foo', 1)->get();
$schedule->call(function() {
// gets executed for every call to php artisan schedule:run
\App\User::where('foo', 1)->get();
});
$schedule->call(function() {
// gets executed for every call to php artisan schedule:run
// IF the closure in the when() function is true;
\App\User::where('foo', 1)->get();
})->when(function() {
// if true is returned the scheduled command or closure is executed otherwise it is skipped
\Schema::hasColumn('user', 'foo');
});
}
But why HAS the schedule command to be exectuted with every command?
Well, obviously php artisan schedule:run is a console command itself. So it definitely needs information about scheduled commands.
Also other commands could need information about scheduled commands... For example if you want to write an artisan command list:scheduledTasks. This command would require that all scheduled commands have been added to the console schedule list.
Maybe there are several other (internal) arguments why the schedule function has to run everytime. ( I did not dig too deep in the source code... )
Nevertheless... information about scheduled commands could be useful to a variety of use cases.
Your error is with table dc_user_meta while your logic is of table user_meta you need to do Schema::hasTable('dc_user_meta')
I'm convinced that table dc_user_meta doesn't exist in database.
As I understand, yor have table "user_meta" not "dc_user_meta" but you have written the code to use table "dc_user_meta" hence there is an error saying "dc_user_meta" table not found.
If anyone still cares about this...
<?php
# This is your app/Console/Kernel.php
use ...;
class Kernel extends ConsoleKernel {
# Other stuff...
protected function schedule(Schedule $schedule) {
if( in_array('schedule:run', $_SERVER['argv']) ){
# Your scheduler commands here...
}
}
}

How to get currently used Artisan console command name in Laravel 5?

Problem / What I've tried:
Getting the currently used controller and action in Laravel 5 is easy (but not as easy as it should be), however I'm stuck with getting the currently used artisan console command.
To fetch the controller name I do this:
$route = Route::getRoutes()->match(Request::capture());
$listAction = explode('\\', $route->getActionName());
$rawAction = end($listAction);
// controller name and action in a simple array
$controllerAndAction = explode('#', $rawAction);
But when calling from a console action, it always returns the default index controller's name ("IndexController" or so in Laravel). Does anybody know how to make this ?
By the way I've also worked throught Request::capture() but this still gives no info about the command.
The simplest way is to just to look at the arguments specified on the command line:
if (array_get(request()->server(), 'argv.1') === 'cache:clear') {
// do things
}
Yes, you can use $_SERVER directly, but I like to use the helper functions or the Facades, as those will give you the current data.
I go from the assumption that - during unit tests - the superglobals might not always reflect the currently tested request.
By the way: Obviously can also do array_get(request()->server('argv'), '1') or something alike. (request()->server('argv.1') doesnt work at this point). Or use \Request::server(). Depends on what you like most.
As per the Symfony\Component\Console\Command\Command class, the method to return the name of the command (eg. my:command) is:
$this->getName();
You should use it from within an Artisan command extending Illuminate\Console\Command (default on Artisan commands).
Remember that it will return only the command name and not the available parameters (eg. for the command signature my:command {--with-params=} it will only return my:command).
Reflection might be of help? Try this:
$var = new \ReflectionClass($this);
dd($var);

How to get the current console command in Laravel

I can see if a script is running in the console with the App::runningInConsole() command, but I would like to know (for audit logging purposes) which command has been run from console.
To add some context - I need to log whenever a system or user accesses a certain type of data. For users, that's pretty simple - I can use Auth::user() and get their IP address from Request, but for console commands, it's a little more difficult.
I can figure out if a console command is running, which is good, but I need to be able to record which console command is running.
I do not see a way to get that information directly Laravel. I'm also not sure how that would be possible, as you can have one command executing other commands or even creating a new application instance like some test tools do.
There is however a way to achieve that using plain PHP. You can check the server/environment variables to identify how application was executed.
Have a look at
dd($_SERVER['argv']);
If you run a command this should give you the command name in $_SERVER['argv'][1]
You can find more information here: http://php.net/manual/en/reserved.variables.argv.php
To get console command together with arguments you should use something like that:
$command = \Request::server('argv', null);
if (is_array($command)) {
$command = implode(' ', $command);
}
In Laravel you can use \Request:server to get $_SERVER variables.
The problem with $SERVER['arg'] is that it doesnt work when you execute the command on the GUI.
I fixed the problem adding the next code on the command.
private function getAttributes()
{
$arguments = $this->arguments();
unset($arguments[0]);
$arguments = collect($arguments)->implode(' ');
$options = collect($this->options())->filter(function($item) {
return $item;
})->map(function($item, $key) {
$return = '--'.$key;
if($item!==true) {
$return .= '='.$item;
}
return $return;
})->implode(' ');
return $arguments.' '.$options;
}
and you get it calling $this->getAttributes() and you will get all the command with the attributes

laravel 4.2 liebig package work on localhost but fail in server cron job command

i want to fire some function to get news about football from rss
i used laravel4.2 https://github.com/liebig/cron
as that
Event::listen('cron.collectJobs', function() {
Cron::add('football', '* * * * *', function() {
//the controller of function
$news=new News_feedController();
$news->football();
return 'success';
});
});
$report = Cron::run();
it work correctly when i use cmd
php artisan cron:run
in my computer
but when use the server cron job command
/usr/bin/php /home/public_html/interestoo.com/artisan cron:run
i don't find any change in
cron_job
table but find data in
cron_manager
table
and the cron job function did not work
i'm sure that the path
/home/sfathy/public_html/interestoo.com/
in command is true and does not find any reason for that problem
any help please.
you might want to give this a try usr/bin/php5 /home/public_html/interestoo.com/artisan cron:run due to laravel required php>=5.4

Categories