%PDF- %PDF-
Direktori : /home/vacivi36/intranet.vacivitta.com.br/protected/humhub/libs/ |
Current File : /home/vacivi36/intranet.vacivitta.com.br/protected/humhub/libs/DbDateValidator.php |
<?php /** * @link https://www.humhub.org/ * @copyright Copyright (c) 2017 HumHub GmbH & Co. KG * @license https://www.humhub.com/licences */ namespace humhub\libs; use Yii; use yii\validators\DateValidator; /** * Validates (user date format or database format) and converts it to an database date(-time) field * * @see \yii\validators\DateValidator * @author luke */ class DbDateValidator extends DateValidator { /** * Database Field - Validators */ const REGEX_DBFORMAT_DATE = '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/'; const REGEX_DBFORMAT_DATETIME = '/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/'; /** * @var string the format the value should converted to (database datetime or date format) */ public $convertToFormat = 'Y-m-d H:i:s'; /** * @var string attribute which holds the time in format hh::mm */ public $timeAttribute = ''; /** * @var string attribute name to save converted value to */ public $targetAttribute = null; /** * @inheritdoc */ public function init() { if (!$this->format) { $this->format = Yii::$app->formatter->dateInputFormat; } if(!$this->timeZone) { $this->timeZone = DateHelper::getUserTimeZone(true); } parent::init(); } /** * @inheritdoc */ public function validateAttribute($model, $attribute) { // If the date is already in system format, we do not need any further translation or parsing if(DateHelper::isInDbFormat($model->$attribute, $this->isDateOnly())) { return; } $timeValue = $this->getTimeValue($model); $timestamp = $this->parseDateTimeValue($model->$attribute, $timeValue); if ($timestamp === false) { $this->addError($model, $attribute, $this->message, []); } elseif ($this->min !== null && $timestamp < $this->min) { $this->addError($model, $attribute, $this->tooSmall, ['min' => $this->minString]); } elseif ($this->max !== null && $timestamp > $this->max) { $this->addError($model, $attribute, $this->tooBig, ['max' => $this->maxString]); } else { // If there is no error, and attribute is not yet in DB Format - convert to DB $date = new \DateTime('now', new \DateTimeZone('UTC')); $date->setTimestamp($timestamp); if ($timeValue) { // Convert timestamp to apps timezone $date->setTimezone(DateHelper::getSystemTimeZone()); } $targetAttribute = ($this->targetAttribute === null) ? $attribute : $this->targetAttribute; if ($this->convertToFormat !== null) { $model->$targetAttribute = $date->format($this->convertToFormat); } } } /** * Parses a date and a time value if timeAttribute is specified. * * @param string $value * @return int|false timestamp in system timezone * @throws \Exception */ protected function parseDateTimeValue($value, $timeValue = null) { // It's already a database datetime / no conversion needed. if (DateHelper::isInDbFormat($value)) { return strtotime($value); } $timestamp = $this->parseDateValue($value); if ($timestamp !== false && $this->hasTime() && !empty($timeValue)) { $timestamp += $this->parseTimeValue($timeValue); $timestamp = $this->fixTimestampTimeZone($timestamp, $this->timeZone); } return $timestamp; } /** * Checks a time attribute name is given, if empty don't handle time * * @return boolean */ protected function hasTime() { return !empty($this->timeAttribute); } /** * @return bool checks if the validator should validate date only fields */ protected function isDateOnly() { return !$this->hasTime(); } /** * Returns time value if provided by the model * * @return string|null time value (e.g. 12:00) */ protected function getTimeValue($model) { if ($this->hasTime()) { $attributeName = $this->timeAttribute; return $model->$attributeName ?: null; } return null; } /** * Parses a date and optionally a time if timeAttribute is specified. * * Returns false in case the value could not be parsed. * * @param string $value * @return int|false * @throws \Exception */ public static function parseDateTime($value, $timeValue = null) { return (new self())->parseDateTimeValue($value, $timeValue); } /** * Parses given time value (hh:mm) to seconds * * @todo Allow more time formats * @param string $value * @return int time converted to seconds */ protected function parseTimeValue($value) { return strtotime($value) - strtotime('TODAY'); } /** * Converts the given timestamp from user (or configured) timezone to a utc timestamp * * @param int $ts the timestamp * @param String $timeZone users timezone * @return int * @throws \Exception */ protected function fixTimestampTimeZone($ts, $timeZone) { // Create date string $fromDateTime = new \DateTime('@' . $ts); // Create date object $toDateTime = \DateTime::createFromFormat('Y-m-d H:i:s', $fromDateTime->format('Y-m-d H:i:s'), new \DateTimeZone($timeZone)); $toDateTime->setTimezone(new \DateTimeZone('UTC')); return $toDateTime->getTimestamp(); } }