disableCsrfValidation(); $this->range_time_parser = new CRangeTimeParser(); } protected function checkInput() { $fields = [ 'method' => 'required|in increment,zoomout,decrement,rangechange,rangeoffset', 'idx' => 'required|in '.implode(',', static::$profiles), 'idx2' => 'required|id', 'from' => 'required|string', 'to' => 'required|string', 'from_offset' => 'int32|ge 0', 'to_offset' => 'int32|ge 0' ]; $ret = $this->validateInput($fields); if (!$ret) { /* * This block executes if, for example, a missing profile is given. Since this is an AJAX request, it should * throw a JS alert() with current message in timeSelectorEventHandler() in gtlc.js. */ $messages = CMessageHelper::getMessages(); $this->setResponse(new CControllerResponseData([ 'main_block' => json_encode(['error' => $messages[0]['message']]) ])); return $ret; } $ret = $this->validateInputDateRange(); if ($this->getInput('method') === 'rangeoffset' && (!$this->hasInput('from_offset') || !$this->hasInput('to_offset'))) { $ret = false; } if (!$ret) { $this->setResponse(new CControllerResponseData(['main_block' => json_encode($this->data)])); } return $ret; } protected function checkPermissions() { return ($this->getUserType() >= USER_TYPE_ZABBIX_USER); } protected function doAction() { $method = $this->getInput('method'); $date = new DateTime(); $value = []; $date_type = []; $ts = []; $ts['now'] = time(); foreach (['from', 'to'] as $field) { $value[$field] = $this->getInput($field); $this->range_time_parser->parse($value[$field]); $date_type[$field] = $this->range_time_parser->getTimeType(); $ts[$field] = $this->range_time_parser ->getDateTime($field === 'from') ->getTimestamp(); } $period = $ts['to'] - $ts['from'] + 1; $this->range_time_parser->parse('now-'.CSettingsHelper::get(CSettingsHelper::MAX_PERIOD)); $max_period = 1 + $ts['now'] - $this->range_time_parser ->getDateTime(true) ->getTimestamp(); switch ($method) { case 'decrement': $offset = $period; if ($ts['from'] - $offset < 0) { $offset = $ts['from']; } $ts['from'] -= $offset; $ts['to'] -= $offset; $value['from'] = $date->setTimestamp($ts['from'])->format(ZBX_FULL_DATE_TIME); $value['to'] = $date->setTimestamp($ts['to'])->format(ZBX_FULL_DATE_TIME); break; case 'increment': $offset = $period; if ($ts['to'] + $offset > $ts['now']) { $offset = $ts['now'] - $ts['to']; } $ts['from'] += $offset; $ts['to'] += $offset; $value['from'] = $date->setTimestamp($ts['from'])->format(ZBX_FULL_DATE_TIME); $value['to'] = $date->setTimestamp($ts['to'])->format(ZBX_FULL_DATE_TIME); break; case 'zoomout': $right_offset = (int) ($period / 2); if ($ts['to'] + $right_offset > $ts['now']) { $right_offset = $ts['now'] - $ts['to']; } $left_offset = $period - $right_offset; if ($ts['from'] - $left_offset < 0) { $left_offset = $ts['from']; } $ts['from'] -= $left_offset; $ts['to'] += $right_offset; if ($ts['to'] - $ts['from'] + 1 > $max_period) { $ts['from'] = $ts['to'] - $max_period + 1; } $value['from'] = $date->setTimestamp($ts['from'])->format(ZBX_FULL_DATE_TIME); $value['to'] = $date->setTimestamp($ts['to'])->format(ZBX_FULL_DATE_TIME); break; case 'rangeoffset': $from_offset = $this->getInput('from_offset'); $to_offset = $this->getInput('to_offset'); if ($from_offset > 0) { $ts['from'] += $from_offset; $value['from'] = $date->setTimestamp($ts['from'])->format(ZBX_FULL_DATE_TIME); } if ($to_offset > 0) { $ts['to'] -= $to_offset; $value['to'] = $date->setTimestamp($ts['to'])->format(ZBX_FULL_DATE_TIME); } break; case 'rangechange': // Format only absolute date according ZBX_FULL_DATE_TIME string. foreach (['from', 'to'] as $field) { if ($date_type[$field] === CRangeTimeParser::ZBX_TIME_ABSOLUTE) { $value[$field] = $date->setTimestamp($ts[$field])->format(ZBX_FULL_DATE_TIME); } } break; } updateTimeSelectorPeriod([ 'profileIdx' => $this->getInput('idx'), 'profileIdx2' => $this->getInput('idx2'), 'from' => $value['from'], 'to' => $value['to'] ]); $this->setResponse(new CControllerResponseData(['main_block' => json_encode([ 'label' => relativeDateToText($value['from'], $value['to']), 'from' => $value['from'], 'from_ts' => $ts['from'], 'from_date' => $date->setTimestamp($ts['from'])->format(ZBX_FULL_DATE_TIME), 'to' => $value['to'], 'to_ts' => $ts['to'], 'to_date' => $date->setTimestamp($ts['to'])->format(ZBX_FULL_DATE_TIME) ] + getTimeselectorActions($value['from'], $value['to']))])); } /** * Validate input 'from' and 'to' arguments. Returns true on success. * * @return bool */ protected function validateInputDateRange() { $this->data['error'] = []; $ts = []; $ts['now'] = time(); foreach (['from', 'to'] as $field) { $value = $this->getInput($field); if ($this->range_time_parser->parse($value) !== CParser::PARSE_SUCCESS) { $this->data['error'][$field] = _('Invalid date.'); } else { $ts[$field] = $this->range_time_parser ->getDateTime($field === 'from') ->getTimestamp(); } } if ($this->data['error']) { return false; } if ($this->getInput('method') === 'rangeoffset') { $ts['from'] += $this->getInput('from_offset'); $ts['to'] -= $this->getInput('to_offset'); } $period = $ts['to'] - $ts['from'] + 1; $this->range_time_parser->parse('now-'.CSettingsHelper::get(CSettingsHelper::MAX_PERIOD)); $max_period = 1 + $ts['now'] - $this->range_time_parser ->getDateTime(true) ->getTimestamp(); if ($period < ZBX_MIN_PERIOD) { $this->data['error']['from'] = _n('Minimum time period to display is %1$s minute.', 'Minimum time period to display is %1$s minutes.', (int) (ZBX_MIN_PERIOD / SEC_PER_MIN) ); } elseif ($period > $max_period) { $this->data['error']['from'] = _n('Maximum time period to display is %1$s day.', 'Maximum time period to display is %1$s days.', (int) round($max_period / SEC_PER_DAY) ); } return !$this->data['error']; } }