Skip to content

Commit

Permalink
Fetch LIVE DataObject when checking canView()
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Penny committed Sep 8, 2022
1 parent b1ed1e9 commit 225a203
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 9 deletions.
15 changes: 13 additions & 2 deletions src/DataObject/DataObjectDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,19 @@ public function shouldIndex(): bool
$dataObject = $this->getDataObject();

// If an anonymous user can't view it
$isPublic = Member::actAs(null, function () use ($dataObject) {
return $dataObject->canView();
$isPublic = Member::actAs(null, static function () use ($dataObject) {
// Need to make sure that the version of the DataObject that we access is always the LIVE version
return Versioned::withVersionedMode(static function () use ($dataObject): bool {
Versioned::set_stage(Versioned::LIVE);

$liveDataObject = DataObject::get($dataObject->ClassName)->byID($dataObject->ID);

if (!$liveDataObject || !$liveDataObject->exists()) {
return false;
}

return $liveDataObject->canView();
});
});

if (!$isPublic) {
Expand Down
94 changes: 87 additions & 7 deletions tests/DataObject/DataObjectDocumentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace SilverStripe\SearchService\Tests\DataObject;

use Page;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\RelationList;
Expand All @@ -22,7 +23,14 @@
class DataObjectDocumentTest extends SearchServiceTest
{

protected static $fixture_file = '../fixtures.yml'; // phpcs:ignore
/**
* @phpcsSuppress SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint
* @var array
*/
protected static $fixture_file = [
'../fixtures.yml',
'../pages.yml',
];

/**
* @phpcsSuppress SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint
Expand Down Expand Up @@ -64,6 +72,22 @@ public function testShouldIndex(): void
$docTwo = DataObjectDocument::create($dataObjectTwo);
$docThree = DataObjectDocument::create($dataObjectThree);

// Add all three documents to our indexes, as this isn't the functionality we're testing here
$config->set(
'getIndexesForDocument',
[
$docOne->getIdentifier() => [
'index' => 'data',
],
$docTwo->getIdentifier() => [
'index' => 'data',
],
$docThree->getIdentifier() => [
'index' => 'data',
],
]
);

// All should be unavailable to index initially
$this->assertFalse($docOne->shouldIndex());
$this->assertFalse($docTwo->shouldIndex());
Expand All @@ -81,12 +105,6 @@ public function testShouldIndex(): void
$docOne = DataObjectDocument::create($dataObjectOne);
$docTwo = DataObjectDocument::create($dataObjectTwo);

$config->set('getIndexesForDocument', [
$docOne->getIdentifier() => [
'index' => 'data',
],
]);

// Document one should be indexable (as it's published and has ShowInSearch: 1)
$this->assertTrue($docOne->shouldIndex());
// Document two should NOT be indexable (it's published but has ShowInSearch: 0)
Expand All @@ -95,6 +113,68 @@ public function testShouldIndex(): void
$this->assertFalse($docThree->shouldIndex());
}

public function testShouldIndexChild(): void
{
$config = $this->mockConfig();

$parent = $this->objFromFixture(Page::class, 'page1');
// Make sure our Parent is published before we fetch our child pages
$parent->publishRecursive();

$childOne = $this->objFromFixture(Page::class, 'page2');
$childTwo = $this->objFromFixture(Page::class, 'page3');
$childThree = $this->objFromFixture(Page::class, 'page5');

// Publish childOne and childThree
$childOne->publishRecursive();
$childThree->publishRecursive();
// Need to re-fetch childOne and childThree so that our Versioned state is up-to-date with what we just
// published
$childOne = $this->objFromFixture(Page::class, 'page2');
$childThree = $this->objFromFixture(Page::class, 'page5');

// $docOne has a published page
$docOne = DataObjectDocument::create($childOne);
// $docTwo has an unpublished page
$docTwo = DataObjectDocument::create($childTwo);
// $docThree has a published page
$docThree = DataObjectDocument::create($childThree);

// Add both documents to our indexes, as this isn't the functionality we're testing here
$config->set(
'getIndexesForDocument',
[
$docOne->getIdentifier() => [
'index' => 'data',
],
$docTwo->getIdentifier() => [
'index' => 'data',
],
$docThree->getIdentifier() => [
'index' => 'data',
],
]
);

// Our parent page has been published, and so has our child page, so this should be indexable
$this->assertTrue($docOne->shouldIndex());
// Our parent page has been published, but the child has not
$this->assertFalse($docTwo->shouldIndex());
// Our parent page is not published, even though the child is
$this->assertFalse($docThree->shouldIndex());

// Now trigger a change on our parent page (so that the draft and live versions no longer match)
$parent->Title = 'Parent Page Changed';
$parent->write();

// Need to re-fetch childOne so that we re-fetch the Parent when we request canView()
$childOne = $this->objFromFixture(Page::class, 'page2');
// Recreate the Document with our new child page
$docOne = DataObjectDocument::create($childOne);
// Check that our child page is still indexable, even after our parent page was given a different draft version
$this->assertTrue($docOne->shouldIndex());
}

public function testMarkIndexed(): void
{
$dataobject = new DataObjectFake(['ShowInSearch' => true]);
Expand Down
19 changes: 19 additions & 0 deletions tests/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Page:
page1:
Title: Parent Page
ShowInSearch: 1
page2:
Title: Child Page 1
Parent: =>Page.page1
ShowInSearch: 1
page3:
Title: Child Page 2
Parent: =>Page.page1
ShowInSearch: 1
page4:
Title: Parent Page 2
ShowInSearch: 1
page5:
Title: Child Page 3
Parent: =>Page.page4
ShowInSearch: 1

0 comments on commit 225a203

Please sign in to comment.