Skip to content

Commit

Permalink
FIX Archive record from live table on delete
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Feb 8, 2024
1 parent 5076ef1 commit d634e15
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
18 changes: 16 additions & 2 deletions src/Controllers/LinkFieldController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use SilverStripe\ORM\DataObject;
use SilverStripe\LinkField\Form\LinkField;
use SilverStripe\LinkField\Form\MultiLinkField;
use SilverStripe\Versioned\Versioned;

class LinkFieldController extends LeftAndMain
{
Expand Down Expand Up @@ -136,15 +137,28 @@ public function linkDelete(): HTTPResponse
if (!SecurityToken::inst()->checkRequest($this->getRequest())) {
$this->jsonError(400);
}
// delete() will also delete any published version immediately
$link->delete();
if ($link->hasExtension(Versioned::class)) {
$link->doArchive();
} else {
$link->delete();
}
// Update owner object if this Link is on a has_one relation on the owner
$owner = $this->getOwnerFromRequest();
$ownerRelation = $this->getOwnerRelationFromRequest();
$hasOne = Injector::inst()->get($owner->ClassName)->hasOne();
if (array_key_exists($ownerRelation, $hasOne) && $owner->canEdit()) {
// Update draft owner table
$owner->$ownerRelation = null;
$owner->write();
// Update live owner table if owner is versioned
if ($owner->hasExtension(Versioned::class)) {
Versioned::withVersionedMode(function () use ($ownerRelation) {
Versioned::set_stage(Versioned::LIVE);
$liveOwner = $this->getOwnerFromRequest();
$liveOwner->$ownerRelation = null;
$liveOwner->write();
});
}
}
// Send response
return $this->jsonSuccess(204);
Expand Down
45 changes: 44 additions & 1 deletion tests/php/Controllers/LinkFieldControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use SilverStripe\Security\SecurityToken;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\LinkField\Tests\Models\LinkTest\LinkOwner;
use SilverStripe\Versioned\Versioned;

class LinkFieldControllerTest extends FunctionalTest
{
Expand All @@ -24,6 +25,15 @@ class LinkFieldControllerTest extends FunctionalTest
protected function setUp(): void
{
parent::setUp();
// The Versioned extension is added to LinkOwner, though it's only used for the
// unit tests speicifically to test Versioned functionality. It interferes with
// other units tests that were written before the Versioned extension was added
// The extenion needs to be added on the class rather than dynmically so that the
// relevant database tables are created. The extension is added back in on unit
// tests that requrie it. There's a call to add the extension back in the
// tearDown method
LinkOwner::remove_extension(Versioned::class);

$this->logInWithPermission('ADMIN');
// CSRF token check is normally disabled for unit-tests
$this->securityTokenWasEnabled = SecurityToken::is_enabled();
Expand All @@ -45,6 +55,8 @@ protected function tearDown(): void
if (!$this->securityTokenWasEnabled) {
SecurityToken::disable();
}
// Reset the extension that was removed in the setUp() method
LinkOwner::add_extension(Versioned::class);
}

/**
Expand Down Expand Up @@ -500,7 +512,6 @@ public function testLinkDelete(
$owner = $this->getFixtureLinkOwner();
$this->assertSame(0, $owner->LinkID);
}
$this->assertTrue(true);
}

public function provideLinkDelete(): array
Expand Down Expand Up @@ -544,6 +555,38 @@ public function provideLinkDelete(): array
];
}

public function testLinkDeleteVersions(): void
{
LinkOwner::add_extension(Versioned::class);
// Need to re-link rejoin $link to $owner as the fixture data for whatever reason
// because doing weird stuff with versioning and adding extensions
$link = $this->getFixtureLink();
$owner = $this->getFixtureLinkOwner();
$owner->Link = $link;
$link->publishSingle();
$owner->publishSingle();
$linkID = $link->ID;
$ownerID = $owner->ID;
$ownerClass = urlencode($owner->ClassName);
$ownerRelation = 'Link';
$url = "/admin/linkfield/delete/$linkID?ownerID=$ownerID&ownerClass=$ownerClass&ownerRelation=$ownerRelation";
$headers = $this->csrfTokenheader();
$this->assertNotSame(0, $owner->LinkID);
$liveOwner = Versioned::get_by_stage($owner::class, Versioned::LIVE)->byID($ownerID);
$this->assertSame($owner->LinkID, $liveOwner->LinkID);
$liveLink = Versioned::get_by_stage($link::class, Versioned::LIVE)->byID($linkID);
$this->assertNotNull($liveLink);
$this->mainSession->sendRequest('DELETE', $url, [], $headers);
$draftOwner = Versioned::get_by_stage($owner::class, Versioned::DRAFT)->byID($ownerID);
$this->assertSame(0, $draftOwner->LinkID);
$draftLink = Versioned::get_by_stage($link::class, Versioned::DRAFT)->byID($linkID);
$this->assertNull($draftLink);
$liveOwner = Versioned::get_by_stage($owner::class, Versioned::LIVE)->byID($ownerID);
$this->assertSame(0, $liveOwner->LinkID);
$liveLink = Versioned::get_by_stage($link::class, Versioned::LIVE)->byID($linkID);
$this->assertNull($liveLink);
}

/**
* @dataProvider provideLinkSort
*/
Expand Down
5 changes: 5 additions & 0 deletions tests/php/Models/LinkTest/LinkOwner.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use SilverStripe\Dev\TestOnly;
use SilverStripe\LinkField\Models\Link;
use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;

class LinkOwner extends DataObject implements TestOnly
{
Expand All @@ -17,6 +18,10 @@ class LinkOwner extends DataObject implements TestOnly
'LinkList2' => Link::class . '.Owner',
];

private static array $extensions = [
Versioned::class,
];

// Allows us to toggle permissions easily within a unit test
public bool $canView = true;
public bool $canEdit = true;
Expand Down

0 comments on commit d634e15

Please sign in to comment.