I have been banging my head for last 3 days to set cron for my website. In my cpanel I have mentioned a cron which will run every 5 minutes and command is
wget http://www.example.com/artisan cron:run
In my artisan I have added
Artisan::add(new CronRunCommand);
And CronRunCommand.php is
<?php
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
class CronRunCommand extends Command {
protected $name = 'cron:run';
protected $description = 'Run the scheduler';
protected $timestamp;
protected $messages = array();
protected $runAt = '03:00';
public function __construct()
{
parent::__construct();
$this->timestamp = time();
}
public function fire()
{
$this->everyFiveMinutes(function()
{
// In the function, you can use anything that you can use everywhere else in Laravel.
$affectedRows = User::where('logged_in', true)->update(array('logged_in' => false)); // Not really useful, but possible
Artisan::call('auth:clear-reminders');
$this->messages[] = $affectedRows . ' users logged out';
});
$this->dailyAt('09:00', function()
{
Mail::send('hello', array(), function($message)
{
$message->to('admin#mydomain.com', 'Cron Job')->subject('I am still running!');
});
});
$this->finish();
}
protected function finish()
{
// Write execution time and messages to the log
$executionTime = round(((microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']) * 1000), 3);
Log::info('Cron: execution time: ' . $executionTime . ' | ' . implode(', ', $this->messages));
}
protected function yearly(callable $callback)
{
if(date('m', $this->timestamp) === '01' && date('d', $this->timestamp) === '01' && date('H:i', $this->timestamp) === $this->runAt) call_user_func($callback);
}
}
And in my email I am getting this message:
404 Not Found
2015-09-06 04:38:02 ERROR 404: Not Found.
--2015-09-06 04:38:02-- ftp://cron/run
=> “run”
Resolving cron... failed: Name or service not known.
wget: unable to resolve host address “cron”
This worked absolutely fine and I have started regular emails
wget http://www.example.com/protected/app/controllers/TestController.php
Related
I want to run simple bash scripts using laravel command class, but I have not found error.
If I go to /var/www/mysite/storage/app/scripts and run script from there in command line, then everything is OK.
$ sh remove-spaces.sh
What is wrong in my Laravel code?
lowercase.sh
for file in /var/www/mysite/storage/app/img/*;
do mv "$file" "`echo $file | tr '[A-Z]' '[a-z]'`";
done
remove-spaces.sh
for file in /var/www/mysite/storage/app/img/*;
do mv "$file" `echo $file | tr ' ' '-'`;
done
RenamePicturesCommand
namespace App\Console\Commands\Pictures;
use Illuminate\Console\Command;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
class RenamePicturesCommand extends Command
{
protected $removeSpaces;
protected $lowercase;
protected $signature = 'pictures:rename';
public function __construct()
{
parent::__construct();
$this->removeSpaces = new Process(['sh /var/www/mysite/storage/app/scripts/remove-spaces.sh']);
$this->lowercase = new Process(['sh /var/www/mysite/storage/app/scripts/lowercase.sh']);
}
public function handle()
{
$this->removeSpaces->run();
if (!$this->removeSpaces->isSuccessful()) {
throw new ProcessFailedException($this->removeSpaces);
}
echo $this->removeSpaces->getOutput();
$this->lowercase->run();
if (!$this->lowercase->isSuccessful()) {
throw new ProcessFailedException($this->lowercase);
}
echo $this->lowercase->getOutput();
}
}
error output
http#0bb690b74597:/var/www/mysite$ php artisan pictures:rename
Symfony\Component\Process\Exception\ProcessFailedException
The command "'sh /var/www/mysite/storage/app/scripts/remove-spaces.sh'" failed.
Exit Code: 127(Command not found)
Working directory: /var/www/mysite
Output:
================
Error Output:
================
sh: 1: exec: sh /var/www/mysite/storage/app/scripts/remove-spaces.sh: not found
at app/Console/Commands/Pictures/RenamePicturesCommand.php:59
55▕ // execute command
56▕ $this->removeSpaces->run();
57▕ // executes after the command finishes
58▕ if (!$this->removeSpaces->isSuccessful()) {
➜ 59▕ throw new ProcessFailedException($this->removeSpaces);
60▕ }
61▕ echo $this->removeSpaces->getOutput();
62▕
63▕
+13 vendor frames
14 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
You may try to provide the command and argument as two separate items in the commands array
namespace App\Console\Commands\Pictures;
use Illuminate\Console\Command;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
class RenamePicturesCommand extends Command
{
protected $removeSpaces;
protected $lowercase;
protected $signature = 'pictures:rename';
public function __construct()
{
parent::__construct();
$this->removeSpaces = new Process(['sh', '/var/www/mysite/storage/app/scripts/remove-spaces.sh']);
$this->lowercase = new Process(['sh', '/var/www/mysite/storage/app/scripts/lowercase.sh']);
//Or you can use Process::fromShellCommandline
//$this->removeSpaces =Process::fromShellCommandline('sh /Volumes/samsung-250/Sites/stackoverflow/storage/app/scripts/lowercase.sh');
//$this->lowercase =Process::fromShellCommandline('sh /Volumes/samsung-250/Sites/stackoverflow/storage/app/scripts/remove-spaces.sh');
}
public function handle()
{
$this->removeSpaces->run();
if (!$this->removeSpaces->isSuccessful()) {
throw new ProcessFailedException($this->removeSpaces);
}
echo $this->removeSpaces->getOutput();
$this->lowercase->run();
if (!$this->lowercase->isSuccessful()) {
throw new ProcessFailedException($this->lowercase);
}
echo $this->lowercase->getOutput();
}
}
You can also achieve the same results with Storage facade without any shell script
namespace App\Console\Commands\Pictures;
use Illuminate\Console\Command;
use Illuminate\Support\LazyCollection;
class RenamePicturesCommand extends Command
{
protected $signature = 'pictures:rename';
public function handle()
{
$this->info('Renaming pictures...');
$this->newLine(2);
$files = LazyCollection::make(Storage::disk('local')->files('img'))
//Remove dotfiles
->reject(fn($filePath) => Str::startsWith($filePath, '.'));
$progress = $this->output->createProgressBar($files->count());
$progress->start();
$modified = [];
$files->each(function ($file) use ($progress, &$modified) {
$new = strtolower(preg_replace('/\s+/', '-', $file));
$temp = ['old' => $file, 'new' => $new, 'status' => 'success'];
if(! Storage::disk('local')->move($file, $new)) {
$temp['status'] = 'failed';
$temp['new'] = $file;
}
$modified[] = $temp;
$progress->advance();
});
$this->newLine(2);
$this->info('Finished Renaming pictures');
$this->newLine(2);
$this->table(['Old', 'New', 'Status'], $modified);
}
}
I have an email service that allows me to send only 60 emails per hour (1/minute).
So that is why i m trying to write an application that respect the service provider's restrictions,
I m dispatching emails to bulk users at once via queue jobs,Please take a look at the code
public function sendEmails(CreateEmailRequest $request)
{
$data = [];
$users = User::find($request->to);
$subject = $request->subject;
$body = $this->fileUpload($request->body);
foreach ($users as $user) {
$vars = array(
"{{name}}" => $user->name,
"{{email}}" => $user->email,
);
$body = strtr($body, $vars);
$data['body'] = $body;
$data['user'] = $user;
$data['subject'] = $subject;
dispatch(new SendEmailJob($data))->onQueue('mail');
}
Flash::success('Email sent successfully.');
return redirect(route('emails.index'));
}
here is SendEmailJob Class code
public function handle()
{
$data = $this->data;
$body = $data['body'];
$user = $data['user'];
$subject = $data['subject'];
// list($body, $user, $subject) = $this->data;
Mail::send('mail.email', ['body' => $body], function ($m) use ($user, $subject) {
$m->to($user->email)->subject($subject);
});
}
public function middleware()
{
return Limit::perMinute(1);
}
when I run php artisan queue:work it process all jobs at once..
can you please tell me how can I achieve this?
I can not use spatie/laravel-rate-limited-job-middleware because my server does not support Redis.
Can you please tell me i m doing wrong ?
You can use Job Middleware with a rate limiting
in the boot method of your AppServiceProvider
RateLimiter::for('emails', function($job) {
return Limit::perMinute(1);
});
and add middleware to the job:
use Illuminate\Queue\Middleware\RateLimited;
public function middleware()
{
return [new RateLimited('emails')];
}
I have a command that I'll run nightly using the Forge scheduler. The command simply loops through and sends emails to each user who qualifies for one.
COMMAND:
public function handle()
{
//Get all users
$users = User::all();
$data = [];
$renewalEmail = '';
foreach($users as $user)
{
//Check each users next_biling_date and see if is less than 72 hours from now, if so send reminder email
$nextBillingDate = ($user->hasSubscription())? $user->getSubscriptionData()->current_period_end : false;
$now = strtotime(now());
$threeDaysFromNow = 60*60*24*3;
//($user->hasSubscription())? $this->updateNextBillingDate($user) : false;//TODO: remove after working: follow up
if($user->hasSubscription() && $nextBillingDate-$now<=$threeDaysFromNow)
{
$data = [
'name' => $user->name,
'billingdate' => date('n/j/Y',strtotime($user->next_billing_date)),
];
// Log::info(print_r($data,true));
$renewalEmail = Mail::to('my#email.com')->send(new SubscriptionRenewalReminder($data));
// Log::info(print_r($renewalEmail,true));
}
}
return true;
}
My Mailable is pretty straight forward:
public function __construct($data)
{
$this->data = $data;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
Log::info('SubscriptionRenewalReminder Email build() called: ');
$firstName = explode(' ',$this->data['name'])[0];
$billingDate = $this->data['billingdate'];
Log::info('firstname: '.$firstName);
Log::info('billingDate: '.$billingDate);
return $this->view('emails.subscription-renewal-reminder')
->from('my#email.com', 'Project')
->subject('Project Subscription Is About To Renew')
->withName($firstName)
->withBillingdate($billingDate);
}
All of my Log::info's dump out the right information. I have 3 test users who all qualify to get the email.
In my testing, all three emails show the first user's name and billing date. Instead of unique emails, they are all identical.
I may move this into a queue but on a small set of users this should work fine. TIA
When I run the task from a console with:
typo3/sysext/core/bin/typo3 scheduler:run
nothing happens. No errors and no mail. The path to PHP is in my search path so that is not the problem. When I run the task from the TYPO3 BE the task get executed as expected. Also after the task should be executed based on the time scheme of the scheduler a sign late appears.
Does anybody know why executing the scheduler task from a console doesn't work.
I use TYPO3 9.5.14. My code in ext_localconf.php:
// Register handler calls for Scheduler
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks’][\Vendor\Extensionname\Command\SyncCommand::class] = [
'extension' => 'verwijswijzer',
'title' => 'LLL:EXT:verwijswijzer/Resources/Private/Language/locallang_be.xlf:scheduler.title',
'description' => 'LLL:EXT:verwijswijzer/Resources/Private/Language/locallang_be.xlf:scheduler.description'
];
and in Classes/Command/SyncCommand.php
namespace Vendor\Extensionname\Command;
use TYPO3\CMS\Scheduler\Task\AbstractTask;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use Vendor\Extensionname\Task\StoreRecords;
class SyncCommand extends AbstractTask {
public $email="email#dnaklik.nl";
public function execute()
{
$exec = $this->getExecution();
// Get call method
if (Environment::isCli()) {
$calledBy = 'CLI module dispatcher';
$site = '-';
} else {
$calledBy = 'TYPO3 backend';
$site = GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
}
$start = $exec->getStart();
$end = $exec->getEnd();
$interval = $exec->getInterval();
$multiple = $exec->getMultiple();
$cronCmd = $exec->getCronCmd();
$mailBody = 'Some content');
// Prepare mailer and send the mail
try {
/** #var \TYPO3\CMS\Core\Mail\MailMessage $mailer */
$mailer = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
$mailer->setFrom([$this->email => 'SCHEDULER GGZ-API-TASK']);
$mailer->setReplyTo([$this->email => 'SCHEDULER GGZ-API-TASK']);
$mailer->setSubject('SCHEDULER GGZ-API-TASK');
$mailer->setBody($mailBody);
$mailer->setTo($this->email);
$mailsSend = $mailer->send();
$success = $mailsSend > 0;
} catch (\Exception $e) {
throw new \TYPO3\CMS\Core\Exception($e->getMessage(), 1476048416);
}
$execTask = GeneralUtility::makeInstance(MyTask::class );
$execTask->run();
return true;
}
}
The following code runs fine under Magento 1.6 but raises a Mage_Core_Exception (message: 'Cannot retrieve entity config: sales/Array') when run under 1.5.0.1. What do I need to do to get this code running under Magento 1.5.0.1?
$results = Mage::getResourceModel('sales/order_collection');
$results->join(
array('status_key_table' => 'order_status'),
'main_table.status = status_key_table.status',
array('status_key_table.label')
);
Thank you,
Ben
If you compare the join() methods between 1.5.0.1 and 1.6.2.0:
1.5.0.1: Mage_Core_Model_Mysql4_Collection_Abstract::join()
public function join($table, $cond, $cols='*')
{
if (!isset($this->_joinedTables[$table])) {
$this->getSelect()->join(array($table=>$this->getTable($table)), $cond, $cols);
$this->_joinedTables[$table] = true;
}
return $this;
}
1.6.2.0: Mage_Core_Model_Resource_Db_Collection_Abstract::join()
public function join($table, $cond, $cols = '*')
{
if (is_array($table)) {
foreach ($table as $k => $v) {
$alias = $k;
$table = $v;
break;
...
You can see that 1.5.0.1 doesn't support aliases. Instead, it calls $this->getTable() on the first parameter you pass in -- which should be a string. So, in your case, you'll need to pass in 'sales/order_status' as the first parameter.