Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion system/Test/ReflectionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,19 @@ public static function getPrivateMethodInvoker($obj, $method)
*/
private static function getAccessibleRefProperty($obj, $property)
{
$refClass = is_object($obj) ? new ReflectionObject($obj) : new ReflectionClass($obj);
if (! is_object($obj)) {
return (new ReflectionClass($obj))->getProperty($property);
}

$refClass = new ReflectionObject($obj);

if (! $refClass->hasProperty($property) && str_contains($obj::class, '@anonymous')) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you know how duplicate properties should work correctly, you can fix it here. When properties exist in both classes

$parentClass = $refClass->getParentClass();

if ($parentClass !== false) {
return $parentClass->getProperty($property);
}
}

return $refClass->getProperty($property);
}
Expand Down
40 changes: 40 additions & 0 deletions tests/system/Test/ReflectionHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,44 @@ public function testGetPrivateMethodInvokerWithStatic(): void
$method('param1', 'param2'),
);
}

public function testGetPrivatePropertyWithAnonymousObject(): void
{
$anonClassObject = new class () extends TestForReflectionHelper {
private string $hideMe = 'active';

public function getHideMe(): string
{
return $this->hideMe;
}
};

$hideMe = $this->getPrivateProperty($anonClassObject, 'hideMe');
$private = $this->getPrivateProperty($anonClassObject, 'private');

$this->assertSame('active', $hideMe);
$this->assertSame($anonClassObject->getPrivate(), $private);
}

public function testSetPrivatePropertyWithAnonymousObject(): void
{
$anonClassObject = new class () extends TestForReflectionHelper {
private string $hideMe = 'active';

public function getHideMe(): string
{
return $this->hideMe;
}
};

$this->setPrivateProperty($anonClassObject, 'hideMe', 'inactive');
$this->setPrivateProperty($anonClassObject, 'private', 'new secret');

$hideMe = $this->getPrivateProperty($anonClassObject, 'hideMe');
$private = $this->getPrivateProperty($anonClassObject, 'private');

$this->assertSame('inactive', $hideMe);
$this->assertSame('new secret', $private);
$this->assertSame('new secret', $anonClassObject->getPrivate());
}
}
4 changes: 2 additions & 2 deletions user_guide_src/source/changelogs/v4.7.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,14 @@ Libraries
- **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.
- **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.


Commands
========

Testing
=======

-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.

Database
========

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


************
Deprecations
************
Expand Down
8 changes: 8 additions & 0 deletions user_guide_src/source/testing/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ instance of the class to test. The second parameter is the name of the property.

.. literalinclude:: overview/014.php

.. versionadded:: 4.7.0

You can access private properties for anonymous classes that extend the parent class.

setPrivateProperty($instance, $property, $value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

.. literalinclude:: overview/015.php

.. versionadded:: 4.7.0

You can access private properties for anonymous classes that extend the parent class.

Mocking Services
================

Expand Down
5 changes: 4 additions & 1 deletion user_guide_src/source/testing/overview/014.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
// Create an instance of the class to test
$obj = new Foo();

// Test the value
// or anonymous class
// $obj = new class () extends Foo {};

// Test the value from Foo
$this->assertEquals('bar', $this->getPrivateProperty($obj, 'baz'));
5 changes: 4 additions & 1 deletion user_guide_src/source/testing/overview/015.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
// Create an instance of the class to test
$obj = new Foo();

// Set the value
// or create anonymous class
// $obj = new class () extends Foo {};

// Set the value to Foo
$this->setPrivateProperty($obj, 'baz', 'oops!');

// Do normal testing...
Loading