PageRenderTime 24ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/web/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php

https://gitlab.com/mohamed_hussein/prodt
PHP | 282 lines | 190 code | 36 blank | 56 comment | 27 complexity | dd15e220dc00b7eaa00ed801af169a0f MD5 | raw file
  1. <?php
  2. namespace Drupal\views_ui\Form\Ajax;
  3. use Drupal\Core\Form\FormStateInterface;
  4. use Drupal\views\ViewEntityInterface;
  5. use Drupal\views\ViewExecutable;
  6. use Drupal\views\Views;
  7. use Symfony\Component\HttpFoundation\Request;
  8. /**
  9. * Provides a form for configuring an item in the Views UI.
  10. *
  11. * @internal
  12. */
  13. class ConfigHandler extends ViewsFormBase {
  14. /**
  15. * Constructs a new ConfigHandler object.
  16. */
  17. public function __construct($type = NULL, $id = NULL) {
  18. $this->setType($type);
  19. $this->setID($id);
  20. }
  21. /**
  22. * {@inheritdoc}
  23. */
  24. public function getFormKey() {
  25. return 'handler';
  26. }
  27. /**
  28. * {@inheritdoc}
  29. */
  30. public function getForm(ViewEntityInterface $view, $display_id, $js, $type = NULL, $id = NULL) {
  31. $this->setType($type);
  32. $this->setID($id);
  33. return parent::getForm($view, $display_id, $js);
  34. }
  35. /**
  36. * {@inheritdoc}
  37. */
  38. public function getFormId() {
  39. return 'views_ui_config_item_form';
  40. }
  41. /**
  42. * {@inheritdoc}
  43. */
  44. public function buildForm(array $form, FormStateInterface $form_state, Request $request = NULL) {
  45. /** @var \Drupal\views\Entity\View $view */
  46. $view = $form_state->get('view');
  47. $display_id = $form_state->get('display_id');
  48. $type = $form_state->get('type');
  49. $id = $form_state->get('id');
  50. $form = [
  51. 'options' => [
  52. '#tree' => TRUE,
  53. '#theme_wrappers' => ['container'],
  54. '#attributes' => ['class' => ['scroll'], 'data-drupal-views-scroll' => TRUE],
  55. ],
  56. ];
  57. $executable = $view->getExecutable();
  58. $save_ui_cache = FALSE;
  59. if (!$executable->setDisplay($display_id)) {
  60. $form['markup'] = ['#markup' => $this->t('Invalid display id @display', ['@display' => $display_id])];
  61. return $form;
  62. }
  63. $item = $executable->getHandler($display_id, $type, $id);
  64. if ($item) {
  65. $handler = $executable->display_handler->getHandler($type, $id);
  66. if (empty($handler)) {
  67. $form['markup'] = ['#markup' => $this->t("Error: handler for @table > @field doesn't exist!", ['@table' => $item['table'], '@field' => $item['field']])];
  68. }
  69. else {
  70. $types = ViewExecutable::getHandlerTypes();
  71. // If this item can come from the default display, show a dropdown
  72. // that lets the user choose which display the changes should apply to.
  73. if ($executable->display_handler->defaultableSections($types[$type]['plural'])) {
  74. $section = $types[$type]['plural'];
  75. $form_state->set('section', $section);
  76. views_ui_standard_display_dropdown($form, $form_state, $section);
  77. }
  78. // A whole bunch of code to figure out what relationships are valid for
  79. // this item.
  80. $relationships = $executable->display_handler->getOption('relationships');
  81. $relationship_options = [];
  82. foreach ($relationships as $relationship) {
  83. // relationships can't link back to self. But also, due to ordering,
  84. // relationships can only link to prior relationships.
  85. if ($type == 'relationship' && $id == $relationship['id']) {
  86. break;
  87. }
  88. $relationship_handler = Views::handlerManager('relationship')->getHandler($relationship);
  89. // ignore invalid/broken relationships.
  90. if (empty($relationship_handler)) {
  91. continue;
  92. }
  93. // If this relationship is valid for this type, add it to the list.
  94. $data = Views::viewsData()->get($relationship['table']);
  95. if (isset($data[$relationship['field']]['relationship']['base']) && $base = $data[$relationship['field']]['relationship']['base']) {
  96. $base_fields = Views::viewsDataHelper()->fetchFields($base, $type, $executable->display_handler->useGroupBy());
  97. if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
  98. $relationship_handler->init($executable, $executable->display_handler, $relationship);
  99. $relationship_options[$relationship['id']] = $relationship_handler->adminLabel();
  100. }
  101. }
  102. }
  103. if (!empty($relationship_options)) {
  104. // Make sure the existing relationship is even valid. If not, force
  105. // it to none.
  106. $base_fields = Views::viewsDataHelper()->fetchFields($view->get('base_table'), $type, $executable->display_handler->useGroupBy());
  107. if (isset($base_fields[$item['table'] . '.' . $item['field']])) {
  108. $relationship_options = array_merge(['none' => $this->t('Do not use a relationship')], $relationship_options);
  109. }
  110. $rel = empty($item['relationship']) ? 'none' : $item['relationship'];
  111. if (empty($relationship_options[$rel])) {
  112. // Pick the first relationship.
  113. $rel = key($relationship_options);
  114. // We want this relationship option to get saved even if the user
  115. // skips submitting the form.
  116. $executable->setHandlerOption($display_id, $type, $id, 'relationship', $rel);
  117. $save_ui_cache = TRUE;
  118. // Re-initialize with new relationship.
  119. $item['relationship'] = $rel;
  120. $handler->init($executable, $executable->display_handler, $item);
  121. }
  122. $form['options']['relationship'] = [
  123. '#type' => 'select',
  124. '#title' => $this->t('Relationship'),
  125. '#options' => $relationship_options,
  126. '#default_value' => $rel,
  127. '#weight' => -500,
  128. ];
  129. }
  130. else {
  131. $form['options']['relationship'] = [
  132. '#type' => 'value',
  133. '#value' => 'none',
  134. ];
  135. }
  136. $form['#title'] = $this->t('Configure @type: @item', ['@type' => $types[$type]['lstitle'], '@item' => $handler->adminLabel()]);
  137. if (!empty($handler->definition['help'])) {
  138. $form['options']['form_description'] = [
  139. '#markup' => $handler->definition['help'],
  140. '#theme_wrappers' => ['container'],
  141. '#attributes' => ['class' => ['js-form-item form-item description']],
  142. '#weight' => -1000,
  143. ];
  144. }
  145. $form['#section'] = $display_id . '-' . $type . '-' . $id;
  146. // Get form from the handler.
  147. $handler->buildOptionsForm($form['options'], $form_state);
  148. $form_state->set('handler', $handler);
  149. }
  150. $name = $form_state->get('update_name');
  151. $view->getStandardButtons($form, $form_state, 'views_ui_config_item_form', $name);
  152. // Add a 'remove' button.
  153. $form['actions']['remove'] = [
  154. '#type' => 'submit',
  155. '#value' => $this->t('Remove'),
  156. '#submit' => [[$this, 'remove']],
  157. '#limit_validation_errors' => [['override']],
  158. '#button_type' => 'danger',
  159. ];
  160. }
  161. if ($save_ui_cache) {
  162. $view->cacheSet();
  163. }
  164. return $form;
  165. }
  166. /**
  167. * {@inheritdoc}
  168. */
  169. public function validateForm(array &$form, FormStateInterface $form_state) {
  170. $form_state->get('handler')->validateOptionsForm($form['options'], $form_state);
  171. if ($form_state->getErrors()) {
  172. $form_state->set('rerender', TRUE);
  173. }
  174. }
  175. /**
  176. * {@inheritdoc}
  177. */
  178. public function submitForm(array &$form, FormStateInterface $form_state) {
  179. $view = $form_state->get('view');
  180. $display_id = $form_state->get('display_id');
  181. $id = $form_state->get('id');
  182. $handler = $form_state->get('handler');
  183. // Run it through the handler's submit function.
  184. $handler->submitOptionsForm($form['options'], $form_state);
  185. $item = $handler->options;
  186. $types = ViewExecutable::getHandlerTypes();
  187. // For footer/header $handler_type is area but $type is footer/header.
  188. // For all other handle types it's the same.
  189. $handler_type = $type = $form_state->get('type');
  190. if (!empty($types[$type]['type'])) {
  191. $handler_type = $types[$type]['type'];
  192. }
  193. $override = NULL;
  194. $executable = $view->getExecutable();
  195. if ($executable->display_handler->useGroupBy() && !empty($item['group_type'])) {
  196. if (empty($executable->query)) {
  197. $executable->initQuery();
  198. }
  199. $aggregate = $executable->query->getAggregationInfo();
  200. if (!empty($aggregate[$item['group_type']]['handler'][$type])) {
  201. $override = $aggregate[$item['group_type']]['handler'][$type];
  202. }
  203. }
  204. // Create a new handler and unpack the options from the form onto it. We
  205. // can use that for storage.
  206. $handler = Views::handlerManager($handler_type)->getHandler($item, $override);
  207. $handler->init($executable, $executable->display_handler, $item);
  208. // Add the incoming options to existing options because items using
  209. // the extra form may not have everything in the form here.
  210. $options = $handler->submitFormCalculateOptions($handler->options, $form_state->getValue('options', []));
  211. // This unpacks only options that are in the definition, ensuring random
  212. // extra stuff on the form is not sent through.
  213. $handler->unpackOptions($handler->options, $options, NULL, FALSE);
  214. // Store the item back on the view
  215. $executable->setHandler($display_id, $type, $id, $handler->options);
  216. // Ensure any temporary options are removed.
  217. if (isset($view->temporary_options[$type][$id])) {
  218. unset($view->temporary_options[$type][$id]);
  219. }
  220. // Write to cache
  221. $view->cacheSet();
  222. }
  223. /**
  224. * Submit handler for removing an item from a view.
  225. */
  226. public function remove(&$form, FormStateInterface $form_state) {
  227. $view = $form_state->get('view');
  228. $display_id = $form_state->get('display_id');
  229. $type = $form_state->get('type');
  230. $id = $form_state->get('id');
  231. // Store the item back on the view
  232. [$was_defaulted, $is_defaulted] = $view->getOverrideValues($form, $form_state);
  233. $executable = $view->getExecutable();
  234. // If the display selection was changed toggle the override value.
  235. if ($was_defaulted != $is_defaulted) {
  236. $display = &$executable->displayHandlers->get($display_id);
  237. $display->optionsOverride($form, $form_state);
  238. }
  239. $executable->removeHandler($display_id, $type, $id);
  240. // Write to cache
  241. $view->cacheSet();
  242. }
  243. }