add QueryBuilder

This commit is contained in:
DavidBadura 2015-04-06 21:49:38 +00:00
parent 0ab45fae1f
commit a0ca517981
4 changed files with 206 additions and 47 deletions

160
src/QueryBuilder.php Normal file
View File

@ -0,0 +1,160 @@
<?php
namespace DavidBadura\Taskwarrior;
use DavidBadura\Taskwarrior\Exception\TaskwarriorException;
/**
* @author David Badura <d.a.badura@gmail.com>
*/
class QueryBuilder
{
const SORT_URGENCY = 'urgency';
const SORT_DESCRIPTION = 'description';
const SORT_ENTRY = 'entry';
/**
* @var TaskManager
*/
protected $taskManager;
/**
* @var array
*/
protected $filter = [];
/**
* @var string
*/
protected $sortBy = self::SORT_URGENCY;
/**
* @param TaskManager $taskManager
*/
public function __construct(TaskManager $taskManager)
{
$this->taskManager = $taskManager;
}
/**
* @param string $project
* @return $this
*/
public function whereProject($project)
{
return $this->where('project:' . $project);
}
/**
* @param string $tag
* @return $this
*/
public function whereTag($tag)
{
return $this->where('+' . $tag);
}
/**
* @param string $priority
* @return $this
*/
public function wherePriority($priority)
{
return $this->where('priority:' . $priority);
}
/**
* @param string $status
* @return $this
*/
public function whereStatus($status)
{
return $this->where('status:' . $status);
}
/**
* @param string $where
* @return $this
*/
public function where($where)
{
$this->filter[] = $where;
return $this;
}
/**
* @param string $by
* @return $this
*/
public function sortBy($by = self::SORT_URGENCY)
{
$this->sortBy = $by;
return $this;
}
/**
* @return string
*/
public function getFilter()
{
return implode(' ', $this->filter);
}
/**
* @return Task[]
*/
public function getResult()
{
$result = $this->taskManager->filter($this->getFilter());
return $this->sort($result, $this->sortBy);
}
/**
* @param Task[] $tasks
* @param string $by
* @return Task[]
* @throws TaskwarriorException
*/
protected function sort(array $tasks, $by)
{
switch ($by) {
case self::SORT_ENTRY:
$callback = function (Task $a, Task $b) {
return $a->getEntry() >= $b->getEntry() ? 1 : -1;
};
break;
case self::SORT_DESCRIPTION:
$callback = function (Task $a, Task $b) {
return strcmp($b->getDescription(), $a->getDescription());
};
break;
case self::SORT_URGENCY:
$callback = function (Task $a, Task $b) {
if (0 != $diff = $b->getUrgency() - $a->getUrgency()) {
return $diff;
}
return $a->getEntry() >= $b->getEntry() ? 1 : -1;
};
break;
default:
throw new TaskwarriorException('sorting by "%s" is not supported', $by);
}
usort($tasks, $callback);
return $tasks;
}
}

View File

@ -2,7 +2,6 @@
namespace DavidBadura\Taskwarrior; namespace DavidBadura\Taskwarrior;
use Carbon\Carbon;
use DavidBadura\Taskwarrior\Exception\TaskwarriorException; use DavidBadura\Taskwarrior\Exception\TaskwarriorException;
use DavidBadura\Taskwarrior\Serializer\Handler\CarbonHandler; use DavidBadura\Taskwarrior\Serializer\Handler\CarbonHandler;
use DavidBadura\Taskwarrior\Serializer\Handler\RecurringHandler; use DavidBadura\Taskwarrior\Serializer\Handler\RecurringHandler;
@ -113,7 +112,7 @@ class TaskManager
$this->tasks[$task->getUuid()] = $task; $this->tasks[$task->getUuid()] = $task;
} }
return $this->sort($result); return $result;
} }
/** /**
@ -216,6 +215,14 @@ class TaskManager
$this->tasks = []; $this->tasks = [];
} }
/**
* @return QueryBuilder
*/
public function createQueryBuilder()
{
return new QueryBuilder($this);
}
/** /**
* @param string|array $filter * @param string|array $filter
* @return Task[] * @return Task[]
@ -291,26 +298,6 @@ class TaskManager
} }
} }
/**
* @param Task[] $tasks
* @return Task[]
*/
private function sort(array $tasks)
{
usort(
$tasks,
function (Task $a, Task $b) {
if (0 != $diff = $b->getUrgency() - $a->getUrgency()) {
return $diff;
}
return $a->getEntry() >= $b->getEntry() ? 1 : -1;
}
);
return $tasks;
}
/** /**
* *
* @param Task $task * @param Task $task

View File

@ -0,0 +1,37 @@
<?php
namespace DavidBadura\Taskwarrior\Test;
use DavidBadura\Taskwarrior\QueryBuilder;
/**
* @author David Badura <badura@simplethings.de>
*/
class QueryBuilderTest extends \PHPUnit_Framework_TestCase
{
/**
* @var QueryBuilder
*/
protected $builder;
public function setUp()
{
$taskManager = $this->getMockBuilder('DavidBadura\Taskwarrior\TaskManager')
->disableOriginalConstructor()
->getMock();
$this->builder = new QueryBuilder($taskManager);
}
public function testWhere()
{
$filter = $this->builder
->whereProject('testProject')
->whereTag('testTag')
->whereStatus('testStatus')
->wherePriority('testPriority')
->getFilter();
$this->assertEquals('project:testProject +testTag status:testStatus priority:testPriority', $filter);
}
}

View File

@ -354,31 +354,6 @@ class TaskManagerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(0, $task1->getUrgency()); $this->assertEquals(0, $task1->getUrgency());
} }
public function testUrgencySort()
{
$task1 = new Task();
$task1->setDescription('foo1');
$task2 = new Task();
$task2->setDescription('foo2');
$task2->setDue($this->createDateTime('1989-01-08 11:12:13'));
$task3 = new Task();
$task3->setDescription('foo3');
$this->taskManager->save($task1);
$this->taskManager->save($task2);
$this->taskManager->save($task3);
$this->assertEquals(0, $task1->getUrgency());
$this->assertEquals(12, $task2->getUrgency());
$this->assertEquals(0, $task3->getUrgency());
$tasks = $this->taskManager->filter();
$this->assertEquals(array($task2, $task1, $task3), $tasks);
}
public function testProject() public function testProject()
{ {
$task1 = new Task(); $task1 = new Task();