mirror of
https://github.com/silverstripe/silverstripe-dms
synced 2024-10-22 14:05:56 +02:00
API Add document sets, remove *Page methods from DMSDocument
* Add 2.0.0 changelog * Update DMSInterface and DMSDocumentInterface removing *page and adding getDocumentSetsByPage to DMSInterface * Update use documentation and update unit tests This commit changes the relationship from Pages has_many Documents to Pages has_many DocumentSets which are many_many to Documents. The upload field has been upated to attach documents to a set instead of a page, the tests updated and the DMSInterface and DMSDocumentInterface updated to be less relevant to pages and more relevant to document sets.
This commit is contained in:
parent
9c5693dab0
commit
e4bc553521
5
CONTRIBUTING.md
Normal file
5
CONTRIBUTING.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
Any open source product is only as good as the community behind it. You can participate by sharing code, ideas, or simply helping others. No matter what your skill level is, every contribution counts.
|
||||||
|
|
||||||
|
See our [high level overview](http://silverstripe.org/contributing-to-silverstripe) on silverstripe.org on how you can help out.
|
@ -2,14 +2,10 @@
|
|||||||
|
|
||||||
$config = Config::inst();
|
$config = Config::inst();
|
||||||
|
|
||||||
DMSSiteTreeExtension::show_documents_tab(); //show the Documents tab on all pages
|
define('DMS_DIR', basename(__DIR__));
|
||||||
DMSSiteTreeExtension::no_documents_tab(); //and don't exclude it from any pages
|
|
||||||
DMSDocumentAddController::add_allowed_extensions(); //add an array of additional allowed extensions
|
|
||||||
|
|
||||||
define('DMS_DIR', 'dms');
|
|
||||||
|
|
||||||
if (!file_exists(BASE_PATH . DIRECTORY_SEPARATOR . DMS_DIR)) {
|
if (!file_exists(BASE_PATH . DIRECTORY_SEPARATOR . DMS_DIR)) {
|
||||||
user_error("DMS directory named incorrectly. Please install the DMS module into a folder named: ".DMS_DIR);
|
user_error('DMS directory named incorrectly. Please install the DMS module into a folder named: ' . DMS_DIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMSMenu::remove_menu_item('DMSDocumentAddController');
|
CMSMenu::remove_menu_item('DMSDocumentAddController');
|
||||||
|
@ -5,11 +5,16 @@ After: framework/routes#coreroutes
|
|||||||
Director:
|
Director:
|
||||||
rules:
|
rules:
|
||||||
'dmsdocument/$ID' : 'DMSDocument_Controller'
|
'dmsdocument/$ID' : 'DMSDocument_Controller'
|
||||||
|
|
||||||
SiteTree:
|
SiteTree:
|
||||||
extensions:
|
extensions:
|
||||||
- DMSSiteTreeExtension
|
- DMSSiteTreeExtension
|
||||||
|
# Whether to show the document sets tab in the CMS for the page type this extension is applied to
|
||||||
|
documents_enabled: true
|
||||||
|
|
||||||
HtmlEditorField_Toolbar:
|
HtmlEditorField_Toolbar:
|
||||||
extensions:
|
extensions:
|
||||||
- DocumentHtmlEditorFieldToolbar
|
- DocumentHtmlEditorFieldToolbar
|
||||||
|
|
||||||
DMSDocument_versions:
|
DMSDocument_versions:
|
||||||
enable_versions: true
|
enable_versions: true
|
||||||
|
26
code/DMS.php
26
code/DMS.php
@ -126,15 +126,25 @@ class DMS implements DMSInterface
|
|||||||
// TODO: Implement getByFullTextSearch() method.
|
// TODO: Implement getByFullTextSearch() method.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getByPage(SiteTree $page, $showEmbargoed = false)
|
||||||
* Returns a list of Document objects associated with a Page
|
|
||||||
* @param $page SiteTree to fetch the associated Documents from
|
|
||||||
* @param bool $showEmbargoed Boolean that specifies if embargoed documents should be included in results
|
|
||||||
* @return DataList Document list associated with the Page
|
|
||||||
*/
|
|
||||||
public function getByPage($page, $showEmbargoed = false)
|
|
||||||
{
|
{
|
||||||
// TODO: Implement getByPage() method.
|
/** @var ArrayList $documents */
|
||||||
|
$documents = $page->getAllDocuments();
|
||||||
|
|
||||||
|
if (!$showEmbargoed) {
|
||||||
|
foreach ($documents as $document) {
|
||||||
|
if ($document->isEmbargoed()) {
|
||||||
|
$documents->remove($document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $documents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDocumentSetsByPage(SiteTree $page)
|
||||||
|
{
|
||||||
|
return $page->getDocumentSets();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
class DMSDocumentAddController extends LeftAndMain
|
class DMSDocumentAddController extends LeftAndMain
|
||||||
{
|
{
|
||||||
|
|
||||||
private static $url_segment = 'pages/adddocument';
|
private static $url_segment = 'pages/adddocument';
|
||||||
private static $url_priority = 60;
|
private static $url_priority = 60;
|
||||||
private static $required_permission_codes = 'CMS_ACCESS_AssetAdmin';
|
private static $required_permission_codes = 'CMS_ACCESS_AssetAdmin';
|
||||||
@ -13,7 +12,13 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
private static $tree_class = 'SiteTree';
|
private static $tree_class = 'SiteTree';
|
||||||
private static $session_namespace = 'CMSMain';
|
private static $session_namespace = 'CMSMain';
|
||||||
|
|
||||||
public static $allowed_extensions = array();
|
/**
|
||||||
|
* Allowed file upload extensions, will be merged with `$allowed_extensions` from {@link File}
|
||||||
|
*
|
||||||
|
* @config
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $allowed_extensions = array();
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'getEditForm',
|
'getEditForm',
|
||||||
@ -22,27 +27,10 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
'documentlist'
|
'documentlist'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an array of additional allowed extensions
|
|
||||||
* @static
|
|
||||||
* @param $array
|
|
||||||
*/
|
|
||||||
public static function add_allowed_extensions($array = null)
|
|
||||||
{
|
|
||||||
if (empty($array)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (is_array($array)) {
|
|
||||||
self::$allowed_extensions = $array;
|
|
||||||
} else {
|
|
||||||
self::$allowed_extensions = array($array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom currentPage() method to handle opening the 'root' folder
|
* Custom currentPage() method to handle opening the 'root' folder
|
||||||
*
|
*
|
||||||
* @return
|
* @return SiteTree
|
||||||
*/
|
*/
|
||||||
public function currentPage()
|
public function currentPage()
|
||||||
{
|
{
|
||||||
@ -61,12 +49,27 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return fake-ID "root" if no ID is found (needed to upload files into the root-folder)
|
* Return fake-ID "root" if no ID is found (needed to upload files into the root-folder)
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function currentPageID()
|
public function currentPageID()
|
||||||
{
|
{
|
||||||
return ($result = parent::currentPageID()) === null ? 0 : $result;
|
return ($result = parent::currentPageID()) === null ? 0 : $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current document set, if a document set ID was provided
|
||||||
|
*
|
||||||
|
* @return DMSDocumentSet
|
||||||
|
*/
|
||||||
|
public function getCurrentDocumentSet()
|
||||||
|
{
|
||||||
|
if ($id = $this->getRequest()->getVar('dsid')) {
|
||||||
|
return DMSDocumentSet::get()->byid($id);
|
||||||
|
}
|
||||||
|
return singleton('DMSDocumentSet');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Form
|
* @return Form
|
||||||
* @todo what template is used here? AssetAdmin_UploadContent.ss doesn't seem to be used anymore
|
* @todo what template is used here? AssetAdmin_UploadContent.ss doesn't seem to be used anymore
|
||||||
@ -75,9 +78,13 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
{
|
{
|
||||||
Requirements::javascript(FRAMEWORK_DIR . '/javascript/AssetUploadField.js');
|
Requirements::javascript(FRAMEWORK_DIR . '/javascript/AssetUploadField.js');
|
||||||
Requirements::css(FRAMEWORK_DIR . '/css/AssetUploadField.css');
|
Requirements::css(FRAMEWORK_DIR . '/css/AssetUploadField.css');
|
||||||
Requirements::css(DMS_DIR.'/css/DMSMainCMS.css');
|
Requirements::css(DMS_DIR . '/css/DMSMainCMS.css');
|
||||||
|
|
||||||
|
/** @var SiteTree $page */
|
||||||
$page = $this->currentPage();
|
$page = $this->currentPage();
|
||||||
|
/** @var DMSDocumentSet $documentSet */
|
||||||
|
$documentSet = $this->getCurrentDocumentSet();
|
||||||
|
|
||||||
$uploadField = DMSUploadField::create('AssetUploadField', '');
|
$uploadField = DMSUploadField::create('AssetUploadField', '');
|
||||||
$uploadField->setConfig('previewMaxWidth', 40);
|
$uploadField->setConfig('previewMaxWidth', 40);
|
||||||
$uploadField->setConfig('previewMaxHeight', 30);
|
$uploadField->setConfig('previewMaxHeight', 30);
|
||||||
@ -87,31 +94,34 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
$uploadField->addExtraClass('ss-assetuploadfield');
|
$uploadField->addExtraClass('ss-assetuploadfield');
|
||||||
$uploadField->removeExtraClass('ss-uploadfield');
|
$uploadField->removeExtraClass('ss-uploadfield');
|
||||||
$uploadField->setTemplate('AssetUploadField');
|
$uploadField->setTemplate('AssetUploadField');
|
||||||
$uploadField->setRecord($page);
|
$uploadField->setRecord($documentSet);
|
||||||
|
|
||||||
$uploadField->getValidator()->setAllowedExtensions(
|
$uploadField->getValidator()->setAllowedExtensions($this->getAllowedExtensions());
|
||||||
array_filter(array_merge(Config::inst()->get('File', 'allowed_extensions'), self::$allowed_extensions))
|
|
||||||
);
|
|
||||||
$exts = $uploadField->getValidator()->getAllowedExtensions();
|
$exts = $uploadField->getValidator()->getAllowedExtensions();
|
||||||
|
|
||||||
asort($exts);
|
asort($exts);
|
||||||
$backlink = $this->Backlink();
|
$backlink = $this->Backlink();
|
||||||
$done = "
|
$done = "
|
||||||
<a class=\"ss-ui-button ss-ui-action-constructive cms-panel-link ui-corner-all\" href=\"".$backlink."\">
|
<a class=\"ss-ui-button ss-ui-action-constructive cms-panel-link ui-corner-all\" href=\"" . $backlink . "\">
|
||||||
Done!
|
" . _t('UploadField.DONE', 'DONE') . "
|
||||||
</a>";
|
</a>";
|
||||||
|
|
||||||
$addExistingField = new DMSDocumentAddExistingField('AddExisting', 'Add Existing');
|
$addExistingField = new DMSDocumentAddExistingField(
|
||||||
$addExistingField->setRecord($page);
|
'AddExisting',
|
||||||
|
_t('DMSDocumentAddExistingField.ADDEXISTING', 'Add Existing')
|
||||||
|
);
|
||||||
|
$addExistingField->setRecord($documentSet);
|
||||||
|
|
||||||
$form = new Form(
|
$form = new Form(
|
||||||
$this,
|
$this,
|
||||||
'getEditForm',
|
'getEditForm',
|
||||||
new FieldList(
|
new FieldList(
|
||||||
new TabSet(
|
new TabSet(
|
||||||
'Main',
|
_t('DMSDocumentAddController.MAINTAB', 'Main'),
|
||||||
new Tab(
|
new Tab(
|
||||||
'From your computer',
|
_t('UploadField.FROMCOMPUTER', 'From your computer'),
|
||||||
new HiddenField('ID', false, $page->ID),
|
new HiddenField('ID', false, $page->ID),
|
||||||
|
new HiddenField('DSID', false, $documentSet->ID),
|
||||||
$uploadField,
|
$uploadField,
|
||||||
new LiteralField(
|
new LiteralField(
|
||||||
'AllowedExtensions',
|
'AllowedExtensions',
|
||||||
@ -123,7 +133,7 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
new Tab(
|
new Tab(
|
||||||
'From the CMS',
|
_t('UploadField.FROMCMS', 'From the CMS'),
|
||||||
$addExistingField
|
$addExistingField
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -136,17 +146,6 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
$form->Backlink = $backlink;
|
$form->Backlink = $backlink;
|
||||||
// Don't use AssetAdmin_EditForm, as it assumes a different panel structure
|
// Don't use AssetAdmin_EditForm, as it assumes a different panel structure
|
||||||
$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
|
$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
|
||||||
/*$form->Fields()->push(
|
|
||||||
new LiteralField(
|
|
||||||
'BackLink',
|
|
||||||
sprintf(
|
|
||||||
'<a href="%s" class="backlink ss-ui-button cms-panel-link" data-icon="back">%s</a>',
|
|
||||||
Controller::join_links(singleton('AssetAdmin')->Link('show'), $folder ? $folder->ID : 0),
|
|
||||||
_t('AssetAdmin.BackToFolder', 'Back to folder')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);*/
|
|
||||||
//$form->loadDataFrom($folder);
|
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
@ -170,29 +169,43 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
}
|
}
|
||||||
|
|
||||||
$items->push(new ArrayData(array(
|
$items->push(new ArrayData(array(
|
||||||
'Title' => 'Add Document',
|
'Title' => _t('DMSDocumentSet.ADDDOCUMENTBUTTON', 'Add Document'),
|
||||||
'Link' => $this->Link()
|
'Link' => $this->Link()
|
||||||
)));
|
)));
|
||||||
|
|
||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the link to be used to return the user after uploading a document. If a document set ID (dsid) is present
|
||||||
|
* then it will be redirected back to the page that owns the document set. @todo redirect back to the document set
|
||||||
|
*
|
||||||
|
* If no document set ID is present then we assume that it has been added from the model admin, so redirect back to
|
||||||
|
* that instead.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function Backlink()
|
public function Backlink()
|
||||||
{
|
{
|
||||||
$pageID = $this->currentPageID();
|
if (!$this->getRequest()->getVar('dsid')) {
|
||||||
return Controller::join_links(singleton('CMSPagesController')->Link(), 'edit/show', $pageID);
|
$modelAdmin = new DMSDocumentAdmin;
|
||||||
|
$modelAdmin->init();
|
||||||
|
return $modelAdmin->Link();
|
||||||
|
}
|
||||||
|
return Controller::join_links(singleton('CMSPagesController')->Link(), 'edit/show', $this->currentPageID());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function documentautocomplete()
|
public function documentautocomplete()
|
||||||
{
|
{
|
||||||
$term = (isset($_GET['term'])) ? $_GET['term'] : '';
|
$term = (string) $this->getRequest()->getVar('term');
|
||||||
$term_sql = Convert::raw2sql($term);
|
$termSql = Convert::raw2sql($term);
|
||||||
$data = DMSDocument::get()
|
$data = DMSDocument::get()
|
||||||
->where(
|
->where(
|
||||||
"(\"ID\" LIKE '%".$term_sql."%' OR \"Filename\" LIKE '%".$term_sql."%' OR \"Title\" LIKE '%".$term_sql."%')"
|
'("ID" LIKE \'%' . $termSql . '%\' OR "Filename" LIKE \'%' . $termSql . '%\''
|
||||||
)
|
. ' OR "Title" LIKE \'%' . $termSql . '%\')'
|
||||||
->sort('ID ASC')
|
)
|
||||||
->limit(20);
|
->sort('ID ASC')
|
||||||
|
->limit(20);
|
||||||
|
|
||||||
$return = array();
|
$return = array();
|
||||||
foreach ($data as $doc) {
|
foreach ($data as $doc) {
|
||||||
@ -202,22 +215,24 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Convert::raw2json($return);
|
||||||
return json_encode($return);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function linkdocument()
|
public function linkdocument()
|
||||||
{
|
{
|
||||||
$return = array('error' => _t('UploadField.FIELDNOTSET', 'Could not add document to page'));
|
$return = array('error' => _t('UploadField.FIELDNOTSET', 'Could not add document to page'));
|
||||||
|
$return = array('error' => 'testing');
|
||||||
|
return Convert::raw2json($return);
|
||||||
$page = $this->currentPage();
|
$page = $this->currentPage();
|
||||||
if (!empty($page)) {
|
if (!empty($page)) {
|
||||||
$document = DataObject::get_by_id('DMSDocument', (int) $_GET['documentID']);
|
$document = DMSDocument::get()->byId($this->getRequest()->getVar('documentID'));
|
||||||
|
// @todo add sets
|
||||||
$document->addPage($page);
|
$document->addPage($page);
|
||||||
|
|
||||||
$buttonText = '<button class="ss-uploadfield-item-edit ss-ui-button ui-corner-all"'
|
$buttonText = '<button class="ss-uploadfield-item-edit ss-ui-button ui-corner-all"'
|
||||||
. ' title="Edit this document" data-icon="pencil">'
|
. ' title="' . _t('DMSDocument.EDITDOCUMENT', 'Edit this document') . '" data-icon="pencil">'
|
||||||
. 'Edit<span class="toggle-details"><span class="toggle-details-icon"></span></span></button>';
|
. _t('DMSDocument.EDIT', 'Edit') . '<span class="toggle-details">'
|
||||||
|
. '<span class="toggle-details-icon"></span></span></button>';
|
||||||
|
|
||||||
// Collect all output data.
|
// Collect all output data.
|
||||||
$return = array(
|
$return = array(
|
||||||
@ -232,21 +247,27 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return json_encode($return);
|
return Convert::raw2json($return);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns HTML representing a list of documents that are associated with the given page ID, across all document
|
||||||
|
* sets.
|
||||||
|
*
|
||||||
|
* @return string HTML
|
||||||
|
*/
|
||||||
public function documentlist()
|
public function documentlist()
|
||||||
{
|
{
|
||||||
if (!isset($_GET['pageID'])) {
|
if (!$this->getRequest()->getVar('pageID')) {
|
||||||
return $this->httpError(400);
|
return $this->httpError(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = SiteTree::get()->byId($_GET['pageID']);
|
$page = SiteTree::get()->byId($this->getRequest()->getVar('pageID'));
|
||||||
|
|
||||||
if ($page && $page->Documents()->count() > 0) {
|
if ($page && $page->getAllDocuments()->count() > 0) {
|
||||||
$list = '<ul>';
|
$list = '<ul>';
|
||||||
|
|
||||||
foreach ($page->Documents() as $document) {
|
foreach ($page->getAllDocuments() as $document) {
|
||||||
$list .= sprintf(
|
$list .= sprintf(
|
||||||
'<li><a class="add-document" data-document-id="%s">%s</a></li>',
|
'<li><a class="add-document" data-document-id="%s">%s</a></li>',
|
||||||
$document->ID,
|
$document->ID,
|
||||||
@ -264,4 +285,20 @@ class DMSDocumentAddController extends LeftAndMain
|
|||||||
_t('DMSDocumentAddController.NODOCUMENTS', 'There are no documents attached to the selected page.')
|
_t('DMSDocumentAddController.NODOCUMENTS', 'There are no documents attached to the selected page.')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an array of allowed file upload extensions, merged with {@link File} and extra configuration from this
|
||||||
|
* class
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAllowedExtensions()
|
||||||
|
{
|
||||||
|
return array_filter(
|
||||||
|
array_merge(
|
||||||
|
(array) Config::inst()->get('File', 'allowed_extensions'),
|
||||||
|
(array) $this->config()->get('allowed_extensions')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
class DMSGridFieldAddNewButton extends GridFieldAddNewButton implements GridField_HTMLProvider
|
class DMSGridFieldAddNewButton extends GridFieldAddNewButton implements GridField_HTMLProvider
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The page ID that the document should be attached to. Used in the GridField for Documents in a Page.
|
* The document set ID that the document should be attached to
|
||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
protected $pageId;
|
protected $documentSetId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overriding the parent method to change the template that the DMS add button will be rendered with
|
* Overriding the parent method to change the template that the DMS add button will be rendered with
|
||||||
@ -30,8 +30,8 @@ class DMSGridFieldAddNewButton extends GridFieldAddNewButton implements GridFiel
|
|||||||
}
|
}
|
||||||
|
|
||||||
$link = singleton('DMSDocumentAddController')->Link();
|
$link = singleton('DMSDocumentAddController')->Link();
|
||||||
if ($this->getPageId()) {
|
if ($this->getDocumentSetId()) {
|
||||||
$link = Controller::join_links($link, '?ID=' . $this->getPageId());
|
$link = Controller::join_links($link, '?dsid=' . $this->getDocumentSetId());
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = new ArrayData(array(
|
$data = new ArrayData(array(
|
||||||
@ -45,24 +45,24 @@ class DMSGridFieldAddNewButton extends GridFieldAddNewButton implements GridFiel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the page ID that this document should be attached to
|
* Set the document set ID that this document should be attached to
|
||||||
*
|
*
|
||||||
* @param int $id
|
* @param int $id
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setPageId($id)
|
public function setDocumentSetId($id)
|
||||||
{
|
{
|
||||||
$this->pageId = $id;
|
$this->documentSetId = $id;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the page ID that this document should be attached to
|
* Get the document set ID that this document should be attached to
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getPageId()
|
public function getDocumentSetId()
|
||||||
{
|
{
|
||||||
return $this->pageId;
|
return $this->documentSetId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ class DMSGridFieldDeleteAction extends GridFieldDeleteAction implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a class to the field to if it is the last gridfield in the list
|
// Add a class to the field to if it is the last gridfield in the list
|
||||||
$numberOfRelations = $record->Pages()->Count();
|
$numberOfRelations = $record->getRelatedPages()->count();
|
||||||
$field
|
$field
|
||||||
// Add a new class for custom JS to handle the delete action
|
// Add a new class for custom JS to handle the delete action
|
||||||
->addExtraClass('dms-delete')
|
->addExtraClass('dms-delete')
|
||||||
|
@ -13,7 +13,7 @@ class DMSGridFieldDetailForm_ItemRequest extends GridFieldDetailForm_ItemRequest
|
|||||||
|
|
||||||
//add a data attribute specifying how many pages this document is referenced on
|
//add a data attribute specifying how many pages this document is referenced on
|
||||||
if ($record = $this->record) {
|
if ($record = $this->record) {
|
||||||
$numberOfPageRelations = $record->Pages()->Count();
|
$numberOfPageRelations = $record->getRelatedPages()->Count();
|
||||||
$relations = new ShortCodeRelationFinder();
|
$relations = new ShortCodeRelationFinder();
|
||||||
$numberOfInlineRelations = $relations->findPageCount($record->ID);
|
$numberOfInlineRelations = $relations->findPageCount($record->ID);
|
||||||
|
|
||||||
|
@ -18,17 +18,12 @@ class DMSUploadField extends UploadField
|
|||||||
"upload",
|
"upload",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The temporary folder name to store files in during upload
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $folderName = 'DMSTemporaryUploads';
|
protected $folderName = 'DMSTemporaryUploads';
|
||||||
|
|
||||||
public function __construct($name, $title = null, SS_List $items = null)
|
|
||||||
{
|
|
||||||
parent::__construct($name, $title, $items);
|
|
||||||
|
|
||||||
//set default DMS replace template to false
|
|
||||||
$this->setConfig('useDMSReplaceTemplate', 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the default behaviour of the UploadField and take the uploaded file (uploaded to assets) and
|
* Override the default behaviour of the UploadField and take the uploaded file (uploaded to assets) and
|
||||||
* add it into the DMS storage, deleting the old/uploaded file.
|
* add it into the DMS storage, deleting the old/uploaded file.
|
||||||
@ -48,9 +43,12 @@ class DMSUploadField extends UploadField
|
|||||||
// Otherwise create it
|
// Otherwise create it
|
||||||
$doc = $dms->storeDocument($file);
|
$doc = $dms->storeDocument($file);
|
||||||
$file->delete();
|
$file->delete();
|
||||||
// Relate to the underlying page being edited.
|
}
|
||||||
// Not applicable when editing the document itself and replacing it.
|
|
||||||
$doc->addPage($record);
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $doc;
|
return $doc;
|
||||||
@ -61,17 +59,6 @@ class DMSUploadField extends UploadField
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function isDisabled()
|
|
||||||
{
|
|
||||||
return (parent::isDisabled() || !$this->isSaveable());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isSaveable()
|
|
||||||
{
|
|
||||||
return (!empty($this->getRecord()->ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to handle upload of a single file
|
* Action to handle upload of a single file
|
||||||
*
|
*
|
||||||
@ -80,6 +67,10 @@ class DMSUploadField extends UploadField
|
|||||||
*/
|
*/
|
||||||
public function upload(SS_HTTPRequest $request)
|
public function upload(SS_HTTPRequest $request)
|
||||||
{
|
{
|
||||||
|
if ($recordId = $request->postVar('ID')) {
|
||||||
|
$this->setRecord(DMSDocumentSet::get()->byId($recordId));
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->isDisabled() || $this->isReadonly()) {
|
if ($this->isDisabled() || $this->isReadonly()) {
|
||||||
return $this->httpError(403);
|
return $this->httpError(403);
|
||||||
}
|
}
|
||||||
@ -110,13 +101,13 @@ class DMSUploadField extends UploadField
|
|||||||
if (!$return['error'] && $this->relationAutoSetting && $record && $record->exists()) {
|
if (!$return['error'] && $this->relationAutoSetting && $record && $record->exists()) {
|
||||||
$tooManyFiles = false;
|
$tooManyFiles = false;
|
||||||
// Some relationships allow many files to be attached.
|
// Some relationships allow many files to be attached.
|
||||||
if ($this->getConfig('allowedMaxFileNumber') && ($record->has_many($name) || $record->many_many($name))) {
|
if ($this->getConfig('allowedMaxFileNumber') && ($record->hasMany($name) || $record->manyMany($name))) {
|
||||||
if (!$record->isInDB()) {
|
if (!$record->isInDB()) {
|
||||||
$record->write();
|
$record->write();
|
||||||
}
|
}
|
||||||
$tooManyFiles = $record->{$name}()->count() >= $this->getConfig('allowedMaxFileNumber');
|
$tooManyFiles = $record->{$name}()->count() >= $this->getConfig('allowedMaxFileNumber');
|
||||||
// has_one only allows one file at any given time.
|
// has_one only allows one file at any given time.
|
||||||
} elseif ($record->has_one($name)) {
|
} elseif ($record->hasOne($name)) {
|
||||||
$tooManyFiles = $record->{$name}() && $record->{$name}()->exists();
|
$tooManyFiles = $record->{$name}() && $record->{$name}()->exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +138,7 @@ class DMSUploadField extends UploadField
|
|||||||
|
|
||||||
// Get the uploaded file into a new file object.
|
// Get the uploaded file into a new file object.
|
||||||
try {
|
try {
|
||||||
$this->upload->loadIntoFile($tmpfile, $fileObject, $this->folderName);
|
$this->upload->loadIntoFile($tmpfile, $fileObject, $this->getFolderName());
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
// we shouldn't get an error here, but just in case
|
// we shouldn't get an error here, but just in case
|
||||||
$return['error'] = $e->getMessage();
|
$return['error'] = $e->getMessage();
|
||||||
@ -155,7 +146,7 @@ class DMSUploadField extends UploadField
|
|||||||
|
|
||||||
if (!$return['error']) {
|
if (!$return['error']) {
|
||||||
if ($this->upload->isError()) {
|
if ($this->upload->isError()) {
|
||||||
$return['error'] = implode(' '.PHP_EOL, $this->upload->getErrors());
|
$return['error'] = implode(' ' . PHP_EOL, $this->upload->getErrors());
|
||||||
} else {
|
} else {
|
||||||
$file = $this->upload->getFile();
|
$file = $this->upload->getFile();
|
||||||
|
|
||||||
@ -198,10 +189,10 @@ class DMSUploadField extends UploadField
|
|||||||
|
|
||||||
// Replace the download template with a new one only when access the upload field through a GridField.
|
// Replace the download template with a new one only when access the upload field through a GridField.
|
||||||
// Needs to be enabled through setConfig('downloadTemplateName', 'ss-dmsuploadfield-downloadtemplate');
|
// Needs to be enabled through setConfig('downloadTemplateName', 'ss-dmsuploadfield-downloadtemplate');
|
||||||
Requirements::javascript('dms/javascript/DMSUploadField_downloadtemplate.js');
|
Requirements::javascript(DMS_DIR . '/javascript/DMSUploadField_downloadtemplate.js');
|
||||||
|
|
||||||
// In the add dialog, add the addtemplate into the set of file that load.
|
// In the add dialog, add the addtemplate into the set of file that load.
|
||||||
Requirements::javascript('dms/javascript/DMSUploadField_addtemplate.js');
|
Requirements::javascript(DMS_DIR . '/javascript/DMSUploadField_addtemplate.js');
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
@ -305,4 +296,26 @@ class DMSUploadField extends UploadField
|
|||||||
|
|
||||||
user_error("Invalid value for UploadField::fileEditValidator", E_USER_ERROR);
|
user_error("Invalid value for UploadField::fileEditValidator", E_USER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the folder name to store DMS files in
|
||||||
|
*
|
||||||
|
* @param string $folderName
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setFolderName($folderName)
|
||||||
|
{
|
||||||
|
$this->folderName = (string) $folderName;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the folder name for storing the document
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFolderName()
|
||||||
|
{
|
||||||
|
return $this->folderName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,14 @@ class DMSUploadField_ItemHandler extends UploadField_ItemHandler
|
|||||||
'EditForm',
|
'EditForm',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a DMS document by its ID
|
||||||
|
*
|
||||||
|
* @return DMSDocument
|
||||||
|
*/
|
||||||
public function getItem()
|
public function getItem()
|
||||||
{
|
{
|
||||||
return DataObject::get_by_id('DMSDocument', $this->itemID);
|
return DMSDocument::get()->byId($this->itemID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,136 +5,56 @@
|
|||||||
*/
|
*/
|
||||||
class DMSSiteTreeExtension extends DataExtension
|
class DMSSiteTreeExtension extends DataExtension
|
||||||
{
|
{
|
||||||
|
private static $has_many = array(
|
||||||
private static $belongs_many_many = array(
|
'DocumentSets' => 'DMSDocumentSet'
|
||||||
'Documents' => 'DMSDocument'
|
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $noDocumentsList = array();
|
|
||||||
|
|
||||||
private static $showDocumentsList = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do not show the documents tab on the array of pages set here
|
|
||||||
* @static
|
|
||||||
* @param $mixed Array of page types to not show the Documents tab on
|
|
||||||
*/
|
|
||||||
public static function no_documents_tab($array = array())
|
|
||||||
{
|
|
||||||
if (empty($array)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (is_array($array)) {
|
|
||||||
self::$noDocumentsList = $array;
|
|
||||||
} else {
|
|
||||||
self::$noDocumentsList = array($array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only show the documents tab on the list of pages set here. Any pages set in the no_documents_tab array will
|
|
||||||
* still not be shown. If this isn't called, or if it is called with an empty array, all pages will get
|
|
||||||
* Document tabs.
|
|
||||||
* @static
|
|
||||||
* @param $array Array of page types to show the Documents tab on
|
|
||||||
*/
|
|
||||||
public static function show_documents_tab($array = array())
|
|
||||||
{
|
|
||||||
if (empty($array)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (is_array($array)) {
|
|
||||||
self::$showDocumentsList = $array;
|
|
||||||
} else {
|
|
||||||
self::$showDocumentsList = array($array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateCMSFields(FieldList $fields)
|
public function updateCMSFields(FieldList $fields)
|
||||||
{
|
{
|
||||||
// Prevent certain pages from having a Document tab in the CMS
|
// Ability to disable document sets for a Page
|
||||||
if (in_array($this->owner->ClassName, self::$noDocumentsList)) {
|
if (!$this->owner->config()->get('documents_enabled')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (count(self::$showDocumentsList) > 0 && !in_array($this->owner->ClassName, self::$showDocumentsList)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Javascript to customize the grid field for the DMS document (overriding entwine
|
|
||||||
// in FRAMEWORK_DIR.'/javascript/GridField.js'
|
|
||||||
Requirements::javascript(DMS_DIR.'/javascript/DMSGridField.js');
|
|
||||||
Requirements::css(DMS_DIR.'/css/DMSMainCMS.css');
|
|
||||||
|
|
||||||
// Javascript for the link editor pop-up in TinyMCE
|
|
||||||
Requirements::javascript(DMS_DIR."/javascript/DocumentHtmlEditorFieldToolbar.js");
|
|
||||||
|
|
||||||
// Document listing
|
|
||||||
$gridFieldConfig = GridFieldConfig::create()->addComponents(
|
|
||||||
new GridFieldToolbarHeader(),
|
|
||||||
new GridFieldFilterHeader(),
|
|
||||||
new GridFieldSortableHeader(),
|
|
||||||
new GridFieldOrderableRows('DocumentSort'),
|
|
||||||
new GridFieldDataColumns(),
|
|
||||||
new GridFieldEditButton(),
|
|
||||||
new DMSGridFieldDeleteAction(), //special delete dialog to handle custom behaviour of unlinking and deleting
|
|
||||||
new GridFieldDetailForm()
|
|
||||||
//GridFieldLevelup::create($folder->ID)->setLinkSpec('admin/assets/show/%d')
|
|
||||||
);
|
|
||||||
|
|
||||||
if (class_exists('GridFieldPaginatorWithShowAll')) {
|
|
||||||
$paginatorComponent = new GridFieldPaginatorWithShowAll(15);
|
|
||||||
} else {
|
|
||||||
$paginatorComponent = new GridFieldPaginator(15);
|
|
||||||
}
|
|
||||||
$gridFieldConfig->addComponent($paginatorComponent);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
$gridFieldConfig->addComponent($sortableComponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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'=>'<a target=\'_blank\' class=\'file-url\' href=\'$Link\'>$FilenameWithoutID</a>'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
//override delete functionality with this class
|
|
||||||
$gridFieldConfig->getComponentByType('GridFieldDetailForm')
|
|
||||||
->setItemRequestClass('DMSGridFieldDetailForm_ItemRequest');
|
|
||||||
|
|
||||||
$gridField = GridField::create(
|
$gridField = GridField::create(
|
||||||
'Documents',
|
'Document Sets',
|
||||||
false,
|
false,
|
||||||
$this->owner->Documents()->Sort('DocumentSort'),
|
$this->owner->DocumentSets(), //->Sort('DocumentSort'),
|
||||||
$gridFieldConfig
|
new GridFieldConfig_RelationEditor
|
||||||
);
|
);
|
||||||
$gridField->addExtraClass('documents');
|
$gridField->addExtraClass('documentsets');
|
||||||
|
|
||||||
$gridFieldConfig->addComponent(
|
$fields->addFieldToTab(
|
||||||
$addNewButton = new DMSGridFieldAddNewButton,
|
'Root.Document Sets (' . $this->owner->DocumentSets()->Count() . ')',
|
||||||
'GridFieldExportButton'
|
$gridField
|
||||||
);
|
);
|
||||||
$addNewButton->setPageId($this->owner->ID);
|
|
||||||
|
|
||||||
$fields->addFieldToTab('Root.Documents (' . $this->owner->Documents()->Count() . ')', $gridField);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enforce sorting for frontend
|
* Get a list of document sets for the owner page
|
||||||
|
*
|
||||||
|
* @return ArrayList
|
||||||
*/
|
*/
|
||||||
public function PageDocuments()
|
public function getDocumentSets()
|
||||||
{
|
{
|
||||||
return $this->owner->getManyManyComponents('Documents')->sort('DocumentSort');
|
return $this->owner->DocumentSets();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of all documents from all document sets for the owner page
|
||||||
|
*
|
||||||
|
* @return ArrayList
|
||||||
|
*/
|
||||||
|
public function getAllDocuments()
|
||||||
|
{
|
||||||
|
$documents = ArrayList::create();
|
||||||
|
|
||||||
|
foreach ($this->getDocumentSets() as $documentSet) {
|
||||||
|
/** @var DocumentSet $documentSet */
|
||||||
|
$documents->merge($documentSet->getDocuments());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $documents;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onBeforeDelete()
|
public function onBeforeDelete()
|
||||||
@ -160,7 +80,7 @@ class DMSSiteTreeExtension extends DataExtension
|
|||||||
|
|
||||||
public function onBeforePublish()
|
public function onBeforePublish()
|
||||||
{
|
{
|
||||||
$embargoedDocuments = $this->owner->Documents()->filter('EmbargoedUntilPublished', true);
|
$embargoedDocuments = $this->owner->getAllDocuments()->filter('EmbargoedUntilPublished', true);
|
||||||
if ($embargoedDocuments->Count() > 0) {
|
if ($embargoedDocuments->Count() > 0) {
|
||||||
foreach ($embargoedDocuments as $doc) {
|
foreach ($embargoedDocuments as $doc) {
|
||||||
$doc->EmbargoedUntilPublished = false;
|
$doc->EmbargoedUntilPublished = false;
|
||||||
@ -169,8 +89,14 @@ class DMSSiteTreeExtension extends DataExtension
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the title of the page with the total number of documents it has associated with it across
|
||||||
|
* all document sets
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getTitleWithNumberOfDocuments()
|
public function getTitleWithNumberOfDocuments()
|
||||||
{
|
{
|
||||||
return $this->owner->Title . ' (' . $this->owner->Documents()->Count() . ')';
|
return $this->owner->Title . ' (' . $this->owner->getAllDocuments()->count() . ')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,58 +6,6 @@
|
|||||||
*/
|
*/
|
||||||
interface DMSDocumentInterface
|
interface DMSDocumentInterface
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Deletes the DMSDocument, its underlying file, as well as any tags related to this DMSDocument.
|
|
||||||
*
|
|
||||||
* @todo Can't be applied to classes which already implement the DataObjectInterface (naming conflict)
|
|
||||||
*
|
|
||||||
* @abstract
|
|
||||||
* @return null
|
|
||||||
*/
|
|
||||||
// function delete();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Associates this DMSDocument with a Page. This method does nothing if the association already exists.
|
|
||||||
* This could be a simple wrapper around $myDoc->Pages()->add($myPage) to add a many_many relation
|
|
||||||
* @abstract
|
|
||||||
* @param $pageObject Page object to associate this DMSDocument with
|
|
||||||
* @return null
|
|
||||||
*/
|
|
||||||
public function addPage($pageObject);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Associates this DMSDocument with a set of Pages. This method loops through a set of page ids, and then
|
|
||||||
* associates this
|
|
||||||
* DMSDocument with the individual Page with the each page id in the set
|
|
||||||
* @abstract
|
|
||||||
* @param $pageIDs array of page ids used for the page objects associate this DMSDocument with
|
|
||||||
* @return null
|
|
||||||
*/
|
|
||||||
public function addPages($pageIDs);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the association between this DMSDocument and a Page. This method does nothing if the association does
|
|
||||||
* not exist.
|
|
||||||
* @abstract
|
|
||||||
* @param $pageObject Page object to remove the association to
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function removePage($pageObject);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of the Page objects associated with this DMSDocument
|
|
||||||
* @abstract
|
|
||||||
* @return DataList
|
|
||||||
*/
|
|
||||||
public function getPages();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all associated Pages from the DMSDocument
|
|
||||||
* @abstract
|
|
||||||
* @return null
|
|
||||||
*/
|
|
||||||
public function removeAllPages();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a metadata tag to the DMSDocument. The tag has a category and a value.
|
* Adds a metadata tag to the DMSDocument. The tag has a category and a value.
|
||||||
* Each category can have multiple values by default. So: addTag("fruit","banana") addTag("fruit", "apple") will
|
* Each category can have multiple values by default. So: addTag("fruit","banana") addTag("fruit", "apple") will
|
||||||
@ -67,7 +15,6 @@ interface DMSDocumentInterface
|
|||||||
* addTag("fruit","banana") addTag("fruit", "apple") would result in a single metadata tag: fruit->apple.
|
* addTag("fruit","banana") addTag("fruit", "apple") would result in a single metadata tag: fruit->apple.
|
||||||
* Can could be implemented as a key/value store table (although it is more like category/value, because the
|
* Can could be implemented as a key/value store table (although it is more like category/value, because the
|
||||||
* same category can occur multiple times)
|
* same category can occur multiple times)
|
||||||
* @abstract
|
|
||||||
* @param $category String of a metadata category to add (required)
|
* @param $category String of a metadata category to add (required)
|
||||||
* @param $value String of a metadata value to add (required)
|
* @param $value String of a metadata value to add (required)
|
||||||
* @param bool $multiValue Boolean that determines if the category is multi-value or single-value (optional)
|
* @param bool $multiValue Boolean that determines if the category is multi-value or single-value (optional)
|
||||||
@ -78,7 +25,6 @@ interface DMSDocumentInterface
|
|||||||
/**
|
/**
|
||||||
* Fetches all tags associated with this DMSDocument within a given category. If a value is specified this method
|
* Fetches all tags associated with this DMSDocument within a given category. If a value is specified this method
|
||||||
* tries to fetch that specific tag.
|
* tries to fetch that specific tag.
|
||||||
* @abstract
|
|
||||||
* @param $category String of the metadata category to get
|
* @param $category String of the metadata category to get
|
||||||
* @param null $value String of the value of the tag to get
|
* @param null $value String of the value of the tag to get
|
||||||
* @return array of Strings of all the tags or null if there is no match found
|
* @return array of Strings of all the tags or null if there is no match found
|
||||||
@ -89,7 +35,6 @@ interface DMSDocumentInterface
|
|||||||
* Removes a tag from the DMSDocument. If you only set a category, then all values in that category are deleted.
|
* Removes a tag from the DMSDocument. If you only set a category, then all values in that category are deleted.
|
||||||
* If you specify both a category and a value, then only that single category/value pair is deleted.
|
* If you specify both a category and a value, then only that single category/value pair is deleted.
|
||||||
* Nothing happens if the category or the value do not exist.
|
* Nothing happens if the category or the value do not exist.
|
||||||
* @abstract
|
|
||||||
* @param $category Category to remove (required)
|
* @param $category Category to remove (required)
|
||||||
* @param null $value Value to remove (optional)
|
* @param null $value Value to remove (optional)
|
||||||
* @return null
|
* @return null
|
||||||
@ -98,14 +43,12 @@ interface DMSDocumentInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all tags associated with this DMSDocument.
|
* Deletes all tags associated with this DMSDocument.
|
||||||
* @abstract
|
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
public function removeAllTags();
|
public function removeAllTags();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a link to download this DMSDocument from the DMS store
|
* Returns a link to download this DMSDocument from the DMS store
|
||||||
* @abstract
|
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
public function getLink();
|
public function getLink();
|
||||||
@ -142,14 +85,12 @@ interface DMSDocumentInterface
|
|||||||
* Hides the DMSDocument, so it does not show up when getByPage($myPage) is called
|
* Hides the DMSDocument, so it does not show up when getByPage($myPage) is called
|
||||||
* (without specifying the $showEmbargoed = true parameter). This is similar to expire, except that this method
|
* (without specifying the $showEmbargoed = true parameter). This is similar to expire, except that this method
|
||||||
* should be used to hide DMSDocuments that have not yet gone live.
|
* should be used to hide DMSDocuments that have not yet gone live.
|
||||||
* @abstract
|
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
public function embargoIndefinitely();
|
public function embargoIndefinitely();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if this is DMSDocument is embargoed or expired.
|
* Returns if this is DMSDocument is embargoed or expired.
|
||||||
* @abstract
|
|
||||||
* @return bool True or False depending on whether this DMSDocument is embargoed or expired
|
* @return bool True or False depending on whether this DMSDocument is embargoed or expired
|
||||||
*/
|
*/
|
||||||
public function isHidden();
|
public function isHidden();
|
||||||
@ -157,7 +98,6 @@ interface DMSDocumentInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if this is DMSDocument is embargoed.
|
* Returns if this is DMSDocument is embargoed.
|
||||||
* @abstract
|
|
||||||
* @return bool True or False depending on whether this DMSDocument is embargoed
|
* @return bool True or False depending on whether this DMSDocument is embargoed
|
||||||
*/
|
*/
|
||||||
public function isEmbargoed();
|
public function isEmbargoed();
|
||||||
@ -165,7 +105,6 @@ interface DMSDocumentInterface
|
|||||||
/**
|
/**
|
||||||
* Hides the DMSDocument, so it does not show up when getByPage($myPage) is called. Automatically un-hides the
|
* Hides the DMSDocument, so it does not show up when getByPage($myPage) is called. Automatically un-hides the
|
||||||
* DMSDocument at a specific date.
|
* DMSDocument at a specific date.
|
||||||
* @abstract
|
|
||||||
* @param $datetime String date time value when this DMSDocument should expire
|
* @param $datetime String date time value when this DMSDocument should expire
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
@ -179,21 +118,18 @@ interface DMSDocumentInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears any previously set embargos, so the DMSDocument always shows up in all queries.
|
* Clears any previously set embargos, so the DMSDocument always shows up in all queries.
|
||||||
* @abstract
|
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
public function clearEmbargo();
|
public function clearEmbargo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if this is DMSDocument is expired.
|
* Returns if this is DMSDocument is expired.
|
||||||
* @abstract
|
|
||||||
* @return bool True or False depending on whether this DMSDocument is expired
|
* @return bool True or False depending on whether this DMSDocument is expired
|
||||||
*/
|
*/
|
||||||
public function isExpired();
|
public function isExpired();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides the DMSDocument at a specific date, so it does not show up when getByPage($myPage) is called.
|
* Hides the DMSDocument at a specific date, so it does not show up when getByPage($myPage) is called.
|
||||||
* @abstract
|
|
||||||
* @param $datetime String date time value when this DMSDocument should expire
|
* @param $datetime String date time value when this DMSDocument should expire
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
@ -201,7 +137,6 @@ interface DMSDocumentInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears any previously set expiry.
|
* Clears any previously set expiry.
|
||||||
* @abstract
|
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
public function clearExpiry();
|
public function clearExpiry();
|
||||||
@ -211,7 +146,6 @@ interface DMSDocumentInterface
|
|||||||
/**
|
/**
|
||||||
* Returns a DataList of all previous Versions of this DMSDocument (check the LastEdited date of each
|
* Returns a DataList of all previous Versions of this DMSDocument (check the LastEdited date of each
|
||||||
* object to find the correct one)
|
* object to find the correct one)
|
||||||
* @abstract
|
|
||||||
* @return DataList List of DMSDocument objects
|
* @return DataList List of DMSDocument objects
|
||||||
*/
|
*/
|
||||||
public function getVersions();
|
public function getVersions();
|
||||||
|
@ -57,11 +57,19 @@ interface DMSInterface
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of Document objects associated with a Page
|
* Returns a list of Document objects associated with a Page via intermediary document sets
|
||||||
* @abstract
|
*
|
||||||
* @param $page SiteTree to fetch the associated Documents from
|
* @param SiteTree $page SiteTree to fetch the associated Documents from
|
||||||
* @param bool $showEmbargoed Boolean that specifies if embargoed documents should be included in results
|
* @param bool $showEmbargoed Boolean that specifies if embargoed documents should be included in results
|
||||||
* @return DataList Document list associated with the Page
|
* @return ArrayList Document list associated with the Page
|
||||||
*/
|
*/
|
||||||
public function getByPage($page, $showEmbargoed = false);
|
public function getByPage(SiteTree $page, $showEmbargoed = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of Document Set objects associated with a Page
|
||||||
|
*
|
||||||
|
* @param SiteTree $page SiteTree to fetch the associated Document Sets from
|
||||||
|
* @return ArrayList Document list associated with the Page
|
||||||
|
*/
|
||||||
|
public function getDocumentSetsByPage(SiteTree $page);
|
||||||
}
|
}
|
||||||
|
@ -43,20 +43,17 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
|
|||||||
"CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
|
"CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private static $belongs_many_many = array(
|
||||||
|
'Sets' => 'DMSDocumentSet'
|
||||||
|
);
|
||||||
|
|
||||||
private static $many_many = array(
|
private static $many_many = array(
|
||||||
'Pages' => 'SiteTree',
|
|
||||||
'RelatedDocuments' => 'DMSDocument',
|
'RelatedDocuments' => 'DMSDocument',
|
||||||
'Tags' => 'DMSTag',
|
'Tags' => 'DMSTag',
|
||||||
'ViewerGroups' => 'Group',
|
'ViewerGroups' => 'Group',
|
||||||
'EditorGroups' => 'Group',
|
'EditorGroups' => 'Group',
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $many_many_extraFields = array(
|
|
||||||
'Pages' => array(
|
|
||||||
'DocumentSort' => 'Int'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $display_fields = array(
|
private static $display_fields = array(
|
||||||
'ID' => 'ID',
|
'ID' => 'ID',
|
||||||
'Title' => 'Title',
|
'Title' => 'Title',
|
||||||
@ -82,7 +79,7 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
|
|||||||
'Filename' => 'Filename',
|
'Filename' => 'Filename',
|
||||||
'Title' => 'Title',
|
'Title' => 'Title',
|
||||||
'ViewCount' => 'ViewCount',
|
'ViewCount' => 'ViewCount',
|
||||||
'getPages.count' => 'Page Use'
|
'getRelatedPages.count' => 'Page Use'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,103 +214,6 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
|
|||||||
return $this->canView();
|
return $this->canView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Associates this document with a Page. This method does nothing if the
|
|
||||||
* association already exists.
|
|
||||||
*
|
|
||||||
* This could be a simple wrapper around $myDoc->Pages()->add($myPage) to
|
|
||||||
* add a many_many relation.
|
|
||||||
*
|
|
||||||
* @param SiteTree $pageObject Page object to associate this Document with
|
|
||||||
*
|
|
||||||
* @return DMSDocument
|
|
||||||
*/
|
|
||||||
public function addPage($pageObject)
|
|
||||||
{
|
|
||||||
$this->Pages()->add($pageObject);
|
|
||||||
|
|
||||||
DB::query(
|
|
||||||
"UPDATE \"DMSDocument_Pages\" SET \"DocumentSort\"=\"DocumentSort\"+1"
|
|
||||||
. " WHERE \"SiteTreeID\" = $pageObject->ID"
|
|
||||||
);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Associates this DMSDocument with a set of Pages. This method loops
|
|
||||||
* through a set of page ids, and then associates this DMSDocument with the
|
|
||||||
* individual Page with the each page id in the set.
|
|
||||||
*
|
|
||||||
* @param array $pageIDs
|
|
||||||
*
|
|
||||||
* @return DMSDocument
|
|
||||||
*/
|
|
||||||
public function addPages($pageIDs)
|
|
||||||
{
|
|
||||||
foreach ($pageIDs as $id) {
|
|
||||||
$pageObject = DataObject::get_by_id("SiteTree", $id);
|
|
||||||
|
|
||||||
if ($pageObject && $pageObject->exists()) {
|
|
||||||
$this->addPage($pageObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the association between this Document and a Page. This method
|
|
||||||
* does nothing if the association does not exist.
|
|
||||||
*
|
|
||||||
* @param SiteTree $pageObject Page object to remove the association to
|
|
||||||
*
|
|
||||||
* @return DMSDocument
|
|
||||||
*/
|
|
||||||
public function removePage($pageObject)
|
|
||||||
{
|
|
||||||
$this->Pages()->remove($pageObject);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see getPages()
|
|
||||||
*
|
|
||||||
* @return DataList
|
|
||||||
*/
|
|
||||||
public function Pages()
|
|
||||||
{
|
|
||||||
$pages = $this->getManyManyComponents('Pages');
|
|
||||||
$this->extend('updatePages', $pages);
|
|
||||||
|
|
||||||
return $pages;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of the Page objects associated with this Document.
|
|
||||||
*
|
|
||||||
* @return DataList
|
|
||||||
*/
|
|
||||||
public function getPages()
|
|
||||||
{
|
|
||||||
return $this->Pages();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all associated Pages from the DMSDocument
|
|
||||||
*
|
|
||||||
* @return DMSDocument
|
|
||||||
*/
|
|
||||||
public function removeAllPages()
|
|
||||||
{
|
|
||||||
$this->Pages()->removeAll();
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increase ViewCount by 1, without update any other record fields such as
|
* Increase ViewCount by 1, without update any other record fields such as
|
||||||
* LastEdited.
|
* LastEdited.
|
||||||
@ -842,8 +742,6 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->removeAllPages();
|
|
||||||
|
|
||||||
// get rid of any versions have saved for this DMSDocument, too
|
// get rid of any versions have saved for this DMSDocument, too
|
||||||
if (DMSDocument_versions::$enable_versions) {
|
if (DMSDocument_versions::$enable_versions) {
|
||||||
$versions = $this->getVersions();
|
$versions = $this->getVersions();
|
||||||
@ -855,11 +753,9 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::delete();
|
return parent::delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Relate an existing file on the filesystem to the document.
|
* Relate an existing file on the filesystem to the document.
|
||||||
*
|
*
|
||||||
@ -1060,7 +956,7 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
|
|||||||
$pagesGrid = GridField::create(
|
$pagesGrid = GridField::create(
|
||||||
'Pages',
|
'Pages',
|
||||||
_t('DMSDocument.RelatedPages', 'Related Pages'),
|
_t('DMSDocument.RelatedPages', 'Related Pages'),
|
||||||
$this->Pages(),
|
$this->getRelatedPages(),
|
||||||
$gridFieldConfig
|
$gridFieldConfig
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1321,7 +1217,7 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
|
|||||||
);
|
);
|
||||||
|
|
||||||
//count the number of pages this document is published on
|
//count the number of pages this document is published on
|
||||||
$publishedOnCount = $this->Pages()->Count();
|
$publishedOnCount = $this->getRelatedPages()->count();
|
||||||
$publishedOnValue = "$publishedOnCount pages";
|
$publishedOnValue = "$publishedOnCount pages";
|
||||||
if ($publishedOnCount == 1) {
|
if ($publishedOnCount == 1) {
|
||||||
$publishedOnValue = "$publishedOnCount page";
|
$publishedOnValue = "$publishedOnCount page";
|
||||||
@ -1419,6 +1315,26 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
|
|||||||
return $documents;
|
return $documents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of related pages for this document by going through the associated document sets
|
||||||
|
*
|
||||||
|
* @return ArrayList
|
||||||
|
*/
|
||||||
|
public function getRelatedPages()
|
||||||
|
{
|
||||||
|
$pages = ArrayList::create();
|
||||||
|
|
||||||
|
foreach ($this->Sets() as $documentSet) {
|
||||||
|
/** @var DocumentSet $documentSet */
|
||||||
|
$pages->add($documentSet->Page());
|
||||||
|
}
|
||||||
|
$pages->removeDuplicates();
|
||||||
|
|
||||||
|
$this->extend('updateRelatedPages', $pages);
|
||||||
|
|
||||||
|
return $pages;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a GridField for managing related documents
|
* Get a GridField for managing related documents
|
||||||
*
|
*
|
||||||
|
123
code/model/DMSDocumentSet.php
Normal file
123
code/model/DMSDocumentSet.php
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* A document set is attached to Pages, and contains many DMSDocuments
|
||||||
|
*/
|
||||||
|
class DMSDocumentSet extends DataObject
|
||||||
|
{
|
||||||
|
private static $db = array(
|
||||||
|
'Title' => 'Varchar(255)'
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $has_one = array(
|
||||||
|
'Page' => 'SiteTree'
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $many_many = array(
|
||||||
|
'Documents' => 'DMSDocument'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a list of the documents in this set. An extension hook is provided before the result is returned.
|
||||||
|
*
|
||||||
|
* You can attach an extension to this event:
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* public function updateDocuments($document)
|
||||||
|
* {
|
||||||
|
* // do something
|
||||||
|
* }
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @return DataList
|
||||||
|
*/
|
||||||
|
public function getDocuments()
|
||||||
|
{
|
||||||
|
$documents = $this->Documents();
|
||||||
|
|
||||||
|
$this->extend('updateDocuments', $documents);
|
||||||
|
|
||||||
|
return $documents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put the "documents" list into the main tab instead of its own tab, and replace the default "Add Document" button
|
||||||
|
* with a customised button for DMS documents
|
||||||
|
*
|
||||||
|
* @return FieldList
|
||||||
|
*/
|
||||||
|
public function getCMSFields()
|
||||||
|
{
|
||||||
|
$this->beforeUpdateCMSFields(function (FieldList $fields) {
|
||||||
|
// Javascript to customize the grid field for the DMS document (overriding entwine
|
||||||
|
// in FRAMEWORK_DIR.'/javascript/GridField.js'
|
||||||
|
Requirements::javascript(DMS_DIR . '/javascript/DMSGridField.js');
|
||||||
|
Requirements::css(DMS_DIR . '/css/DMSMainCMS.css');
|
||||||
|
|
||||||
|
// Javascript for the link editor pop-up in TinyMCE
|
||||||
|
Requirements::javascript(DMS_DIR . '/javascript/DocumentHtmlEditorFieldToolbar.js');
|
||||||
|
|
||||||
|
// Document listing
|
||||||
|
$gridFieldConfig = GridFieldConfig::create()
|
||||||
|
->addComponents(
|
||||||
|
new GridFieldToolbarHeader(),
|
||||||
|
new GridFieldFilterHeader(),
|
||||||
|
new GridFieldSortableHeader(),
|
||||||
|
// new GridFieldOrderableRows('DocumentSort'),
|
||||||
|
new GridFieldDataColumns(),
|
||||||
|
new GridFieldEditButton(),
|
||||||
|
new DMSGridFieldDeleteAction(), //special delete dialog to handle custom behaviour of unlinking and deleting
|
||||||
|
new GridFieldDetailForm()
|
||||||
|
//GridFieldLevelup::create($folder->ID)->setLinkSpec('admin/assets/show/%d')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (class_exists('GridFieldPaginatorWithShowAll')) {
|
||||||
|
$paginatorComponent = new GridFieldPaginatorWithShowAll(15);
|
||||||
|
} else {
|
||||||
|
$paginatorComponent = new GridFieldPaginator(15);
|
||||||
|
}
|
||||||
|
$gridFieldConfig->addComponent($paginatorComponent);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
$gridFieldConfig->addComponent($sortableComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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' => '<a target=\'_blank\' class=\'file-url\' href=\'$Link\'>$FilenameWithoutID</a>'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
//override delete functionality with this class
|
||||||
|
$gridFieldConfig->getComponentByType('GridFieldDetailForm')
|
||||||
|
->setItemRequestClass('DMSGridFieldDetailForm_ItemRequest');
|
||||||
|
|
||||||
|
$gridField = GridField::create(
|
||||||
|
'Documents',
|
||||||
|
false,
|
||||||
|
$this->Documents(),//->Sort('DocumentSort'),
|
||||||
|
$gridFieldConfig
|
||||||
|
);
|
||||||
|
$gridField->addExtraClass('documents');
|
||||||
|
|
||||||
|
$gridFieldConfig->addComponent(
|
||||||
|
$addNewButton = new DMSGridFieldAddNewButton,
|
||||||
|
'GridFieldExportButton'
|
||||||
|
);
|
||||||
|
$addNewButton->setDocumentSetId($this->ID);
|
||||||
|
|
||||||
|
$fields->removeByName('Documents');
|
||||||
|
$fields->addFieldToTab('Root.Main', $gridField);
|
||||||
|
});
|
||||||
|
return parent::getCMSFields();
|
||||||
|
}
|
||||||
|
}
|
30
docs/en/changelogs/2.0.0.md
Normal file
30
docs/en/changelogs/2.0.0.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# 2.0.0 (unreleased)
|
||||||
|
|
||||||
|
## Document sets
|
||||||
|
|
||||||
|
Documents now belong to "sets", which are attached to Pages. A Page can have many Document Sets, and a Set has a
|
||||||
|
many_many relationship with Documents.
|
||||||
|
|
||||||
|
When upgrading from 1.x to 2.x you will need to migrate the relationships from your Pages to Documents so support
|
||||||
|
having a Document Set intermediary (@todo Add a build task for this).
|
||||||
|
|
||||||
|
## API changes
|
||||||
|
|
||||||
|
* `DMSSiteTreeExtension::no_documents_tab` removed, use YAML configuration `MyPage.documents_enabled: false` instead
|
||||||
|
* `DMSSiteTreeExtension::show_documents_tab` removed, use YAML configuration `MyPage.documents_enabled: true` instead
|
||||||
|
* `DMSSiteTreeExtension::PageDocuments` removed, use `DMSSiteTreeExtension::getDocumentSets` instead
|
||||||
|
* `DMSSiteTreeExtension::getDocuments` removed, use `DMSSiteTreeExtension::getAllDocuments` instead
|
||||||
|
* `DMSDocument::addPage` removed, use document sets instead
|
||||||
|
* `DMSDocument::addPages` removed, use document sets instead
|
||||||
|
* `DMSDocument::removePage` removed, use document sets instead
|
||||||
|
* `DMSDocument::removeAllPages` removed, use document sets instead
|
||||||
|
* `DMSDocument::getPages` removed, use `DMSDocument::getRelatedPages` instead
|
||||||
|
* `DMSDocumentInterface` has had the page manipulation methods removed, as above
|
||||||
|
* `DMSDocumentAddController::add_allowed_extensions` removed, use YAML configuration `DMSDocumentAddController::allowed_extensions` instead
|
||||||
|
* `DMSInterface` (and `DMS`) are stricter in the `getByPage` method, enforcing a `SiteTree` type hint
|
||||||
|
* New method `DMSInterface::getDocumentSetsByPage` (and in `DMS`)
|
||||||
|
|
||||||
|
## Template changes
|
||||||
|
|
||||||
|
The default template entry point is now `DocumentSets.ss` (previously `Documents.ss`). As well as this change,
|
||||||
|
`Documents.ss` has been renamed to `DocumentSet.ss`.
|
@ -1,3 +1,30 @@
|
|||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
The file location is set via the `DMS::$dmsFolder` static, and points to a location in the webroot.
|
The file location is set via the `DMS::$dmsFolder` static, and points to a location in the webroot.
|
||||||
|
|
||||||
|
## Enable/disable documents/sets for a specific page type
|
||||||
|
|
||||||
|
If you don't need documents/document sets for a specific page type you can disable this with YAML configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
MyPageType:
|
||||||
|
documents_enabled: false
|
||||||
|
```
|
||||||
|
|
||||||
|
Likewise, you could override a previously set configuration value by setting this back to `true` in a configuration
|
||||||
|
file with a higher precedence.
|
||||||
|
|
||||||
|
## Allowed extensions for DMS documents
|
||||||
|
|
||||||
|
By default the allowed extensions for DMS documents will come from the UploadField's allowed extesions list, and will
|
||||||
|
have a customised list of extensions for DMS merged in. The base `allowed_extensions` is a site-wide configuration
|
||||||
|
setting. [See here for information](https://docs.silverstripe.org/en/3/developer_guides/forms/field_types/uploadfield/#limit-the-allowed-filetypes) on changing this.
|
||||||
|
|
||||||
|
To add extra allowed file extensions purely for DMS documents, you can update the YAML configuration property:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
DMSDocumentAddController:
|
||||||
|
allowed_extensions:
|
||||||
|
- php
|
||||||
|
- php5
|
||||||
|
```
|
||||||
|
@ -1,18 +1,35 @@
|
|||||||
# Creating documents
|
# Creating documents
|
||||||
|
|
||||||
Create by relative path:
|
The following examples will allow you to create a DMS document in the system without associating it to a document set.
|
||||||
|
|
||||||
|
## Create by relative path
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$dms = DMS::getDMSInstance();
|
$dms = DMS::inst();
|
||||||
$doc = $dms->storeDocument('assets/myfile.pdf');
|
$doc = $dms->storeDocument('assets/myfile.pdf');
|
||||||
```
|
```
|
||||||
|
|
||||||
Create from an existing `File` record:
|
## Create from an existing `File` record
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$dms = DMS::getDMSInstance();
|
$dms = DMS::inst();
|
||||||
$file = File::get()->byID(99);
|
$file = File::get()->byID(99);
|
||||||
$doc = $dms->storeDocument($file);
|
$doc = $dms->storeDocument($file);
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: Both operations copy the existing file.
|
Note: Both operations copy the existing file.
|
||||||
|
|
||||||
|
## Associate to a document set
|
||||||
|
|
||||||
|
If you need to associate a document to a set once it has already been created, you can use the ORM relationship from
|
||||||
|
SiteTree to access the document sets, or you can simply access the document set directly:
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Add document to the first set in my page
|
||||||
|
$firstSetInPage = $myPage->DocumentSets()->first();
|
||||||
|
$firstSetInPage->add($doc);
|
||||||
|
|
||||||
|
// Add document to a specific document set
|
||||||
|
$docSet = DMSDocumentSet::get()->byId(123);
|
||||||
|
$docSet->add($doc);
|
||||||
|
```
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
You can use `DMSDocument::getLink` to retrieve the secure route to download a DMS document:
|
You can use `DMSDocument::getLink` to retrieve the secure route to download a DMS document:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$dms = DMS::getDMSInstance();
|
$dms = DMS::inst();
|
||||||
$docs = $dms->getByTag('priority', 'important')->First();
|
$docs = $dms->getByTag('priority', 'important')->First();
|
||||||
$link = $doc->getLink();
|
$link = $doc->getLink();
|
||||||
```
|
```
|
||||||
|
@ -14,3 +14,7 @@
|
|||||||
## CMS user help
|
## CMS user help
|
||||||
|
|
||||||
* TBC
|
* TBC
|
||||||
|
|
||||||
|
### Changelogs
|
||||||
|
|
||||||
|
* [2.0.0 (unreleased)](changelogs/2.0.0.md)
|
||||||
|
@ -1,10 +1,35 @@
|
|||||||
# Manage page relations
|
# Manage page relations
|
||||||
|
|
||||||
To find documents by a Page:
|
Documents are associated to pages via "document sets". You can retrieve document sets for a page, then retrieve
|
||||||
|
documents that belong to those sets. You can still retrieve all documents for a page if you want to.
|
||||||
|
|
||||||
|
## Get document sets for a page
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$dms = DMS::getDMSInstance();
|
$dms = DMS::inst();
|
||||||
$page = SiteTree::get()->filter('URLSegment', 'home')->first();
|
$sets = $dms->getDocumentSetsByPage($myPage);
|
||||||
/** @var DataList $docs */
|
```
|
||||||
$docs = $dms->getByPage($page);
|
|
||||||
|
You can also request sets directly from the SiteTree instance:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$sets = $page->getDocumentSets();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Get all related documents for a page
|
||||||
|
|
||||||
|
`DMS::getByPage` will exclude currently embargoed documents by default. To include embargoed documents as well
|
||||||
|
add `true` as the second argument.
|
||||||
|
|
||||||
|
```php
|
||||||
|
$dms = DMS::inst();
|
||||||
|
|
||||||
|
$documents = $dms->getByPage($myPage);
|
||||||
|
$documentsIncludingEmbargoed = $dms->getByPage($myPage, true);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also request this directly from the SiteTree instance:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$documents = $myPage->getAllDocuments();
|
||||||
```
|
```
|
||||||
|
@ -4,7 +4,7 @@ Add a simple include to any of your `.ss` templates to display the DMSDocuments
|
|||||||
the current page on the front-end.
|
the current page on the front-end.
|
||||||
|
|
||||||
```
|
```
|
||||||
<% include Documents %>
|
<% include DocumentSets %>
|
||||||
```
|
```
|
||||||
|
|
||||||
You can fine tune the HTML markup or display behaviour of any of the templates in `/dms/templates/Includes` to change
|
You can fine tune the HTML markup or display behaviour of any of the templates in `/dms/templates/Includes` to change
|
||||||
|
25
lang/en.yml
25
lang/en.yml
@ -9,6 +9,8 @@ en:
|
|||||||
TYPE: 'File type'
|
TYPE: 'File type'
|
||||||
URL: URL
|
URL: URL
|
||||||
DMSDocument:
|
DMSDocument:
|
||||||
|
EDIT: Edit
|
||||||
|
EDITDOCUMENT: Edit this document
|
||||||
PLURALNAME: Documents
|
PLURALNAME: Documents
|
||||||
RelatedPages: 'Related Pages'
|
RelatedPages: 'Related Pages'
|
||||||
RelatedReferences: 'Related References'
|
RelatedReferences: 'Related References'
|
||||||
@ -16,9 +18,14 @@ en:
|
|||||||
Versions: Versions
|
Versions: Versions
|
||||||
DOWNLOAD: "Download {title}"
|
DOWNLOAD: "Download {title}"
|
||||||
LASTCHANGED: "Last changed: {date}"
|
LASTCHANGED: "Last changed: {date}"
|
||||||
|
DMSDocumentSet:
|
||||||
|
ADDDOCUMENTBUTTON: Add Document
|
||||||
|
ADDDOCUMENTSBUTTON: Add Documents
|
||||||
|
PLURALNAME: Document Sets
|
||||||
|
SINGULARNAME: Document Set
|
||||||
DMSTag:
|
DMSTag:
|
||||||
PLURALNAME: 'D M S Tags'
|
PLURALNAME: 'DMS Tags'
|
||||||
SINGULARNAME: 'D M S Tag'
|
SINGULARNAME: 'DMS Tag'
|
||||||
FileIFrameField:
|
FileIFrameField:
|
||||||
ATTACHONCESAVED2: 'Files can be attached once you have saved the record for the first time.'
|
ATTACHONCESAVED2: 'Files can be attached once you have saved the record for the first time.'
|
||||||
GridAction:
|
GridAction:
|
||||||
@ -29,8 +36,10 @@ en:
|
|||||||
DeletePermissionsFailure: 'No delete permissions'
|
DeletePermissionsFailure: 'No delete permissions'
|
||||||
UploadField:
|
UploadField:
|
||||||
ATTACHFILE: 'Attach a file'
|
ATTACHFILE: 'Attach a file'
|
||||||
|
DONE: Done!
|
||||||
DROPFILE: 'drop a file'
|
DROPFILE: 'drop a file'
|
||||||
FIELDNOTSET: 'File information not found'
|
FIELDNOTSET: 'File information not found'
|
||||||
|
FROMCMS: From the CMS
|
||||||
FROMCOMPUTER: 'From your computer'
|
FROMCOMPUTER: 'From your computer'
|
||||||
FROMCOMPUTERINFO: 'Upload from your computer'
|
FROMCOMPUTERINFO: 'Upload from your computer'
|
||||||
MAXNUMBEROFFILES: 'Max number of {count} file(s) exceeded.'
|
MAXNUMBEROFFILES: 'Max number of {count} file(s) exceeded.'
|
||||||
@ -38,6 +47,14 @@ en:
|
|||||||
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'
|
RELATEDDOCUMENTS: 'Related Documents'
|
||||||
|
MAINTAB: Main
|
||||||
DMSDocument_versions:
|
DMSDocument_versions:
|
||||||
PLURALNAME: 'D M S Document_versionss'
|
PLURALNAME: 'DMS Document_versionss'
|
||||||
SINGULARNAME: 'D M S Document_versions'
|
SINGULARNAME: 'DMS Document_versions'
|
||||||
|
DMSDocumentAddExistingField:
|
||||||
|
ADDEXISTING: Add Existing
|
||||||
|
AUTOCOMPLETE: Search by ID or filename
|
||||||
|
CHOOSESET: Choose Document Set
|
||||||
|
EDITDOCUMENTDETAILS: Edit Document Details
|
||||||
|
LINKADOCUMENT: Link a Document
|
||||||
|
SELECTED: Selected Document
|
||||||
|
@ -1,64 +1,43 @@
|
|||||||
<div id="document" class="ss-add field treedropdown searchable">
|
<div id="document" class="ss-add field treedropdown searchable">
|
||||||
<div class="document-add-existing <% if useFieldContext %>field<% else %>link-editor-context<% end_if %>">
|
<div class="document-add-existing <% if $useFieldContext %>field<% else %>link-editor-context<% end_if %>">
|
||||||
<% if useFieldContext %>
|
<% if $useFieldContext %><h3><% else %><div><% end_if %>
|
||||||
<h3>
|
<span class="step-label">
|
||||||
<% else %>
|
<% if $useFieldContext %>
|
||||||
<div>
|
<span class="flyout">1</span><span class="arrow"></span>
|
||||||
<% end_if %>
|
<strong class="title"><%t DMSDocumentAddExistingField.LINKADOCUMENT "Link a Document" %></strong>
|
||||||
<span class="step-label">
|
<% end_if %>
|
||||||
<% if useFieldContext %>
|
</span>
|
||||||
<span class="flyout">1</span><span class="arrow"></span>
|
<% if $useFieldContext %></h3><% else %></div><% end_if %>
|
||||||
<strong class="title">Link a Document</strong>
|
|
||||||
<% else %>
|
|
||||||
<% end_if %>
|
|
||||||
</span>
|
|
||||||
<% if useFieldContext %>
|
|
||||||
</h3>
|
|
||||||
<% else %>
|
|
||||||
</div>
|
|
||||||
<% end_if %>
|
|
||||||
|
|
||||||
<% if useFieldContext %>
|
<% if not $useFieldContext %>
|
||||||
<% else %>
|
<label><%t DMSDocumentAddExistingField.LINKADOCUMENT "Link a Document" %></label>
|
||||||
<label>Link a Document</label>
|
<div class="middleColumn">
|
||||||
<div class="middleColumn">
|
<% end_if %>
|
||||||
<% end_if %>
|
<input class="document-autocomplete text" type="text" placeholder="<%t DMSDocumentAddExistingField.AUTOCOMPLETE "Search by ID or filename" %>" />
|
||||||
|
$fieldByName(PageSelector)
|
||||||
|
<div class="document-list"></div>
|
||||||
|
<% if not $useFieldContext %>
|
||||||
|
</div>
|
||||||
|
<% end_if %>
|
||||||
|
</div>
|
||||||
|
|
||||||
<input class="document-autocomplete text" type="text" placeholder="Search by ID or filename" />
|
<div class="ss-assetuploadfield <% if useFieldContext %>field<% else %>link-editor-context<% end_if %>">
|
||||||
<!-- <span>or Add from page</span> -->
|
<div class="step4">
|
||||||
$fieldByName(PageSelector)
|
<span class="step-label">
|
||||||
|
<% if useFieldContext %>
|
||||||
<div class="document-list"></div>
|
<span class="flyout">2</span><span class="arrow"></span>
|
||||||
|
<strong class="title"><%t DMSDocumentAddExistingField.EDITDOCUMENTDETAILS "Edit Document Details" %></strong>
|
||||||
<% if useFieldContext %>
|
<% else %>
|
||||||
<% else %>
|
<label><%t DMSDocumentAddExistingField.SELECTED "Selected Document" %></label>
|
||||||
</div>
|
<% end_if %>
|
||||||
<% end_if %>
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
<% if not $useFieldContext %>
|
||||||
|
<div class="middleColumn">
|
||||||
<div class="ss-assetuploadfield <% if useFieldContext %>field<% else %>link-editor-context<% end_if %>">
|
<% end_if %>
|
||||||
<div class="step4">
|
<ul class="files ss-uploadfield-files ss-add-files"></ul>
|
||||||
<span class="step-label">
|
<% if not $useFieldContext %>
|
||||||
<% if useFieldContext %>
|
</div>
|
||||||
<span class="flyout">2</span><span class="arrow"></span>
|
<% end_if %>
|
||||||
<strong class="title">Edit Document Details</strong>
|
</div>
|
||||||
<% else %>
|
|
||||||
<label>Selected Document</label>
|
|
||||||
<% end_if %>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="fileOverview"></div> -->
|
|
||||||
|
|
||||||
<% if useFieldContext %>
|
|
||||||
<% else %>
|
|
||||||
<div class="middleColumn">
|
|
||||||
<% end_if %>
|
|
||||||
<ul class="files ss-uploadfield-files ss-add-files"></ul>
|
|
||||||
<% if useFieldContext %>
|
|
||||||
<% else %>
|
|
||||||
</div>
|
|
||||||
<% end_if %>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
@ -12,7 +12,7 @@
|
|||||||
<div class="clear"><!-- --></div>
|
<div class="clear"><!-- --></div>
|
||||||
</label>
|
</label>
|
||||||
<div class="ss-uploadfield-item-actions">
|
<div class="ss-uploadfield-item-actions">
|
||||||
<% if Top.isDisabled || Top.isReadonly %>
|
<% if $Top.isDisabled || $Top.isReadonly %>
|
||||||
<% else %>
|
<% else %>
|
||||||
$UploadFieldFileButtons
|
$UploadFieldFileButtons
|
||||||
<% end_if %>
|
<% end_if %>
|
||||||
@ -25,11 +25,11 @@
|
|||||||
<% end_loop %>
|
<% end_loop %>
|
||||||
<% end_if %>
|
<% end_if %>
|
||||||
</ul>
|
</ul>
|
||||||
<% if isDisabled || isReadonly %>
|
<% if $isDisabled || $isReadonly %>
|
||||||
<% if isSaveable %>
|
<% if $isSaveable %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<div class="ss-uploadfield-item">
|
<div class="ss-uploadfield-item">
|
||||||
<em><% _t('FileIFrameField.ATTACHONCESAVED2', 'Files can be attached once you have saved the record for the first time.') %></em>
|
<em><%t FileIFrameField.ATTACHONCESAVED2 "Files can be attached once you have saved the record for the first time." %></em>
|
||||||
</div>
|
</div>
|
||||||
<% end_if %>
|
<% end_if %>
|
||||||
<% else %>
|
<% else %>
|
||||||
@ -41,8 +41,8 @@
|
|||||||
<label class="ss-uploadfield-item-name"><b>
|
<label class="ss-uploadfield-item-name"><b>
|
||||||
<% _t('UploadField.ATTACHFILE', 'Attach a file') %>
|
<% _t('UploadField.ATTACHFILE', 'Attach a file') %>
|
||||||
</b></label>
|
</b></label>
|
||||||
<label class="ss-uploadfield-fromcomputer ss-ui-button ui-corner-all" title="<% _t('UploadField.FROMCOMPUTERINFO', 'Upload from your computer') %>" data-icon="drive-upload">
|
<label class="ss-uploadfield-fromcomputer ss-ui-button ui-corner-all" title="<%t UploadField.FROMCOMPUTERINFO 'Upload from your computer' %>" data-icon="drive-upload">
|
||||||
<% _t('UploadField.FROMCOMPUTER', 'From your computer') %>
|
<%t UploadField.FROMCOMPUTER 'From your computer' %>
|
||||||
<input id="$id" name="$getName" class="$extraClass ss-uploadfield-fromcomputer-fileinput" data-config="$configString" type="file"<% if $multiple %> multiple="multiple"<% end_if %> />
|
<input id="$id" name="$getName" class="$extraClass ss-uploadfield-fromcomputer-fileinput" data-config="$configString" type="file"<% if $multiple %> multiple="multiple"<% end_if %> />
|
||||||
</label>
|
</label>
|
||||||
<div class="clear"><!-- --></div>
|
<div class="clear"><!-- --></div>
|
||||||
|
11
templates/Includes/DocumentSet.ss
Normal file
11
templates/Includes/DocumentSet.ss
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<% if $getDocuments %>
|
||||||
|
<div class="documentsets-set">
|
||||||
|
<% if $Title %>
|
||||||
|
<h3>$Title</h3>
|
||||||
|
<% end_if %>
|
||||||
|
|
||||||
|
<% loop $getDocuments %>
|
||||||
|
<% include Document %>
|
||||||
|
<% end_loop %>
|
||||||
|
</div>
|
||||||
|
<% end_if %>
|
7
templates/Includes/DocumentSets.ss
Normal file
7
templates/Includes/DocumentSets.ss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<% if $getDocumentSets %>
|
||||||
|
<div class="documentsets">
|
||||||
|
<% loop $getDocumentSets %>
|
||||||
|
<% include DocumentSet %>
|
||||||
|
<% end_loop %>
|
||||||
|
</div>
|
||||||
|
<% end_if %>
|
@ -1,8 +0,0 @@
|
|||||||
<% if $PageDocuments %>
|
|
||||||
<div class="documents">
|
|
||||||
<h3><%t DMSDocument.PLURALNAME "Documents" %></h3>
|
|
||||||
<% loop $PageDocuments %>
|
|
||||||
<% include Document %>
|
|
||||||
<% end_loop %>
|
|
||||||
</div>
|
|
||||||
<% end_if %>
|
|
35
tests/DMSDocumentSetTest.php
Normal file
35
tests/DMSDocumentSetTest.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class DMSDocumentSetTest extends SapphireTest
|
||||||
|
{
|
||||||
|
protected static $fixture_file = 'dmstest.yml';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that getDocuments is extensible
|
||||||
|
*/
|
||||||
|
public function testGetDocumentsIsExtensible()
|
||||||
|
{
|
||||||
|
DMSDocumentSet::add_extension('StubRelatedDocumentExtension');
|
||||||
|
|
||||||
|
$set = new DMSDocumentSet;
|
||||||
|
$documents = $set->getDocuments();
|
||||||
|
|
||||||
|
$this->assertCount(1, $documents);
|
||||||
|
$this->assertSame('Extended', $documents->first()->Filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRelations()
|
||||||
|
{
|
||||||
|
$s1 = $this->objFromFixture('SiteTree', 's1');
|
||||||
|
$s2 = $this->objFromFixture('SiteTree', 's2');
|
||||||
|
$s4 = $this->objFromFixture('SiteTree', 's4');
|
||||||
|
|
||||||
|
$ds1 = $this->objFromFixture('DMSDocumentSet', 'ds1');
|
||||||
|
$ds2 = $this->objFromFixture('DMSDocumentSet', 'ds2');
|
||||||
|
$ds3 = $this->objFromFixture('DMSDocumentSet', 'ds3');
|
||||||
|
|
||||||
|
$this->assertCount(0, $s4->getDocumentSets(), 'Page 4 has no document sets associated');
|
||||||
|
$this->assertCount(2, $s1->getDocumentSets(), 'Page 1 has 2 document sets');
|
||||||
|
$this->assertEquals(array($ds1->ID, $ds2->ID), $s1->getDocumentSets()->column('ID'));
|
||||||
|
}
|
||||||
|
}
|
@ -19,150 +19,6 @@ class DMSDocumentTest extends SapphireTest
|
|||||||
self::$is_running_test = $this->originalIsRunningTest;
|
self::$is_running_test = $this->originalIsRunningTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPageRelations()
|
|
||||||
{
|
|
||||||
$s1 = $this->objFromFixture('SiteTree', 's1');
|
|
||||||
$s2 = $this->objFromFixture('SiteTree', 's2');
|
|
||||||
$s3 = $this->objFromFixture('SiteTree', 's3');
|
|
||||||
$s4 = $this->objFromFixture('SiteTree', 's4');
|
|
||||||
$s5 = $this->objFromFixture('SiteTree', 's5');
|
|
||||||
$s6 = $this->objFromFixture('SiteTree', 's6');
|
|
||||||
|
|
||||||
$d1 = $this->objFromFixture('DMSDocument', 'd1');
|
|
||||||
|
|
||||||
$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');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testAddPageRelation()
|
|
||||||
{
|
|
||||||
$s1 = $this->objFromFixture('SiteTree', 's1');
|
|
||||||
$s2 = $this->objFromFixture('SiteTree', 's2');
|
|
||||||
$s3 = $this->objFromFixture('SiteTree', 's3');
|
|
||||||
|
|
||||||
$doc = new DMSDocument();
|
|
||||||
$doc->Filename = 'test file';
|
|
||||||
$doc->Folder = '0';
|
|
||||||
$doc->write();
|
|
||||||
|
|
||||||
$doc->addPage($s1);
|
|
||||||
$doc->addPage($s2);
|
|
||||||
$doc->addPage($s3);
|
|
||||||
|
|
||||||
$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');
|
|
||||||
|
|
||||||
$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');
|
|
||||||
|
|
||||||
$documents = $s2->Documents();
|
|
||||||
$documentsArray = $documents->toArray();
|
|
||||||
$this->assertDOSContains(
|
|
||||||
array(
|
|
||||||
array('Filename' => $doc->Filename)
|
|
||||||
),
|
|
||||||
$documentsArray,
|
|
||||||
'Document associated with page'
|
|
||||||
);
|
|
||||||
|
|
||||||
$doc->removeAllPages();
|
|
||||||
$pages = $doc->Pages();
|
|
||||||
$this->assertEquals($pages->Count(), 0, 'All pages removed');
|
|
||||||
|
|
||||||
$documents = $s2->Documents();
|
|
||||||
$documentsArray = $documents->toArray();
|
|
||||||
$this->assertNotContains($doc, $documentsArray, 'Document no longer associated with page');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testDeletingPageWithAssociatedDocuments()
|
|
||||||
{
|
|
||||||
$s1 = $this->objFromFixture('SiteTree', 's1');
|
|
||||||
$s2 = $this->objFromFixture('SiteTree', 's2');
|
|
||||||
$s2->publish('Stage', 'Live');
|
|
||||||
$s2ID = $s2->ID;
|
|
||||||
|
|
||||||
$doc = new DMSDocument();
|
|
||||||
$doc->Filename = 'delete test file';
|
|
||||||
$doc->Folder = '0';
|
|
||||||
$doc->write();
|
|
||||||
|
|
||||||
$doc->addPage($s1);
|
|
||||||
$doc->addPage($s2);
|
|
||||||
|
|
||||||
$s1->delete();
|
|
||||||
|
|
||||||
$documents = DataObject::get("DMSDocument", "\"Filename\" = 'delete test file'", false);
|
|
||||||
$this->assertEquals(
|
|
||||||
$documents->Count(),
|
|
||||||
'1',
|
|
||||||
"Deleting one of the associated page doesn't affect the single document we created"
|
|
||||||
);
|
|
||||||
|
|
||||||
$s2->delete();
|
|
||||||
$documents = DataObject::get("DMSDocument", "\"Filename\" = 'delete test file'");
|
|
||||||
$this->assertEquals(
|
|
||||||
$documents->Count(),
|
|
||||||
'1',
|
|
||||||
"Deleting a page from draft stage doesn't delete the associated docs,"
|
|
||||||
. "even if it's the last page they're associated with"
|
|
||||||
);
|
|
||||||
|
|
||||||
$s2 = Versioned::get_one_by_stage('SiteTree', 'Live', sprintf('"SiteTree"."ID" = %d', $s2ID));
|
|
||||||
$s2->doDeleteFromLive();
|
|
||||||
$documents = DataObject::get("DMSDocument", "\"Filename\" = 'delete test file'");
|
|
||||||
$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'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testUnpublishPageWithAssociatedDocuments()
|
|
||||||
{
|
|
||||||
$s2 = $this->objFromFixture('SiteTree', 's2');
|
|
||||||
$s2->publish('Stage', 'Live');
|
|
||||||
$s2ID = $s2->ID;
|
|
||||||
|
|
||||||
$doc = new DMSDocument();
|
|
||||||
$doc->Filename = 'delete test file';
|
|
||||||
$doc->Folder = '0';
|
|
||||||
$doc->write();
|
|
||||||
|
|
||||||
$doc->addPage($s2);
|
|
||||||
|
|
||||||
$s2->doDeleteFromLive();
|
|
||||||
$documents = DataObject::get("DMSDocument", "\"Filename\" = 'delete test file'");
|
|
||||||
$this->assertEquals(
|
|
||||||
$documents->Count(),
|
|
||||||
'1',
|
|
||||||
"Deleting a page from live stage doesn't delete the associated docs,"
|
|
||||||
. "even if it's the last page they're associated with"
|
|
||||||
);
|
|
||||||
|
|
||||||
$s2 = Versioned::get_one_by_stage('SiteTree', 'Stage', sprintf('"SiteTree"."ID" = %d', $s2ID));
|
|
||||||
$s2->delete();
|
|
||||||
$documents = DataObject::get("DMSDocument", "\"Filename\" = 'delete test file'");
|
|
||||||
$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'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testDefaultDownloadBehabiourCMSFields()
|
public function testDefaultDownloadBehabiourCMSFields()
|
||||||
{
|
{
|
||||||
$document = singleton('DMSDocument');
|
$document = singleton('DMSDocument');
|
||||||
@ -364,4 +220,15 @@ class DMSDocumentTest extends SapphireTest
|
|||||||
$doc3 = $this->objFromFixture('DMSDocument', 'doc-anyone');
|
$doc3 = $this->objFromFixture('DMSDocument', 'doc-anyone');
|
||||||
$this->assertEquals('', $doc3->getPermissionDeniedReason());
|
$this->assertEquals('', $doc3->getPermissionDeniedReason());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that all pages that a document belongs to (via many document sets) can be retrieved in one list
|
||||||
|
*/
|
||||||
|
public function testGetRelatedPages()
|
||||||
|
{
|
||||||
|
$document = $this->objFromFixture('DMSDocument', 'd1');
|
||||||
|
$result = $document->getRelatedPages();
|
||||||
|
$this->assertCount(3, $result, 'Document 1 is related to 3 Pages');
|
||||||
|
$this->assertSame(array('s1', 's2', 's3'), $result->column('URLSegment'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ class DMSEmbargoTest extends SapphireTest
|
|||||||
$doc->Folder = "0";
|
$doc->Folder = "0";
|
||||||
$dID = $doc->write();
|
$dID = $doc->write();
|
||||||
|
|
||||||
$doc->addPage($s1);
|
$s1->getDocumentSets()->first()->getDocuments()->add($doc);
|
||||||
|
|
||||||
$s1->publish('Stage', 'Live');
|
$s1->publish('Stage', 'Live');
|
||||||
$s1->doPublish();
|
$s1->doPublish();
|
||||||
|
@ -24,24 +24,24 @@ class DMSGridFieldAddNewButtonTest extends SapphireTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that when no page ID is present then it is not added to the URL for "add document"
|
* Test that when no document set ID is present then it is not added to the URL for "add document"
|
||||||
*/
|
*/
|
||||||
public function testNoPageIdInAddUrlWhenNotProvided()
|
public function testNoPageIdInAddUrlWhenNotProvided()
|
||||||
{
|
{
|
||||||
$fragments = $this->button->getHTMLFragments($this->gridField);
|
$fragments = $this->button->getHTMLFragments($this->gridField);
|
||||||
$result = array_pop($fragments)->getValue();
|
$result = array_pop($fragments)->getValue();
|
||||||
$this->assertNotContains('?ID', $result);
|
$this->assertNotContains('?dsid', $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that when a page ID is provided, it is added onto the "add document" link
|
* Test that when a document set ID is provided, it is added onto the "add document" link
|
||||||
*/
|
*/
|
||||||
public function testPageIdAddedToLinkWhenProvided()
|
public function testPageIdAddedToLinkWhenProvided()
|
||||||
{
|
{
|
||||||
$this->button->setPageId(123);
|
$this->button->setDocumentSetId(123);
|
||||||
|
|
||||||
$fragments = $this->button->getHTMLFragments($this->gridField);
|
$fragments = $this->button->getHTMLFragments($this->gridField);
|
||||||
$result = array_pop($fragments)->getValue();
|
$result = array_pop($fragments)->getValue();
|
||||||
$this->assertContains('?ID=123', $result);
|
$this->assertContains('?dsid=123', $result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
class DMSTest extends FunctionalTest
|
class DMSTest extends FunctionalTest
|
||||||
{
|
{
|
||||||
protected $usesDatabase = true;
|
protected static $fixture_file = 'dmstest.yml';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stub PDF files for testing
|
* Stub PDF files for testing
|
||||||
@ -16,6 +16,11 @@ class DMSTest extends FunctionalTest
|
|||||||
public static $dmsFolderOld;
|
public static $dmsFolderOld;
|
||||||
public static $dmsFolderSizeOld;
|
public static $dmsFolderSizeOld;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DMS
|
||||||
|
*/
|
||||||
|
protected $dms;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
@ -28,6 +33,8 @@ class DMSTest extends FunctionalTest
|
|||||||
|
|
||||||
//clear out the test folder (in case a broken test doesn't delete it)
|
//clear out the test folder (in case a broken test doesn't delete it)
|
||||||
$this->delete(BASE_PATH . DIRECTORY_SEPARATOR . 'dms-assets-test-1234');
|
$this->delete(BASE_PATH . DIRECTORY_SEPARATOR . 'dms-assets-test-1234');
|
||||||
|
|
||||||
|
$this->dms = DMS::inst();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown()
|
public function tearDown()
|
||||||
@ -82,10 +89,8 @@ class DMSTest extends FunctionalTest
|
|||||||
|
|
||||||
public function testDMSStorage()
|
public function testDMSStorage()
|
||||||
{
|
{
|
||||||
$dms = DMS::inst();
|
|
||||||
|
|
||||||
$file = self::$testFile;
|
$file = self::$testFile;
|
||||||
$document = $dms->storeDocument($file);
|
$document = $this->dms->storeDocument($file);
|
||||||
|
|
||||||
$this->assertNotNull($document, "Document object created");
|
$this->assertNotNull($document, "Document object created");
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
@ -100,13 +105,11 @@ class DMSTest extends FunctionalTest
|
|||||||
public function testDMSFolderSpanning()
|
public function testDMSFolderSpanning()
|
||||||
{
|
{
|
||||||
DMS::$dmsFolderSize = 5;
|
DMS::$dmsFolderSize = 5;
|
||||||
$dms = DMS::inst();
|
|
||||||
|
|
||||||
$file = self::$testFile;
|
$file = self::$testFile;
|
||||||
|
|
||||||
$documents = array();
|
$documents = array();
|
||||||
for ($i = 0; $i <= 16; $i++) {
|
for ($i = 0; $i <= 16; $i++) {
|
||||||
$document = $dms->storeDocument($file);
|
$document = $this->dms->storeDocument($file);
|
||||||
$this->assertNotNull($document, "Document object created on run number: $i");
|
$this->assertNotNull($document, "Document object created on run number: $i");
|
||||||
$this->assertTrue(file_exists($document->getFullPath()));
|
$this->assertTrue(file_exists($document->getFullPath()));
|
||||||
$documents[] = $document;
|
$documents[] = $document;
|
||||||
@ -131,10 +134,8 @@ class DMSTest extends FunctionalTest
|
|||||||
|
|
||||||
public function testReplaceDocument()
|
public function testReplaceDocument()
|
||||||
{
|
{
|
||||||
$dms = DMS::inst();
|
|
||||||
|
|
||||||
// Store the first document
|
// Store the first document
|
||||||
$document = $dms->storeDocument(self::$testFile);
|
$document = $this->dms->storeDocument(self::$testFile);
|
||||||
$document->Title = "My custom title";
|
$document->Title = "My custom title";
|
||||||
$document->Description = "My custom description";
|
$document->Description = "My custom description";
|
||||||
$document->write();
|
$document->write();
|
||||||
@ -158,4 +159,39 @@ class DMSTest extends FunctionalTest
|
|||||||
$this->assertEquals("My custom title", $document->Title, "Custom title not modified");
|
$this->assertEquals("My custom title", $document->Title, "Custom title not modified");
|
||||||
$this->assertEquals("My custom description", $document->Description, "Custom description not modified");
|
$this->assertEquals("My custom description", $document->Description, "Custom description not modified");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that documents can be returned by a given page
|
||||||
|
*/
|
||||||
|
public function testGetByPageWithoutEmbargoes()
|
||||||
|
{
|
||||||
|
$pageWithEmbargoes = $this->objFromFixture('SiteTree', 's3');
|
||||||
|
$documents = $this->dms->getByPage($pageWithEmbargoes);
|
||||||
|
// Fixture: 3 documents in set, 1 is embargoed
|
||||||
|
$this->assertCount(2, $documents, 'Embargoed documents are excluded by default');
|
||||||
|
$this->assertContainsOnlyInstancesOf('DMSDocument', $documents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that embargoed documents are excluded from getByPage
|
||||||
|
*/
|
||||||
|
public function testGetByPageWithEmbargoedDocuments()
|
||||||
|
{
|
||||||
|
$pageWithEmbargoes = $this->objFromFixture('SiteTree', 's3');
|
||||||
|
$documents = $this->dms->getByPage($pageWithEmbargoes, true);
|
||||||
|
// Fixture: 3 documents in set, 1 is embargoed
|
||||||
|
$this->assertCount(3, $documents, 'Embargoed documents can be included');
|
||||||
|
$this->assertContainsOnlyInstancesOf('DMSDocument', $documents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that document sets can be retrieved for a given page
|
||||||
|
*/
|
||||||
|
public function testGetDocumentSetsByPage()
|
||||||
|
{
|
||||||
|
$page = $this->objFromFixture('SiteTree', 's1');
|
||||||
|
$sets = $this->dms->getDocumentSetsByPage($page);
|
||||||
|
$this->assertCount(2, $sets);
|
||||||
|
$this->assertContainsOnlyInstancesOf('DMSDocumentSet', $sets);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,38 @@
|
|||||||
class StubRelatedDocumentExtension extends DataExtension implements TestOnly
|
class StubRelatedDocumentExtension extends DataExtension implements TestOnly
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Push a fixed array entry into the datalist for extensibility testing
|
* For method {@link DMSDocument::getRelatedDocuments}
|
||||||
*
|
*
|
||||||
* @param ArrayList $relatedDocuments
|
* @param ArrayList $relatedDocuments
|
||||||
* @return ArrayList
|
* @return ArrayList
|
||||||
*/
|
*/
|
||||||
public function updateRelatedDocuments(ArrayList $relatedDocuments)
|
public function updateRelatedDocuments($relatedDocuments)
|
||||||
|
{
|
||||||
|
$relatedDocuments->push($this->getFakeDocument());
|
||||||
|
return $relatedDocuments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For method {@link DMSDocumentSet::getDocuments}
|
||||||
|
*
|
||||||
|
* @param ArrayList $relatedDocuments
|
||||||
|
* @return ArrayList
|
||||||
|
*/
|
||||||
|
public function updateDocuments($documents)
|
||||||
|
{
|
||||||
|
$documents->push($this->getFakeDocument());
|
||||||
|
return $documents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a dummy document for testing purposes
|
||||||
|
*
|
||||||
|
* @return DMSDocument
|
||||||
|
*/
|
||||||
|
protected function getFakeDocument()
|
||||||
{
|
{
|
||||||
$fakeDocument = new DMSDocument;
|
$fakeDocument = new DMSDocument;
|
||||||
$fakeDocument->Filename = 'Extended';
|
$fakeDocument->Filename = 'Extended';
|
||||||
$relatedDocuments->push($fakeDocument);
|
return $fakeDocument;
|
||||||
return $relatedDocuments;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
|
DMSDocumentSet:
|
||||||
|
ds1:
|
||||||
|
Title: Document Set 1
|
||||||
SiteTree:
|
SiteTree:
|
||||||
s1:
|
s1:
|
||||||
Title: testPage1
|
Title: testPage1
|
||||||
URLSegment: s1
|
URLSegment: s1
|
||||||
|
DocumentSets: =>DMSDocumentSet.ds1
|
||||||
s2:
|
s2:
|
||||||
Title: testPage2
|
Title: testPage2
|
||||||
URLSegment: s2
|
URLSegment: s2
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
SiteTree:
|
SiteTree:
|
||||||
s1:
|
s1:
|
||||||
Title: testPage1
|
Title: testPage1 has document sets
|
||||||
URLSegment: s1
|
URLSegment: s1
|
||||||
s2:
|
s2:
|
||||||
Title: testPage2
|
Title: testPage2 has document sets
|
||||||
URLSegment: s2
|
URLSegment: s2
|
||||||
s3:
|
s3:
|
||||||
Title: testPage3
|
Title: testPage3 has document sets with embargoed docs
|
||||||
URLSegment: s3
|
URLSegment: s3
|
||||||
s4:
|
s4:
|
||||||
Title: testPage4
|
Title: testPage4 has no sets
|
||||||
URLSegment: s4
|
URLSegment: s4
|
||||||
s5:
|
s5:
|
||||||
Title: testPage5
|
Title: testPage5 has no sets
|
||||||
URLSegment: s5
|
URLSegment: s5
|
||||||
s6:
|
s6:
|
||||||
Title: testPage6
|
Title: testPage6 has no sets
|
||||||
URLSegment: s6
|
URLSegment: s6
|
||||||
DMSTag:
|
DMSTag:
|
||||||
t1:
|
t1:
|
||||||
@ -43,17 +43,30 @@ Group:
|
|||||||
cable-guy:
|
cable-guy:
|
||||||
Code: cable-guy
|
Code: cable-guy
|
||||||
Title: "Cable Guy"
|
Title: "Cable Guy"
|
||||||
|
DMSDocumentSet:
|
||||||
|
ds1:
|
||||||
|
Title: Document Set 1
|
||||||
|
Page: =>SiteTree.s1
|
||||||
|
ds2:
|
||||||
|
Title: Document Set 2
|
||||||
|
Page: =>SiteTree.s1
|
||||||
|
ds3:
|
||||||
|
Title: Document Set 3
|
||||||
|
Page: =>SiteTree.s2
|
||||||
|
ds4:
|
||||||
|
Title: Set containing embargoed documents
|
||||||
|
Page: =>SiteTree.s3
|
||||||
DMSDocument:
|
DMSDocument:
|
||||||
d1:
|
d1:
|
||||||
Filename: test-file-file-doesnt-exist-1
|
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
|
Sets: =>DMSDocumentSet.ds1, =>DMSDocumentSet.ds2, =>DMSDocumentSet.ds3, =>DMSDocumentSet.ds4
|
||||||
d2:
|
d2:
|
||||||
Filename: test-file-file-doesnt-exist-2
|
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
|
Sets: =>DMSDocumentSet.ds1, =>DMSDocumentSet.ds2, =>DMSDocumentSet.ds3, =>DMSDocumentSet.ds4
|
||||||
document_with_relations:
|
document_with_relations:
|
||||||
Filename: file-with-relations
|
Filename: file-with-relations
|
||||||
Folder: 5
|
Folder: 5
|
||||||
@ -80,6 +93,11 @@ DMSDocument:
|
|||||||
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
|
||||||
ViewerGroups: =>Group.content-author
|
ViewerGroups: =>Group.content-author
|
||||||
EditorGroups: =>Group.content-author
|
EditorGroups: =>Group.content-author
|
||||||
|
embargoed_document1:
|
||||||
|
Filename: foobar
|
||||||
|
EmbargoedIndefinitely: true
|
||||||
|
Folder: 5
|
||||||
|
Sets: =>DMSDocumentSet.ds4
|
||||||
Member:
|
Member:
|
||||||
editor:
|
editor:
|
||||||
Name: editor
|
Name: editor
|
||||||
|
Loading…
Reference in New Issue
Block a user