summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2015-06-28 21:04:37 -0400
committerFrederic Guillot <fred@kanboard.net>2015-06-28 21:04:37 -0400
commit7c1222fc595091d9e292bae9d563a3fdaf660d7b (patch)
treeffdb99b873ab1269b637e9f2cee879777803b03a
parent2e7e7031804b09a04c83896535b31acb12138960 (diff)
Add description attribute for advanced search
-rw-r--r--app/Core/Lexer.php3
-rw-r--r--app/Model/TaskFilter.php46
-rw-r--r--docs/search.markdown6
-rw-r--r--tests/units/LexerTest.php20
-rw-r--r--tests/units/TaskFilterTest.php21
5 files changed, 80 insertions, 16 deletions
diff --git a/app/Core/Lexer.php b/app/Core/Lexer.php
index 34d85704..ccd29588 100644
--- a/app/Core/Lexer.php
+++ b/app/Core/Lexer.php
@@ -29,7 +29,7 @@ class Lexer
"/^(color:)/" => 'T_COLOR',
"/^(due:)/" => 'T_DUE',
"/^(status:)/" => 'T_STATUS',
- "/^(title:)/" => 'T_TITLE',
+ "/^(description:)/" => 'T_DESCRIPTION',
"/^(\s+)/" => 'T_WHITESPACE',
'/^([<=>]{0,2}[0-9]{4}-[0-9]{2}-[0-9]{2})/' => 'T_DATE',
'/^(yesterday|tomorrow|today)/' => 'T_DATE',
@@ -117,6 +117,7 @@ class Lexer
case 'T_STATUS':
case 'T_DUE':
+ case 'T_DESCRIPTION':
$next = next($tokens);
if ($next !== false && ($next['token'] === 'T_DATE' || $next['token'] === 'T_STRING')) {
diff --git a/app/Model/TaskFilter.php b/app/Model/TaskFilter.php
index 6577c9b4..bdfbb190 100644
--- a/app/Model/TaskFilter.php
+++ b/app/Model/TaskFilter.php
@@ -56,6 +56,9 @@ class TaskFilter extends Base
case 'T_STATUS':
$this->filterByStatusName($value);
break;
+ case 'T_DESCRIPTION':
+ $this->filterByDescription($value);
+ break;
}
}
@@ -135,9 +138,22 @@ class TaskFilter extends Base
* @param string $title
* @return TaskFilter
*/
+ public function filterByDescription($title)
+ {
+ $this->query->ilike(Task::TABLE.'.description', '%'.$title.'%');
+ return $this;
+ }
+
+ /**
+ * Filter by title
+ *
+ * @access public
+ * @param string $title
+ * @return TaskFilter
+ */
public function filterByTitle($title)
{
- $this->query->ilike('title', '%'.$title.'%');
+ $this->query->ilike(Task::TABLE.'.title', '%'.$title.'%');
return $this;
}
@@ -150,7 +166,7 @@ class TaskFilter extends Base
*/
public function filterByProjects(array $project_ids)
{
- $this->query->in('project_id', $project_ids);
+ $this->query->in(Task::TABLE.'.project_id', $project_ids);
return $this;
}
@@ -164,7 +180,7 @@ class TaskFilter extends Base
public function filterByProject($project_id)
{
if ($project_id > 0) {
- $this->query->eq('project_id', $project_id);
+ $this->query->eq(Task::TABLE.'.project_id', $project_id);
}
return $this;
@@ -180,7 +196,7 @@ class TaskFilter extends Base
public function filterByCategory($category_id)
{
if ($category_id >= 0) {
- $this->query->eq('category_id', $category_id);
+ $this->query->eq(Task::TABLE.'.category_id', $category_id);
}
return $this;
@@ -196,7 +212,7 @@ class TaskFilter extends Base
public function filterByOwner($owner_id)
{
if ($owner_id >= 0) {
- $this->query->eq('owner_id', $owner_id);
+ $this->query->eq(Task::TABLE.'.owner_id', $owner_id);
}
return $this;
@@ -217,10 +233,10 @@ class TaskFilter extends Base
switch ($assignee) {
case 'me':
- $this->query->eq('owner_id', $this->userSession->getId());
+ $this->query->eq(Task::TABLE.'.owner_id', $this->userSession->getId());
break;
case 'nobody':
- $this->query->eq('owner_id', 0);
+ $this->query->eq(Task::TABLE.'.owner_id', 0);
break;
default:
$this->query->ilike(User::TABLE.'.username', '%'.$assignee.'%');
@@ -241,7 +257,7 @@ class TaskFilter extends Base
public function filterByColor($color_id)
{
if ($color_id !== '') {
- $this->query->eq('color_id', $color_id);
+ $this->query->eq(Task::TABLE.'.color_id', $color_id);
}
return $this;
@@ -277,7 +293,7 @@ class TaskFilter extends Base
public function filterByColumn($column_id)
{
if ($column_id >= 0) {
- $this->query->eq('column_id', $column_id);
+ $this->query->eq(Task::TABLE.'.column_id', $column_id);
}
return $this;
@@ -293,7 +309,7 @@ class TaskFilter extends Base
public function filterBySwimlane($swimlane_id)
{
if ($swimlane_id >= 0) {
- $this->query->eq('swimlane_id', $swimlane_id);
+ $this->query->eq(Task::TABLE.'.swimlane_id', $swimlane_id);
}
return $this;
@@ -325,7 +341,7 @@ class TaskFilter extends Base
public function filterByStatus($is_active)
{
if ($is_active >= 0) {
- $this->query->eq('is_active', $is_active);
+ $this->query->eq(Task::TABLE.'.is_active', $is_active);
}
return $this;
@@ -340,10 +356,10 @@ class TaskFilter extends Base
*/
public function filterByDueDate($date)
{
- $this->query->neq('date_due', '');
- $this->query->neq('date_due', 0);
- $this->query->notNull('date_due');
- return $this->filterWithOperator('date_due', $date, true);
+ $this->query->neq(Task::TABLE.'.date_due', '');
+ $this->query->neq(Task::TABLE.'.date_due', 0);
+ $this->query->notNull(Task::TABLE.'.date_due');
+ return $this->filterWithOperator(Task::TABLE.'.date_due', $date, true);
}
/**
diff --git a/docs/search.markdown b/docs/search.markdown
index 338f0052..bcd889be 100644
--- a/docs/search.markdown
+++ b/docs/search.markdown
@@ -112,3 +112,9 @@ Operators supported:
- Greater than or equal: **due:>=2015-06-29**
- Lower than or equal: **due:<=2015-06-29**
+Search by description
+---------------------
+
+Attribute: **description**
+
+Example: `description:"text search"`
diff --git a/tests/units/LexerTest.php b/tests/units/LexerTest.php
index 7ba3801c..e2b97566 100644
--- a/tests/units/LexerTest.php
+++ b/tests/units/LexerTest.php
@@ -96,6 +96,26 @@ class LexerTest extends Base
);
}
+ public function testDescriptionQuery()
+ {
+ $lexer = new Lexer;
+
+ $this->assertEquals(
+ array(array('match' => 'description:', 'token' => 'T_DESCRIPTION'), array('match' => 'my text search', 'token' => 'T_STRING')),
+ $lexer->tokenize('description:"my text search"')
+ );
+
+ $this->assertEquals(
+ array('T_DESCRIPTION' => 'my text search'),
+ $lexer->map($lexer->tokenize('description:"my text search"'))
+ );
+
+ $this->assertEquals(
+ array(),
+ $lexer->map($lexer->tokenize('description: '))
+ );
+ }
+
public function testDueDateQuery()
{
$lexer = new Lexer;
diff --git a/tests/units/TaskFilterTest.php b/tests/units/TaskFilterTest.php
index 4f826cd2..494a0f1b 100644
--- a/tests/units/TaskFilterTest.php
+++ b/tests/units/TaskFilterTest.php
@@ -53,6 +53,27 @@ class TaskFilterTest extends Base
$this->assertCount(1, $tasks);
}
+ public function testSearchWithDescription()
+ {
+ $p = new Project($this->container);
+ $tc = new TaskCreation($this->container);
+ $tf = new TaskFilter($this->container);
+
+ $this->assertEquals(1, $p->create(array('name' => 'test')));
+ $this->assertNotFalse($tc->create(array('project_id' => 1, 'title' => 'task1')));
+ $this->assertNotFalse($tc->create(array('project_id' => 1, 'title' => 'task2', 'description' => '**something to do**')));
+
+ $tf->search('description:"something"');
+ $tasks = $tf->findAll();
+ $this->assertNotEmpty($tasks);
+ $this->assertCount(1, $tasks);
+ $this->assertEquals('task2', $tasks[0]['title']);
+
+ $tf->search('description:"rainy day"');
+ $tasks = $tf->findAll();
+ $this->assertEmpty($tasks);
+ }
+
public function testSearchWithDueDate()
{
$dp = new DateParser($this->container);