class GConfigForm in Jammer 1.0.x
Hierarchy
- class \Drupal\Core\Form\FormBase implements ContainerInjectionInterface, FormInterface uses DependencySerializationTrait, LoggerChannelTrait, MessengerTrait, RedirectDestinationTrait, StringTranslationTrait
- class \Drupal\Core\Form\ConfigFormBase uses ConfigFormBaseTrait
- class \Drupal\jammer\Form\GConfigForm
- class \Drupal\Core\Form\ConfigFormBase uses ConfigFormBaseTrait
Expanded class hierarchy of GConfigForm
1 string reference to 'GConfigForm'
File
- src/
Form/ GConfigForm.php, line 15
Namespace
Drupal\jammer\FormView source
class GConfigForm extends ConfigFormBase {
public function getFormId() {
return 'jammer_config';
}
// returns TRUE if given $entry still present in $data (same form+element(s))
private function entryMatch($entry, $data) {
foreach ($data as $line) {
if ($line['form'] != $entry['form']) {
continue;
// skip, not the same form
}
foreach ($line['elements'] as $el) {
if (in_array($el, $entry['elements'])) {
return TRUE;
// at least one match
}
}
}
// no match
return FALSE;
}
// build array for #rows of existing entries (for display in 'table')
// TODO: this function may clearly be umproved
private function buildTable($data, &$headers) {
// create table 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'),
];
// prepare array for per-group sorting
$groups = [];
foreach ($data as $entry) {
if (isset($entry['group']) and !empty($entry['group'])) {
$groups[$entry['group']] = $entry['group'];
}
}
// sort ascending and insert before the "unsorted" group
sort($groups, SORT_LOCALE_STRING);
array_unshift($groups, $this
->t("Unsorted entries"));
// prepare and store data in group-sorted array
$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'];
// add modify/delete
$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;
}
// flatten result (with groups as separated rows)
$result = [];
foreach ($content as $grp => $list) {
$t = new FormattableMarkup("<b>• {$grp}</b>", []);
$result[] = [
$t,
'',
'',
'',
'',
'',
'',
'',
'',
];
foreach ($list as $l) {
$result[] = $l;
}
}
return $result;
}
// explode list to array: used to convert comma-separated lists
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);
// proper data
}
return $res2;
}
// build data line (in module data format) from submited values
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');
// still an array
$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;
}
// configuration form builder
public function buildForm(array $form, FormStateInterface $form_state) {
$weight = 0;
$messenger = \Drupal::messenger();
// get calling parameters
$action = \Drupal::routeMatch()
->getParameter('action');
$id = \Drupal::routeMatch()
->getParameter('id');
// get our array of data
$config = $this
->config('jammer.settings');
$tmp = $config
->get('stored_values');
$data = unserialize($tmp);
$headers = [];
// build table rows (for display, at end of the form)
$rows_table = $this
->buildTable($data, $headers);
// get list of nodes types and list of fields
$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>";
// get list of roles
$roles_list = Role::loadMultiple();
$roles = [];
foreach ($roles_list as $role_list) {
$roles[$role_list
->id()] = $role_list
->label();
}
// if $id get the corresponding line
if (isset($id) and isset($data[$id])) {
$currentLine = $data[$id];
}
else {
$currentLine = NULL;
}
// if action is "export" generates a dump of configuration
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 is "import" present a textarea to insert data and button to validate import
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 prepare data for pre-fill fields
if ($action == 'modify') {
if (!$currentLine) {
// call for 'modify' without valid line: redirect to base form
$messenger
->addMessage($this
->t('Bad \'modify\' data. Ignored'), $messenger::TYPE_WARNING);
// go back to default page
return new redirectResponse(Url::fromRoute('jammer.jammer_config')
->toString());
}
else {
// will be used to pre-fill fields
$prefill = $currentLine;
}
}
else {
$prefill = NULL;
}
// if action=clear just show confirm button
if ($action == 'clear') {
// just display a custom confirm form
$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 just show confirm button
if ($action == 'delete') {
if (!$currentLine) {
// call for 'delete' without valid line: redirect to base form
$messenger
->addMessage($this
->t('Bad \'delete\' data. Ignored'), $messenger::TYPE_WARNING);
// go back to default page
return new redirectResponse(Url::fromRoute('jammer.jammer_config')
->toString());
}
// just display a custom confirm form (TODO: add data about concerned entry)
$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;
}
// build our view/configuration form
$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 needed, set default values
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'];
}
// return the form
$form2 = parent::buildForm($form, $form_state);
// change submit button name (Note: can't figure how to *move' submit button
// so I created an other one at the desired position)
$form2['actions']['submit']['#value'] = $this
->t('Validate');
return $form2;
}
// check data and submit change
public function submitForm(array &$form, FormStateInterface $form_state) {
$messenger = \Drupal::messenger();
// get calling parameters
$action = \Drupal::routeMatch()
->getParameter('action');
$id = \Drupal::routeMatch()
->getParameter('id');
// get our array of data
$config = $this
->config('jammer.settings');
$tmp = $config
->get('stored_values');
$data = unserialize($tmp);
// bad action value (TODO: improve routing to prevent this to happen)
if (isset($action) and $action != 'delete' and $action != 'modify' and $action != 'import' and $action != 'export' and $action != 'clear') {
// go back to main config page
$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;
}
// should not occur
if (isset($action) and $action == 'export') {
// go back to main config page
$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;
}
// request for clear
if (isset($action) and $action == 'clear') {
$data = [];
$config
->set('stored_values', serialize($data));
$config
->save();
// go back to main config page
$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;
}
// request for import
if (isset($action) and $action == 'import') {
// get data to import
$import = trim($form_state
->getValue('import'));
// make some sanity checks on imported data
$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');
}
// note: should add more sanity checks (data structure)
if (!$ok) {
// go back to main config page
$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;
}
// record it into configuration
$config
->set('stored_values', $import);
$config
->save();
// go back to main config page
$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;
}
// request for deleting entry
if (isset($action) and $action == 'delete') {
// bad $id
if (!isset($id) or !isset($data[$id])) {
$messenger
->addMessage($this
->t('Bad or missing \'id\' for \'delete\' action'), $messenger::TYPE_ERROR);
// go back to main config page
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
return;
}
// unset line and rebuild array
unset($data[$id]);
$data = array_values($data);
// save new configuration
$config
->set('stored_values', serialize($data));
$config
->save();
// go back to main config page
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
// this is to prevent the default submit message
$messenger
->deleteByType($messenger::TYPE_STATUS);
$messenger
->addMessage($this
->t('Entry deleted'), $messenger::TYPE_STATUS);
return;
}
// request for modifying entry
if (isset($action) and $action == 'modify') {
// bad $id
if (!isset($id) or !isset($data[$id])) {
$messenger
->addMessage($this
->t('Bad or missing \'id\' for \'modify\' action'), $messenger::TYPE_ERROR);
// go back to main config page
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
return;
}
// prepare new values for entry
$entry = $this
->buildLine($form_state);
// modify entry
$data[$id] = $entry;
// save new configuration
$config
->set('stored_values', serialize($data));
$config
->save();
// go back to main config page
$form_state
->setRedirect('jammer.jammer_config');
parent::submitForm($form, $form_state);
// this is to prevent the default submit message
$messenger
->deleteByType($messenger::TYPE_STATUS);
$messenger
->addMessage($this
->t('Entry modified'), $messenger::TYPE_STATUS);
return;
}
// no action: request for creating entry
$entry = $this
->buildLine($form_state);
// check if still exists an entry with same form and field(s) and generate a warning
$warn = $this
->entryMatch($entry, $data);
// add entry
$data[] = $entry;
// save new configuration
$config
->set('stored_values', serialize($data));
$config
->save();
parent::submitForm($form, $form_state);
// this is to prevent the default submit message
$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',
];
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ConfigFormBase:: |
public static | function |
Instantiates a new instance of this class. Overrides FormBase:: |
18 |
ConfigFormBase:: |
public | function | Constructs a \Drupal\system\ConfigFormBase object. | 16 |
ConfigFormBaseTrait:: |
protected | function | Retrieves a configuration object. | |
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
public | function | 2 | |
DependencySerializationTrait:: |
public | function | 2 | |
FormBase:: |
protected | property | The config factory. | 3 |
FormBase:: |
protected | property | The request stack. | 1 |
FormBase:: |
protected | property | The route match. | |
FormBase:: |
protected | function | Gets the config factory for this form. | 3 |
FormBase:: |
private | function | Returns the service container. | |
FormBase:: |
protected | function | Gets the current user. | |
FormBase:: |
protected | function | Gets the request object. | |
FormBase:: |
protected | function | Gets the route match. | |
FormBase:: |
protected | function | Gets the logger for a specific channel. | |
FormBase:: |
protected | function | Returns a redirect response object for the specified route. | |
FormBase:: |
public | function | Resets the configuration factory. | |
FormBase:: |
public | function | Sets the config factory for this form. | |
FormBase:: |
public | function | Sets the request stack object to use. | |
FormBase:: |
public | function |
Form validation handler. Overrides FormInterface:: |
72 |
GConfigForm:: |
public | function |
Form constructor. Overrides ConfigFormBase:: |
|
GConfigForm:: |
private | function | ||
GConfigForm:: |
private | function | ||
GConfigForm:: |
private | function | ||
GConfigForm:: |
private | function | ||
GConfigForm:: |
protected | function |
Gets the configuration names that will be editable. Overrides ConfigFormBaseTrait:: |
|
GConfigForm:: |
public | function |
Returns a unique string identifying the form. Overrides FormInterface:: |
|
GConfigForm:: |
public | function |
Form submission handler. Overrides ConfigFormBase:: |
|
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 27 |
MessengerTrait:: |
public | function | Gets the messenger. | 27 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 4 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |