From 9ed7f6ff7c701bddb92671e758d18d38aa468f7d Mon Sep 17 00:00:00 2001 From: DavidBadura Date: Sun, 8 Feb 2015 11:23:14 +0000 Subject: [PATCH] add carbon lib for date operations --- composer.json | 3 +- src/Serializer/Handler/CarbonHandler.php | 108 +++++++++++++++++++++++ src/Task.php | 34 +++---- src/TaskManager.php | 31 ++++--- src/Taskwarrior.php | 13 ++- tests/TaskManagerTest.php | 30 ++++++- 6 files changed, 185 insertions(+), 34 deletions(-) create mode 100644 src/Serializer/Handler/CarbonHandler.php diff --git a/composer.json b/composer.json index 05bbe35..ac8af42 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,8 @@ "php": ">=5.4", "symfony/process": "~2.3", "jms/serializer": "0.16.*", - "symfony/filesystem": "~2.3" + "symfony/filesystem": "~2.3", + "nesbot/carbon": "~1.14" }, "require-dev": { "phpunit/phpunit": "~4.0" diff --git a/src/Serializer/Handler/CarbonHandler.php b/src/Serializer/Handler/CarbonHandler.php new file mode 100644 index 0000000..6233b14 --- /dev/null +++ b/src/Serializer/Handler/CarbonHandler.php @@ -0,0 +1,108 @@ + + */ +class CarbonHandler implements SubscribingHandlerInterface +{ + /** + * @var string + */ + private $defaultFormat; + + /** + * @var \DateTimeZone + */ + private $defaultTimezone; + + /** + * @param string $defaultFormat + * @param string $defaultTimezone + */ + public function __construct($defaultFormat = 'Ymd\THis\Z', $defaultTimezone = 'UTC') + { + $this->defaultFormat = $defaultFormat; + $this->defaultTimezone = new \DateTimeZone($defaultTimezone); + } + + /** + * @return array + */ + public static function getSubscribingMethods() + { + $methods = array(); + $types = array('Carbon\Carbon', 'Carbon'); + + foreach ($types as $type) { + $methods[] = array( + 'type' => $type, + 'format' => 'json', + 'direction' => GraphNavigator::DIRECTION_DESERIALIZATION, + 'method' => 'deserializeCarbon' + ); + + $methods[] = array( + 'type' => $type, + 'format' => 'json', + 'direction' => GraphNavigator::DIRECTION_SERIALIZATION, + 'method' => 'serializeCarbon' + ); + } + + return $methods; + } + + /** + * @param VisitorInterface $visitor + * @param Carbon $date + * @param array $type + * @param Context $context + * @return string + */ + public function serializeCarbon(VisitorInterface $visitor, Carbon $date, array $type, Context $context) + { + return $visitor->visitString($date->format($this->getFormat($type)), $type, $context); + } + + /** + * @param VisitorInterface $visitor + * @param string $data + * @param array $type + * @return \DateTime|null + */ + public function deserializeCarbon(VisitorInterface $visitor, $data, array $type) + { + if (null === $data) { + return null; + } + + $timezone = isset($type['params'][1]) ? new \DateTimeZone($type['params'][1]) : $this->defaultTimezone; + $format = $this->getFormat($type); + + $datetime = Carbon::createFromFormat($format, (string)$data, $timezone); + + if (false === $datetime) { + throw new RuntimeException(sprintf('Invalid datetime "%s", expected format %s.', $data, $format)); + } + + return $datetime; + } + + /** + * @param array $type + * @return string + */ + private function getFormat(array $type) + { + return isset($type['params'][0]) ? $type['params'][0] : $this->defaultFormat; + } +} diff --git a/src/Task.php b/src/Task.php index 38ca52d..e2888dd 100644 --- a/src/Task.php +++ b/src/Task.php @@ -2,6 +2,7 @@ namespace DavidBadura\Taskwarrior; +use Carbon\Carbon; use JMS\Serializer\Annotation as JMS; /** @@ -47,23 +48,23 @@ class Task private $project; /** - * @var \DateTime + * @var Carbon * - * @JMS\Type(name="DateTime<'Ymd\THis\Z'>") + * @JMS\Type("Carbon") */ private $due; /** - * @var \DateTime + * @var Carbon * - * @JMS\Type(name="DateTime<'Ymd\THis\Z'>") + * @JMS\Type("Carbon") */ private $wait; /** - * @var \DateTime + * @var Carbon * - * @JMS\Type(name="DateTime<'Ymd\THis\Z'>") + * @JMS\Type("Carbon") */ private $until; @@ -82,24 +83,24 @@ class Task private $urgency; /** - * @var \DateTime + * @var Carbon * - * @JMS\Type(name="DateTime<'Ymd\THis\Z'>") + * @JMS\Type("Carbon") */ private $entry; /** - * @var \DateTime + * @var Carbon * - * @JMS\Type(name="DateTime<'Ymd\THis\Z'>") + * @JMS\Type("Carbon") */ private $modified; /** - * @var \DateTime + * @var Carbon * - * @JMS\Type(name="DateTime<'Ymd\THis\Z'>") + * @JMS\Type("Carbon") */ private $end; @@ -116,7 +117,7 @@ class Task public function __construct() { $this->urgency = 0; - $this->entry = new \DateTime('now', new \DateTimeZone('UTC')); + $this->entry = new Carbon('now', new \DateTimeZone('UTC')); $this->status = self::STATUS_PENDING; } @@ -348,7 +349,10 @@ class Task private function parseDateTime($date) { if ($date instanceof \DateTime) { + return new Carbon($date->format('Y-m-d H:i:s'), new \DateTimeZone('UTC')); + } + if ($date instanceof Carbon) { $date = clone $date; $date->setTimezone(new \DateTimeZone('UTC')); @@ -356,7 +360,7 @@ class Task } if (is_string($date)) { - return new \DateTime($date, new \DateTimeZone('UTC')); + return new Carbon($date, new \DateTimeZone('UTC')); } if ($date === null) { @@ -372,7 +376,7 @@ class Task public function __clone() { $this->uuid = null; - $this->entry = new \DateTime('now', new \DateTimeZone('UTC')); + $this->entry = new Carbon('now', new \DateTimeZone('UTC')); $this->status = self::STATUS_PENDING; } } \ No newline at end of file diff --git a/src/TaskManager.php b/src/TaskManager.php index a0a8e4b..702b0dc 100644 --- a/src/TaskManager.php +++ b/src/TaskManager.php @@ -2,9 +2,10 @@ namespace DavidBadura\Taskwarrior; +use DavidBadura\Taskwarrior\Serializer\Handler\CarbonHandler; +use JMS\Serializer\Handler\HandlerRegistryInterface; +use JMS\Serializer\Serializer; use JMS\Serializer\SerializerBuilder; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Process\ProcessBuilder; /** * @author David Badura @@ -164,11 +165,7 @@ class TaskManager { $json = $this->taskwarrior->export($filter); - $serializer = SerializerBuilder::create() - ->addDefaultHandlers() - ->build(); - - return $serializer->deserialize($json, 'array', 'json'); + return $this->getSerializer()->deserialize($json, 'array', 'json'); } /** @@ -241,11 +238,7 @@ class TaskManager */ private function serializeTask(Task $task) { - $serializer = SerializerBuilder::create() - ->addDefaultHandlers() - ->build(); - - $result = $serializer->serialize($task, 'json'); + $result = $this->getSerializer()->serialize($task, 'json'); return str_replace("\\/", "/", $result); } @@ -263,6 +256,20 @@ class TaskManager $prop->setValue($task, $value); } + /** + * @return Serializer + */ + private function getSerializer() + { + return SerializerBuilder::create() + ->configureHandlers(function (HandlerRegistryInterface $registry) { + $registry->registerSubscribingHandler(new CarbonHandler()); + }) + ->addDefaultHandlers() + ->setDebug(true) + ->build(); + } + /** * @return self */ diff --git a/src/Taskwarrior.php b/src/Taskwarrior.php index cf12499..7f37c69 100644 --- a/src/Taskwarrior.php +++ b/src/Taskwarrior.php @@ -16,6 +16,11 @@ class Taskwarrior */ private $rcOptions; + /** + * @var string + */ + private $version; + /** * @param string $taskrc * @param string $taskData @@ -56,7 +61,7 @@ class Taskwarrior */ public function add(array $params) { - $this->command('modify', null, $this->getOptions($params)); + $this->command('add', null, $this->getOptions($params)); } /** @@ -173,7 +178,11 @@ class Taskwarrior */ public function version() { - return $this->command('_version'); + if ($this->version) { + return $this->version; + } + + return $this->version = $this->command('_version'); } /** diff --git a/tests/TaskManagerTest.php b/tests/TaskManagerTest.php index 04cc12f..768c3ad 100644 --- a/tests/TaskManagerTest.php +++ b/tests/TaskManagerTest.php @@ -176,8 +176,15 @@ class TaskManagerTest extends \PHPUnit_Framework_TestCase $this->assertCount(1, $this->taskManager->filter('project:home prio:H +now')); } - public function testDates() + public function testModified() { + if (version_compare($this->taskwarrior->version(), '2.2.0', '>=')) { + $this->markTestSkipped(sprintf( + 'taskwarrior version %s dont support modified attr', + $this->taskwarrior->version() + )); + } + $task1 = new Task(); $task1->setDescription('foo1'); @@ -185,7 +192,6 @@ class TaskManagerTest extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('DateTime', $task1->getEntry()); $this->assertNull($task1->getModified()); - $this->assertNull($task1->getEnd()); $task1->setDescription('bar2'); @@ -193,12 +199,28 @@ class TaskManagerTest extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('DateTime', $task1->getEntry()); $this->assertInstanceOf('DateTime', $task1->getModified()); + } + + public function testEnd() + { + $task1 = new Task(); + $task1->setDescription('foo1'); + + $this->taskManager->save($task1); + + $this->assertInstanceOf('DateTime', $task1->getEntry()); + $this->assertNull($task1->getEnd()); + + $task1->setDescription('bar2'); + + $this->taskManager->save($task1); + + $this->assertInstanceOf('DateTime', $task1->getEntry()); $this->assertNull($task1->getEnd()); $this->taskManager->done($task1); $this->assertInstanceOf('DateTime', $task1->getEntry()); - $this->assertInstanceOf('DateTime', $task1->getModified()); $this->assertInstanceOf('DateTime', $task1->getEnd()); } @@ -507,6 +529,6 @@ class TaskManagerTest extends \PHPUnit_Framework_TestCase */ private function createDateTime($string = 'now') { - return new \DateTime($string); + return new \DateTime($string, new \DateTimeZone('UTC')); } } \ No newline at end of file