View source
<?php
namespace Drupal\business_rules\Plugin\BusinessRulesAction;
use Drupal\business_rules\ActionInterface;
use Drupal\business_rules\Entity\Action;
use Drupal\business_rules\Events\BusinessRulesEvent;
use Drupal\business_rules\ItemInterface;
use Drupal\business_rules\Plugin\BusinessRulesActionPlugin;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\RemoveCommand;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;
class ChangeFieldInfo extends BusinessRulesActionPlugin {
const MAKE_REQUIRED = 'make_required';
const MAKE_OPTIONAL = 'make_optional';
const MAKE_READ_ONLY = 'make_read_only';
const MAKE_HIDDEN = 'make_hidden';
protected $actionOptions = [];
public function __construct(array $configuration = [], $plugin_id = 'change_field_info', $plugin_definition = []) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->actionOptions = [
'' => t('-Select-'),
self::MAKE_REQUIRED => t('Make field required'),
self::MAKE_OPTIONAL => t('Make field optional'),
self::MAKE_READ_ONLY => t('Make field read only'),
self::MAKE_HIDDEN => t('Make field hidden'),
];
}
public static function addFieldSubmit(array $form, FormStateInterface $form_state) {
$action = $form_state
->get('action');
$field = $form_state
->getValue('fields')['new.field'];
$id = $field['field'] . '__' . $field['action'];
$settings = $action
->getSettings();
$availableFields = \Drupal::getContainer()
->get('business_rules.util')
->getBundleEditableFields($action
->getTargetEntityType(), $action
->getTargetBundle());
$settings['fields'][$id] = [
'id' => $id,
'field' => $field['field'],
'action' => $field['action'],
];
uasort($settings['fields'], function ($a, $b) use ($availableFields) {
return $availableFields[$a['field']] > $availableFields[$b['field']] ? 1 : -1;
});
$action
->setSetting('fields', $settings['fields']);
$action
->save();
$form_state
->setRedirect('entity.business_rules_action.edit_form', [
'business_rules_action' => $action
->id(),
], [
'fragment' => 'field-' . $id,
]);
}
public static function removeField($action, $field, $method) {
$action = Action::load($action);
$fields = $action
->getSettings('fields');
unset($fields[$field]);
$action
->setSetting('fields', $fields);
$action
->save();
if ($method == 'ajax') {
$response = new AjaxResponse();
$response
->addCommand(new RemoveCommand('#field-' . $field));
return $response;
}
else {
$url = new Url('entity.business_rules_action.edit_form', [
'business_rules_action' => $action
->id(),
]);
return new RedirectResponse($url
->toString());
}
}
public function getSettingsForm(array &$form, FormStateInterface $form_state, ItemInterface $item) {
if ($item
->isNew()) {
return [];
}
$form_state
->set('action', $item);
$settings['fields'] = [
'#type' => 'table',
'#header' => [
'field' => t('Filed'),
'action' => t('Action'),
'operations' => t('Operations'),
],
'#attributes' => [
'id' => 'array_variable_fields_table',
],
];
$settings['info'] = [
'#type' => 'markup',
'#markup' => t('Multiple value fields cannot be changed to be Required or Optional by this module. Create a new rule as "Entity form validation" to achieve this purpose see this issue on https://www.drupal.org/node/1592814.
<br>Hidden fields are removed from the form array, and not rendered. So be careful if you hide a required field because some field widgets can validate it anyway.'),
];
$this
->getRows($item, $settings['fields']);
return $settings;
}
private function getRows(ItemInterface $item, array &$settings) {
$fields = $item
->getSettings('fields');
$availableFields = $this->util
->getBundleEditableFields($item
->getTargetEntityType(), $item
->getTargetBundle());
if (count($fields)) {
foreach ($fields as $key => $field) {
$links['remove'] = [
'title' => t('Remove'),
'url' => Url::fromRoute('business_rules.plugins.action.change_field_info.remove_field', [
'action' => $item
->id(),
'field' => $field['id'],
'method' => 'nojs',
], [
'attributes' => [
'class' => [
'use-ajax',
],
],
]),
'weight' => 1,
];
$settings[$key] = [
'field' => [
'#type' => 'markup',
'#markup' => $availableFields[$field['field']],
],
'action' => [
'#type' => 'markup',
'#markup' => $this->actionOptions[$field['action']],
],
'operations' => [
'#type' => 'operations',
'#links' => $links,
],
'#attributes' => [
'id' => 'field-' . $field['id'],
],
];
}
}
$settings['new.field'] = [
'field' => [
'#type' => 'select',
'#required' => FALSE,
'#options' => array_merge([
'' => t('-Select-'),
], $availableFields),
],
'action' => [
'#type' => 'select',
'#required' => FALSE,
'#options' => $this->actionOptions,
],
'operations' => [
'#type' => 'submit',
'#value' => t('Add'),
'#validate' => [
get_class($this) . '::validateAddFieldForm',
],
'#submit' => [
get_class($this) . '::addFieldSubmit',
],
],
];
}
public function buildForm(array &$form, FormStateInterface $form_state) {
unset($form['variables']);
}
public function validateForm(array &$form, FormStateInterface $form_state) {
self::validateAddFieldForm($form, $form_state);
}
public static function validateAddFieldForm(array &$form, FormStateInterface $form_state) {
$field = $form_state
->getValue('fields');
$field_field = $field['new.field']['field'];
$field_action = $field['new.field']['action'];
if (empty($field_action) && !empty($field_field) || !empty($field_action) && empty($field_field)) {
$form_state
->setErrorByName('fields', t("Please, fill all field data or none of them."));
}
if ($field['new.field']['field'] == 'title' && $field['new.field']['action'] == self::MAKE_OPTIONAL) {
$form_state
->setErrorByName('fields', t('The title field cannot be optional.'));
}
}
public function processSettings(array $settings, ItemInterface $item) {
if ($item
->isNew()) {
return [];
}
if (count($item
->getSettings('fields'))) {
$settings['fields'] += $item
->getSettings('fields');
}
if ($settings['fields']['new.field']['field'] && $settings['fields']['new.field']['action']) {
$availableFields = $this->util
->getBundleEditableFields($item
->getTargetEntityType(), $item
->getTargetBundle());
$id = $settings['fields']['new.field']['field'] . '__' . $settings['fields']['new.field']['action'];
$settings['fields'][$id] = $settings['fields']['new.field'];
$settings['fields'][$id]['id'] = $id;
uasort($settings['fields'], function ($a, $b) use ($availableFields) {
return $availableFields[$a['field']] > $availableFields[$b['field']] ? 1 : -1;
});
}
unset($settings['fields']['new.field']);
return $settings;
}
public function execute(ActionInterface $action, BusinessRulesEvent $event) {
$fields = $action
->getSettings('fields');
if (!count($fields)) {
$result = [
'#type' => 'markup',
'#markup' => t('Nothing to do.'),
];
return $result;
}
$element = $event
->getArgument('element');
$context = $event
->getArgument('context');
$items = $context['items'];
$element_name = $items
->getName();
foreach ($fields as $field) {
if ($field['field'] == $element_name) {
$this
->changeFieldInfo($element, $field);
}
}
$event
->setArgument('element', $element);
foreach ($fields as $field) {
$debug_message = t('<br>%method: %field', [
'%field' => $field['field'],
'%method' => $this->actionOptions[$field['action']],
]);
$result[] = [
'#type' => 'markup',
'#markup' => $debug_message,
];
}
return $result;
}
protected function changeFieldInfo(array &$element, $action_field) {
switch ($action_field['action']) {
case self::MAKE_REQUIRED:
$element['#required'] = TRUE;
if (isset($element[0])) {
$element[0]['#required'] = TRUE;
}
if (isset($element['target_id'])) {
$element['target_id']['#required'] = TRUE;
}
break;
case self::MAKE_OPTIONAL:
$element['#required'] = FALSE;
if (isset($element[0])) {
$element[0]['#required'] = FALSE;
}
if (isset($element['target_id'])) {
$element['target_id']['#required'] = FALSE;
}
break;
case self::MAKE_READ_ONLY:
$element['#disabled'] = TRUE;
break;
case self::MAKE_HIDDEN:
$element = [];
break;
}
}
}