diff --git a/code/Controllers/CMSMain.php b/code/Controllers/CMSMain.php index 7f067a32..d582c25e 100644 --- a/code/Controllers/CMSMain.php +++ b/code/Controllers/CMSMain.php @@ -375,6 +375,16 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr return $this->Link('listview'); } + /** + * Get the link for editing a page. + * + * @see CMSEditLinkExtension::getCMSEditLinkForManagedDataObject() + */ + public function getCMSEditLinkForManagedDataObject(SiteTree $obj): string + { + return Controller::join_links(CMSPageEditController::singleton()->Link('show'), $obj->ID); + } + public function LinkPageEdit($id = null) { if (!$id) { diff --git a/code/Model/SiteTree.php b/code/Model/SiteTree.php index 2c19f445..4e6f0e7a 100755 --- a/code/Model/SiteTree.php +++ b/code/Model/SiteTree.php @@ -4,7 +4,9 @@ namespace SilverStripe\CMS\Model; use Page; use Psr\SimpleCache\CacheInterface; +use SilverStripe\Admin\CMSEditLinkExtension; use SilverStripe\Assets\Shortcodes\FileLinkTracking; +use SilverStripe\CMS\Controllers\CMSMain; use SilverStripe\CMS\Controllers\CMSPageEditController; use SilverStripe\CMS\Controllers\ContentController; use SilverStripe\CMS\Controllers\ModelAsController; @@ -113,7 +115,6 @@ use SilverStripe\View\SSViewer; */ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvider, CMSPreviewable, Resettable, Flushable, MemberCacheFlusher { - /** * Indicates what kind of children this page type can have. * This can be an array of allowed child classes, or the string "none" - @@ -215,6 +216,12 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi */ private static $controller_name = null; + /** + * The class of the LeftAndMain controller where this class is managed. + * @see CMSEditLinkExtension::getCMSEditOwner() + */ + private static string $cms_edit_owner = CMSMain::class; + /** * You can define the a map of Page namespaces to Controller namespaces here * This will apply after the magic of appending Controller, and in order @@ -316,6 +323,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi Hierarchy::class, Versioned::class, InheritedPermissionsExtension::class, + CMSEditLinkExtension::class, ]; private static $searchable_fields = [ @@ -734,14 +742,11 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi */ public function CMSEditLink() { - $link = Controller::join_links( - CMSPageEditController::singleton()->Link('show'), - $this->ID - ); - return Director::absoluteURL($link); + // This method has to be implemented here to satisfy the CMSPreviewable interface. + // See the actual implementation in CMSEditLinkExtension. + return $this->extend('CMSEditLink')[0]; } - /** * Return a CSS identifier generated from this page's link. * diff --git a/composer.json b/composer.json index 617e9250..e3186a66 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ } ], "require": { - "silverstripe/admin": "^1.9@dev", + "silverstripe/admin": "^1.12@dev", "silverstripe/campaign-admin": "^1.7@dev", "silverstripe/framework": "^4.11", "silverstripe/reports": "^4.7@dev", diff --git a/tests/php/Model/CMSEditLinkExtensionTest/BelongsToPage.php b/tests/php/Model/CMSEditLinkExtensionTest/BelongsToPage.php new file mode 100644 index 00000000..952987ae --- /dev/null +++ b/tests/php/Model/CMSEditLinkExtensionTest/BelongsToPage.php @@ -0,0 +1,27 @@ + 'Varchar(25)', + ]; + + private static $has_one = [ + 'Parent' => SiteTree::class, + ]; + + private static $extensions = [ + CMSEditLinkExtension::class, + ]; +} diff --git a/tests/php/Model/CMSEditLinkExtensionTest/PageWithChild.php b/tests/php/Model/CMSEditLinkExtensionTest/PageWithChild.php new file mode 100644 index 00000000..e6c7429f --- /dev/null +++ b/tests/php/Model/CMSEditLinkExtensionTest/PageWithChild.php @@ -0,0 +1,25 @@ + BelongsToPage::class, + ]; + + public function getCMSFields() + { + $fields = parent::getCMSFields(); + $fields->addFieldToTab( + 'Root.ChildObjects', + GridField::create('ChildObjects', 'ChildObjects', $this->ChildObjects(), GridFieldConfig_RelationEditor::create()) + ); + return $fields; + } +} diff --git a/tests/php/Model/CMSEditLinkExtensionTest/fixtures.yml b/tests/php/Model/CMSEditLinkExtensionTest/fixtures.yml new file mode 100644 index 00000000..8c7876e5 --- /dev/null +++ b/tests/php/Model/CMSEditLinkExtensionTest/fixtures.yml @@ -0,0 +1,9 @@ +SilverStripe\CMS\Tests\CMSEditLinkExtensionTest\BelongsToPage: + one: + Name: 'some name' + +SilverStripe\CMS\Tests\CMSEditLinkExtensionTest\PageWithChild: + root: + Title: 'page has child' + ChildObjects: + - '=>SilverStripe\CMS\Tests\CMSEditLinkExtensionTest\BelongsToPage.one' diff --git a/tests/php/Model/SiteTreeTest.php b/tests/php/Model/SiteTreeTest.php index 229b7ded..86880f7c 100644 --- a/tests/php/Model/SiteTreeTest.php +++ b/tests/php/Model/SiteTreeTest.php @@ -10,6 +10,8 @@ use SilverStripe\CMS\Model\RedirectorPage; use SilverStripe\CMS\Model\SiteTree; use SilverStripe\CMS\Model\VirtualPage; use SilverStripe\CMS\Tests\Controllers\SiteTreeTest_NamespaceMapTestController; +use SilverStripe\CMS\Tests\CMSEditLinkExtensionTest\BelongsToPage; +use SilverStripe\CMS\Tests\CMSEditLinkExtensionTest\PageWithChild; use SilverStripe\CMS\Tests\Page\SiteTreeTest_NamespaceMapTest; use SilverStripe\Control\ContentNegotiator; use SilverStripe\Control\Controller; @@ -40,7 +42,10 @@ use const RESOURCES_DIR; class SiteTreeTest extends SapphireTest { - protected static $fixture_file = 'SiteTreeTest.yml'; + protected static $fixture_file = [ + 'SiteTreeTest.yml', + 'CMSEditLinkExtensionTest/fixtures.yml', + ]; protected static $illegal_extensions = [ SiteTree::class => [ @@ -58,6 +63,8 @@ class SiteTreeTest extends SapphireTest SiteTreeTest_NotRoot::class, SiteTreeTest_StageStatusInherit::class, SiteTreeTest_DataObject::class, + PageWithChild::class, + BelongsToPage::class, ]; public function reservedSegmentsProvider() @@ -1986,4 +1993,28 @@ class SiteTreeTest extends SapphireTest ); // END ARCHIVED } + + public function testGetCMSEditLinkForManagedDataObject() + { + $page = $this->objFromFixture(PageWithChild::class, 'root'); + $child = $this->objFromFixture(BelongsToPage::class, 'one'); + $this->assertSame( + "http://localhost/admin/pages/edit/show/$page->ID/field/ChildObjects/item/$child->ID", + $page->getCMSEditLinkForManagedDataObject($child, 'Parent') + ); + } + + public function testCMSEditLink() + { + $page = $this->objFromFixture(PageWithChild::class, 'root'); + $child = $this->objFromFixture(BelongsToPage::class, 'one'); + $this->assertSame( + "http://localhost/admin/pages/edit/show/$page->ID", + $page->CMSEditLink() + ); + $this->assertSame( + "http://localhost/admin/pages/edit/show/$page->ID/field/ChildObjects/item/$child->ID", + $child->CMSEditLink() + ); + } }