diff --git a/api/v1/entries/product.php b/api/v1/entries/product.php index 367e4594e2..9a3628a5fb 100644 --- a/api/v1/entries/product.php +++ b/api/v1/entries/product.php @@ -10,15 +10,40 @@ class productEntry extends Entry { public function get($productID) { + $fields = $this->param('fields'); + $control = $this->loadController('product', 'view'); $control->view($productID); $data = $this->getData(); - if(!$data or (isset($data->message) and $data->message == '404 Not found')) return $this->send404(); - if(isset($data->status) and $data->status == 'success') return $this->send(200, $this->format($data->data->product, 'createdDate:time')); - if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message); + if(!$data or !isset($data->status)) return $this->send400('error'); + if(isset($data->status) and $data->status == 'fail') + { + return isset($data->code) and $data->code == 404 ? $this->send404() : $this->sendError(400, $data->message); + } - $this->sendError(400, 'error'); + $product = $this->format($data->data->product, 'createdDate:time'); + if(!$fields) return $this->send(200, $product); + + /* Set other fields. */ + $fields = explode(',', $fields); + foreach($fields as $field) + { + switch($field) + { + case 'modules': + $control = $this->loadController('tree', 'browse'); + $control->browse($productID, 'story'); + $data = $this->getData(); + if(isset($data->status) and $data->status == 'success') + { + $product->modules = $data->data->tree; + } + break; + } + } + + return $this->send(200, $product); } public function put($productID) diff --git a/api/v1/entries/products.php b/api/v1/entries/products.php index 59c3cc71b8..3e837f2b99 100644 --- a/api/v1/entries/products.php +++ b/api/v1/entries/products.php @@ -10,19 +10,40 @@ class productsEntry extends entry { public function get() { - $control = $this->loadController('product', 'all'); - $control->all($this->param('status', 'all'), $this->param('order', 'order_asc')); - - /* Response */ - $data = $this->getData(); - if(isset($data->status) and $data->status == 'success') + $programID = $this->param('program', 0); + if($programID) { - $result = array(); - $products = $data->data->productStats; - foreach($products as $product) $result[] = $this->format($product, 'createdDate:time'); + $control = $this->loadController('program', 'product'); + $control->product($programID, $this->param('status', 'all'), $this->param('order', 'order_asc'), 0, 10000); - return $this->send(200, array('products' => $result)); + /* Response */ + $data = $this->getData(); + if(isset($data->status) and $data->status == 'success') + { + $result = array(); + $products = $data->data->products; + foreach($products as $product) $result[] = $this->format($product, 'createdDate:time'); + + return $this->send(200, array('products' => $result)); + } } + else + { + $control = $this->loadController('product', 'all'); + $control->all($this->param('status', 'all'), $this->param('order', 'order_asc')); + + /* Response */ + $data = $this->getData(); + if(isset($data->status) and $data->status == 'success') + { + $result = array(); + $products = $data->data->productStats; + foreach($products as $product) $result[] = $this->format($product, 'createdDate:time'); + + return $this->send(200, array('products' => $result)); + } + } + if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message); return $this->sendError(400, 'error'); diff --git a/api/v1/entries/task.php b/api/v1/entries/task.php index eeb7a9ff7f..058646316b 100644 --- a/api/v1/entries/task.php +++ b/api/v1/entries/task.php @@ -14,8 +14,12 @@ class taskEntry extends Entry $control->view($taskID); $data = $this->getData(); - if(!$data or (isset($data->message) and $data->message == '404 Not found')) return $this->send404(); - if(isset($data->status) and $data->status == 'fail') return $this->sendError(400, $data->message); + + if(!$data or !isset($data->status)) return $this->send400('error'); + if(isset($data->status) and $data->status == 'fail') + { + return isset($data->code) and $data->code == 404 ? $this->send404() : $this->sendError(400, $data->message); + } $task = $data->data->task; $this->send(200, $this->format($task, 'openedDate:time,assignedDate:time,realStarted:time,finishedDate:time,canceledDate:time,closedDate:time,lastEditedDate:time')); diff --git a/api/v1/entries/user.php b/api/v1/entries/user.php index 2f265956a6..690dc0a669 100644 --- a/api/v1/entries/user.php +++ b/api/v1/entries/user.php @@ -11,7 +11,7 @@ class userEntry extends Entry public function get($userID = 0) { /* Get my info defaultly. */ - if(!$userID) return $this->getInfo(); + if(!$userID) return $this->getInfo($this->param('fields', '')); /* Get user by id. */ $control = $this->loadController('user', 'profile'); @@ -24,13 +24,73 @@ class userEntry extends Entry $this->send(200, $this->format($user, 'last:time,locked:time')); } - private function getInfo() + /** + * Get my info. + * + * @param string $fields + * + * @access private + * @return void + */ + private function getInfo($fields = '') { - $info = $this->loadModel('my')->getInfo(); + $info = new stdclass(); - $info->product = $this->my->getProducts(); - $info->project = $this->my->getProjects(); - $info->actions = $this->my->getActions(); + $info->profile = $this->loadModel('user')->getById($this->app->user->account); + unset($info->profile->password); + + if(!$fields) return $this->send(200, $info); + + /* Set other fields. */ + $fields = explode(',', $fields); + + $this->loadModel('my'); + foreach($fields as $field) + { + switch($field) + { + case 'product': + $info->product = $this->my->getProducts(); + break; + case 'project': + $info->project = $this->my->getProjects(); + break; + case 'doc': + $info->doc = $this->my->getDocs(); + break; + case 'actions': + $info->actions = $this->my->getActions(); + break; + case 'task': + $info->task = array('count' => 0, 'recentTask' => array()); + + $control = $this->loadController('my', 'task'); + $control->task($this->param('type', 'assignedTo'), $this->param('order', 'id_desc'), $this->param('total', 0), $this->param('limit', 5), $this->param('page', 1)); + $data = $this->getData(); + + if($data->status == 'success') + { + $info->task['count'] = $data->data->pager->recTotal; + $info->task['recentTasks'] = $data->data->tasks; + } + + break; + case 'todo': + $info->todo = array('count' => 0, 'recentTodos' => array()); + + $control = $this->loadController('my', 'todo'); + $control->todo($this->param('date', 'all'), '', 'all', 'date_desc', 0, 0, $this->param('limit', 10), 1); + $data = $this->getData(); + + if($data->status == 'success') + { + $info->todo['count'] = $data->data->pager->recTotal; + $info->todo['recentTodos'] = $data->data->todos; + } + + break; + } + } $this->send(200, $info); } diff --git a/framework/api/entry.class.php b/framework/api/entry.class.php index eb498ec90f..00b81db466 100644 --- a/framework/api/entry.class.php +++ b/framework/api/entry.class.php @@ -248,18 +248,23 @@ class baseEntry */ public function loadController($moduleName, $methodName) { - global $app; - $app->setModuleName($moduleName); - $app->setMethodName($methodName); - $app->setControlFile(); + ob_start(); - /* - * 引入该模块的control文件。 - * Include the control file of the module. - **/ - $file2Included = $app->setActionExtFile() ? $app->extActionFile : $app->controlFile; - chdir(dirname($file2Included)); - helper::import($file2Included); + if(!class_exists($moduleName) and !class_exists("my$moduleName")) + { + global $app; + $app->setModuleName($moduleName); + $app->setMethodName($methodName); + $app->setControlFile(); + + /* + * 引入该模块的control文件。 + * Include the control file of the module. + **/ + $file2Included = $app->setActionExtFile() ? $app->extActionFile : $app->controlFile; + chdir(dirname($file2Included)); + helper::import($file2Included); + } /* * 设置control的类名。 diff --git a/framework/base/router.class.php b/framework/base/router.class.php index bd843fadcf..998053506b 100644 --- a/framework/base/router.class.php +++ b/framework/base/router.class.php @@ -140,6 +140,24 @@ class baseRouter */ public $clientLang; + /** + * 请求的原始模块名。 + * The requestd module name parsed from a URL. + * + * @var string + * @access public + */ + public $rawModule; + + /** + * 请求的原始方法名。 + * The requested method name parsed from a URL. + * + * @var string + * @access public + */ + public $rawMethod; + /** * 当前页面所在的应用,用于左侧菜单栏判断。 * The current app code(url: '#app=?'), highlight left menu. diff --git a/framework/router.class.php b/framework/router.class.php index 07f5135d4c..d482fd3889 100755 --- a/framework/router.class.php +++ b/framework/router.class.php @@ -20,24 +20,6 @@ include dirname(__FILE__) . '/base/router.class.php'; class router extends baseRouter { - /** - * 请求的原始模块名。 - * The requestd module name parsed from a URL. - * - * @var string - * @access public - */ - public $rawModule; - - /** - * 请求的原始方法名。 - * The requested method name parsed from a URL. - * - * @var string - * @access public - */ - public $rawMethod; - /** * 请求的原始参数。 * The requested params parsed from a URL. diff --git a/module/my/model.php b/module/my/model.php index 35c5323d5b..70d7d6de8d 100644 --- a/module/my/model.php +++ b/module/my/model.php @@ -61,14 +61,10 @@ class myModel extends model * Get my charged products. * * @access public - * @return array + * @return object */ public function getProducts() { - $data = new stdClass(); - $countAll = 0; - $countUnclosed = 0; - $products = $this->dao->select('t1.id as id,t1.*')->from(TABLE_PRODUCT)->alias('t1') ->leftJoin(TABLE_PROGRAM)->alias('t2')->on('t1.program = t2.id') ->where('t1.deleted')->eq(0) @@ -109,24 +105,27 @@ class myModel extends model $executions[$key]->progress = ($execution->totalConsumed + $execution->totalLeft) ? floor($execution->totalConsumed / ($execution->totalConsumed + $execution->totalLeft) * 1000) / 1000 * 100 : 0; } + $allCount = count($products); + $unclosedCount = 0; foreach($products as $key => $product) { $product->plans = isset($plans[$product->id]) ? $plans[$product->id] : 0; $product->releases = isset($releases[$product->id]) ? $releases[$product->id] : 0; if(isset($executions[$product->id])) $product->executions = $executions[$product->id]; $product->storyEstimateCount = isset($stories[$product->id]) ? $stories[$product->id] : 0; - $countAll++; - if($product->status != 'closed') $countUnclosed++; + if($product->status != 'closed') $unclosedCount++; if($product->status == 'closed') unset($products[$key]); } - /* Sort by storyCount,get five record */ + /* Sort by storyCount, get 5 records */ array_multisort(array_column($products, 'storyEstimateCount'), SORT_DESC, $products); $products = array_slice($products, 0, 5); - $data->count_all = $countAll; - $data->count_unclosed = $countUnclosed; - $data->products = array_values($products); + $data = new stdClass(); + $data->allCount = $allCount; + $data->unclosedCount = $unclosedCount; + $data->products = array_values($products); + return $data; } @@ -134,43 +133,59 @@ class myModel extends model * Get my projects. * * @access public - * @return array + * @return object */ public function getProjects() - { + { $data = new stdClass(); - $countDoing = 0; - $consumedAll = 0; - $consumedThisYear = 0; + $allConsumed = 0; + $thisYearConsumed = 0; $doingProjects = array(); $projects = $this->loadModel('project')->getOverviewList('byStatus', 'all', 'id_desc'); $projectsConsumed = $this->project->getProjectsConsumed(array_keys($projects), 'this_year'); + $doingCount = 0; foreach($projects as $key => $project) { if($project->status == 'doing') { - $countDoing++; + $doingCount++; $workhour = $this->project->getWorkhour($project->id); $projects[$key]->progress = ($workhour->totalConsumed + $workhour->totalLeft) ? floor($workhour->totalConsumed / ($workhour->totalConsumed + $workhour->totalLeft) * 1000) / 1000 * 100 : 0; $doingProjects[] = $projects[$key]; } - $consumedAll += $project->consumed; - $consumedThisYear += $projectsConsumed[$project->id]->totalConsumed; + $allConsumed += $project->consumed; + $thisYearConsumed += $projectsConsumed[$project->id]->totalConsumed; } /* Sort by consumed,get five record */ array_multisort(array_column($doingProjects, 'consumed'), SORT_DESC, $doingProjects); $doingProjects = array_slice($doingProjects, 0, 5); - $data->count_all = count($projects); - $data->count_doing = $countDoing; - $data->consumed_all = $consumedAll; - $data->consumed_this_year = $consumedThisYear; + $data->allCount = count($projects); + $data->doingCount = $doingCount; + $data->allConsumed = $allConsumed; + $data->thisYearConsumed = $thisYearConsumed; $data->projects = $doingProjects; + return $data; } + /** + * Get my doc. + * + * @access public + * @return object + */ + public function getDocs() + { + /* Get count of docs created by me. */ + $doc = new stdclass(); + $doc->createdCount = $this->dao->select('count(*) AS count')->from(TABLE_DOC)->where('addedBy')->eq($this->app->user->account)->andWhere('deleted')->eq('0')->fetch('count'); + + return $doc; + } + /** * Get latest actions. * @@ -180,161 +195,12 @@ class myModel extends model public function getActions() { $actions = $this->loadModel('action')->getDynamic('all', 'today', 'date_desc'); - $users = $this->loadModel('user')->getPairs('noletter'); + $users = $this->loadModel('user')->getPairs('noletter'); foreach($actions as $key => $action) { $actions[$key]->actor = $users[$action->actor]; } + return $actions; } - - /** - * Get my info. - * - * @access public - * @return object - */ - public function getInfo() - { - $info = new stdclass(); - $info->profile = $this->loadModel('user')->getById($this->app->user->account); - - /* My tasks. */ - $info->task = new stdclass(); - $info->task->total = (int) $this->dao->select('count(*) AS count')->from(TABLE_TASK)->where('assignedTo')->eq($this->app->user->account)->andWhere('status')->ne('closed')->andWhere('deleted')->eq(0)->fetch('count'); - $info->task->dynamic = array(); - - if(common::hasPriv('task', 'view')) - { - $tasks = $this->dao->select('*')->from(TABLE_TASK) - ->where('assignedTo')->eq($this->app->user->account) - ->andWhere('deleted')->eq('0') - ->andWhere('status')->ne('closed') - ->orderBy('id_desc') - ->limit(3) - ->fetchAll(); - $info->task->dynamic = $tasks; - } - - /* My stories. */ - $info->story = new stdclass(); - $info->story->total = (int) $this->dao->select('count(*) AS count')->from(TABLE_STORY)->where('assignedTo')->eq($this->app->user->account)->andWhere('status')->ne('closed')->andWhere('deleted')->eq(0)->andWhere('type')->eq('story')->fetch('count'); - $info->story->dynamic = array(); - if(common::hasPriv('story', 'view')) - { - $stories = $this->dao->select('*')->from(TABLE_STORY) - ->where('assignedTo')->eq($this->app->user->account) - ->andWhere('deleted')->eq('0') - ->andWhere('status')->ne('closed') - ->orderBy('id_desc') - ->limit(3) - ->fetchAll(); - $info->story->dynamic = $stories; - } - - /* My bugs. */ - $info->bug = new stdclass(); - $info->bug->total = (int) $this->dao->select('count(*) AS count')->from(TABLE_BUG)->where('assignedTo')->eq($this->app->user->account)->andWhere('status')->ne('closed')->andWhere('deleted')->eq(0)->fetch('count'); - $info->bug->dynamic = array(); - if(common::hasPriv('bug', 'view')) - { - $this->app->loadLang('bug'); - $bugs = $this->dao->select('*')->from(TABLE_BUG) - ->where('assignedTo')->eq($this->app->user->account) - ->andWhere('deleted')->eq('0') - ->andWhere('status')->ne('closed') - ->orderBy('id_desc') - ->limit(3) - ->fetchAll(); - $info->bug->dynamic = $bugs; - } - - /* My todos. */ - $info->todo = new stdclass(); - $info->todo->total = (int) $this->dao->select('count(*) AS count')->from(TABLE_TODO)->where('assignedTo')->eq($this->app->user->account)->andWhere('status')->ne('closed')->andWhere('deleted')->eq(0)->fetch('count'); - $info->todo->dynamic = array(); - if(common::hasPriv('todo', 'view')) - { - $this->app->loadClass('date'); - $todos = $this->dao->select('*')->from(TABLE_TODO) - ->where('assignedTo')->eq($this->app->user->account) - ->andWhere('cycle')->eq(0) - ->andWhere('deleted')->eq(0) - ->andWhere('status')->eq('wait') - ->orderBy('`date` desc') - ->limit(3) - ->fetchAll(); - foreach($todos as $key => $todo) - { - $todo->begin = date::formatTime($todo->begin); - $todo->end = date::formatTime($todo->end); - } - $info->todo->dynamic = $todos; - } - - /* My risks. */ - $info->risk = new stdclass(); - $info->risk->total = 0; - $info->risk->dynamic = array(); - if(common::hasPriv('risk', 'view') and isset($this->config->maxVersion)) - { - $risks = $this->dao->select('*')->from(TABLE_RISK) - ->where('assignedTo')->eq($this->app->user->account) - ->andWhere('deleted')->eq('0') - ->andWhere('status')->ne('closed') - ->orderBy('id_desc') - ->limit(3) - ->fetchAll(); - $info->risk->total = (int) $this->dao->select('count(*) AS count')->from(TABLE_RISK)->where('assignedTo')->eq($this->app->user->account)->andWhere('status')->ne('closed')->andWhere('deleted')->eq(0)->fetch('count'); - $info->risk->dynamic = $risks; - } - - /* My meetings. */ - $info->meeting = new stdclass(); - $info->meeting->total = 0; - $info->meeting->dynamic = array(); - if(common::hasPriv('meeting', 'view') and isset($this->config->maxVersion)) - { - $today = helper::today(); - $now = date('H:i:s', strtotime(helper::now())); - - $meetings = $this->dao->select('*')->from(TABLE_MEETING) - ->Where('deleted')->eq('0') - ->andWhere('(date')->gt($today) - ->orWhere('(begin')->gt($now) - ->andWhere('date')->eq($today) - ->markRight(2) - ->andwhere('(host')->eq($this->app->user->account) - ->orWhere('participant')->in($this->app->user->account) - ->markRight(1) - ->orderBy('id_desc') - ->fetchAll(); - $info->meeting->total = count($meetings); - $info->meeting->dynamic = array_slice($meetings, 0, 3); - } - - /* My issues. */ - $info->issue = new stdclass(); - $info->issue->total = 0; - $info->issue->dynamic = array(); - if(common::hasPriv('issue', 'view') and isset($this->config->maxVersion)) - { - $issues = $this->dao->select('*')->from(TABLE_ISSUE) - ->where('assignedTo')->eq($this->app->user->account) - ->andWhere('deleted')->eq('0') - ->andWhere('status')->ne('closed') - ->orderBy('id_desc') - ->limit(3) - ->fetchAll(); - $info->issue->total = (int) $this->dao->select('count(*) AS count')->from(TABLE_ISSUE)->where('assignedTo')->eq($this->app->user->account)->andWhere('status')->ne('closed')->andWhere('deleted')->eq(0)->fetch('count'); - $info->issue->dynamic = $issues; - } - - /* Get count of docs created by me. */ - $info->doc = new stdclass(); - $info->doc->total = $this->dao->select('count(*) AS count')->from(TABLE_DOC)->where('addedBy')->eq($this->app->user->account)->andWhere('deleted')->eq('0')->fetch('count'); - - return $info; - } - } diff --git a/module/product/control.php b/module/product/control.php index ac802686b3..1929604363 100644 --- a/module/product/control.php +++ b/module/product/control.php @@ -694,7 +694,7 @@ class product extends control if(!$product) { - if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'message' => '404 Not found')); + if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'code' => 404, 'message' => '404 Not found')); die(js::error($this->lang->notFound) . js::locate('back')); } diff --git a/module/task/control.php b/module/task/control.php index f1196f7e74..55285058f8 100644 --- a/module/task/control.php +++ b/module/task/control.php @@ -674,7 +674,7 @@ class task extends control $task = $this->task->getById($taskID, true); if(!$task) { - if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'message' => '404 Not found')); + if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'code' => 404, 'message' => '404 Not found')); die(js::error($this->lang->notFound) . js::locate('back')); } $this->session->project = $task->project; diff --git a/module/todo/model.php b/module/todo/model.php index ca4af5fc80..94ef901090 100644 --- a/module/todo/model.php +++ b/module/todo/model.php @@ -553,6 +553,7 @@ class todoModel extends model $todos[] = $todo; } + return $todos; }