11<?php
2- /**
3- * Pterodactyl - Panel
4- * Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
5- *
6- * This software is licensed under the terms of the MIT license.
7- * https://opensource.org/licenses/MIT
8- */
92
103namespace Pterodactyl \Services \Schedules ;
114
5+ use Carbon \Carbon ;
126use Cron \CronExpression ;
13- use Webmozart \Assert \Assert ;
147use Pterodactyl \Models \Schedule ;
158use Pterodactyl \Services \Schedules \Tasks \RunTaskService ;
169use Pterodactyl \Contracts \Repository \ScheduleRepositoryInterface ;
@@ -20,12 +13,17 @@ class ProcessScheduleService
2013 /**
2114 * @var \Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface
2215 */
23- protected $ repository ;
16+ private $ repository ;
2417
2518 /**
2619 * @var \Pterodactyl\Services\Schedules\Tasks\RunTaskService
2720 */
28- protected $ runnerService ;
21+ private $ runnerService ;
22+
23+ /**
24+ * @var \Carbon\Carbon|null
25+ */
26+ private $ runTimeOverride ;
2927
3028 /**
3129 * ProcessScheduleService constructor.
@@ -39,23 +37,31 @@ public function __construct(RunTaskService $runnerService, ScheduleRepositoryInt
3937 $ this ->runnerService = $ runnerService ;
4038 }
4139
40+ /**
41+ * Set the time that this schedule should be run at. This will override the time
42+ * defined on the schedule itself. Useful for triggering one-off task runs.
43+ *
44+ * @param \Carbon\Carbon $time
45+ * @return $this
46+ */
47+ public function setRunTimeOverride (Carbon $ time )
48+ {
49+ $ this ->runTimeOverride = $ time ;
50+
51+ return $ this ;
52+ }
53+
4254 /**
4355 * Process a schedule and push the first task onto the queue worker.
4456 *
45- * @param int| \Pterodactyl\Models\Schedule $schedule
57+ * @param \Pterodactyl\Models\Schedule $schedule
4658 *
4759 * @throws \Pterodactyl\Exceptions\Model\DataValidationException
4860 * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
4961 */
50- public function handle ($ schedule )
62+ public function handle (Schedule $ schedule )
5163 {
52- Assert::true (($ schedule instanceof Schedule || is_digit ($ schedule )),
53- 'First argument passed to handle must be instance of \Pterodactyl\Models\Schedule or an integer, received %s. '
54- );
55-
56- if (($ schedule instanceof Schedule && ! $ schedule ->relationLoaded ('tasks ' )) || ! $ schedule instanceof Schedule) {
57- $ schedule = $ this ->repository ->getScheduleWithTasks (is_digit ($ schedule ) ? $ schedule : $ schedule ->id );
58- }
64+ $ this ->repository ->loadTasks ($ schedule );
5965
6066 $ formattedCron = sprintf ('%s %s %s * %s * ' ,
6167 $ schedule ->cron_minute ,
@@ -66,10 +72,25 @@ public function handle($schedule)
6672
6773 $ this ->repository ->update ($ schedule ->id , [
6874 'is_processing ' => true ,
69- 'next_run_at ' => CronExpression:: factory ( $ formattedCron )-> getNextRunDate ( ),
75+ 'next_run_at ' => $ this -> getRunAtTime ( $ formattedCron ),
7076 ]);
7177
72- $ task = $ schedule ->tasks ->where ('sequence_id ' , 1 )->first ();
78+ $ task = $ schedule ->getRelation ( ' tasks ' ) ->where ('sequence_id ' , 1 )->first ();
7379 $ this ->runnerService ->handle ($ task );
7480 }
81+
82+ /**
83+ * Get the timestamp to store in the database as the next_run time for a schedule.
84+ *
85+ * @param string $formatted
86+ * @return \DateTime|string
87+ */
88+ private function getRunAtTime (string $ formatted )
89+ {
90+ if ($ this ->runTimeOverride instanceof Carbon) {
91+ return $ this ->runTimeOverride ->toDateTimeString ();
92+ }
93+
94+ return CronExpression::factory ($ formatted )->getNextRunDate ();
95+ }
7596}
0 commit comments