Passed
Push — master ( 5bdfe8...9d312b )
by Vincent
04:50
created

DateTimeElement::toPhp()   B

Complexity

Conditions 7
Paths 12

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
c 1
b 0
f 0
dl 0
loc 32
ccs 16
cts 16
cp 1
rs 8.8333
cc 7
nc 12
nop 1
crap 7
1
<?php
2
3
namespace Bdf\Form\Leaf\Date;
4
5
use Bdf\Form\Choice\ChoiceInterface;
6
use Bdf\Form\Leaf\LeafElement;
7
use Bdf\Form\Transformer\TransformerInterface;
8
use Bdf\Form\Validator\ValueValidatorInterface;
9
use DateTime;
10
use DateTimeInterface;
11
use DateTimeZone;
12
use InvalidArgumentException;
13
14
/**
15
 * Handle DateTime form element
16
 * The element use a formatted string as http value, and can return any implementation of DateTimeInterface
17
 *
18
 * @method DateTimeInterface value()
19
 * @extends LeafElement<DateTimeInterface>
20
 */
21
final class DateTimeElement extends LeafElement
22
{
23
    /**
24
     * @var class-string<DateTimeInterface>
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<DateTimeInterface> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<DateTimeInterface>.
Loading history...
25
     */
26
    private $className;
27
28
    /**
29
     * @var string
30
     */
31
    private $format;
32
33
    /**
34
     * @var DateTimeZone|null
35
     */
36
    private $timezone;
37
38
    /**
39
     * DateTimeType constructor.
40
     *
41
     * @param ValueValidatorInterface|null $validator
42
     * @param TransformerInterface|null $transformer
43
     * @param ChoiceInterface|null $choices
44
     * @param class-string<DateTimeInterface> $className The date time class name to use
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<DateTimeInterface> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<DateTimeInterface>.
Loading history...
45
     * @param string $format The time format string
46
     * @param DateTimeZone|null $timezone Timezone to use. Use null to not define a timezone
47
     */
48 50
    public function __construct(?ValueValidatorInterface $validator = null, ?TransformerInterface $transformer = null, ?ChoiceInterface $choices = null, string $className = DateTime::class, string $format = DateTime::ATOM, ?DateTimeZone $timezone = null)
49
    {
50 50
        parent::__construct($validator, $transformer, $choices);
51
52 50
        $this->className = $className;
53 50
        $this->format = $format;
54 50
        $this->timezone = $timezone;
55 50
    }
56
57
    /**
58
     * Get the timezone of the element
59
     *
60
     * @return DateTimeZone|null The timezone, or null if not defined
61
     */
62 3
    public function timezone(): ?DateTimeZone
63
    {
64 3
        return $this->timezone;
65
    }
66
67
    /**
68
     * Get the handled date time class name
69
     *
70
     * @return class-string<DateTimeInterface>
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<DateTimeInterface> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<DateTimeInterface>.
Loading history...
71
     */
72 2
    public function dateTimeClassName(): string
73
    {
74 2
        return $this->className;
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80 32
    protected function toPhp($httpValue): ?DateTimeInterface
81
    {
82 32
        if ($httpValue === null) {
83 3
            return null;
84
        }
85
86
        switch (true) {
87 29
            case $httpValue instanceof $this->className:
88 1
                $dateTime = $httpValue; // Clone ?
89 1
                break;
90
91 28
            case $httpValue instanceof DateTimeInterface:
92 1
                $httpValue = $httpValue->format($this->format);
93
                // No break
94
95
            default:
96 28
                if (!method_exists($this->className, 'createFromFormat')) {
97 1
                    throw new \LogicException('Invalid DateTime class name "'.$this->className.'" : method createFromFormat() is not found.');
98
                }
99
100 27
                $dateTime = ($this->className)::createFromFormat($this->format, $httpValue, $this->timezone);
101
        }
102
103 28
        if ($dateTime === false) {
104 1
            throw new InvalidArgumentException('Invalid date format');
105
        }
106
107 27
        if ($this->timezone !== null) {
108 2
            $dateTime->setTimezone($this->timezone);
109
        }
110
111 27
        return $dateTime;
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117 10
    protected function toHttp($phpValue)
118
    {
119 10
        if (!$phpValue instanceof DateTimeInterface) {
120 2
            return null;
121
        }
122
123 8
        return $phpValue->format($this->format);
124
    }
125
}
126