diff --git a/LibreNMS/Alert/AlertRules.php b/LibreNMS/Alert/AlertRules.php index 02597bd727..cdd7ccff72 100644 --- a/LibreNMS/Alert/AlertRules.php +++ b/LibreNMS/Alert/AlertRules.php @@ -34,6 +34,7 @@ namespace LibreNMS\Alert; use App\Models\Device; +use Carbon\Carbon; use LibreNMS\Alert\AlertUtil; use LibreNMS\Alert\AlertDB; use LibreNMS\Enum\AlertState; @@ -113,7 +114,7 @@ class AlertRules if (is_null($current_state)) { dbInsert(array('state' => AlertState::ACTIVE, 'device_id' => $device_id, 'rule_id' => $rule['id'], 'open' => 1,'alerted' => 0), 'alerts'); } else { - dbUpdate(['state' => AlertState::ACTIVE, 'open' => 1, 'timestamp' => array('NOW()')], 'alerts', 'device_id = ? && rule_id = ?', [$device_id, $rule['id']]); + dbUpdate(['state' => AlertState::ACTIVE, 'open' => 1, 'timestamp' => Carbon::now()->timestamp], 'alerts', 'device_id = ? && rule_id = ?', [$device_id, $rule['id']]); } c_echo(PHP_EOL . 'Status: %rALERT'); } @@ -126,7 +127,7 @@ class AlertRules if (is_null($current_state)) { dbInsert(['state' => AlertState::RECOVERED, 'device_id' => $device_id, 'rule_id' => $rule['id'], 'open' => 1, 'alerted' => 0], 'alerts'); } else { - dbUpdate(['state' => AlertState::RECOVERED, 'open' => 1, 'note' => '', 'timestamp' => array('NOW()')], 'alerts', 'device_id = ? && rule_id = ?', [$device_id, $rule['id']]); + dbUpdate(['state' => AlertState::RECOVERED, 'open' => 1, 'note' => '', 'timestamp' => Carbon::now()->timestamp], 'alerts', 'device_id = ? && rule_id = ?', [$device_id, $rule['id']]); } c_echo(PHP_EOL . 'Status: %gOK'); diff --git a/LibreNMS/Alert/AlertUtil.php b/LibreNMS/Alert/AlertUtil.php index 85bd136b6e..6ca72bf8b7 100644 --- a/LibreNMS/Alert/AlertUtil.php +++ b/LibreNMS/Alert/AlertUtil.php @@ -27,6 +27,7 @@ namespace LibreNMS\Alert; use App\Models\Device; use App\Models\User; +use DeviceCache; use LibreNMS\Config; use PHPMailer\PHPMailer\PHPMailer; @@ -196,8 +197,7 @@ class AlertUtil */ public static function isMaintenance($device_id) { - $device = Device::find($device_id); - return !is_null($device) && $device->isUnderMaintenance(); + return DeviceCache::get($device_id)->isUnderMaintenance(); } /** diff --git a/LibreNMS/Alert/RunAlerts.php b/LibreNMS/Alert/RunAlerts.php index f8e5f1fc7e..d925e01518 100644 --- a/LibreNMS/Alert/RunAlerts.php +++ b/LibreNMS/Alert/RunAlerts.php @@ -453,7 +453,7 @@ class RunAlerts $noacc = false; } - if (AlertUtil::isMaintenance($alert['device_id']) > 0) { + if (AlertUtil::isMaintenance($alert['device_id'])) { $noiss = true; $noacc = true; } diff --git a/app/Http/Controllers/PaginatedAjaxController.php b/app/Http/Controllers/PaginatedAjaxController.php index aca30ae9ff..534a68edd0 100644 --- a/app/Http/Controllers/PaginatedAjaxController.php +++ b/app/Http/Controllers/PaginatedAjaxController.php @@ -33,6 +33,12 @@ use Illuminate\Support\Collection; abstract class PaginatedAjaxController extends Controller { + /** + * Default sort, column => direction + * @var array + */ + protected $default_sort = []; + /** * Base rules for this controller. * @@ -88,6 +94,18 @@ abstract class PaginatedAjaxController extends Controller return []; } + /** + * Defines sortable fields. The incoming sort field should be the key, the sql column or DB::raw() should be the value + * + * @param \Illuminate\Http\Request $request + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function sortFields($request) + { + return []; + } + /** * Format an item for display. Default is pass-through * @@ -148,9 +166,14 @@ abstract class PaginatedAjaxController extends Controller */ protected function sort($request, $query) { - $sort = $request->get('sort', []); + $columns = $this->sortFields($request); + + $sort = $request->get('sort', $this->default_sort); + foreach ($sort as $column => $direction) { - $query->orderBy($column, $direction); + if (isset($columns[$column])) { + $query->orderBy($columns[$column], $direction == 'desc' ? 'desc' : 'asc'); + } } return $query; diff --git a/app/Http/Controllers/Table/AlertScheduleController.php b/app/Http/Controllers/Table/AlertScheduleController.php new file mode 100644 index 0000000000..6645055efc --- /dev/null +++ b/app/Http/Controllers/Table/AlertScheduleController.php @@ -0,0 +1,101 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2020 Tony Murray + * @author Tony Murray + */ + +namespace App\Http\Controllers\Table; + +use App\Models\AlertSchedule; +use Carbon\Carbon; +use DB; + +class AlertScheduleController extends TableController +{ + protected $default_sort = ['title' => 'asc', 'start' => 'asc']; + + protected function baseQuery($request) + { + return AlertSchedule::query(); + } + + protected function searchFields($request) + { + return['title', 'start', 'end']; + } + + protected function sortFields($request) + { + return [ + 'start_recurring_dt' => DB::raw('DATE(`start`)'), + 'start_recurring_ht' => DB::raw('TIME(`start`)'), + 'end_recurring_dt' => DB::raw('DATE(`end`)'), + 'end_recurring_ht' => DB::raw('TIME(`end`)'), + 'title' => 'title', + 'recurring' => 'recurring', + 'start' => 'start', + 'end' => 'end', + 'status' => DB::raw("end < '" . Carbon::now('UTC') ."'"), // only partition lapsed + ]; + } + + /** + * @param AlertSchedule $schedule + * @return array + */ + public function formatItem($schedule) + { + return [ + 'title' => $schedule->title, + 'notes' => $schedule->notes, + 'id' => $schedule->schedule_id, + 'start' => $schedule->recurring ? '' : $schedule->start->toDateTimeString('minutes'), + 'end' => $schedule->recurring ? '' : $schedule->end->toDateTimeString('minutes'), + 'start_recurring_dt' => $schedule->recurring ? $schedule->start_recurring_dt : '', + 'start_recurring_hr' => $schedule->recurring ? $schedule->start_recurring_hr : '', + 'end_recurring_dt' => $schedule->recurring ? $schedule->end_recurring_dt : '', + 'end_recurring_hr' => $schedule->recurring ? $schedule->end_recurring_hr : '', + 'recurring' => $schedule->recurring ? __('Yes') : __('No'), + 'recurring_day' => $schedule->recurring ? implode(',', $schedule->recurring_day) : '', + 'status' => $schedule->status, + ]; + } + +// /** +// * @param Request $request +// * @param Builder $query +// * @return Builder +// */ +// protected function sort($request, $query) +// { +// $columns = $this->sortFields($request); +// $sort = $request->get('sort', $this->default_sort); +// +// foreach ($sort as $column => $direction) { +// if (isset($columns[$column])) { +// $query->orderBy($columns[$column], $direction == 'desc' ? 'desc' : 'asc'); +// } +// } +// +// return $query; +// } +} diff --git a/app/Http/Controllers/Table/TableController.php b/app/Http/Controllers/Table/TableController.php index 7ee2d6738d..5acffbfb70 100644 --- a/app/Http/Controllers/Table/TableController.php +++ b/app/Http/Controllers/Table/TableController.php @@ -32,7 +32,17 @@ use Illuminate\Http\Request; abstract class TableController extends PaginatedAjaxController { - protected $default_sort = []; + protected $model; + + protected function sortFields($request) + { + if (isset($this->model)) { + $fields = \Schema::getColumnListing((new $this->model)->getTable()); + return array_combine($fields, $fields); + } + + return []; + } final protected function baseRules() { diff --git a/app/Models/AlertSchedule.php b/app/Models/AlertSchedule.php index fdeeaff33a..429a1e440d 100644 --- a/app/Models/AlertSchedule.php +++ b/app/Models/AlertSchedule.php @@ -25,48 +25,187 @@ namespace App\Models; +use Carbon\Carbon; +use Carbon\CarbonImmutable; +use Date; use DB; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class AlertSchedule extends Model { + const SCHEDULE_SET = 0; + const SCHEDULE_ACTIVE = 2; + const SCHEDULE_LAPSED = 1; + public $timestamps = false; protected $table = 'alert_schedule'; protected $primaryKey = 'schedule_id'; + protected $appends = ['start_recurring_dt', 'end_recurring_dt', 'start_recurring_hr', 'end_recurring_hr', 'status']; + + private $timezone; + private $days = [ + 'Mo' => 1, + 'Tu' => 2, + 'We' => 3, + 'Th' => 4, + 'Fr' => 5, + 'Sa' => 6, + 'Su' => 7, + ]; + + public function __construct(array $attributes = []) + { + parent::__construct($attributes); + $this->timezone = config('app.timezone'); + } + + // ---- Accessors/Mutators ---- + + public function getRecurringDayAttribute() + { + return explode(',', str_replace(array_values($this->days), array_keys($this->days), $this->attributes['recurring_day'])); + } + + public function setRecurringDayAttribute($days) + { + $days = is_array($days) ? $days : explode(',', $days); + $new_days = []; + + foreach ($days as $day) { + if (isset($this->days[$day])) { + $new_days[] = $this->days[$day]; + } + } + + $this->attributes['recurring_day'] = implode(',', $new_days); + } + + public function getStartAttribute() + { + return Date::parse($this->attributes['start'], 'UTC')->tz($this->timezone); + } + + public function setStartAttribute($start) + { + $this->attributes['start'] = $this->fromDateTime(Date::parse($start)->tz('UTC')); + } + + public function getEndAttribute() + { + return Date::parse($this->attributes['end'], 'UTC')->tz($this->timezone); + } + + public function setEndAttribute($end) + { + $this->attributes['end'] = $this->fromDateTime(Date::parse($end)->tz('UTC')); + } + + public function getStartRecurringDtAttribute() + { + return $this->start->toDateString(); + } + + public function getStartRecurringHrAttribute() + { + return $this->start->toTimeString('minute'); + } + + public function getEndRecurringDtAttribute() + { + $end = $this->end; + return $end->year == '9000' ? null : $end->toDateString(); + } + + public function getEndRecurringHrAttribute() + { + return $this->end->toTimeString('minute'); + } + + public function setStartRecurringDtAttribute($date) + { + $this->start = $this->start->setDateFrom(Date::parse($date, $this->timezone)); + } + + public function setStartRecurringHrAttribute($time) + { + $this->start = $this->start->setTimeFrom(Date::parse($time, $this->timezone)); + } + + public function setEndRecurringDtAttribute($date) + { + $this->end = $this->end->setDateFrom(Date::parse($date ?: '9000-09-09', $this->timezone)); + } + + public function setEndRecurringHrAttribute($time) + { + $this->end = $this->end->setTimeFrom(Date::parse($time, $this->timezone)); + } + + /** + * @return int Status 0: SCHEDULE_SET, 1: SCHEDULE_LAPSED, 2: SCHEDULE_ACTIVE + */ + public function getStatusAttribute() + { + $now = Carbon::now(); + + if ($now > $this->end) { + return self::SCHEDULE_LAPSED; + } + + if (!$this->recurring) { + return $now > $this->start ? self::SCHEDULE_ACTIVE : self::SCHEDULE_SET; + } + + // recurring + $now_time = $now->secondsSinceMidnight(); + $start_time = $this->start->secondsSinceMidnight(); + $end_time = $this->end->secondsSinceMidnight(); + $after_start = $now > $this->start; + $spans_days = $start_time > $end_time; + + // check inside start and end times or outside start and end times (if we span a day) + $active = $spans_days ? ($after_start && ($now_time < $end_time || $now_time >= $start_time)) : ($now_time >= $start_time && $now_time < $end_time); + + return $active && Str::contains($this->attributes['recurring_day'], $now->format('N')) ? self::SCHEDULE_ACTIVE : self::SCHEDULE_SET; + } // ---- Query scopes ---- public function scopeIsActive($query) { - // TODO use Carbon? return $query->where(function ($query) { - $query->where(function ($query) { - // Non recurring simply between start and end - $query->where('recurring', 0) - ->where('start', '<=', DB::raw('NOW()')) - ->where('end', '>=', DB::raw('NOW()')); - })->orWhere(function ($query) { - $query->where('recurring', 1) - // Check the time is after the start date and before the end date, or end date is not set - ->where(function ($query) { - $query->where('start_recurring_dt', '<=', DB::raw("date_format(NOW(), '%Y-%m-%d')")) - ->where(function ($query) { - $query->where('end_recurring_dt', '>=', DB::raw("date_format(NOW(), '%Y-%m-%d')")) - ->orWhereNull('end_recurring_dt'); + $now = CarbonImmutable::now('UTC'); + $query->where('start', '<=', $now) + ->where('end', '>=', $now) + ->where(function ($query) use ($now) { + $query->where('recurring', 0) // Non recurring simply between start and end + ->orWhere(function ($query) use ($now) { + $query->where('recurring', 1) + // Check the time is after the start date and before the end date, or end date is not set + ->where(function ($query) use ($now) { + $query->where(function ($query) use ($now) { + // normal, inside one day + $query->whereTime('start', '<', DB::raw("time(`end`)")) + ->whereTime('start', '<=', $now->toTimeString()) + ->whereTime('end', '>', $now->toTimeString()); + })->orWhere(function ($query) use ($now) { + // outside, spans days + $query->whereTime('start', '>', DB::raw("time(`end`)")) + ->where(function ($query) use ($now) { + $query->whereTime('end', '<=', $now->toTimeString()) + ->orWhereTime('start', '>', $now->toTimeString()); + }); + }); + }) + // Check we are on the correct day of the week + ->where(function ($query) use ($now) { + $query->where('recurring_day', 'like', $now->format('%N%')) + ->orWhereNull('recurring_day'); }); - }) - // Check the time is between the start and end hour/minutes/seconds - ->where('start_recurring_hr', '<=', DB::raw("date_format(NOW(), '%H:%i:%s')")) - ->where('end_recurring_hr', '>=', DB::raw("date_format(NOW(), '%H:%i:%s')")) - // Check we are on the correct day of the week - ->where(function ($query) { - /** @var Builder $query */ - $query->where('recurring_day', 'like', DB::raw("CONCAT('%', date_format(NOW(), '%w'), '%')")) - ->orWhereNull('recurring_day') - ->orWhere('recurring_day', ''); }); - }); + }); }); } @@ -74,11 +213,16 @@ class AlertSchedule extends Model public function devices() { - return $this->morphedByMany(\App\Models\Device::class, 'alert_schedulable', 'alert_schedulables', 'schedule_id', 'schedule_id'); + return $this->morphedByMany(\App\Models\Device::class, 'alert_schedulable', 'alert_schedulables', 'schedule_id', 'alert_schedulable_id'); } public function deviceGroups() { - return $this->morphedByMany(\App\Models\DeviceGroup::class, 'alert_schedulable'); + return $this->morphedByMany(\App\Models\DeviceGroup::class, 'alert_schedulable', 'alert_schedulables', 'schedule_id', 'alert_schedulable_id'); + } + + public function locations() + { + return $this->morphedByMany(\App\Models\Location::class, 'alert_schedulable', 'alert_schedulables', 'schedule_id', 'alert_schedulable_id'); } } diff --git a/app/Models/Device.php b/app/Models/Device.php index 2232866a66..2ecf3146cd 100644 --- a/app/Models/Device.php +++ b/app/Models/Device.php @@ -133,25 +133,25 @@ class Device extends BaseModel public function isUnderMaintenance() { + if (!$this->device_id) { + return false; + } + $query = AlertSchedule::isActive() - ->join('alert_schedulables', 'alert_schedule.schedule_id', 'alert_schedulables.schedule_id') - ->where(function ($query) { - $query->where(function ($query) { - $query->where('alert_schedulable_type', 'device') - ->where('alert_schedulable_id', $this->device_id); + ->where(function (Builder $query) { + $query->whereHas('devices', function (Builder $query) { + $query->where('alert_schedulables.alert_schedulable_id', $this->device_id); }); if ($this->groups) { - $query->orWhere(function ($query) { - $query->where('alert_schedulable_type', 'device_group') - ->whereIn('alert_schedulable_id', $this->groups->pluck('id')); + $query->orWhereHas('deviceGroups', function (Builder $query) { + $query->whereIn('alert_schedulables.alert_schedulable_id', $this->groups->pluck('id')); }); } if ($this->location) { - $query->orWhere(function ($query) { - $query->where('alert_schedulable_type', 'location') - ->where('alert_schedulable_id', $this->location->id); + $query->orWhereHas('locations', function (Builder $query) { + $query->where('alert_schedulables.alert_schedulable_id', $this->location->id); }); } }); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 9dd8b1f9a0..d0fbf1c217 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -85,6 +85,7 @@ class AppServiceProvider extends ServiceProvider 'sensor' => \App\Models\Sensor::class, 'device' => \App\Models\Device::class, 'device_group' => \App\Models\DeviceGroup::class, + 'location' => \App\Models\Location::class, ], $sensor_types)); } diff --git a/config/app.php b/config/app.php index 84a421694d..f89e089d70 100644 --- a/config/app.php +++ b/config/app.php @@ -212,6 +212,7 @@ return [ 'Config' => Illuminate\Support\Facades\Config::class, 'Cookie' => Illuminate\Support\Facades\Cookie::class, 'Crypt' => Illuminate\Support\Facades\Crypt::class, + 'Date' => Illuminate\Support\Facades\Date::class, 'DB' => Illuminate\Support\Facades\DB::class, 'Eloquent' => Illuminate\Database\Eloquent\Model::class, 'Event' => Illuminate\Support\Facades\Event::class, diff --git a/database/migrations/2020_04_08_172357_alert_schedule_utc.php b/database/migrations/2020_04_08_172357_alert_schedule_utc.php new file mode 100644 index 0000000000..e0c5d56c55 --- /dev/null +++ b/database/migrations/2020_04_08_172357_alert_schedule_utc.php @@ -0,0 +1,54 @@ +update([ + 'start' => DB::raw("CONVERT_TZ(IF(`recurring` = 1, STR_TO_DATE(CONCAT(start_recurring_dt, ' ', start_recurring_hr), '%Y-%m-%d %H:%i:%s'), start), @@global.time_zone, '+00:00')"), + 'end' => DB::raw("CONVERT_TZ(IF(`recurring` = 1, STR_TO_DATE(CONCAT(IFNULL(end_recurring_dt, '9000-09-09'), ' ', end_recurring_hr), '%Y-%m-%d %H:%i:%s'), end), @@global.time_zone, '+00:00')"), + 'recurring_day' => DB::raw('REPLACE(recurring_day, 0, 7)'), // convert to RFC N date format + ]); + } + + Schema::table('alert_schedule', function (Blueprint $table) { + $table->dropColumn(['start_recurring_dt', 'start_recurring_hr', 'end_recurring_dt', 'end_recurring_hr']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('alert_schedule', function (Blueprint $table) { + $table->date('start_recurring_dt')->nullable(false)->default('1970-01-01')->after('end'); + $table->time('start_recurring_hr')->nullable(false)->default('00:00:00')->after('start_recurring_dt'); + $table->date('end_recurring_dt')->nullable()->after('start_recurring_hr'); + $table->time('end_recurring_hr')->nullable(false)->default('00:00:00')->after('end_recurring_dt'); + }); + + if (\LibreNMS\DB\Eloquent::getDriver() == 'mysql') { + DB::table('alert_schedule')->update([ + 'start' => DB::raw("CONVERT_TZ(start, '+00:00', @@global.time_zone)"), + 'end' => DB::raw("CONVERT_TZ(end, '+00:00', @@global.time_zone)"), + 'start_recurring_dt' => DB::raw("DATE(CONVERT_TZ(start, '+00:00', @@global.time_zone))"), + 'start_recurring_hr' => DB::raw("TIME(CONVERT_TZ(start, '+00:00', @@global.time_zone))"), + 'end_recurring_dt' => DB::raw("DATE(CONVERT_TZ(end, '+00:00', @@global.time_zone))"), + 'end_recurring_hr' => DB::raw("TIME(CONVERT_TZ(end, '+00:00', @@global.time_zone))"), + 'recurring_day' => DB::raw('REPLACE(recurring_day, 7, 0)'), + ]); + } + } +} diff --git a/includes/html/forms/schedule-maintenance.inc.php b/includes/html/forms/schedule-maintenance.inc.php index 15d8997b60..10f47414ba 100644 --- a/includes/html/forms/schedule-maintenance.inc.php +++ b/includes/html/forms/schedule-maintenance.inc.php @@ -14,6 +14,8 @@ use Illuminate\Support\Str; * the source code distribution for details. */ +use Carbon\Carbon; + if (!Auth::user()->hasGlobalAdmin()) { header('Content-type: text/plain'); die('ERROR: You need to be admin'); @@ -34,7 +36,7 @@ if ($sub_type == 'new-maintenance') { $title = mres($_POST['title']); $notes = mres($_POST['notes']); - $recurring = mres($_POST['recurring']); + $recurring = $_POST['recurring'] ? 1 : 0; $start_recurring_dt = mres($_POST['start_recurring_dt']); $end_recurring_dt = mres($_POST['end_recurring_dt']); $start_recurring_hr = mres($_POST['start_recurring_hr']); @@ -75,7 +77,7 @@ if ($sub_type == 'new-maintenance') { $message .= 'Please check end recurring date
'; } } else { - $end_recurring_dt = null; + $end_recurring_dt = '9000-09-09'; } if (empty($start_recurring_hr)) { @@ -117,18 +119,27 @@ if ($sub_type == 'new-maintenance') { } if (empty($message)) { - if (empty($schedule_id)) { - $schedule_id = dbInsert(array('recurring' => $recurring, 'start' => $start, 'end' => $end, 'start_recurring_dt' => $start_recurring_dt, 'end_recurring_dt' => $end_recurring_dt, 'start_recurring_hr' => $start_recurring_hr, 'end_recurring_hr' => $end_recurring_hr, 'recurring_day' => $recurring_day, 'title' => $title, 'notes' => $notes), 'alert_schedule'); - } else { - dbUpdate(array('recurring' => $recurring, 'start' => $start, 'end' => $end, 'start_recurring_dt' => $start_recurring_dt, 'end_recurring_dt' => $end_recurring_dt, 'start_recurring_hr' => $start_recurring_hr, 'end_recurring_hr' => $end_recurring_hr, 'recurring_day' => $recurring_day, 'title' => $title, 'notes' => $notes), 'alert_schedule', '`schedule_id`=?', array($schedule_id)); - } + $alert_schedule = \App\Models\AlertSchedule::findOrNew($schedule_id); + $alert_schedule->title = $title; + $alert_schedule->notes = $notes; + $alert_schedule->recurring = $recurring; + $alert_schedule->start = $start; + $alert_schedule->end = $end; - if ($schedule_id > 0) { + if ($recurring) { + $alert_schedule->start_recurring_dt = $start_recurring_dt; + $alert_schedule->start_recurring_hr = $start_recurring_hr; + $alert_schedule->end_recurring_dt = $end_recurring_dt; + $alert_schedule->end_recurring_hr = $end_recurring_hr; + } + $alert_schedule->save(); + + if ($alert_schedule->schedule_id > 0) { $items = array(); $fail = 0; if ($update == 1) { - dbDelete('alert_schedulables', '`schedule_id`=?', array($schedule_id)); + dbDelete('alert_schedulables', '`schedule_id`=?', [$alert_schedule->schedule_id]); } foreach ($_POST['maps'] as $target) { @@ -141,7 +152,7 @@ if ($sub_type == 'new-maintenance') { $target = substr($target, 1); } - $item = dbInsert(['schedule_id' => $schedule_id, 'alert_schedulable_type' => $type, 'alert_schedulable_id' => $target], 'alert_schedulables'); + $item = dbInsert(['schedule_id' => $alert_schedule->schedule_id, 'alert_schedulable_type' => $type, 'alert_schedulable_id' => $target], 'alert_schedulables'); if ($notes && $type = 'device' && get_user_pref('add_schedule_note_to_device', false)) { $device_notes = dbFetchCell('SELECT `notes` FROM `devices` WHERE `device_id` = ?;', [$target]); $device_notes.= ((empty($device_notes)) ? '' : PHP_EOL) . date("Y-m-d H:i") . ' Alerts delayed: ' . $notes; @@ -159,7 +170,7 @@ if ($sub_type == 'new-maintenance') { dbDelete('alert_schedulables', '`item_id`=?', array($item)); } - dbDelete('alert_schedule', '`schedule_id`=?', array($schedule_id)); + dbDelete('alert_schedule', '`schedule_id`=?', [$alert_schedule->schedule_id]); $message = 'Issue scheduling maintenance'; } else { $status = 'ok'; @@ -176,7 +187,7 @@ if ($sub_type == 'new-maintenance') { ); } elseif ($sub_type == 'parse-maintenance') { $schedule_id = mres($_POST['schedule_id']); - $schedule = dbFetchRow('SELECT * FROM `alert_schedule` WHERE `schedule_id`=?', array($schedule_id)); + $alert_schedule = \App\Models\AlertSchedule::findOrFail($schedule_id); $items = []; foreach (dbFetchRows('SELECT `alert_schedulable_type`, `alert_schedulable_id` FROM `alert_schedulables` WHERE `schedule_id`=?', [$schedule_id]) as $target) { $id = $target['alert_schedulable_id']; @@ -195,19 +206,9 @@ if ($sub_type == 'new-maintenance') { ]; } - $response = array( - 'start' => $schedule['start'], - 'end' => $schedule['end'], - 'title' => $schedule['title'], - 'notes' => $schedule['notes'], - 'recurring' => $schedule['recurring'], - 'start_recurring_dt' => ($schedule['start_recurring_dt'] != '0000-00-00' ? $schedule['start_recurring_dt']: '1970-01-02 00:00:01'), - 'end_recurring_dt' => ($schedule['end_recurring_dt']!= '0000-00-00' ? $schedule['end_recurring_dt'] : '1970-01-02 00:00:01'), - 'start_recurring_hr' => substr($schedule['start_recurring_hr'], 0, 5), - 'end_recurring_hr' => substr($schedule['end_recurring_hr'], 0, 5), - 'recurring_day' => $schedule['recurring_day'], - 'targets' => $items, - ); + $response = $alert_schedule->toArray(); + $response['recurring_day'] = $alert_schedule->getOriginal('recurring_day'); + $response['targets'] = $items; } elseif ($sub_type == 'del-maintenance') { $schedule_id = mres($_POST['del_schedule_id']); dbDelete('alert_schedule', '`schedule_id`=?', array($schedule_id)); diff --git a/includes/html/modal/alert_schedule.inc.php b/includes/html/modal/alert_schedule.inc.php index 34b8193eb9..3080ba74cd 100644 --- a/includes/html/modal/alert_schedule.inc.php +++ b/includes/html/modal/alert_schedule.inc.php @@ -93,13 +93,13 @@ if (\Auth::user()->hasGlobalAdmin()) {
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -126,7 +126,6 @@ $('#schedule-maintenance').on('hide.bs.modal', function (event) { $('#schedule_id').val(''); $('#title').val(''); $('#notes').val(''); - $('#recurring').val(''); $('#start').val(moment().format('YYYY-MM-DD HH:mm')).data("DateTimePicker").maxDate(false).minDate(moment()); $('#end').val(moment().add(1, 'hour').format('YYYY-MM-DD HH:mm')).data("DateTimePicker").maxDate(false).minDate(moment()); var $startRecurringDt = $('#start_recurring_dt'); @@ -138,7 +137,7 @@ $('#schedule-maintenance').on('hide.bs.modal', function (event) { $('#start_recurring_hr').val('').data("DateTimePicker").minDate(false).maxDate(false); $('#end_recurring_hr').val('').data("DateTimePicker").minDate(false).maxDate(false); - $('#recurring_day').prop('checked', false); + $("input[name='recurring_day[]']").prop('checked', false); $("#recurring").bootstrapSwitch('state', false); $('#recurring').val(0); $('#norecurringgroup').show(); @@ -184,7 +183,7 @@ $('#schedule-maintenance').on('show.bs.modal', function (event) { $('#end_recurring_dt').val(''); $('#start_recurring_hr').val(''); $('#end_recurring_hr').val(''); - $('#recurring_day').prop('checked', false); + $("input[name='recurring_day[]']").prop('checked', false); $("#recurring").bootstrapSwitch('state', false); $('#recurring').val(0); }else{ @@ -211,7 +210,7 @@ $('#schedule-maintenance').on('show.bs.modal', function (event) { $("input[name='recurring_day[]'][value="+checkedday+"]").prop('checked', true); }); }else{ - $('#recurring_day').prop('checked', false); + $("input[name='recurring_day[]']").prop('checked', false); } $('#norecurringgroup').hide(); diff --git a/includes/html/modal/remove_alert_schedule.inc.php b/includes/html/modal/remove_alert_schedule.inc.php index 128ed6efb3..868c7b3366 100644 --- a/includes/html/modal/remove_alert_schedule.inc.php +++ b/includes/html/modal/remove_alert_schedule.inc.php @@ -31,8 +31,8 @@ if (Auth::user()->hasGlobalAdmin()) { - - + + diff --git a/includes/html/pages/alert-schedule.inc.php b/includes/html/pages/alert-schedule.inc.php index b18ae3dd6c..bc4b3cd84c 100644 --- a/includes/html/pages/alert-schedule.inc.php +++ b/includes/html/pages/alert-schedule.inc.php @@ -77,12 +77,7 @@ var grid = $("#alert-schedule").bootgrid({ "

" }, rowCount: [50, 100, 250, -1], - post: function () { - return { - id: "alert-schedule", - }; - }, - url: "ajax_table.php" + url: "ajax/table/alert-schedule" }).on("loaded.rs.jquery.bootgrid", function() { /* Executes after data is loaded and rendered */ grid.find(".command-edit").on("click", function(e) { diff --git a/includes/html/pages/device/edit/device.inc.php b/includes/html/pages/device/edit/device.inc.php index fb523c1f7a..e2dd13b8d0 100644 --- a/includes/html/pages/device/edit/device.inc.php +++ b/includes/html/pages/device/edit/device.inc.php @@ -307,7 +307,8 @@ If `devices.ignore = 0` or `macros.device = 1` condition is is set and ignore al