diff --git a/fixtures/f014/ReadonlyObjectProperty.php b/fixtures/f014/ReadonlyObjectProperty.php new file mode 100644 index 0000000..4e0c78e --- /dev/null +++ b/fixtures/f014/ReadonlyObjectProperty.php @@ -0,0 +1,13 @@ +foo = new ReadonlyScalarProperty(); + } +} \ No newline at end of file diff --git a/fixtures/f014/ReadonlyScalarProperty.php b/fixtures/f014/ReadonlyScalarProperty.php new file mode 100644 index 0000000..d21be67 --- /dev/null +++ b/fixtures/f014/ReadonlyScalarProperty.php @@ -0,0 +1,17 @@ +foo = 'foo'; + $this->bar = 1; + $this->baz = []; + } +} \ No newline at end of file diff --git a/src/DeepCopy/DeepCopy.php b/src/DeepCopy/DeepCopy.php index 6e766d8..084858e 100644 --- a/src/DeepCopy/DeepCopy.php +++ b/src/DeepCopy/DeepCopy.php @@ -224,6 +224,11 @@ private function copyObjectProperty($object, ReflectionProperty $property) return; } + // Ignore readonly properties + if (method_exists($property, 'isReadOnly') && $property->isReadOnly()) { + return; + } + // Apply the filters foreach ($this->filters as $item) { /** @var Matcher $matcher */ diff --git a/tests/DeepCopyTest/DeepCopyTest.php b/tests/DeepCopyTest/DeepCopyTest.php index 0b44648..8890391 100644 --- a/tests/DeepCopyTest/DeepCopyTest.php +++ b/tests/DeepCopyTest/DeepCopyTest.php @@ -21,6 +21,7 @@ use DeepCopy\f011; use DeepCopy\f012\Suit; use DeepCopy\f013; +use DeepCopy\f014; use DeepCopy\Filter\ChainableFilter; use DeepCopy\Filter\Doctrine\DoctrineProxyFilter; use DeepCopy\Filter\KeepFilter; @@ -542,6 +543,23 @@ public function test_it_can_copy_property_after_applying_doctrine_proxy_filter_w $this->assertNotEquals($copy->getFoo(), $object->getFoo()); } + /** + * @requires PHP 8.1 + */ + public function test_it_can_copy_object_with_readonly_property() + { + $scalarProperties = new f014\ReadonlyScalarProperty(); + $objectProperties = new f014\ReadonlyObjectProperty(); + + $deepCopy = new DeepCopy(); + + $scalarPropertiesCopy = $deepCopy->copy($scalarProperties); + $objectPropertiesCopy = $deepCopy->copy($objectProperties); + + $this->assertEqualButNotSame($scalarProperties, $scalarPropertiesCopy); + $this->assertEqualButNotSame($objectProperties, $objectPropertiesCopy); + } + private function assertEqualButNotSame($expected, $val) { $this->assertEquals($expected, $val);