Contextual Filters cause duplicate results when saving legacy 8.x-1.2 draggableviews_structure rows

Created on 9 February 2022, over 2 years ago
Updated 18 June 2024, 6 days ago

After updating from 8.x-1.2 to 2.0.1, legacy views using contextual filters will create duplicate rows in the draggableviews_structure table when saving.

I've tracked this down to the draggableviews_views_submit function in the draggableviews.module file.

  $view_args = !empty($view->args) ? json_encode($view->args) : '[]';

  $connection = Database::getConnection();
  $transaction = $connection->startTransaction();
  try {
    foreach ($input['draggableviews'] as $item) {
      // Remove old data.
      $connection->delete('draggableviews_structure')
        ->condition('view_name', $view_name)
        ->condition('view_display', $view_display)
        ->condition('args', $view_args)
        ->condition('entity_id', $item['id'])
        ->execute();

Since the previous structure inserted a value of '[]' into the 'args' column of the draggableviews_structure table, I've found that when using the "Save order" button to save the structure, new values are entered into the 'args' column containing the contextual filter values (e.g. '["3"]') but the rows with the old value of '[]' are not deleted. This causes the results in the view to be duplicated, since there is a row with '[]' displayed along with a row with the new value of $view_args.

In the code above since the condition('args', $view_args) will be for example condition('args', '["3"]') whereas the existing legacy value would need to be condition('args', '[]') in order to be properly deleted.

I propose changing it to something like:

  $view_args = !empty($view->args) ? json_encode($view->args) : '[]';

  $connection = Database::getConnection();
  $transaction = $connection->startTransaction();
  try {
    foreach ($input['draggableviews'] as $item) {
      // Remove potential legacy rows with args = '[]' to prevent duplicate results.
      if ($view_args !== '[]') {
        $connection->delete('draggableviews_structure')
        ->condition('view_name', $view_name)
        ->condition('view_display', $view_display)
        ->condition('args', '[]')
        ->condition('entity_id', $item['id'])
        ->execute();
      }

      // Remove old data.
      $connection->delete('draggableviews_structure')
        ->condition('view_name', $view_name)
        ->condition('view_display', $view_display)
        ->condition('args', $view_args)
        ->condition('entity_id', $item['id'])
        ->execute();

I'm not sure how this will affect other use cases, although my thinking is that it won't affect any, since if $view_args isn't empty it will delete any legacy rows with '[]', and replace them with the new value of $view_args, which should happen anyways...

...similarly, if $view_args is empty, things should proceed as usual and still not break anything...

πŸ› Bug report
Status

Needs work

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States Zooney

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.69.0 2024