| <?php |
| |
| /** |
| * Thanks to https://github.com/flaushi for his suggestion: |
| * https://github.com/doctrine/dbal/issues/2873#issuecomment-534956358 |
| */ |
| namespace Carbon\Doctrine; |
| |
| use Carbon\Carbon; |
| use Carbon\CarbonInterface; |
| use DateTimeInterface; |
| use Doctrine\DBAL\Platforms\AbstractPlatform; |
| use Doctrine\DBAL\Types\ConversionException; |
| use Exception; |
| |
| /** |
| * @template T of CarbonInterface |
| */ |
| trait CarbonTypeConverter |
| { |
| /** |
| * @return class-string<T> |
| */ |
| protected function getCarbonClassName(): string |
| { |
| return Carbon::class; |
| } |
| |
| public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) |
| { |
| $precision = ($fieldDeclaration['precision'] ?: 10) === 10 |
| ? DateTimeDefaultPrecision::get() |
| : $fieldDeclaration['precision']; |
| $type = parent::getSQLDeclaration($fieldDeclaration, $platform); |
| |
| if (!$precision) { |
| return $type; |
| } |
| |
| if (str_contains($type, '(')) { |
| return preg_replace('/\(\d+\)/', "($precision)", $type); |
| } |
| |
| [$before, $after] = explode(' ', "$type "); |
| |
| return trim("$before($precision) $after"); |
| } |
| |
| /** |
| * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
| * |
| * @return T|null |
| */ |
| public function convertToPHPValue($value, AbstractPlatform $platform) |
| { |
| $class = $this->getCarbonClassName(); |
| |
| if ($value === null || is_a($value, $class)) { |
| return $value; |
| } |
| |
| if ($value instanceof DateTimeInterface) { |
| return $class::instance($value); |
| } |
| |
| $date = null; |
| $error = null; |
| |
| try { |
| $date = $class::parse($value); |
| } catch (Exception $exception) { |
| $error = $exception; |
| } |
| |
| if (!$date) { |
| throw ConversionException::conversionFailedFormat( |
| $value, |
| $this->getName(), |
| 'Y-m-d H:i:s.u or any format supported by '.$class.'::parse()', |
| $error |
| ); |
| } |
| |
| return $date; |
| } |
| |
| /** |
| * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
| * |
| * @return string|null |
| */ |
| public function convertToDatabaseValue($value, AbstractPlatform $platform) |
| { |
| if ($value === null) { |
| return $value; |
| } |
| |
| if ($value instanceof DateTimeInterface) { |
| return $value->format('Y-m-d H:i:s.u'); |
| } |
| |
| throw ConversionException::conversionFailedInvalidType( |
| $value, |
| $this->getName(), |
| ['null', 'DateTime', 'Carbon'] |
| ); |
| } |
| } |