Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c6a7f6d

Browse files
committed
[ObjectMapper] handle non existing property errors
1 parent ae30d7c commit c6a7f6d

File tree

4 files changed

+76
-1
lines changed

4 files changed

+76
-1
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\ObjectMapper\Exception;
13+
14+
/**
15+
* Thrown when a property cannot be found.
16+
*
17+
* @author Antoine Bluchet <[email protected]>
18+
*/
19+
class NoSuchPropertyException extends MappingException
20+
{
21+
}

src/Symfony/Component/ObjectMapper/ObjectMapper.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Psr\Container\ContainerInterface;
1515
use Symfony\Component\ObjectMapper\Exception\MappingException;
1616
use Symfony\Component\ObjectMapper\Exception\MappingTransformException;
17+
use Symfony\Component\ObjectMapper\Exception\NoSuchPropertyException;
1718
use Symfony\Component\ObjectMapper\Metadata\Mapping;
1819
use Symfony\Component\ObjectMapper\Metadata\ObjectMapperMetadataFactoryInterface;
1920
use Symfony\Component\ObjectMapper\Metadata\ReflectionObjectMapperMetadataFactory;
@@ -167,7 +168,15 @@ public function map(object $source, object|string|null $target = null): object
167168

168169
private function getRawValue(object $source, string $propertyName): mixed
169170
{
170-
return $this->propertyAccessor ? $this->propertyAccessor->getValue($source, $propertyName) : $source->{$propertyName};
171+
if ($this->propertyAccessor) {
172+
return $this->propertyAccessor->getValue($source, $propertyName);
173+
}
174+
175+
if (!property_exists($source, $propertyName)) {
176+
throw new NoSuchPropertyException(sprintf('The property "%s" does not exist on "%s".', $propertyName, get_debug_type($source)));
177+
}
178+
179+
return $source->{$propertyName};
171180
}
172181

173182
private function getSourceValue(object $source, object $target, mixed $value, \SplObjectStorage $objectMap, ?Mapping $mapping = null): mixed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Symfony\Component\ObjectMapper\Tests\Fixtures\DefaultValueStdClass;
4+
5+
use Symfony\Component\ObjectMapper\Attribute\Map;
6+
7+
class TargetDto
8+
{
9+
public function __construct(
10+
public string $id,
11+
#[Map(source: 'optional', if: [self::class, 'isDefined'])]
12+
public ?string $optional = null,
13+
)
14+
{
15+
}
16+
17+
public static function isDefined($source): bool {
18+
return isset($source);
19+
}
20+
}

src/Symfony/Component/ObjectMapper/Tests/ObjectMapperTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Psr\Container\ContainerInterface;
1616
use Symfony\Component\ObjectMapper\Exception\MappingException;
1717
use Symfony\Component\ObjectMapper\Exception\MappingTransformException;
18+
use Symfony\Component\ObjectMapper\Exception\NoSuchPropertyException;
1819
use Symfony\Component\ObjectMapper\Metadata\Mapping;
1920
use Symfony\Component\ObjectMapper\Metadata\ObjectMapperMetadataFactoryInterface;
2021
use Symfony\Component\ObjectMapper\Metadata\ReflectionObjectMapperMetadataFactory;
@@ -28,6 +29,7 @@
2829
use Symfony\Component\ObjectMapper\Tests\Fixtures\DeeperRecursion\RecursiveDto;
2930
use Symfony\Component\ObjectMapper\Tests\Fixtures\DeeperRecursion\Relation;
3031
use Symfony\Component\ObjectMapper\Tests\Fixtures\DeeperRecursion\RelationDto;
32+
use Symfony\Component\ObjectMapper\Tests\Fixtures\DefaultValueStdClass\TargetDto;
3133
use Symfony\Component\ObjectMapper\Tests\Fixtures\Flatten\TargetUser;
3234
use Symfony\Component\ObjectMapper\Tests\Fixtures\Flatten\User;
3335
use Symfony\Component\ObjectMapper\Tests\Fixtures\Flatten\UserProfile;
@@ -303,4 +305,27 @@ public function testMultipleTargetMapProperty()
303305
$this->assertEquals('donotmap', $c->foo);
304306
$this->assertEquals('foo', $c->doesNotExistInTargetB);
305307
}
308+
309+
public function testDefaultValueStdClass()
310+
{
311+
$this->expectException(NoSuchPropertyException::class);
312+
$u = new \stdClass();
313+
$u->id = 'abc';
314+
$mapper = new ObjectMapper();
315+
$b = $mapper->map($u, TargetDto::class);
316+
$this->assertInstanceOf(TargetDto::class, $b);
317+
$this->assertEquals('abc', $b->id);
318+
$this->assertEquals(null, $b->optional);
319+
}
320+
321+
public function testDefaultValueStdClassWithPropertyInfo()
322+
{
323+
$u = new \stdClass();
324+
$u->id = 'abc';
325+
$mapper = new ObjectMapper(propertyAccessor: PropertyAccess::createPropertyAccessorBuilder()->disableExceptionOnInvalidPropertyPath()->getPropertyAccessor());
326+
$b = $mapper->map($u, TargetDto::class);
327+
$this->assertInstanceOf(TargetDto::class, $b);
328+
$this->assertEquals('abc', $b->id);
329+
$this->assertEquals(null, $b->optional);
330+
}
306331
}

0 commit comments

Comments
 (0)