diff --git a/_config.php b/_config.php
index 6d59e6c..b288829 100644
--- a/_config.php
+++ b/_config.php
@@ -15,11 +15,11 @@ if (!file_exists(BASE_PATH . DIRECTORY_SEPARATOR . DMS_DIR)) {
CMSMenu::remove_menu_item('DMSDocumentAddController');
ShortcodeParser::get('default')->register(
- 'dms_document_link',
+ 'dms_document_link',
array('DMSShortcodeHandler', 'handle')
);
if ($config->get('DMSDocument_versions', 'enable_versions')) {
- //using the same db relations for the versioned documents, as for the actual documents
- $config->update('DMSDocument_versions', 'db', $config->get('DMSDocument', 'db'));
+ //using the same db relations for the versioned documents, as for the actual documents
+ $config->update('DMSDocument_versions', 'db', $config->get('DMSDocument', 'db'));
}
diff --git a/code/model/DMSDocument.php b/code/model/DMSDocument.php
index 95961ba..6a565e9 100644
--- a/code/model/DMSDocument.php
+++ b/code/model/DMSDocument.php
@@ -2,6 +2,26 @@
/**
* @package dms
+ *
+ * @property Varchar Filename
+ * @property Varchar Folder
+ * @property Varchar Title
+ * @property Text Description
+ * @property int ViewCount
+ * @property DateTime LastChanged
+ * @property Boolean EmbargoedIndefinitely
+ * @property Boolean EmbargoedUntilPublished
+ * @property DateTime EmbargoedUntilDate
+ * @property DateTime ExpireAtDate
+ * @property Enum DownloadBehavior
+ * @property Enum CanViewType Enum('Anyone, LoggedInUsers, OnlyTheseUsers', 'Anyone')
+ * @property Enum CanEditType Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')
+ *
+ * @method ManyManyList RelatedDocuments
+ * @method ManyManyList Tags
+ * @method ManyManyList ViewerGroups
+ * @method ManyManyList EditorGroups
+ *
*/
class DMSDocument extends DataObject implements DMSDocumentInterface
{
@@ -19,12 +39,16 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
"EmbargoedUntilDate" => 'SS_DateTime',
"ExpireAtDate" => 'SS_DateTime',
"DownloadBehavior" => 'Enum(array("open","download"), "download")',
+ "CanViewType" => "Enum('Anyone, LoggedInUsers, OnlyTheseUsers', 'Anyone')",
+ "CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
);
private static $many_many = array(
'Pages' => 'SiteTree',
'RelatedDocuments' => 'DMSDocument',
- 'Tags' => 'DMSTag'
+ 'Tags' => 'DMSTag',
+ 'ViewerGroups' => 'Group',
+ 'EditorGroups' => 'Group',
);
private static $many_many_extraFields = array(
@@ -67,11 +91,6 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
*/
private static $default_download_behaviour = 'download';
- /**
- * @param Member $member
- *
- * @return boolean
- */
public function canView($member = null)
{
if (!$member || !(is_a($member, 'Member')) || is_numeric($member)) {
@@ -87,18 +106,36 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
}
}
- if ($member && $member->ID) {
+ if (!$this->CanViewType || $this->CanViewType == 'Anyone') {
return true;
}
- return false;
+ if ($member && Permission::checkMember($member,
+ array(
+ 'ADMIN',
+ 'SITETREE_EDIT_ALL',
+ 'SITETREE_VIEW_ALL',
+ )
+ )
+ ) {
+ return true;
+ }
+
+ if ($this->isHidden()) {
+ return false;
+ }
+
+ if ($this->CanViewType == 'LoggedInUsers') {
+ return $member && $member->exists();
+ }
+
+ if ($this->CanViewType == 'OnlyTheseUsers' && $this->ViewerGroups()->count()) {
+ return ($member && $member->inGroups($this->ViewerGroups()));
+ }
+
+ return $this->canEdit($member);
}
- /**
- * @param Member $member
- *
- * @return boolean
- */
public function canEdit($member = null)
{
if (!$member || !(is_a($member, 'Member')) || is_numeric($member)) {
@@ -113,7 +150,27 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
}
}
- return $this->canView();
+ // Do early admin check
+ if ($member && Permission::checkMember($member,
+ array(
+ 'ADMIN',
+ 'SITETREE_EDIT_ALL',
+ 'SITETREE_VIEW_ALL',
+ )
+ )
+ ) {
+ return true;
+ }
+
+ if ($this->CanEditType === 'LoggedInUsers') {
+ return $member && $member->exists();
+ }
+
+ if ($this->CanEditType === 'OnlyTheseUsers' && $this->EditorGroups()->count()) {
+ return $member && $member->inGroups($this->EditorGroups());
+ }
+
+ return ($member && Permission::checkMember($member, array('ADMIN', 'SITETREE_EDIT_ALL')));
}
/**
@@ -135,7 +192,7 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
}
}
- return $this->canView();
+ return $this->canEdit($member);
}
/**
@@ -294,7 +351,7 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
* @param string $category of a metadata category to add (required)
* @param string $value of a metadata value to add (required)
* @param bool $multiValue Boolean that determines if the category is
- * multi-value or single-value (optional)
+ * multi-value or single-value (optional)
*
* @return DMSDocument
*/
@@ -445,12 +502,30 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
/**
* Returns a link to download this document from the DMS store.
+ * Alternatively a basic javascript alert will be shown should the user not have view permissions. An extension
+ * point for this was also added.
+ *
+ * To extend use the following from within an Extension subclass:
+ *
+ *
+ * public function updateGetLink($result)
+ * {
+ * // Do something here
+ * }
+ *
*
* @return string
*/
public function getLink()
{
- return Controller::join_links(Director::baseURL(), 'dmsdocument/'.$this->ID);
+ $result = Controller::join_links(Director::baseURL(), 'dmsdocument/' . $this->ID);
+ if (!$this->canView()) {
+ $result = sprintf("javascript:alert('%s')", $this->getPermissionDeniedReason());
+ }
+
+ $this->extend('updateGetLink', $result);
+
+ return $result;
}
/**
@@ -1095,14 +1170,52 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
$actionsPanel->setName("ActionsPanel");
$actionsPanel->addExtraClass("DMSDocumentActionsPanel");
-
$fields->push($actionsPanel);
+ $this->addPermissionsFields($fields);
$this->extend('updateCMSFields', $fields);
return $fields;
}
+ /**
+ * Adds permissions selection fields to the FieldList.
+ *
+ * @param FieldList $fields
+ */
+ public function addPermissionsFields($fields)
+ {
+ $showFields = array(
+ 'CanViewType' => '',
+ 'ViewerGroups' => 'hide',
+ 'CanEditType' => '',
+ 'EditorGroups' => 'hide',
+ );
+ /** @var SiteTree $siteTree */
+ $siteTree = singleton('SiteTree');
+ $settingsFields = $siteTree->getSettingsFields();
+
+ foreach ($showFields as $name => $extraCss) {
+ $compositeName = "Root.Settings.$name";
+ /** @var FormField $field */
+ if ($field = $settingsFields->fieldByName($compositeName)) {
+ $field->addExtraClass($extraCss);
+ $title = str_replace('page', 'document', $field->Title());
+ $field->setTitle($title);
+
+ // Remove Inherited source option from DropdownField
+ if ($field instanceof DropdownField) {
+ $options = $field->getSource();
+ unset($options['Inherit']);
+ $field->setSource($options);
+ }
+ $fields->push($field);
+ }
+ }
+
+ $this->extend('updatePermissionsFields', $fields);
+ }
+
public function onBeforeWrite()
{
parent::onBeforeWrite();
@@ -1329,4 +1442,55 @@ class DMSDocument extends DataObject implements DMSDocumentInterface
return $gridField;
}
+
+ /**
+ * Checks at least one group is selected if CanViewType || CanEditType == 'OnlyTheseUsers'
+ *
+ * @return ValidationResult
+ */
+ protected function validate()
+ {
+ $valid = parent::validate();
+
+ if ($this->CanViewType == 'OnlyTheseUsers' && !$this->ViewerGroups()->count()) {
+ $valid->error(
+ _t(
+ 'DMSDocument.VALIDATIONERROR_NOVIEWERSELECTED',
+ "Selecting 'Only these people' from a viewers list needs at least one group selected."
+ )
+ );
+ }
+
+ if ($this->CanEditType == 'OnlyTheseUsers' && !$this->EditorGroups()->count()) {
+ $valid->error(
+ _t(
+ 'DMSDocument.VALIDATIONERROR_NOEDITORSELECTED',
+ "Selecting 'Only these people' from a editors list needs at least one group selected."
+ )
+ );
+ }
+
+ return $valid;
+ }
+
+ /**
+ * Returns a reason as to why this document cannot be viewed.
+ *
+ * @return string
+ */
+ public function getPermissionDeniedReason()
+ {
+ $result = '';
+
+ if ($this->CanViewType == 'LoggedInUsers') {
+ $result = _t('DMSDocument.PERMISSIONDENIEDREASON_LOGINREQUIRED', 'Please log in to view this document');
+ }
+
+ if ($this->CanViewType == 'OnlyTheseUsers') {
+ $result = _t('DMSDocument.PERMISSIONDENIEDREASON_NOTAUTHORISED',
+ 'You are not authorised to view this document');
+ }
+
+ return $result;
+ }
}
diff --git a/code/model/DMSDocument_Controller.php b/code/model/DMSDocument_Controller.php
index ab32db2..7fa4f0b 100644
--- a/code/model/DMSDocument_Controller.php
+++ b/code/model/DMSDocument_Controller.php
@@ -54,39 +54,9 @@ class DMSDocument_Controller extends Controller
{
$doc = $this->getDocumentFromID($request);
+
if (!empty($doc)) {
- $canView = false;
-
- // Runs through all pages that this page links to and sets canView
- // to true if the user can view ONE of these pages
- if (method_exists($doc, 'Pages')) {
- $pages = $doc->Pages();
- if ($pages->Count() > 0) {
- foreach ($pages as $page) {
- if ($page->CanView()) {
- // just one canView is enough to know that we can
- // view the file
- $canView = true;
- break;
- }
- }
- } else {
- // if the document isn't on any page, then allow viewing of
- // the document (because there is no canView() to consult)
- $canView = true;
- }
- }
-
- // check for embargo or expiry
- if ($doc->isHidden()) {
- $canView = false;
- }
-
- //admins can always download any document, even if otherwise hidden
- $member = Member::currentUser();
- if ($member && Permission::checkMember($member, 'ADMIN')) {
- $canView = true;
- }
+ $canView = $doc->canView();
if ($canView) {
$path = $doc->getFullPath();
@@ -129,8 +99,7 @@ class DMSDocument_Controller extends Controller
//its ViewCount should be increased by 1 just before the browser sending the file to front.
$doc->trackView();
- $this->sendFile($path, $mime, $doc->getFilenameWithoutID(), $disposition);
- return;
+ return $this->sendFile($path, $mime, $doc->getFilenameWithoutID(), $disposition);
}
}
}
diff --git a/javascript/DMSDocumentCMSFields.js b/javascript/DMSDocumentCMSFields.js
index ecbffde..82b138b 100644
--- a/javascript/DMSDocumentCMSFields.js
+++ b/javascript/DMSDocumentCMSFields.js
@@ -1,7 +1,7 @@
-(function ($) {
+(function($) {
"use strict";
- $.entwine('ss', function ($) {
+ $.entwine('ss', function($) {
$('#DocumentTypeID ul li').entwine({
onadd: function () {
@@ -11,7 +11,7 @@
this.addClass('selected');
}
},
- onclick: function (e) {
+ onclick: function(e) {
$('#DocumentTypeID').find('li.selected').removeClass('selected');
this.find('input').prop("checked", true);
this.addClass('selected');
@@ -34,7 +34,22 @@
}
}
});*/
-
+ $('#CanViewType input, #CanEditType input').entwine({
+ onchange: function () {
+ var dropDown = $(this).closest('.field').next();
+ if ($(this).val() === 'OnlyTheseUsers') {
+ dropDown.removeClass('hide');
+ } else {
+ dropDown.addClass('hide');
+ }
+ },
+ onadd: function () {
+ if ($(this).is(':checked') && $(this).val() === 'OnlyTheseUsers') {
+ var dropDown = $(this).closest('.field').next();
+ dropDown.removeClass('hide');
+ }
+ }
+ });
$('#Actions ul li').entwine({
onclick: function (e) {
@@ -56,7 +71,6 @@
$('#Form_ItemEditForm_Embargo input, #Form_EditForm_Embargo input').entwine({
onchange: function () {
- console.log('called');
//selected the date options
if (this.attr('value') === 'Date') {
$('.embargoDatetime').children().show();
diff --git a/templates/Includes/Document.ss b/templates/Includes/Document.ss
index d074b01..2428804 100644
--- a/templates/Includes/Document.ss
+++ b/templates/Includes/Document.ss
@@ -1,4 +1,4 @@
-<% if $isHidden != true %>
+<% if not $isHidden %>