Skip to content

Commit 5252a7a

Browse files
committed
fix: Anonymous class support for ReflectionHelper
1 parent 12cf2b4 commit 5252a7a

File tree

6 files changed

+71
-5
lines changed

6 files changed

+71
-5
lines changed

system/Test/ReflectionHelper.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,19 @@ public static function getPrivateMethodInvoker($obj, $method)
5555
*/
5656
private static function getAccessibleRefProperty($obj, $property)
5757
{
58-
$refClass = is_object($obj) ? new ReflectionObject($obj) : new ReflectionClass($obj);
58+
if (! is_object($obj)) {
59+
return (new ReflectionClass($obj))->getProperty($property);
60+
}
61+
62+
$refClass = new ReflectionObject($obj);
63+
64+
if (! $refClass->hasProperty($property) && str_contains($obj::class, '@anonymous')) {
65+
$parentClass = $refClass->getParentClass();
66+
67+
if ($parentClass !== false) {
68+
return $parentClass->getProperty($property);
69+
}
70+
}
5971

6072
return $refClass->getProperty($property);
6173
}

tests/system/Test/ReflectionHelperTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,44 @@ public function testGetPrivateMethodInvokerWithStatic(): void
9393
$method('param1', 'param2'),
9494
);
9595
}
96+
97+
public function testGetPrivatePropertyWithAnonymousObject(): void
98+
{
99+
$anonClassObject = new class () extends TestForReflectionHelper {
100+
private string $hideMe = 'active';
101+
102+
public function getHideMe(): string
103+
{
104+
return $this->hideMe;
105+
}
106+
};
107+
108+
$hideMe = $this->getPrivateProperty($anonClassObject, 'hideMe');
109+
$private = $this->getPrivateProperty($anonClassObject, 'private');
110+
111+
$this->assertSame('active', $hideMe);
112+
$this->assertSame($anonClassObject->getPrivate(), $private);
113+
}
114+
115+
public function testSetPrivatePropertyWithAnonymousObject(): void
116+
{
117+
$anonClassObject = new class () extends TestForReflectionHelper {
118+
private string $hideMe = 'active';
119+
120+
public function getHideMe(): string
121+
{
122+
return $this->hideMe;
123+
}
124+
};
125+
126+
$this->setPrivateProperty($anonClassObject, 'hideMe', 'inactive');
127+
$this->setPrivateProperty($anonClassObject, 'private', 'new secret');
128+
129+
$hideMe = $this->getPrivateProperty($anonClassObject, 'hideMe');
130+
$private = $this->getPrivateProperty($anonClassObject, 'private');
131+
132+
$this->assertSame('inactive', $hideMe);
133+
$this->assertSame('new secret', $private);
134+
$this->assertSame('new secret', $anonClassObject->getPrivate());
135+
}
96136
}

user_guide_src/source/changelogs/v4.7.0.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,14 @@ Libraries
250250
- **View:** Added the ability to override namespaced views (e.g., from modules/packages) by placing a matching file structure within the **app/Views/overrides** directory. See :ref:`Overriding Namespaced Views <views-overriding-namespaced-views>` for details.
251251
- **Toolbar:** Fixed an issue where the Debug Toolbar was incorrectly injected into responses generated by third-party libraries (e.g., Dompdf) that use native PHP headers instead of the framework's Response object.
252252

253-
254253
Commands
255254
========
256255

257256
Testing
258257
=======
259258

259+
-The ``CodeIgniter\Test\ReflectionHelper::getPrivateProperty`` and ``CodeIgniter\Test\ReflectionHelper::setPrivateProperty`` methods has added support for accessing the private properties of an anonymous class that extends the parent class.
260+
260261
Database
261262
========
262263

@@ -306,7 +307,6 @@ Changes
306307
- **Paths:** Added support for changing the location of the ``.env`` file via the ``Paths::$envDirectory`` property.
307308
- **Toolbar:** Added ``$disableOnHeaders`` property to **app/Config/Toolbar.php**.
308309

309-
310310
************
311311
Deprecations
312312
************

user_guide_src/source/testing/overview.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ instance of the class to test. The second parameter is the name of the property.
224224

225225
.. literalinclude:: overview/014.php
226226

227+
.. versionadded:: 4.7.0
228+
229+
You can access private properties for anonymous classes that extend the parent class.
230+
227231
setPrivateProperty($instance, $property, $value)
228232
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
229233

@@ -232,6 +236,10 @@ parameter is the name of the property to set the value of. The third parameter i
232236

233237
.. literalinclude:: overview/015.php
234238

239+
.. versionadded:: 4.7.0
240+
241+
You can access private properties for anonymous classes that extend the parent class.
242+
235243
Mocking Services
236244
================
237245

user_guide_src/source/testing/overview/014.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@
55
// Create an instance of the class to test
66
$obj = new Foo();
77

8-
// Test the value
8+
// or anonymous class
9+
// $obj = new class () extends Foo {};
10+
11+
// Test the value from Foo
912
$this->assertEquals('bar', $this->getPrivateProperty($obj, 'baz'));

user_guide_src/source/testing/overview/015.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
// Create an instance of the class to test
66
$obj = new Foo();
77

8-
// Set the value
8+
// or create anonymous class
9+
// $obj = new class () extends Foo {};
10+
11+
// Set the value to Foo
912
$this->setPrivateProperty($obj, 'baz', 'oops!');
1013

1114
// Do normal testing...

0 commit comments

Comments
 (0)