From d30311c5ef4470161055f1d72b5f3f404d5fc25f Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Fri, 22 Dec 2023 17:40:34 +0200 Subject: [PATCH] add support for "nesbot/carbon" --- README.md | 6 ++++++ composer.json | 1 + src/TypecastBehavior.php | 29 +++++++++++++++++++++++++++++ tests/TypecastBehaviorTest.php | 28 ++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/README.md b/README.md index 973bb9c..f161e7c 100644 --- a/README.md +++ b/README.md @@ -276,6 +276,12 @@ $model = Item::model()->findByPk($id); var_dump($model->created_at); // outputs: object(DateTime) ``` +This extension also supports [nesbot/carbon](https://packagist.org/packages/nesbot/carbon) package. +In order to convert dates to `\Carbon\Carbon` you should use following types: + +- `\yii1tech\model\typecast\TypecastBehavior::TYPE_DATETIME_CARBON` +- `\yii1tech\model\typecast\TypecastBehavior::TYPE_TIMESTAMP_CARBON` + ### Custom typecasting diff --git a/composer.json b/composer.json index 4618db4..a223da9 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ "yiisoft/yii": "~1.1.0" }, "require-dev": { + "nesbot/carbon": "^2.67", "phpunit/phpunit": "^6.0 || ^7.0 || ^8.0 || ^9.3 || ^10.0.7" }, "autoload": { diff --git a/src/TypecastBehavior.php b/src/TypecastBehavior.php index 78e233c..6634d39 100644 --- a/src/TypecastBehavior.php +++ b/src/TypecastBehavior.php @@ -3,6 +3,7 @@ namespace yii1tech\model\typecast; use CActiveRecord; +use Carbon\Carbon; use CBehavior; use CBooleanValidator; use CDbColumnSchema; @@ -114,6 +115,14 @@ class TypecastBehavior extends CBehavior * Converts integer Unix timestamp into {@see \DateTime} and vice versa. */ const TYPE_TIMESTAMP = 'timestamp'; + /** + * Converts ISO datetime string into {@see \Carbon\Carbon} and vice versa. + */ + const TYPE_DATETIME_CARBON = 'datetime-carbon'; + /** + * Converts integer Unix timestamp into {@see \Carbon\Carbon} and vice versa. + */ + const TYPE_TIMESTAMP_CARBON = 'timestamp-carbon'; /** * @var array|null attribute typecast map in format: attributeName => type. @@ -308,6 +317,26 @@ protected function typecastValue($value, $type) } return (new \DateTime())->setTimestamp((int) $value); + case self::TYPE_DATETIME_CARBON: + if ($value === null || $value instanceof \DateTime) { + return $value; + } + + if (!class_exists(Carbon::class)) { + throw new \LogicException('Extension "nesbot/carbon" has not been installed'); + } + + return Carbon::createFromFormat('Y-m-d H:i:s', (string) $value); + case self::TYPE_TIMESTAMP_CARBON: + if ($value === null || $value instanceof \DateTime) { + return $value; + } + + if (!class_exists(Carbon::class)) { + throw new \LogicException('Extension "nesbot/carbon" has not been installed'); + } + + return (new Carbon())->setTimestamp((int) $value); default: throw new InvalidArgumentException("Unsupported attribute type '{$type}'"); } diff --git a/tests/TypecastBehaviorTest.php b/tests/TypecastBehaviorTest.php index 8bdbe81..1d95580 100644 --- a/tests/TypecastBehaviorTest.php +++ b/tests/TypecastBehaviorTest.php @@ -3,6 +3,7 @@ namespace yii1tech\model\typecast\test; use ArrayObject; +use Carbon\Carbon; use DateTime; use yii1tech\model\typecast\TypecastBehavior; use yii1tech\model\typecast\test\data\FormWithTypecast; @@ -176,6 +177,33 @@ public function testDateTime(): void $this->assertSame($createdDateTime->getTimestamp(), $model->created_timestamp->getTimestamp()); } + /** + * @depends testDateTime + */ + public function testDateTimeCarbon(): void + { + $baseBehavior = new TypecastBehavior(); + $baseBehavior->attributeTypes = [ + 'created_date' => TypecastBehavior::TYPE_DATETIME_CARBON, + 'created_timestamp' => TypecastBehavior::TYPE_TIMESTAMP_CARBON, + ]; + + $timestamp = time(); + + $model = new Item(); + $model->created_timestamp = $timestamp; + $model->created_date = date('Y-m-d H:i:s', $timestamp); + + $baseBehavior->attach($model); + $baseBehavior->typecastAttributes(); + + $this->assertTrue($model->created_date instanceof Carbon); + $this->assertTrue($model->created_timestamp instanceof Carbon); + + $this->assertSame($timestamp, $model->created_date->getTimestamp()); + $this->assertSame($timestamp, $model->created_timestamp->getTimestamp()); + } + /** * @depends testTypecast */