mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
112 lines
3.1 KiB
PHP
112 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace Chill\MainBundle\Doctrine\Type;
|
|
|
|
use Doctrine\DBAL\Types\DateIntervalType;
|
|
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
|
use Doctrine\DBAL\Types\ConversionException;
|
|
|
|
/**
|
|
* Re-declare the date interval to use the implementation of date interval in
|
|
* postgreql
|
|
*
|
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
|
*/
|
|
class NativeDateIntervalType extends DateIntervalType
|
|
{
|
|
const FORMAT = '%rP%YY%MM%DDT%HH%IM%SS';
|
|
|
|
public function getName(): string
|
|
{
|
|
return \Doctrine\DBAL\Types\Type::DATEINTERVAL;
|
|
}
|
|
|
|
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
|
|
{
|
|
return 'INTERVAL';
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function convertToDatabaseValue($value, AbstractPlatform $platform)
|
|
{
|
|
if (null === $value) {
|
|
return null;
|
|
}
|
|
|
|
if ($value instanceof \DateInterval) {
|
|
return $value->format(self::FORMAT);
|
|
}
|
|
|
|
throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateInterval']);
|
|
}
|
|
|
|
public function convertToPHPValue($value, AbstractPlatform $platform)
|
|
{
|
|
if ($value === null || $value instanceof \DateInterval) {
|
|
return $value;
|
|
}
|
|
|
|
try {
|
|
$strings = explode(' ', $value);
|
|
|
|
if (count($strings) === 0) {
|
|
return null;
|
|
}
|
|
$intervalSpec = 'P';
|
|
\reset($strings);
|
|
|
|
do {
|
|
$intervalSpec .= $this->convertEntry($strings);
|
|
} while (next($strings) !== FALSE);
|
|
|
|
return new \DateInterval($intervalSpec);
|
|
} catch (\Exception $exception) {
|
|
throw $this->createConversionException($value, $exception);
|
|
}
|
|
}
|
|
|
|
private function convertEntry(&$strings)
|
|
{
|
|
$current = \current($strings);
|
|
|
|
if (is_numeric($current)) {
|
|
$next = \next($strings);
|
|
switch($next) {
|
|
case 'year':
|
|
case 'years':
|
|
$unit = 'Y';
|
|
break;
|
|
case 'mon':
|
|
case 'mons':
|
|
$unit = 'M';
|
|
break;
|
|
case 'day':
|
|
case 'days':
|
|
$unit = 'D';
|
|
break;
|
|
default:
|
|
throw $this->createConversionException(implode('', $strings));
|
|
}
|
|
|
|
return $current.$unit;
|
|
|
|
} elseif (\preg_match('/([0-9]{2}\:[0-9]{2}:[0-9]{2})/', $current) === 1) {
|
|
$tExploded = explode(':', $current);
|
|
$intervalSpec = 'T';
|
|
$intervalSpec.= $tExploded[0].'H';
|
|
$intervalSpec.= $tExploded[1].'M';
|
|
$intervalSpec.= $tExploded[2].'S';
|
|
|
|
return $intervalSpec;
|
|
}
|
|
}
|
|
|
|
protected function createConversionException($value, $exception = null)
|
|
{
|
|
return ConversionException::conversionFailedFormat($value, $this->getName(), 'xx year xx mons xx days 01:02:03', $exception);
|
|
}
|
|
|
|
}
|