NEW Relate documents to other documents

* Modularise templates, add missing localisations, add related documents to template
* Add getRelatedDocuments as an extensible getter in DMSDocument
This commit is contained in:
Robbie Averill 2017-05-01 16:29:04 +12:00
parent 2e2112a3b5
commit 9c0ec616d1
9 changed files with 213 additions and 96 deletions

View File

@ -23,6 +23,7 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
private static $many_many = array( private static $many_many = array(
'Pages' => 'SiteTree', 'Pages' => 'SiteTree',
'RelatedDocuments' => 'DMSDocument',
'Tags' => 'DMSTag' 'Tags' => 'DMSTag'
); );
@ -1012,19 +1013,19 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
$versionsGridFieldConfig $versionsGridFieldConfig
); );
$extraTasks .= '<li class="ss-ui-button" data-panel="find-versions">Versions</li>'; $extraTasks .= '<li class="ss-ui-button" data-panel="find-versions">Versions</li>';
//$extraFields = $versionsGrid->addExtraClass('find-versions');
} }
$fields->add(new LiteralField( $fields->add(new LiteralField(
'BottomTaskSelection', 'BottomTaskSelection',
'<div id="Actions" class="field actions"><label class="left">Actions</label><ul>'. '<div id="Actions" class="field actions"><label class="left">Actions</label><ul>'
'<li class="ss-ui-button" data-panel="embargo">Embargo</li>'. . '<li class="ss-ui-button" data-panel="embargo">Embargo</li>'
'<li class="ss-ui-button" data-panel="expiry">Expiry</li>'. . '<li class="ss-ui-button" data-panel="expiry">Expiry</li>'
'<li class="ss-ui-button" data-panel="replace">Replace</li>'. . '<li class="ss-ui-button" data-panel="replace">Replace</li>'
'<li class="ss-ui-button" data-panel="find-usage">Usage</li>'. . '<li class="ss-ui-button" data-panel="find-usage">Usage</li>'
'<li class="ss-ui-button" data-panel="find-references">References</li>'. . '<li class="ss-ui-button" data-panel="find-references">References</li>'
$extraTasks. . '<li class="ss-ui-button" data-panel="find-relateddocuments">Related Documents</li>'
'</ul></div>' . $extraTasks
. '</ul></div>'
)); ));
$embargoValue = 'None'; $embargoValue = 'None';
@ -1076,27 +1077,13 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
// These are toggled on and off via the Actions Buttons above // These are toggled on and off via the Actions Buttons above
// exit('hit'); // exit('hit');
$actionsPanel = FieldGroup::create( $actionsPanel = FieldGroup::create(
FieldGroup::create($embargo, $embargoDatetime)->addExtraClass('embargo'),
FieldGroup::create( FieldGroup::create($expiry, $expiryDatetime)->addExtraClass('expiry'),
$embargo, FieldGroup::create($uploadField)->addExtraClass('replace'),
$embargoDatetime FieldGroup::create($pagesGrid)->addExtraClass('find-usage'),
)->addExtraClass('embargo'), FieldGroup::create($referencesGrid)->addExtraClass('find-references'),
FieldGroup::create( FieldGroup::create($versionsGrid)->addExtraClass('find-versions'),
$expiry, FieldGroup::create($this->getRelatedDocumentsGridField())->addExtraClass('find-relateddocuments')
$expiryDatetime
)->addExtraClass('expiry'),
FieldGroup::create(
$uploadField
)->addExtraClass('replace'),
FieldGroup::create(
$pagesGrid
)->addExtraClass('find-usage'),
FieldGroup::create(
$referencesGrid
)->addExtraClass('find-references'),
FieldGroup::create(
$versionsGrid
)->addExtraClass('find-versions')
); );
$actionsPanel->setName("ActionsPanel"); $actionsPanel->setName("ActionsPanel");
@ -1104,22 +1091,6 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
$fields->push($actionsPanel); $fields->push($actionsPanel);
// $fields->add(FieldGroup::create(
// FieldGroup::create(
// $embargo,
// $embargoDatetime
// )->addExtraClass('embargo'),
// FieldGroup::create(
// $expiry,
// $expiryDatetime
// )->addExtraClass('expiry'),
// $uploadField->addExtraClass('replace'),
// $pagesGrid->addExtraClass('find-usage'),
// $referencesGrid->addExtraClass('find-references'),
// $extraFields
// )->setName("ActionsPanel")->addExtraClass('dmsupload ss-uploadfield'));
$this->extend('updateCMSFields', $fields); $this->extend('updateCMSFields', $fields);
return $fields; return $fields;
@ -1313,4 +1284,42 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
return $this; return $this;
} }
/**
* Get a data list of documents related to this document
*
* @return DataList
*/
public function getRelatedDocuments()
{
$documents = $this->RelatedDocuments();
$this->extend('updateRelatedDocuments', $documents);
return $documents;
}
/**
* Get a GridField for managing related documents
*
* @return GridField
*/
protected function getRelatedDocumentsGridField()
{
$gridField = GridField::create(
'RelatedDocuments',
_t('DMSDocument.RELATEDDOCUMENTS', 'Related Documents'),
$this->RelatedDocuments(),
new GridFieldConfig_RelationEditor
);
$gridField->getConfig()->removeComponentsByType('GridFieldAddNewButton');
// Move the autocompleter to the left
$gridField->getConfig()->removeComponentsByType('GridFieldAddExistingAutocompleter');
$gridField->getConfig()->addComponent(new GridFieldAddExistingAutocompleter('buttons-before-left'));
$this->extend('updateRelatedDocumentsGridField', $gridField);
return $gridField;
}
} }

