diff --git a/src/Models/BaseElement.php b/src/Models/BaseElement.php index 6b7ad42c..519fe913 100644 --- a/src/Models/BaseElement.php +++ b/src/Models/BaseElement.php @@ -701,7 +701,7 @@ public function AbsoluteLink($action = null) /** * @param string|null $action - * @return string + * @return string|null * @throws \Psr\Container\NotFoundExceptionInterface * @throws \SilverStripe\ORM\ValidationException */ @@ -721,16 +721,28 @@ public function Link($action = null) /** * @param string|null $action - * @return string + * @return string|null * @throws \Psr\Container\NotFoundExceptionInterface * @throws \SilverStripe\ORM\ValidationException */ public function PreviewLink($action = null) { - $action = $action . '?ElementalPreview=' . mt_rand(); - $link = $this->Link($action); - $this->extend('updatePreviewLink', $link); + $link = null; + if ($page = $this->getPage()) { + if (ClassInfo::hasMethod($page, 'Link')) { + $link = $page->Link($action); + } + if (!$link && ($page instanceof CMSPreviewable)) { + $link = $page->PreviewLink($action); + } + if ($link) { + // The ElementalPreview getvar is used in ElementalPageExtension + // The anchor must be at the end of the URL to function correctly + $link .= '?ElementalPreview=' . mt_rand() . '#' . $this->getAnchor(); + } + } + $this->extend('updatePreviewLink', $link); return $link; } diff --git a/tests/BaseElementTest.php b/tests/BaseElementTest.php index 4c7db4f5..0de95c6b 100644 --- a/tests/BaseElementTest.php +++ b/tests/BaseElementTest.php @@ -401,4 +401,50 @@ public function testAbsoluteLink(string $class, string $element, ?string $link) $absoluteLink = $object->AbsoluteLink(); $this->assertEquals($link, $absoluteLink); } + + public function previewLinksProvider() + { + return [ + // Element on Page + [ + ElementContent::class, + 'content1', + '/test-elemental/', + ], + // Element in DataObject WITHOUT PreviewLink or Link + [ + TestElement::class, + 'elementDataObject2', + null, + ], + // Element in DataObject WITH PreviewLink WITHOUT Link + [ + TestElement::class, + 'elementDataObject3', + 'preview-link', + ], + // Element in DataObject WITH PreviewLink AND Link (different paths) + [ + TestElement::class, + 'elementDataObject4', + 'base-link', + ], + ]; + } + + /** + * @dataProvider previewLinksProvider + */ + public function testPreviewLink(string $class, string $elementIdentifier, ?string $link) + { + /** @var BaseElement $element */ + $element = $this->objFromFixture($class, $elementIdentifier); + + if ($link) { + $regex = '/^' . preg_quote($link . '?ElementalPreview=', '/') .'\d*#' . $element->getAnchor() . '$/'; + $this->assertTrue((bool)preg_match($regex, $element->PreviewLink())); + } else { + $this->assertSame($link, $element->PreviewLink()); + } + } } diff --git a/tests/ElementalAreaDataObjectTest.yml b/tests/ElementalAreaDataObjectTest.yml index 5744c95a..0681ea5f 100644 --- a/tests/ElementalAreaDataObjectTest.yml +++ b/tests/ElementalAreaDataObjectTest.yml @@ -5,6 +5,12 @@ DNADesign\Elemental\Models\ElementalArea: areaDataObject2: Title: Area 2 OwnerClassName: DNADesign\Elemental\Tests\Src\TestDataObject + areaDataObject3: + Title: Area 3 + OwnerClassName: DNADesign\Elemental\Tests\Src\TestPreviewableDataObject + areaDataObject4: + Title: Area 4 + OwnerClassName: DNADesign\Elemental\Tests\Src\TestPreviewableDataObjectWithLink DNADesign\Elemental\Tests\Src\TestDataObjectWithCMSEditLink: dataObject1: @@ -13,9 +19,19 @@ DNADesign\Elemental\Tests\Src\TestDataObjectWithCMSEditLink: DNADesign\Elemental\Tests\Src\TestDataObject: dataObject2: - Title: DataObject without CMSEditLink method + Title: DataObject without CMSEditLink, Link, or PreviewLink methods ElementalAreaID: =>DNADesign\Elemental\Models\ElementalArea.areaDataObject2 +DNADesign\Elemental\Tests\Src\TestPreviewableDataObject: + dataObject3: + Title: DataObject with PreviewLink method + ElementalAreaID: =>DNADesign\Elemental\Models\ElementalArea.areaDataObject3 + +DNADesign\Elemental\Tests\Src\TestPreviewableDataObjectWithLink: + dataObject4: + Title: DataObject with PreviewLink and Link methods + ElementalAreaID: =>DNADesign\Elemental\Models\ElementalArea.areaDataObject4 + DNADesign\Elemental\Tests\Src\TestElement: elementDataObject1: Title: Element 1 @@ -25,6 +41,14 @@ DNADesign\Elemental\Tests\Src\TestElement: Title: Element 2 TestValue: 'Hello Test' ParentID: =>DNADesign\Elemental\Models\ElementalArea.areaDataObject2 + elementDataObject3: + Title: Element 3 + TestValue: 'Hello Test' + ParentID: =>DNADesign\Elemental\Models\ElementalArea.areaDataObject3 + elementDataObject4: + Title: Element 4 + TestValue: 'Hello Test' + ParentID: =>DNADesign\Elemental\Models\ElementalArea.areaDataObject4 DNADesign\Elemental\Tests\Src\TestElementDataObject: testElementDataObject1: diff --git a/tests/Src/TestDataObject.php b/tests/Src/TestDataObject.php index caaa5657..9b5635bf 100644 --- a/tests/Src/TestDataObject.php +++ b/tests/Src/TestDataObject.php @@ -3,8 +3,6 @@ namespace DNADesign\Elemental\Tests\Src; use DNADesign\Elemental\Models\ElementalArea; -use SilverStripe\Control\Controller; -use SilverStripe\Control\Director; use SilverStripe\ORM\DataObject; use SilverStripe\Dev\TestOnly; diff --git a/tests/Src/TestPreviewableDataObject.php b/tests/Src/TestPreviewableDataObject.php new file mode 100644 index 00000000..c38101fd --- /dev/null +++ b/tests/Src/TestPreviewableDataObject.php @@ -0,0 +1,26 @@ +