diff --git a/app/Helpers/Utilities.php b/app/Helpers/Utilities.php index d6b4e752f..6e8e9223c 100644 --- a/app/Helpers/Utilities.php +++ b/app/Helpers/Utilities.php @@ -42,13 +42,14 @@ class Utilities * @param string $minute * @param string $hour * @param string $dayOfMonth + * @param string $month * @param string $dayOfWeek * @return \Carbon\Carbon */ - public static function getScheduleNextRunDate(string $minute, string $hour, string $dayOfMonth, string $dayOfWeek) + public static function getScheduleNextRunDate(string $minute, string $hour, string $dayOfMonth, string $month, string $dayOfWeek) { return Carbon::instance(CronExpression::factory( - sprintf('%s %s %s * %s', $minute, $hour, $dayOfMonth, $dayOfWeek) + sprintf('%s %s %s %s %s', $minute, $hour, $dayOfMonth, $month, $dayOfWeek) )->getNextRunDate()); } diff --git a/app/Http/Controllers/Api/Client/Servers/ScheduleController.php b/app/Http/Controllers/Api/Client/Servers/ScheduleController.php index a9310abd6..0d7241a63 100644 --- a/app/Http/Controllers/Api/Client/Servers/ScheduleController.php +++ b/app/Http/Controllers/Api/Client/Servers/ScheduleController.php @@ -84,6 +84,7 @@ class ScheduleController extends ClientApiController 'server_id' => $server->id, 'name' => $request->input('name'), 'cron_day_of_week' => $request->input('day_of_week'), + 'cron_month' => $request->input('month'), 'cron_day_of_month' => $request->input('day_of_month'), 'cron_hour' => $request->input('hour'), 'cron_minute' => $request->input('minute'), @@ -136,6 +137,7 @@ class ScheduleController extends ClientApiController $data = [ 'name' => $request->input('name'), 'cron_day_of_week' => $request->input('day_of_week'), + 'cron_month' => $request->input('month'), 'cron_day_of_month' => $request->input('day_of_month'), 'cron_hour' => $request->input('hour'), 'cron_minute' => $request->input('minute'), @@ -211,6 +213,7 @@ class ScheduleController extends ClientApiController $request->input('minute'), $request->input('hour'), $request->input('day_of_month'), + $request->input('month'), $request->input('day_of_week') ); } catch (Exception $exception) { diff --git a/app/Models/Schedule.php b/app/Models/Schedule.php index de0475639..6d23f5c11 100644 --- a/app/Models/Schedule.php +++ b/app/Models/Schedule.php @@ -12,6 +12,7 @@ use Pterodactyl\Contracts\Extensions\HashidsInterface; * @property int $server_id * @property string $name * @property string $cron_day_of_week + * @property string $cron_month * @property string $cron_day_of_month * @property string $cron_hour * @property string $cron_minute @@ -58,6 +59,7 @@ class Schedule extends Model 'server_id', 'name', 'cron_day_of_week', + 'cron_month', 'cron_day_of_month', 'cron_hour', 'cron_minute', @@ -93,6 +95,7 @@ class Schedule extends Model protected $attributes = [ 'name' => null, 'cron_day_of_week' => '*', + 'cron_month' => '*', 'cron_day_of_month' => '*', 'cron_hour' => '*', 'cron_minute' => '*', @@ -107,6 +110,7 @@ class Schedule extends Model 'server_id' => 'required|exists:servers,id', 'name' => 'required|string|max:191', 'cron_day_of_week' => 'required|string', + 'cron_month' => 'required|string', 'cron_day_of_month' => 'required|string', 'cron_hour' => 'required|string', 'cron_minute' => 'required|string', @@ -123,7 +127,7 @@ class Schedule extends Model */ public function getNextRunDate() { - $formatted = sprintf('%s %s %s * %s', $this->cron_minute, $this->cron_hour, $this->cron_day_of_month, $this->cron_day_of_week); + $formatted = sprintf('%s %s %s %s %s', $this->cron_minute, $this->cron_hour, $this->cron_day_of_month, $this->cron_month, $this->cron_day_of_week); return CarbonImmutable::createFromTimestamp( CronExpression::factory($formatted)->getNextRunDate()->getTimestamp() diff --git a/app/Transformers/Api/Client/ScheduleTransformer.php b/app/Transformers/Api/Client/ScheduleTransformer.php index 43e35ed42..09e8708e1 100644 --- a/app/Transformers/Api/Client/ScheduleTransformer.php +++ b/app/Transformers/Api/Client/ScheduleTransformer.php @@ -40,6 +40,7 @@ class ScheduleTransformer extends BaseClientTransformer 'cron' => [ 'day_of_week' => $model->cron_day_of_week, 'day_of_month' => $model->cron_day_of_month, + 'month' => $model->cron_month, 'hour' => $model->cron_hour, 'minute' => $model->cron_minute, ], diff --git a/database/migrations/2021_01_13_013420_add_cron_month.php b/database/migrations/2021_01_13_013420_add_cron_month.php new file mode 100644 index 000000000..c449a53e8 --- /dev/null +++ b/database/migrations/2021_01_13_013420_add_cron_month.php @@ -0,0 +1,32 @@ +string('cron_month')->after('cron_day_of_week'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('schedules', function (Blueprint $table) { + $table->dropColumn('cron_month'); + }); + } +} diff --git a/resources/scripts/api/server/schedules/createOrUpdateSchedule.ts b/resources/scripts/api/server/schedules/createOrUpdateSchedule.ts index 0545650be..481cea777 100644 --- a/resources/scripts/api/server/schedules/createOrUpdateSchedule.ts +++ b/resources/scripts/api/server/schedules/createOrUpdateSchedule.ts @@ -11,6 +11,7 @@ export default (uuid: string, schedule: Data): Promise => { minute: schedule.cron.minute, hour: schedule.cron.hour, day_of_month: schedule.cron.dayOfMonth, + month: schedule.cron.month, day_of_week: schedule.cron.dayOfWeek, }) .then(({ data }) => resolve(rawDataToServerSchedule(data.attributes))) diff --git a/resources/scripts/api/server/schedules/getServerSchedules.ts b/resources/scripts/api/server/schedules/getServerSchedules.ts index 42514582a..f7a07617c 100644 --- a/resources/scripts/api/server/schedules/getServerSchedules.ts +++ b/resources/scripts/api/server/schedules/getServerSchedules.ts @@ -5,6 +5,7 @@ export interface Schedule { name: string; cron: { dayOfWeek: string; + month: string; dayOfMonth: string; hour: string; minute: string; @@ -46,6 +47,7 @@ export const rawDataToServerSchedule = (data: any): Schedule => ({ name: data.name, cron: { dayOfWeek: data.cron.day_of_week, + month: data.cron.month, dayOfMonth: data.cron.day_of_month, hour: data.cron.hour, minute: data.cron.minute, diff --git a/resources/scripts/components/server/schedules/EditScheduleModal.tsx b/resources/scripts/components/server/schedules/EditScheduleModal.tsx index 73f74f2cf..e0df9e981 100644 --- a/resources/scripts/components/server/schedules/EditScheduleModal.tsx +++ b/resources/scripts/components/server/schedules/EditScheduleModal.tsx @@ -19,6 +19,7 @@ type Props = { interface Values { name: string; dayOfWeek: string; + month: string; dayOfMonth: string; hour: string; minute: string; @@ -38,7 +39,7 @@ const EditScheduleModal = ({ schedule, ...props }: Omit -
+
@@ -48,6 +49,9 @@ const EditScheduleModal = ({ schedule, ...props }: Omit
+
+ +
@@ -94,6 +98,7 @@ export default ({ schedule, visible, ...props }: Props) => { minute: values.minute, hour: values.hour, dayOfWeek: values.dayOfWeek, + month: values.month, dayOfMonth: values.dayOfMonth, }, isActive: values.enabled, @@ -116,10 +121,11 @@ export default ({ schedule, visible, ...props }: Props) => { onSubmit={submit} initialValues={{ name: schedule?.name || '', - dayOfWeek: schedule?.cron.dayOfWeek || '*', - dayOfMonth: schedule?.cron.dayOfMonth || '*', - hour: schedule?.cron.hour || '*', minute: schedule?.cron.minute || '*/5', + hour: schedule?.cron.hour || '*', + dayOfMonth: schedule?.cron.dayOfMonth || '*', + month: schedule?.cron.month || '*', + dayOfWeek: schedule?.cron.dayOfWeek || '*', enabled: schedule ? schedule.isActive : true, } as Values} validationSchema={null} diff --git a/resources/scripts/components/server/schedules/ScheduleCronRow.tsx b/resources/scripts/components/server/schedules/ScheduleCronRow.tsx index e7918a132..2a733b2d4 100644 --- a/resources/scripts/components/server/schedules/ScheduleCronRow.tsx +++ b/resources/scripts/components/server/schedules/ScheduleCronRow.tsx @@ -22,7 +22,7 @@ const ScheduleCronRow = ({ cron, className }: Props) => (

Day (Month)

-

*

+

{cron.month}

Month

diff --git a/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx b/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx index 17d58ac4e..ff4c12843 100644 --- a/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx +++ b/resources/scripts/components/server/schedules/ScheduleEditContainer.tsx @@ -88,11 +88,11 @@ export default () => { : <> -
+
- +
diff --git a/tests/Integration/Api/Client/Server/Schedule/CreateServerScheduleTest.php b/tests/Integration/Api/Client/Server/Schedule/CreateServerScheduleTest.php index 51345fa79..6c6f9f85e 100644 --- a/tests/Integration/Api/Client/Server/Schedule/CreateServerScheduleTest.php +++ b/tests/Integration/Api/Client/Server/Schedule/CreateServerScheduleTest.php @@ -25,6 +25,7 @@ class CreateServerScheduleTest extends ClientApiIntegrationTestCase 'minute' => '0', 'hour' => '*/2', 'day_of_week' => '2', + 'month' => '1', 'day_of_month' => '*', ]); @@ -39,6 +40,7 @@ class CreateServerScheduleTest extends ClientApiIntegrationTestCase $this->assertSame('0', $schedule->cron_minute); $this->assertSame('*/2', $schedule->cron_hour); $this->assertSame('2', $schedule->cron_day_of_week); + $this->assertSame('1', $schedule->cron_month); $this->assertSame('*', $schedule->cron_day_of_month); $this->assertSame('Test Schedule', $schedule->name); @@ -69,6 +71,7 @@ class CreateServerScheduleTest extends ClientApiIntegrationTestCase 'minute' => '*', 'hour' => '*', 'day_of_month' => '*', + 'month' => '*', 'day_of_week' => '*', ]) ->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY) diff --git a/tests/Integration/Api/Client/Server/Schedule/UpdateServerScheduleTest.php b/tests/Integration/Api/Client/Server/Schedule/UpdateServerScheduleTest.php index ec60a4137..979cd9e2f 100644 --- a/tests/Integration/Api/Client/Server/Schedule/UpdateServerScheduleTest.php +++ b/tests/Integration/Api/Client/Server/Schedule/UpdateServerScheduleTest.php @@ -19,6 +19,7 @@ class UpdateServerScheduleTest extends ClientApiIntegrationTestCase 'minute' => '5', 'hour' => '*', 'day_of_week' => '*', + 'month' => '*', 'day_of_month' => '*', 'is_active' => false, ]; @@ -35,7 +36,7 @@ class UpdateServerScheduleTest extends ClientApiIntegrationTestCase /** @var \Pterodactyl\Models\Schedule $schedule */ $schedule = factory(Schedule::class)->create(['server_id' => $server->id]); - $expected = Utilities::getScheduleNextRunDate('5', '*', '*', '*'); + $expected = Utilities::getScheduleNextRunDate('5', '*', '*', '*', '*'); $response = $this->actingAs($user) ->postJson("/api/client/servers/{$server->uuid}/schedules/{$schedule->id}", $this->updateData);