Problem/Motivation

In FeedsFileSystemBase::saveData the return value is declared as on the interface:

The file uri the data was saved to. This includes the uri to the feeds directory.

But in fact this method only returns the destination, the file should be saved to. It uses drupal cores file_system service which eventually renames the file if another file with the same name already exists. This can result in a wrong return since the saveData does just return the destination.

  /**
   * {@inheritdoc}
   */
  public function saveData($data, string $filename): string {
    $destination = $this->getFeedsDirectory() . '/' . $filename;
    $directory = $this->fileSystem->dirname($destination);
    $this->prepareDirectory($directory);

    $this->fileSystem->saveData($data, $destination);
    return $destination;
  }

The file_system service does return the real url.
$this->fileSystem->saveData($data, $destination);

Steps to reproduce

- Process a feed which uses a file as ressource
- cancel the process
- change something in the feed
- start it again with that changed file

In my case the old file is still present and the new one with the changes is not getting used, since the saveData method returns the wrong file.

Proposed resolution

Return the url the file_system returns.

Issue fork feeds-3406779

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Hydra created an issue. See original summary.

Hydra changed the visibility of the branch 3406779-savedata-in-feedsfilesystembase to hidden.

Hydra changed the visibility of the branch 3406779-savedata-in-feedsfilesystembase to active.

hydra’s picture

Status: Active » Needs review

I added the path returning from file_system in consideration for the return value. This this can be FALSE in theory, I added a fallback to the current behavior.
Another possible attend would be to replace the existing file. This could be achieved like that:

    $this->fileSystem->saveData($data, $destination, FileSystemInterface::EXISTS_REPLACE);

I'm not sure whats better.

MegaChriz made their first commit to this issue’s fork.

  • MegaChriz committed e7d3d7d4 on 8.x-3.x authored by Hydra
    Issue #3406779 by Hydra: FeedsFileSystemBase::saveData() should return...
megachriz’s picture

Status: Needs review » Fixed

I think that the file getting renamed upon save if one already exists with the same name is safer. It looks like that FALSE can only be returned when the $replace parameter of Drupal\Core\File\FileSystemInterface::saveData() is FileSystemInterface::EXISTS_ERROR, but there could theoritically be different behavior for classes that override the file_system service.

Using Feeds Log, I checked if the new return value was still correct and I can confirm that that was the case. I merged the code!

hydra’s picture

Nice, thx!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.