From 44d518e95a49fc24cf51b6193f97f3b6c08b3c80 Mon Sep 17 00:00:00 2001 From: DavidBadura Date: Tue, 7 Jul 2015 23:17:00 +0000 Subject: [PATCH] fist draft --- composer.json | 3 +- src/Exception/ReferenceException.php | 12 +++ src/Serializer/Handler/DependsHandler.php | 101 ++++++++++++++++++++++ src/Task.php | 33 +++++++ src/TaskManager.php | 49 +++++++++++ src/Taskwarrior.php | 8 ++ tests/TaskManagerTest.php | 55 ++++++++++++ 7 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 src/Exception/ReferenceException.php create mode 100644 src/Serializer/Handler/DependsHandler.php diff --git a/composer.json b/composer.json index f08e741..1e1e6bd 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "nesbot/carbon": "^1.14", "doctrine/collections": "^1.3", "webmozart/path-util": "^2.0", - "webmozart/assert": "^1.0.1" + "webmozart/assert": "^1.0.1", + "ocramius/proxy-manager": "^1.0" }, "require-dev": { "phpunit/phpunit": "^4.0", diff --git a/src/Exception/ReferenceException.php b/src/Exception/ReferenceException.php new file mode 100644 index 0000000..ed6f36a --- /dev/null +++ b/src/Exception/ReferenceException.php @@ -0,0 +1,12 @@ + + */ +class DependsHandler implements SubscribingHandlerInterface +{ + /** + * @var TaskManager + */ + protected $taskManager; + + /** + * @param TaskManager $taskManager + */ + function __construct(TaskManager $taskManager) + { + $this->taskManager = $taskManager; + } + + /** + * @return array + */ + public static function getSubscribingMethods() + { + $methods = array(); + + $methods[] = array( + 'type' => 'Depends', + 'format' => 'json', + 'direction' => GraphNavigator::DIRECTION_DESERIALIZATION, + 'method' => 'deserializeCarbon' + ); + + $methods[] = array( + 'type' => 'Depends', + 'format' => 'json', + 'direction' => GraphNavigator::DIRECTION_SERIALIZATION, + 'method' => 'serializeCarbon' + ); + + return $methods; + } + + /** + * @param VisitorInterface $visitor + * @param Task[] $tasks + * @param array $type + * @param Context $context + * @return string + * @throws ReferenceException + */ + public function serializeCarbon(VisitorInterface $visitor, $tasks, array $type, Context $context) + { + $list = []; + + foreach ($tasks as $task) { + if (!$task->getUuid()) { + throw new ReferenceException("you can't save a task that has dependencies to tasks that have not been saved"); + } + + $list[] = $task->getUuid(); + } + + return $visitor->visitString(implode(',', $list), $type, $context); + } + + /** + * @param VisitorInterface $visitor + * @param string $data + * @param array $type + * @return ArrayCollection + */ + public function deserializeCarbon(VisitorInterface $visitor, $data, array $type) + { + dump($data); + + if (!$data) { + return new ArrayCollection(); + } + + $tasks = []; + + foreach (explode(',', $data) as $uuid) { + $tasks[] = $this->taskManager->getReference($uuid); + } + + return new ArrayCollection($tasks); + } +} diff --git a/src/Task.php b/src/Task.php index b6a265d..c95a92f 100644 --- a/src/Task.php +++ b/src/Task.php @@ -4,6 +4,7 @@ namespace DavidBadura\Taskwarrior; use Carbon\Carbon; use DavidBadura\Taskwarrior\Exception\DatetimeParseException; +use Doctrine\Common\Collections\ArrayCollection; use JMS\Serializer\Annotation as JMS; /** @@ -126,6 +127,13 @@ class Task */ private $status; + /** + * @var Task[]|ArrayCollection + * + * @JMS\Type("Depends") + */ + private $depends; + /** * */ @@ -134,6 +142,7 @@ class Task $this->urgency = 0; $this->entry = new Carbon('now'); $this->status = self::STATUS_PENDING; + $this->depends = new ArrayCollection(); } /** @@ -268,6 +277,30 @@ class Task } } + /** + * @return Task[]|ArrayCollection + */ + public function getDependencies() + { + return $this->depends; + } + + /** + * @param Task $task + */ + public function addDependency(Task $task) + { + $this->depends->add($task); + } + + /** + * @param Task $task + */ + public function removeDependency(Task $task) + { + $this->depends->removeElement($task); + } + /** * @return Recurring */ diff --git a/src/TaskManager.php b/src/TaskManager.php index 8379c2a..31ff42c 100644 --- a/src/TaskManager.php +++ b/src/TaskManager.php @@ -4,10 +4,13 @@ namespace DavidBadura\Taskwarrior; use DavidBadura\Taskwarrior\Config\Context; use DavidBadura\Taskwarrior\Config\Report; +use DavidBadura\Taskwarrior\Exception\ReferenceException; use DavidBadura\Taskwarrior\Exception\TaskwarriorException; use DavidBadura\Taskwarrior\Query\QueryBuilder; use DavidBadura\Taskwarrior\Serializer\Handler\CarbonHandler; +use DavidBadura\Taskwarrior\Serializer\Handler\DependsHandler; use DavidBadura\Taskwarrior\Serializer\Handler\RecurringHandler; +use DavidBadura\Taskwarrior\Serializer\Handler\TaskHandler; use Doctrine\Common\Collections\ArrayCollection; use JMS\Serializer\Handler\HandlerRegistryInterface; use JMS\Serializer\JsonSerializationVisitor; @@ -15,6 +18,9 @@ use JMS\Serializer\Naming\CamelCaseNamingStrategy; use JMS\Serializer\Naming\SerializedNameAnnotationStrategy; use JMS\Serializer\Serializer; use JMS\Serializer\SerializerBuilder; +use ProxyManager\Factory\LazyLoadingGhostFactory; +use ProxyManager\Factory\LazyLoadingValueHolderFactory; +use ProxyManager\Proxy\LazyLoadingInterface; /** * @author David Badura @@ -285,6 +291,38 @@ class TaskManager ->getResult(); } + /** + * @param string $uuid + * @return Task + */ + public function getReference($uuid) + { + if (isset($this->tasks[$uuid])) { + return $this->tasks[$uuid]; + } + + $self = $this; + $factory = new LazyLoadingValueHolderFactory(); + + $initializer = function ( + & $wrappedObject, + LazyLoadingInterface $proxy, + $method, + array $parameters, + & $initializer + ) use ($self, $uuid) { + + $initializer = null; + $wrappedObject = $this->export($uuid)[0]; + + return true; + }; + + $task = $factory->createProxy('DavidBadura\Taskwarrior\Task', $initializer); + + return $this->tasks[$uuid] = $task; + } + /** * @param Task $task */ @@ -338,6 +376,16 @@ class TaskManager $params['recur'] = $task->getRecurring()->getValue(); } + $params['depends'] = []; + + foreach ($task->getDependencies() as $depend) { + if (!$depend->getUuid()) { + throw new ReferenceException("you can't save a task that has dependencies to tasks that have not been saved"); + } + + $params['depends'][] = $depend->getUuid(); + } + $this->taskwarrior->modify($params, $task->getUuid()); } @@ -419,6 +467,7 @@ class TaskManager ->configureHandlers(function (HandlerRegistryInterface $registry) { $registry->registerSubscribingHandler(new CarbonHandler()); $registry->registerSubscribingHandler(new RecurringHandler()); + $registry->registerSubscribingHandler(new DependsHandler($this)); }) ->addDefaultHandlers() ->setSerializationVisitor('json', $visitor) diff --git a/src/Taskwarrior.php b/src/Taskwarrior.php index 0de5b32..d8ae36b 100644 --- a/src/Taskwarrior.php +++ b/src/Taskwarrior.php @@ -309,6 +309,14 @@ class Taskwarrior } } + if (array_key_exists('depends', $params)) { + if (is_array($params['depends'])) { + $options[] = 'depends:' . implode(',', $params['depends']); + } else { + $options[] = 'depends:' . $params['depends']; + } + } + if (array_key_exists('status', $params)) { $options[] = 'status:' . $params['status']; } diff --git a/tests/TaskManagerTest.php b/tests/TaskManagerTest.php index 740770a..4e17610 100644 --- a/tests/TaskManagerTest.php +++ b/tests/TaskManagerTest.php @@ -787,6 +787,61 @@ class TaskManagerTest extends \PHPUnit_Framework_TestCase $this->assertCount(1, $this->taskManager->filterPending('(status:pending or status:waiting)')); } + public function testDependenciesException() + { + $this->setExpectedException('DavidBadura\Taskwarrior\Exception\ReferenceException'); + + $task1 = new Task(); + $task1->setDescription("a"); + + $task2 = new Task(); + $task2->setDescription("b"); + + $task3 = new Task(); + $task3->setDescription("c"); + + $task1->addDependency($task2); + $task1->addDependency($task3); + + $this->taskManager->save($task1); + } + + + public function testDependencies() + { + $task1 = new Task(); + $task1->setDescription("a"); + + $task2 = new Task(); + $task2->setDescription("b"); + + $task1->addDependency($task2); + + $this->taskManager->save($task2); + $this->taskManager->save($task1); + + $this->taskManager->clear(); + $temp1 = $this->taskManager->find($task1->getUuid()); + + $this->assertCount(1, $temp1->getDependencies()); + + $temp2 = $temp1->getDependencies()[0]; + + $this->assertInstanceOf('DavidBadura\Taskwarrior\Task', $temp2); + $this->assertEquals('b', $temp2->getDescription()); + + $temp1->removeDependency($temp2); + + $this->taskManager->save($temp1); + + $this->taskManager->clear(); + $temp1 = $this->taskManager->find($task1->getUuid()); + + dump($temp1); + + $this->assertCount(0, $temp1->getDependencies()); + } + /** * @param string $string * @return \DateTime