StringToDateTimeTransformer::transform()   C
last analyzed

Complexity

Conditions 8
Paths 17

Size

Total Lines 40
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 8

Importance

Changes 0
Metric Value
dl 0
loc 40
ccs 25
cts 25
cp 1
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 22
nc 17
nop 1
crap 8
1
<?php
2
3
namespace TreeHouse\Feeder\Modifier\Data\Transformer;
4
5
use TreeHouse\Feeder\Exception\TransformationFailedException;
6
use TreeHouse\Feeder\Exception\UnexpectedTypeException;
7
8
/**
9
 * Transforms between a normalized time and a localized time string.
10
 *
11
 * Copied from Symfony's Form component
12
 */
13
class StringToDateTimeTransformer extends AbstractDateTimeTransformer
14
{
15
    /**
16
     * @var string
17
     */
18
    protected $format;
19
20
    /**
21
     * @param string $format         The date format
22
     * @param string $inputTimezone  The name of the input timezone
23
     * @param string $outputTimezone The name of the output timezone
24
     * @param bool   $resetFields    Whether to reset date/time fields that are not defined in the format
25
     *
26
     * @throws UnexpectedTypeException
27
     * @throws \InvalidArgumentException
28
     */
29 66
    public function __construct($format = 'Y-m-d H:i:s', $inputTimezone = null, $outputTimezone = null, $resetFields = true)
30
    {
31 66
        parent::__construct($inputTimezone, $outputTimezone);
32
33
        /*
34
         * The character "|" in the format makes sure that the parts of a date
35
         * that are *not* specified in the format are reset to the corresponding
36
         * values from 1970-01-01 00:00:00 instead of the current time.
37
         *
38
         * @see http://php.net/manual/en/datetime.createfromformat.php
39
         */
40 60
        if ($resetFields && false === strpos($format, '|')) {
41 60
            $format .= '|';
42 60
        }
43
44 60
        $this->format = $format;
45 60
    }
46
47
    /**
48
     * @inheritdoc
49
     */
50 60
    public function transform($value)
51
    {
52 60
        if (null === $value) {
53 2
            return null;
54
        }
55
56 60
        if (is_scalar($value)) {
57 56
            $value = (string) $value;
58 56
        }
59
60 60
        if (!is_string($value)) {
61 4
            throw new TransformationFailedException(
62 4
                sprintf('Expected a string to transform, got "%s" instead.', json_encode($value))
63 4
            );
64
        }
65
66 56
        if ('' === $value) {
67 2
            return null;
68
        }
69
70
        try {
71 54
            $outputTz = new \DateTimeZone($this->outputTimezone);
72 54
            $dateTime = \DateTime::createFromFormat($this->format, $value, $outputTz);
73
74 54
            $lastErrors = \DateTime::getLastErrors();
75
76 54
            if (0 < $lastErrors['warning_count'] || 0 < $lastErrors['error_count']) {
77 6
                throw new TransformationFailedException(
78 6
                    implode(', ', array_merge(
79 6
                        array_values($lastErrors['warnings']),
80 6
                        array_values($lastErrors['errors'])
81 6
                    ))
82 6
                );
83
            }
84 54
        } catch (\Exception $e) {
85 6
            throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
86
        }
87
88 48
        return $dateTime;
89
    }
90
}
91