Browse Source

Delete tombstone if it exists (#97)

* Delete tombstone if it exists

* Coding standards
pull/756/head
Jared Whiklo 6 years ago committed by Seth Shaw
parent
commit
2b3418e0fa
  1. 40
      src/Flysystem/Adapter/FedoraAdapter.php
  2. 72
      tests/src/Kernel/FedoraAdapterTest.php

40
src/Flysystem/Adapter/FedoraAdapter.php

@ -283,8 +283,14 @@ class FedoraAdapter implements AdapterInterface {
*/ */
public function delete($path) { public function delete($path) {
$response = $this->fedora->deleteResource($path); $response = $this->fedora->deleteResource($path);
$code = $response->getStatusCode(); $code = $response->getStatusCode();
if ($code == 204) {
// Deleted so check for a tombstone as well.
$tomb_code = $this->deleteTombstone($path);
if (!is_null($tomb_code)) {
return $tomb_code;
}
}
return in_array($code, [204, 404]); return in_array($code, [204, 404]);
} }
@ -321,4 +327,36 @@ class FedoraAdapter implements AdapterInterface {
return $this->getMetadata($dirname); return $this->getMetadata($dirname);
} }
/**
* Delete a tombstone for a path if it exists.
*
* @param string $path
* The original deleted resource path.
*
* @return bool|null
* NULL if no tombstone, TRUE if tombstone deleted, FALSE otherwise.
*/
private function deleteTombstone($path) {
$response = $this->fedora->getResourceHeaders($path);
$return = NULL;
if ($response->getStatusCode() == 410) {
$return = FALSE;
$link_headers = Psr7\parse_header($response->getHeader('Link'));
if ($link_headers) {
$tombstones = array_filter($link_headers, function ($o) {
return (isset($o['rel']) && $o['rel'] == 'hasTombstone');
});
foreach ($tombstones as $tombstone) {
// Trim <> from URL.
$url = rtrim(ltrim($tombstone[0], '<'), '>');
$response = $this->fedora->deleteResource($url);
if ($response->getStatusCode() == 204) {
$return = TRUE;
}
}
}
}
return $return;
}
} }

72
tests/src/Kernel/FedoraAdapterTest.php

@ -185,6 +185,60 @@ class FedoraAdapterTest extends IslandoraKernelTestBase {
return new FedoraAdapter($api, $mime_guesser); return new FedoraAdapter($api, $mime_guesser);
} }
/**
* Mocks up an adapter for Delete requests with a tombstone.
*/
protected function createAdapterForDeleteWithTombstone() {
$fedora_prophecy = $this->prophesize(IFedoraApi::class);
$prophecy = $this->prophesize(Response::class);
$prophecy->getStatusCode()->willReturn(204);
$head_prophecy = $this->prophesize(Response::class);
$head_prophecy->getStatusCode()->willReturn(410);
$head_prophecy->getHeader('Link')->willReturn('<some-path-to-a-tombstone>; rel="hasTombstone"');
$tombstone_prophecy = $this->prophesize(Response::class);
$tombstone_prophecy->getStatusCode()->willReturn(204);
$fedora_prophecy->deleteResource('')->willReturn($prophecy->reveal());
$fedora_prophecy->getResourceHeaders('')->willReturn($head_prophecy->reveal());
$fedora_prophecy->deleteResource('some-path-to-a-tombstone')->willReturn($tombstone_prophecy->reveal());
$api = $fedora_prophecy->reveal();
$mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class)->reveal();
return new FedoraAdapter($api, $mime_guesser);
}
/**
* Mocks up an adapter for Delete requests with a tombstone which fail.
*/
protected function createAdapterForDeleteWithTombstoneFail() {
$fedora_prophecy = $this->prophesize(IFedoraApi::class);
$prophecy = $this->prophesize(Response::class);
$prophecy->getStatusCode()->willReturn(204);
$head_prophecy = $this->prophesize(Response::class);
$head_prophecy->getStatusCode()->willReturn(410);
$head_prophecy->getHeader('Link')->willReturn('<some-path-to-a-tombstone>; rel="hasTombstone"');
$tombstone_prophecy = $this->prophesize(Response::class);
$tombstone_prophecy->getStatusCode()->willReturn(500);
$fedora_prophecy->deleteResource('')->willReturn($prophecy->reveal());
$fedora_prophecy->getResourceHeaders('')->willReturn($head_prophecy->reveal());
$fedora_prophecy->deleteResource('some-path-to-a-tombstone')->willReturn($tombstone_prophecy->reveal());
$api = $fedora_prophecy->reveal();
$mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class)->reveal();
return new FedoraAdapter($api, $mime_guesser);
}
/** /**
* Asserts the stucture/contents of a metadata response for a file. * Asserts the stucture/contents of a metadata response for a file.
*/ */
@ -459,6 +513,24 @@ class FedoraAdapterTest extends IslandoraKernelTestBase {
$this->assertTrue($adapter->deleteDir('') == TRUE, "deleteDir() must return TRUE on 204 or 404"); $this->assertTrue($adapter->deleteDir('') == TRUE, "deleteDir() must return TRUE on 204 or 404");
} }
/**
* @covers \Drupal\islandora\Flysystem\Adapter\FedoraAdapter::delete
*/
public function testDeleteWithTombstone() {
$adapter = $this->createAdapterForDeleteWithTombstone();
$this->assertTrue($adapter->delete(''), 'delete() must return TRUE on 204 or 404 reponse after deleting the tombstone.');
}
/**
* @covers \Drupal\islandora\Flysystem\Adapter\FedoraAdapter::delete
*/
public function testDeleteWithTombstoneFail() {
$adapter = $this->createAdapterForDeleteWithTombstoneFail();
$this->assertFalse($adapter->delete(''), 'delete() must return FALSE on non-(204 or 404) response after deleting the tombstone.');
}
/** /**
* @covers \Drupal\islandora\Flysystem\Adapter\FedoraAdapter::rename * @covers \Drupal\islandora\Flysystem\Adapter\FedoraAdapter::rename
* @covers \Drupal\islandora\Flysystem\Adapter\FedoraAdapter::copy * @covers \Drupal\islandora\Flysystem\Adapter\FedoraAdapter::copy

Loading…
Cancel
Save