5 * Contains draggableviews.module.
8 use Drupal\draggableviews\DraggableViews;
9 use Drupal\Core\Form\FormStateInterface;
10 use Drupal\Core\Database\Database;
11 use Drupal\Core\Cache\Cache;
14 * Implements hook_views_data_alter().
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.'),
28 'help' => t('Filter by the draggableviews weight value (Native handler only).'),
35 $data['draggableviews_structure']['parent'] = [
36 'title' => t('Parent'),
37 'help' => t('The parent entity id.'),
38 'group' => t('Draggableviews'),
43 'help' => t("Filter by the draggableviews parent's entity id (Native handler only)."),
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'],
61 'id' => 'draggable_views_field',
62 'click sortable' => FALSE,
65 // Explain to every entity how to join with draggableviews_structure
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',
79 * Implements hook_preprocess_views_view_table().
81 function draggableviews_preprocess_views_view_table(&$variables) {
82 $view = $variables['view'];
84 // If this view is not the sort view, then stop here.
85 if (!isset($view->field['draggableviews'])) {
89 $draggableviews = new DraggableViews($variables['view']);
92 foreach ($variables['rows'] as $key => $row) {
93 $columns = array_keys($row['columns']);
94 // Find the first column that is not the draggableviews field.
96 $first_column = current($columns);
97 if ($first_column !== 'draggableviews') {
100 // Set the first column.
101 $first_column = each($columns);
102 } while ($first_column);
104 // Indent the first column that is not the draggableviews field.
105 $columns_title = $row['columns'][$first_column]['content'][0]['field_output']['#markup'];
107 '#theme' => 'indentation',
108 '#size' => $draggableviews->getDepth($key),
110 $variables['rows'][$key]['columns'][$first_column]['content'][0]['field_output']['#markup'] = (string) (render($indent) . $columns_title);
113 // Add table attributes.
114 $variables['attributes']['id'] = $draggableviews->getHtmlId();
116 // Add rows attributes.
117 foreach ($variables['rows'] as &$row) {
118 $row['attributes']->addClass('draggable');
124 * Implements hook_form_alter().
126 function draggableviews_form_alter(&$form, FormStateInterface $form_state, $form_id) {
127 // Filter the right form.
128 if (strpos($form_id, 'views_form_') === FALSE) {
132 // Check whether the view is draggable.
133 $view = $form_state->getBuildInfo()['args'][0];
134 if (!isset($view->field['draggableviews'])) {
138 // Remove default submit button.
139 $form['actions']['submit']['#access'] = FALSE;
141 if (\Drupal::currentUser()->hasPermission('access draggableviews')) {
142 // Create draggableviews save order button.
143 $form['actions']['save_order'] = [
144 '#value' => t('Save order'),
149 // If there is no results remove the save-order button.
150 if (!isset($form['draggableviews'][0])) {
151 $form['actions']['save_order']['#access'] = FALSE;
155 $form['actions']['save_order']['#submit'][] = 'draggableviews_views_submit';
161 function draggableviews_views_submit(&$form, FormStateInterface $form_state) {
162 $input = $form_state->getUserInput();
164 /** @var \Drupal\views\ViewExecutable $view */
165 $view = $form_state->getBuildInfo()['args'][0];
166 $view_name = $view->id();
167 $view_display = $view->current_display;
171 $connection = Database::getConnection();
172 $transaction = $connection->startTransaction();
174 foreach ($input['draggableviews'] as $item) {
176 $connection->delete('draggableviews_structure')
177 ->condition('view_name', $view_name)
178 ->condition('view_display', $view_display)
179 ->condition('entity_id', $item['id'])
184 'view_name' => $view_name,
185 'view_display' => $view_display,
187 'entity_id' => $item['id'],
190 // Save parent if exists.
191 if (isset($item['parent'])) {
192 $record['parent'] = $item['parent'];
194 $connection->insert('draggableviews_structure')->fields($record)->execute();
197 // We invalidate the entity list cache, so other views are also aware of the
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';
204 $entity_type_id = reset($result);
205 $list_cache_tags = \Drupal::entityTypeManager()->getDefinition($entity_type_id)->getListCacheTags();
206 Cache::invalidateTags($list_cache_tags);
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');