monster_menus-9.0.x-dev/src/Plugin/MMSearchAction/CleanPermissions.php
src/Plugin/MMSearchAction/CleanPermissions.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\node\Entity\Node;
/**
* Provides the MM Search Results Action to clean page/node permissions.
*
* @MMSearchAction(
* id = "mm_search_action_clean_perms",
* label = @Translation("clean permissions"),
* description = @Translation("Provides the MM Search Results Action to clean messy permissions."),
* useDrupalSettings = true,
* jsInit = "MMSR_init_action_clean_perms",
* )
*/
class CleanPermissions extends ModifyPermissions {
use ResultsTrait;
/**
* @inheritDoc
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$effects = [];
$search_type = $this->getConfiguration('search_type');
if ($search_type == self::SEARCH_TYPE_GROUPS) {
$effects[] = $this->t('Remove the <strong>Add Content</strong> permission from groups');
}
if ($search_type == self::SEARCH_TYPE_NODES || $search_type == self::SEARCH_TYPE_NODES_ON_PAGES) {
$effects[] = $this->t('Remove the <strong>Owner</strong> from the list of individual users who can edit the content');
}
else {
$effects[] = $this->t('Remove the <strong>Owner</strong> from the list of individual users having any permission');
$effects[] = $this->t('Remove other unnecessarily duplicated permissions');
}
$form['help'] = [
'#markup' => $this->t('<p>This action will always:<ul><li>') . implode('</li><li>', $effects) . '</li></ul></p>',
];
$form['remove_indiv'] = [
'#type' => 'checkbox',
'#title' => $this->t('Also remove individual users who are members of a group with the same permission'),
'#default_value' => $_SESSION['mmsr-cp']['remove_indiv'] ?? FALSE,
];
$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('Execute'),
'#attributes' => ['onclick' => '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($this->iterateNode(...), $this->iteratePage(...));
$_SESSION['mmsr-cp']['remove_indiv'] = !empty($this->values['remove_indiv']);
$this->returnResults($this->updateNeeded);
}
public function iterateNode($row) {
if (mm_content_user_can_node($row->nid, Constants::MM_PERMS_WRITE)) {
if ($node = Node::load($row->nid)) {
$this->countAllowed++;
$changed = FALSE;
// Remove owner from individuals list.
if (in_array($node->getOwnerId(), array_keys($node->__get('users_w')))) {
$changed = TRUE;
unset($node->__get('users_w')[$node->getOwnerId()]);
}
// Remove individual users who are members of a group with the same
// permission.
if (!empty($this->values['remove_indiv'])) {
if ($node->__get('groups_w') && $node->__get('users_w') && ($list = mm_content_get_uids_in_group(array_keys($node->__get('groups_w')), array_keys($node->__get('users_w'))))) {
$changed = TRUE;
$node->__set('users_w', array_diff_key($node->__get('users_w'), $list));
}
}
if ($changed) {
$this->countChanged++;
if ($this->updateNeeded) {
$node->save();
}
}
}
}
}
public function iteratePage($row) {
static $waur = [Constants::MM_PERMS_WRITE, Constants::MM_PERMS_SUB, Constants::MM_PERMS_APPLY, Constants::MM_PERMS_READ];
static $aur = [Constants::MM_PERMS_SUB, Constants::MM_PERMS_APPLY, Constants::MM_PERMS_READ];
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;
$settings = $tree->getExtendedSettings();
$perms = &$settings['perms'];
// Remove 'u' for groups.
if ($this->getConfiguration('search_type') == self::SEARCH_TYPE_GROUPS) {
if ($perms[Constants::MM_PERMS_APPLY]['users']) {
$changed = TRUE;
$perms[Constants::MM_PERMS_APPLY]['users'] = [];
}
if ($perms[Constants::MM_PERMS_APPLY]['groups']) {
$changed = TRUE;
$perms[Constants::MM_PERMS_APPLY]['groups'] = [];
}
}
// Remove owner from individuals list.
foreach ($waur as $mode) {
if (in_array($tree->getOwnerId(), $perms[$mode]['users'])) {
$changed = TRUE;
$perms[$mode]['users'] = array_diff($perms[$mode]['users'], [$tree->getOwnerId()]);
}
}
foreach (['users', 'groups'] as $ug) {
// Remove users/groups in a/u/r when also in w.
foreach ($aur as $mode) {
if ($perms[Constants::MM_PERMS_WRITE][$ug] && array_intersect($perms[Constants::MM_PERMS_WRITE][$ug], $perms[$mode][$ug])) {
$changed = TRUE;
$perms[$mode][$ug] = array_diff($perms[$mode][$ug], $perms[Constants::MM_PERMS_WRITE][$ug]);
}
}
// Remove users/groups in r when also in a or u.
$au = array_merge($perms[Constants::MM_PERMS_SUB][$ug], $perms[Constants::MM_PERMS_APPLY][$ug]);
if ($au && array_intersect($au, $perms[Constants::MM_PERMS_READ][$ug])) {
$changed = TRUE;
$perms[Constants::MM_PERMS_READ][$ug] = array_diff($perms[Constants::MM_PERMS_READ][$ug], $au);
}
}
// Remove individual users who are members of a group with the same
// permission.
if (!empty($this->values['remove_indiv'])) {
foreach ($waur as $mode) {
if ($perms[$mode]['groups'] && $perms[$mode]['users'] && ($list = mm_content_get_uids_in_group($perms[$mode]['groups'], $perms[$mode]['users']))) {
$changed = TRUE;
$perms[$mode]['users'] = array_diff($perms[$mode]['users'], array_keys($list));
}
}
}
if ($changed) {
$this->countChanged++;
if ($this->updateNeeded) {
$tree->setExtendedSettings($settings);
$tree->save();
}
}
}
}
}
}