diff --git a/module/design/control.php b/module/design/control.php index 0916bc666f..d782c7f3a3 100755 --- a/module/design/control.php +++ b/module/design/control.php @@ -121,6 +121,7 @@ class design extends control $this->view->orderBy = $orderBy; $this->view->pager = $pager; $this->view->users = $this->loadModel('user')->getPairs('noletter'); + $this->view->project = $project; $this->display(); } diff --git a/module/design/ui/browse.html.php b/module/design/ui/browse.html.php index 7c5ba86b56..5fe4bc36a8 100644 --- a/module/design/ui/browse.html.php +++ b/module/design/ui/browse.html.php @@ -21,8 +21,9 @@ featureBar ); /* zin: Define the toolbar on main menu. */ -$canCreate = hasPriv('design', 'create'); -$canBatchCreate = hasPriv('design', 'batchCreate'); +$canBeChanged = common::canModify('project', $project); +$canCreate = $canBeChanged && hasPriv('design', 'create'); +$canBatchCreate = $canBeChanged && hasPriv('design', 'batchCreate'); $createItem = array('text' => $lang->design->create, 'url' => helper::createLink('design', 'create', "projectID={$projectID}&productID={$productID}&type={$type}")); $batchCreateItem = array('text' => $lang->design->batchCreate, 'url' => helper::createLink('design', 'batchCreate', "projectID={$projectID}&productID={$productID}&type={$type}")); toolbar diff --git a/module/product/ui/browse.html.php b/module/product/ui/browse.html.php index f40803d285..3c6e738b45 100644 --- a/module/product/ui/browse.html.php +++ b/module/product/ui/browse.html.php @@ -68,6 +68,7 @@ $fnGenerateSideBar = function() use ($moduleTree, $moduleID, $productID, $branch $fnBuildCreateStoryButton = function() use ($lang, $product, $isProjectStory, $storyType, $productID, $branch, $moduleID, $projectID, $project, $projectProducts) { if(!common::canModify('product', $product)) return null; + if(!empty($project) && !common::canModify('project', $project)) return null; global $app, $config; $currentProductID = empty($productID) ? current(array_keys($projectProducts)) : $productID; @@ -162,6 +163,7 @@ $fnBuildCreateStoryButton = function() use ($lang, $product, $isProjectStory, $s $fnBuildLinkStoryButton = function() use($lang, $app, $product, $projectHasProduct, $project, $storyType) { if(!common::canModify('product', $product)) return null; + if(!empty($project) && !common::canModify('project', $project)) return null; if(!$projectHasProduct) return null; @@ -236,13 +238,14 @@ $fnGenerateFootToolbar = function() use ($lang, $app, $product, $productID, $pro { /* Flag variables of permissions. */ $canBeChanged = common::canModify('product', $product); + if(!empty($project)) $canBeChanged = $canBeChanged && common::canModify('project', $project); if($isProjectStory && $config->vision == 'rnd') { - $canBatchClose = hasPriv('projectstory', 'batchClose') && strtolower($browseType) != 'closedbyme'; - $canBatchEdit = hasPriv('projectstory', 'batchEdit'); - $canBatchReview = hasPriv('projectstory', 'batchReview'); - $canBatchAssignTo = hasPriv('projectstory', 'batchAssignTo'); - $canBatchChangePlan = hasPriv('projectstory', 'batchChangePlan') && $productID && $product; + $canBatchClose = $canBeChanged && hasPriv('projectstory', 'batchClose') && strtolower($browseType) != 'closedbyme'; + $canBatchEdit = $canBeChanged && hasPriv('projectstory', 'batchEdit'); + $canBatchReview = $canBeChanged && hasPriv('projectstory', 'batchReview'); + $canBatchAssignTo = $canBeChanged && hasPriv('projectstory', 'batchAssignTo'); + $canBatchChangePlan = $canBeChanged && hasPriv('projectstory', 'batchChangePlan') && $productID && $product; } else { diff --git a/module/programplan/ui/browse.html.php b/module/programplan/ui/browse.html.php index b61349b693..b6560dfcbf 100644 --- a/module/programplan/ui/browse.html.php +++ b/module/programplan/ui/browse.html.php @@ -20,7 +20,7 @@ if(empty($plans)) ( setClass('table-empty-tip'), span(setClass('muted'), $lang->programplan->noData), - common::hasPriv('programplan', 'create') ? btn(setClass('info'), set::url($this->createLink('programplan', 'create', "projectID=$projectID&productID=$productID")), icon('plus'), $lang->programplan->create) : null + common::canModify('project', $project) && common::hasPriv('programplan', 'create') ? btn(setClass('info'), set::url($this->createLink('programplan', 'create', "projectID=$projectID&productID=$productID")), icon('plus'), $lang->programplan->create) : null ); } else diff --git a/module/programplan/ui/gantt.html.php b/module/programplan/ui/gantt.html.php index 95708296f6..40c1119622 100644 --- a/module/programplan/ui/gantt.html.php +++ b/module/programplan/ui/gantt.html.php @@ -53,7 +53,7 @@ if($app->rawModule == 'programplan') )) ), btn(set::url($this->createLink('programplan', 'ajaxcustom')), set::icon('cog-outline'), $lang->settings, setClass('no-underline'), set::type('link'), set('data-toggle', 'modal'), set('data-size', 'sm')), - (common::hasPriv('programplan', 'create') && empty($product->deleted)) ? btn(set::url($this->createLink('programplan', 'create', "projectID=$projectID")), set::icon('plus'), $lang->programplan->create, setClass('primary programplan-create-btn')) : null + (common::canModify('project', $project) && common::hasPriv('programplan', 'ocreate') && empty($product->deleted)) ? btn(set::url($this->createLink('programplan', 'create', "projectID=$projectID")), set::icon('plus'), $lang->programplan->create, setClass('primary programplan-create-btn')) : null ); } diff --git a/module/project/ui/bug.html.php b/module/project/ui/bug.html.php index d54890bc9c..e49e961751 100644 --- a/module/project/ui/bug.html.php +++ b/module/project/ui/bug.html.php @@ -17,7 +17,8 @@ featureBar li(searchToggle(set::module('projectBug'), set::open($type == 'bysearch'))) ); -$canCreate = (common::canModify('project', $project) && hasPriv('bug', 'create')); +$canModify = common::canModify('project', $project); +$canCreate = ($canModify && hasPriv('bug', 'create')); toolbar ( hasPriv('bug', 'export') ? item(set(array @@ -70,7 +71,6 @@ foreach($config->bug->dtable->fieldList as $fieldCode => $fieldInfo) if(!$canBatchAssignTo) $config->bug->dtable->fieldList['id']['type'] = 'id'; -foreach($bugs as $bug) $bug->canBeChanged = common::canBeChanged('bug', $bug); $footToolbar = array(); if($canBatchAssignTo) { @@ -86,6 +86,7 @@ if($canBatchAssignTo) $cols = $this->loadModel('datatable')->getSetting('project'); $bugs = initTableData($bugs, $cols, $this->bug); +if(!$canModify) foreach($bugs as $bug) $bug->actions = array(); dtable ( diff --git a/module/project/ui/build.html.php b/module/project/ui/build.html.php index aef72edbc2..2982253fd3 100644 --- a/module/project/ui/build.html.php +++ b/module/project/ui/build.html.php @@ -37,7 +37,8 @@ featureBar ); /* zin: Define the toolbar on main menu. */ -$canCreateBuild = hasPriv('projectbuild', 'create') && common::canModify('project', $project); +$canModify = common::canModify('project', $project); +$canCreateBuild = hasPriv('projectbuild', 'create') && $canModify; if($canCreateBuild) toolbar(item(set(array('icon' => 'plus', 'class' => 'primary', 'text' => $lang->build->create, 'url' => createLink('projectbuild', 'create', "projectID={$project->id}"))))); @@ -56,6 +57,7 @@ if(($project->model == 'kanban' && $app->rawModule == 'projectbuild') || !$proje } unset($fieldList['actions']['list'][$app->tab == 'project' ? 'linkStory' : 'linkProjectStory']); if(!$project->multiple) unset($fieldList['executionName']); +if(!$canModify) unset($fieldList['actions']['list']); $builds = initTableData($builds, $fieldList, $this->build); dtable diff --git a/module/project/ui/execution.html.php b/module/project/ui/execution.html.php index 8a27a5ed0b..32ce79149f 100644 --- a/module/project/ui/execution.html.php +++ b/module/project/ui/execution.html.php @@ -125,7 +125,8 @@ featureBar ); /* zin: Define the toolbar on main menu. */ -$createLink = $isStage ? createLink('programplan', 'create', "projectID={$projectID}&productID={$productID}") : createLink('execution', 'create', "projectID={$projectID}"); +$createLink = $isStage ? createLink('programplan', 'create', "projectID={$projectID}&productID={$productID}") : createLink('execution', 'create', "projectID={$projectID}"); +$canModifyProject = common::canModify('project', $project); toolbar ( in_array($project->model, array('waterfall', 'waterfallplus', 'ipd')) && in_array($this->config->edition, array('max', 'ipd')) ? btnGroup @@ -141,21 +142,21 @@ toolbar 'data-toggle' => "modal", 'url' => createLink('execution', 'export', "status={$status}&productID={$productID}&orderBy={$orderBy}&from=project") ))) : null, - common::hasPriv('programplan', 'create') && $isStage && empty($product->deleted) ? item(set(array + $canModifyProject && common::hasPriv('programplan', 'create') && $isStage && empty($product->deleted) ? item(set(array ( 'icon' => 'plus', 'text' => $lang->programplan->create, 'class' => "primary create-execution-btn", 'url' => $createLink ))) : null, - hasPriv('execution', 'create') && !$isStage && $project->model != 'agileplus' ? item(set(array + $canModifyProject && hasPriv('execution', 'create') && !$isStage && $project->model != 'agileplus' ? item(set(array ( 'icon' => 'plus', 'text' => $isStage ? $lang->programplan->create : $lang->execution->create, 'class' => "primary create-execution-btn", 'url' => $createLink ))) : null, - hasPriv('execution', 'create') && !$isStage && $project->model == 'agileplus' ? btngroup( + $canModifyProject && hasPriv('execution', 'create') && !$isStage && $project->model == 'agileplus' ? btngroup( setClass('create-execution-btn'), btn(setClass('btn primary'), set::icon('plus'), set::url($createLink), $lang->execution->create), dropdown @@ -172,7 +173,7 @@ toolbar ) : null ); -$canCreateExecution = $isStage ? common::hasPriv('programplan', 'create') : common::hasPriv('execution', 'create'); +$canCreateExecution = $canModifyProject && $isStage ? common::hasPriv('programplan', 'create') : common::hasPriv('execution', 'create'); dtable ( set::userMap($users), diff --git a/module/project/ui/testtask.html.php b/module/project/ui/testtask.html.php index e598b06856..c11bddfd87 100644 --- a/module/project/ui/testtask.html.php +++ b/module/project/ui/testtask.html.php @@ -27,7 +27,8 @@ featureBar ) ); -$canCreate = common::canModify('project', $project) && common::hasPriv('testtask', 'create'); +$canModify = common::canModify('project', $project); +$canCreate = $canModify && common::hasPriv('testtask', 'create'); toolbar ( $canCreate ? btn @@ -41,6 +42,7 @@ toolbar ); $config->project->dtable->testtask->fieldList['actions']['list']['report']['url']['params'] = "objectID={project}&objectType=project&extra={id}"; +if(!$canModify) unset($config->project->dtable->testtask->fieldList['actions']['list']); $tasks = initTableData($tasks, $config->project->dtable->testtask->fieldList); $summary = sprintf($lang->testtask->allSummary, count($tasks), $waitCount, $testingCount, $blockedCount, $doneCount); diff --git a/module/projectrelease/ui/browse.html.php b/module/projectrelease/ui/browse.html.php index d87bed7e00..7f83be20bc 100644 --- a/module/projectrelease/ui/browse.html.php +++ b/module/projectrelease/ui/browse.html.php @@ -18,7 +18,7 @@ featureBar toolbar ( - hasPriv('projectrelease', 'create') ? item(set + common::canModify('project', $project) && hasPriv('projectrelease', 'create') ? item(set ([ 'text' => $lang->release->create, 'icon' => 'plus', diff --git a/module/story/tao.php b/module/story/tao.php index d4aab6c67d..42399e7761 100644 --- a/module/story/tao.php +++ b/module/story/tao.php @@ -1884,6 +1884,8 @@ class storyTao extends storyModel global $lang; $actions = array(); + if(!empty($execution) && !common::canModify('execution', $execution)) return $actions; + $tutorialMode = commonModel::isTutorialMode(); if($this->config->edition == 'ipd' && $storyType == 'story') { diff --git a/module/testcase/ui/browse.html.php b/module/testcase/ui/browse.html.php index a350efd8ab..935a688d43 100644 --- a/module/testcase/ui/browse.html.php +++ b/module/testcase/ui/browse.html.php @@ -16,16 +16,16 @@ jsVar('confirmBatchDeleteSceneCase', $lang->testcase->confirmBatchDeleteSceneCas $topSceneCount = count(array_filter(array_map(function($case){return $case->isScene && $case->grade == 1;}, $cases))); -$canBatchRun = hasPriv('testtask', 'batchRun') && !$isOnlyScene; -$canBatchEdit = hasPriv('testcase', 'batchEdit') && !$isOnlyScene; -$canBatchReview = hasPriv('testcase', 'batchReview') && !$isOnlyScene && ($config->testcase->needReview || !empty($config->testcase->forceReview)); -$canBatchDelete = hasPriv('testcase', 'batchDelete') && !$isOnlyScene; -$canBatchChangeType = hasPriv('testcase', 'batchChangeType') && !$isOnlyScene; -$canBatchConfirmStoryChange = hasPriv('testcase', 'batchConfirmStoryChange') && !$isOnlyScene; -$canBatchChangeBranch = hasPriv('testcase', 'batchChangeBranch') && !$isOnlyScene && isset($product->type) && $product->type != 'normal'; -$canBatchChangeModule = hasPriv('testcase', 'batchChangeModule') && !empty($productID) && ((isset($product->type) && $product->type == 'normal') || $branch !== 'all'); -$canBatchChangeScene = hasPriv('testcase', 'batchChangeScene') && !$isOnlyScene; -$canImportToLib = hasPriv('testcase', 'importToLib') && !$isOnlyScene; +$canBatchRun = $canModify && hasPriv('testtask', 'batchRun') && !$isOnlyScene; +$canBatchEdit = $canModify && hasPriv('testcase', 'batchEdit') && !$isOnlyScene; +$canBatchReview = $canModify && hasPriv('testcase', 'batchReview') && !$isOnlyScene && ($config->testcase->needReview || !empty($config->testcase->forceReview)); +$canBatchDelete = $canModify && hasPriv('testcase', 'batchDelete') && !$isOnlyScene; +$canBatchChangeType = $canModify && hasPriv('testcase', 'batchChangeType') && !$isOnlyScene; +$canBatchConfirmStoryChange = $canModify && hasPriv('testcase', 'batchConfirmStoryChange') && !$isOnlyScene; +$canBatchChangeBranch = $canModify && hasPriv('testcase', 'batchChangeBranch') && !$isOnlyScene && isset($product->type) && $product->type != 'normal'; +$canBatchChangeModule = $canModify && hasPriv('testcase', 'batchChangeModule') && !empty($productID) && ((isset($product->type) && $product->type == 'normal') || $branch !== 'all'); +$canBatchChangeScene = $canModify && hasPriv('testcase', 'batchChangeScene') && !$isOnlyScene; +$canImportToLib = $canModify && hasPriv('testcase', 'importToLib') && !$isOnlyScene; $canGroupBatch = ($canBatchRun || $canBatchEdit || $canBatchReview || $canBatchDelete || $canBatchChangeType || $canBatchConfirmStoryChange); $canBatchAction = ($canGroupBatch || $canBatchChangeBranch || $canBatchChangeModule || $canBatchChangeScene || $canImportToLib); @@ -128,6 +128,7 @@ foreach($cases as $case) $case->stage = implode(',', array_filter($stages)); $case->browseType = $browseType; initTableData(array($case), $cols, $this->testcase); + if(!$canModify) unset($case->actions); } $linkParams = ''; diff --git a/module/testcase/ui/header.html.php b/module/testcase/ui/header.html.php index 2c8c00c960..ce71a1f64b 100644 --- a/module/testcase/ui/header.html.php +++ b/module/testcase/ui/header.html.php @@ -27,24 +27,25 @@ $load = $rawMethod !== 'browse' ? null : 'table'; $product = is_bool($product) ? new stdclass() : $product; $canModify = common::canModify('product', $product); +if(!empty($project)) $canModify = $canModify && common::canModify('project', $project); $canSwitchCaseType = $this->app->tab == 'qa'; $canDisplaySuite = $this->app->tab == 'qa' && $rawMethod != 'browseunits'; -$canManageModule = hasPriv('tree', 'browse') && !empty($productID) && (!isset($project) || $project->hasProduct); -$canCreateSuite = hasPriv('testsuite', 'create'); +$canManageModule = $canModify && hasPriv('tree', 'browse') && !empty($productID) && (!isset($project) || $project->hasProduct); +$canCreateSuite = $canModify && hasPriv('testsuite', 'create'); $canBrowseUnits = hasPriv('testtask', 'browseunits'); $canBrowseZeroCase = hasPriv('testcase', 'zerocase') && $rawMethod != 'browseunits'; $canBrowseGroupCase = hasPriv('testcase', 'groupcase'); -$canAutomation = hasPriv('testcase', 'automation') && !empty($productID) && $rawMethod != 'browseunits'; +$canAutomation = $canModify && hasPriv('testcase', 'automation') && !empty($productID) && $rawMethod != 'browseunits'; $canExport = hasPriv('testcase', 'export'); $canExportTemplate = hasPriv('testcase', 'exportTemplate'); $canExportXmind = hasPriv('testcase', 'exportXmind'); -$canImport = hasPriv('testcase', 'import'); -$canImportFromLib = hasPriv('testcase', 'importFromLib'); -$canImportXmind = hasPriv('testcase', 'importXmind'); -$canCreateCase = hasPriv('testcase', 'create'); -$canBatchCreateCase = $productID && hasPriv('testcase', 'batchCreate'); -$canCreateScene = $productID && hasPriv('testcase', 'createScene'); -$canImportUnitResult = hasPriv('testtask', 'importUnitResult'); +$canImport = $canModify && hasPriv('testcase', 'import'); +$canImportFromLib = $canModify && hasPriv('testcase', 'importFromLib'); +$canImportXmind = $canModify && hasPriv('testcase', 'importXmind'); +$canCreateCase = $canModify && hasPriv('testcase', 'create'); +$canBatchCreateCase = $canModify && $productID && hasPriv('testcase', 'batchCreate'); +$canCreateScene = $canModify && $productID && hasPriv('testcase', 'createScene'); +$canImportUnitResult = $canModify && hasPriv('testtask', 'importUnitResult'); $canCreate = $canCreateCase || $canBatchCreateCase || $canCreateScene; $lang->testcase->typeList[''] = $lang->testcase->allType;