diff --git a/code/model/DMSDocument.php b/code/model/DMSDocument.php index ead12bb..48b57f8 100644 --- a/code/model/DMSDocument.php +++ b/code/model/DMSDocument.php @@ -23,6 +23,7 @@ class DMSDocument extends DataObject implements DMSDocumentInterface private static $many_many = array( 'Pages' => 'SiteTree', + 'RelatedDocuments' => 'DMSDocument', 'Tags' => 'DMSTag' ); @@ -1012,19 +1013,19 @@ class DMSDocument extends DataObject implements DMSDocumentInterface $versionsGridFieldConfig ); $extraTasks .= '
  • Versions
  • '; - //$extraFields = $versionsGrid->addExtraClass('find-versions'); } $fields->add(new LiteralField( 'BottomTaskSelection', - '
    ' + '
    ' )); $embargoValue = 'None'; @@ -1076,27 +1077,13 @@ class DMSDocument extends DataObject implements DMSDocumentInterface // These are toggled on and off via the Actions Buttons above // exit('hit'); $actionsPanel = FieldGroup::create( - - FieldGroup::create( - $embargo, - $embargoDatetime - )->addExtraClass('embargo'), - FieldGroup::create( - $expiry, - $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') + FieldGroup::create($embargo, $embargoDatetime)->addExtraClass('embargo'), + FieldGroup::create($expiry, $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'), + FieldGroup::create($this->getRelatedDocumentsGridField())->addExtraClass('find-relateddocuments') ); $actionsPanel->setName("ActionsPanel"); @@ -1104,22 +1091,6 @@ class DMSDocument extends DataObject implements DMSDocumentInterface $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); return $fields; @@ -1313,4 +1284,42 @@ class DMSDocument extends DataObject implements DMSDocumentInterface 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; + } } diff --git a/lang/en.yml b/lang/en.yml index ed30a1b..23d1ffc 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -14,6 +14,8 @@ en: RelatedReferences: 'Related References' SINGULARNAME: Document Versions: Versions + DOWNLOAD: "Download {title}" + LASTCHANGED: "Last changed: {date}" DMSTag: PLURALNAME: 'D M S Tags' SINGULARNAME: 'D M S Tag' @@ -35,6 +37,7 @@ en: DMSDocumentAddController: MENUTITLE: 'Edit Page' NODOCUMENTS: 'There are no documents attached to the selected page.' + RELATEDDOCUMENTS: 'Related Documents' DMSDocument_versions: PLURALNAME: 'D M S Document_versionss' SINGULARNAME: 'D M S Document_versions' diff --git a/templates/Includes/Document.ss b/templates/Includes/Document.ss index 4514a23..9e0d6cc 100644 --- a/templates/Includes/Document.ss +++ b/templates/Includes/Document.ss @@ -1,19 +1,18 @@ -<% if isHidden != true %> -
    - <% if Title %> -

    $Title

    - <% else %> -

    $FilenameWithoutID

    - <% end_if %> - -

    - $FilenameWithoutID - | $Extension - | $FileSizeFormatted - | Last Changed: $LastChanged.Nice -

    - <% if Description %> -

    $DescriptionWithLineBreak

    - <% end_if %> -
    -<% end_if %> \ No newline at end of file +<% if $isHidden != true %> +
    + <% if $Title %> +

    ">$Title

    + <% else %> +

    ">$FilenameWithoutID

    + <% end_if %> + +

    <% include DocumentDetails %>

    + <% if $Description %> +

    $DescriptionWithLineBreak

    + <% end_if %> + + <% if $RelatedDocuments %> + <% include RelatedDocuments %> + <% end_if %> +
    +<% end_if %> diff --git a/templates/Includes/DocumentDetails.ss b/templates/Includes/DocumentDetails.ss new file mode 100644 index 0000000..25a90d7 --- /dev/null +++ b/templates/Includes/DocumentDetails.ss @@ -0,0 +1,4 @@ +$FilenameWithoutID +| $Extension +| $FileSizeFormatted +| <%t DMSDocument.LASTCHANGED "Last changed: {date}" date=$LastChanged.Nice %> \ No newline at end of file diff --git a/templates/Includes/Documents.ss b/templates/Includes/Documents.ss index 8832616..516d8f2 100644 --- a/templates/Includes/Documents.ss +++ b/templates/Includes/Documents.ss @@ -1,4 +1,8 @@ <% if PageDocuments %> -

    Documents:

    - <% loop PageDocuments %><% include Document %><% end_loop %> +
    +

    <%t DMSDocument.PLURALNAME "Documents" %>

    + <% loop PageDocuments %> + <% include Document %> + <% end_loop %> +
    <% end_if %> diff --git a/templates/Includes/RelatedDocuments.ss b/templates/Includes/RelatedDocuments.ss new file mode 100644 index 0000000..f648a54 --- /dev/null +++ b/templates/Includes/RelatedDocuments.ss @@ -0,0 +1,14 @@ +
    <%t DMSDocument.RELATED_DOCUMENTS "Related documents" %>
    + + diff --git a/tests/DMSDocumentTest.php b/tests/DMSDocumentTest.php index 0e4138a..10f3660 100644 --- a/tests/DMSDocumentTest.php +++ b/tests/DMSDocumentTest.php @@ -1,17 +1,17 @@ delete(); } - $t = DataObject::get("DMSTag"); + $t = DataObject::get('DMSTag'); foreach ($t as $t1) { $t1->delete(); } @@ -32,12 +32,12 @@ class DMSDocumentTest extends SapphireTest $pages = $d1->Pages(); $pagesArray = $pages->toArray(); - $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[2]->ID, $s3->ID, "Page 3 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[5]->ID, $s6->ID, "Page 6 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[2]->ID, $s3->ID, 'Page 3 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[5]->ID, $s6->ID, 'Page 6 associated correctly'); } public function testAddPageRelation() @@ -47,8 +47,8 @@ class DMSDocumentTest extends SapphireTest $s3 = $this->objFromFixture('SiteTree', 's3'); $doc = new DMSDocument(); - $doc->Filename = "test file"; - $doc->Folder = "0"; + $doc->Filename = 'test file'; + $doc->Folder = '0'; $doc->write(); $doc->addPage($s1); @@ -57,15 +57,15 @@ class DMSDocumentTest extends SapphireTest $pages = $doc->Pages(); $pagesArray = $pages->toArray(); - $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[2]->ID, $s3->ID, "Page 3 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[2]->ID, $s3->ID, 'Page 3 associated correctly'); $doc->removePage($s1); $pages = $doc->Pages(); $pagesArray = $pages->toArray(); // Page 1 is missing - $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[0]->ID, $s2->ID, 'Page 2 still associated correctly'); + $this->assertEquals($pagesArray[1]->ID, $s3->ID, 'Page 3 still associated correctly'); $documents = $s2->Documents(); $documentsArray = $documents->toArray(); @@ -74,16 +74,16 @@ class DMSDocumentTest extends SapphireTest array('Filename' => $doc->Filename) ), $documentsArray, - "Document associated with page" + 'Document associated with page' ); $doc->removeAllPages(); $pages = $doc->Pages(); - $this->assertEquals($pages->Count(), 0, "All pages removed"); + $this->assertEquals($pages->Count(), 0, 'All pages removed'); $documents = $s2->Documents(); $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() @@ -94,8 +94,8 @@ class DMSDocumentTest extends SapphireTest $s2ID = $s2->ID; $doc = new DMSDocument(); - $doc->Filename = "delete test file"; - $doc->Folder = "0"; + $doc->Filename = 'delete test file'; + $doc->Folder = '0'; $doc->write(); $doc->addPage($s1); @@ -125,8 +125,8 @@ class DMSDocumentTest extends SapphireTest $this->assertEquals( $documents->Count(), '0', - "However, deleting the live version of the last page that a document is " - ."associated with causes that document to be deleted as well" + 'However, deleting the live version of the last page that a document is ' + . 'associated with causes that document to be deleted as well' ); } @@ -137,8 +137,8 @@ class DMSDocumentTest extends SapphireTest $s2ID = $s2->ID; $doc = new DMSDocument(); - $doc->Filename = "delete test file"; - $doc->Folder = "0"; + $doc->Filename = 'delete test file'; + $doc->Folder = '0'; $doc->write(); $doc->addPage($s2); @@ -158,8 +158,8 @@ class DMSDocumentTest extends SapphireTest $this->assertEquals( $documents->Count(), '0', - "However, deleting the draft version of the last page that a document is " - ."associated with causes that document to be deleted as well" + 'However, deleting the draft version of the last page that a document is ' + . 'associated with causes that document to be deleted as well' ); } @@ -175,4 +175,66 @@ class DMSDocumentTest extends SapphireTest $cmsFields = $document->getCMSFields(); $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' + ); + } } diff --git a/tests/Stub/StubRelatedDocumentExtension.php b/tests/Stub/StubRelatedDocumentExtension.php new file mode 100644 index 0000000..0a74b33 --- /dev/null +++ b/tests/Stub/StubRelatedDocumentExtension.php @@ -0,0 +1,18 @@ +Filename = 'Extended'; + $relatedDocuments->push($fakeDocument); + return $relatedDocuments; + } +} diff --git a/tests/dmstest.yml b/tests/dmstest.yml index e727c01..3832895 100644 --- a/tests/dmstest.yml +++ b/tests/dmstest.yml @@ -38,12 +38,16 @@ DMSTag: Value: tag6value DMSDocument: d1: - Filename: test-file-file-doesnt-exist + Filename: test-file-file-doesnt-exist-1 Folder: 5 Tags: =>DMSTag.t1, =>DMSTag.t2, =>DMSTag.t3, =>DMSTag.t4 Pages: =>SiteTree.s1, =>SiteTree.s2, =>SiteTree.s3, =>SiteTree.s4, =>SiteTree.s5, =>SiteTree.s6 d2: - Filename: test-file-file-doesnt-exist + Filename: test-file-file-doesnt-exist-2 Folder: 5 Tags: =>DMSTag.t5, =>DMSTag.t6 Pages: =>SiteTree.s5, =>SiteTree.s6 + document_with_relations: + Filename: file-with-relations + Folder: 5 + RelatedDocuments: =>DMSDocument.d1, =>DMSDocument.d2