I was having an issue where the import would fail and checking the item object on an afterParse event the headers of the csv were not being mapped accordingly.
It was a silly mistake on the csv or on the csv export that there was an extra space added by the end of some of the headers.

Adding a simple trim to the CsvParser solved the issue. I know it's very minor and stupid mistake, but this are hand made csvs and prone to mistakes so I want to make sure that my import won't run because of that. Couldn't find any other way of trimming/altering the headers before the import and it was so minor that wouldn't justify a custom Parser.

Issue fork feeds-3153083

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

bbombachini created an issue. See original summary.

bbombachini’s picture

StatusFileSize
new633 bytes
bbombachini’s picture

Title: CSV headers with extra space doesn't get mapped to correct field » CSV headers with extra space don't get mapped to correct fields
jamesdixon’s picture

I guess a tamper trim plugin wouldn't work on this because it's the headers of the CSV file.

@megachriz: Do you think we should always trim headers or would that mess up some use cases?

megachriz’s picture

Status: Active » Needs work
Issue tags: +Needs tests

I think trimming the CSV source columns when entering them in the user interface is a good idea.

Trimming the CSV column names during parsing should then happen as well.

This needs a test to ensure that a CSV file with extra spaces in the column names can be imported without issues. The test could be added to the existing class \Drupal\Tests\feeds\Kernel\Feeds\Parser\CsvParserTest.

jamesdixon’s picture

Great, we could call it something like trimColumnNameTest().

matroskeen’s picture

StatusFileSize
new583 bytes

This is just a re-roll for the latest module version.

megachriz’s picture

I've written some tests. I did it on mobile though (via gitlab web IDE), so let's see how that goes.

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

gomez_in_the_south’s picture

The commit I added was just to pull in the latest dev branch changes and fix the associated merge conflict.

The new tests seem to still be failing, though I didn't piece together what may need to be changed in the CSV Parser to resolve this.

megachriz’s picture

Status: Needs work » Needs review

I think this is now good enough to test and review.

metasim’s picture

StatusFileSize
new788 bytes

rerolling the patch for 3.0

benstallings’s picture

Version: 8.x-3.0-alpha7 » 8.x-3.x-dev
Status: Needs review » Needs work

Claude Code says, re patch #14:

Two bugs introduced

1. Null coalescing (??) replaced with truthy check — changes behavior for missing headers.

?? triggers only when $header[$delta] is null or undefined. The replacement ?: (truthy check) also triggers when the value is "" (empty string), "0", or false. A CSV header column literally named "0" would be silently replaced with the numeric delta index. More practically, if a header is an empty string, the old code would use "" as the key; the new code uses the numeric index, changing which source the column maps to.

2. PHP warning when header index doesn't exist.

$header[$delta] ?? $delta safely handles the case where $header[$delta] is undefined (no warning). The replacement $header[$delta] ? ... will emit an Undefined array key warning in PHP 8.x when $delta exceeds the header array length (which happens when a data row has more columns than the header row).

The right fix

Keep ?? for safety and add trim():
$key = isset($header[$delta]) ? trim($header[$delta]) : $delta;

Or more concisely:
$key = trim($header[$delta] ?? '') ?: $delta;

Note also that trimming should arguably happen once when the header is read (in CsvFileParser::getHeader() or right after line 63), not on every row iteration. And the source mapping at line 43 already trims source values (trim(strval($info['value']))), so if the header is trimmed too, they'd match consistently.

Verdict

The idea is right — whitespace in CSV headers should be trimmed — but the implementation introduces two regressions. Use isset() + trim() instead of replacing the null coalescing operator, and consider trimming at the header level rather than per-row.

benstallings’s picture

Assigned: Unassigned » benstallings
benstallings’s picture

Assigned: benstallings » Unassigned
Status: Needs work » Needs review