Browse Source

Added TimeType. Fixes #2933

Tigran Gabrielyan 12 years ago
parent
commit
497e5e7377

+ 1 - 0
src/Database/Type.php

@@ -35,6 +35,7 @@ class Type {
 	protected static $_types = [
 		'binary' => 'Cake\Database\Type\BinaryType',
 		'date' => 'Cake\Database\Type\DateType',
+		'time' => 'Cake\Database\Type\TimeType',
 		'datetime' => 'Cake\Database\Type\DateTimeType',
 		'timestamp' => 'Cake\Database\Type\DateTimeType',
 		'uuid' => 'Cake\Database\Type\UuidType',

+ 10 - 5
src/Database/Type/DateTimeType.php

@@ -1,7 +1,5 @@
 <?php
 /**
- * PHP Version 5.4
- *
  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  *
@@ -27,9 +25,16 @@ use \DateTime;
 class DateTimeType extends \Cake\Database\Type {
 
 /**
+ * String format to use for DateTime parsing
+ *
+ * @var string
+ */
+	protected $_format = 'Y-m-d H:i:s';
+
+/**
  * Convert DateTime instance into strings.
  *
- * @param string|Datetime $value The value to convert.
+ * @param string|DateTime $value The value to convert.
  * @param Driver $driver The driver instance to convert with.
  * @return string
  */
@@ -37,7 +42,7 @@ class DateTimeType extends \Cake\Database\Type {
 		if (is_string($value)) {
 			return $value;
 		}
-		return $value->format('Y-m-d H:i:s');
+		return $value->format($this->_format);
 	}
 
 /**
@@ -51,7 +56,7 @@ class DateTimeType extends \Cake\Database\Type {
 		if ($value === null) {
 			return null;
 		}
-		$value = DateTime::createFromFormat('Y-m-d H:i:s', $value);
+		$value = DateTime::createFromFormat($this->_format, $value);
 		return $value;
 	}
 

+ 7 - 53
src/Database/Type/DateType.php

@@ -1,7 +1,5 @@
 <?php
 /**
- * PHP Version 5.4
- *
  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  *
@@ -16,38 +14,14 @@
  */
 namespace Cake\Database\Type;
 
-use Cake\Database\Driver;
-use \DateTime;
-
-class DateType extends \Cake\Database\Type {
-
-/**
- * Convert DateTime instance into strings.
- *
- * @param string|Datetime $value The value to convert.
- * @param Driver $driver The driver instance to convert with.
- * @return string
- */
-	public function toDatabase($value, Driver $driver) {
-		if (is_string($value)) {
-			return $value;
-		}
-		return $value->format('Y-m-d');
-	}
+class DateType extends \Cake\Database\Type\DateTimeType {
 
 /**
- * Convert strings into DateTime instances.
+ * Date format for DateTime object
  *
- * @param string $value The value to convert.
- * @param Driver $driver The driver instance to convert with.
- * @return Datetime
+ * @var string
  */
-	public function toPHP($value, Driver $driver) {
-		if ($value === null) {
-			return null;
-		}
-		return DateTime::createFromFormat('Y-m-d', $value);
-	}
+	protected $_format = 'Y-m-d';
 
 /**
  * Convert request data into a datetime object.
@@ -56,30 +30,10 @@ class DateType extends \Cake\Database\Type {
  * @return \DateTime
  */
 	public function marshal($value) {
-		try {
-			if ($value === '' || $value === null || $value === false || $value === true) {
-				return $value;
-			} elseif (is_numeric($value)) {
-				$date = new DateTime('@' . $value);
-			} elseif (is_string($value)) {
-				$date = new DateTime($value);
-			}
-			if (isset($date)) {
-				$date->setTime(0, 0, 0);
-				return $date;
-			}
-		} catch (\Exception $e) {
-			return $value;
-		}
-
-		$date = new DateTime();
-		if (
-			isset($value['year'], $value['month'], $value['day']) &&
-			(is_numeric($value['year']) & is_numeric($value['month']) && is_numeric($value['day']))
-		) {
-			$date->setDate($value['year'], $value['month'], $value['day']);
+		$date = parent::marshal($value);
+		if ($date instanceof \DateTime) {
+			$date->setTime(0, 0, 0);
 		}
-		$date->setTime(0, 0, 0);
 		return $date;
 	}
 

+ 31 - 0
src/Database/Type/TimeType.php

@@ -0,0 +1,31 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+namespace Cake\Database\Type;
+
+/**
+ * Time type converter.
+ *
+ * Use to convert time instances to strings & back.
+ */
+class TimeType extends \Cake\Database\Type\DateTimeType {
+
+/**
+ * Time format for DateTime object
+ *
+ * @var string
+ */
+	protected $_format = 'H:i:s';
+
+}

+ 151 - 0
tests/TestCase/Database/Type/TimeTypeTest.php

@@ -0,0 +1,151 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+namespace Cake\Test\TestCase\Database\Type;
+
+use Cake\Database\Type;
+use Cake\Database\Type\TimeType;
+use Cake\TestSuite\TestCase;
+
+/**
+ * Test for the Time type.
+ */
+class TimeTypeTest extends TestCase {
+
+/**
+ * Setup
+ *
+ * @return void
+ */
+	public function setUp() {
+		parent::setUp();
+		$this->type = Type::build('time');
+		$this->driver = $this->getMock('Cake\Database\Driver');
+	}
+
+/**
+ * Test toPHP
+ *
+ * @return void
+ */
+	public function testToPHP() {
+		$this->assertNull($this->type->toPHP(null, $this->driver));
+
+		$result = $this->type->toPHP('16:30:15', $this->driver);
+		$this->assertInstanceOf('DateTime', $result);
+		$this->assertEquals('16', $result->format('H'));
+		$this->assertEquals('30', $result->format('i'));
+		$this->assertEquals('15', $result->format('s'));
+
+		$result = $this->type->toPHP('2001-01-04 10:11:12', $this->driver);
+		$this->assertFalse($result);
+	}
+
+/**
+ * Test converting to database format
+ *
+ * @return void
+ */
+	public function testToDatabase() {
+		$value = '16:30:15';
+		$result = $this->type->toDatabase($value, $this->driver);
+		$this->assertEquals($value, $result);
+
+		$date = new \DateTime('16:30:15');
+		$result = $this->type->toDatabase($date, $this->driver);
+		$this->assertEquals('16:30:15', $result);
+
+		$date = new \DateTime('2013-08-12 15:16:18');
+		$result = $this->type->toDatabase($date, $this->driver);
+		$this->assertEquals('15:16:18', $result);
+	}
+
+/**
+ * Data provider for marshal()
+ *
+ * @return array
+ */
+	public function marshalProvider() {
+		$date = new \DateTime('@1392387900');
+
+		return [
+			// invalid types.
+			[null, null],
+			[false, false],
+			[true, true],
+			['', ''],
+			['derpy', 'derpy'],
+			['16-nope!', '16-nope!'],
+
+			// valid string types
+			['1392387900', $date],
+			[1392387900, $date],
+			['13:10:10', new \DateTime('13:10:10')],
+			['2014-02-14 13:14:15', new \DateTime('2014-02-14 13:14:15')],
+
+			// valid array types
+			[
+				['year' => 2014, 'month' => 2, 'day' => 14, 'hour' => 13, 'minute' => 14, 'second' => 15],
+				new \DateTime('2014-02-14 13:14:15')
+			],
+			[
+				[
+					'year' => 2014, 'month' => 2, 'day' => 14,
+					'hour' => 1, 'minute' => 14, 'second' => 15,
+					'meridian' => 'am'
+				],
+				new \DateTime('2014-02-14 01:14:15')
+			],
+			[
+				[
+					'year' => 2014, 'month' => 2, 'day' => 14,
+					'hour' => 1, 'minute' => 14, 'second' => 15,
+					'meridian' => 'pm'
+				],
+				new \DateTime('2014-02-14 13:14:15')
+			],
+			[
+				[
+					'hour' => 1, 'minute' => 14, 'second' => 15,
+				],
+				new \DateTime('01:14:15')
+			],
+
+			// Invalid array types
+			[
+				['hour' => 'nope', 'minute' => 14, 'second' => 15],
+				new \DateTime(date('Y-m-d 00:14:15'))
+			],
+			[
+				[
+					'year' => '2014', 'month' => '02', 'day' => '14',
+					'hour' => 'nope', 'minute' => 'nope'
+				],
+				new \DateTime('2014-02-14 00:00:00')
+			],
+		];
+	}
+
+/**
+ * test marshalling data.
+ *
+ * @dataProvider marshalProvider
+ * @return void
+ */
+	public function testMarshal($value, $expected) {
+		$result = $this->type->marshal($value);
+		$this->assertEquals($expected, $result);
+	}
+
+}