Completed
Push — master ( a8fe50...bce26f )
by Maciej
13s
created

lib/Doctrine/ODM/MongoDB/Types/DateType.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ODM\MongoDB\Types;
6
7
use MongoDB\BSON\UTCDateTime;
8
use function date_default_timezone_get;
9
use function explode;
10
use function get_class;
11
use function gettype;
12
use function is_numeric;
13
use function is_scalar;
14
use function is_string;
15
use function sprintf;
16
use function str_pad;
17
use function strpos;
18
19
/**
20
 * The Date type.
21
 *
22
 */
23
class DateType extends Type
24
{
25
    /**
26
     * Converts a value to a DateTime.
27
     * Supports microseconds
28
     *
29
     * @throws InvalidArgumentException If $value is invalid.
30
     * @param  mixed $value \DateTimeInterface|\MongoDB\BSON\UTCDateTime|int|float
31
     */
32 210
    public static function getDateTime($value): \DateTimeInterface
33
    {
34 210
        $datetime = false;
35 210
        $exception = null;
36
37 210
        if ($value instanceof \DateTimeInterface) {
38 186
            return $value;
39 123
        } elseif ($value instanceof UTCDateTime) {
40 111
            $datetime = $value->toDateTime();
41 111
            $datetime->setTimezone(new \DateTimeZone(date_default_timezone_get()));
42 18
        } elseif (is_numeric($value)) {
43 5
            $seconds = $value;
44 5
            $value = (string) $value;
45 5
            $microseconds = 0;
46
47 5
            if (strpos($value, '.') !== false) {
48 3
                list($seconds, $microseconds) = explode('.', $value);
49 3
                $microseconds = str_pad($microseconds, 6, '0'); // ensure microseconds
50
            }
51
52 5
            $datetime = static::craftDateTime((int) $seconds, $microseconds);
0 ignored issues
show
Since craftDateTime() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of craftDateTime() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
53 13
        } elseif (is_string($value)) {
54
            try {
55 10
                $datetime = new \DateTime($value);
56 2
            } catch (\Throwable $e) {
57 2
                $exception = $e;
58
            }
59
        }
60
61 123
        if ($datetime === false) {
62 5
            throw new \InvalidArgumentException(sprintf('Could not convert %s to a date value', is_scalar($value) ? '"' . $value . '"' : gettype($value)), 0, $exception);
63
        }
64
65 118
        return $datetime;
66
    }
67
68 5
    private static function craftDateTime(int $seconds, $microseconds = 0): \DateTime
69
    {
70
        // @todo fix typing for $microseconds
71 5
        $datetime = new \DateTime();
72 5
        $datetime->setTimestamp($seconds);
73 5
        if ($microseconds > 0) {
74 3
            $datetime = \DateTime::createFromFormat('Y-m-d H:i:s.u', $datetime->format('Y-m-d H:i:s') . '.' . $microseconds);
75
        }
76
77 5
        return $datetime;
78
    }
79
80 190
    public function convertToDatabaseValue($value)
81
    {
82 190
        if ($value === null || $value instanceof UTCDateTime) {
83 15
            return $value;
84
        }
85
86 189
        $datetime = static::getDateTime($value);
87
88 184
        return new UTCDateTime((int) $datetime->format('Uv'));
89
    }
90
91 9
    public function convertToPHPValue($value)
92
    {
93 9
        if ($value === null) {
94 1
            return null;
95
        }
96
97 8
        return static::getDateTime($value);
98
    }
99
100
    public function closureToMongo(): string
101
    {
102
        return 'if ($value === null || $value instanceof \MongoDB\BSON\UTCDateTime) { $return = $value; } else { $datetime = \\' . get_class($this) . '::getDateTime($value); $return = new \MongoDB\BSON\UTCDateTime((int) $datetime->format(\'Uv\')); }';
103
    }
104
105 14
    public function closureToPHP(): string
106
    {
107 14
        return 'if ($value === null) { $return = null; } else { $return = \\' . get_class($this) . '::getDateTime($value); }';
108
    }
109
}
110