From b3161bbd848a601043119fb152cbf66e3e5051d1 Mon Sep 17 00:00:00 2001 From: axman Date: Tue, 6 Jul 2021 14:49:09 -0700 Subject: [PATCH] Group Grouping for WG --- Controller/GrouperGroupsController.php | 116 ++++++++++--- Model/GrouperGroup.php | 143 ++++++++++++---- PlantUML/1.puml | 75 +++++++++ PlantUML/2.puml | 25 +++ PlantUML/3.puml | 46 ++++++ PlantUML/4.puml | 64 ++++++++ PlantUML/5.puml | 121 ++++++++++++++ PlantUML/6.puml | 27 +++ PlantUML/7.puml | 63 +++++++ PlantUML/GroupsBelongTo.puml | 219 +++++++++++++++++++++++++ PlantUML/MyMemberProcess.puml | 219 +++++++++++++++++++++++++ View/GrouperGroups/groupmember.ctp | 40 ++++- View/GrouperGroups/groupoptin.ctp | 89 ++++++---- View/GrouperGroups/groupowner.ctp | 111 +++++++++---- 14 files changed, 1235 insertions(+), 123 deletions(-) create mode 100644 PlantUML/1.puml create mode 100644 PlantUML/2.puml create mode 100644 PlantUML/3.puml create mode 100644 PlantUML/4.puml create mode 100644 PlantUML/5.puml create mode 100644 PlantUML/6.puml create mode 100644 PlantUML/7.puml create mode 100644 PlantUML/GroupsBelongTo.puml create mode 100644 PlantUML/MyMemberProcess.puml diff --git a/Controller/GrouperGroupsController.php b/Controller/GrouperGroupsController.php index 502c271..5257ba8 100644 --- a/Controller/GrouperGroupsController.php +++ b/Controller/GrouperGroupsController.php @@ -77,7 +77,6 @@ public function beforeFilter() { $this->setConnection(); } - //Need to verify if user is part of } /** @@ -180,8 +179,8 @@ public function groupOwner() { //Set initial settings for pagination $scope = [ 'userId' => $this->userId, - 'page' => (isset($this->passedArgs['page']) ? $this->passedArgs['page']: $this->paginate['page']), - 'limit' => (isset($this->passedArgs['limit']) ? $this->passedArgs['limit']: $this->paginate['limit']), + 'page' => ($this->passedArgs['page'] ?? $this->paginate['page']), + 'limit' => ($this->passedArgs['limit'] ?? $this->paginate['limit']), ]; if (isset($this->request->data['search'])) { @@ -195,12 +194,24 @@ public function groupOwner() { $scope['searchpage'] = 'ownerGroups'; $data = $this->Paginator->paginate('GrouperGroup', $scope); - $this->set('groupergroupsowner', $data); + + $wgData = array(); + $notWGData = array(); + foreach($data as $group) { + if(isset($group['WGName'])) { + $wgData[] = $group; + } else { + $notWGData[] = $group; + } + } + + $this->set('groupsowners', $notWGData); + $this->set('wgowners', $wgData); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ' Search: ' . var_export($e->getMessage(), true)); - $this->set('groupergroupsowner', array()); + $this->set('groupsowners', array()); $this->Flash->set(_txt('pl.grouperlite.message.flash.owner-group-failed'), array('key' => 'error')); return; } @@ -209,12 +220,25 @@ public function groupOwner() { $scope['method'] = 'ownerGroups'; $data = $this->Paginator->paginate('GrouperGroup', $scope); - $this->set('groupergroupsowner', $data); + + $wgData = array(); + $notWGData = array(); + foreach($data as $group) { + if(isset($group['WGName'])) { + $wgData[] = $group; + } else { + $notWGData[] = $group; + } + } + + $this->set('groupsowners', $notWGData); + $this->set('wgowners', $wgData); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); - $this->set('groupergroupsowner', array()); + $this->set('groupsowners', array()); + $this->set('wgowners', array()); $this->Flash->set(_txt('pl.grouperlite.message.flash.owner-group-failed'), array('key' => 'error')); return; } @@ -235,8 +259,8 @@ public function groupMember() { //Set initial settings for pagination $scope = [ 'userId' => $this->userId, - 'page' => (isset($this->passedArgs['page']) ? $this->passedArgs['page']: $this->paginate['page']), - 'limit' => (isset($this->passedArgs['limit']) ? $this->passedArgs['limit']: $this->paginate['limit']), + 'page' => ($this->passedArgs['page'] ?? $this->paginate['page']), + 'limit' => ($this->passedArgs['limit'] ?? $this->paginate['limit']), ]; if (isset($this->request->data['search'])) { @@ -250,13 +274,26 @@ public function groupMember() { $scope['searchpage'] = 'filteredMemberOfGroups'; $data = $this->Paginator->paginate('GrouperGroup', $scope); - $this->set('groupergroupmemberships', $data); + + $wgData = array(); + $notWGData = array(); + foreach($data as $group) { + if(isset($group['WGName'])) { + $wgData[] = $group; + } else { + $notWGData[] = $group; + } + } + + $this->set('groupmemberships', $notWGData); + $this->set('wgmemberships', $wgData); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ' Search: ' . var_export($e->getMessage(), true)); $this->Flash->set("Your Search Group cannot be found, please try again later.", array('key' => 'error')); - $this->set('groupergroupmemberships', array()); + $this->set('groupmemberships', array()); + $this->set('wgmemberships', array()); return; } } else { @@ -265,13 +302,26 @@ public function groupMember() { $scope['method'] = 'filteredMemberOfGroups'; $data = $this->Paginator->paginate('GrouperGroup', $scope); - $this->set('groupergroupmemberships', $data); + + $wgData = array(); + $notWGData = array(); + foreach($data as $group) { + if(isset($group['WGName'])) { + $wgData[] = $group; + } else { + $notWGData[] = $group; + } + } + + $this->set('groupmemberships', $notWGData); + $this->set('wgmemberships', $wgData); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); $this->Flash->set("Your Member Group cannot be found, please try again later.", array('key' => 'error')); - $this->set('groupergroupmemberships', array()); + $this->set('groupmemberships', array()); + $this->set('wgmemberships', array()); return; } } @@ -288,8 +338,8 @@ public function groupOptin() { //Set initial settings for pagination $scope = [ 'userId' => $this->userId, - 'page' => (isset($this->passedArgs['page']) ? $this->passedArgs['page']: $this->paginate['page']), - 'limit' => (isset($this->passedArgs['limit']) ? $this->passedArgs['limit']: $this->paginate['limit']), + 'page' => ($this->passedArgs['page'] ?? $this->paginate['page']), + 'limit' => ($this->passedArgs['limit'] ?? $this->paginate['limit']), ]; if (isset($this->request->data['search'])) { @@ -303,13 +353,27 @@ public function groupOptin() { $scope['searchpage'] = 'optinGroups'; $data = $this->Paginator->paginate('GrouperGroup', $scope); - $this->set('groupergroupoptin', $data); + //$this->set('groupoptin', $data); + + $wgData = array(); + $notWGData = array(); + foreach($data as $group) { + if(isset($group['WGName'])) { + $wgData[] = $group; + } else { + $notWGData[] = $group; + } + } + + $this->set('groupoptins', $notWGData); + $this->set('wgoptins', $wgData); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . 'Search: ' . var_export($e->getMessage(), true)); $this->Flash->set("Your Optin Group Search cannot be found, please try again later.", array('key' => 'error')); - $this->set('groupergroupoptin', array()); + $this->set('groupoptins', array()); + $this->set('wgoptins', array()); return; } } else { @@ -318,12 +382,26 @@ public function groupOptin() { $scope['method'] = 'optinGroups'; $data = $this->Paginator->paginate('GrouperGroup', $scope); - $this->set('groupergroupoptin', $data); + //$this->set('groupoptin', $data); + + $wgData = array(); + $notWGData = array(); + foreach($data as $group) { + if(isset($group['WGName'])) { + $wgData[] = $group; + } else { + $notWGData[] = $group; + } + } + + $this->set('groupoptins', $notWGData); + $this->set('wgoptins', $wgData); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': ' . var_export($e->getMessage(), true)); $this->Flash->set("An error occurred with the Optin Groups, please try again later.", array('key' => 'error')); - $this->set('groupergroupoptin', array()); + $this->set('groupoptins', array()); + $this->set('wgoptins', array()); return; } } diff --git a/Model/GrouperGroup.php b/Model/GrouperGroup.php index 548cb2b..4e12b1c 100644 --- a/Model/GrouperGroup.php +++ b/Model/GrouperGroup.php @@ -47,6 +47,13 @@ class GrouperGroup extends GrouperLiteAppModel /** @var string Group whose members can create Groups via Template process*/ private $templateCreationGroup = 'ref:workinggroupadmins'; + private $stemsWorkingGroup = array( + 'app:jira', + 'app:confluence', + 'app:sympa:internet2', + 'app:sympa:incommon', + 'ref:incommon-collab' + ); /** * Verifies if user is an owner/admin of a group and then stores results in Session. @@ -149,7 +156,7 @@ public function filteredMemberOfGroups(array $conditions) { } } - return $this->getFriendlyName($memberOfGroups); + return array_values($memberOfGroups); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); @@ -168,7 +175,7 @@ public function filteredMemberOfEmails(array $conditions) { } } - return $memberOfEmails; + return array_values($memberOfEmails); } /** @@ -190,6 +197,78 @@ private function memberOfGroups(array $conditions) { } } + + private function getFriendlyWorkingGroupName(array $groups) { + + $arrayIndex = 0; + foreach ($groups as &$group) { + foreach($this->stemsWorkingGroup as $stem) { + $len = strlen($stem); + if (substr(strtolower($group['name']), 0, $len) === $stem){ + $stemSections = explode(':', $group['name']); + //Get second to last stem section + $sectionCount = count($stemSections) - 2; + $group['WGName'] = $stemSections[$sectionCount]; + //Get user type, which is after the WG name + if (isset($stemSections[$sectionCount + 1])){ + $group['WGRole'] = $stemSections[$sectionCount + 1]; + } else { + $group['WGRole'] = ''; + } + $appCount = 0; + $appName = ''; + foreach ($stemSections as $stemSection ) { + //Skip first entry + if ($appCount > 0) { + if ($appCount < $sectionCount) { + if ($appCount == 1) { + $appName = $stemSection; + } else { + $appName = $appName . " - " . $stemSection; + } + } + } + $appCount += 1; + } + $group['WGApp'] = $appName; + $workingGroups[] = $group; + unset($groups[$arrayIndex]); + } + } + $arrayIndex += 1; + } + + $finalWorkingGroups = array(); + + foreach ($workingGroups as $workingGroup) { + //Need to set first group in final Working Group array + if (count($finalWorkingGroups) == 0) { + $finalWorkingGroups[] = array('WGName' => $workingGroup['WGName'], 'Groups' => array($workingGroup)); + } else { + $foundMatch = false; + foreach ($finalWorkingGroups as &$finalWorkingGroup) { + if($finalWorkingGroup['WGName'] == $workingGroup['WGName']){ + $finalWorkingGroup['Groups'][] = $workingGroup; + $foundMatch = true; + } + } + if (!$foundMatch) { + $finalWorkingGroups[] = array('WGName' => $workingGroup['WGName'], 'Groups' => array($workingGroup)); + } + } + } + + $friendlyGroups = $this->getFriendlyName(array_values($groups)); + + //Now need to add the groups back together for one set + foreach($friendlyGroups as $friendlyGroup) { + $finalWorkingGroups[] = $friendlyGroup; + } + + return $finalWorkingGroups; + } + + /** * Determine if result set contains friendly name, if so add as a new attribute in result set * @@ -200,37 +279,30 @@ private function memberOfGroups(array $conditions) { private function getFriendlyName(array $groups) { //NOT fetching attributes now, just using name display name as friendly name, if different from name field +// foreach ($groups as &$group) { +// //$group['friendlyName'] = $group['displayName']; +// $nameSections = explode(':', $group['name']); +// $friendlySections = explode(':', $group['displayName']); +// $numberNameSections = count($nameSections); +// for ($x = 0; $x < $numberNameSections; $x++) { +// if ($nameSections[$x] == $friendlySections[$x]) { +// unset($friendlySections[$x]); +// } else { +// break; +// } +// } +// $group['friendlyName'] = implode(':', $friendlySections); +// if (strlen($group['friendlyName']) == 0) { +// $group['friendlyName'] = $group['name']; +// } +// } + + //TODO - For now just returning Display name as Friendly name, till determined by Bill K. foreach ($groups as &$group) { - //$group['friendlyName'] = $group['displayName']; - $nameSections = explode(':', $group['name']); - $friendlySections = explode(':', $group['displayName']); - $numberNameSections = count($nameSections); - for ($x = 0; $x < $numberNameSections; $x++) { - if ($nameSections[$x] == $friendlySections[$x]) { - unset($friendlySections[$x]); - } - } - $group['friendlyName'] = implode(':', $friendlySections); - if (strlen($group['friendlyName']) == 0) { - $group['friendlyName'] = $group['name']; - } + $group['friendlyName'] = $group['displayName']; } return $groups; - - /* Old Process, keeping in case changes back! - foreach ($groups as &$group) { - $group['friendlyName'] = $group['displayName']; - $attributes = $this->grouperAPI->getGroupAttributes(array('conditions' => array('groupName' => $group['displayName']))); - foreach ($attributes as $attribute) { - if ($attribute['attributeDefNameName'] == $this->friendly) { - if (isset($attribute['wsAttributeAssignValues']['valueSystem'])) { - $group['friendlyName'] = $attribute['wsAttributeAssignValues']['valueSystem']; - } - break; - } - } - }*/ } /** @@ -248,9 +320,8 @@ public function groupDescriptions(string $groupName) { $args['groupName'] = $groupName; $groupDescription = $this->grouperAPI->getGrouperGroupInfo($args); - $groupInfo = $this->getFriendlyName($groupDescription); - return $groupInfo; + return $groupDescription; } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); @@ -325,7 +396,7 @@ public function ownerGroups(array $conditions) { try { $ownGroups = $this->grouperAPI->getOwnedGroups($conditions); - return $this->getFriendlyName($ownGroups); + return $ownGroups; } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); @@ -384,7 +455,7 @@ public function optinGroups(array $conditions) { } //$finalSet = $this->paginateRecords($joinOrLeave, $conditions); - return $this->getFriendlyName($joinOrLeave); + return array_values($joinOrLeave); } catch (Exception $e) { CakeLog::write('error', __METHOD__ . ': An error occurred'); @@ -402,7 +473,7 @@ public function optinEmailGroups(array $conditions) { } } - return $allGroups; + return array_values($allGroups); } /** @@ -632,7 +703,9 @@ public function paginate($conditions) { $resultSet = $this->$method($conditions); - return $this->paginateRecords($resultSet, $conditions); + $friendlyResults = $this->getFriendlyWorkingGroupName($resultSet); + + return $this->paginateRecords($friendlyResults, $conditions); } /** diff --git a/PlantUML/1.puml b/PlantUML/1.puml new file mode 100644 index 0000000..86c136e --- /dev/null +++ b/PlantUML/1.puml @@ -0,0 +1,75 @@ +# Data from API call to get all Groups belong to +@startjson +#highlight "WsGetGroupsLiteResult" / "wsGroups" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "0" / "name" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "0" / "displayName" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "0" / "description" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "1" / "name" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "1" / "displayName" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "1" / "description" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "2" / "name" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "2" / "displayName" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "2" / "description" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "3" / "name" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "3" / "displayName" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "3" / "description" +{ + "WsGetGroupsLiteResult": { + "resultMetadata": { + "success": "T", + "resultCode": "SUCCESS" + }, + "wsSubject": { + "...": "..." + }, + "responseMetadata": { + "...": "..." + }, + "wsGroups": [ + { + "extension": "CO_members_active", + "displayName": "app:comanage-provision:CO_members_active", + "description": "Internet2 Collaborations Active Members", + "uuid": "f5dae468b9d9429993992781712c2f83", + "enabled": "T", + "displayExtension": "CO_members_active", + "name": "app:comanage-provision:CO_members_active", + "typeOfGroup": "group", + "idIndex": "11104" + }, + { + "extension": "grouperUiUserData", + "displayName": "etc:grouperUi:grouperUiUserData", + "description": "Internal group for grouper which has ...", + "uuid": "2748e23e51174145a4dc4d9e115c59da", + "enabled": "T", + "displayExtension": "grouperUiUserData", + "name": "etc:grouperUi:grouperUiUserData", + "typeOfGroup": "group", + "idIndex": "10015" + }, + { + "extension": "AdministeredByUniconFolks", + "displayName": "sandbox:UniconTest:Administered By Unicon Folks", + "description": "Description goes here", + "uuid": "0b26aa411a99405b9440be3d0b18dafa", + "enabled": "T", + "displayExtension": "Administered By Unicon Folks", + "name": "sandbox:UniconTest:AdministeredByUniconFolks", + "typeOfGroup": "group", + "idIndex": "18451" + }, + { + "extension": "MembersFromUniconAZ", + "displayName": "sandbox:UniconTest:Members At Unicon in AZ", + "uuid": "7a9f3b9837024a56b12a2a6259d520e0", + "enabled": "T", + "displayExtension": "Members At Unicon in AZ", + "name": "sandbox:UniconTest:MembersFromUniconAZ", + "typeOfGroup": "group", + "idIndex": "18447" + } + ] + } +} +@endjson \ No newline at end of file diff --git a/PlantUML/2.puml b/PlantUML/2.puml new file mode 100644 index 0000000..2cfc608 --- /dev/null +++ b/PlantUML/2.puml @@ -0,0 +1,25 @@ +@startuml +skinparam titleBorderRoundCorner 15 +skinparam titleBorderThickness 2 +skinparam titleBorderColor red +skinparam titleBackgroundColor Aqua-CadetBlue + +title Mapping of //My Membership// page to API results + +map "** API Grouper (with example data) => My Membership Page **" as CC { + extension = CO_members_active => NA + displayName = app:comanage-provision:CO_members_active => Name + description = Internet2 Collaborations Active Members => Description + uuid = f5dae468b9d9429993992781712c2f83 => NA + enabled = T => NA + displayExtension = CO_members_active => NA + name = app:comanage-provision:CO_members_active => Name + typeOfGroup = group => NA + idIndex = 11104 => NA +} + +note right of CC + Name Fields are used to determine Friendly Name +end note + +@enduml \ No newline at end of file diff --git a/PlantUML/3.puml b/PlantUML/3.puml new file mode 100644 index 0000000..16c8503 --- /dev/null +++ b/PlantUML/3.puml @@ -0,0 +1,46 @@ +@startuml +skinparam titleBorderRoundCorner 15 +skinparam titleBorderThickness 2 +skinparam titleBorderColor red +skinparam titleBackgroundColor Aqua-CadetBlue + +title Current Friendly name process for\nNon Working Groups + +start +:GET "Groups Member Of"; +:Group 1 +{ + "extension": "UniconMemberGroup", + "displayName": "sandbox:UniconTest:Unicon Members Group", + "uuid": "35c1ae4d9529492aac8cb2acb970279b", + "enabled": "T", + "displayExtension": "Unicon Members Group", + "name": "sandbox:UniconTest:UniconMemberGroup", + "typeOfGroup": "group", + "idIndex": "18446" +}; +partition "Compare Displayname and Name Params for Group 1" { +:Data: +**displayName** = "sandbox:UniconTest:Unicon Members Group" +**name** = "sandbox:UniconTest:UniconMemberGroup"; +:**Logic: Compare each Stem section**; + +if (Does "sandbox" == "sandbox"?) then (yes) + if (Does "UniconTest" == "UniconTest"?) then (yes) + if (Does "Unicon Members Group" == "UniconMemberGroup"?) then (yes) + :**FriendlyName** = "sandbox:UniconTest:UniconMemberGroup" + (No variance between **name** and **displayName**); + else (no) + :**FriendlyName** = "Unicon Members Group"; + endif + else (no) + #red:**FriendlyName** = "Unicon Members Group"; + note right: Not possible + endif +else (no) + #red:**FriendlyName** = "UniconTest:Unicon Members Group"; + note: Not possible +endif +stop +} +@enduml \ No newline at end of file diff --git a/PlantUML/4.puml b/PlantUML/4.puml new file mode 100644 index 0000000..37a5912 --- /dev/null +++ b/PlantUML/4.puml @@ -0,0 +1,64 @@ +# Current Friendly name process for Working Groups that is broken +@startuml +skinparam titleBorderRoundCorner 15 +skinparam titleBorderThickness 2 +skinparam titleBorderColor red +skinparam titleBackgroundColor Aqua-CadetBlue + +title Current Friendly name process for\na Working Groups that is broken + +start +:GET "Groups Member Of"; +fork +:Group 1 +{ + "extension": "admins", + "displayName": "app:confluence:Axel Working Group:admins", + "description": "Admins of confluence space for working group. Axel's working group for testing", + "uuid": "35eaa34fd2d443e5a66a0a355505f69e", + "enabled": "T", + "displayExtension": "admins", + "name": "app:confluence:AxelWorkingGroup:admins", + "typeOfGroup": "group", + "idIndex": "19010" +}; +fork again +:Group 2 +{ + "extension": "users", + "displayName": "app:confluence:Axel Working Group:users", + "description": "Users of confluence space for working group. Axel's working group for testing", + "uuid": "163dc892fa8e484a9262e6e9fa619791", + "enabled": "T", + "displayExtension": "users", + "name": "app:confluence:AxelWorkingGroup:users", + "typeOfGroup": "group", + "idIndex": "19011" +}; +end fork +partition "Compare Displayname and Name Params from Group 2" { +:Group 2 Data: +**displayName** = "app:confluence:Axel Working Group:users" +**name** = "app:confluence:AxelWorkingGroup:users"; +:**Logic: Compare each Stem section**; + +if (Does "app" == "app"?) then (yes) + if (Does "confluence" == "confluence"?) then (yes) + if (Does "Axel Working Group" == "AxelWorkingGroup"?) then (yes) + :**FriendlyName** = "app:confluence:AxelWorkingGroup:users" + (No variance between **name** and **displayName**); + else (no) + #red:**FriendlyName** = "Axel Working Group"; + note right: Missing **:users** + endif + else (no) + #red:**FriendlyName** = "Axel Working Group:users"; + note right: Not possible + endif +else (no) + #red:**FriendlyName** = "confluence:Axel Working Group:users"; + note: Not possible +endif +stop +} +@enduml \ No newline at end of file diff --git a/PlantUML/5.puml b/PlantUML/5.puml new file mode 100644 index 0000000..3856ac4 --- /dev/null +++ b/PlantUML/5.puml @@ -0,0 +1,121 @@ +# Removed "enabled"", "typeOfGroup", ""uuid"" and "idIndex" from returned records for brevity +@startjson +{ +"wsGroups": [ + { + "extension": "CO_members_active", + "displayName": "app:comanage-provision:CO_members_active", + "description": "Internet2 Collaborations Active Members", + "displayExtension": "CO_members_active", + "name": "app:comanage-provision:CO_members_active", + "typeOfGroup": "group", + "idIndex": "11104" + }, + { + "extension": "admins", + "displayName": "app:confluence:Axel Working Group:admins", + "description": "Admins of confluence space for working group. Axel's working group for testing", + "displayExtension": "admins", + "name": "app:confluence:AxelWorkingGroup:admins" + }, + { + "extension": "users", + "displayName": "app:confluence:Axel Working Group:users", + "description": "Users of confluence space for working group. Axel's working group for testing", + "displayExtension": "users", + "name": "app:confluence:AxelWorkingGroup:users" + }, + { + "extension": "admins", + "displayName": "app:confluence:NewWorkingGroupTest1155:admins", + "description": "Admins of confluence space for working group. NewWorkingGroupTest1155", + "displayExtension": "admins", + "name": "app:confluence:NewWorkingGroupTest1155:admins" + }, + { + "extension": "admins", + "displayName": "app:jira:AxelWorkingGroup:admins", + "description": "Users of jira project for working group. Axel's working group for testing", + "displayExtension": "admins", + "name": "app:jira:AxelWorkingGroup:admins" + }, + { + "extension": "users", + "displayName": "app:jira:AxelWorkingGroup:users", + "description": "Subscribers list receives working group emails. Axel's working group for testing", + "displayExtension": "users", + "name": "app:jira:AxelWorkingGroup:users" + }, + { + "extension": "admins", + "displayName": "app:jira:NewWorkingGroupTest1155:admins", + "description": "Users of jira project for working group. NewWorkingGroupTest1155", + "displayExtension": "admins", + "name": "app:jira:NewWorkingGroupTest1155:admins" + }, + { + "extension": "owners", + "displayName": "app:sympa:internet2:AxelWorkingGroup:owners", + "description": "Owners list manages the email list for the working group. Axel's working group for testing", + "displayExtension": "owners", + "name": "app:sympa:internet2:AxelWorkingGroup:owners" + }, + { + "extension": "subscribers", + "displayName": "app:sympa:internet2:AxelWorkingGroup:subscribers", + "description": "Subscribers list receives working group emails. Axel's working group for testing", + "displayExtension": "subscribers", + "name": "app:sympa:internet2:AxelWorkingGroup:subscribers" + }, + { + "extension": "owners", + "displayName": "app:sympa:internet2:NewWorkingGroupTest1155:owners", + "description": "Owners list manages the email list for the working group. NewWorkingGroupTest1155", + "displayExtension": "owners", + "name": "app:sympa:internet2:NewWorkingGroupTest1155:owners" + }, + { + "extension": "grouperUiUserData", + "displayName": "etc:grouperUi:grouperUiUserData", + "description": "Internal group for grouper which has user data stored ...", + "displayExtension": "grouperUiUserData", + "name": "etc:grouperUi:grouperUiUserData" + }, + { + "extension": "sysadmingroup", + "displayName": "etc:sysadmingroup", + "description": "system administrators with all privileges", + "displayExtension": "sysadmingroup", + "name": "etc:sysadmingroup" + }, + { + "extension": "admins", + "displayName": "ref:InCommon-collab:AxelWorkingGroup:AxelWorkingGroup admins", + "description": "Admins role means can manage / attest the working group. Axel's working group for testing", + "displayExtension": "AxelWorkingGroup admins", + "name": "ref:incommon-collab:AxelWorkingGroup:admins" + }, + { + "extension": "users", + "displayName": "ref:InCommon-collab:AxelWorkingGroup:AxelWorkingGroup users", + "description": "Users role means members of the working group with access to collaboration tools. Axel's working group for testing", + "displayExtension": "AxelWorkingGroup users", + "name": "ref:incommon-collab:AxelWorkingGroup:users" + }, + { + "extension": "admins", + "displayName": "ref:InCommon-collab:NewWorkingGroupTest1155:NewWorkingGroupTest1155 admins", + "description": "Admins role means can manage / attest the working group. NewWorkingGroupTest1155", + "displayExtension": "NewWorkingGroupTest1155 admins", + "name": "ref:incommon-collab:NewWorkingGroupTest1155:admins" + }, + { + "extension": "workinggroupadmins", + "displayName": "ref:workinggroupadmins", + "description": "Being a member of this group enables you to create collaboration groups under ...", + "displayExtension": "workinggroupadmins", + "name": "ref:workinggroupadmins" + } + ] +} +@endjson \ No newline at end of file diff --git a/PlantUML/6.puml b/PlantUML/6.puml new file mode 100644 index 0000000..0999820 --- /dev/null +++ b/PlantUML/6.puml @@ -0,0 +1,27 @@ +# Info taken from https://spaces.at.internet2.edu/display/Grouper/Grouper+custom+template+via+GSH+Internet2+example +@startuml +skinparam titleBorderRoundCorner 15 +skinparam titleBorderThickness 2 +skinparam titleBorderColor red +skinparam titleBackgroundColor Aqua-CadetBlue + +title Process groups to verify if part of\na Working Group + +start +:Working Group Stems: +---- +* "app:jira" +* "app:confluence" +* "app:sympa:internet2" +* "app:sympa:incommon" +* "ref:InCommon-collab"; + +partition "For Each Group" { +if (Does "app:jira:AxelWorkingGroup:users" start with any **Working Group Stem**?) then (yes) + :Hold as part of a Working Group; +else (no) + :Next record"; +endif +} +stop +@enduml \ No newline at end of file diff --git a/PlantUML/7.puml b/PlantUML/7.puml new file mode 100644 index 0000000..24616f8 --- /dev/null +++ b/PlantUML/7.puml @@ -0,0 +1,63 @@ +@startuml +skinparam titleBorderRoundCorner 15 +skinparam titleBorderThickness 2 +skinparam titleBorderColor red +skinparam titleBackgroundColor Aqua-CadetBlue + +title With records held as part of\na Working Group + +start +:GET "Groups Member Of"; +fork +:Group 1 +{ + "extension": "admins", + "displayName": "app:confluence:Bill Working Group:admins", + "description": "Admins of confluence space for working group." + "displayExtension": "admins", + "name": "app:confluence:BillWorkingGroup:admins" +}; +fork again +:Group 2 +{ + "extension": "users", + "displayName": "app:confluence:Axel Working Group:users", + "description": "Users of confluence space for working group." + "displayExtension": "users", + "name": "app:confluence:AxelWorkingGroup:users" +}; +fork again +:Group 3 +{ + "extension": "admins", + "displayName": "app:jira:AxelWorkingGroup:admins", + "description": "Users of jira project for working group." + "displayExtension": "admins", + "name": "app:jira:AxelWorkingGroup:admins" +}; +end fork +partition "Compare Each Group to see if same Working Group" { +:Compare Group 1 and Group 2 +**Group 1 name** = "app:confluence:BillWorkingGroup:admins" +**Group 2 name** = "app:confluence:AxelWorkingGroup:users"; +:Assumption = Last section of name value is **ALWAYS** Members (users, admins) , therefore second to last section is Working Group Name; +if (Does "BillWorkingGroup" == "AxelWorkingGroup"?) then (yes) + :Save to BillWorkingGroup; +endif +:Compare Group 2 and Group 3; +if (Does "AxelWorkingGroup" == "AxelWorkingGroup"?) then (yes) + :Save to AxelWorkingGroup; +endif +} +stop + +:=//My Membership:// +---- +**BillWorkingGroup:** +* Confluence Admins +---- +**Axel Working Group:** +* Confluence Users +* Jira Admins; + +@enduml \ No newline at end of file diff --git a/PlantUML/GroupsBelongTo.puml b/PlantUML/GroupsBelongTo.puml new file mode 100644 index 0000000..c81241a --- /dev/null +++ b/PlantUML/GroupsBelongTo.puml @@ -0,0 +1,219 @@ + +# Removed "enabled"", "typeOfGroup", ""uuid"" and "idIndex" from returned records for brevity +@startjson +{ +"wsGroups": [ + { + "extension": "CO_members_active", + "displayName": "app:comanage-provision:CO_members_active", + "description": "Internet2 Collaborations Active Members", + "displayExtension": "CO_members_active", + "name": "app:comanage-provision:CO_members_active", + "typeOfGroup": "group", + "idIndex": "11104" + }, + { + "extension": "admins", + "displayName": "app:confluence:Axel Working Group:admins", + "description": "Admins of confluence space for working group. Axel's working group for testing", + "displayExtension": "admins", + "name": "app:confluence:AxelWorkingGroup:admins" + }, + { + "extension": "users", + "displayName": "app:confluence:Axel Working Group:users", + "description": "Users of confluence space for working group. Axel's working group for testing", + "displayExtension": "users", + "name": "app:confluence:AxelWorkingGroup:users" + }, + { + "extension": "admins", + "displayName": "app:confluence:NewWorkingGroupTest1155:admins", + "description": "Admins of confluence space for working group. NewWorkingGroupTest1155", + "displayExtension": "admins", + "name": "app:confluence:NewWorkingGroupTest1155:admins" + }, + { + "extension": "admins", + "displayName": "app:jira:AxelWorkingGroup:admins", + "description": "Users of jira project for working group. Axel's working group for testing", + "displayExtension": "admins", + "name": "app:jira:AxelWorkingGroup:admins" + }, + { + "extension": "users", + "displayName": "app:jira:AxelWorkingGroup:users", + "description": "Subscribers list receives working group emails. Axel's working group for testing", + "displayExtension": "users", + "name": "app:jira:AxelWorkingGroup:users" + }, + { + "extension": "admins", + "displayName": "app:jira:NewWorkingGroupTest1155:admins", + "description": "Users of jira project for working group. NewWorkingGroupTest1155", + "displayExtension": "admins", + "name": "app:jira:NewWorkingGroupTest1155:admins" + }, + { + "extension": "owners", + "displayName": "app:sympa:internet2:AxelWorkingGroup:owners", + "description": "Owners list manages the email list for the working group. Axel's working group for testing", + "displayExtension": "owners", + "name": "app:sympa:internet2:AxelWorkingGroup:owners" + }, + { + "extension": "subscribers", + "displayName": "app:sympa:internet2:AxelWorkingGroup:subscribers", + "description": "Subscribers list receives working group emails. Axel's working group for testing", + "displayExtension": "subscribers", + "name": "app:sympa:internet2:AxelWorkingGroup:subscribers" + }, + { + "extension": "owners", + "displayName": "app:sympa:internet2:NewWorkingGroupTest1155:owners", + "description": "Owners list manages the email list for the working group. NewWorkingGroupTest1155", + "displayExtension": "owners", + "name": "app:sympa:internet2:NewWorkingGroupTest1155:owners" + }, + { + "extension": "grouperUiUserData", + "displayName": "etc:grouperUi:grouperUiUserData", + "description": "Internal group for grouper which has user data stored ...", + "displayExtension": "grouperUiUserData", + "name": "etc:grouperUi:grouperUiUserData" + }, + { + "extension": "sysadmingroup", + "displayName": "etc:sysadmingroup", + "description": "system administrators with all privileges", + "displayExtension": "sysadmingroup", + "name": "etc:sysadmingroup" + }, + { + "extension": "admins", + "displayName": "ref:InCommon-collab:AxelWorkingGroup:AxelWorkingGroup admins", + "description": "Admins role means can manage / attest the working group. Axel's working group for testing", + "displayExtension": "AxelWorkingGroup admins", + "name": "ref:incommon-collab:AxelWorkingGroup:admins" + }, + { + "extension": "users", + "displayName": "ref:InCommon-collab:AxelWorkingGroup:AxelWorkingGroup users", + "description": "Users role means members of the working group with access to collaboration tools. Axel's working group for testing", + "displayExtension": "AxelWorkingGroup users", + "name": "ref:incommon-collab:AxelWorkingGroup:users" + }, + { + "extension": "admins", + "displayName": "ref:InCommon-collab:NewWorkingGroupTest1155:NewWorkingGroupTest1155 admins", + "description": "Admins role means can manage / attest the working group. NewWorkingGroupTest1155", + "displayExtension": "NewWorkingGroupTest1155 admins", + "name": "ref:incommon-collab:NewWorkingGroupTest1155:admins" + }, + { + "extension": "workinggroupadmins", + "displayName": "ref:workinggroupadmins", + "description": "Being a member of this group enables you to create collaboration groups under ...", + "displayExtension": "workinggroupadmins", + "name": "ref:workinggroupadmins" + } + ] +} +@endjson + + +============================================================= + +# Info taken from https://spaces.at.internet2.edu/display/Grouper/Grouper+custom+template+via+GSH+Internet2+example +@startuml +skinparam titleBorderRoundCorner 15 +skinparam titleBorderThickness 2 +skinparam titleBorderColor red +skinparam titleBackgroundColor Aqua-CadetBlue + +title Process groups to verify if part of\na Working Group + +start +:Working Group Stems: +---- +* "app:jira" +* "app:confluence" +* "app:sympa:internet2" +* "app:sympa:incommon" +* "ref:InCommon-collab"; + +partition "For Each Group" { +if (Does "app:jira:AxelWorkingGroup:users" start with any **Working Group Stem**?) then (yes) + :Hold as part of a Working Group; +else (no) + :Next record"; +endif +} +stop +@enduml + +============================================================= + +@startuml +skinparam titleBorderRoundCorner 15 +skinparam titleBorderThickness 2 +skinparam titleBorderColor red +skinparam titleBackgroundColor Aqua-CadetBlue + +title With records held as part of\na Working Group + +start +:GET "Groups Member Of"; +fork +:Group 1 +{ + "extension": "admins", + "displayName": "app:confluence:Bill Working Group:admins", + "description": "Admins of confluence space for working group." + "displayExtension": "admins", + "name": "app:confluence:BillWorkingGroup:admins" +}; +fork again +:Group 2 +{ + "extension": "users", + "displayName": "app:confluence:Axel Working Group:users", + "description": "Users of confluence space for working group." + "displayExtension": "users", + "name": "app:confluence:AxelWorkingGroup:users" +}; +fork again +:Group 3 +{ + "extension": "admins", + "displayName": "app:jira:AxelWorkingGroup:admins", + "description": "Users of jira project for working group." + "displayExtension": "admins", + "name": "app:jira:AxelWorkingGroup:admins" +}; +end fork +partition "Compare Each Group to see if same Working Group" { +:Compare Group 1 and Group 2 +**Group 1 name** = "app:confluence:BillWorkingGroup:admins" +**Group 2 name** = "app:confluence:AxelWorkingGroup:users"; +:Assumption = Last section of name value is **ALWAYS** Members (users, admins) , therefore second to last section is Working Group Name; +if (Does "BillWorkingGroup" == "AxelWorkingGroup"?) then (yes) + :Save to BillWorkingGroup; +endif +:Compare Group 2 and Group 3; +if (Does "AxelWorkingGroup" == "AxelWorkingGroup"?) then (yes) + :Save to AxelWorkingGroup; +endif +} +stop + +:=//My Membership:// +---- +**BillWorkingGroup:** +* Confluence Admins +---- +**Axel Working Group:** +* Confluence Users +* Jira Admins; + +@enduml \ No newline at end of file diff --git a/PlantUML/MyMemberProcess.puml b/PlantUML/MyMemberProcess.puml new file mode 100644 index 0000000..211ce24 --- /dev/null +++ b/PlantUML/MyMemberProcess.puml @@ -0,0 +1,219 @@ +# Data from API call to get all Groups belong to +@startjson +#highlight "WsGetGroupsLiteResult" / "wsGroups" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "0" / "name" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "0" / "displayName" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "0" / "description" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "1" / "name" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "1" / "displayName" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "1" / "description" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "2" / "name" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "2" / "displayName" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "2" / "description" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "3" / "name" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "3" / "displayName" +#highlight "WsGetGroupsLiteResult" / "wsGroups" / "3" / "description" +{ + "WsGetGroupsLiteResult": { + "resultMetadata": { + "success": "T", + "resultCode": "SUCCESS" + }, + "wsSubject": { + "...": "..." + }, + "responseMetadata": { + "...": "..." + }, + "wsGroups": [ + { + "extension": "CO_members_active", + "displayName": "app:comanage-provision:CO_members_active", + "description": "Internet2 Collaborations Active Members", + "uuid": "f5dae468b9d9429993992781712c2f83", + "enabled": "T", + "displayExtension": "CO_members_active", + "name": "app:comanage-provision:CO_members_active", + "typeOfGroup": "group", + "idIndex": "11104" + }, + { + "extension": "grouperUiUserData", + "displayName": "etc:grouperUi:grouperUiUserData", + "description": "Internal group for grouper which has ...", + "uuid": "2748e23e51174145a4dc4d9e115c59da", + "enabled": "T", + "displayExtension": "grouperUiUserData", + "name": "etc:grouperUi:grouperUiUserData", + "typeOfGroup": "group", + "idIndex": "10015" + }, + { + "extension": "AdministeredByUniconFolks", + "displayName": "sandbox:UniconTest:Administered By Unicon Folks", + "description": "Description goes here", + "uuid": "0b26aa411a99405b9440be3d0b18dafa", + "enabled": "T", + "displayExtension": "Administered By Unicon Folks", + "name": "sandbox:UniconTest:AdministeredByUniconFolks", + "typeOfGroup": "group", + "idIndex": "18451" + }, + { + "extension": "MembersFromUniconAZ", + "displayName": "sandbox:UniconTest:Members At Unicon in AZ", + "uuid": "7a9f3b9837024a56b12a2a6259d520e0", + "enabled": "T", + "displayExtension": "Members At Unicon in AZ", + "name": "sandbox:UniconTest:MembersFromUniconAZ", + "typeOfGroup": "group", + "idIndex": "18447" + } + ] + } +} +@endjson + +============================================================= + +@startuml +skinparam titleBorderRoundCorner 15 +skinparam titleBorderThickness 2 +skinparam titleBorderColor red +skinparam titleBackgroundColor Aqua-CadetBlue + +title Mapping of //My Membership// page to API results + +map "** API Grouper (with example data) => My Membership Page **" as CC { + extension = CO_members_active => NA + displayName = app:comanage-provision:CO_members_active => Name + description = Internet2 Collaborations Active Members => Description + uuid = f5dae468b9d9429993992781712c2f83 => NA + enabled = T => NA + displayExtension = CO_members_active => NA + name = app:comanage-provision:CO_members_active => Name + typeOfGroup = group => NA + idIndex = 11104 => NA +} + +note right of CC + Name Fields are used to determine Friendly Name +end note + +@enduml + +============================================================= + +@startuml +skinparam titleBorderRoundCorner 15 +skinparam titleBorderThickness 2 +skinparam titleBorderColor red +skinparam titleBackgroundColor Aqua-CadetBlue + +title Current Friendly name process for\nNon Working Groups + +start +:GET "Groups Member Of"; +:Group 1 +{ + "extension": "UniconMemberGroup", + "displayName": "sandbox:UniconTest:Unicon Members Group", + "uuid": "35c1ae4d9529492aac8cb2acb970279b", + "enabled": "T", + "displayExtension": "Unicon Members Group", + "name": "sandbox:UniconTest:UniconMemberGroup", + "typeOfGroup": "group", + "idIndex": "18446" +}; +partition "Compare Displayname and Name Params for Group 1" { +:Data: +**displayName** = "sandbox:UniconTest:Unicon Members Group" +**name** = "sandbox:UniconTest:UniconMemberGroup"; +:**Logic: Compare each Stem section**; + +if (Does "sandbox" == "sandbox"?) then (yes) + if (Does "UniconTest" == "UniconTest"?) then (yes) + if (Does "Unicon Members Group" == "UniconMemberGroup"?) then (yes) + :**FriendlyName** = "sandbox:UniconTest:UniconMemberGroup" + (No variance between **name** and **displayName**); + else (no) + :**FriendlyName** = "Unicon Members Group"; + endif + else (no) + #red:**FriendlyName** = "Unicon Members Group"; + note right: Not possible + endif +else (no) + #red:**FriendlyName** = "UniconTest:Unicon Members Group"; + note: Not possible +endif +stop +} +@enduml + +============================================================= + +# Current Friendly name process for Working Groups that is broken +@startuml +skinparam titleBorderRoundCorner 15 +skinparam titleBorderThickness 2 +skinparam titleBorderColor red +skinparam titleBackgroundColor Aqua-CadetBlue + +title Current Friendly name process for\na Working Groups that is broken + +start +:GET "Groups Member Of"; +fork +:Group 1 +{ + "extension": "admins", + "displayName": "app:confluence:Axel Working Group:admins", + "description": "Admins of confluence space for working group. Axel's working group for testing", + "uuid": "35eaa34fd2d443e5a66a0a355505f69e", + "enabled": "T", + "displayExtension": "admins", + "name": "app:confluence:AxelWorkingGroup:admins", + "typeOfGroup": "group", + "idIndex": "19010" +}; +fork again +:Group 2 +{ + "extension": "users", + "displayName": "app:confluence:Axel Working Group:users", + "description": "Users of confluence space for working group. Axel's working group for testing", + "uuid": "163dc892fa8e484a9262e6e9fa619791", + "enabled": "T", + "displayExtension": "users", + "name": "app:confluence:AxelWorkingGroup:users", + "typeOfGroup": "group", + "idIndex": "19011" +}; +end fork +partition "Compare Displayname and Name Params from Group 2" { +:Group 2 Data: +**displayName** = "app:confluence:Axel Working Group:users" +**name** = "app:confluence:AxelWorkingGroup:users"; +:**Logic: Compare each Stem section**; + +if (Does "app" == "app"?) then (yes) + if (Does "confluence" == "confluence"?) then (yes) + if (Does "Axel Working Group" == "AxelWorkingGroup"?) then (yes) + :**FriendlyName** = "app:confluence:AxelWorkingGroup:users" + (No variance between **name** and **displayName**); + else (no) + #red:**FriendlyName** = "Axel Working Group"; + note right: Missing **:users** + endif + else (no) + #red:**FriendlyName** = "Axel Working Group:users"; + note right: Not possible + endif +else (no) + #red:**FriendlyName** = "confluence:Axel Working Group:users"; + note: Not possible +endif +stop +} +@enduml diff --git a/View/GrouperGroups/groupmember.ctp b/View/GrouperGroups/groupmember.ctp index 734a40c..9074a6d 100644 --- a/View/GrouperGroups/groupmember.ctp +++ b/View/GrouperGroups/groupmember.ctp @@ -2,7 +2,7 @@ Html->addCrumb(_txt('pl.grouperlite.nav.memberships')); ?> element('GrouperLite.Components/navigation-groups', array('active' => 'groupmember')); ?> element('GrouperLite.Components/search', array('active' => 'groupmember')); ?> - 0) : ?> + 0 || count($wgmemberships) > 0) : ?>
element("pagination", array( 'goto' => false, @@ -20,7 +20,7 @@ - $group) : ?> + $group) : ?> - + ) ?>" title=""> + element('GrouperLite.Components/optAction', array( 'member' => $group['optOut'], @@ -40,6 +40,36 @@ + + + + + + $group) : ?> + + + + + + + +
+ element('GrouperLite.Components/optAction', array( + 'member' => $group['optOut'], + 'action' => 'leavegroup', + 'group' => $group['name'], + 'idx' => $key + )) : ''; ?> +
+ + + element("pagination", array( @@ -50,7 +80,7 @@ )); ?>
- +

