View source
<?php
namespace Drupal\quicktabs\Form;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\quicktabs\Entity\QuickTabsInstance;
use Drupal\quicktabs\TabRendererManager;
use Drupal\quicktabs\TabTypeManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
class QuickTabsInstanceEditForm extends EntityForm {
protected $tabRendererManager;
protected $tabTypeManager;
protected $messenger;
public function __construct(TabRendererManager $tab_renderer, TabTypeManager $tab_type, MessengerInterface $messenger) {
$this->tabRendererManager = $tab_renderer;
$this->tabTypeManager = $tab_type;
$this->messenger = $messenger;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.tab_renderer'), $container
->get('plugin.manager.tab_type'), $container
->get('messenger'));
}
public function getFormId() {
return 'quicktab_instance_edit';
}
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
$form['label'] = [
'#title' => $this
->t('Name'),
'#description' => $this
->t('This will appear as the block title.'),
'#type' => 'textfield',
'#default_value' => $this->entity
->label(),
'#weight' => -9,
'#required' => TRUE,
'#placeholder' => $this
->t('Enter name'),
];
$form['id'] = [
'#type' => 'machine_name',
'#maxlength' => 32,
'#required' => TRUE,
'#default_value' => $this->entity
->id(),
'#machine_name' => [
'exists' => 'Drupal\\quicktabs\\Entity\\QuickTabsInstance::getQuickTabsInstance',
],
'#description' => $this
->t('A unique machine-readable name for this QuickTabs instance. It must only contain lowercase letters, numbers, and underscores. The machine name will be used internally by QuickTabs and will be used in the CSS ID of your QuickTabs block.'),
'#weight' => -8,
];
$plugin_definitions = $this->tabRendererManager
->getDefinitions();
$renderers = [];
$renderer_form_options = [];
foreach ($plugin_definitions as $index => $def) {
$renderers[$index] = $def['name']
->__toString();
$object = $this->tabRendererManager
->createInstance($index);
$renderer_form_options[$index] = $object
->optionsForm($this->entity);
}
$form['renderer'] = [
'#type' => 'select',
'#title' => $this
->t('Renderer'),
'#options' => $renderers,
'#default_value' => $this->entity
->getRenderer(),
'#description' => $this
->t('Choose how to render the content.'),
'#weight' => -7,
];
$form['options'] = [
'#tree' => TRUE,
'#weight' => -6,
];
foreach ($renderer_form_options as $renderer => $options) {
foreach ($options as &$option) {
$option['#states'] = [
'visible' => [
':input[name="renderer"]' => [
'value' => $renderer,
],
],
];
}
$form['options'][$renderer] = $options;
}
$form['hide_empty_tabs'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Hide empty tabs'),
'#default_value' => $this->entity
->getHideEmptyTabs(),
'#description' => $this
->t('Empty and restricted tabs will not be displayed. Could be useful when the tab content is not accessible.<br />This option does not work in ajax mode.'),
'#weight' => -3,
];
$tab_titles = [
QuickTabsInstance::QUICKTABS_DELTA_NONE => $this
->t('- None -'),
];
$qt = new \stdClass();
if (!empty($form_state
->getValue('configuration_data'))) {
$qt->tabs = $form_state
->getValue('configuration_data');
}
else {
$qt->tabs = $this->entity
->getConfigurationData();
}
if (empty($qt->tabs)) {
$qt->tabs = [
0 => [],
1 => [],
];
}
else {
if (is_numeric($form_state
->get('to_remove'))) {
unset($qt->tabs[$form_state
->get('to_remove')]);
$form_state
->set('num_tabs', $form_state
->get('num_tabs') - 1);
}
if ($form_state
->get('num_tabs') > count($qt->tabs)) {
$qt->tabs[] = [];
}
}
$delta = 0;
if (!empty($qt->tabs)) {
foreach ($qt->tabs as $tab) {
if (!empty($tab)) {
$tab_titles[$delta] = $tab['title'];
$delta++;
}
}
}
$form['default_tab'] = [
'#type' => 'select',
'#title' => $this
->t('Default tab'),
'#options' => $tab_titles,
'#default_value' => $this->entity
->getDefaultTab(),
'#access' => !empty($tab_titles),
'#weight' => -4,
];
$form['configuration_data_wrapper'] = [
'#tree' => FALSE,
'#weight' => -3,
'#prefix' => '<div class="clear-block" id="configuration-data-wrapper">',
'#suffix' => '</div>',
];
$form['configuration_data_wrapper']['configuration_data'] = $this
->getConfigurationDataForm($qt);
$form['tabs_more'] = [
'#name' => 'tabs_more',
'#type' => 'submit',
'#value' => $this
->t('Add tab'),
'#attributes' => [
'class' => [
'add-tab',
],
'title' => $this
->t('Click here to add more tabs.'),
],
'#weight' => 1,
'#submit' => [
[
$this,
'ajaxFormSubmit',
],
],
'#ajax' => [
'callback' => [
$this,
'ajaxFormCallback',
],
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
'effect' => 'fade',
],
];
$form['#attached']['library'][] = 'quicktabs/quicktabs.form';
return $form;
}
public function ajaxFormCallback(array &$form, FormStateInterface $form_state) {
$ajax_response = new AjaxResponse();
$ajax_response
->addCommand(new HtmlCommand('#configuration-data-wrapper', $form['configuration_data_wrapper']['configuration_data']));
return $ajax_response;
}
public function ajaxFormSubmit(array &$form, FormStateInterface $form_state) {
if ($form_state
->getTriggeringElement()['#name'] === 'tabs_more') {
$form_state
->set('num_tabs', count($form_state
->getValue('configuration_data')) + 1);
$form_state
->setRebuild(TRUE);
}
elseif (is_numeric($form_state
->getTriggeringElement()['#row_number'])) {
$form_state
->set('to_remove', $form_state
->getTriggeringElement()['#row_number']);
$form_state
->setRebuild(TRUE);
}
}
public function validate(array $form, FormStateInterface $form_state) {
$id = $form_state
->getValue('id');
if (empty($id)) {
$form_state
->setErrorByName('machine_name', $this
->t('The quicktabs machine name is required.'));
}
elseif (!preg_match('!^[a-z0-9_]+$!', $id)) {
$form_state
->setErrorByName('machine_name', $this
->t('The quicktabs machine name must contain only lowercase letters, numbers, and underscores.'));
}
$tabs = $form_state
->getValue('tabs');
if (!isset($tabs)) {
$form_state
->setErrorByName('', $this
->t('At least one tab should be created.'));
}
else {
foreach ($tabs as $j => $tab) {
if (empty($tab['title'])) {
$form_state
->setErrorByName('tabs][' . $j . '][title', $this
->t('Title is required for each tab.'));
}
}
}
}
public function save(array $form, FormStateInterface $form_state) {
$ordered_configuration_data = [];
foreach ($this->entity
->getConfigurationData() as $item) {
$ordered_configuration_data[] = $item;
}
$this->entity
->setConfigurationData($ordered_configuration_data);
$status = $this->entity
->save();
if ($status == SAVED_NEW) {
$form_state
->setRedirect('quicktabs.admin');
}
$this->messenger
->addStatus($this
->t('Your changes have been saved.'));
drupal_flush_all_caches();
}
private function getConfigurationDataForm($qt) {
$configuration_data = [
'#type' => 'table',
'#header' => [
$this
->t('Tab title'),
$this
->t('Tab weight'),
$this
->t('Tab type'),
$this
->t('Tab content'),
$this
->t('Operations'),
],
'#empty' => $this
->t('There are no tabs yet'),
'#tabledrag' => [
[
'action' => 'order',
'relationship' => 'sibling',
'group' => 'mytable-order-weight',
],
],
];
foreach ($qt->tabs as $index => $tab) {
$tab['entity_id'] = $this->entity
->id();
$tab['delta'] = $index;
$configuration_data[$index] = $this
->getRow($index, $tab);
}
return $configuration_data;
}
private function getRow($row_number, $tab = NULL) {
if ($tab === NULL) {
$tab = [];
}
$type = $this->tabTypeManager;
$plugin_definitions = $type
->getDefinitions();
$types = [];
foreach ($plugin_definitions as $index => $def) {
$name = $def['name'];
$types[$index] = $name
->render();
}
ksort($types);
$row = [];
$row['#attributes']['class'][] = 'draggable';
$row['#weight'] = isset($tab['weight']) ? $tab['weight'] : 0;
$row['title'] = [
'#type' => 'textfield',
'#size' => '10',
'#default_value' => isset($tab['title']) ? $tab['title'] : '',
];
$row['weight'] = [
'#type' => 'weight',
'#title' => $this
->t('Weight'),
'#title_display' => 'invisible',
'#default_value' => isset($tab['weight']) ? $tab['weight'] : 0,
'#attributes' => [
'class' => [
'mytable-order-weight',
],
],
];
$row['type'] = [
'#type' => 'select',
'#options' => $types,
'#default_value' => isset($tab['type']) ? $tab['type'] : key($types),
];
foreach ($plugin_definitions as $index => $def) {
$name = $def['name'];
$row['content'][$index] = [
'#prefix' => '<div class="' . $index . '-plugin-content plugin-content qt-tab-options-form qt-tab-' . $index . '-options-form" >',
'#suffix' => '</div>',
];
$object = $type
->createInstance($index);
$row['content'][$index]['options'] = $object
->optionsForm($tab);
}
$row['operations'] = [
'#row_number' => $row_number,
'#name' => 'row-' . $row_number,
'#type' => 'submit',
'#value' => $this
->t('Remove'),
'#attributes' => [
'class' => [
'delete-tab',
],
'title' => $this
->t('Click here to delete this tab.'),
],
'#submit' => [
[
$this,
'ajaxFormSubmit',
],
],
'#ajax' => [
'callback' => [
$this,
'ajaxFormCallback',
],
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
'effect' => 'fade',
],
];
return $row;
}
}