Skip to content

Commit

Permalink
FIX Allow public extension getter methods to work
Browse files Browse the repository at this point in the history
Accidentally broke this in silverstripe#10670
  • Loading branch information
GuySartorelli committed Feb 1, 2023
1 parent 2274b3e commit e52d1c2
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 5 deletions.
10 changes: 9 additions & 1 deletion src/Core/CustomMethods.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,15 @@ protected function registerExtraMethodCallback($name, $callback)
*/
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;
}

/**
Expand Down
5 changes: 4 additions & 1 deletion src/View/ViewableData.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,14 @@ public function setField($field, $value)
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();
}
Expand Down
20 changes: 18 additions & 2 deletions tests/php/View/ViewableDataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@
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,
* from a template-parsing perspective.
*/
class ViewableDataTest extends SapphireTest
{
protected static $required_extensions = [
ViewableDataTestObject::class => [
ViewableDataTestExtension::class,
],
];

public function testCasting()
{
Expand Down Expand Up @@ -213,6 +219,7 @@ public function testIsAccessibleMethod()
$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');
Expand All @@ -226,8 +233,17 @@ public function testIsAccessibleMethod()
$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()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace SilverStripe\View\Tests;
namespace SilverStripe\View\Tests\ViewableDataTest;

use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
Expand Down
24 changes: 24 additions & 0 deletions tests/php/View/ViewableDataTest/ViewableDataTextExtension.php
Original file line number Diff line number Diff line change
@@ -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';
}
}

0 comments on commit e52d1c2

Please sign in to comment.