monster_menus-9.0.x-dev/src/Plugin/MMSearchAction/ModifyGroupMembers.php
src/Plugin/MMSearchAction/ModifyGroupMembers.php
<?php
namespace Drupal\monster_menus\Plugin\MMSearchAction;
use Drupal\Core\Form\FormStateInterface;
use Drupal\monster_menus\Annotation\MMSearchAction;
use Drupal\monster_menus\Constants;
use Drupal\monster_menus\Entity\MMTree;
use Drupal\monster_menus\MMSearchAction\MMSearchActionBase;
/**
* Provides the MM Search Results Action to modify page/node permissions.
*
* @MMSearchAction(
* id = "mm_search_action_modify_group",
* label = @Translation("modify group membership"),
* description = @Translation("Provides the MM Search Results Action to modify group membership."),
* useDrupalSettings = true,
* jsInit = "MMSR_init_action_modify_perms",
* )
*/
class ModifyGroupMembers extends MMSearchActionBase {
use ResultsTrait;
final public const ADD_GROUP_MEMBER = 'add_mem';
final public const DEL_GROUP_MEMBER = 'del_mem';
final public const SESSION_DATA = 'mmsr-mg';
/**
* @inheritDoc
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['modify_mode'] = [
'#type' => 'select',
'#options' => [
self::ADD_GROUP_MEMBER => $this->t('add members to group'),
self::DEL_GROUP_MEMBER => $this->t('delete members from group'),
],
'#default_value' => $_SESSION[self::SESSION_DATA]['modify_mode'] ?? self::ADD_GROUP_MEMBER,
];
$form['modify_perms'] = [
'modify' => [
'#type' => 'container',
'#tree' => TRUE,
'users_w-choose' => [
'#type' => 'textfield',
'#attributes' => ['autocomplete' => 'off'], // Prevent FF from caching a previous value
'#autocomplete_route_name' => 'monster_menus.autocomplete',
'#size' => 30,
],
'users_w' => [
'#type' => 'mm_userlist',
'#title' => $this->t('Members'),
'#mm_list_autocomplete_name' => 'modify[users_w-choose]',
'#default_value' => $_SESSION[self::SESSION_DATA]['users_w'] ?? [],
],
],
];
$form['actions'] = [
'#type' => 'actions',
'calc' => [
'#type' => 'submit',
'#value' => $this->t('Calculate'),
'#attributes' => ['onclick' => 'MMSR_recalculate_action(this); return false;'],
],
'mp_result' => [
'#type' => 'submit',
'#value' => $this->t('Modify Membership'),
'#attributes' => ['onclick' => 'var t = jQuery("#mmsr-mp-status-text").text(); if (!t || confirm(t)) MMSR_recalculate_action(this); return false;'],
],
];
$this->addStatusMarkup($form);
return $form;
}
/**
* @inheritDoc
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->setSubmittedValues($form_state);
$this->iterate(function() {}, $this->iterateGroup(...));
$_SESSION[self::SESSION_DATA] = [
'modify_mode' => $this->values['modify_mode'],
'groups_w' => $this->values['modify']['groups_w'],
'users_w' => $this->values['modify']['users_w'],
];
$this->returnResults($this->updateNeeded);
}
public function iterateGroup($row) {
if (mm_content_user_can($row->mmtid, Constants::MM_PERMS_WRITE) && !mm_content_is_vgroup($row->mmtid)) {
if ($tree = MMTree::load($row->mmtid)) {
$this->countAllowed++;
$changed = FALSE;
if (!empty($this->values['modify']['users_w'])) {
$changed_members = array_keys($this->values['modify']['users_w']);
switch ($this->values['modify_mode']) {
case self::ADD_GROUP_MEMBER:
if (array_diff($changed_members, $tree->members)) {
$changed = TRUE;
if ($this->updateNeeded) {
$this->setTreeMembers($tree, array_unique(array_merge($tree->members, $changed_members)));
}
}
break;
case self::DEL_GROUP_MEMBER:
if (array_intersect($changed_members, $tree->members)) {
$changed = TRUE;
if ($this->updateNeeded) {
$this->setTreeMembers($tree, array_diff($tree->members, $changed_members));
}
}
break;
}
}
if ($changed) {
$this->countChanged++;
if ($this->updateNeeded) {
$tree->save();
}
}
}
}
}
private function setTreeMembers(MMTree $tree, $list) {
$settings = $tree->getExtendedSettings();
$settings['members'] = $list;
$tree->setExtendedSettings($settings);
}
/**
* @inheritDoc
*/
public function applies() {
return $this->getConfiguration('search_type') == self::SEARCH_TYPE_GROUPS;
}
/**
* @inheritDoc
*/
public function access() {
if ($this->getConfiguration('result_count') > 0) {
$return = $this->iterate(fn() => FALSE, function ($row) {
if (mm_content_user_can($row->mmtid, Constants::MM_PERMS_WRITE) && !mm_content_is_vgroup($row->mmtid)) {
return TRUE;
}
});
return !empty($return);
}
return FALSE;
}
}