/** * Validation of DateTime Fields (both Date and Time together) * * @param mixed $value * @param array $options * - dateFormat (defaults to 'ymd') * - allowEmpty * - after/before (fieldName to validate against) * - min/max (defaults to >= 1 - at least 1 minute apart) * @param array $context * @return bool Success */ public function validateDateTime($value, $options = [], array $context = []) { if (!$value) { if (!empty($options['allowEmpty'])) { return true; } return false; } $format = !empty($options['dateFormat']) ? $options['dateFormat'] : 'ymd'; if (!is_object($value)) { $value = new Time($value); } $pieces = $value->format(FORMAT_DB_DATETIME); $dateTime = explode(' ', $pieces, 2); $date = $dateTime[0]; $time = !empty($dateTime[1]) ? $dateTime[1] : ''; if (!empty($options['allowEmpty']) && (empty($date) && empty($time))) { return true; } if (Validation::date($date, $format) && Validation::time($time)) { // after/before? $seconds = isset($options['min']) ? $options['min'] : 1; if (!empty($options['after'])) { if (!is_object($options['after']) && isset($context['data'][$options['after']])) { $options['after'] = $context['data'][$options['after']]; if (!is_object($options['after'])) { $options['after'] = new Time($options['after']); } } elseif (!is_object($options['after'])) { return false; } } if (!empty($options['before'])) { if (!is_object($options['before']) && isset($context['data'][$options['before']])) { $options['before'] = $context['data'][$options['before']]; if (!is_object($options['before'])) { $options['before'] = new Time($options['before']); } } elseif (!is_object($options['before'])) { return false; } } // We need this for those not using immutable objects just yet $compareValue = clone $value; if (!empty($options['after'])) { $compare = $compareValue->subSeconds($seconds); if ($options['after']->gt($compare)) { return false; } if (!empty($options['max'])) { $after = $options['after']->addSeconds($options['max']); if ($value->gt($after)) { return false; } } } if (!empty($options['before'])) { $compare = $compareValue->addSeconds($seconds); if ($options['before']->lt($compare)) { return false; } if (!empty($options['max'])) { $after = $options['before']->subSeconds($options['max']); if ($value->lt($after)) { return false; } } } return true; } return false; }