├── Bootstrap.php
├── .php_cs
├── LICENSE
├── composer.json
├── CallbackEvent.php
├── Schedule.php
├── ScheduleController.php
├── README.md
└── Event.php
/Bootstrap.php:
--------------------------------------------------------------------------------
1 | controllerMap['schedule'])) {
22 | $app->controllerMap['schedule'] = 'yii2mod\scheduling\ScheduleController';
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/.php_cs:
--------------------------------------------------------------------------------
1 | exclude([
5 | 'vendor',
6 | 'runtime',
7 | 'tests/_output',
8 | 'tests/_support',
9 | ])
10 | ->in([__DIR__]);
11 |
12 | $config = PhpCsFixer\Config::create()
13 | ->setUsingCache(false)
14 | ->setRules([
15 | '@Symfony' => true,
16 | 'phpdoc_align' => false,
17 | 'phpdoc_summary' => false,
18 | 'phpdoc_inline_tag' => false,
19 | 'pre_increment' => false,
20 | 'heredoc_to_nowdoc' => false,
21 | 'cast_spaces' => false,
22 | 'include' => false,
23 | 'phpdoc_no_package' => false,
24 | 'concat_space' => ['spacing' => 'one'],
25 | 'ordered_imports' => true,
26 | 'array_syntax' => ['syntax' => 'short'],
27 | 'yoda_style' => false,
28 | ])
29 | ->setFinder($finder);
30 |
31 | return $config;
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Yii2 modules & extensions
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yii2mod/yii2-scheduling",
3 | "description": "Scheduling extension for Yii2 framework",
4 | "type": "yii2-extension",
5 | "keywords": [
6 | "yii",
7 | "scheduling",
8 | "cron"
9 | ],
10 | "authors": [
11 | {
12 | "name": "Igor Chepurnoi",
13 | "email": "chepurnoi.igor@gmail.com"
14 | }
15 | ],
16 | "require": {
17 | "php": ">=5.6",
18 | "yiisoft/yii2": "2.0.*",
19 | "symfony/process": "~3.2",
20 | "mtdowling/cron-expression": "~1.0",
21 | "league/climate": "^3.2",
22 | "guzzlehttp/guzzle": "^6.3",
23 | "nesbot/carbon": "~1.21"
24 | },
25 | "require-dev": {
26 | "friendsofphp/php-cs-fixer": "~2.0",
27 | "phpunit/phpunit": "~6.0"
28 | },
29 | "autoload": {
30 | "psr-4": {
31 | "yii2mod\\scheduling\\": ""
32 | }
33 | },
34 | "extra": {
35 | "bootstrap": "yii2mod\\scheduling\\Bootstrap"
36 | },
37 | "repositories": [
38 | {
39 | "type": "composer",
40 | "url": "https://asset-packagist.org"
41 | }
42 | ]
43 | }
44 |
--------------------------------------------------------------------------------
/CallbackEvent.php:
--------------------------------------------------------------------------------
1 | callback = $callback;
37 | $this->parameters = $parameters;
38 |
39 | if (!is_string($this->callback) && !is_callable($this->callback)) {
40 | throw new InvalidParamException(
41 | 'Invalid scheduled callback event. Must be string or callable.'
42 | );
43 | }
44 |
45 | parent::__construct($config);
46 | }
47 |
48 | /**
49 | * Run the given event.
50 | *
51 | * @param Application $app
52 | *
53 | * @return mixed
54 | */
55 | public function run(Application $app)
56 | {
57 | $response = call_user_func_array($this->callback, array_merge($this->parameters, [$app]));
58 | parent::callAfterCallbacks($app);
59 |
60 | return $response;
61 | }
62 |
63 | /**
64 | * Get the summary of the event for display.
65 | *
66 | * @return string
67 | */
68 | public function getSummaryForDisplay()
69 | {
70 | if (is_string($this->_description)) {
71 | return $this->_description;
72 | }
73 |
74 | return is_string($this->callback) ? $this->callback : 'Closure';
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Schedule.php:
--------------------------------------------------------------------------------
1 | _events[] = $event = new CallbackEvent($callback, $parameters);
31 |
32 | return $event;
33 | }
34 |
35 | /**
36 | * Add a new cli command event to the schedule.
37 | *
38 | * @param string $command
39 | *
40 | * @return Event
41 | */
42 | public function command($command)
43 | {
44 | return $this->exec(PHP_BINARY . ' yii ' . $command);
45 | }
46 |
47 | /**
48 | * Add a new command event to the schedule.
49 | *
50 | * @param string $command
51 | *
52 | * @return Event
53 | */
54 | public function exec($command)
55 | {
56 | $this->_events[] = $event = new Event($command);
57 |
58 | return $event;
59 | }
60 |
61 | /**
62 | * Get events
63 | *
64 | * @return Event[]
65 | */
66 | public function getEvents()
67 | {
68 | return $this->_events;
69 | }
70 |
71 | /**
72 | * Get all of the events on the schedule that are due.
73 | *
74 | * @param \yii\base\Application $app
75 | *
76 | * @return Event[]
77 | */
78 | public function dueEvents(Application $app)
79 | {
80 | return array_filter($this->_events, function (Event $event) use ($app) {
81 | return $event->isDue($app);
82 | });
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/ScheduleController.php:
--------------------------------------------------------------------------------
1 | has($this->schedule)) {
48 | $this->schedule = Instance::ensure($this->schedule, Schedule::class);
49 | } else {
50 | $this->schedule = Yii::createObject(Schedule::class);
51 | }
52 | }
53 |
54 | /**
55 | * Run scheduled commands
56 | */
57 | public function actionRun()
58 | {
59 | $this->importScheduleFile();
60 |
61 | $events = $this->schedule->dueEvents(Yii::$app);
62 |
63 | foreach ($events as $event) {
64 | $this->stdout('Running scheduled command: ' . $event->getSummaryForDisplay() . "\n");
65 | $event->run(Yii::$app);
66 | }
67 |
68 | if (count($events) === 0) {
69 | $this->stdout("No scheduled commands are ready to run.\n");
70 | }
71 | }
72 |
73 | /**
74 | * Render list of registered tasks
75 | */
76 | public function actionList()
77 | {
78 | $this->importScheduleFile();
79 |
80 | $climate = new CLImate();
81 | $data = [];
82 | $row = 0;
83 |
84 | foreach ($this->schedule->getEvents() as $event) {
85 | $data[] = [
86 | '#' => ++$row,
87 | 'Task' => $event->getSummaryForDisplay(),
88 | 'Expression' => $event->getExpression(),
89 | 'Command to Run' => is_a($event, CallbackEvent::class)
90 | ? $event->getSummaryForDisplay()
91 | : $event->command,
92 | 'Next run at' => $this->getNextRunDate($event),
93 | ];
94 | }
95 |
96 | $climate->table($data);
97 | }
98 |
99 | /**
100 | * Import schedule file
101 | *
102 | * @throws InvalidConfigException
103 | */
104 | protected function importScheduleFile()
105 | {
106 | $scheduleFile = Yii::getAlias($this->scheduleFile);
107 |
108 | if (!file_exists($scheduleFile)) {
109 | throw new InvalidConfigException("Can not load schedule file {$this->scheduleFile}");
110 | }
111 |
112 | $schedule = $this->schedule;
113 | call_user_func(function () use ($schedule, $scheduleFile) {
114 | include $scheduleFile;
115 | });
116 | }
117 |
118 | /**
119 | * Get the next scheduled run date for this event
120 | *
121 | * @param Event $event
122 | *
123 | * @return string
124 | */
125 | protected function getNextRunDate(Event $event)
126 | {
127 | $cron = CronExpression::factory($event->getExpression());
128 | $date = Carbon::now();
129 |
130 | if ($event->hasTimezone()) {
131 | $date->setTimezone($event->getTimezone());
132 | }
133 |
134 | return $cron->getNextRunDate()->format('Y-m-d H:i:s');
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Yii2 Schedule Extension
6 |
7 |
8 |
9 | This extension is the port of Laravel's Schedule component (http://laravel.com/docs/master/artisan#scheduling-artisan-commands)
10 |
11 | [](https://packagist.org/packages/yii2mod/yii2-scheduling) [](https://packagist.org/packages/yii2mod/yii2-scheduling)
12 | [](https://packagist.org/packages/yii2mod/yii2-scheduling)
13 | [](https://travis-ci.org/yii2mod/yii2-scheduling)
14 | [](https://scrutinizer-ci.com/g/yii2mod/yii2-scheduling/?branch=master)
15 |
16 | Installation
17 | ------------
18 |
19 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/).
20 |
21 | Either run
22 |
23 | ```
24 | php composer.phar require yii2mod/yii2-scheduling "*"
25 | ```
26 |
27 | or add
28 |
29 | ```
30 | "yii2mod/yii2-scheduling": "*"
31 | ```
32 |
33 | to the `require` section of your composer.json.
34 |
35 | Description
36 | -----------
37 |
38 | This project is inspired by the Laravel's Schedule component and tries to bring it's simplicity to the Yii framework.
39 | Quote from Laravel's documentation:
40 |
41 | ```
42 | In the past, developers have generated a Cron entry for each console command they wished to schedule.
43 | However, this is a headache. Your console schedule is no longer in source control,
44 | and you must SSH into your server to add the Cron entries. Let's make our lives easier.
45 | ```
46 |
47 | After installation all you have to do is to put single line into crontab:
48 |
49 | ```
50 | * * * * * php /path/to/yii yii schedule/run --scheduleFile=@path/to/schedule.php 1>> /dev/null 2>&1
51 | ```
52 |
53 | You can put your schedule into the `schedule.php` file, or add it withing bootstrapping of your extension or
54 | application
55 |
56 | Schedule examples
57 | -----------------
58 |
59 | This extension is support all features of Laravel's Schedule, except environments and maintance mode.
60 |
61 | **Scheduling Closures**
62 |
63 | ```php
64 | $schedule->call(function()
65 | {
66 | // Do some task...
67 |
68 | })->hourly();
69 | ```
70 |
71 | **Scheduling Terminal Commands**
72 |
73 | ```php
74 | $schedule->exec('composer self-update')->daily();
75 | ```
76 |
77 | **Running command of your application**
78 |
79 | ```php
80 | $schedule->command('migrate')->cron('* * * * *');
81 | ```
82 |
83 | **Frequent Jobs**
84 |
85 | ```php
86 | $schedule->command('foo')->everyFiveMinutes();
87 |
88 | $schedule->command('foo')->everyTenMinutes();
89 |
90 | $schedule->command('foo')->everyThirtyMinutes();
91 | ```
92 |
93 | **Daily Jobs**
94 |
95 | ```php
96 | $schedule->command('foo')->daily();
97 | ```
98 |
99 | **Daily Jobs At A Specific Time (24 Hour Time)**
100 |
101 | ```php
102 | $schedule->command('foo')->dailyAt('15:00');
103 | ```
104 |
105 | **Twice Daily Jobs**
106 |
107 | ```php
108 | $schedule->command('foo')->twiceDaily();
109 | ```
110 |
111 | **Job That Runs Every Weekday**
112 |
113 | ```php
114 | $schedule->command('foo')->weekdays();
115 | ```
116 |
117 | **Weekly Jobs**
118 |
119 | ```php
120 | $schedule->command('foo')->weekly();
121 |
122 | // Schedule weekly job for specific day (0-6) and time...
123 | $schedule->command('foo')->weeklyOn(1, '8:00');
124 | ```
125 |
126 | **Monthly Jobs**
127 |
128 | ```php
129 | $schedule->command('foo')->monthly();
130 | ```
131 |
132 | **Job That Runs On Specific Days**
133 |
134 | ```php
135 | $schedule->command('foo')->mondays();
136 | $schedule->command('foo')->tuesdays();
137 | $schedule->command('foo')->wednesdays();
138 | $schedule->command('foo')->thursdays();
139 | $schedule->command('foo')->fridays();
140 | $schedule->command('foo')->saturdays();
141 | $schedule->command('foo')->sundays();
142 | ```
143 |
144 | **Only Allow Job To Run When Callback Is True**
145 |
146 | ```php
147 | $schedule->command('foo')->monthly()->when(function()
148 | {
149 | return true;
150 | });
151 | ```
152 |
153 | **Only Allow Job To Run When `skip` Callback is False**
154 |
155 | ```php
156 | $schedule->command('foo')->monthly()->skip(function()
157 | {
158 | return false;
159 | });
160 | ```
161 |
162 | **Set Custom Description For Scheduled Job**
163 |
164 | ```php
165 | $schedule->command('foo')->monthly()->description('command description');
166 | ```
167 |
168 | **E-mail The Output Of A Scheduled Job**
169 |
170 | ```php
171 | $schedule->command('foo')->sendOutputTo($filePath)->emailOutputTo('foo@example.com');
172 | ```
173 |
174 | **To see the list of registered tasks, you can use the `schedule/list` command as below:**
175 |
176 | ```bash
177 | php yii schedule/list
178 |
179 | +---+-------------------------------------+-------------+-----------------------------------------------------+
180 | | # | Task | Expression | Command to Run |
181 | +---+-------------------------------------+-------------+-----------------------------------------------------+
182 | | 1 | Delete the logs older than week | 0 0 * * 0 * | /usr/bin/php5 yii app/delete-logs-older-then-week |
183 | +---+-------------------------------------+-------------+-----------------------------------------------------+
184 | ```
185 |
186 | How to use this extension in your application?
187 | ----------------------------------------------
188 |
189 | You should create the following file under `@console/config/schedule.php` (note: you can create file with any name
190 | and extension and anywere on your server, simpli ajust the name of the scheduleFile in the command below):
191 |
192 | ```php
193 | exec('ls')->everyFiveMinutes();
202 |
203 | // This command will execute migration command of your application every hour
204 | $schedule->command('migrate')->hourly();
205 |
206 | // This command will call callback function every day at 10:00
207 | $schedule->call(function(\yii\console\Application $app) {
208 | // Some code here...
209 | })->dailyAt('10:00');
210 |
211 | ```
212 |
213 | Next your should add the following command to your crontab:
214 | ```
215 | * * * * * php /path/to/yii yii schedule/run --scheduleFile=@console/config/schedule.php 1>> /dev/null 2>&1
216 | ```
217 |
218 | That's all! Now all your cronjobs will be runned as configured in your schedule.php file.
219 |
220 | How to use this extension in your own extension?
221 | ------------------------------------------------
222 |
223 | First of all, you should include dependency to the `yii2mod\yii2-scheduling` into your composer.json:
224 |
225 | ```
226 | 'require': {
227 | "yii2mod/yii2-scheduling": "*"
228 | }
229 | ```
230 |
231 | Next you should create bootstrapping class for your extension, as described in the http://www.yiiframework.com/doc-2.0/guide-structure-extensions.html#bootstrapping-classes
232 |
233 | Place into your bootstrapping method the following code:
234 |
235 | ```php
236 | public function bootstrap(Application $app)
237 | {
238 | if ($app instanceof \yii\console\Application) {
239 | if ($app->has('schedule')) {
240 | /** @var omnilight\scheduling\Schedule $schedule */
241 | $schedule = $app->get('schedule');
242 | // Place all your shedule command below
243 | $schedule->command('my-extension-command')->dailyAt('12:00');
244 | }
245 | }
246 | }
247 | ```
248 |
249 | Add to the README of your extension info for the user to register `schedule` component for the application
250 | and add `schedule/run` command to the crontab as described upper.
251 |
252 | Using `schedule` component
253 | --------------------------
254 |
255 | You do not have to use `schedule` component directly or define it in your application if you use schedule only in your application (and do not want to give ability for extensions to register they own cron jobs). But if you what to give extensions ability to register cronjobs, you should define `schedule` component in the application config:
256 |
257 | ```php
258 | 'schedule' => 'yii2mod\scheduling\Schedule',
259 | ```
260 |
261 | Using addition functions
262 | ------------------------
263 |
264 | If you want to use `thenPing` method of the Event, you should add the following string to the `composer.json` of your app:
265 | ```
266 | "guzzlehttp/guzzle": "~5.3|~6.0"
267 | ```
268 |
269 | Note about timezones
270 | --------------------
271 |
272 | Please note, that this is PHP extension, so it use timezone defined in php config or in your Yii's configuration file,
273 | so set them correctly.
274 |
--------------------------------------------------------------------------------
/Event.php:
--------------------------------------------------------------------------------
1 | command = $command;
102 | $this->_output = $this->getDefaultOutput();
103 |
104 | parent::__construct($config);
105 | }
106 |
107 | /**
108 | * Run the given event.
109 | *
110 | * @param Application $app
111 | */
112 | public function run(Application $app)
113 | {
114 | $this->trigger(self::EVENT_BEFORE_RUN);
115 |
116 | if (count($this->_afterCallbacks) > 0) {
117 | $this->runCommandInForeground($app);
118 | } else {
119 | $this->runCommandInBackground($app);
120 | }
121 |
122 | $this->trigger(self::EVENT_AFTER_RUN);
123 | }
124 |
125 | /**
126 | * Run the command in the foreground.
127 | *
128 | * @param Application $app
129 | */
130 | protected function runCommandInForeground(Application $app)
131 | {
132 | (new Process(
133 | trim($this->buildCommand(), '& '), dirname($app->request->getScriptFile()), null, null, null
134 | ))->run();
135 | $this->callAfterCallbacks($app);
136 | }
137 |
138 | /**
139 | * Build the command string.
140 | *
141 | * @return string
142 | */
143 | public function buildCommand()
144 | {
145 | $command = $this->command . ' > ' . $this->_output . ' 2>&1 &';
146 |
147 | return $this->_user ? 'sudo -u ' . $this->_user . ' ' . $command : $command;
148 | }
149 |
150 | /**
151 | * Call all of the "after" callbacks for the event.
152 | *
153 | * @param Application $app
154 | */
155 | protected function callAfterCallbacks(Application $app)
156 | {
157 | foreach ($this->_afterCallbacks as $callback) {
158 | call_user_func($callback, $app);
159 | }
160 | }
161 |
162 | /**
163 | * Run the command in the background using exec.
164 | *
165 | * @param Application $app
166 | */
167 | protected function runCommandInBackground(Application $app)
168 | {
169 | chdir(dirname($app->request->getScriptFile()));
170 | exec($this->buildCommand());
171 | }
172 |
173 | /**
174 | * Determine if the given event should run based on the Cron expression.
175 | *
176 | * @param Application $app
177 | *
178 | * @return bool
179 | */
180 | public function isDue(Application $app)
181 | {
182 | return $this->expressionPasses() && $this->filtersPass($app);
183 | }
184 |
185 | /**
186 | * Determine if the Cron expression passes.
187 | *
188 | * @return bool
189 | */
190 | protected function expressionPasses()
191 | {
192 | $date = new \DateTime('now');
193 | if ($this->_timezone) {
194 | $date->setTimezone($this->_timezone);
195 | }
196 |
197 | return CronExpression::factory($this->_expression)->isDue($date);
198 | }
199 |
200 | /**
201 | * Determine if the filters pass for the event.
202 | *
203 | * @param Application $app
204 | *
205 | * @return bool
206 | */
207 | protected function filtersPass(Application $app)
208 | {
209 | if (is_callable($this->_filter) && call_user_func($this->_filter, $app) === false) {
210 | return false;
211 | }
212 |
213 | if (is_callable($this->_reject) && call_user_func($this->_reject, $app)) {
214 | return false;
215 | }
216 |
217 | return true;
218 | }
219 |
220 | /**
221 | * Schedule the event to run hourly.
222 | *
223 | * @return $this
224 | */
225 | public function hourly()
226 | {
227 | return $this->cron('0 * * * * *');
228 | }
229 |
230 | /**
231 | * The Cron expression representing the event's frequency.
232 | *
233 | * @param string $expression
234 | *
235 | * @return $this
236 | */
237 | public function cron($expression)
238 | {
239 | $this->_expression = $expression;
240 |
241 | return $this;
242 | }
243 |
244 | /**
245 | * Schedule the event to run daily.
246 | *
247 | * @return $this
248 | */
249 | public function daily()
250 | {
251 | return $this->cron('0 0 * * * *');
252 | }
253 |
254 | /**
255 | * Schedule the command at a given time.
256 | *
257 | * @param string $time
258 | *
259 | * @return $this
260 | */
261 | public function at($time)
262 | {
263 | return $this->dailyAt($time);
264 | }
265 |
266 | /**
267 | * Schedule the event to run daily at a given time (10:00, 19:30, etc).
268 | *
269 | * @param string $time
270 | *
271 | * @return $this
272 | */
273 | public function dailyAt($time)
274 | {
275 | $segments = explode(':', $time);
276 |
277 | return $this->spliceIntoPosition(2, (int) $segments[0])
278 | ->spliceIntoPosition(1, count($segments) == 2 ? (int) $segments[1] : '0');
279 | }
280 |
281 | /**
282 | * Splice the given value into the given position of the expression.
283 | *
284 | * @param int $position
285 | * @param string $value
286 | *
287 | * @return Event
288 | */
289 | protected function spliceIntoPosition($position, $value)
290 | {
291 | $segments = explode(' ', $this->_expression);
292 | $segments[$position - 1] = $value;
293 |
294 | return $this->cron(implode(' ', $segments));
295 | }
296 |
297 | /**
298 | * Schedule the event to run twice daily.
299 | *
300 | * @return $this
301 | */
302 | public function twiceDaily()
303 | {
304 | return $this->cron('0 1,13 * * * *');
305 | }
306 |
307 | /**
308 | * Schedule the event to run only on weekdays.
309 | *
310 | * @return $this
311 | */
312 | public function weekdays()
313 | {
314 | return $this->spliceIntoPosition(5, '1-5');
315 | }
316 |
317 | /**
318 | * Schedule the event to run only on Mondays.
319 | *
320 | * @return $this
321 | */
322 | public function mondays()
323 | {
324 | return $this->days(1);
325 | }
326 |
327 | /**
328 | * Set the days of the week the command should run on.
329 | *
330 | * @param array|int $days
331 | *
332 | * @return $this
333 | */
334 | public function days($days)
335 | {
336 | $days = is_array($days) ? $days : func_get_args();
337 |
338 | return $this->spliceIntoPosition(5, implode(',', $days));
339 | }
340 |
341 | /**
342 | * Schedule the event to run only on Tuesdays.
343 | *
344 | * @return $this
345 | */
346 | public function tuesdays()
347 | {
348 | return $this->days(2);
349 | }
350 |
351 | /**
352 | * Schedule the event to run only on Wednesdays.
353 | *
354 | * @return $this
355 | */
356 | public function wednesdays()
357 | {
358 | return $this->days(3);
359 | }
360 |
361 | /**
362 | * Schedule the event to run only on Thursdays.
363 | *
364 | * @return $this
365 | */
366 | public function thursdays()
367 | {
368 | return $this->days(4);
369 | }
370 |
371 | /**
372 | * Schedule the event to run only on Fridays.
373 | *
374 | * @return $this
375 | */
376 | public function fridays()
377 | {
378 | return $this->days(5);
379 | }
380 |
381 | /**
382 | * Schedule the event to run only on Saturdays.
383 | *
384 | * @return $this
385 | */
386 | public function saturdays()
387 | {
388 | return $this->days(6);
389 | }
390 |
391 | /**
392 | * Schedule the event to run only on Sundays.
393 | *
394 | * @return $this
395 | */
396 | public function sundays()
397 | {
398 | return $this->days(0);
399 | }
400 |
401 | /**
402 | * Schedule the event to run weekly.
403 | *
404 | * @return $this
405 | */
406 | public function weekly()
407 | {
408 | return $this->cron('0 0 * * 0 *');
409 | }
410 |
411 | /**
412 | * Schedule the event to run weekly on a given day and time.
413 | *
414 | * @param int $day
415 | * @param string $time
416 | *
417 | * @return $this
418 | */
419 | public function weeklyOn($day, $time = '0:0')
420 | {
421 | $this->dailyAt($time);
422 |
423 | return $this->spliceIntoPosition(5, $day);
424 | }
425 |
426 | /**
427 | * Schedule the event to run monthly.
428 | *
429 | * @return $this
430 | */
431 | public function monthly()
432 | {
433 | return $this->cron('0 0 1 * * *');
434 | }
435 |
436 | /**
437 | * Schedule the event to run yearly.
438 | *
439 | * @return $this
440 | */
441 | public function yearly()
442 | {
443 | return $this->cron('0 0 1 1 * *');
444 | }
445 |
446 | /**
447 | * Schedule the event to run every minute.
448 | *
449 | * @return $this
450 | */
451 | public function everyMinute()
452 | {
453 | return $this->cron('* * * * * *');
454 | }
455 |
456 | /**
457 | * Schedule the event to run every N minutes.
458 | *
459 | * @param int|string $minutes
460 | *
461 | * @return $this
462 | */
463 | public function everyNMinutes($minutes)
464 | {
465 | return $this->cron('*/' . $minutes . ' * * * * *');
466 | }
467 |
468 | /**
469 | * Schedule the event to run every five minutes.
470 | *
471 | * @return $this
472 | */
473 | public function everyFiveMinutes()
474 | {
475 | return $this->everyNMinutes(5);
476 | }
477 |
478 | /**
479 | * Schedule the event to run every ten minutes.
480 | *
481 | * @return $this
482 | */
483 | public function everyTenMinutes()
484 | {
485 | return $this->everyNMinutes(10);
486 | }
487 |
488 | /**
489 | * Schedule the event to run every thirty minutes.
490 | *
491 | * @return $this
492 | */
493 | public function everyThirtyMinutes()
494 | {
495 | return $this->cron('0,30 * * * * *');
496 | }
497 |
498 | /**
499 | * Set the timezone the date should be evaluated on.
500 | *
501 | * @param \DateTimeZone|string $timezone
502 | *
503 | * @return $this
504 | */
505 | public function timezone($timezone)
506 | {
507 | $this->_timezone = $timezone;
508 |
509 | return $this;
510 | }
511 |
512 | /**
513 | * @return bool
514 | */
515 | public function hasTimezone()
516 | {
517 | return $this->_timezone !== null;
518 | }
519 |
520 | /**
521 | * @return \DateTimeZone|string
522 | */
523 | public function getTimezone()
524 | {
525 | return $this->_timezone;
526 | }
527 |
528 | /**
529 | * Set which user the command should run as.
530 | *
531 | * @param string $user
532 | *
533 | * @return $this
534 | */
535 | public function user($user)
536 | {
537 | $this->_user = $user;
538 |
539 | return $this;
540 | }
541 |
542 | /**
543 | * Register a callback to further filter the schedule.
544 | *
545 | * @param \Closure $callback
546 | *
547 | * @return $this
548 | */
549 | public function when(\Closure $callback)
550 | {
551 | $this->_filter = $callback;
552 |
553 | return $this;
554 | }
555 |
556 | /**
557 | * Register a callback to further filter the schedule.
558 | *
559 | * @param \Closure $callback
560 | *
561 | * @return $this
562 | */
563 | public function skip(\Closure $callback)
564 | {
565 | $this->_reject = $callback;
566 |
567 | return $this;
568 | }
569 |
570 | /**
571 | * Send the output of the command to a given location.
572 | *
573 | * @param string $location
574 | *
575 | * @return $this
576 | */
577 | public function sendOutputTo($location)
578 | {
579 | $this->_output = $location;
580 |
581 | return $this;
582 | }
583 |
584 | /**
585 | * E-mail the results of the scheduled operation.
586 | *
587 | * @param array $addresses
588 | *
589 | * @return $this
590 | *
591 | * @throws \LogicException
592 | */
593 | public function emailOutputTo($addresses)
594 | {
595 | if (is_null($this->_output) || $this->_output == $this->getDefaultOutput()) {
596 | throw new InvalidCallException('Must direct output to a file in order to e-mail results.');
597 | }
598 | $addresses = is_array($addresses) ? $addresses : func_get_args();
599 |
600 | return $this->then(function (Application $app) use ($addresses) {
601 | $this->emailOutput($app->mailer, $addresses);
602 | });
603 | }
604 |
605 | /**
606 | * Register a callback to be called after the operation.
607 | *
608 | * @param \Closure $callback
609 | *
610 | * @return $this
611 | */
612 | public function then(\Closure $callback)
613 | {
614 | $this->_afterCallbacks[] = $callback;
615 |
616 | return $this;
617 | }
618 |
619 | /**
620 | * E-mail the output of the event to the recipients.
621 | *
622 | * @param MailerInterface $mailer
623 | * @param array $addresses
624 | */
625 | protected function emailOutput(MailerInterface $mailer, $addresses)
626 | {
627 | $mailer->compose()
628 | ->setTextBody(file_get_contents($this->_output))
629 | ->setSubject($this->getEmailSubject())
630 | ->setTo($addresses)
631 | ->send();
632 | }
633 |
634 | /**
635 | * Get the e-mail subject line for output results.
636 | *
637 | * @return string
638 | */
639 | protected function getEmailSubject()
640 | {
641 | if ($this->_description) {
642 | return 'Scheduled Job Output (' . $this->_description . ')';
643 | }
644 |
645 | return 'Scheduled Job Output';
646 | }
647 |
648 | /**
649 | * Register a callback to the ping a given URL after the job runs.
650 | *
651 | * @param string $url
652 | *
653 | * @return $this
654 | */
655 | public function thenPing($url)
656 | {
657 | return $this->then(function () use ($url) {
658 | (new HttpClient())->get($url);
659 | });
660 | }
661 |
662 | /**
663 | * Set the human-friendly description of the event.
664 | *
665 | * @param string $description
666 | *
667 | * @return $this
668 | */
669 | public function description($description)
670 | {
671 | $this->_description = $description;
672 |
673 | return $this;
674 | }
675 |
676 | /**
677 | * Get the Cron description for the event.
678 | *
679 | * @return string
680 | */
681 | public function getDescription()
682 | {
683 | return $this->_description;
684 | }
685 |
686 | /**
687 | * Get the summary of the event for display.
688 | *
689 | * @return string
690 | */
691 | public function getSummaryForDisplay()
692 | {
693 | if (is_string($this->_description)) {
694 | return $this->_description;
695 | }
696 |
697 | return $this->buildCommand();
698 | }
699 |
700 | /**
701 | * Get the Cron expression for the event.
702 | *
703 | * @return string
704 | */
705 | public function getExpression()
706 | {
707 | return $this->_expression;
708 | }
709 |
710 | /**
711 | * Get default output
712 | *
713 | * @return string
714 | */
715 | public function getDefaultOutput()
716 | {
717 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
718 | return 'NUL';
719 | } else {
720 | return '/dev/null';
721 | }
722 | }
723 | }
724 |
--------------------------------------------------------------------------------