Skip to content

Commit

Permalink
Adding support for the MapCell::ignore property
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Dec 15, 2023
1 parent b81b450 commit c302584
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ All Notable changes to `Csv` will be documented in this file
- `SwapDelimiter` stream filter to allow working with multibyte CSV delimiter
- `League\Csv\Serializer\AfterMapping` to work around the limitation aroud constructor usage.
- `Denormalizer` can register type alias to simplify callback usage.
- `League\Csv\Serializer\MapCell` has a new property `ignore` to qllow ignoring a property or a method typcasting during conversion.

### Deprecated

Expand Down
4 changes: 3 additions & 1 deletion docs/9.0/reader/record-mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,14 @@ The above rule can be translated in plain English like this:
This attribute will override any automatic resolution and enable fine-tuning type casting.
It can be used on class properties and methods regardless of their visibility and their type.

The attribute can take up to three (3) arguments which are all optional:
The attribute can take up to four (4) arguments which are all optional:

- The `column` argument tells the engine which record key to use via its numeric or name. If not present the property name or the name of the first argument of the `setter` method will be used. In such case, you are required to specify the property names information.
- The `cast` argument which accept the name of a class implementing the `TypeCasting` interface and responsible for type casting the record value. If not present, the mechanism will try to resolve the typecasting based on the property or method argument type.
- The `options` argument enables controlling typecasting by providing extra arguments to `TypeCasting::setOptions` method. The argument expects an associative array and relies on named arguments to inject its value to the method.
- The `ignore` arguemnt which is a boolean control if the property or method should be completely ignored by the mechanism. By default its value is `false`. This property takes precedence over all the other properties of the attribute once set to `true`.

<p class="message-info">The <code>ignore</code> argument was added in version <code>9.13.0</code></p>
<p class="message-notice">You can use the mechanism on a CSV without a header row but it requires
adding a <code>MapCell</code> attribute on each property or method needed for the conversion. Or you
can use the optional second argument of <code>TabularDataReader::getObjects</code> to specify the
Expand Down
6 changes: 5 additions & 1 deletion src/Serializer/Denormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,12 @@ private function autoDiscoverPropertySetter(ReflectionMethod|ReflectionProperty
*
* @throws MappingFailed
*/
private function findPropertySetter(MapCell $cell, ReflectionMethod|ReflectionProperty $accessor, array $propertyNames): PropertySetter
private function findPropertySetter(MapCell $cell, ReflectionMethod|ReflectionProperty $accessor, array $propertyNames): ?PropertySetter
{
if ($cell->ignore) {
return null;
}

$typeCaster = $this->resolveTypeCaster($cell, $accessor);

$offset = $cell->column ?? match (true) {
Expand Down
34 changes: 34 additions & 0 deletions src/Serializer/DenormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,40 @@ public function __construct(
self::assertInstanceOf($class::class, $instance);
self::assertSame('yamoussokro', $instance->str);
}

#[Test]
public function it_will_ignore_the_property_during_auto_discovery(): void
{
$classIgnoreMethod = new class () {
public DateTimeInterface $observedOn;

#[MapCell(ignore: true)]
public function setObservedOn(DateTimeInterface $observedOn): void
{
$this->observedOn = DateTime::createFromInterface($observedOn);
}
};

$instance = Denormalizer::assign($classIgnoreMethod::class, ['observedOn' => '2023-10-01']);

self::assertInstanceOf($classIgnoreMethod::class, $instance);
self::assertInstanceOf(DateTimeImmutable::class, $instance->observedOn);

$classIgnoreProperty = new class () {
#[MapCell(ignore: true)]
public DateTimeInterface $observedOn;

public function setObservedOn(DateTimeInterface $observedOn): void
{
$this->observedOn = DateTime::createFromInterface($observedOn);
}
};

$instance = Denormalizer::assign($classIgnoreProperty::class, ['observedOn' => '2023-10-01']);

self::assertInstanceOf($classIgnoreProperty::class, $instance);
self::assertInstanceOf(DateTime::class, $instance->observedOn);
}
}

enum Place: string
Expand Down
3 changes: 2 additions & 1 deletion src/Serializer/MapCell.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ final class MapCell
public function __construct(
public readonly string|int|null $column = null,
public readonly ?string $cast = null,
public readonly array $options = []
public readonly array $options = [],
public readonly bool $ignore = false,
) {
}
}

0 comments on commit c302584

Please sign in to comment.