diff --git a/_config/querybuilder.yml b/_config/querybuilder.yml
new file mode 100644
index 0000000..1814ba2
--- /dev/null
+++ b/_config/querybuilder.yml
@@ -0,0 +1,16 @@
+DMSDocument:
+ searchable_fields:
+ Title:
+ title: "Document title matches ..."
+ Description:
+ title: "Document summary matches ..."
+ CreatedByID:
+ title: 'Document created by ...'
+ field: 'ListboxField'
+ filter: 'ExactMatchFilter'
+ LastEditedByID:
+ title: 'Document last changed by ...'
+ field: 'ListboxField'
+ filter: 'ExactMatchFilter'
+ Filename:
+ title: 'File name'
\ No newline at end of file
diff --git a/code/cms/DMSDocumentAddController.php b/code/cms/DMSDocumentAddController.php
index 1258742..799e1be 100644
--- a/code/cms/DMSDocumentAddController.php
+++ b/code/cms/DMSDocumentAddController.php
@@ -120,8 +120,6 @@ class DMSDocumentAddController extends LeftAndMain
_t('DMSDocumentAddController.MAINTAB', 'Main'),
new Tab(
_t('UploadField.FROMCOMPUTER', 'From your computer'),
- new HiddenField('ID', false, $page->ID),
- new HiddenField('DSID', false, $documentSet->ID),
$uploadField,
new LiteralField(
'AllowedExtensions',
@@ -146,6 +144,8 @@ class DMSDocumentAddController extends LeftAndMain
$form->Backlink = $backlink;
// Don't use AssetAdmin_EditForm, as it assumes a different panel structure
$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
+ $form->Fields()->push(HiddenField::create('ID', false, $documentSet->ID));
+ $form->Fields()->push(HiddenField::create('DSID', false, $documentSet->ID));
return $form;
}
diff --git a/code/cms/DMSUploadField.php b/code/cms/DMSUploadField.php
index b926baa..89b65f1 100644
--- a/code/cms/DMSUploadField.php
+++ b/code/cms/DMSUploadField.php
@@ -48,7 +48,7 @@ class DMSUploadField extends UploadField
// Relate to the underlying document set being edited.
// Not applicable when editing the document itself and replacing it, or uploading from the ModelAdmin
if ($record instanceof DMSDocumentSet) {
- $record->Documents()->add($doc);
+ $record->Documents()->add($doc, array('BelongsToSet' => 1));
}
return $doc;
diff --git a/code/forms/JsonField.php b/code/forms/JsonField.php
new file mode 100644
index 0000000..f1269f4
--- /dev/null
+++ b/code/forms/JsonField.php
@@ -0,0 +1,118 @@
+setName($name);
+
+ if ($children instanceof FieldList || is_array($children)) {
+ foreach ($children as $child) {
+ $this->setChildName($child);
+ }
+ } else {
+ $children = is_array(func_get_args()) ? func_get_args() : array();
+ if (!empty($children)) {
+ array_shift($children);
+ }
+ foreach ($children as $child) {
+ $this->setChildName($child);
+ }
+ }
+ parent::__construct($children);
+ }
+
+ /**
+ * Sets the name of the child object
+ *
+ * @param FormField $child
+ */
+ private function setChildName($child)
+ {
+ $child->setName("{$this->getName()}[{$child->getName()}]");
+ }
+
+ public function hasData()
+ {
+ return true;
+ }
+
+ /**
+ * Override parent's behaviour as it's no longer required
+ *
+ * @param array $list
+ * @param bool $saveableOnly
+ */
+ public function collateDataFields(&$list, $saveableOnly = false)
+ {
+ }
+
+ /**
+ * Recursively removed empty key-value pairs from $haystack
+ *
+ * @param $haystack
+ *
+ * @return mixed
+ */
+ public function arrayFilterEmptyRecursive($haystack)
+ {
+ foreach ($haystack as $key => $value) {
+ if (is_array($value)) {
+ $haystack[$key] = $this->arrayFilterEmptyRecursive($haystack[$key]);
+ }
+ if (empty($haystack[$key])) {
+ unset($haystack[$key]);
+ }
+ }
+
+ return $haystack;
+ }
+
+ /**
+ * Overrides parent behaviour to remove empty elements
+ *
+ * @return mixed|null|string
+ */
+ public function dataValue()
+ {
+ $result = null;
+ if (is_array($this->value)) {
+ $this->value = $this->arrayFilterEmptyRecursive($this->value);
+ $result = (!empty($this->value)) ? Convert::array2json($this->value) : $result;
+ } else {
+ $result = parent::dataValue();
+ }
+
+ return $result;
+ }
+
+ /**
+ * Sets
+ * @param mixed $value
+ *
+ * @return $this
+ */
+ public function setValue($value)
+ {
+ $this->value = $value;
+ if (is_string($value) && !empty($value)) {
+ $value = Convert::json2array($value);
+ } elseif (!is_array($value)) {
+ $value = array($value);
+ }
+
+ $pattern = "/^{$this->getName()}\[(.*)\]$/";
+ foreach ($this->children as $c) {
+ $title = $c->getName();
+ preg_match($pattern, $title, $matches);
+ if (!empty($matches[1]) && isset($value[$matches[1]])) {
+ $c->setValue($value[$matches[1]]);
+ }
+ }
+
+ return $this;
+ }
+}
diff --git a/code/model/DMSDocument.php b/code/model/DMSDocument.php
index 001ce27..958c8d4 100644
--- a/code/model/DMSDocument.php
+++ b/code/model/DMSDocument.php
@@ -8,7 +8,6 @@
* @property Varchar Title
* @property Text Description
* @property int ViewCount
- * @property DateTime LastChanged
* @property Boolean EmbargoedIndefinitely
* @property Boolean EmbargoedUntilPublished
* @property DateTime EmbargoedUntilDate
@@ -22,6 +21,11 @@
* @method ManyManyList ViewerGroups
* @method ManyManyList EditorGroups
*
+ * @method Member CreatedBy
+ * @property Int CreatedByID
+ * @method Member LastEditedBy
+ * @property Int LastEditedByID
+ *
*/
class DMSDocument extends DataObject implements DMSDocumentInterface
{
@@ -31,9 +35,6 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
"Title" => 'Varchar(1024)', // eg. "Energy Saving Report for Year 2011, New Zealand LandCorp"
"Description" => 'Text',
"ViewCount" => 'Int',
- // When this document's file was created or last replaced (small changes like updating title don't count)
- "LastChanged" => 'SS_DateTime',
-
"EmbargoedIndefinitely" => 'Boolean(false)',
"EmbargoedUntilPublished" => 'Boolean(false)',
"EmbargoedUntilDate" => 'SS_DateTime',
@@ -47,6 +48,12 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
'Sets' => 'DMSDocumentSet'
);
+ private static $has_one = array(
+ 'CoverImage' => 'Image',
+ 'CreatedBy' => 'Member',
+ 'LastEditedBy' => 'Member',
+ );
+
private static $many_many = array(
'RelatedDocuments' => 'DMSDocument',
'Tags' => 'DMSTag',
@@ -58,23 +65,13 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
'ID' => 'ID',
'Title' => 'Title',
'FilenameWithoutID' => 'Filename',
- 'LastChanged' => 'LastChanged'
+ 'LastEdited' => 'LastEdited'
);
private static $singular_name = 'Document';
private static $plural_name = 'Documents';
- private static $searchable_fields = array(
- 'ID' => array(
- 'filter' => 'ExactMatchFilter',
- 'field' => 'NumericField'
- ),
- 'Title',
- 'Filename',
- 'LastChanged'
- );
-
private static $summary_fields = array(
'Filename' => 'Filename',
'Title' => 'Title',
@@ -122,7 +119,12 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
return true;
}
- if ($member && Permission::checkMember($member, array('ADMIN', 'SITETREE_EDIT_ALL', 'SITETREE_VIEW_ALL'))) {
+ if ($member && Permission::checkMember($member, array(
+ 'ADMIN',
+ 'SITETREE_EDIT_ALL',
+ 'SITETREE_VIEW_ALL',
+ ))
+ ) {
return true;
}
@@ -156,13 +158,14 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
}
// Do early admin check
- if ($member && Permission::checkMember($member,
- array(
+ if ($member && Permission::checkMember(
+ $member,
+ array(
'ADMIN',
'SITETREE_EDIT_ALL',
'SITETREE_VIEW_ALL',
)
- )
+ )
) {
return true;
}
@@ -813,7 +816,6 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
$this->Title = basename($filePath, '.'.$extension);
}
- $this->LastChanged = SS_Datetime::now()->Rfc2822();
$this->write();
return $this;
@@ -906,8 +908,14 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
$fieldsTop = $this->getFieldsForFile($relationList->count());
$fields->add($fieldsTop);
- $fields->add(new TextField('Title', 'Title'));
- $fields->add(new TextareaField('Description', 'Description'));
+ $fields->add(TextField::create('Title', _t('DMSDocument.TITLE', 'Title')));
+ $fields->add(TextareaField::create('Description', _t('DMSDocument.DESCRIPTION', 'Description')));
+
+ $coverImageField = UploadField::create('CoverImage', _t('DMSDocument.COVERIMAGE', 'Cover Image'));
+ $coverImageField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
+ $coverImageField->setConfig('allowedMaxFileNumber', 1);
+ $fields->add($coverImageField);
+
$downloadBehaviorSource = array(
'open' => _t('DMSDocument.OPENINBROWSER', 'Open in browser'),
@@ -984,7 +992,6 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
);
$versionsGridFieldConfig->getComponentByType('GridFieldDataColumns')
->setDisplayFields(Config::inst()->get('DMSDocument_versions', 'display_fields'))
- ->setFieldCasting(array('LastChanged'=>"Datetime->Ago"))
->setFieldFormatting(
array(
'FilenameWithoutID' => ''
@@ -1112,6 +1119,19 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
return CompositeField::create($fields);
}
+ /**
+ * Return a title to use on the frontend, preferably the "title", otherwise the filename without it's numeric ID
+ *
+ * @return string
+ */
+ public function getTitle()
+ {
+ if ($this->getField('Title')) {
+ return $this->getField('Title');
+ }
+ return $this->FilenameWithoutID;
+ }
+
public function onBeforeWrite()
{
parent::onBeforeWrite();
@@ -1120,7 +1140,7 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
//set the embargo options from the OptionSetField created in the getCMSFields method
//do not write after clearing the embargo (write happens automatically)
$savedDate = $this->EmbargoedUntilDate;
- $this->clearEmbargo(false); //clear all previous settings and re-apply them on save
+ $this->clearEmbargo(false); // Clear all previous settings and re-apply them on save
if ($this->Embargo == 'Published') {
$this->embargoUntilPublished(false);
@@ -1138,7 +1158,15 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
$this->expireAtDate($this->ExpireAtDate, false);
} else {
$this->clearExpiry(false);
- } //clear all previous settings
+ } // Clear all previous settings
+ }
+
+ // Set user fields
+ if ($currentUserID = Member::currentUserID()) {
+ if (!$this->CreatedByID) {
+ $this->CreatedByID = $currentUserID;
+ }
+ $this->LastEditedByID = $currentUserID;
}
}
@@ -1266,11 +1294,6 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
_t('AssetTableField.LASTEDIT', 'Last changed') . ':',
$this->LastEdited
),
- new DateField_Disabled(
- "LastChanged",
- _t('AssetTableField.LASTCHANGED', 'Last replaced') . ':',
- $this->LastChanged
- ),
new ReadonlyField("PublishedOn", "Published on". ':', $publishedOnValue),
new ReadonlyField("ReferencedOn", "Referenced on". ':', $relationListCountValue),
new ReadonlyField("ViewCount", "View count". ':', $this->ViewCount)
diff --git a/code/model/DMSDocumentSet.php b/code/model/DMSDocumentSet.php
index 77a5d6b..332d5c9 100644
--- a/code/model/DMSDocumentSet.php
+++ b/code/model/DMSDocumentSet.php
@@ -1,19 +1,34 @@
'Varchar(255)'
+ 'Title' => 'Varchar(255)',
+ 'KeyValuePairs' => 'Text',
+ 'SortBy' => "Enum('LastEdited,Created,Title')')",
+ 'SortByDirection' => "Enum('DESC,ASC')')",
);
private static $has_one = array(
- 'Page' => 'SiteTree'
+ 'Page' => 'SiteTree',
);
private static $many_many = array(
- 'Documents' => 'DMSDocument'
+ 'Documents' => 'DMSDocument',
+ );
+
+ private static $many_many_extraFields = array(
+ 'Documents' => array(
+ 'BelongsToSet' => 'Boolean(1)', // Flag indicating if a document was added directly to a set - in which case it is set - or added via the query-builder.
+ ),
);
/**
@@ -28,14 +43,12 @@ class DMSDocumentSet extends DataObject
* }
*
*
- * @return DataList
+ * @return DataList|null
*/
public function getDocuments()
{
$documents = $this->Documents();
-
$this->extend('updateDocuments', $documents);
-
return $documents;
}
@@ -49,8 +62,11 @@ class DMSDocumentSet extends DataObject
{
// PHP 5.3 only
$self = $this;
-
$this->beforeUpdateCMSFields(function (FieldList $fields) use ($self) {
+ $fields->removeFieldsFromTab(
+ 'Root.Main',
+ array('KeyValuePairs', 'SortBy', 'SortByDirection')
+ );
// Don't put the GridField for documents in until the set has been created
if (!$self->isInDB()) {
$fields->addFieldToTab(
@@ -64,70 +80,67 @@ class DMSDocumentSet extends DataObject
),
'Title'
);
- return;
- }
-
- // Document listing
- $gridFieldConfig = GridFieldConfig::create()
- ->addComponents(
- new GridFieldToolbarHeader(),
- new GridFieldFilterHeader(),
- new GridFieldSortableHeader(),
- // new GridFieldOrderableRows('DocumentSort'),
- new GridFieldDataColumns(),
- new GridFieldEditButton(),
- // Special delete dialog to handle custom behaviour of unlinking and deleting
- new DMSGridFieldDeleteAction(),
- new GridFieldDetailForm()
- );
-
- if (class_exists('GridFieldPaginatorWithShowAll')) {
- $paginatorComponent = new GridFieldPaginatorWithShowAll(15);
} else {
- $paginatorComponent = new GridFieldPaginator(15);
- }
- $gridFieldConfig->addComponent($paginatorComponent);
+ // Document listing
+ $gridFieldConfig = GridFieldConfig::create()
+ ->addComponents(
+ new GridFieldToolbarHeader(),
+ new GridFieldFilterHeader(),
+ new GridFieldSortableHeader(),
+ new GridFieldDataColumns(),
+ new GridFieldEditButton(),
+ // Special delete dialog to handle custom behaviour of unlinking and deleting
+ new DMSGridFieldDeleteAction(),
+ new GridFieldDetailForm()
+ );
- if (class_exists('GridFieldSortableRows')) {
- $sortableComponent = new GridFieldSortableRows('DocumentSort');
- // setUsePagenation method removed from newer version of SortableGridField.
- if (method_exists($sortableComponent, 'setUsePagination')) {
- $sortableComponent->setUsePagination(false)->setForceRedraw(true);
+ if (class_exists('GridFieldPaginatorWithShowAll')) {
+ $paginatorComponent = new GridFieldPaginatorWithShowAll(15);
+ } else {
+ $paginatorComponent = new GridFieldPaginator(15);
}
- $gridFieldConfig->addComponent($sortableComponent);
- }
+ $gridFieldConfig->addComponent($paginatorComponent);
- // HACK: Create a singleton of DMSDocument to ensure extensions are applied before we try to get display fields.
- singleton('DMSDocument');
- $gridFieldConfig->getComponentByType('GridFieldDataColumns')
- ->setDisplayFields(Config::inst()->get('DMSDocument', 'display_fields'))
- ->setFieldCasting(array('LastChanged' => 'Datetime->Ago'))
- ->setFieldFormatting(
- array(
- 'FilenameWithoutID' => '$FilenameWithoutID'
- )
+ if (class_exists('GridFieldSortableRows')) {
+ $sortableComponent = new GridFieldSortableRows('DocumentSort');
+ // setUsePagination method removed from newer version of SortableGridField.
+ if (method_exists($sortableComponent, 'setUsePagination')) {
+ $sortableComponent->setUsePagination(false)->setForceRedraw(true);
+ }
+ $gridFieldConfig->addComponent($sortableComponent);
+ }
+
+ $gridFieldConfig->getComponentByType('GridFieldDataColumns')
+ ->setDisplayFields(DMSDocument::create()->config()->get('display_fields'))
+ ->setFieldCasting(array('LastEdited' => 'Datetime->Ago'))
+ ->setFieldFormatting(
+ array(
+ 'FilenameWithoutID' => '$FilenameWithoutID',
+ )
+ );
+
+ // Override delete functionality with this class
+ $gridFieldConfig->getComponentByType('GridFieldDetailForm')
+ ->setItemRequestClass('DMSGridFieldDetailForm_ItemRequest');
+ $gridField = GridField::create(
+ 'Documents',
+ false,
+ $self->Documents(),
+ $gridFieldConfig
);
+ $gridField->setModelClass('DMSDocument');
+ $gridField->addExtraClass('documents');
- // Override delete functionality with this class
- $gridFieldConfig->getComponentByType('GridFieldDetailForm')
- ->setItemRequestClass('DMSGridFieldDetailForm_ItemRequest');
+ $gridFieldConfig->addComponent(
+ $addNewButton = new DMSGridFieldAddNewButton,
+ 'GridFieldExportButton'
+ );
+ $addNewButton->setDocumentSetId($self->ID);
- $gridField = GridField::create(
- 'Documents',
- false,
- $self->Documents(), //->Sort('DocumentSort'),
- $gridFieldConfig
- );
- $gridField->addExtraClass('documents');
-
- $gridFieldConfig->addComponent(
- $addNewButton = new DMSGridFieldAddNewButton,
- 'GridFieldExportButton'
- );
- $addNewButton->setDocumentSetId($self->ID);
-
- $fields->removeByName('Documents');
- $fields->addFieldToTab('Root.Main', $gridField);
+ $fields->removeByName('Documents');
+ $fields->addFieldToTab('Root.Main', $gridField);
+ $self->addQueryFields($fields);
+ }
});
$this->addRequirements();
return parent::getCMSFields();
@@ -150,4 +163,95 @@ class DMSDocumentSet extends DataObject
return $this;
}
+
+ /**
+ * Adds the query fields to build the document logic to the DMSDocumentSet.
+ *
+ * To extend use the following from within an Extension subclass:
+ *
+ *
+ * public function updateQueryFields($result)
+ * {
+ * // Do something here
+ * }
+ *
+ *
+ * @param FieldList $fields
+ */
+ public function addQueryFields($fields)
+ {
+ /** @var DMSDocument $doc */
+ $doc = singleton('DMSDocument');
+ /** @var FormField $field */
+ $dmsDocFields = $doc->scaffoldSearchFields(array('fieldClasses' => true));
+ $membersMap = Member::get()->map('ID', 'Name')->toArray();
+ asort($membersMap);
+ foreach ($dmsDocFields as $field) {
+ // Apply field customisations where necessary
+ if (in_array($field->getName(), array('CreatedByID', 'LastEditedByID', 'LastEditedByID'))) {
+ /** @var ListboxField $field */
+ $field->setMultiple(true)->setSource($membersMap);
+ }
+ }
+ $keyValPairs = JsonField::create('KeyValuePairs', $dmsDocFields->toArray());
+
+ // Now lastly add the sort fields
+ $sortedBy = FieldGroup::create('SortedBy', array(
+ DropdownField::create('SortBy', '', array(
+ 'LastEdited' => 'Last changed',
+ 'Created' => 'Created',
+ 'Title' => 'Document title',
+ ), 'LastEdited'),
+ DropdownField::create('SortByDirection', '', $this->dbObject('SortByDirection')->enumValues(), 'DESC'),
+ ));
+
+ $sortedBy->setTitle(_t('DMSDocumentSet.SORTED_BY', 'Sort the document set by:'));
+ $fields->addFieldsToTab('Root.QueryBuilder', array($keyValPairs, $sortedBy));
+ $this->extend('updateQueryFields', $fields);
+ }
+
+ public function onBeforeWrite()
+ {
+ parent::onBeforeWrite();
+
+ $this->saveLinkedDocuments();
+ }
+
+ /**
+ * Retrieve a list of the documents in this set. An extension hook is provided before the result is returned.
+ *
+ * @return ArrayList|null
+ */
+ public function saveLinkedDocuments()
+ {
+ // Documents that belong to just this set.
+ /** @var ManyManyList $originals */
+ $originals = $this->Documents();
+ if (!(empty($this->KeyValuePairs)) && $this->isChanged('KeyValuePairs')) {
+ $keyValuesPair = Convert::json2array($this->KeyValuePairs);
+ /** @var DMSDocument $dmsDoc */
+ $dmsDoc = singleton('DMSDocument');
+ $context = $dmsDoc->getDefaultSearchContext();
+
+ $sortBy = $this->SortBy ? $this->SortBy : 'LastEdited';
+ $sortByDirection = $this->SortByDirection ? $this->SortByDirection : 'DESC';
+ $sortedBy = sprintf('%s %s', $sortBy, $sortByDirection);
+ /** @var DataList $documents */
+ $documents = $context->getResults($keyValuesPair, $sortedBy);
+ $now = SS_Datetime::now()->Rfc2822();
+ $documents = $documents->where(
+ "\"EmbargoedIndefinitely\" = 0 AND ".
+ " \"EmbargoedUntilPublished\" = 0 AND ".
+ "(\"EmbargoedUntilDate\" IS NULL OR " .
+ "(\"EmbargoedUntilDate\" IS NOT NULL AND '{$now}' >= \"EmbargoedUntilDate\")) AND " .
+ "\"ExpireAtDate\" IS NULL OR (\"ExpireAtDate\" IS NOT NULL AND '{$now}' < \"ExpireAtDate\")"
+ );
+
+ // Remove all BelongsToSet as the rules have changed
+ $originals->removeByFilter('"BelongsToSet" = 0');
+ foreach ($documents as $document) {
+ $originals->add($document, array('BelongsToSet' => 0));
+ }
+ }
+ }
}
diff --git a/code/model/DMSDocument_versions.php b/code/model/DMSDocument_versions.php
index 450295c..7957e8f 100644
--- a/code/model/DMSDocument_versions.php
+++ b/code/model/DMSDocument_versions.php
@@ -34,7 +34,7 @@ class DMSDocument_versions extends DataObject
private static $display_fields = array(
'VersionCounter' => 'Version Counter',
'FilenameWithoutID' => 'Filename',
- 'LastChanged' => 'Last Changed'
+ 'LastEdited' => 'Last Changed'
);
private static $summary_fields = array(
@@ -47,7 +47,7 @@ class DMSDocument_versions extends DataObject
);
private static $default_sort = array(
- 'LastChanged' => 'DESC'
+ 'LastEdited' => 'DESC'
);
diff --git a/docs/en/configuration.md b/docs/en/configuration.md
index 50fee04..a9a1bf8 100644
--- a/docs/en/configuration.md
+++ b/docs/en/configuration.md
@@ -28,3 +28,31 @@ DMSDocumentAddController:
- php
- php5
```
+
+## Adding fields to the Query Builder
+Query builder fields are read from the DMSDocument::searchable_fields property set in [querybuilder.yml](../../_config/querybuilder.yml). Some default fields are provided and can be customised
+by modifying the field and/or filter properties of a field or adding a new field entirely.
+
+[See here for information](https://docs.silverstripe.org/en/developer_guides/model/searchfilters/) on how to modify search filters and [see here for more information](https://docs.silverstripe.org/en/developer_guides/forms/field_types/common_subclasses/)
+on the field types available.
+
+The default searchable filters available to query builder is as follows:
+
+```yaml
+DMSDocument:
+ searchable_fields:
+ Title:
+ title: "Document title matches ..."
+ Description:
+ title: "Document summary matches ..."
+ CreatedByID:
+ title: 'Document created by ...'
+ field: 'ListboxField'
+ filter: 'ExactMatchFilter'
+ LastEditedByID:
+ title: 'Document last changed by ...'
+ field: 'ListboxField'
+ filter: 'ExactMatchFilter'
+ Filename:
+ title: 'File name'
+```
\ No newline at end of file
diff --git a/lang/en.yml b/lang/en.yml
index 18d5e8e..78d9f4f 100644
--- a/lang/en.yml
+++ b/lang/en.yml
@@ -9,6 +9,8 @@ en:
TYPE: 'File type'
URL: URL
DMSDocument:
+ COVERIMAGE: Cover Image
+ DESCRIPTION: Description
EDIT: Edit
EDITDOCUMENT: Edit this document
PLURALNAME: Documents
@@ -18,6 +20,7 @@ en:
Versions: Versions
DOWNLOAD: "Download {title}"
LASTCHANGED: "Last changed: {date}"
+ TITLE: Title
DMSDocumentSet:
ADDDOCUMENTBUTTON: Add Document
ADDDOCUMENTSBUTTON: Add Documents
diff --git a/templates/Includes/Document.ss b/templates/Includes/Document.ss
index 2428804..a3fe7cf 100644
--- a/templates/Includes/Document.ss
+++ b/templates/Includes/Document.ss
@@ -1,9 +1,11 @@
<% if not $isHidden %>
<% include DocumentDetails %>
diff --git a/templates/Includes/DocumentDetails.ss b/templates/Includes/DocumentDetails.ss index 25a90d7..d9fde11 100644 --- a/templates/Includes/DocumentDetails.ss +++ b/templates/Includes/DocumentDetails.ss @@ -1,4 +1,4 @@ $FilenameWithoutID | $Extension | $FileSizeFormatted -| <%t DMSDocument.LASTCHANGED "Last changed: {date}" date=$LastChanged.Nice %> \ No newline at end of file +| <%t DMSDocument.LASTCHANGED "Last changed: {date}" date=$LastEdited.Nice %> \ No newline at end of file diff --git a/tests/DMSDocumentSetTest.php b/tests/DMSDocumentSetTest.php index 7be996e..22108e5 100644 --- a/tests/DMSDocumentSetTest.php +++ b/tests/DMSDocumentSetTest.php @@ -83,4 +83,57 @@ class DMSDocumentSetTest extends SapphireTest $sortableAssertion = class_exists('GridFieldSortableRows') ? 'assertNotNull' : 'assertNull'; $this->$sortableAssertion($config->getComponentByType('GridFieldSortableRows')); } + + /** + * Test that query fields can be added to the gridfield + */ + public function testAddQueryFields() + { + + /** @var DMSDocumentSet $set */ + $set = $this->objFromFixture('DMSDocumentSet', 'ds6'); + /** @var FieldList $fields */ + $fields = new FieldList(new TabSet('Root')); + /** @var FieldList $fields */ + $set->addQueryFields($fields); + $keyValuePairs = $fields->dataFieldByName('KeyValuePairs'); + $this->assertNotNull( + $keyValuePairs, + 'addQueryFields() includes KeyValuePairs composite field' + ); + $this->assertNotNull( + $keyValuePairs->fieldByName('KeyValuePairs[Title]'), + 'addQueryFields() includes KeyValuePairs composite field' + ); + } + + public function testAddQueryFieldsIsExtensible() + { + + DMSDocumentSet::add_extension('StubDocumentSetMockExtension'); + + $fields = new FieldList(new TabSet('Root')); + $set = new DMSDocumentSet; + $set->addQueryFields($fields); + + $this->assertNotNull( + $fields->dataFieldByName('ExtendedField'), + 'addQueryFields() is extendible as it included the field from the extension' + ); + } + + /** + * Test that extra documents are added after write + */ + public function testSaveLinkedDocuments() + { + /** @var DMSDocumentSet $set */ + $set = $this->objFromFixture('DMSDocumentSet', 'dsSaveLinkedDocuments'); + // Assert initially docs + $this->assertEquals(1, $set->getDocuments()->count(), 'Set has 1 document'); + // Now apply the query and see if 2 extras were added with CreatedByID filter + $set->KeyValuePairs = '{"Filename":"extradoc3"}'; + $set->saveLinkedDocuments(); + $this->assertEquals(2, $set->getDocuments()->count(), 'Set has 2 documents'); + } } diff --git a/tests/DMSDocumentTest.php b/tests/DMSDocumentTest.php index c1a16a3..d010e3f 100644 --- a/tests/DMSDocumentTest.php +++ b/tests/DMSDocumentTest.php @@ -247,4 +247,16 @@ class DMSDocumentTest extends SapphireTest $this->assertCount(3, $result, 'Document 1 is related to 3 Pages'); $this->assertSame(array('s1', 's2', 's3'), $result->column('URLSegment')); } + + /** + * Test that the title is returned if it is set, otherwise the filename without ID + */ + public function testGetTitleOrFilenameWithoutId() + { + $d1 = $this->objFromFixture('DMSDocument', 'd1'); + $this->assertSame('test-file-file-doesnt-exist-1', $d1->getTitle()); + + $d2 = $this->objFromFixture('DMSDocument', 'd2'); + $this->assertSame('File That Doesn\'t Exist (Title)', $d2->getTitle()); + } } diff --git a/tests/JsonFieldTest.php b/tests/JsonFieldTest.php new file mode 100644 index 0000000..5fbf0ec --- /dev/null +++ b/tests/JsonFieldTest.php @@ -0,0 +1,47 @@ +assertEquals($jsonField->FieldList()->count(), 2); + $this->assertNotNull($jsonField->FieldList()->dataFieldByName('MyJsonField[FirstName]')); + + $jsonField = new JsonField('MyJsonField', array(new TextField('FirstName', 'Given name'), + new TextField('Surname', 'Last name'))); + $this->assertEquals($jsonField->FieldList()->count(), 2); + $this->assertNotNull($jsonField->FieldList()->dataFieldByName('MyJsonField[FirstName]')); + + $jsonField = new JsonField( + 'MyJsonField', + new TextField('FirstName', 'Given name'), + new TextField('Surname', 'Last name') + ); + $this->assertEquals($jsonField->FieldList()->count(), 2); + $this->assertNotNull($jsonField->FieldList()->dataFieldByName('MyJsonField[FirstName]')); + } + + public function testJsonFieldDataValueCouldDealWithArray() + { + $jsonField = new JsonField('MyJsonField', new FieldList( + new TextField('FirstName', 'Given name'), + new TextField('Surname', 'Last name') + )); + $jsonField->setValue($value = array( + 'MyJsonField'=>array( + 'FirstName' => 'Normann', + 'Surname' => 'Lou', + ), + )); + + $this->assertEquals($jsonField->dataValue(), Convert::array2json($value)); + $jsonField->setValue($value = array( + 'MyJsonField'=>array(), + )); + $this->assertNull($jsonField->dataValue()); + } +} diff --git a/tests/Stub/StubDocumentSetMockExtension.php b/tests/Stub/StubDocumentSetMockExtension.php new file mode 100644 index 0000000..78dd2e9 --- /dev/null +++ b/tests/Stub/StubDocumentSetMockExtension.php @@ -0,0 +1,24 @@ +addFieldToTab('Root.QueryBuilder', new TextField('ExtendedField')); + + return $fields; + } +} diff --git a/tests/Stub/StubRelatedDocumentExtension.php b/tests/Stub/StubRelatedDocumentExtension.php index 2af3984..38cb39c 100644 --- a/tests/Stub/StubRelatedDocumentExtension.php +++ b/tests/Stub/StubRelatedDocumentExtension.php @@ -1,5 +1,10 @@ SiteTree.s7 + ds6: + Title: Test Set 6 + Page: =>SiteTree.s8 + dsSaveLinkedDocuments: + Title: Test Set 6 + Page: =>SiteTree.s9 DMSDocument: d1: Filename: test-file-file-doesnt-exist-1 @@ -78,6 +90,7 @@ DMSDocument: d2: Filename: test-file-file-doesnt-exist-2 Folder: 5 + Title: File That Doesn't Exist (Title) Tags: =>DMSTag.t5, =>DMSTag.t6 Sets: =>DMSDocumentSet.ds1, =>DMSDocumentSet.ds2, =>DMSDocumentSet.ds3, =>DMSDocumentSet.ds4 document_with_relations: @@ -121,3 +134,23 @@ DMSDocument: EmbargoUntilPublish: true Folder: 5 Sets: =>DMSDocumentSet.ds5 + extraDoc1: + Filename: extradoc1 + Folder: 5 + Sets: =>DMSDocumentSet.ds6 + BelongsToSet: 1 + CreatedByID: 2 + extraDoc2: + Filename: extradoc2 + Folder: 5 + CreatedByID: 2 + BelongsToSet: 0 + extraDoc3: + Filename: extradoc3 + Folder: 5 + BelongsToSet: 0 + CreatedByID: 2 + docSaveLinkedDocuments1: + Filename: saveLinkedDocument1 + Folder: 5 + Sets: =>DMSDocumentSet.dsSaveLinkedDocuments \ No newline at end of file