View File

@ -14,6 +14,8 @@ en:
RelatedReferences: 'Related References' RelatedReferences: 'Related References'
SINGULARNAME: Document SINGULARNAME: Document
Versions: Versions Versions: Versions
DOWNLOAD: "Download {title}"
LASTCHANGED: "Last changed: {date}"
DMSTag: DMSTag:
PLURALNAME: 'D M S Tags' PLURALNAME: 'D M S Tags'
SINGULARNAME: 'D M S Tag' SINGULARNAME: 'D M S Tag'
@ -35,6 +37,7 @@ en:
DMSDocumentAddController: DMSDocumentAddController:
MENUTITLE: 'Edit Page' MENUTITLE: 'Edit Page'
NODOCUMENTS: 'There are no documents attached to the selected page.' NODOCUMENTS: 'There are no documents attached to the selected page.'
RELATEDDOCUMENTS: 'Related Documents'
DMSDocument_versions: DMSDocument_versions:
PLURALNAME: 'D M S Document_versionss' PLURALNAME: 'D M S Document_versionss'
SINGULARNAME: 'D M S Document_versions' SINGULARNAME: 'D M S Document_versions'

View File

@ -1,19 +1,18 @@
<% if isHidden != true %> <% if $isHidden != true %>
<div class="document $Extension"> <div class="document $Extension">
<% if Title %> <% if $Title %>
<h4><a href="$Link" title="Download $Title">$Title</a></h4> <h4><a href="$Link" title="<%t DMSDocument.DOWNLOAD "Download {title}" title=$Title %>">$Title</a></h4>
<% else %> <% else %>
<h4><a href="$Link" title="Download $FilenameWithoutID">$FilenameWithoutID</a></h4> <h4><a href="$Link" title="<%t DMSDocument.DOWNLOAD "Download {title}" title=$FilenameWithoutID %>">$FilenameWithoutID</a></h4>
<% end_if %> <% end_if %>
<p class='details'> <p class="details"><% include DocumentDetails %></p>
<strong>$FilenameWithoutID</strong> <% if $Description %>
| $Extension <p>$DescriptionWithLineBreak</p>
| $FileSizeFormatted <% end_if %>
| Last Changed: $LastChanged.Nice
</p> <% if $RelatedDocuments %>
<% if Description %> <% include RelatedDocuments %>
<p>$DescriptionWithLineBreak</p> <% end_if %>
<% end_if %> </div>
</div> <% end_if %>
<% end_if %>

View File

@ -0,0 +1,4 @@
<strong>$FilenameWithoutID</strong>
| $Extension
| $FileSizeFormatted
| <%t DMSDocument.LASTCHANGED "Last changed: {date}" date=$LastChanged.Nice %>

View File

@ -1,4 +1,8 @@
<% if PageDocuments %> <% if PageDocuments %>
<div><h3>Documents:</h3></div> <div class="documents">
<% loop PageDocuments %><% include Document %><% end_loop %> <h3><%t DMSDocument.PLURALNAME "Documents" %></h3>
<% loop PageDocuments %>
<% include Document %>
<% end_loop %>
</div>
<% end_if %> <% end_if %>

View File

@ -0,0 +1,14 @@
<h5><%t DMSDocument.RELATED_DOCUMENTS "Related documents" %></h5>
<ul class="documents-relateddocuments">
<% loop $RelatedDocuments %>
<li>
<% if $Title %>
<a href="$Link" title="<%t DMSDocument.DOWNLOAD "Download {title}" title=$Title %>">$Title</a>
<% else %>
<a href="$Link" title="<%t DMSDocument.DOWNLOAD "Download {title}" title=$FilenameWithoutID %>">$FilenameWithoutID</a>
<% end_if %>
<span class="documents-relateddocuments-documentdetails"><% include DocumentDetails %></span>
</li>
<% end_loop %>
</ul>

View File

@ -1,17 +1,17 @@
<?php <?php
class DMSDocumentTest extends SapphireTest class DMSDocumentTest extends SapphireTest
{ {
protected static $fixture_file = "dmstest.yml"; protected static $fixture_file = 'dmstest.yml';
public function tearDownOnce() public function tearDownOnce()
{ {
self::$is_running_test = true; self::$is_running_test = true;
$d = DataObject::get("DMSDocument"); $d = DataObject::get('DMSDocument');
foreach ($d as $d1) { foreach ($d as $d1) {
$d1->delete(); $d1->delete();
} }
$t = DataObject::get("DMSTag"); $t = DataObject::get('DMSTag');
foreach ($t as $t1) { foreach ($t as $t1) {
$t1->delete(); $t1->delete();
} }
@ -32,12 +32,12 @@ class DMSDocumentTest extends SapphireTest
$pages = $d1->Pages(); $pages = $d1->Pages();
$pagesArray = $pages->toArray(); $pagesArray = $pages->toArray();
$this->assertEquals($pagesArray[0]->ID, $s1->ID, "Page 1 associated correctly"); $this->assertEquals($pagesArray[0]->ID, $s1->ID, 'Page 1 associated correctly');
$this->assertEquals($pagesArray[1]->ID, $s2->ID, "Page 2 associated correctly"); $this->assertEquals($pagesArray[1]->ID, $s2->ID, 'Page 2 associated correctly');
$this->assertEquals($pagesArray[2]->ID, $s3->ID, "Page 3 associated correctly"); $this->assertEquals($pagesArray[2]->ID, $s3->ID, 'Page 3 associated correctly');
$this->assertEquals($pagesArray[3]->ID, $s4->ID, "Page 4 associated correctly"); $this->assertEquals($pagesArray[3]->ID, $s4->ID, 'Page 4 associated correctly');
$this->assertEquals($pagesArray[4]->ID, $s5->ID, "Page 5 associated correctly"); $this->assertEquals($pagesArray[4]->ID, $s5->ID, 'Page 5 associated correctly');
$this->assertEquals($pagesArray[5]->ID, $s6->ID, "Page 6 associated correctly"); $this->assertEquals($pagesArray[5]->ID, $s6->ID, 'Page 6 associated correctly');
} }
public function testAddPageRelation() public function testAddPageRelation()
@ -47,8 +47,8 @@ class DMSDocumentTest extends SapphireTest
$s3 = $this->objFromFixture('SiteTree', 's3'); $s3 = $this->objFromFixture('SiteTree', 's3');
$doc = new DMSDocument(); $doc = new DMSDocument();
$doc->Filename = "test file"; $doc->Filename = 'test file';
$doc->Folder = "0"; $doc->Folder = '0';
$doc->write(); $doc->write();
$doc->addPage($s1); $doc->addPage($s1);
@ -57,15 +57,15 @@ class DMSDocumentTest extends SapphireTest
$pages = $doc->Pages(); $pages = $doc->Pages();
$pagesArray = $pages->toArray(); $pagesArray = $pages->toArray();
$this->assertEquals($pagesArray[0]->ID, $s1->ID, "Page 1 associated correctly"); $this->assertEquals($pagesArray[0]->ID, $s1->ID, 'Page 1 associated correctly');
$this->assertEquals($pagesArray[1]->ID, $s2->ID, "Page 2 associated correctly"); $this->assertEquals($pagesArray[1]->ID, $s2->ID, 'Page 2 associated correctly');
$this->assertEquals($pagesArray[2]->ID, $s3->ID, "Page 3 associated correctly"); $this->assertEquals($pagesArray[2]->ID, $s3->ID, 'Page 3 associated correctly');
$doc->removePage($s1); $doc->removePage($s1);
$pages = $doc->Pages(); $pages = $doc->Pages();
$pagesArray = $pages->toArray(); // Page 1 is missing $pagesArray = $pages->toArray(); // Page 1 is missing
$this->assertEquals($pagesArray[0]->ID, $s2->ID, "Page 2 still associated correctly"); $this->assertEquals($pagesArray[0]->ID, $s2->ID, 'Page 2 still associated correctly');
$this->assertEquals($pagesArray[1]->ID, $s3->ID, "Page 3 still associated correctly"); $this->assertEquals($pagesArray[1]->ID, $s3->ID, 'Page 3 still associated correctly');
$documents = $s2->Documents(); $documents = $s2->Documents();
$documentsArray = $documents->toArray(); $documentsArray = $documents->toArray();
@ -74,16 +74,16 @@ class DMSDocumentTest extends SapphireTest
array('Filename' => $doc->Filename) array('Filename' => $doc->Filename)
), ),
$documentsArray, $documentsArray,
"Document associated with page" 'Document associated with page'
); );
$doc->removeAllPages(); $doc->removeAllPages();
$pages = $doc->Pages(); $pages = $doc->Pages();
$this->assertEquals($pages->Count(), 0, "All pages removed"); $this->assertEquals($pages->Count(), 0, 'All pages removed');
$documents = $s2->Documents(); $documents = $s2->Documents();
$documentsArray = $documents->toArray(); $documentsArray = $documents->toArray();
$this->assertNotContains($doc, $documentsArray, "Document no longer associated with page"); $this->assertNotContains($doc, $documentsArray, 'Document no longer associated with page');
} }
public function testDeletingPageWithAssociatedDocuments() public function testDeletingPageWithAssociatedDocuments()
@ -94,8 +94,8 @@ class DMSDocumentTest extends SapphireTest
$s2ID = $s2->ID; $s2ID = $s2->ID;
$doc = new DMSDocument(); $doc = new DMSDocument();
$doc->Filename = "delete test file"; $doc->Filename = 'delete test file';
$doc->Folder = "0"; $doc->Folder = '0';
$doc->write(); $doc->write();
$doc->addPage($s1); $doc->addPage($s1);
@ -125,8 +125,8 @@ class DMSDocumentTest extends SapphireTest
$this->assertEquals( $this->assertEquals(
$documents->Count(), $documents->Count(),
'0', '0',
"However, deleting the live version of the last page that a document is " 'However, deleting the live version of the last page that a document is '
."associated with causes that document to be deleted as well" . 'associated with causes that document to be deleted as well'
); );
} }
@ -137,8 +137,8 @@ class DMSDocumentTest extends SapphireTest
$s2ID = $s2->ID; $s2ID = $s2->ID;
$doc = new DMSDocument(); $doc = new DMSDocument();
$doc->Filename = "delete test file"; $doc->Filename = 'delete test file';
$doc->Folder = "0"; $doc->Folder = '0';
$doc->write(); $doc->write();
$doc->addPage($s2); $doc->addPage($s2);
@ -158,8 +158,8 @@ class DMSDocumentTest extends SapphireTest
$this->assertEquals( $this->assertEquals(
$documents->Count(), $documents->Count(),
'0', '0',
"However, deleting the draft version of the last page that a document is " 'However, deleting the draft version of the last page that a document is '
."associated with causes that document to be deleted as well" . 'associated with causes that document to be deleted as well'
); );
} }
@ -175,4 +175,66 @@ class DMSDocumentTest extends SapphireTest
$cmsFields = $document->getCMSFields(); $cmsFields = $document->getCMSFields();
$this->assertEquals('download', $cmsFields->dataFieldByName('DownloadBehavior')->Value()); $this->assertEquals('download', $cmsFields->dataFieldByName('DownloadBehavior')->Value());
} }
/**
* Ensure that related documents can be retrieved for a given DMS document
*/
public function testRelatedDocuments()
{
$document = $this->objFromFixture('DMSDocument', 'document_with_relations');
$this->assertGreaterThan(0, $document->RelatedDocuments()->count());
$this->assertEquals(
array('test-file-file-doesnt-exist-1', 'test-file-file-doesnt-exist-2'),
$document->getRelatedDocuments()->column('Filename')
);
}
/**
* Test the extensibility of getRelatedDocuments
*/
public function testGetRelatedDocumentsIsExtensible()
{
DMSDocument::add_extension('StubRelatedDocumentExtension');
$emptyDocument = new DMSDocument;
$relatedDocuments = $emptyDocument->getRelatedDocuments();
$this->assertCount(1, $relatedDocuments);
$this->assertSame('Extended', $relatedDocuments->first()->Filename);
}
/**
* Ensure that the DMS Document CMS actions contains a grid field for managing related documents
*/
public function testDocumentHasCmsFieldForManagingRelatedDocuments()
{
$document = $this->objFromFixture('DMSDocument', 'document_with_relations');
$documentFields = $document->getCMSFields();
/** @var FieldGroup $actions */
$actions = $documentFields->fieldByName('ActionsPanel');
$gridField = null;
foreach ($actions->getChildren() as $child) {
/** @var FieldGroup $child */
if ($gridField = $child->fieldByName('RelatedDocuments')) {
break;
}
}
$this->assertInstanceOf('GridField', $gridField);
/** @var GridFieldConfig $gridFieldConfig */
$gridFieldConfig = $gridField->getConfig();
$this->assertNotNull(
'GridFieldAddExistingAutocompleter',
$addExisting = $gridFieldConfig->getComponentByType('GridFieldAddExistingAutocompleter'),
'Related documents GridField has an "add existing" autocompleter'
);
$this->assertNull(
$gridFieldConfig->getComponentByType('GridFieldAddNewButton'),
'Related documents GridField does not have an "add new" button'
);
}
} }

