monster_menus-9.0.x-dev/src/Plugin/MMSearchAction/ModifyPageAssignments.php
src/Plugin/MMSearchAction/ModifyPageAssignments.php
<?php
namespace Drupal\monster_menus\Plugin\MMSearchAction;
use Drupal\Core\Form\EnforcedResponseException;
use Drupal\Core\Form\FormStateInterface;
use Drupal\monster_menus\Annotation\MMSearchAction;
use Drupal\monster_menus\Constants;
use Drupal\monster_menus\MMSearchAction\MMSearchActionBase;
use Drupal\node\Entity\Node;
/**
* Provides the MM Search Results Action to change which page(s) a node is
* assigned to.
*
* @MMSearchAction(
* id = "mm_search_action_modify_page_assignments",
* label = @Translation("modify page assignments"),
* description = @Translation("Provides the MM Search Results Action to change which page(s) a node is assigned to."),
* useDrupalSettings = true,
* jsInit = "MMSR_init_action_modify_pages",
* )
*/
class ModifyPageAssignments extends MMSearchActionBase {
use ResultsTrait;
final public const ADD_PAGES = 'add_pgs';
final public const DEL_PAGES = 'del_pgs';
final public const REPLACE_PAGES = 'repl_pgs';
final public const SET_PAGES = 'set_pgs';
final public const SESSION_DATA = 'mmsr-mpa';
private $error;
/**
* @inheritDoc
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['modify_mode'] = [
'#type' => 'select',
'#options' => [
self::ADD_PAGES => $this->t('add these page(s)'),
self::DEL_PAGES => $this->t('remove these page(s)'),
self::REPLACE_PAGES => $this->t('replace these page(s)'),
self::SET_PAGES => $this->t('set the entire list'),
],
'#default_value' => $_SESSION[self::SESSION_DATA]['modify_mode'] ?? self::ADD_PAGES,
];
$form['repl_catlist'] = [
'#type' => 'container',
'repl_catlist' => [
'#type' => 'mm_catlist',
'#default_value' => $_SESSION[self::SESSION_DATA]['repl_catlist'] ?? [],
'#mm_list_popup_start' => 1,
'#mm_list_selectable' => Constants::MM_PERMS_READ,
],
'label' => [
'#markup' => $this->t('with these page(s):'),
],
];
$form['catlist'] = [
'#type' => 'mm_catlist',
'#default_value' => $_SESSION[self::SESSION_DATA]['catlist'] ?? [],
'#mm_list_popup_start' => 1,
'#mm_list_selectable' => Constants::MM_PERMS_READ,
];
$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 Page Assignments'),
'#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(...), NULL);
$_SESSION[self::SESSION_DATA] = [
'modify_mode' => $this->values['modify_mode'],
'catlist' => $this->values['catlist'],
'repl_catlist' => $this->values['repl_catlist'],
];
if (!empty($this->error)) {
throw new EnforcedResponseException(mm_json_response([
'action_result' => $this->error,
'action_result_div' => '#mmsr-mp-status-text',
'action_result_js' => 'MMSR_action_modify_perms_update',
'mp_enable' => FALSE,
]));
}
$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++;
$original_pages = $node->__get('mm_catlist');
if ($changed_pages = $this->values['catlist']) {
$changed = FALSE;
switch ($this->values['modify_mode']) {
case self::ADD_PAGES:
if (array_diff_key($changed_pages, $original_pages)) {
$changed = $changed_pages + $original_pages;
}
break;
case self::DEL_PAGES:
if (array_intersect_key($changed_pages, $original_pages)) {
if ($test = array_diff_key($original_pages, $changed_pages)) {
$changed = $test;
}
else {
$this->error = $this->t('<span>Deleting the selected page(s) from one or more pieces of content would cause them to become orphaned. Consider the <strong>replace page(s)</strong> option instead.</span>');
}
}
break;
case self::REPLACE_PAGES:
if ($replace = $this->values['repl_catlist']) {
if (array_intersect_key($replace, $original_pages)) {
$test = array_diff_key($original_pages, $replace) + $changed_pages;
if (array_keys($test) != array_keys($original_pages)) {
$changed = $test;
}
}
}
else {
$this->error = $this->t('<span>Please add one or more pages to the first list.</span>');
}
break;
case self::SET_PAGES:
if (array_diff_key($original_pages, $changed_pages)) {
$changed = $changed_pages;
}
break;
}
if ($changed) {
$this->countChanged++;
if ($this->updateNeeded) {
$node->__set('mm_catlist', $changed);
$node->save();
}
}
}
}
}
}
/**
* @inheritDoc
*/
public function applies() {
return in_array($this->getConfiguration('search_type'), [self::SEARCH_TYPE_NODES, self::SEARCH_TYPE_NODES_ON_PAGES]);
}
/**
* @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;
}
}, NULL);
return !empty($return);
}
return FALSE;
}
}