summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Core/Lexer.php5
-rw-r--r--app/Model/TaskFilter.php66
-rw-r--r--docs/search.markdown96
-rw-r--r--tests/units/LexerTest.php65
4 files changed, 165 insertions, 67 deletions
diff --git a/app/Core/Lexer.php b/app/Core/Lexer.php
index 0a237254..d7e6fde4 100644
--- a/app/Core/Lexer.php
+++ b/app/Core/Lexer.php
@@ -28,6 +28,9 @@ class Lexer
"/^(assignee:)/" => 'T_ASSIGNEE',
"/^(color:)/" => 'T_COLOR',
"/^(due:)/" => 'T_DUE',
+ "/^(updated:)/" => 'T_UPDATED',
+ "/^(modified:)/" => 'T_UPDATED',
+ "/^(created:)/" => 'T_CREATED',
"/^(status:)/" => 'T_STATUS',
"/^(description:)/" => 'T_DESCRIPTION',
"/^(category:)/" => 'T_CATEGORY',
@@ -128,6 +131,8 @@ class Lexer
case 'T_STATUS':
case 'T_DUE':
+ case 'T_UPDATED':
+ case 'T_CREATED':
case 'T_DESCRIPTION':
case 'T_REFERENCE':
$next = next($tokens);
diff --git a/app/Model/TaskFilter.php b/app/Model/TaskFilter.php
index 0dbadbf8..77ab1f3c 100644
--- a/app/Model/TaskFilter.php
+++ b/app/Model/TaskFilter.php
@@ -50,6 +50,12 @@ class TaskFilter extends Base
case 'T_DUE':
$this->filterByDueDate($value);
break;
+ case 'T_UPDATED':
+ $this->filterByModificationDate($value);
+ break;
+ case 'T_CREATED':
+ $this->filterByCreationDate($value);
+ break;
case 'T_TITLE':
$this->filterByTitle($value);
break;
@@ -580,6 +586,22 @@ class TaskFilter extends Base
* Filter by creation date
*
* @access public
+ * @param string $date ISO8601 date format
+ * @return TaskFilter
+ */
+ public function filterByCreationDate($date)
+ {
+ if ($date === 'recently') {
+ return $this->filterRecentlyDate(Task::TABLE.'.date_creation');
+ }
+
+ return $this->filterWithOperator(Task::TABLE.'.date_creation', $date, true);
+ }
+
+ /**
+ * Filter by creation date
+ *
+ * @access public
* @param string $start
* @param string $end
* @return TaskFilter
@@ -597,6 +619,22 @@ class TaskFilter extends Base
}
/**
+ * Filter by modification date
+ *
+ * @access public
+ * @param string $date ISO8601 date format
+ * @return TaskFilter
+ */
+ public function filterByModificationDate($date)
+ {
+ if ($date === 'recently') {
+ return $this->filterRecentlyDate(Task::TABLE.'.date_modification');
+ }
+
+ return $this->filterWithOperator(Task::TABLE.'.date_modification', $date, true);
+ }
+
+ /**
* Get all results of the filter
*
* @access public
@@ -826,7 +864,6 @@ class TaskFilter extends Base
);
foreach ($operators as $operator => $method) {
-
if (strpos($value, $operator) === 0) {
$value = substr($value, strlen($operator));
$this->query->$method($field, $is_date ? $this->dateParser->getTimestampFromIsoFormat($value) : $value);
@@ -834,7 +871,32 @@ class TaskFilter extends Base
}
}
- $this->query->eq($field, $is_date ? $this->dateParser->getTimestampFromIsoFormat($value) : $value);
+ if ($is_date) {
+ $timestamp = $this->dateParser->getTimestampFromIsoFormat($value);
+ $this->query->gte($field, $timestamp);
+ $this->query->lte($field, $timestamp + 86399);
+ }
+ else {
+ $this->query->eq($field, $value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Use the board_highlight_period for the "recently" keyword
+ *
+ * @access private
+ * @param string $field
+ * @return TaskFilter
+ */
+ private function filterRecentlyDate($field)
+ {
+ $duration = $this->config->get('board_highlight_period', 0);
+
+ if ($duration > 0) {
+ $this->query->gte($field, time() - $duration);
+ }
return $this;
}
diff --git a/docs/search.markdown b/docs/search.markdown
index 4674a07e..c269b5c1 100644
--- a/docs/search.markdown
+++ b/docs/search.markdown
@@ -31,94 +31,60 @@ Search by assignee
Attribute: **assignee**
-Query with the full name:
+- Query with the full name: `assignee:"Frederic Guillot"`
+- Query with the username: `assignee:fguillot`
+- Multiple assignee lookup: `assignee:user1 assignee:"John Doe"`
+- Query for unassigned tasks: `assignee:nobody`
+- Query for my assigned tasks: `assignee:me`
-```
-assignee:"Frederic Guillot"
-```
-
-Query with the username:
-
-```
-assignee:fguillot
-```
-
-Multiple assignee lookup:
-
-```
-assignee:user1 assignee:"John Doe"
-```
-
-Kanboard will search tasks assigned to the "user1" or "John Doe".
-
-Query for unassigned tasks:
-
-```
-assignee:nobody
-```
-
-Query for my assigned tasks
-
-```
-assignee:me
-```
-
-Note: Results will also include subtasks assignee with the status todo or in progress.
+Note: Kanboard will also search in assigned subtasks with the status todo and in progress.
Search by color
---------------
Attribute: **color**
-Query to search by color id:
-
-```
-color:blue
-```
-
-Query to search by color name:
-
-```
-color:"Deep Orange"
-```
+- Query to search by color id: `color:blue`
+- Query to search by color name: `color:"Deep Orange"`
Search by due date
------------------
Attribute: **due**
-Query to search tasks due today:
+- Search tasks due today: `due:today`
+- Search tasks due tomorrow: `due:tomorrow`
+- Search tasks due yesterday: `due:yesterday`
+- Search tasks due with the exact date: `due:2015-06-29`
-```
-due:today
-```
+The date must use the ISO8601 format: **YYYY-MM-DD**.
-Query to search tasks due tomorrow:
+All string formats supported by the `strtotime()` function are supported, by example `next Thursday`, `-2 days`, `+2 months`, `tomorrow`, etc...
-```
-due:tomorrow
-```
+Operators supported with a date:
-Query to search tasks due yesterday:
+- Greater than: **due:>2015-06-29**
+- Lower than: **due:<2015-06-29**
+- Greater than or equal: **due:>=2015-06-29**
+- Lower than or equal: **due:<=2015-06-29**
-```
-due:yesterday
-```
+Search by modification date
+---------------------------
-Query to search tasks due with the exact date:
+Attribute: **modified** or **updated**
-```
-due:2015-06-29
-```
+The date formats are the same as the due date.
-The date must use the ISO8601 format: **YYYY-MM-DD**.
+There is also a filter by recently modified tasks: `modified:recently`.
-Operators supported:
+This query will use the same value as the board highlight period configured in settings.
-- Greater than: **due:>2015-06-29**
-- Lower than: **due:<2015-06-29**
-- Greater than or equal: **due:>=2015-06-29**
-- Lower than or equal: **due:<=2015-06-29**
+Search by creation date
+-----------------------
+
+Attribute: **created**
+
+Works in the same way as the modification date queries.
Search by description
---------------------
diff --git a/tests/units/LexerTest.php b/tests/units/LexerTest.php
index 8710f79a..3b15810e 100644
--- a/tests/units/LexerTest.php
+++ b/tests/units/LexerTest.php
@@ -311,6 +311,71 @@ class LexerTest extends Base
);
}
+ public function testModifiedQuery()
+ {
+ $lexer = new Lexer;
+
+ $this->assertEquals(
+ array(array('match' => 'modified:', 'token' => 'T_UPDATED'), array('match' => '2015-05-01', 'token' => 'T_DATE')),
+ $lexer->tokenize('modified:2015-05-01')
+ );
+
+ $this->assertEquals(
+ array(array('match' => 'modified:', 'token' => 'T_UPDATED'), array('match' => '<2015-05-01', 'token' => 'T_DATE')),
+ $lexer->tokenize('modified:<2015-05-01')
+ );
+
+ $this->assertEquals(
+ array(array('match' => 'modified:', 'token' => 'T_UPDATED'), array('match' => '>2015-05-01', 'token' => 'T_DATE')),
+ $lexer->tokenize('modified:>2015-05-01')
+ );
+
+ $this->assertEquals(
+ array(array('match' => 'updated:', 'token' => 'T_UPDATED'), array('match' => '<=2015-05-01', 'token' => 'T_DATE')),
+ $lexer->tokenize('updated:<=2015-05-01')
+ );
+
+ $this->assertEquals(
+ array(array('match' => 'updated:', 'token' => 'T_UPDATED'), array('match' => '>=2015-05-01', 'token' => 'T_DATE')),
+ $lexer->tokenize('updated:>=2015-05-01')
+ );
+
+ $this->assertEquals(
+ array(array('match' => 'updated:', 'token' => 'T_UPDATED'), array('match' => 'yesterday', 'token' => 'T_DATE')),
+ $lexer->tokenize('updated:yesterday')
+ );
+
+ $this->assertEquals(
+ array(array('match' => 'updated:', 'token' => 'T_UPDATED'), array('match' => 'tomorrow', 'token' => 'T_DATE')),
+ $lexer->tokenize('updated:tomorrow')
+ );
+
+ $this->assertEquals(
+ array(),
+ $lexer->tokenize('updated:#2015-05-01')
+ );
+
+ $this->assertEquals(
+ array(),
+ $lexer->tokenize('modified:01-05-1024')
+ );
+
+ $this->assertEquals(
+ array('T_UPDATED' => '2015-05-01'),
+ $lexer->map($lexer->tokenize('modified:2015-05-01'))
+ );
+
+ $this->assertEquals(
+ array('T_UPDATED' => '<2015-05-01'),
+ $lexer->map($lexer->tokenize('modified:<2015-05-01'))
+ );
+
+ $this->assertEquals(
+ array('T_UPDATED' => 'today'),
+ $lexer->map($lexer->tokenize('modified:today'))
+ );
+ }
+
public function testMultipleCriterias()
{
$lexer = new Lexer;