Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / draggableviews / draggableviews.module
1 <?php
2
3 /**
4  * @file
5  * Contains draggableviews.module.
6  */
7
8 use Drupal\draggableviews\DraggableViews;
9 use Drupal\Core\Form\FormStateInterface;
10 use Drupal\Core\Database\Database;
11 use Drupal\Core\Cache\Cache;
12
13 /**
14  * Implements hook_views_data_alter().
15  */
16 function draggableviews_views_data_alter(&$data) {
17   $data['draggableviews_structure']['weight'] = [
18     'title' => t('DraggableViews Weight'),
19     'group' => t('Draggableviews'),
20     'help' => t('Display the weight value.'),
21     'field' => [
22       'id' => 'numeric',
23     ],
24     'sort' => [
25       'id' => 'standard',
26     ],
27     'filter' => [
28       'help' => t('Filter by the draggableviews weight value (Native handler only).'),
29       'id' => 'numeric',
30     ],
31     'argument' => [
32       'id' => 'numeric',
33     ],
34   ];
35   $data['draggableviews_structure']['parent'] = [
36     'title' => t('Parent'),
37     'help' => t('The parent entity id.'),
38     'group' => t('Draggableviews'),
39     'field' => [
40       'id' => 'numeric',
41     ],
42     'filter' => [
43       'help' => t("Filter by the draggableviews parent's entity id (Native handler only)."),
44       'id' => 'numeric',
45     ],
46     'argument' => [
47       'id' => 'numeric',
48     ],
49   ];
50
51   foreach (\Drupal::entityTypeManager()->getDefinitions() as $entity_type) {
52     $base_table = $entity_type->getDataTable() ?: $entity_type->getBaseTable();
53     $entity_keys = $entity_type->getKeys();
54     if ($base_table && isset($data[$base_table]['table'])) {
55       $data[$base_table]['draggableviews'] = [
56         'title' => $data[$base_table]['table']['group'],
57         'group' => t('Draggableviews'),
58         'help' => t('Provide a draggable functionality.'),
59         'entity field' => $entity_keys['id'],
60         'field' => [
61           'id' => 'draggable_views_field',
62           'click sortable' => FALSE,
63         ],
64       ];
65       // Explain to every entity how to join with draggableviews_structure
66       // table.
67       $data['draggableviews_structure']['table']['join'][$base_table] = [
68         'handler' => 'draggableviews_join_handler',
69         // Because this is a direct link it could be left out.
70         'left_table' => $base_table,
71         'left_field' => $entity_keys['id'],
72         'field' => 'entity_id',
73       ];
74     }
75   }
76 }
77
78 /**
79  * Implements hook_preprocess_views_view_table().
80  */
81 function draggableviews_preprocess_views_view_table(&$variables) {
82   $view = $variables['view'];
83
84   // If this view is not the sort view, then stop here.
85   if (!isset($view->field['draggableviews'])) {
86     return;
87   }
88
89   $draggableviews = new DraggableViews($variables['view']);
90
91   // Add hierarchy.
92   foreach ($variables['rows'] as $key => $row) {
93     $columns = array_keys($row['columns']);
94     // Find the first column that is not the draggableviews field.
95     do {
96       $first_column = current($columns);
97       if ($first_column !== 'draggableviews') {
98         break;
99       }
100       // Set the first column.
101       $first_column = each($columns);
102     } while ($first_column);
103
104     // Indent the first column that is not the draggableviews field.
105     $columns_title = $row['columns'][$first_column]['content'][0]['field_output']['#markup'];
106     $indent = [
107       '#theme' => 'indentation',
108       '#size' => $draggableviews->getDepth($key),
109     ];
110     $variables['rows'][$key]['columns'][$first_column]['content'][0]['field_output']['#markup'] = (string) (render($indent) . $columns_title);
111   }
112
113   // Add table attributes.
114   $variables['attributes']['id'] = $draggableviews->getHtmlId();
115
116   // Add rows attributes.
117   foreach ($variables['rows'] as &$row) {
118     $row['attributes']->addClass('draggable');
119   }
120   unset($row);
121 }
122
123 /**
124  * Implements hook_form_alter().
125  */
126 function draggableviews_form_alter(&$form, FormStateInterface $form_state, $form_id) {
127   // Filter the right form.
128   if (strpos($form_id, 'views_form_') === FALSE) {
129     return;
130   }
131
132   // Check whether the view is draggable.
133   $view = $form_state->getBuildInfo()['args'][0];
134   if (!isset($view->field['draggableviews'])) {
135     return;
136   }
137
138   // Remove default submit button.
139   $form['actions']['submit']['#access'] = FALSE;
140
141   if (\Drupal::currentUser()->hasPermission('access draggableviews')) {
142     // Create draggableviews save order button.
143     $form['actions']['save_order'] = [
144       '#value' => t('Save order'),
145       '#type' => 'submit',
146     ];
147   }
148
149   // If there is no results remove the save-order button.
150   if (!isset($form['draggableviews'][0])) {
151     $form['actions']['save_order']['#access'] = FALSE;
152     return;
153   }
154
155   $form['actions']['save_order']['#submit'][] = 'draggableviews_views_submit';
156 }
157
158 /**
159  * Submit handler.
160  */
161 function draggableviews_views_submit(&$form, FormStateInterface $form_state) {
162   $input = $form_state->getUserInput();
163
164   /** @var \Drupal\views\ViewExecutable $view */
165   $view = $form_state->getBuildInfo()['args'][0];
166   $view_name = $view->id();
167   $view_display = $view->current_display;
168
169   $weight = 0;
170
171   $connection = Database::getConnection();
172   $transaction = $connection->startTransaction();
173   try {
174     foreach ($input['draggableviews'] as $item) {
175       // Remove old data.
176       $connection->delete('draggableviews_structure')
177         ->condition('view_name', $view_name)
178         ->condition('view_display', $view_display)
179         ->condition('entity_id', $item['id'])
180         ->execute();
181
182       // Add new data.
183       $record = [
184         'view_name' => $view_name,
185         'view_display' => $view_display,
186         'args' => '[]',
187         'entity_id' => $item['id'],
188         'weight' => $weight,
189       ];
190       // Save parent if exists.
191       if (isset($item['parent'])) {
192         $record['parent'] = $item['parent'];
193       }
194       $connection->insert('draggableviews_structure')->fields($record)->execute();
195       $weight++;
196     }
197     // We invalidate the entity list cache, so other views are also aware of the
198     // cache.
199     $views_entity_table_info = $view->query->getEntityTableInfo();
200     // Find the entity type used by the view.
201     $result = array_keys(array_filter($views_entity_table_info, function ($info) {
202       return $info['relationship_id'] == 'none';
203     }));
204     $entity_type_id = reset($result);
205     $list_cache_tags = \Drupal::entityTypeManager()->getDefinition($entity_type_id)->getListCacheTags();
206     Cache::invalidateTags($list_cache_tags);
207   }
208   catch (\Exception $e) {
209     $transaction->rollback();
210     \Drupal::logger('draggableviews')->error('Failed with @message', ['@message' => $e->getMessage()]);
211     drupal_set_message(t('There was an error while saving the data. Please, try gain.'), 'warning');
212   }
213 }