blob: ecfe17e793846300ff6d58a02033a16c8ac1584d [file] [log] [blame]
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +02001<?php
2
3/**
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +01004 * This file is part of the Carbon package.
5 *
6 * (c) Brian Nesbitt <brian@nesbot.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020010 */
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010011
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020012namespace Carbon\Doctrine;
13
14use Carbon\Carbon;
15use Carbon\CarbonInterface;
16use DateTimeInterface;
17use Doctrine\DBAL\Platforms\AbstractPlatform;
18use Doctrine\DBAL\Types\ConversionException;
19use Exception;
20
21/**
22 * @template T of CarbonInterface
23 */
24trait CarbonTypeConverter
25{
26 /**
27 * @return class-string<T>
28 */
29 protected function getCarbonClassName(): string
30 {
31 return Carbon::class;
32 }
33
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010034 /**
35 * @return string
36 */
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020037 public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
38 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010039 $precision = $fieldDeclaration['precision'] ?: 10;
40
41 if ($fieldDeclaration['secondPrecision'] ?? false) {
42 $precision = 0;
43 }
44
45 if ($precision === 10) {
46 $precision = DateTimeDefaultPrecision::get();
47 }
48
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020049 $type = parent::getSQLDeclaration($fieldDeclaration, $platform);
50
51 if (!$precision) {
52 return $type;
53 }
54
55 if (str_contains($type, '(')) {
56 return preg_replace('/\(\d+\)/', "($precision)", $type);
57 }
58
59 [$before, $after] = explode(' ', "$type ");
60
61 return trim("$before($precision) $after");
62 }
63
64 /**
65 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
66 *
67 * @return T|null
68 */
69 public function convertToPHPValue($value, AbstractPlatform $platform)
70 {
71 $class = $this->getCarbonClassName();
72
73 if ($value === null || is_a($value, $class)) {
74 return $value;
75 }
76
77 if ($value instanceof DateTimeInterface) {
78 return $class::instance($value);
79 }
80
81 $date = null;
82 $error = null;
83
84 try {
85 $date = $class::parse($value);
86 } catch (Exception $exception) {
87 $error = $exception;
88 }
89
90 if (!$date) {
91 throw ConversionException::conversionFailedFormat(
92 $value,
93 $this->getName(),
94 'Y-m-d H:i:s.u or any format supported by '.$class.'::parse()',
95 $error
96 );
97 }
98
99 return $date;
100 }
101
102 /**
103 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
104 *
105 * @return string|null
106 */
107 public function convertToDatabaseValue($value, AbstractPlatform $platform)
108 {
109 if ($value === null) {
110 return $value;
111 }
112
113 if ($value instanceof DateTimeInterface) {
114 return $value->format('Y-m-d H:i:s.u');
115 }
116
117 throw ConversionException::conversionFailedInvalidType(
118 $value,
119 $this->getName(),
120 ['null', 'DateTime', 'Carbon']
121 );
122 }
123}