Skip to content

Commit f9f1538

Browse files
Implement new search field to add user as group member
* Introduce new `UserSuggestions` class for search suggestions * Make AddMemberForm an Ipl form extending `SimpleSearchField`
1 parent 62d7ca8 commit f9f1538

File tree

3 files changed

+230
-112
lines changed

3 files changed

+230
-112
lines changed

application/controllers/GroupController.php

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Icinga\Data\DataArray\ArrayDatasource;
1010
use Icinga\Data\Filter\Filter;
1111
use Icinga\Data\Reducible;
12+
use Icinga\Data\UserSuggestions;
1213
use Icinga\Exception\NotFoundError;
1314
use Icinga\Forms\Config\UserGroup\AddMemberForm;
1415
use Icinga\Forms\Config\UserGroup\UserGroupForm;
@@ -17,7 +18,7 @@
1718
use Icinga\Web\Form;
1819
use Icinga\Web\Notification;
1920
use Icinga\Web\Url;
20-
use Icinga\Web\Widget;
21+
use ipl\Web\Url as IplUrl;
2122

2223
class GroupController extends AuthBackendController
2324
{
@@ -224,24 +225,50 @@ public function addmemberAction()
224225
{
225226
$this->assertPermission('config/access-control/groups');
226227
$groupName = $this->params->getRequired('group');
227-
$backend = $this->getUserGroupBackend($this->params->getRequired('backend'), 'Icinga\Data\Extensible');
228+
$backend = $this->getUserGroupBackend(
229+
$this->params->getRequired('backend'),
230+
'Icinga\Data\Extensible'
231+
);
228232

229-
$form = new AddMemberForm();
230-
$form->setDataSource($this->fetchUsers())
233+
$form = (new AddMemberForm())
231234
->setBackend($backend)
232235
->setGroupName($groupName)
233236
->setRedirectUrl(
234-
Url::fromPath('group/show', array('backend' => $backend->getName(), 'group' => $groupName))
237+
IplUrl::fromPath('group/show', ['backend' => $backend->getName(), 'group' => $groupName])
235238
)
236-
->setUidDisabled();
239+
->setSuggestionUrl(IplUrl::fromPath(
240+
'group/complete',
241+
[
242+
'_disableLayout' => true,
243+
'showCompact' => true,
244+
'backend' => $this->params->getRequired('backend'),
245+
'group' => $groupName
246+
]
247+
));
237248

238-
try {
239-
$form->handleRequest();
240-
} catch (NotFoundError $_) {
241-
$this->httpNotFound(sprintf($this->translate('Group "%s" not found'), $groupName));
242-
}
249+
$form->on(AddMemberForm::ON_SUCCESS, function ($form) {
250+
$this->getResponse()->redirectAndExit($form->getRedirectUrl());
251+
})->handleRequest($this->getServerRequest());
252+
253+
$this->addTitleTab($this->translate('New User Group Member'));
254+
$this->addContent($form);
255+
}
256+
257+
public function completeAction()
258+
{
259+
$backend = $this->getUserGroupBackend(
260+
$this->params->getRequired('backend'),
261+
'Icinga\Data\Extensible'
262+
);
263+
264+
$groupName = $this->params->getRequired('group');
243265

244-
$this->renderForm($form, $this->translate('New User Group Member'));
266+
$suggestions = (new UserSuggestions())
267+
->setUserGroupName($groupName)
268+
->setUserGroupBackend($backend)
269+
->setUserBackends($this->loadUserBackends('Icinga\Data\Selectable'))
270+
->forRequest($this->getServerRequest());
271+
$this->getDocument()->addHtml($suggestions);
245272
}
246273

247274
/**
Lines changed: 20 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,18 @@
11
<?php
2-
/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */
2+
/* Icinga Web 2 | (c) 2015 Icinga GmbH | GPLv2+ */
33

44
namespace Icinga\Forms\Config\UserGroup;
55

66
use Exception;
77
use Icinga\Data\Extensible;
8-
use Icinga\Data\Filter\Filter;
9-
use Icinga\Data\Selectable;
10-
use Icinga\Exception\NotFoundError;
11-
use Icinga\Web\Form;
128
use Icinga\Web\Notification;
9+
use ipl\Web\Control\SimpleSearchField;
1310

1411
/**
1512
* Form for adding one or more group members
1613
*/
17-
class AddMemberForm extends Form
14+
class AddMemberForm extends SimpleSearchField
1815
{
19-
/**
20-
* The data source to fetch users from
21-
*
22-
* @var Selectable
23-
*/
24-
protected $ds;
25-
2616
/**
2717
* The user group backend to use
2818
*
@@ -37,19 +27,6 @@ class AddMemberForm extends Form
3727
*/
3828
protected $groupName;
3929

40-
/**
41-
* Set the data source to fetch users from
42-
*
43-
* @param Selectable $ds
44-
*
45-
* @return $this
46-
*/
47-
public function setDataSource(Selectable $ds)
48-
{
49-
$this->ds = $ds;
50-
return $this;
51-
}
52-
5330
/**
5431
* Set the user group backend to use
5532
*
@@ -76,107 +53,50 @@ public function setGroupName($groupName)
7653
return $this;
7754
}
7855

79-
/**
80-
* Create and add elements to this form
81-
*
82-
* @param array $formData The data sent by the user
83-
*/
84-
public function createElements(array $formData)
56+
public function onSuccess()
8557
{
86-
// TODO(jom): Fetching already existing members to prevent the user from mistakenly creating duplicate
87-
// memberships (no matter whether the data source permits it or not, a member does never need to be
88-
// added more than once) should be kept at backend level (GroupController::fetchUsers) but this does
89-
// not work currently as our ldap protocol stuff is unable to handle our filter implementation..
90-
$members = $this->backend
91-
->select()
92-
->from('group_membership', array('user_name'))
93-
->where('group_name', $this->groupName)
94-
->fetchColumn();
95-
$filter = empty($members) ? Filter::matchAll() : Filter::not(Filter::where('user_name', $members));
58+
$q = $this->getValue($this->getSearchParameter());
59+
if (empty($q)) {
60+
Notification::info(t('Please provide at least one username'));
9661

97-
$users = $this->ds->select()->from('user', array('user_name'))->applyFilter($filter)->fetchColumn();
98-
if (! empty($users)) {
99-
$this->addElement(
100-
'multiselect',
101-
'user_name',
102-
array(
103-
'multiOptions' => array_combine($users, $users),
104-
'label' => $this->translate('Backend Users'),
105-
'description' => $this->translate(
106-
'Select one or more users (fetched from your user backends) to add as group member'
107-
),
108-
'class' => 'grant-permissions'
109-
)
110-
);
62+
return;
11163
}
11264

113-
$this->addElement(
114-
'textarea',
115-
'users',
116-
array(
117-
'required' => empty($users),
118-
'label' => $this->translate('Users'),
119-
'description' => $this->translate(
120-
'Provide one or more usernames separated by comma to add as group member'
121-
)
122-
)
65+
$userNames = array_unique(
66+
explode(self::TERM_SEPARATOR, urldecode($q))
12367
);
12468

125-
$this->setTitle(sprintf($this->translate('Add members for group %s'), $this->groupName));
126-
$this->setSubmitLabel($this->translate('Add'));
127-
}
128-
129-
/**
130-
* Insert the members for the group
131-
*
132-
* @return bool
133-
*/
134-
public function onSuccess()
135-
{
136-
$userNames = $this->getValue('user_name') ?: array();
137-
if (($users = $this->getValue('users'))) {
138-
$userNames = array_merge($userNames, array_map('trim', explode(',', $users)));
139-
}
140-
141-
if (empty($userNames)) {
142-
$this->info($this->translate(
143-
'Please provide at least one username, either by choosing one '
144-
. 'in the list or by manually typing one in the text box below'
145-
));
146-
return false;
147-
}
69+
$userNames = array_filter(
70+
array_map('trim', $userNames)
71+
);
14872

14973
$single = null;
15074
foreach ($userNames as $userName) {
15175
try {
15276
$this->backend->insert(
15377
'group_membership',
154-
array(
78+
[
15579
'group_name' => $this->groupName,
15680
'user_name' => $userName
157-
)
81+
]
15882
);
159-
} catch (NotFoundError $e) {
160-
throw $e; // Trigger 404, the group name is initially accessed as GET parameter
16183
} catch (Exception $e) {
16284
Notification::error(sprintf(
163-
$this->translate('Failed to add "%s" as group member for "%s"'),
85+
t('Failed to add "%s" as group member for "%s"'),
16486
$userName,
16587
$this->groupName
16688
));
167-
$this->error($e->getMessage());
168-
return false;
89+
90+
return;
16991
}
17092

17193
$single = $single === null;
17294
}
17395

17496
if ($single) {
175-
Notification::success(sprintf($this->translate('Group member "%s" added successfully'), $userName));
97+
Notification::success(sprintf(t('Group member "%s" added successfully'), $userName));
17698
} else {
177-
Notification::success($this->translate('Group members added successfully'));
99+
Notification::success(t('Group members added successfully'));
178100
}
179-
180-
return true;
181101
}
182102
}

0 commit comments

Comments
 (0)