diff --git a/.gitattributes b/.gitattributes
index 16daf97..a67f2cd 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,4 @@
+/docs export-ignore
/tests export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
diff --git a/README.md b/README.md
index aa82a91..b0a53a6 100644
--- a/README.md
+++ b/README.md
@@ -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
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 .= '
'
));
$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/docs/en/_manifest_exclude b/docs/en/_manifest_exclude
new file mode 100644
index 0000000..e69de29
diff --git a/docs/en/configuration.md b/docs/en/configuration.md
new file mode 100644
index 0000000..01d3199
--- /dev/null
+++ b/docs/en/configuration.md
@@ -0,0 +1,3 @@
+# Configuration
+
+The file location is set via the `DMS::$dmsFolder` static, and points to a location in the webroot.
diff --git a/docs/en/creating-documents.md b/docs/en/creating-documents.md
new file mode 100644
index 0000000..82b7891
--- /dev/null
+++ b/docs/en/creating-documents.md
@@ -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.
diff --git a/docs/en/documents-on-the-filesystem.md b/docs/en/documents-on-the-filesystem.md
new file mode 100644
index 0000000..04f3636
--- /dev/null
+++ b/docs/en/documents-on-the-filesystem.md
@@ -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
+```
diff --git a/docs/en/download-documents.md b/docs/en/download-documents.md
new file mode 100644
index 0000000..dcfbbf9
--- /dev/null
+++ b/docs/en/download-documents.md
@@ -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
+```
diff --git a/docs/en/index.md b/docs/en/index.md
new file mode 100644
index 0000000..eafc027
--- /dev/null
+++ b/docs/en/index.md
@@ -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
diff --git a/docs/en/manage-page-relations.md b/docs/en/manage-page-relations.md
new file mode 100644
index 0000000..d91d444
--- /dev/null
+++ b/docs/en/manage-page-relations.md
@@ -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);
+```
diff --git a/docs/en/manage-related-documents.md b/docs/en/manage-related-documents.md
new file mode 100644
index 0000000..c53719e
--- /dev/null
+++ b/docs/en/manage-related-documents.md
@@ -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) {
+ // ...
+}
+```
diff --git a/docs/en/manage-tags.md b/docs/en/manage-tags.md
new file mode 100644
index 0000000..7b9e51e
--- /dev/null
+++ b/docs/en/manage-tags.md
@@ -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();
+```
diff --git a/docs/en/use-in-templates.md b/docs/en/use-in-templates.md
new file mode 100644
index 0000000..b95e337
--- /dev/null
+++ b/docs/en/use-in-templates.md
@@ -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.
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..d074b01 100644
--- a/templates/Includes/Document.ss
+++ b/templates/Includes/Document.ss
@@ -1,19 +1,18 @@
-<% if isHidden != true %>
-