• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nette / forms / 6684252643

29 Oct 2023 03:28PM UTC coverage: 93.349% (+0.05%) from 93.303%
6684252643

push

github

dg
updated netteForms.min.js

2049 of 2195 relevant lines covered (93.35%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.2
/src/Forms/Controls/DateTimeControl.php
1
<?php
2

3
/**
4
 * This file is part of the Nette Framework (https://nette.org)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7

8
declare(strict_types=1);
9

10
namespace Nette\Forms\Controls;
11

12
use Nette;
13
use Nette\Forms\Form;
14

15

16
/**
17
 * Selects date or time or date & time.
18
 */
19
class DateTimeControl extends BaseControl
20
{
21
        public const
22
                TypeDate = 1,
23
                TypeTime = 2,
24
                TypeDateTime = 3;
25

26
        public const
27
                FormatObject = 'object',
28
                FormatTimestamp = 'timestamp';
29

30
        /** @var int */
31
        private $type;
32

33
        /** @var bool  */
34
        private $withSeconds;
35

36
        /** @var string */
37
        private $format = self::FormatObject;
38

39

40
        public function __construct($label = null, int $type = self::TypeDate, bool $withSeconds = false)
1✔
41
        {
42
                $this->type = $type;
1✔
43
                $this->withSeconds = $withSeconds;
1✔
44
                parent::__construct($label);
1✔
45
                $this->control->step = $withSeconds ? 1 : null;
1✔
46
        }
1✔
47

48

49
        public function getType(): int
50
        {
51
                return $this->type;
1✔
52
        }
53

54

55
        /**
56
         * Format of returned value. Allowed values are string (ie 'Y-m-d'), DateTimeControl::FormatObject and DateTimeControl::FormatTimestamp.
57
         * @return static
58
         */
59
        public function setFormat(string $format)
1✔
60
        {
61
                $this->format = $format;
1✔
62
                return $this;
1✔
63
        }
64

65

66
        /**
67
         * @param \DateTimeInterface|string|int|null $value
68
         * @return static
69
         */
70
        public function setValue($value)
71
        {
72
                $this->value = $value === null ? null : $this->normalizeValue($value);
1✔
73
                return $this;
1✔
74
        }
75

76

77
        /**
78
         * @return \DateTimeImmutable|string|int|null
79
         */
80
        public function getValue()
81
        {
82
                if ($this->format === self::FormatObject) {
1✔
83
                        return $this->value;
1✔
84
                } elseif ($this->format === self::FormatTimestamp) {
1✔
85
                        return $this->value ? $this->value->getTimestamp() : null;
1✔
86
                } else {
87
                        return $this->value ? $this->value->format($this->format) : null;
1✔
88
                }
89
        }
90

91

92
        /**
93
         * @param \DateTimeInterface|string|int $value
94
         */
95
        private function normalizeValue($value): \DateTimeImmutable
96
        {
97
                if (is_numeric($value)) {
1✔
98
                        $dt = (new \DateTimeImmutable)->setTimestamp((int) $value);
1✔
99
                } elseif (is_string($value)) {
1✔
100
                        $dt = new \DateTimeImmutable($value); // createFromFormat() must not be used because it allows invalid values
1✔
101
                } elseif ($value instanceof \DateTime) {
1✔
102
                        $dt = \DateTimeImmutable::createFromMutable($value);
1✔
103
                } elseif ($value instanceof \DateTimeImmutable) {
1✔
104
                        $dt = $value;
1✔
105
                } elseif (!$value instanceof \DateTimeInterface) {
1✔
106
                        throw new Nette\InvalidArgumentException('Value must be DateTimeInterface or string or null, ' . gettype($value) . ' given.');
1✔
107
                }
108

109
                [$h, $m, $s] = [(int) $dt->format('H'), (int) $dt->format('i'), $this->withSeconds ? (int) $dt->format('s') : 0];
1✔
110
                if ($this->type === self::TypeDate) {
1✔
111
                        return $dt->setTime(0, 0);
1✔
112
                } elseif ($this->type === self::TypeTime) {
1✔
113
                        return $dt->setDate(0, 1, 1)->setTime($h, $m, $s);
1✔
114
                } elseif ($this->type === self::TypeDateTime) {
1✔
115
                        return $dt->setTime($h, $m, $s);
1✔
116
                }
117
        }
118

119

120
        public function loadHttpData(): void
121
        {
122
                $value = $this->getHttpData(Nette\Forms\Form::DataText);
1✔
123
                try {
124
                        $this->value = is_string($value) && preg_match('~^(\d{4}-\d{2}-\d{2})?T?(\d{2}:\d{2}(:\d{2}(\.\d+)?)?)?$~', $value)
1✔
125
                                ? $this->normalizeValue($value)
1✔
126
                                : null;
1✔
127
                } catch (\Throwable $e) {
1✔
128
                        $this->value = null;
1✔
129
                }
130
        }
1✔
131

132

133
        public function getControl(): Nette\Utils\Html
134
        {
135
                return parent::getControl()->addAttributes([
1✔
136
                        'value' => $this->value ? $this->formatHtmlValue($this->value) : null,
1✔
137
                        'type' => [self::TypeDate => 'date', self::TypeTime => 'time', self::TypeDateTime => 'datetime-local'][$this->type],
1✔
138
                ]);
139
        }
140

141

142
        /**
143
         * Formats a date/time for HTML attributes.
144
         * @param  \DateTimeInterface|string|int  $value
145
         */
146
        public function formatHtmlValue($value): string
147
        {
148
                $value = $this->normalizeValue($value);
1✔
149
                return $value->format([
1✔
150
                        self::TypeDate => 'Y-m-d',
1✔
151
                        self::TypeTime => $this->withSeconds ? 'H:i:s' : 'H:i',
1✔
152
                        self::TypeDateTime => $this->withSeconds ? 'Y-m-d\\TH:i:s' : 'Y-m-d\\TH:i',
1✔
153
                ][$this->type]);
1✔
154
        }
155

156

157
        /**
158
         * Formats a date/time according to the locale and formatting options.
159
         * @param  \DateTimeInterface|string|int  $value
160
         */
161
        public function formatLocaleText($value): string
162
        {
163
                $value = $this->normalizeValue($value);
1✔
164
                if ($this->type === self::TypeDate) {
1✔
165
                        return \IntlDateFormatter::formatObject($value, [\IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE]);
1✔
166
                } elseif ($this->type === self::TypeTime) {
1✔
167
                        return \IntlDateFormatter::formatObject($value, [\IntlDateFormatter::NONE, $this->withSeconds ? \IntlDateFormatter::MEDIUM : \IntlDateFormatter::SHORT]);
1✔
168
                } elseif ($this->type === self::TypeDateTime) {
×
169
                        return \IntlDateFormatter::formatObject($value, [\IntlDateFormatter::MEDIUM, $this->withSeconds ? \IntlDateFormatter::MEDIUM : \IntlDateFormatter::SHORT]);
×
170
                }
171
        }
172

173

174
        /** @return static */
175
        public function addRule($validator, $errorMessage = null, $arg = null)
176
        {
177
                if ($validator === Form::Min) {
1✔
178
                        $this->control->min = $arg = $this->formatHtmlValue($arg);
1✔
179
                } elseif ($validator === Form::Max) {
1✔
180
                        $this->control->max = $arg = $this->formatHtmlValue($arg);
1✔
181
                } elseif ($validator === Form::Range) {
1✔
182
                        $this->control->min = isset($arg[0])
1✔
183
                                ? $arg[0] = $this->formatHtmlValue($arg[0])
1✔
184
                                : null;
×
185
                        $this->control->max = isset($arg[1])
1✔
186
                                ? $arg[1] = $this->formatHtmlValue($arg[1])
1✔
187
                                : null;
×
188
                }
189

190
                return parent::addRule($validator, $errorMessage, $arg);
1✔
191
        }
192
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc