Skip to content

Commit

Permalink
BUG Check is_callable parent methods before invoke (#10637)
Browse files Browse the repository at this point in the history
  • Loading branch information
sabina-talipova authored Jan 11, 2023
1 parent 2868edd commit 6d45425
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/View/ViewableData.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use InvalidArgumentException;
use IteratorAggregate;
use LogicException;
use ReflectionObject;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Config\Configurable;
Expand Down Expand Up @@ -155,13 +156,22 @@ public function __get($property)
public function __set($property, $value)
{
$this->objCacheClear();
if ($this->hasMethod($method = "set$property")) {
$method = "set$property";

if ($this->hasMethod($method) && !$this->isPrivate($this, $method)) {
$this->$method($value);
} else {
$this->setField($property, $value);
}
}

private function isPrivate(object $class, string $method): bool
{
$class = new ReflectionObject($class);

return $class->getMethod($method)->isPrivate();
}

/**
* Set a failover object to attempt to get data from if it is not present on this object.
*
Expand Down
15 changes: 15 additions & 0 deletions tests/php/View/ViewableDataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

namespace SilverStripe\View\Tests;

use ReflectionMethod;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\View\ArrayData;
use SilverStripe\View\SSViewer;
use SilverStripe\View\ViewableData;
use SilverStripe\View\Tests\ViewableDataTestObject;

/**
* See {@link SSViewerTest->testCastingHelpers()} for more tests related to casting and ViewableData behaviour,
Expand Down Expand Up @@ -205,4 +207,17 @@ public function testSetFailover()
$this->assertSame($failover, $container->getFailover(), 'getFailover() returned a different object');
$this->assertFalse($container->hasMethod('testMethod'), 'testMethod() incorrectly reported as existing');
}

public function testIsPrivate()
{
$reflectionMethod = new ReflectionMethod(ViewableData::class, 'isPrivate');
$reflectionMethod->setAccessible(true);
$object = new ViewableDataTestObject();

$output = $reflectionMethod->invokeArgs($object, [$object, 'privateMethod']);
$this->assertTrue($output, 'Method is not private');

$output = $reflectionMethod->invokeArgs($object, [$object, 'publicMethod']);
$this->assertFalse($output, 'Method is private');
}
}
19 changes: 19 additions & 0 deletions tests/php/View/ViewableDataTestObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace SilverStripe\View\Tests;

use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;

class ViewableDataTestObject extends DataObject implements TestOnly
{
private function privateMethod(): string
{
return 'Private function';
}

public function publicMethod(): string
{
return 'Public function';
}
}

0 comments on commit 6d45425

Please sign in to comment.