monster_menus-9.0.x-dev/src/Plugin/MMSearchAction/ModifyPermissions.php

src/Plugin/MMSearchAction/ModifyPermissions.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;
use Drupal\node\Entity\Node;

/**
 * Provides the MM Search Results Action to modify page/node permissions.
 *
 * @MMSearchAction(
 *   id = "mm_search_action_modify_perms",
 *   label = @Translation("modify permissions"),
 *   description = @Translation("Provides the MM Search Results Action to modify page/node permissions."),
 *   useDrupalSettings = true,
 *   jsInit = "MMSR_init_action_modify_perms",
 * )
 */
class ModifyPermissions extends MMSearchActionBase {

  use ResultsTrait;

  public const ADD_USER_GROUP = 'add_ug';
  public const DEL_USER_GROUP = 'del_ug';
  public const OWNER = 'owner';
  public const SUB_APPLY = 'au';
  public const SESSION_DATA = 'mmsr-mp';

  /**
   * @inheritDoc
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $x = ['@thing' => $this->t('permissions')];
    switch ($this->getConfiguration('search_type')) {
      case self::SEARCH_TYPE_GROUPS:
        $mp_modes = [
          Constants::MM_PERMS_WRITE => $this->t('delete/change settings'),
          Constants::MM_PERMS_SUB => $this->t('append sub-groups'),
          Constants::MM_PERMS_READ => $this->t('see group members'),
        ];
        break;

      case self::SEARCH_TYPE_PAGES:
        $mp_modes = [
          Constants::MM_PERMS_WRITE => $this->t('delete/change settings'),
          Constants::MM_PERMS_SUB => $this->t('append sub-pages'),
          Constants::MM_PERMS_APPLY => $this->t('add content'),
          self::SUB_APPLY => $this->t('append sub-pages AND add content'),
          Constants::MM_PERMS_READ => $this->t('read'),
        ];
        break;

      default:
        $x = ['@thing' => $this->t('"Who can edit or delete this content"')];
        $mp_modes = [];
    }

    $form['modify_mode'] = [
      '#type' => 'select',
      '#options' => [
        self::ADD_USER_GROUP => $this->t('add users/groups to @thing', $x),
        self::DEL_USER_GROUP => $this->t('remove users/groups from @thing', $x),
        self::OWNER          => $this->t('change the owner', $x),
      ],
      '#default_value' => $_SESSION[self::SESSION_DATA]['modify_mode'] ?? self::ADD_USER_GROUP,
    ];

    $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',
          '#mm_list_autocomplete_name' => 'modify[users_w-choose]',
          '#default_value' => $_SESSION[self::SESSION_DATA]['users_w'] ?? [],
        ],
        'groups_w' => [
          '#type' => 'mm_grouplist',
          '#default_value' => $_SESSION[self::SESSION_DATA]['groups_w'] ?? [],
        ],
        'owner' => [
          'userlist-choose' => [
            '#type' => 'textfield',
            '#attributes' => ['autocomplete' => 'off'], // Prevent FF from caching a previous value
            '#autocomplete_route_name' => 'monster_menus.autocomplete',
            '#size' => 30,
          ],
          'userlist' => [
            '#type' => 'mm_userlist',
            '#title' => $this->t('Owner'),
            '#mm_list_autocomplete_name' => 'modify[owner][userlist-choose]',
            '#default_value' => $_SESSION[self::SESSION_DATA]['owner'] ?? [0 => ''],
            '#mm_list_min' => 1,
            '#mm_list_max' => 1,
          ],
        ],
      ],
    ];
    if ($mp_modes) {
      $form['modify_perms']['modify']['mp_mode'] = [
        '#type' => 'select',
        '#title' => $this->t('with the permission'),
        '#options' => $mp_modes,
        '#default_value' => $_SESSION[self::SESSION_DATA]['mp_mode'] ?? NULL,
      ];
    }

    $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 Permissions'),
        '#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($this->iterateNode(...), $this->iteratePage(...));

    $_SESSION[self::SESSION_DATA] = [
      'modify_mode' => $this->values['modify_mode'],
      'groups_w' => $this->values['modify']['groups_w'] ?? [],
      'users_w' => $this->values['modify']['users_w'] ?? [],
      'owner' => $this->values['modify']['owner']['userlist'] ?? [],
      'mp_mode' => $this->values['modify']['mp_mode'] ?? '',
    ];

    $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;
        switch ($this->values['modify_mode']) {
          case self::ADD_USER_GROUP:
            foreach (['users_w', 'groups_w'] as $ug) {
              if (!empty($this->values['modify'][$ug])) {
                if (array_diff_key($this->values['modify'][$ug], $node->__get($ug))) {
                  $changed = TRUE;
                  if ($this->updateNeeded) {
                    $node->__set($ug, $node->__get($ug) + $this->values['modify'][$ug]);
                  }
                }
              }
            }
            break;

          case self::DEL_USER_GROUP:
            foreach (['users_w', 'groups_w'] as $ug) {
              if (!empty($this->values['modify'][$ug])) {
                if (array_intersect_key($node->__get($ug), $this->values['modify'][$ug])) {
                  $changed = TRUE;
                  if ($this->updateNeeded) {
                    $node->__set($ug, array_diff_key($node->__get($ug), $this->values['modify'][$ug]));
                  }
                }
              }
            }
            break;

          case self::OWNER:
            $changed = $this->processOwner($node) || $changed;
            break;
        }

        if ($changed) {
          $this->countChanged++;
          if ($this->updateNeeded) {
            $node->save();
          }
        }
      }
    }
  }

  public function iteratePage($row) {
    if (mm_content_user_can($row->mmtid, Constants::MM_PERMS_WRITE)) {
      if ($tree = MMTree::load($row->mmtid)) {
        $this->countAllowed++;
        $changed = FALSE;
        switch ($this->values['modify_mode']) {
          case self::ADD_USER_GROUP:
            foreach (['users', 'groups'] as $ug) {
              $valkey = "{$ug}_w";
              if (!empty($this->values['modify'][$valkey])) {
                $adds = array_keys($this->values['modify'][$valkey]);
                foreach (str_split($this->values['modify']['mp_mode']) as $mode) {
                  if (array_diff($adds, $tree->perms[$mode][$ug])) {
                    $changed = TRUE;
                    if ($this->updateNeeded) {
                      $this->setTreePerms($tree, $mode, $ug, array_unique(array_merge($tree->perms[$mode][$ug], $adds)));
                    }
                  }
                }
              }
            }
            break;

          case self::DEL_USER_GROUP:
            foreach (['users', 'groups'] as $ug) {
              $valkey = "{$ug}_w";
              if (!empty($this->values['modify'][$valkey])) {
                $dels = array_keys($this->values['modify'][$valkey]);
                foreach ($tree->perms as $mode => $list) {
                  if (array_intersect($list[$ug], $dels)) {
                    $changed = TRUE;
                    if ($this->updateNeeded) {
                      $this->setTreePerms($tree, $mode, $ug, array_diff($list[$ug], $dels));
                    }
                  }
                }
              }
            }
            break;

          case self::OWNER:
            $changed = $this->processOwner($tree) || $changed;
            break;
        }

        if ($changed) {
          $this->countChanged++;
          if ($this->updateNeeded) {
            $tree->save();
          }
        }
      }
    }
  }

  private function setTreePerms(MMTree $tree, $mode, $ug, $perms) {
    $settings = $tree->getExtendedSettings();
    $settings['perms'][$mode][$ug] = $perms;
    $tree->setExtendedSettings($settings);
  }

  private function processOwner($entity) {
    if (!empty($this->values['modify']['owner']['userlist'])) {
      $uid = mm_ui_mmlist_key0($this->values['modify']['owner']['userlist']);
      if ($entity->getOwnerId() != $uid) {
        if ($this->updateNeeded) {
          $entity->setOwnerId($uid);
        }
        return TRUE;
      }
    }
    return FALSE;
  }

    /**
   * @inheritDoc
   */
  public function applies() {
    return TRUE;
  }

  /**
   * @inheritDoc
   */
  public function access() {
    if ($this->getConfiguration('result_count') > 0) {
      $return = $this->iterate(function ($row) {
        if (mm_content_user_can_node($row->nid, Constants::MM_PERMS_WRITE)) {
          return TRUE;
        }
      }, function ($row) {
        if (mm_content_user_can($row->mmtid, Constants::MM_PERMS_WRITE)) {
          return TRUE;
        }
      });
      return !empty($return);
    }
    return FALSE;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc