NEW Add friendly URL segments for DMS documents

This commit is contained in:
Robbie Averill 2017-05-24 11:43:23 +12:00
parent 2ddd20cd6c
commit 80e36c3350
5 changed files with 71 additions and 25 deletions

View File

@ -260,7 +260,8 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
*/ */
public function getLink() public function getLink()
{ {
$result = Controller::join_links(Director::baseURL(), 'dmsdocument/' . $this->ID); $urlSegment = sprintf('%d-%s', $this->ID, URLSegmentFilter::create()->filter($this->getTitle()));
$result = Controller::join_links(Director::baseURL(), 'dmsdocument/' . $urlSegment);
if (!$this->canView()) { if (!$this->canView()) {
$result = sprintf("javascript:alert('%s')", $this->getPermissionDeniedReason()); $result = sprintf("javascript:alert('%s')", $this->getPermissionDeniedReason());
} }
@ -787,12 +788,12 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
$gridFieldConfig->getComponentByType('GridFieldDataColumns') $gridFieldConfig->getComponentByType('GridFieldDataColumns')
->setDisplayFields(array( ->setDisplayFields(array(
'Title'=>'Title', 'Title' => 'Title',
'ClassName'=>'Page Type', 'ClassName' => 'Page Type',
'ID'=>'Page ID' 'ID' => 'Page ID'
)) ))
->setFieldFormatting(array( ->setFieldFormatting(array(
'Title'=>sprintf( 'Title' => sprintf(
'<a class=\"cms-panel-link\" href=\"%s/$ID\">$Title</a>', '<a class=\"cms-panel-link\" href=\"%s/$ID\">$Title</a>',
singleton('CMSPageEditController')->Link('show') singleton('CMSPageEditController')->Link('show')
) )
@ -823,7 +824,7 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
->setDisplayFields(Config::inst()->get('DMSDocument_versions', 'display_fields')) ->setDisplayFields(Config::inst()->get('DMSDocument_versions', 'display_fields'))
->setFieldFormatting( ->setFieldFormatting(
array( array(
'FilenameWithoutID' => '<a target=\'_blank\' class=\'file-url\' href=\'$Link\'>' 'FilenameWithoutID' => '<a target="_blank" class="file-url" href="$Link">'
. '$FilenameWithoutID</a>' . '$FilenameWithoutID</a>'
) )
); );

View File

@ -31,21 +31,37 @@ class DMSDocument_Controller extends Controller
$doc = null; $doc = null;
$id = Convert::raw2sql($request->param('ID')); $id = Convert::raw2sql($request->param('ID'));
if (strpos($id, 'version') === 0) { if (strpos($id, 'version') === 0) {
// Versioned document // Versioned document
$id = str_replace('version', '', $id); $id = $this->getDocumentIdFromSlug(str_replace('version', '', $id));
$doc = DataObject::get_by_id('DMSDocument_versions', $id); $doc = DataObject::get_by_id('DMSDocument_versions', $id);
$this->extend('updateVersionFromID', $doc, $request); $this->extend('updateVersionFromID', $doc, $request);
} else { } else {
// Normal document // Normal document
$doc = DataObject::get_by_id('DMSDocument', $id); $doc = DataObject::get_by_id('DMSDocument', $this->getDocumentIdFromSlug($id));
$this->extend('updateDocumentFromID', $doc, $request); $this->extend('updateDocumentFromID', $doc, $request);
} }
return $doc; return $doc;
} }
/**
* Get a document's ID from a "friendly" URL slug containing a numeric ID and slugged title
*
* @param string $slug
* @return int
* @throws InvalidArgumentException if an invalid format is provided
*/
protected function getDocumentIdFromSlug($slug)
{
$parts = (array) sscanf($slug, '%d-%s');
$id = array_shift($parts);
if (is_numeric($id)) {
return (int) $id;
}
throw new InvalidArgumentException($slug . ' is not a valid DMSDocument URL');
}
/** /**
* Access the file download without redirecting user, so we can block direct * Access the file download without redirecting user, so we can block direct
* access to documents. * access to documents.
@ -54,7 +70,6 @@ class DMSDocument_Controller extends Controller
{ {
$doc = $this->getDocumentFromID($request); $doc = $this->getDocumentFromID($request);
if (!empty($doc)) { if (!empty($doc)) {
$canView = $doc->canView(); $canView = $doc->canView();

View File

@ -7,6 +7,29 @@ class DMSDocumentControllerTest extends SapphireTest
{ {
protected static $fixture_file = 'dmstest.yml'; protected static $fixture_file = 'dmstest.yml';
/**
* @var DMSDocument_Controller
*/
protected $controller;
public function setUp()
{
parent::setUp();
Config::inst()->update('DMS', 'folder_name', 'assets/_unit-test-123');
$this->logInWithPermission('ADMIN');
$this->controller = $this->getMockBuilder('DMSDocument_Controller')
->setMethods(array('sendFile'))
->getMock();
}
public function tearDown()
{
DMSFilesystemTestHelper::delete('assets/_unit-test-123');
parent::tearDown();
}
/** /**
* Test that the download behaviour is either "open" or "download" * Test that the download behaviour is either "open" or "download"
* *
@ -16,16 +39,8 @@ class DMSDocumentControllerTest extends SapphireTest
*/ */
public function testDownloadBehaviourOpen($behaviour, $expectedDisposition) public function testDownloadBehaviourOpen($behaviour, $expectedDisposition)
{ {
Config::inst()->update('DMS', 'folder_name', 'assets/_unit-test-123');
$this->logInWithPermission('ADMIN');
/** @var DMSDocument_Controller $controller */
$controller = $this->getMockBuilder('DMSDocument_Controller')
->setMethods(array('sendFile'))->getMock();
$self = $this; $self = $this;
$controller->expects($this->once()) $this->controller->expects($this->once())
->method('sendFile') ->method('sendFile')
->will( ->will(
$this->returnCallback(function ($path, $mime, $name, $disposition) use ($self, $expectedDisposition) { $this->returnCallback(function ($path, $mime, $name, $disposition) use ($self, $expectedDisposition) {
@ -38,11 +53,9 @@ class DMSDocumentControllerTest extends SapphireTest
$openDoc->clearEmbargo(false); $openDoc->clearEmbargo(false);
$openDoc->write(); $openDoc->write();
$request = new SS_HTTPRequest('GET', 'index/' . $openDoc->ID); $request = new SS_HTTPRequest('GET', $openDoc->Link());
$request->match('index/$ID'); $request->match('dmsdocument/$ID');
$controller->index($request); $this->controller->index($request);
DMSFilesystemTestHelper::delete('assets/_unit-test-123');
} }
/** /**

View File

@ -264,6 +264,20 @@ class DMSDocumentTest extends SapphireTest
DMSFilesystemTestHelper::delete('assets/_unit-tests'); DMSFilesystemTestHelper::delete('assets/_unit-tests');
} }
/**
* Test that the link contains an ID and URL slug
*/
public function testGetLink()
{
Config::inst()->update('DMS', 'folder_name', 'assets/_unit-tests');
$document = DMS::inst()->storeDocument('dms/tests/DMS-test-lorum-file.pdf');
$expected = '/dmsdocument/' . $document->ID . '-dms-test-lorum-file-pdf';
$this->assertSame($expected, $document->Link());
$this->assertSame($expected, $document->getLink());
}
/** /**
* Ensure that the description can be returned in HTML format * Ensure that the description can be returned in HTML format
*/ */

View File

@ -22,7 +22,10 @@ class DMSShortcodeTest extends SapphireTest
$value = Injector::inst()->create('HTMLValue', $result); $value = Injector::inst()->create('HTMLValue', $result);
$link = $value->query('//a')->item(0); $link = $value->query('//a')->item(0);
$this->assertStringEndsWith("/dmsdocument/$document->ID", $link->getAttribute('href')); $this->assertStringEndsWith(
'/dmsdocument/' . $document->ID . '-dms-test-lorum-file-pdf',
$link->getAttribute('href')
);
$this->assertEquals($document->getExtension(), $link->getAttribute('data-ext')); $this->assertEquals($document->getExtension(), $link->getAttribute('data-ext'));
$this->assertEquals($document->getFileSizeFormatted(), $link->getAttribute('data-size')); $this->assertEquals($document->getFileSizeFormatted(), $link->getAttribute('data-size'));