Introduce Exporter::hasCustomRepresentationFor() for checking whether an object exporter provides the representation for an object

This commit is contained in:
Sebastian Bergmann 2026-08-01 09:45:25 +02:00
parent 1ff285c572
commit 642e2bbda7
No known key found for this signature in database
4 changed files with 75 additions and 0 deletions

View File

@ -8,6 +8,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
* `ObjectExporter` interface, `ObjectExporterChain`, and `ExportContext` for customizing how objects are exported (an object exporter can be passed to `Exporter`'s constructor and is consulted before the default representation of an object is used) * `ObjectExporter` interface, `ObjectExporterChain`, and `ExportContext` for customizing how objects are exported (an object exporter can be passed to `Exporter`'s constructor and is consulted before the default representation of an object is used)
* `Exporter::shortenedExport()` and `Exporter::shortenedRecursiveExport()` use the representation provided by an object exporter as well; it is collapsed to a single line and shortened when it is longer than the configured maximum length * `Exporter::shortenedExport()` and `Exporter::shortenedRecursiveExport()` use the representation provided by an object exporter as well; it is collapsed to a single line and shortened when it is longer than the configured maximum length
* `Exporter::hasCustomRepresentationFor()` for checking whether an object exporter provides the representation for an object
## [8.1.1] - 2026-07-13 ## [8.1.1] - 2026-07-13

View File

@ -334,3 +334,22 @@ print $exporter->shortenedExport(new Money(1999, 'EUR'));
``` ```
Bear in mind that these representations are used where a short, single-line, and stable string is required. The representation of a data set is built using `Exporter::shortenedRecursiveExport()`, for instance, and is part of the name of a test that uses a data provider. An object exporter should therefore provide a representation that is compact and that does not change from one export to the next. Bear in mind that these representations are used where a short, single-line, and stable string is required. The representation of a data set is built using `Exporter::shortenedRecursiveExport()`, for instance, and is part of the name of a test that uses a data provider. An object exporter should therefore provide a representation that is compact and that does not change from one export to the next.
### Custom Representations
`Exporter::hasCustomRepresentationFor()` tells whether an object exporter provides the representation for an object. This is meant for code that renders objects itself and wants to use the representation an object exporter provides when there is one:
```php
<?php declare(strict_types=1);
use SebastianBergmann\Exporter\Exporter;
$exporter = new Exporter(objectExporter: new MoneyExporter);
// true
var_dump($exporter->hasCustomRepresentationFor(new Money(1999, 'EUR')));
// false
var_dump($exporter->hasCustomRepresentationFor(new stdClass));
```
Bear in mind that an object that is (indirectly) nested in itself is replaced with a reference to the object instead of being exported by an object exporter again.

View File

@ -202,6 +202,26 @@ final readonly class Exporter
return $this->export($value); return $this->export($value);
} }
/**
* Returns whether a custom object exporter provides the representation
* for an object.
*
* This is intended for code that renders objects itself and wants to use
* the representation a custom object exporter provides when there is one.
*
* Bear in mind that an object that is (indirectly) nested in itself is
* replaced with a reference to the object instead of being exported by a
* custom object exporter again.
*/
public function hasCustomRepresentationFor(object $object): bool
{
if ($this->objectExporter === null) {
return false;
}
return $this->objectExporter->handles($object);
}
/** /**
* Converts an object to an array containing all of its private, protected * Converts an object to an array containing all of its private, protected
* and public properties. * and public properties.

View File

@ -939,6 +939,41 @@ EOT,
); );
} }
public function testKnowsThatCustomObjectExporterProvidesRepresentationForObjectItHandles(): void
{
$exporter = new Exporter(
0,
40,
new ObjectExporterChain(
[
new ObjectExporterThatHandlesObjectsOfSpecificType(ExampleClass::class),
],
),
);
$this->assertTrue($exporter->hasCustomRepresentationFor(new ExampleClass('bar')));
}
public function testKnowsThatCustomObjectExporterDoesNotProvideRepresentationForObjectItDoesNotHandle(): void
{
$exporter = new Exporter(
0,
40,
new ObjectExporterChain(
[
new ObjectExporterThatHandlesObjectsOfSpecificType(ExampleClass::class),
],
),
);
$this->assertFalse($exporter->hasCustomRepresentationFor(new stdClass));
}
public function testKnowsThatNoCustomObjectExporterProvidesRepresentationForObjectWhenNoneIsConfigured(): void
{
$this->assertFalse((new Exporter)->hasCustomRepresentationFor(new stdClass));
}
public function testCustomObjectExporterCanExportValuesNestedInObjectItHandles(): void public function testCustomObjectExporterCanExportValuesNestedInObjectItHandles(): void
{ {
$exporter = new Exporter( $exporter = new Exporter(