diff --git a/module/group/control.php b/module/group/control.php index 8bfec7829b..aa0a8bf00d 100644 --- a/module/group/control.php +++ b/module/group/control.php @@ -205,7 +205,7 @@ class group extends control } if($type == 'byGroup' || $type == 'byPackage') $this->groupZen->managePrivByGroup($groupID, $nav, $version); - if($type == 'byModule') $this->groupZen->managePrivByModule($groupID, $nav, $version); + if($type == 'byModule') $this->groupZen->managePrivByModule(); $this->display(); } diff --git a/module/group/js/managepriv.ui.js b/module/group/js/managepriv.ui.js index f1898a2ca8..61c1ab9c9c 100644 --- a/module/group/js/managepriv.ui.js +++ b/module/group/js/managepriv.ui.js @@ -321,28 +321,27 @@ function positionBtn() * @access public * @return void */ -window.setModulePackages = function() +window.setSubsetPackages = function() { - const module = $(this).val(); + let subset = $(this).val(); $('#packageBox select').addClass('hidden'); // Hide all select first. $('#packageBox select').val(''); // Unselect all select. - $("select[data-module='" + module + "']").removeClass('hidden'); // Show the action control for current module. + $("select[data-module='" + subset + "']").removeClass('hidden'); // Show the action control for current module. - updatePrivList('module', module); + updatePrivList(subset, ''); } /** - * Update the action box when module or package selected. + * Update the action box when subset or package selected. * - * @param string parentType module|package - * @param string parentList + * @param string selectedSubset + * @param string selectedPackages * @access public * @return void */ -function updatePrivList(parentType, parentList) +function updatePrivList(selectedSubset, selectedPackages) { - const selectedModule = $('#module').val(); - $.get($.createLink('group', 'ajaxGetPrivByParents', 'module=' + selectedModule + '&parentType=' + parentType + '&parentList=' + parentList), function(data) + $.get($.createLink('group', 'ajaxGetPrivByParents', 'subset=' + selectedSubset + '&packages=' + selectedPackages), function(data) { $('#actions').replaceWith(data); }) @@ -358,10 +357,10 @@ function setActions() { $('#actionBox select').val(''); - var hasSelectedPackage = ',' + $('#packageBox select').not('.hidden').val().join(',') + ','; - - updatePrivList('package', hasSelectedPackage); + var selectedSubset = $('[name=module]').val(); + var selectedPackages = '|' + $('#packageBox select').not('.hidden').val().join('|') + '|'; + updatePrivList(selectedSubset, selectedPackages); } window.setNoChecked = function() @@ -411,12 +410,12 @@ function groupItemChange() changeParentChecked($(this), moduleName, packageID); var privID = $(this).closest('.group-item').attr('data-id'); - if(privID != 0) + if(privID) { var index = selectedPrivIdList.indexOf(privID); - if(privID > 0 && index < 0 && checked) selectedPrivIdList.push(privID); - if(privID > 0 && index > -1 && !checked) selectedPrivIdList.splice(index, 1); + if(index < 0 && checked) selectedPrivIdList.push(privID); + if(index > -1 && !checked) selectedPrivIdList.splice(index, 1); updatePrivTree(selectedPrivIdList); } @@ -469,7 +468,7 @@ function recommendChange($item, checked) $parentItem.closest('.checkbox-primary').find('label').addClass('checkbox-indeterminate-block'); } - var privID = $item.attr('module') + '-' + $item.attr('method'); + var privID = $item.attr('data-id'); if(privID) { var index = selectedPrivIdList.indexOf(privID); diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php index effb2a8857..81311334c9 100644 --- a/module/group/lang/resource.php +++ b/module/group/lang/resource.php @@ -632,7 +632,7 @@ $lang->resource->productplan->batchUnlinkStory = 'batchUnlinkStory'; $lang->resource->productplan->linkBug = 'linkBug'; $lang->resource->productplan->unlinkBug = 'unlinkBug'; $lang->resource->productplan->batchUnlinkBug = 'batchUnlinkBug'; -$lang->resource->productplan->batchEdit = 'batchEditAction'; +$lang->resource->productplan->batchEdit = 'batchEdit'; $lang->resource->productplan->start = 'start'; $lang->resource->productplan->finish = 'finish'; $lang->resource->productplan->close = 'close'; diff --git a/module/group/model.php b/module/group/model.php index c8ed463ddc..96538d1ce3 100644 --- a/module/group/model.php +++ b/module/group/model.php @@ -1849,7 +1849,9 @@ class groupModel extends model $this->app->loadLang($moduleName); if($moduleName == 'requirement') $this->app->loadLang('story'); } - $priv = (object)array('subset' => $packageData->subset, 'package' => $packageCode, 'module' => $moduleName, 'method' => $methodName, 'selected' => false, 'name' => $this->lang->$moduleName->$methodLang); + + $privName = isset($this->lang->$moduleName) && isset($this->lang->$moduleName->$methodLang) ? $this->lang->$moduleName->$methodLang : $privCode; + $priv = (object)array('subset' => $packageData->subset, 'package' => $packageCode, 'module' => $moduleName, 'method' => $methodName, 'selected' => false, 'name' => $privName); $privList[$privCode] = $priv; } @@ -2516,7 +2518,7 @@ class groupModel extends model $method = $this->lang->resource->$moduleName->$methodName; if(!isset($this->lang->$moduleName->$method)) $this->app->loadLang($moduleName); - $subsetPrivs[$type][$subsetName]['children'][] = array('id' => $relatedPriv, 'module' => $moduleName, 'method' => $methodName, 'subset' => $subsetName, 'text' => $this->lang->$moduleName->$method); + $subsetPrivs[$type][$subsetName]['children'][] = array('id' => $relatedPriv, 'data-module' => $moduleName, 'data-method' => $methodName, 'subset' => $subsetName, 'text' => $this->lang->$moduleName->$method, 'data-id' => $relatedPriv); } } @@ -2582,16 +2584,16 @@ class groupModel extends model $subset = $packageData->subset; if($subset !== $selectedSubset) continue; - if($selectedPackages && strpos($selectedPackages, ",$packageCode,") === false) continue; + if($selectedPackages && strpos($selectedPackages, "|$packageCode|") === false) continue; $methodLang = $this->lang->resource->$moduleName->$methodName; if(!isset($this->lang->$moduleName->$methodLang)) $this->app->loadLang($moduleName); - $privs[$privCode] = $this->lang->$moduleName->$methodLang; + $privs[$privCode] = isset($this->lang->$moduleName) && isset($this->lang->$moduleName->$methodLang) ? $this->lang->$moduleName->$methodLang : $privCode; } } - if(empty($selectedPackages) || strpos($selectedPackages, ',other,') !== false) + if(empty($selectedPackages) || strpos($selectedPackages, '|other|') !== false) { /* Privs in resource but not in package. */ $this->sortResource(); @@ -2604,7 +2606,7 @@ class groupModel extends model if(isset($allPrivs["$module-$method"])) continue; if(!isset($this->lang->$module->$methodLang)) $this->app->loadLang($module); - $privs["$module-$method"] = $this->lang->$module->$methodLang; + $privs["$module-$method"] = isset($this->lang->$module) && isset($this->lang->$module->$methodLang) ? $this->lang->$module->$methodLang : "$module-$method"; } } } diff --git a/module/group/packagemanager.php b/module/group/packagemanager.php index 9e06017351..57afaafae1 100644 --- a/module/group/packagemanager.php +++ b/module/group/packagemanager.php @@ -783,10 +783,6 @@ $config->group->package->importRequirement->privs['requirement-export'] $config->group->package->importRequirement->privs['requirement-import'] = array('edition' => 'max,ipd', 'vision' => 'rnd,or', 'order' => 115, 'depend' => array('product-requirement', 'requirement-exportTemplate'), 'recommend' => array()); $config->group->package->importRequirement->privs['requirement-exportTemplate'] = array('edition' => 'max,ipd', 'vision' => 'rnd,or', 'order' => 120, 'depend' => array('product-requirement'), 'recommend' => array()); -$config->group->package->deleteRequirement = new stdclass(); -$config->group->package->deleteRequirement->order = 25; -$config->group->package->deleteRequirement->subset = 'requirement'; - $config->group->package->reviewRequirement = new stdclass(); $config->group->package->reviewRequirement->order = 15; $config->group->package->reviewRequirement->subset = 'requirement'; @@ -2523,10 +2519,6 @@ $config->group->package->workflow->privs['workflow-setApproval'] = array('editio $config->group->package->workflow->privs['workflow-setJS'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd,lite', 'order' => 80, 'depend' => array('workflow-browseFlow'), 'recommend' => array()); $config->group->package->workflow->privs['workflow-setCSS'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd,lite', 'order' => 85, 'depend' => array('workflow-browseFlow'), 'recommend' => array()); -$config->group->package->downloadCode = new stdclass(); -$config->group->package->downloadCode->order = 10; -$config->group->package->downloadCode->subset = 'repocode'; - $config->group->package->dev = new stdclass(); $config->group->package->dev->order = 5; $config->group->package->dev->subset = 'dev'; @@ -2664,10 +2656,6 @@ $config->group->package->webhook->privs['webhook-log'] = array('edition' $config->group->package->webhook->privs['webhook-bind'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'lite,rnd,or', 'order' => 30, 'depend' => array('webhook-chooseDept'), 'recommend' => array()); $config->group->package->webhook->privs['webhook-chooseDept'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'lite,rnd,or', 'order' => 35, 'depend' => array('webhook-browse'), 'recommend' => array('webhook-create', 'webhook-delete', 'webhook-edit')); -$config->group->package->gitlab = new stdclass(); -$config->group->package->gitlab->order = 10; -$config->group->package->gitlab->subset = 'repo'; - $config->group->package->sms = new stdclass(); $config->group->package->sms->order = 20; $config->group->package->sms->subset = 'notifysetting'; @@ -2777,10 +2765,6 @@ $config->group->package->chat->privs['client-create'] = array('edition' $config->group->package->chat->privs['client-edit'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite', 'order' => 6, 'depend' => array('admin-xuanxuan'), 'recommend' => array()); $config->group->package->chat->privs['client-delete'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite', 'order' => 7, 'depend' => array('admin-xuanxuan'), 'recommend' => array()); -$config->group->package->jenkins = new stdclass(); -$config->group->package->jenkins->order = 25; -$config->group->package->jenkins->subset = 'repo'; - $config->group->package->systemSetting = new stdclass(); $config->group->package->systemSetting->order = 5; $config->group->package->systemSetting->subset = 'systemsetting'; @@ -3061,10 +3045,6 @@ $config->group->package->measurement->privs['report-saveReport'] = arra $config->group->package->measurement->privs['report-crystalExport'] = array('edition' => 'max,ipd', 'vision' => 'rnd', 'order' => 22, 'depend' => array('measurement-template'), 'recommend' => array()); $config->group->package->measurement->privs['report-export'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 25, 'depend' => array('measurement-template'), 'recommend' => array()); -$config->group->package->usercl = new stdclass(); -$config->group->package->usercl->order = 25; -$config->group->package->usercl->subset = 'featureconfig'; - $config->group->package->meetingroom = new stdclass(); $config->group->package->meetingroom->order = 30; $config->group->package->meetingroom->subset = 'featureconfig'; @@ -3213,10 +3193,6 @@ $config->group->package->template->privs = array(); $config->group->package->template->privs['user-setPublicTemplate'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite,or', 'order' => 10, 'depend' => array(), 'recommend' => array()); $config->group->package->template->privs['datatable-setGlobal'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd,lite', 'order' => 5, 'depend' => array(), 'recommend' => array()); -$config->group->package->table = new stdclass(); -$config->group->package->table->order = 5; -$config->group->package->table->subset = 'datatable'; - $config->group->package->automation = new stdclass(); $config->group->package->automation->order = 5; $config->group->package->automation->subset = 'ci'; @@ -3807,10 +3783,6 @@ $config->group->package->deletePrompt->subset = 'ai'; $config->group->package->deletePrompt->privs = array(); $config->group->package->deletePrompt->privs['ai-promptDelete'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 30, 'depend' => array('admin-index', 'ai-prompts', 'ai-promptView'), 'recommend' => array()); -$config->group->package->resource = new stdclass(); -$config->group->package->resource->order = 2200; -$config->group->package->resource->subset = 'ops'; - $config->group->package->manageServiceProvider = new stdclass(); $config->group->package->manageServiceProvider->order = 2300; $config->group->package->manageServiceProvider->subset = 'ops'; diff --git a/module/group/ui/privbygroup.html.php b/module/group/ui/privbygroup.html.php index a6345483ec..4213c9be6b 100644 --- a/module/group/ui/privbygroup.html.php +++ b/module/group/ui/privbygroup.html.php @@ -9,11 +9,11 @@ declare(strict_types=1); * @link https://www.zentao.net */ namespace zin; -jsVar('window.selectedPrivIdList', $selectedPrivIdList); -jsVar('excludeIdList', $excludePrivsIdList); +jsVar('window.selectedPrivIdList', $selectedPrivList); +jsVar('allPrivList', $allPrivList); jsVar('groupID', $groupID); jsVar('type', $type); -jsVar('menu', $menu); +jsVar('nav', $nav); if($group->role == 'limited') { @@ -89,11 +89,11 @@ if($group->role == 'limited') } else { - $params = "type=byGroup¶m=$groupID&menu=%s&version=$version"; + $params = "type=byGroup¶m=$groupID&nav=%s&version=$version"; $mainNavItems = null; $i = 0; $dropDownItems = array(); - foreach($lang->mainNav as $module => $title) + foreach($lang->mainNav as $navKey => $title) { if(!is_string($title)) continue; @@ -103,14 +103,14 @@ else $dropDownItems[] = array ( 'text' => strip_tags(substr($title, 0, strpos($title, '|'))), - 'url' => inlink('managePriv', sprintf($params, $module)), - 'class' => $menu == $module ? 'active' : '' + 'url' => inlink('managePriv', sprintf($params, $navKey)), + 'class' => $nav == $navKey ? 'active' : '' ); } } $i = 0; - foreach($lang->mainNav as $module => $title) + foreach($lang->mainNav as $navKey => $title) { if(!is_string($title) || $i >= $config->group->maxToolBarCount) continue; @@ -137,8 +137,8 @@ else setClass('nav-item'), a ( - setClass($menu == $module ? 'active' : ''), - set::href(inlink('managePriv', sprintf($params, $module))), + setClass($nav == $navKey ? 'active' : ''), + set::href(inlink('managePriv', sprintf($params, $navKey))), strip_tags(substr($title, 0, strpos($title, '|'))) ) ); @@ -172,7 +172,7 @@ else setclass('nav-item'), a ( - setclass(empty($menu) ? 'active' : ''), + setclass(empty($nav) ? 'active' : ''), set::href(inlink('managepriv', sprintf($params, ''))), span($lang->group->all) ) @@ -183,7 +183,7 @@ else setClass('nav-item'), a ( - setClass($menu == 'general' ? 'active' : ''), + setClass($nav == 'general' ? 'active' : ''), set::href(inlink('managePriv', sprintf($params, 'general'))), span($lang->group->general) ) @@ -200,19 +200,18 @@ else ), ); - $getMethodItems = function($privs, $moduleName, $packageID, $groupPrivs) + $getMethodItems = function($package, $subsetName, $packageID, $groupPrivs) { $methodItems = array(); - foreach($privs as $privID => $priv) + foreach($package->privs as $privID => $priv) { - if(!empty($lang->$moduleName->menus) and ($priv->method == 'browse' or in_array($priv->method, array_keys($lang->$moduleName->menus)))) continue; $methodItems[] = div ( setClass('group-item'), - set('data-module', $moduleName), + set('data-module', $subsetName), set('data-package', $packageID), - set('data-divid', "{$moduleName}{$packageID}"), - set('data-id', zget($priv, 'id', 0)), + set('data-divid', "{$subsetName}{$packageID}"), + set('data-id', $privID), checkbox ( set::name("actions[{$priv->module}][]"), @@ -220,33 +219,42 @@ else set::checked(isset($groupPrivs[$priv->module][$priv->method])), setID("actions[{$priv->module}][{$priv->method}]"), set::text($priv->name), - set('data-id', $priv->action), + set('data-id', $privID), ) ); } return $methodItems; }; - $privBody = null; - foreach($privList as $moduleName => $packages) + $dependTree = null; + foreach($relatedPrivData['depend'] as $dependPrivs) { - if(!count((array)$packages)) continue; + $dependTree[] = checkboxGroup + ( + set::title(array('text' => $dependPrivs['text'], 'id' => "dependPrivs[{$dependPrivs['id']}]", 'name' => 'dependPrivs[]', 'data-id' => $dependPrivs['id'], 'data-has-children' => !empty($dependPrivs['children']), 'disabled' => true, 'checked' => true)), + !empty($dependPrivs['children']) ? set::items($dependPrivs['children']) : null, + ); + } - $i = 1; - $modulePrivs = count($privList[$moduleName], 1) - count($selectPrivs[$moduleName], 1); - $moduleSelect = array_sum($selectPrivs[$moduleName]); - foreach($packages as $packageID => $privs) + $recommendTree = null; + foreach($relatedPrivData['recommend'] as $recommendPrivs) + { + $recommendTree[] = checkboxGroup + ( + set::title(array('text' => $recommendPrivs['text'], 'id' => "recommendPrivs[{$recommendPrivs['id']}]", 'name' => 'recommendPrivs[]', 'data-id' => $recommendPrivs['id'], 'data-has-children' => !empty($recommendPrivs['children']))), + !empty($recommendPrivs['children']) ? set::items($recommendPrivs['children']) : null, + ); + } + + $privBody = null; + foreach($subsets as $subsetName => $subset) + { + if($subset->allCount == 0) continue; + + $i = 1; + foreach($packages[$subsetName] as $packageID => $package) { - $packagePrivs = count($privs); - $packageSelect = $selectPrivs[$moduleName][$packageID]; - $moduleTitle = $lang->$moduleName->common; - if(in_array($moduleName, array('doc', 'api'))) $moduleTitle = $lang->$moduleName->manage; - - if(isset($lang->$moduleName->menus)) - { - $menusPrivs = count($lang->$moduleName->menus); - $menusSelect = count(array_intersect(array_keys($lang->$moduleName->menus), array_keys(zget($groupPrivs, $moduleName, array())))); - } + $subsetTitle = isset($lang->$subsetName) && isset($lang->$subsetName->common) ? $lang->$subsetName->common : $subsetName; $privBody[] = h::tr ( @@ -254,20 +262,20 @@ else $i == 1 ? h::th ( setClass('text-middle text-left module'), - set('rowspan', $i == 1 ? count($packages) : 1), - set('data-module', $moduleName), - set('all-privs', $moduleprivs), - set('select-privs', $moduleSelect), + set('rowspan', count($packages[$subsetName]) ? count($packages[$subsetName]) : 1), + set('data-module', $subsetName), + set('all-privs', $subset->allCount), + set('select-privs', $subset->selectCount), div ( setClass('checkbox-primary checkbox-inline checkbox-left check-all'), checkbox ( - setID("allChecker{$moduleName}"), + setID("allChecker{$subsetName}"), set::value(1), - set::checked(!empty($moduleSelect) && $modulePrivs == $moduleSelect), - set::text($moduleTitle), - set::labelClass(!empty($moduleSelect) && $modulePrivs != $moduleSelect ? 'text-left checkbox-indeterminate-block' : 'text-left'), + set::checked($subset->selectCount && $subset->selectCount == $subset->allCount), + set::text($subsetTitle), + set::labelClass($subset->selectCount && $subset->selectCount != $subset->allCount ? 'text-left checkbox-indeterminate-block' : 'text-left'), ) ) ) : null, @@ -275,58 +283,29 @@ else ( setClass('text-middle text-left package'), setClass($i == 1 ? 'td-sm' : 'td-md'), - set('data-module', $moduleName), + set('data-module', $subsetName), set('data-package', $packageID), - set('data-divid', "{$moduleName}{$packageID}"), - set('all-privs', $packagePrivs), - set('select-privs', $packageSelect), + set('data-divid', "{$subsetName}{$packageID}"), + set('all-privs', $package->allCount), + set('select-privs', $package->selectCount), div ( setClass('checkbox-primary checkbox-inline checkbox-left check-all'), checkbox ( - setID("allCheckerModule{$moduleName}Package{$packageID}"), + setID("allCheckerModule{$subsetName}Package{$packageID}"), set::value('browse'), - set::checked($packagePrivs == $packageSelect), - set::text(zget($privPackages, $packageID, $lang->group->other)), - set::labelClass(!empty($packageSelect) && $packagePrivs != $packageSelect ? 'text-left checkbox-indeterminate-block' : 'text-left'), + set::checked($package->allCount == $package->selectCount), + set::text($lang->group->package->$packageID), + set::labelClass($package->selectCount && $package->selectCount != $package->allCount ? 'text-left checkbox-indeterminate-block' : 'text-left'), ) ) ), - isset($lang->$moduleName->menus) ? h::td - ( - setClass("menus {$moduleName}"), - set('all-privs', $menusPrivs), - set('select-privs', $menusSelect), - set('data-module', $moduleName), - set('data-package', 0), - set('data-divid', "{$moduleName}0"), - div - ( - setClass('checkbox-primary checkbox-inline checkbox-left check-all'), - checkbox - ( - setID("actions[{$moduleName}]browse"), - set::value('browse'), - set::checked($menusPrivs == $menusSelect), - set::text($lang->$moduleName->browse), - set::labelClass(!empty($menusSelect) && $menusPrivs != $menusSelect ? 'text-left checkbox-indeterminate-block' : 'text-left'), - ), - icon('plus'), - checkList - ( - set::items($lang->$moduleName->menus), - set::name("actions[{$moduleName}]"), - set::value(isset($groupPrivs[$moduleName]) ? implode(',', $groupPrivs[$moduleName]) : ''), - ), - ) - ) : null, h::td ( setClass('pv-10px'), - setID($moduleName), - set('colspan', !empty($lang->$moduleName->menus) ? 1 : 2), - $getMethodItems($privs, $moduleName, $packageID, $groupPrivs), + setID($subsetName), + $getMethodItems($package, $subsetName, $packageID, $groupPrivs), ) ); $i ++; @@ -352,13 +331,13 @@ else a ( setClass('btn switchBtn'), - set::href(inlink('managePriv', "type=byPackage¶m={$groupID}&menu={$menu}&version={$version}")), + set::href(inlink('managePriv', "type=byPackage¶m={$groupID}&nav={$nav}&version={$version}")), html(""), ), a ( setClass('btn switchBtn text-primary'), - set::href(inlink('managePriv', "type=byGroup¶m={$groupID}&menu={$menu}&version={$version}")), + set::href(inlink('managePriv', "type=byGroup¶m={$groupID}&nav={$nav}&version={$version}")), html(""), ), ), diff --git a/module/group/ui/privbymodule.html.php b/module/group/ui/privbymodule.html.php index cad187eaa4..c799710875 100644 --- a/module/group/ui/privbymodule.html.php +++ b/module/group/ui/privbymodule.html.php @@ -9,6 +9,7 @@ declare(strict_types=1); * @link https://www.zentao.net */ namespace zin; +jsVar('window.selectedPrivIdList', array()); to::header( span @@ -25,16 +26,16 @@ to::header( $packageBox = null; $hiddenClass = ''; -foreach($packageGroup as $module => $modulePackages) +foreach($packages as $subset => $subsetPackages) { $packageBox[] = select ( set::name('packages[]'), set::className($hiddenClass), - set::items($modulePackages), + set::items($subsetPackages), set::multiple(true), set::required(true), - set('data-module', $module), + set('data-module', $subset), on::change('setActions'), ); @@ -62,10 +63,11 @@ form select ( set::name('module'), - set::items($modulePairs), + set::items($subsets), set::size(10), + set::value(key($subsets)), set::required(true), - on::change('window.setModulePackages'), + on::change('window.setSubsetPackages'), ) ) ), @@ -99,7 +101,7 @@ form select ( set::name('actions[]'), - set::items($indexPrivs), + set::items($privs), set::multiple(true), set::required(true) ) diff --git a/module/group/zen.php b/module/group/zen.php index 99c09a3836..94b4a04d1a 100644 --- a/module/group/zen.php +++ b/module/group/zen.php @@ -130,7 +130,7 @@ class groupZen extends group $subset = $packageData->subset; if(!isset($subsets[$subset])) { - $subsets[$subset] = $this->lang->$subset->common; + $subsets[$subset] = isset($this->lang->$subset) && isset($this->lang->$subset->common) ? $this->lang->$subset->common : $subset; $packages[$subset] = array(); }