Newer
Older
* @file
* Implementations of administration functions for the acl module.
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
Hans Salvisberg
committed
use Drupal\Core\Entity\Element\EntityAutocomplete;
Hans Salvisberg
committed
use Drupal\user\Entity\User;
*/
function _acl_edit_form($acl_id, $label = NULL, $new_acl = FALSE) {
Hans Salvisberg
committed
$database = \Drupal::database();
if (!$new_acl) {
// Ensure the ACL in question even exists.
Hans Salvisberg
committed
if (!($record = $database->query("SELECT name, figure FROM {acl} WHERE acl_id = :acl_id", [
])->fetchAssoc())) {
Hans Salvisberg
committed
return [];
Hans Salvisberg
committed
$accounts = acl_get_usernames($acl_id);
else {
$accounts = [];
}
if (isset($record['name'])) {
$label = $record['name'];
}
elseif (isset($record['figure'])) {
$label = $record['figure'];
}
else {
$label = $acl_id;
}
Hans Salvisberg
committed
$form = [
Hans Salvisberg
committed
'#type' => 'details',
'#title' => Html::escape($label),
Hans Salvisberg
committed
];
Hans Salvisberg
committed
$form['acl_id'] = [
'#type' => 'value',
'#value' => $acl_id,
Hans Salvisberg
committed
];
Hans Salvisberg
committed
$form['deletions'] = [
'#type' => 'checkboxes',
Hans Salvisberg
committed
'#options' => [],
];
$form['delete_button'] = [
'#name' => 'acl_' . $acl_id,
Hans Salvisberg
committed
'#submit' => [],
];
Hans Salvisberg
committed
$form['add'] = [
Hans Salvisberg
committed
'#type' => 'entity_autocomplete',
'#target_type' => 'user',
'#title' => t('Add user'),
'#maxlength' => 60,
'#size' => 40,
Hans Salvisberg
committed
'#selection_settings' => ['include_anonymous' => FALSE],
Hans Salvisberg
committed
];
$form['add_button'] = [
'#name' => 'acl_' . $acl_id,
Hans Salvisberg
committed
'#submit' => [],
];
Hans Salvisberg
committed
$form['user_list'] = [
'#default_value' => json_encode($accounts),
Hans Salvisberg
committed
];
Hans Salvisberg
committed
$form['user_list_changed'] = [
'#type' => 'hidden',
'#value' => FALSE,
];
$form['#after_build'] = ['_acl_edit_form_after_build'];
return $form;
}
/**
* Process a form that had our buttons on it.
*/
function _acl_edit_form_after_build($form, FormStateInterface $form_state) {
Hans Salvisberg
committed
// We can't use the form values because it's the entire structure,
// and we have no clue where our values actually are.
// That's ok though, because #value still works for us.
$user_list = acl_edit_form_get_user_list($form);
$triggering_element = $form_state->getTriggeringElement();
if (!empty($triggering_element) && $triggering_element['#value'] == $form['delete_button']['#value']) {
$deletions = $form['deletions']['#value'];
foreach ($deletions as $uid) {
unset($user_list[$uid]);
unset($form['deletions']['#value'][$uid]);
}
}
elseif (!empty($triggering_element['#value']) && $triggering_element['#value'] == $form['add_button']['#value'] && !empty($form['add']['#value'])) {
Hans Salvisberg
committed
$value = $form['add']['#value'];
if ($match = EntityAutocomplete::extractEntityIdFromAutocompleteInput($value)) {
$user = @User::load($match);
}
if (empty($user)) {
$form_state->setError($form['add'], t("Invalid user specified."));
Hans Salvisberg
committed
$user_list[$user->id()] = $user->getDisplayName();
Hans Salvisberg
committed
$form['add']['#value'] = '';
}
}
if (count($user_list) != 0) {
$form['deletions']['#type'] = 'checkboxes';
$form['deletions']['#title'] = t("Current users");
$form['deletions']['#options'] = $user_list;
Hans Salvisberg
committed
// Don't carry the value through.
$form['deletions']['#value'] = [];
$form['deletions'] = \Drupal::formBuilder()->doBuildForm(!empty($form['#post']) ? $form['#post']['form_id'] : 'acl_form', $form['deletions'], $form_state);
}
else {
$form['delete_button']['#type'] = 'value';
}
$form['user_list']['#value'] = json_encode($user_list);
Hans Salvisberg
committed
$original_user_list = acl_edit_form_get_user_list($form, TRUE);
$form['user_list_changed']['#value'] = !empty(array_diff($original_user_list, $user_list)) || !empty(array_diff($user_list, $original_user_list));
* Write the results of a form.
*
* The module that embedded our form must call this function!
Hans Salvisberg
committed
*
* @param array $form
* The ACL edit form part of the form_state array.
* @param null|int $priority
* The priority of the calling module's node access grants.
*/
function acl_save_form($form, $priority = NULL) {
Hans Salvisberg
committed
$database = \Drupal::database();
$users = acl_edit_form_get_user_list($form);
Hans Salvisberg
committed
$database->delete('acl_user')
->condition('acl_id', $form['acl_id'])
->execute();
$insert = $database->insert('acl_user')->fields(['acl_id', 'uid']);
foreach ($users as $uid => $name) {
$insert->values([
'acl_id' => $form['acl_id'],
'uid' => $uid,
]);
$insert->execute();
Hans Salvisberg
committed
$database->update('acl_node')
->fields([
->condition('acl_id', $form['acl_id'])
->execute();
/**
* Decode and return the list of users.
*
* @param array $form
Hans Salvisberg
committed
* The ACL form array or the ACL edit form array part of the form_state.
* @param bool $get_default
* (optional) In the case of a form array, whether to return the
* '#default_value' (or the '#value').
*
* @return array
* An array of $uid => $username.
*/
Hans Salvisberg
committed
function acl_edit_form_get_user_list(array $form, $get_default = FALSE) {
if (is_array($form['user_list'])) {
return json_decode($form['user_list'][$get_default ? '#default_value' : '#value'], TRUE);
}
return json_decode($form['user_list'], TRUE);
}
Hans Salvisberg
committed
Hans Salvisberg
committed
/**
* Check whether the user_list has been changed or not.
*
* @param array $form
* The ACL form array or the ACL edit form array part of the form_state.
*
* @return bool
* TRUE if the user_list has been changed.
*/
function acl_edit_form_get_user_list_changed($form) {
return $form['user_list_changed']['#value'] ?? $form['user_list_changed'];
}