Merge pull request #106 from robbieaverill/feature/related-documents

NEW Relate documents to other documents and tidy up documentation
This commit is contained in:
Franco Springveldt 2017-05-02 13:08:29 +12:00 committed by GitHub
commit bbe9e35d99
21 changed files with 411 additions and 200 deletions

1
.gitattributes vendored
View File

@ -1,3 +1,4 @@
/docs export-ignore
/tests export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore

113
README.md
View File

@ -3,25 +3,20 @@
[![Build status](https://travis-ci.org/silverstripe/silverstripe-dms.png?branch=master)](https://travis-ci.org/silverstripe/silverstripe-dms)
[![Code quality](https://scrutinizer-ci.com/g/silverstripe/silverstripe-dms/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/silverstripe/silverstripe-dms/?branch=master)
[![Code coverage](https://codecov.io/gh/silverstripe/silverstripe-dms/branch/master/graph/badge.svg)](https://codecov.io/gh/silverstripe/silverstripe-dms)
![Helpful Robot](https://img.shields.io/badge/helpfulrobot-52-yellow.svg?style=flat)
## Overview
The module adds a new `DMSDocument` model which allows management
of large amounts of files, and their relations to pages.
In contrast to the `File` model built into SilverStripe core,
it aims to wrap storage and access concerns in a generic API,
which allows more fine-grained control over how the documents are
managed and exposed through the website.
The module adds a new `DMSDocument` model which allows management of large amounts of files, and their relations to
pages. In contrast to the `File` model built into SilverStripe core, it aims to wrap storage and access concerns in
a generic API. This allows more fine-grained control over how the documents are managed and exposed through the website.
Additionally, documents are stored and managed as part of a page instead of
away in a separate assets store.
Additionally, documents are stored and managed as part of a page instead of away in a separate assets store.
Read more about the DMS module in this [blog post on silverstripe.org](http://www.silverstripe.org/document-management-system-module)
Features:
## Features
* Relation of documents to pages
* Relation of documents to other documents
* Management and upload of documents within a page context in the CMS
* Metadata management through the powerful `GridField` and `UploadField` core APIs
* Configurable tags for documents
@ -29,30 +24,11 @@ Features:
* Access control based on PHP logic, and page relations
* Replacement of existing files
## Documents on the Filesystem
## Documentation
While the DMS architecture allows for remote storage of files,
the default implementation (the `DMS` class) stores them locally.
Relations to pages and tags are persisted as many-many relationships
through the SilverStripe ORM.
For information on configuring and using this module, please see [the documentation section](docs/en/index.md).
File locations in this implementation are structured into
subfolders, in order to avoid exceeding filesystem limits.
The file name is a composite based on its database ID
and the original file name. The exact location shouldn't
be relied on by custom logic, but rather retrieved through
the API (`DMSDocument->getLink()`).
Example:
dms-assets/
0/
1234~myfile.pdf
1/
2345~myotherfile.pdf
### Requirements
## Requirements
* PHP 5.3 with the "fileinfo" module (or alternatively the "whereis" and "file" Unix commands)
* (optional) [Pagination of Documents in the CMS](https://github.com/silverstripe-big-o/gridfieldpaginatorwithshowall)
@ -61,75 +37,6 @@ Example:
* (optional) [Text extraction for Document full-text search](https://github.com/silverstripe-big-o/silverstripe-textextraction)
* (optional) [Tags](https://github.com/tubbs/silverstripe-dms-simple-tags)
### Configuration
The file location is set via the `DMS::$dmsFolder` static, and points to a location in the webroot.
### Usage
Add a simple include to any of your .ss templates to display the DMSDocuments associated with
the current page on the front-end.
<% include Documents %>
#### Create Documents
Create by relative path:
$dms = DMS::getDMSInstance();
$doc = $dms->storeDocument('assets/myfile.pdf');
Create from an existing `File` record:
$dms = DMS::getDMSInstance();
$file = File::get()->byID(99);
$doc = $dms->storeDocument($file);
Note: Both operations copy the existing file.
#### Download Documents
$dms = DMS::getDMSInstance();
$docs = $dms->getByTag('priority', 'important')->First();
$link = $doc->getLink();
// Set default download behavior ('open' or 'download'). 'download' is the system default
// Attempt to open the file in the browser
Config::inst()->update('DMSDocument', 'default_download_behaviour', 'open');
Or in you config.yml:
DMSDocument:
default_download_behaviour: open
#### Manage Page Relations
// Find documents by page
$dms = DMS::getDMSInstance();
$page = SiteTree::get()->filter('URLSegment', 'home')->First();
$docs = $dms->getByPage($page);
// Add documents to page
#### Manage Tags
// Find documents by tag
$dms = DMS::getDMSInstance();
$docs = $dms->getByTag('priority', 'important');
// Add tag to existing document
$doc = Document::get()->byID(99);
$doc->addTag('priority', 'low');
// Supports multiple values for tags
$doc->addTag('category', 'keyboard');
$doc->addTag('category', 'input device');
// Removing tags is abstracted as well
$doc->removeTag('category', 'keyboard');
$doc->removeTag('category', 'input device');
$doc->removeAllTags();
## Contributing
### Translations

View File

@ -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 .= '<li class="ss-ui-button" data-panel="find-versions">Versions</li>';
//$extraFields = $versionsGrid->addExtraClass('find-versions');
}
$fields->add(new LiteralField(
'BottomTaskSelection',
'<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="expiry">Expiry</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-references">References</li>'.
$extraTasks.
'</ul></div>'
'<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="expiry">Expiry</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-references">References</li>'
. '<li class="ss-ui-button" data-panel="find-relateddocuments">Related Documents</li>'
. $extraTasks
. '</ul></div>'
));
$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;
}
}

View File

3
docs/en/configuration.md Normal file
View File

@ -0,0 +1,3 @@
# Configuration
The file location is set via the `DMS::$dmsFolder` static, and points to a location in the webroot.

View File

@ -0,0 +1,18 @@
# Creating documents
Create by relative path:
```php
$dms = DMS::getDMSInstance();
$doc = $dms->storeDocument('assets/myfile.pdf');
```
Create from an existing `File` record:
```php
$dms = DMS::getDMSInstance();
$file = File::get()->byID(99);
$doc = $dms->storeDocument($file);
```
Note: Both operations copy the existing file.

View File

@ -0,0 +1,18 @@
# Documents on the Filesystem
While the DMS architecture allows for remote storage of files, the default implementation (the `DMS` class)
stores them locally. Relations to pages and tags are persisted as many-many relationships through the SilverStripe ORM.
File locations in this implementation are structured into subfolders, in order to avoid exceeding filesystem limits.
The file name is a composite based on its database ID and the original file name. The exact location shouldn't be
relied on by custom logic, but rather retrieved through the API method `DMSDocument::getLink`.
Example:
```
dms-assets/
0/
1234~myfile.pdf
1/
2345~myotherfile.pdf
```

View File

@ -0,0 +1,28 @@
# Download documents
## Get the download link
You can use `DMSDocument::getLink` to retrieve the secure route to download a DMS document:
```php
$dms = DMS::getDMSInstance();
$docs = $dms->getByTag('priority', 'important')->First();
$link = $doc->getLink();
```
## Default download behaviour
The default download behaviour is "download" which will force the browser to download the document. You
can select "open" as an option in the document's settings in the CMS individually, or you can change the global
default value with configuration:
```php
Config::inst()->update('DMSDocument', 'default_download_behaviour', 'open');
```
Or in YAML:
```yaml
DMSDocument:
default_download_behaviour: open
```

16
docs/en/index.md Normal file
View File

@ -0,0 +1,16 @@
# DMS documentation
## Development
* [Configuration](configuration.md)
* [Documents on the filesystem](documents-on-the-filesystem.md)
* [Use in templates](use-in-templates.md)
* [Creating documents](creating-documents.md)
* [Download documents](download-documents.md)
* [Manage page relations](manage-page-relations.md)
* [Manage tags](manage-tags.md)
* [Manage related documents](manage-related-documents.md)
## CMS user help
* TBC

View File

@ -0,0 +1,10 @@
# Manage page relations
To find documents by a Page:
```php
$dms = DMS::getDMSInstance();
$page = SiteTree::get()->filter('URLSegment', 'home')->first();
/** @var DataList $docs */
$docs = $dms->getByPage($page);
```

View File

@ -0,0 +1,50 @@
# Manage related documents
You can relate documents to each other using the GridField under "Related Documents" in the CMS.
## Add related documents
You can use the model relationship `DMSDocument::RelatedDocuments` to modify the DataList and save as required:
```php
$parentDocument = DMSDocument::get()->byId(123);
$relatedDocument = DMSDocument::get()->byId(234);
$parentDocument->RelatedDocuments()->add($relatedDocument);
```
Using the relationship method directly will skip the extension hook available in `getRelatedDocuments` (see below).
## Modifying the related documents list
If you need to modify the related documents DataList returned by the ORM, use the `updateRelatedDocuments` extension
hook provided by `DMSDocument::getRelatedDocuments`:
```php
# MyExtension is an extension applied to DMSDocument
class MyExtension extends DataExtension
{
public function updateRelatedDocuments($relatedDocuments)
{
foreach ($relatedDocuments as $document) {
// Add square brackets around the description
$document->Description = '[' . $document->Description . ']';
}
return $relatedDocuments;
}
}
```
## Retrieving related documents
To retrieve a DataList of related documents you can either use `getRelatedDocuments` or the ORM relationship method
`RelatedDocuments` directly. The former will allow extensions to modify the list, whereas the latter will not.
```php
$relatedDocuments = $document->getRelatedDocuments();
foreach ($relatedDocuments as $relatedDocument) {
// ...
}
```

32
docs/en/manage-tags.md Normal file
View File

@ -0,0 +1,32 @@
# Manage Tags
## Find documents by tag
```php
$dms = DMS::getDMSInstance();
$docs = $dms->getByTag('priority', 'important');
```
## Add tag to existing document
```php
$doc = DMSDocument::get()->byID(99);
$doc->addTag('priority', 'low');
```
## Supports multiple values for tags
```php
$doc->addTag('category', 'keyboard');
$doc->addTag('category', 'input device');
```
## Removing tags
Removing tags is abstracted as well.
```php
$doc->removeTag('category', 'keyboard');
$doc->removeTag('category', 'input device');
$doc->removeAllTags();
```

View File

@ -0,0 +1,11 @@
# Use in templates
Add a simple include to any of your `.ss` templates to display the DMSDocuments associated with
the current page on the front-end.
```
<% include Documents %>
```
You can fine tune the HTML markup or display behaviour of any of the templates in `/dms/templates/Includes` to change
the way documents will be displayed in your project.

View File

@ -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'

View File

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

View File

@ -0,0 +1,14 @@
<h5><%t DMSDocument.RELATED_DOCUMENTS "Related documents" %></h5>
<ul class="documents-relateddocuments">
<% loop $getRelatedDocuments %>
<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
class DMSDocumentTest extends SapphireTest
{
protected static $fixture_file = "dmstest.yml";
protected static $fixture_file = 'dmstest.yml';
public function tearDownOnce()
{
self::$is_running_test = true;
$d = DataObject::get("DMSDocument");
$d = DataObject::get('DMSDocument');
foreach ($d as $d1) {
$d1->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'
);
}
}

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
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