<?php

namespace BVD\PetroleumBundle\DoctrineExtensions\DBAL\Types;

use Doctrine\DBAL\Types\DateTimeType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\ConversionException;

/**
 * http://docs.doctrine-project.org/en/2.0.x/cookbook/working-with-datetime.html
 * 
 * phpc doctrine:schema:update --dump-sql will always show columns of this type as requiring changes for the following reason:
 * comparison of Columns Type property happens at: Doctrine\DBAL\Schema\Comparator#diffColumn():317
 * $column1->getType(), which returns object of type Doctrine\DBAL\Schema\Type.
 * Schema that represents BD will always return for utcdatetime columns object of Doctrine\DBAL\Types\DateTimeType,
 * whereas what is reflected from Entities is BVD\PetroleumBundle\DoctrineExtensions\DBAL\Types\UTCDateTimeType.
 * So, the comparison fails to equal, and always prints this SQL as required changes.
 * To never show the redundant SQL, the comparison at Doctrine\DBAL\Schema\Comparator#diffColumn():317 can be changed into:
 * if ( $column1->getType()->getName() != $column2->getType()->getName() ) {
 */
class UTCDateTimeType extends DateTimeType
{
    static private $utc = null;

    public function getName()
    {
        return "utcdatetime";
    }
    
    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if(empty($value)) return null;

        if (is_null(self::$utc)) {
            self::$utc = new \DateTimeZone('UTC');
        }

        $value->setTimeZone(self::$utc);

        return $value->format($platform->getDateTimeFormatString());
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        if ($value === null) {
            return null;
        }

        if (is_null(self::$utc)) {
            self::$utc = new \DateTimeZone('UTC');
        }

        $val = \DateTime::createFromFormat($platform->getDateTimeFormatString(), $value, self::$utc);

        if (!$val) {
            throw ConversionException::conversionFailed($value, $this->getName());
        }

        return $val;
    }
}