View File

@ -0,0 +1,18 @@
<?php
class StubRelatedDocumentExtension extends DataExtension implements TestOnly
{
/**
* Push a fixed array entry into the datalist for extensibility testing
*
* @param ArrayList $relatedDocuments
* @return ArrayList
*/
public function updateRelatedDocuments(ArrayList $relatedDocuments)
{
$fakeDocument = new DMSDocument;
$fakeDocument->Filename = 'Extended';
$relatedDocuments->push($fakeDocument);
return $relatedDocuments;
}
}

View File

@ -38,12 +38,16 @@ DMSTag:
Value: tag6value Value: tag6value
DMSDocument: DMSDocument:
d1: d1:
Filename: test-file-file-doesnt-exist Filename: test-file-file-doesnt-exist-1
Folder: 5 Folder: 5
Tags: =>DMSTag.t1, =>DMSTag.t2, =>DMSTag.t3, =>DMSTag.t4 Tags: =>DMSTag.t1, =>DMSTag.t2, =>DMSTag.t3, =>DMSTag.t4
Pages: =>SiteTree.s1, =>SiteTree.s2, =>SiteTree.s3, =>SiteTree.s4, =>SiteTree.s5, =>SiteTree.s6 Pages: =>SiteTree.s1, =>SiteTree.s2, =>SiteTree.s3, =>SiteTree.s4, =>SiteTree.s5, =>SiteTree.s6
d2: d2:
Filename: test-file-file-doesnt-exist Filename: test-file-file-doesnt-exist-2
Folder: 5 Folder: 5
Tags: =>DMSTag.t5, =>DMSTag.t6 Tags: =>DMSTag.t5, =>DMSTag.t6
Pages: =>SiteTree.s5, =>SiteTree.s6 Pages: =>SiteTree.s5, =>SiteTree.s6
document_with_relations:
Filename: file-with-relations
Folder: 5
RelatedDocuments: =>DMSDocument.d1, =>DMSDocument.d2