FIX Allow public extension getter methods to work (#10676)

Accidentally broke this in #10670
This commit is contained in:
Guy Sartorelli 2023-02-01 16:05:54 +13:00 committed by GitHub
parent 826028082b
commit 738ca487ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 5 deletions

View File

@ -147,7 +147,15 @@ trait CustomMethods
*/
public function hasMethod($method)
{
return method_exists($this, $method ?? '') || $this->getExtraMethodConfig($method);
return method_exists($this, $method ?? '') || $this->hasCustomMethod($method);
}
/**
* Determines if a custom method with this name is defined.
*/
protected function hasCustomMethod($method): bool
{
return $this->getExtraMethodConfig($method) !== null;
}
/**

View File

@ -247,11 +247,14 @@ class ViewableData implements IteratorAggregate
private function isAccessibleMethod(string $method): bool
{
if (!method_exists($this, $method)) {
return false;
// Methods added via extensions are accessible
return $this->hasCustomMethod($method);
}
// All methods defined on ViewableData are accessible to ViewableData
if (static::class === self::class) {
return true;
}
// Private methods defined on subclasses are not accessible to ViewableData
$reflectionMethod = new ReflectionMethod($this, $method);
return !$reflectionMethod->isPrivate();
}

View File

@ -7,8 +7,9 @@ use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\View\ArrayData;
use SilverStripe\View\SSViewer;
use SilverStripe\View\Tests\ViewableDataTest\ViewableDataTestExtension;
use SilverStripe\View\Tests\ViewableDataTest\ViewableDataTestObject;
use SilverStripe\View\ViewableData;
use SilverStripe\View\Tests\ViewableDataTestObject;
/**
* See {@link SSViewerTest->testCastingHelpers()} for more tests related to casting and ViewableData behaviour,
@ -16,6 +17,11 @@ use SilverStripe\View\Tests\ViewableDataTestObject;
*/
class ViewableDataTest extends SapphireTest
{
protected static $required_extensions = [
ViewableDataTestObject::class => [
ViewableDataTestExtension::class,
],
];
public function testCasting()
{
@ -213,6 +219,7 @@ class ViewableDataTest extends SapphireTest
$reflectionMethod = new ReflectionMethod(ViewableData::class, 'isAccessibleMethod');
$reflectionMethod->setAccessible(true);
$object = new ViewableDataTestObject();
$viewableData = new ViewableData();
$output = $reflectionMethod->invokeArgs($object, ['privateMethod']);
$this->assertFalse($output, 'Method should not be accessible');
@ -226,8 +233,17 @@ class ViewableDataTest extends SapphireTest
$output = $reflectionMethod->invokeArgs($object, ['missingMethod']);
$this->assertFalse($output, 'Method should not be accessible');
$output = $reflectionMethod->invokeArgs(new ViewableData(), ['isAccessibleProperty']);
$output = $reflectionMethod->invokeArgs($viewableData, ['isAccessibleProperty']);
$this->assertTrue($output, 'Method should be accessible');
$output = $reflectionMethod->invokeArgs($object, ['publicMethodFromExtension']);
$this->assertTrue($output, 'Method should be accessible');
$output = $reflectionMethod->invokeArgs($object, ['protectedMethodFromExtension']);
$this->assertFalse($output, 'Method should not be accessible');
$output = $reflectionMethod->invokeArgs($object, ['privateMethodFromExtension']);
$this->assertFalse($output, 'Method should not be accessible');
}
public function testIsAccessibleProperty()

View File

@ -1,6 +1,6 @@
<?php
namespace SilverStripe\View\Tests;
namespace SilverStripe\View\Tests\ViewableDataTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;

View File

@ -0,0 +1,24 @@
<?php
namespace SilverStripe\View\Tests\ViewableDataTest;
use SilverStripe\Core\Extension;
use SilverStripe\Dev\TestOnly;
class ViewableDataTestExtension extends Extension implements TestOnly
{
private function privateMethodFromExtension(): string
{
return 'Private function';
}
protected function protectedMethodFromExtension(): string
{
return 'Protected function';
}
public function publicMethodFromExtension(): string
{
return 'Public function';
}
}