0) $this->session->set('program', (int)$programID); if($programID == 0 and $this->cookie->lastProgram) $this->session->set('program', (int)$this->cookie->lastProgram); if($programID == 0 and $this->session->program == '') $this->session->set('program', key($programs)); if(!isset($programs[$this->session->program])) { $this->session->set('program', key($programs)); if($programID && strpos(",{$this->app->user->view->programs},", ",{$this->session->program},") === false) $this->accessDenied(); } return $this->session->program; } /** * Get program pairs. * * @param bool $isQueryAll * @access public * @return array */ public function getPairs($isQueryAll = false) { return $this->dao->select('id, name')->from(TABLE_PROGRAM) ->where('type')->eq('program') ->andWhere('deleted')->eq(0) ->beginIF(!$this->app->user->admin and !$isQueryAll)->andWhere('id')->in($this->app->user->view->programs)->fi() ->fetchPairs(); } /** * Get the product associated with the program. * * @param int $programID * @param string $mode all|assign * @param string $status all|noclosed * @access public * @return array */ public function getProductPairs($programID = 0, $mode = 'assign', $status = 'all') { /* Get the top programID. */ if($programID) { $program = $this->getByID($programID); $path = explode(',', $program->path); $path = array_filter($path); $programID = current($path); } /* When mode equals assign and programID equals 0, you can query the standalone product. */ $products = $this->dao->select('*')->from(TABLE_PRODUCT) ->where('deleted')->eq(0) ->beginIF($mode == 'assign')->andWhere('program')->eq($programID)->fi() ->beginIF(strpos($status, 'noclosed') !== false)->andWhere('status')->ne('closed')->fi() ->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->products)->fi() ->fetchPairs('id', 'name'); return $products; } /** * Get program by id. * * @param int $programID * @access public * @return array */ public function getByID($programID = 0) { return $this->dao->select('*')->from(TABLE_PROGRAM)->where('id')->eq($programID)->andWhere('`type`')->eq('program')->fetch(); } /** * Get program list. * * @param string $status * @param string $orderBy * @param object $pager * @access public * @return array */ public function getList($status = 'all', $orderBy = 'id_asc', $pager = NULL) { return $this->dao->select('*')->from(TABLE_PROGRAM) ->where('type')->in('program,project') ->andWhere('deleted')->eq(0) ->beginIF(!$this->app->user->admin) ->andWhere('(id')->in($this->app->user->view->programs) ->orWhere('id')->in($this->app->user->view->projects) ->markRight(1) ->fi() ->beginIF($status != 'all')->andWhere('status')->eq($status)->fi() ->beginIF(!$this->cookie->showClosed)->andWhere('status')->ne('closed')->fi() ->orderBy($orderBy) ->page($pager) ->fetchAll('id'); } /** * Get project list data. * * @param int $programID * @param string $browseType * @param string $queryID * @param string $orderBy * @param object $pager * @param int $programTitle * @param int $involved * @access public * @return object */ public function getProjectList($programID = 0, $browseType = 'all', $queryID = 0, $orderBy = 'id_desc', $pager = null, $programTitle = 0, $involved = 0) { $path = ''; if($programID) { $program = $this->getByID($programID); $path = $program->path; } $projectList = $this->dao->select('*')->from(TABLE_PROJECT) ->where('deleted')->eq('0') ->beginIF($this->config->systemMode == 'new')->andWhere('type')->eq('project')->fi() ->beginIF($browseType != 'all')->andWhere('status')->eq($browseType)->fi() ->beginIF($path)->andWhere('path')->like($path . '%')->fi() ->beginIF(!$this->app->user->admin and $this->config->systemMode == 'new')->andWhere('id')->in($this->app->user->view->projects)->fi() ->beginIF(!$this->app->user->admin and $this->config->systemMode == 'classic')->andWhere('id')->in($this->app->user->view->sprints)->fi() ->beginIF($this->cookie->involved or $involved) ->andWhere('openedBy', true)->eq($this->app->user->account) ->orWhere('PM')->eq($this->app->user->account) ->markRight(1) ->fi() ->orderBy($orderBy) ->page($pager) ->fetchAll('id'); /* Determine how to display the name of the program. */ if($programTitle and $this->config->systemMode == 'new') { $programList = $this->getPairs(); foreach($projectList as $id => $project) { $path = explode(',', $project->path); $path = array_filter($path); array_pop($path); $programID = $programTitle == 'base' ? current($path) : end($path); if(empty($path) || $programID == $id) continue; $programName = isset($programList[$programID]) ? $programList[$programID] : ''; $projectList[$id]->name = $programName . '/' . $projectList[$id]->name; } } return $projectList; } /** * Get stakeholders by program id. * * @param int $programID * @param string $orderBy * @param object $paper * @access public * @return array */ public function getStakeholders($programID = 0, $orderBy, $pager = null) { return $this->dao->select('t2.account,t2.realname,t2.role,t2.qq,t2.mobile,t2.phone,t2.weixin,t2.email,t1.id,t1.type,t1.key')->from(TABLE_STAKEHOLDER)->alias('t1') ->leftJoin(TABLE_USER)->alias('t2')->on('t1.user=t2.account') ->where('t1.objectID')->eq($programID) ->andWhere('t1.objectType')->eq('program') ->orderBy($orderBy) ->page($pager) ->fetchAll(); } /** * Get stakeholders by program id list. * * @param string $programIdList * @access public * @return array */ public function getStakeholdersByPrograms($programIdList = 0) { return $this->dao->select('distinct user as account')->from(TABLE_STAKEHOLDER) ->where('objectID')->in($programIdList) ->andWhere('objectType')->eq('program') ->fetchAll(); } /** * Create a program. * * @access private * @return int|bool */ public function create() { $program = fixer::input('post') ->setDefault('status', 'wait') ->setDefault('openedBy', $this->app->user->account) ->setDefault('parent', 0) ->setDefault('openedDate', helper::now()) ->setIF($this->post->acl == 'open', 'whitelist', '') ->setIF($this->post->delta == 999, 'end', LONG_TIME) ->setIF($this->post->budget != 0, 'budget', round($this->post->budget, 2)) ->add('type', 'program') ->join('whitelist', ',') ->stripTags($this->config->program->editor->create['id'], $this->config->allowedTags) ->remove('delta,future') ->get(); if($program->parent) { $parentProgram = $this->dao->select('*')->from(TABLE_PROGRAM)->where('id')->eq($program->parent)->fetch(); if($parentProgram) { /* Child program begin cannot less than parent. */ if($program->begin < $parentProgram->begin) dao::$errors['begin'] = sprintf($this->lang->program->beginLetterParent, $parentProgram->begin); /* When parent set end then child program end cannot greater than parent. */ if($parentProgram->end != '0000-00-00' and $program->end > $parentProgram->end) dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end); /* When parent set end then child program cannot set longTime. */ if(empty($program->end) and $this->post->delta == 999 and $parentProgram->end != '0000-00-00') dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end); /* The budget of a child program cannot beyond the remaining budget of the parent program. */ $program->budgetUnit = $parentProgram->budgetUnit; if(isset($program->budget) and $parentProgram->budget != 0) { $availableBudget = $this->getBudgetLeft($parentProgram); if($program->budget > $availableBudget) dao::$errors['budget'] = $this->lang->program->beyondParentBudget; } if(dao::isError()) return false; } } /* Redefines the language entries for the fields in the project table. */ foreach(explode(',', $this->config->program->create->requiredFields) as $field) { if(isset($this->lang->program->$field)) $this->lang->project->$field = $this->lang->program->$field; } $program = $this->loadModel('file')->processImgURL($program, $this->config->program->editor->create['id'], $this->post->uid); $this->dao->insert(TABLE_PROGRAM)->data($program) ->autoCheck() ->batchcheck($this->config->program->create->requiredFields, 'notempty') ->checkIF($program->begin != '', 'begin', 'date') ->checkIF($program->end != '', 'end', 'date') ->checkIF($program->end != '', 'end', 'gt', $program->begin) ->checkIF(!empty($program->name), 'name', 'unique') ->exec(); if(!dao::isError()) { $programID = $this->dao->lastInsertId(); $this->dao->update(TABLE_PROGRAM)->set('`order`')->eq($programID * 5)->where('id')->eq($programID)->exec(); // Save order. $whitelist = explode(',', $program->whitelist); $this->loadModel('personnel')->updateWhitelist($whitelist, 'program', $programID); if($program->acl != 'open') $this->loadModel('user')->updateUserView($programID, 'program'); $this->file->updateObjectID($this->post->uid, $programID, 'program'); $this->setTreePath($programID); return $programID; } } /** * Update program. * * @param int $programID * @access public * @return array|bool */ public function update($programID) { $programID = (int)$programID; $oldProgram = $this->dao->findById($programID)->from(TABLE_PROGRAM)->fetch(); $program = fixer::input('post') ->setDefault('team', $this->post->name) ->setDefault('end', '') ->setIF($this->post->begin == '0000-00-00', 'begin', '') ->setIF($this->post->end == '0000-00-00', 'end', '') ->setIF($this->post->acl == 'open', 'whitelist', '') ->setIF($this->post->delta == 999, 'end', LONG_TIME) ->setIF($this->post->future, 'budget', 0) ->setIF($this->post->budget != 0, 'budget', round($this->post->budget, 2)) ->join('whitelist', ',') ->stripTags($this->config->program->editor->edit['id'], $this->config->allowedTags) ->remove('uid,delta,future') ->get(); $program = $this->loadModel('file')->processImgURL($program, $this->config->program->editor->edit['id'], $this->post->uid); $children = $this->getChildren($programID); if($children > 0) { $minChildBegin = $this->dao->select('min(begin) as minBegin')->from(TABLE_PROGRAM)->where('id')->ne($programID)->andWhere('deleted')->eq(0)->andWhere('path')->like("%,{$programID},%")->fetch('minBegin'); $maxChildEnd = $this->dao->select('max(end) as maxEnd')->from(TABLE_PROGRAM)->where('id')->ne($programID)->andWhere('deleted')->eq(0)->andWhere('path')->like("%,{$programID},%")->andWhere('end')->ne('0000-00-00')->fetch('maxEnd'); if($minChildBegin and $program->begin > $minChildBegin) dao::$errors['begin'] = sprintf($this->lang->program->beginGreateChild, $minChildBegin); if($maxChildEnd and $program->end < $maxChildEnd and $this->post->delta != 999) dao::$errors['end'] = sprintf($this->lang->program->endLetterChild, $maxChildEnd); } if($program->parent) { $parentProgram = $this->dao->select('*')->from(TABLE_PROGRAM)->where('id')->eq($program->parent)->fetch(); if($parentProgram) { if($program->begin < $parentProgram->begin) dao::$errors['begin'] = sprintf($this->lang->program->beginLetterParent, $parentProgram->begin); if($parentProgram->end != '0000-00-00' and $program->end > $parentProgram->end) dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end); if(empty($program->end) and $this->post->delta == 999 and $parentProgram->end != '0000-00-00') dao::$errors['end'] = sprintf($this->lang->program->endGreaterParent, $parentProgram->end); } /* The budget of a child program cannot beyond the remaining budget of the parent program. */ $program->budgetUnit = $parentProgram->budgetUnit; if($program->budget != 0 and $parentProgram->budget != 0) { $availableBudget = $this->getBudgetLeft($parentProgram); if($program->budget > $availableBudget + $oldProgram->budget) dao::$errors['budget'] = $this->lang->program->beyondParentBudget; } } if(dao::isError()) return false; /* Redefines the language entries for the fields in the project table. */ foreach(explode(',', $this->config->program->edit->requiredFields) as $field) { if(isset($this->lang->program->$field)) $this->lang->project->$field = $this->lang->program->$field; } $this->dao->update(TABLE_PROGRAM)->data($program) ->autoCheck($skipFields = 'begin,end') ->batchcheck($this->config->program->edit->requiredFields, 'notempty') ->checkIF($program->begin != '', 'begin', 'date') ->checkIF($program->end != '', 'end', 'date') ->checkIF($program->end != '', 'end', 'gt', $program->begin) ->check('name', 'unique', "id!=$programID and deleted='0'") ->where('id')->eq($programID) ->limit(1) ->exec(); if(!dao::isError()) { $this->file->updateObjectID($this->post->uid, $programID, 'project'); $whitelist = explode(',', $program->whitelist); $this->loadModel('personnel')->updateWhitelist($whitelist, 'program', $programID); if($program->acl != 'open') $this->loadModel('user')->updateUserView($programID, 'program'); if($oldProgram->parent != $program->parent) $this->processNode($programID, $program->parent, $oldProgram->path, $oldProgram->grade); return common::createChanges($oldProgram, $program); } } /* * Get program swapper. * * @param int $programID * @access private * @return string */ public function getSwitcher($programID = 0) { $currentProgramName = ''; $currentModule = $this->app->moduleName; $currentMethod = $this->app->methodName; if($programID) { setCookie("lastProgram", $programID, $this->config->cookieLife, $this->config->webRoot, '', false, true); $currentProgram = $this->getById($programID); $currentProgramName = $currentProgram->name; } else { $currentProgramName = $this->lang->program->all; } $dropMenuLink = helper::createLink('program', 'ajaxGetDropMenu', "objectID=$programID&module=$currentModule&method=$currentMethod"); $output = "