diff --git a/View/GrouperGroups/groupoptin.ctp b/View/GrouperGroups/groupoptin.ctp index e17a2c7..d275e14 100644 --- a/View/GrouperGroups/groupoptin.ctp +++ b/View/GrouperGroups/groupoptin.ctp @@ -2,55 +2,88 @@ Html->addCrumb(_txt('pl.grouperlite.nav.groups-can-join')); ?> element('GrouperLite.Components/navigation-groups', array('active' => 'groupoptin')); ?> element('GrouperLite.Components/search', array('active' => 'groupoptin')); ?> - 0) : ?> -
- element("pagination", array( + 0 || count($wgoptins) > 0) : ?> +
+ element("pagination", array( 'goto' => false, 'limit' => false, 'numbers' => false, 'counter' => true, 'class' => 'counter' - )); ?> - - + )); ?> +
+ - - - $group) : ?> + + + $group) : ?> - + array( + 'controller' => 'grouper_groups', + 'action' => 'groupinfo', + '?' => array('groupname' => urlencode($group['name'])) + ) + ) ?>" title=""> + + + + + + + - -
- element('GrouperLite.Components/optAction', array( - 'member' => $group['member'], - 'action' => 'joingroup', - 'group' => $group['name'], - 'idx' => $key - )); ?> + element('GrouperLite.Components/optAction', array( + 'member' => $group['member'], + 'action' => 'joingroup', + 'group' => $group['name'], + 'idx' => $key + )); ?> +
+ + + $group) : ?> + + + + + + + +
+ + element('GrouperLite.Components/optAction', array( + 'member' => $group['member'], + 'action' => 'joingroup', + 'group' => $group['name'], + 'idx' => $key + )); ?> +
- element("pagination", array( + + + element("pagination", array( 'goto' => false, 'limit' => true, 'numbers' => true, 'counter' => false - )); ?> -
+ )); ?> +
- +

diff --git a/View/GrouperGroups/groupowner.ctp b/View/GrouperGroups/groupowner.ctp index 0654d39..05b7892 100644 --- a/View/GrouperGroups/groupowner.ctp +++ b/View/GrouperGroups/groupowner.ctp @@ -3,37 +3,39 @@ element('Components/navigation-groups', array('active' => 'groupowner')); ?> element('Components/search', array('active' => 'groupowner')); ?> - 0) : ?> + 0 || count($wgowners) > 0) : ?>
- element("pagination", array( - 'goto' => false, - 'limit' => false, - 'numbers' => false, - 'counter' => true, - 'class' => 'counter' - )); ?> + element("pagination", array( + 'goto' => false, + 'limit' => false, + 'numbers' => false, + 'counter' => true, + 'class' => 'counter' + )); ?> - - - - - - + + + + + + - - - - - - + + + + - - + + + + + + + +
+ +
+ -
+ + + $group) : ?> + + + + + + + + +
+ + + + + +
+
- element("pagination", array( - 'goto' => false, - 'limit' => true, - 'numbers' => true, - 'counter' => false - )); ?> + element("pagination", array( + 'goto' => false, + 'limit' => true, + 'numbers' => true, + 'counter' => false + )); ?>
- +