View source
<?php
namespace Drupal\jammer\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing;
use Drupal\user\Entity\Role;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Url;
use Drupal\Core\Link;
use Symfony\Component\HttpFoundation\RedirectResponse;
class GConfigForm extends ConfigFormBase {
public function getFormId() {
return 'jammer_config';
}
private function entryMatch($entry, $data) {
foreach ($data as $line) {
if ($line['form'] != $entry['form']) {
continue;
}
foreach ($line['elements'] as $el) {
if (in_array($el, $entry['elements'])) {
return TRUE;
}
}
}
return FALSE;
}
private function buildTable($data, &$headers) {
$headers = [
$this
->t('Form id'),
$this
->t('Element id'),
$this
->t('Hide/disable'),
$this
->t('Exception'),
$this
->t('Role(s)'),
$this
->t('Invert roles'),
$this
->t('Priority'),
$this
->t('Comment'),
$this
->t('Modify'),
$this
->t('Delete'),
];
$groups = [];
foreach ($data as $entry) {
if (isset($entry['group']) and !empty($entry['group'])) {
$groups[$entry['group']] = $entry['group'];
}
}
sort($groups, SORT_LOCALE_STRING);
array_unshift($groups, $this
->t("Unsorted entries"));
$content = [];
foreach ($groups as $g) {
$content[$g] = [];
}
foreach ($data as $cnt => $entry) {
if (isset($entry['group']) and !empty($entry['group'])) {
$target = $entry['group'];
}
else {
$target = $this
->t("Unsorted entries");
}
$line = [];
$line[] = $entry['form'];
if (is_array($entry['elements'])) {
$line[] = implode(" ", $entry['elements']);
}
else {
$line[] = $entry['elements'];
}
if ($entry['remove'] == 0) {
$line[] = $this
->t('Remove');
}
else {
$line[] = $this
->t('Disable');
}
if ($entry['creation'] == 0) {
$line[] = $this
->t('Always');
}
else {
if ($entry['creation'] == 1) {
$line[] = $this
->t('Exclude creation');
}
else {
if ($entry['creation'] == 2) {
$line[] = $this
->t('Only creation');
}
else {
$line[] = $this
->t('Exclude when empty');
}
}
}
if (isset($entry['roles']) and is_array($entry['roles'])) {
$line[] = implode("; ", $entry['roles']);
}
else {
$line[] = "";
}
if ($entry['invert'] == 1) {
$line[] = $this
->t("Yes");
}
else {
$line[] = $this
->t("No");
}
$line[] = $entry['priority'];
$line[] = $entry['comment'];
$t = Link::createFromRoute('Modify', 'jammer.jammer_config_action', [
'action' => 'modify',
'id' => $cnt,
]);
$line[] = $t;
$t = Link::createFromRoute('Delete', 'jammer.jammer_config_action', [
'action' => 'delete',
'id' => $cnt,
]);
$line[] = $t;
$content[$target][] = $line;
}
$result = [];
foreach ($content as $grp => $list) {
$t = new FormattableMarkup("<b>• {$grp}</b>", []);
$result[] = [
$t,
'',
'',
'',
'',
'',
'',
'',
'',
];
foreach ($list as $l) {
$result[] = $l;
}
}
return $result;
}
private function createArray($val) {
$val = str_replace(";", " ", $val);
$val = str_replace(",", " ", $val);
$val = str_replace(" ", " ", $val);
$val = str_replace(" ", " ", $val);
$res = explode(" ", $val);
$res2 = [];
foreach ($res as $r) {
$res2[] = trim($r);
}
return $res2;
}
private function buildLine($form_state) {
$result = [];
$result['form'] = $form_state
->getValue('target_form_id');
$result['elements'] = $this
->createArray($form_state
->getValue('element_id'));
$result['remove'] = $form_state
->getValue('remove_disable');
$result['creation'] = $form_state
->getValue('always_creation');
$result['roles'] = $form_state
->getValue('roles');
$result['invert'] = $form_state
->getValue('invert_roles');
$result['priority'] = $form_state
->getValue('priority');
$result['group'] = $form_state
->getValue('group');
$result['comment'] = $form_state
->getValue('comment');
return $result;
}
public function buildForm(array $form, FormStateInterface $form_state) {
$weight = 0;
$messenger = \Drupal::messenger();
$action = \Drupal::routeMatch()
->getParameter('action');
$id = \Drupal::routeMatch()
->getParameter('id');
$config = $this
->config('jammer.settings');
$tmp = $config
->get('stored_values');
$data = unserialize($tmp);
$headers = [];
$rows_table = $this
->buildTable($data, $headers);
$node_types = \Drupal\node\Entity\NodeType::loadMultiple();
$options = [];
$list_elements = "<div><ul>";
foreach ($node_types as $node_type) {
$options[$node_type
->id()] = $node_type
->label();
$fields_in = \Drupal::service('entity_field.manager')
->getFieldDefinitions('node', $node_type
->id());
$list_elements .= "<li>" . $node_type
->label() . "</li><ul>";
foreach ($fields_in as $field_in => $nop) {
$list_elements .= "<li>{$field_in}</li>";
}
$list_elements .= "</ul>";
}
$list_elements .= "</ul></div>";
$roles_list = Role::loadMultiple();
$roles = [];
foreach ($roles_list as $role_list) {
$roles[$role_list
->id()] = $role_list
->label();
}
if (isset($id) and isset($data[$id])) {
$currentLine = $data[$id];
}
else {
$currentLine = NULL;
}
if ($action == 'export') {
$form['intro'] = [
'#type' => 'textarea',
'#rows' => 16,
'#cols' => 64,
'#default_value' => serialize($data),
'#disabled' => 'disabled',
'#weight' => $weight++,
];
$form['post'] = [
'#markup' => "<div><p>Save this dump and " . Link::createFromRoute('go back', 'jammer.jammer_config', [], [
'attributes' => [
'class' => 'button',
],
])
->toString() . " to configuration page.</p></div>",
'#allowed_tags' => [
'a',
'div',
'p',
],
'#weight' => $weight++,
];
$form2 = parent::buildForm($form, $form_state);
$form2['actions']['submit']['#access'] = FALSE;
return $form2;
}
if ($action == 'import') {
$form['intro'] = [
'#markup' => "<div><p>Copy export-data into following text area and click 'Import' button.</p><p>" . "Beware: if you import garbage, you will get garbage!</p></div>",
'#allowed_tags' => [
'div',
'p',
],
'#weight' => $weight++,
];
$form['import'] = [
'#type' => 'textarea',
'#rows' => 16,
'#cols' => 64,
'#weight' => $weight++,
];
$form['post'] = [
'#markup' => "<div><p>Validate this import or " . Link::createFromRoute('go back', 'jammer.jammer_config', [], [
'attributes' => [
'class' => 'button',
],
])
->toString() . " if you are not sure.</p></div>",
'#allowed_tags' => [
'a',
'div',
'p',
],
'#weight' => $weight++,
];
$form2 = parent::buildForm($form, $form_state);
$form2['actions']['submit']['#value'] = $this
->t('Import');
return $form2;
}
if ($action == 'modify') {
if (!$currentLine) {
$messenger
->addMessage($this
->t('Bad \'modify\' data. Ignored'), $messenger::TYPE_WARNING);
return new redirectResponse(Url::fromRoute('jammer.jammer_config')
->toString());
}
else {
$prefill = $currentLine;
}
}
else {
$prefill = NULL;
}
if ($action == 'clear') {
$form['intro'] = [
'#markup' => "<div>You are about to delete <b>all</b> the configuration. Please confirm or <b>" . Link::createFromRoute('go back', 'jammer.jammer_config', [], [
'attributes' => [
'class' => 'button',
],
])
->toString() . "</b>!</div>",
'#allowed_tags' => [
'div',
'b',
'a',
],
];
$form2 = parent::buildForm($form, $form_state);
$form2['actions']['submit']['#value'] = $this
->t('Confirm');
return $form2;
}
if ($action == 'delete') {
if (!$currentLine) {
$messenger
->addMessage($this
->t('Bad \'delete\' data. Ignored'), $messenger::TYPE_WARNING);
return new redirectResponse(Url::fromRoute('jammer.jammer_config')
->toString());
}
$form['intro'] = [
'#markup' => "<div>You are about to delete this entry. Please confirm or <b>" . Link::createFromRoute('go back', 'jammer.jammer_config', [], [
'attributes' => [
'class' => 'button',
],
])
->toString() . "</b>!</div>",
'#allowed_tags' => [
'div',
'b',
'a',
],
];
$form2 = parent::buildForm($form, $form_state);
$form2['actions']['submit']['#value'] = $this
->t('Confirm');
return $form2;
}
$form['intro'] = [
'#markup' => "<div><b>Configuration panel for G-Jammer module.</b></div>" . "<div>You can also:<ul><li>" . Link::createFromRoute('export current configuration', 'jammer.jammer_config_action', [
'action' => 'export',
'id' => 'all',
])
->toString() . '</li><li>' . Link::createFromRoute('import a configuration', 'jammer.jammer_config_action', [
'action' => 'import',
'id' => 'all',
])
->toString() . '</li><li>' . Link::createFromRoute('clear the current configuration', 'jammer.jammer_config_action', [
'action' => 'clear',
'id' => 'all',
])
->toString() . '</li></ul>',
'#allowed_tags' => [
'div',
'b',
'a',
'ul',
'li',
],
'#weight' => $weight++,
];
$form['target_form_id'] = [
'#type' => 'select',
'#title' => $this
->t('Form id'),
'#options' => $options,
'#required' => TRUE,
'#chosen' => TRUE,
'#description' => $this
->t('The form id containing the element you want to remove'),
'#weight' => $weight++,
];
$form['element_id'] = [
'#type' => 'textfield',
'#title' => $this
->t('Element id'),
'#required' => TRUE,
'#size' => 512,
'#description' => $this
->t('The element id of the element you want to remove. Can be a list (comma or space separated)'),
'#weight' => $weight++,
];
$form['existing_values'] = [
'#type' => 'details',
'#title' => $this
->t('Existing elements Id per node type'),
'#open' => FALSE,
'#weight' => $weight++,
];
$form['existing_values']['text'] = [
'#markup' => $list_elements,
'#allowed_tags' => [
'div',
'ul',
'li',
],
'#weight' => $weight++,
];
$form['remove_disable'] = [
'#type' => 'radios',
'#title' => $this
->t('Remove or disable element'),
'#default_value' => 0,
'#options' => [
0 => $this
->t('Remove'),
1 => $this
->t('Disable'),
],
'#description' => $this
->t('Select if you want to remove (hide) or disable (read-only) element. Selecting disable has no effect on non-interactive elements'),
'#weight' => $weight++,
];
$form['always_creation'] = [
'#type' => 'radios',
'#title' => $this
->t('Always jam or exclude/only creation'),
'#default_value' => 0,
'#options' => [
0 => $this
->t('Always'),
1 => $this
->t('Exclude creation'),
2 => $this
->t('Only creation'),
3 => $this
->t('Exclude when empty'),
],
'#description' => $this
->t('Select if jam is always performed or if a form used to create a new content should be ignored, or if it should only applies at creation. Exclude when empty makes the jam to be applied only when field is not empty. Beware that it makes sense only for text fields (or related fields)'),
'#weight' => $weight++,
];
$form['roles'] = [
'#type' => 'select',
'#title' => $this
->t('Only apply to role(s)'),
'#options' => $roles,
'#multiple' => TRUE,
'#chosen' => TRUE,
'#size' => 128,
'#description' => $this
->t('Select role(s) for which element will be removed/disabled (if user has any of the roles listed here element will be hidden). By default all role(s) are selected except administrator'),
'#weight' => $weight++,
];
$form['invert_roles'] = [
'#type' => 'checkbox',
'#return_value' => 1,
'#title' => $this
->t(' Reverse role(s)'),
'#description' => $this
->t('When selected the jam will not be applied to listed role(s), and will apply to all other role(s)'),
'#weight' => $weight++,
];
$priorities = [];
for ($i = -20; $i <= 20; $i++) {
$priorities[$i] = $i;
}
$form['priority'] = [
'#type' => 'select',
'#title' => $this
->t('Priority'),
'#options' => $priorities,
'#default_value' => 0,
'#description' => $this
->t('Rules are evaluated in top-bottom order of this value'),
'#weight' => $weight++,
];
$form['group'] = [
'#type' => 'textfield',
'#title' => $this
->t('Category/group'),
'#size' => 32,
'#maxlength' => 32,
'#description' => $this
->t('Used to group elements together in summary list below'),
'#weight' => $weight++,
];
$form['comment'] = [
'#type' => 'textfield',
'#title' => $this
->t('Comment'),
'#size' => 64,
'#maxlength' => 64,
'#description' => $this
->t('Associated comment'),
'#weight' => $weight++,
];
$form['validate'] = [
'#type' => 'submit',
'#value' => $this
->t('Validate'),
'#button_type' => 'primary',
'#weight' => $weight++,
];
$form['table_list'] = [
'#type' => 'table',
'#caption' => $this
->t('Existing actions'),
'#header' => $headers,
'#rows' => $rows_table,
'#weight' => $weight++,
];
if ($prefill) {
$form['target_form_id']['#default_value'] = $prefill['form'];
$form['element_id']['#default_value'] = implode(" ", $prefill['elements']);
$form['remove_disable']['#default_value'] = $prefill['remove'];
$form['always_creation']['#default_value'] = $prefill['creation'];
$form['roles']['#default_value'] = $prefill['roles'];
$form['invert_roles']['#default_value'] = $prefill['invert'];
$form['priority']['#default_value'] = $prefill['priority'];
$form['group']['#default_value'] = $prefill['group'];
$form['comment']['#default_value'] = $prefill['comment'];
}
$form2 = parent::buildForm($form, $form_state);
$form2['actions']['submit']['#value'] = $this
->t('Validate');
return $form2;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$messenger = \Drupal::messenger();
$action = \Drupal::routeMatch()
->getParameter('action');
$id = \Drupal::routeMatch()
->getParameter('id');
$config = $this
->config('jammer.settings');
$tmp = $config
->get('stored_values');
$data = unserialize($tmp);
if (isset($action) and $action != 'delete' and $action != 'modify' and $action != 'import' and $action != 'export' and $action != 'clear') {
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
$messenger
->deleteByType($messenger::TYPE_STATUS);
$messenger
->addMessage($this
->t('Bad action type'), $messenger::TYPE_ERROR);
return;
}
if (isset($action) and $action == 'export') {
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
$messenger
->deleteByType($messenger::TYPE_STATUS);
$messenger
->addMessage($this
->t('Bad action type (\'export\' is not accessible to \'submit\')'), $messenger::TYPE_ERROR);
return;
}
if (isset($action) and $action == 'clear') {
$data = [];
$config
->set('stored_values', serialize($data));
$config
->save();
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
$messenger
->deleteByType($messenger::TYPE_STATUS);
$messenger
->addMessage($this
->t('Configuration all cleared'), $messenger::TYPE_STATUS);
return;
}
if (isset($action) and $action == 'import') {
$import = trim($form_state
->getValue('import'));
$tmp = @unserialize($import);
$ok = TRUE;
if ($tmp === FALSE) {
$ok = FALSE;
$msg = $this
->t('corrupted data');
}
if (!is_array($tmp)) {
$ok = FALSE;
$msg = $this
->t('bad format');
}
if (!$ok) {
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
$messenger
->deleteByType($messenger::TYPE_STATUS);
$messenger
->addMessage($this
->t('Error with import-data: ') . $msg, $messenger::TYPE_ERROR);
return;
}
$config
->set('stored_values', $import);
$config
->save();
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
$messenger
->deleteByType($messenger::TYPE_STATUS);
$messenger
->addMessage($this
->t('Configuration imported'), $messenger::TYPE_STATUS);
return;
}
if (isset($action) and $action == 'delete') {
if (!isset($id) or !isset($data[$id])) {
$messenger
->addMessage($this
->t('Bad or missing \'id\' for \'delete\' action'), $messenger::TYPE_ERROR);
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
return;
}
unset($data[$id]);
$data = array_values($data);
$config
->set('stored_values', serialize($data));
$config
->save();
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
$messenger
->deleteByType($messenger::TYPE_STATUS);
$messenger
->addMessage($this
->t('Entry deleted'), $messenger::TYPE_STATUS);
return;
}
if (isset($action) and $action == 'modify') {
if (!isset($id) or !isset($data[$id])) {
$messenger
->addMessage($this
->t('Bad or missing \'id\' for \'modify\' action'), $messenger::TYPE_ERROR);
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
return;
}
$entry = $this
->buildLine($form_state);
$data[$id] = $entry;
$config
->set('stored_values', serialize($data));
$config
->save();
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
$messenger
->deleteByType($messenger::TYPE_STATUS);
$messenger
->addMessage($this
->t('Entry modified'), $messenger::TYPE_STATUS);
return;
}
$entry = $this
->buildLine($form_state);
$warn = $this
->entryMatch($entry, $data);
$data[] = $entry;
$config
->set('stored_values', serialize($data));
$config
->save();
parent::submitForm($form, $form_state);
$messenger
->deleteByType($messenger::TYPE_STATUS);
$messenger
->addMessage($this
->t('Entry added'), $messenger::TYPE_STATUS);
if ($warn) {
$messenger
->addMessage($this
->t('An entry still has this form and field(s). You should check for duplicated/conflicting entries'), $messenger::TYPE_WARNING);
}
return;
}
protected function getEditableConfigNames() {
return [
'jammer.settings',
];
}
}