diff --git a/api/v1/entries/projectissue.php b/api/v1/entries/productissue.php similarity index 96% rename from api/v1/entries/projectissue.php rename to api/v1/entries/productissue.php index 2e88f2bae9..1546897052 100644 --- a/api/v1/entries/projectissue.php +++ b/api/v1/entries/productissue.php @@ -1,18 +1,17 @@ loadModel('entry'); - $this->setParam('timeFormat', 'utc'); $idParams = explode('-', $issueID); if(count($idParams) < 2) $this->sendError(400, 'The id of issue is wrong.'); diff --git a/api/v1/entries/projectissues.php b/api/v1/entries/productissues.php similarity index 65% rename from api/v1/entries/projectissues.php rename to api/v1/entries/productissues.php index 8665b880ff..1957e2538b 100644 --- a/api/v1/entries/projectissues.php +++ b/api/v1/entries/productissues.php @@ -1,19 +1,17 @@ sendError(400, 'The project_id is not supported'); - - $this->setParam('timeFormat', 'utc'); + if(!is_numeric($productID)) $this->sendError(400, 'The productt_id is not supported'); $taskFields = 'id,status'; $taskStatus = array('' => ''); @@ -32,12 +30,14 @@ class projectIssuesEntry extends entry $productID = (int)$productID; $status = $this->param('status', ''); - $label = $this->param('label', ''); $search = $this->param('search', ''); $page = intval($this->param('page', 1)); $limit = intval($this->param('limit', 20)); $order = $this->param('order', 'openedDate_desc'); + $labels = $this->param('labels', ''); + $labels = $labels ? explode(',', $labels) : array(); + $orderParams = explode('_', $order); $order = $orderParams[0]; $sort = (isset($orderParams[1]) and strtolower($orderParams[1]) == 'asc') ? 'asc' : 'desc'; @@ -68,35 +68,75 @@ class projectIssuesEntry extends entry $issues = array(); - $executions = $this->dao->select('project')->from(TABLE_PROJECTPRODUCT)->where('product')->eq($productID)->fetchPairs(); - $tasks = $this->dao->select($taskFields)->from(TABLE_TASK)->where('execution')->in(array_values($executions)) - ->beginIF($search)->andWhere('name')->like("%$search%")->fi() - ->beginIF($label)->andWhere('type')->eq($label)->fi() - ->beginIF($status)->andWhere('status')->in($taskStatus[$status])->fi() - ->andWhere('deleted')->eq(0) - ->fetchAll(); - foreach($tasks as $task) $issues[] = array('id' => $task->id, 'type' => 'task', 'order' => $task->$order, 'status' => $this->getKey($task->status, $taskStatus)); + $storyFilter = array(); + $bugFilter = array(); + $taskFilter = array(); - $stories = $this->dao->select($storyFields)->from(TABLE_STORY)->where('product')->eq($productID) - ->beginIF($search)->andWhere('title')->like("%$search%")->fi() - ->beginIF($label)->andWhere('type')->eq($label)->fi() - ->beginIF($status)->andWhere('status')->in($storyStatus[$status])->fi() - ->andWhere('deleted')->eq(0) - ->fetchAll(); - foreach($stories as $story) + if(empty($labels)) { - $issues[] = array('id' => $story->id, 'type' => 'story', 'order' => $story->$order, 'status' => $this->getKey($story->status, $storyStatus)); + $storyFilter[] = 'all'; + $bugFilter[] = 'all'; + $taskFilter[] = 'all'; + } + else + { + $this->app->loadLang('story'); + $this->app->loadLang('task'); + $this->app->loadLang('bug'); + + $storyTypeMap = array_flip($this->app->lang->story->categoryList); + $taskTypeMap = array_flip($this->app->lang->task->typeList); + $bugTypeMap = array_flip($this->app->lang->bug->typeList); + foreach($labels as $label) + { + if($label == $this->app->lang->story->common) $storyFilter = array('all'); + if(isset($storyTypeMap[$label]) and $storyFilter != array('all')) $storyFilter[] = $storyTypeMap[$label]; + + if($label == $this->app->lang->task->common) $taskFilter = array('all'); + if(isset($taskTypeMap[$label]) and $taskFilter != array('all')) $taskFilter[] = $taskTypeMap[$label]; + + if($label == $this->app->lang->bug->common) $bugFilter = array('all'); + if(isset($bugTypeMap[$label]) and $bugFilter != array('all')) $bugFilter[] = $bugTypeMap[$label]; + } + } + $storyFilter = implode(',', $storyFilter); + $taskFilter = implode(',', $taskFilter); + $bugFilter = implode(',', $bugFilter); + + $executions = $this->dao->select('project')->from(TABLE_PROJECTPRODUCT)->where('product')->eq($productID)->fetchPairs(); + if($taskFilter) + { + $tasks = $this->dao->select($taskFields)->from(TABLE_TASK)->where('execution')->in(array_values($executions)) + ->beginIF($search)->andWhere('name')->like("%$search%")->fi() + ->beginIF($status)->andWhere('status')->in($taskStatus[$status])->fi() + ->beginIF($taskFilter != 'all')->andWhere('type')->in($taskFilter)->fi() + ->andWhere('deleted')->eq(0) + ->fetchAll(); + foreach($tasks as $task) $issues[] = array('id' => $task->id, 'type' => 'task', 'order' => $task->$order, 'status' => $this->getKey($task->status, $taskStatus)); } - $bugs = $this->dao->select($bugFields)->from(TABLE_BUG)->where('product')->eq($productID) - ->beginIF($search)->andWhere('title')->like("%$search%")->fi() - ->beginIF($label)->andWhere('type')->eq($label)->fi() - ->beginIF($status)->andWhere('status')->in($bugStatus[$status])->fi() - ->andWhere('deleted')->eq(0) - ->fetchAll(); - foreach($bugs as $bug) + if($storyFilter) { - $issues[] = array('id' => $bug->id, 'type' => 'bug', 'order' => $bug->$order, 'status' => $this->getKey($bug->status, $bugStatus)); + $stories = $this->dao->select($storyFields)->from(TABLE_STORY) + ->where('product')->eq($productID) + ->beginIF($search)->andWhere('title')->like("%$search%")->fi() + ->beginIF($status)->andWhere('status')->in($storyStatus[$status])->fi() + ->beginIF($storyFilter != 'all')->andWhere('category')->in($storyFilter)->fi() + ->andWhere('deleted')->eq(0) + ->fetchAll(); + foreach($stories as $story) $issues[] = array('id' => $story->id, 'type' => 'story', 'order' => $story->$order, 'status' => $this->getKey($story->status, $storyStatus)); + } + + if($bugFilter) + { + $bugs = $this->dao->select($bugFields)->from(TABLE_BUG) + ->where('product')->eq($productID) + ->beginIF($search)->andWhere('title')->like("%$search%")->fi() + ->beginIF($status)->andWhere('status')->in($bugStatus[$status])->fi() + ->beginIF($bugFilter != 'all')->andWhere('type')->in($bugFilter)->fi() + ->andWhere('deleted')->eq(0) + ->fetchAll(); + foreach($bugs as $bug) $issues[] = array('id' => $bug->id, 'type' => 'bug', 'order' => $bug->$order, 'status' => $this->getKey($bug->status, $bugStatus)); } array_multisort(array_column($issues, 'order'), $sort == 'asc' ? SORT_ASC : SORT_DESC, $issues); @@ -118,8 +158,8 @@ class projectIssuesEntry extends entry */ public function processIssues($issues) { - $this->app->loadLang('task'); $this->app->loadLang('story'); + $this->app->loadLang('task'); $this->app->loadLang('bug'); $this->loadModel('entry'); diff --git a/api/v1/entries/projects.php b/api/v1/entries/projects.php index d0d886679d..f0480dce7d 100644 --- a/api/v1/entries/projects.php +++ b/api/v1/entries/projects.php @@ -30,6 +30,7 @@ class projectsEntry extends entry return $this->sendError(400, $data->message); } + // TODO There is no handle for 401. return $this->sendError(400, 'error'); } diff --git a/config/routes.php b/config/routes.php index d6e179ea37..985f82dc15 100644 --- a/config/routes.php +++ b/config/routes.php @@ -38,8 +38,8 @@ $routes['/user'] = 'user'; $routes['/programs'] = 'programs'; $routes['/programs/:id'] = 'program'; -$routes['/issues/:issueID'] = 'projectIssue'; -$routes['/projects/:projectID/issues'] = 'projectIssues'; +$routes['/issues/:issueID'] = 'productIssue'; +$routes['/products/:productID/issues'] = 'productIssues'; $routes['/my'] = 'my'; diff --git a/framework/api/entry.class.php b/framework/api/entry.class.php index f48391751a..9ba11620b8 100644 --- a/framework/api/entry.class.php +++ b/framework/api/entry.class.php @@ -82,7 +82,7 @@ class baseEntry */ public function param($key, $defaultValue = '') { - if(isset($_GET[$key])) return $_GET[$key]; + if(isset($_GET[$key])) return trim($_GET[$key]); return $defaultValue; } @@ -496,7 +496,7 @@ class baseEntry switch($type) { case 'time': - $timeFormat = $this->param('timeFormat', ''); + $timeFormat = $this->param('timeFormat', 'utc'); if($timeFormat == 'utc') { if(!$value or $value == '0000-00-00 00:00:00') return null;