diff --git a/css/UploadField.css b/css/UploadField.css index 70e18efca..481d3f6df 100644 --- a/css/UploadField.css +++ b/css/UploadField.css @@ -16,8 +16,8 @@ Used in side panels and action tabs .ss-uploadfield .middleColumn { width: 526px; padding: 0; background: #fff; border: 1px solid #b3b3b3; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #efefef), color-stop(10%, #ffffff), color-stop(90%, #ffffff), color-stop(100%, #efefef)); background-image: -webkit-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -moz-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -o-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); } .ss-uploadfield .ss-uploadfield-item { margin: 0; padding: 15px; overflow: auto; } .ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-preview { height: 60px; line-height: 60px; width: 80px; text-align: center; font-weight: bold; float: left; overflow: hidden; } -.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-preview.ss-uploadfield-dropzone { -webkit-box-shadow: gray 0 0 4px 0 inset; -moz-box-shadow: gray 0 0 4px 0 inset; box-shadow: gray 0 0 4px 0 inset; border: 2px dashed gray; background: #d0d3d5; display: none; } -.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-info { margin: 0 0 0 100px; } +.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-preview.ss-uploadfield-dropzone { -webkit-box-shadow: gray 0 0 4px 0 inset; -moz-box-shadow: gray 0 0 4px 0 inset; box-shadow: gray 0 0 4px 0 inset; border: 2px dashed gray; background: #d0d3d5; display: none; margin-right: 15px; } +.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-info { float: left; } .ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name { display: block; line-height: 13px; height: 26px; margin: 0; text-align: left; } .ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name b { font-weight: bold; padding: 0 5px 0 0; } .ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .name { font-size: 11px; color: #848484; width: 290px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; display: inline; float: left; } diff --git a/forms/UploadField.php b/forms/UploadField.php index 272e9ce5b..c5374787f 100644 --- a/forms/UploadField.php +++ b/forms/UploadField.php @@ -81,6 +81,10 @@ class UploadField extends FileField { * @var int */ 'allowedMaxFileNumber' => null, + /** + * @var boolean Can the user upload new files, or just select from existing files. + */ + 'canUpload' => true, /** * @var int */ @@ -441,7 +445,9 @@ class UploadField extends FileField { * @return string json */ public function upload(SS_HTTPRequest $request) { - if($this->isDisabled() || $this->isReadonly()) return $this->httpError(403); + if($this->isDisabled() || $this->isReadonly() || !$this->canUpload()) { + return $this->httpError(403); + } // Protect against CSRF on destructive action $token = $this->getForm()->getSecurityToken(); @@ -629,6 +635,12 @@ class UploadField extends FileField { // Don't allow upload or edit of a relation when the underlying record hasn't been persisted yet return (!$record || !$this->managesRelation() || $record->exists()); } + + public function canUpload() { + $can = $this->getConfig('canUpload'); + return (is_bool($can)) ? $can : Permission::check($can); + } + } /** diff --git a/scss/UploadField.scss b/scss/UploadField.scss index d2474504e..d77dbe009 100644 --- a/scss/UploadField.scss +++ b/scss/UploadField.scss @@ -47,11 +47,12 @@ border: 2px dashed $color-medium-separator; background: $color-light-separator; display: none; + margin-right: 15px; } } .ss-uploadfield-item-info { - margin: 0 0 0 100px; - + float: left; + .ss-uploadfield-item-name { display: block; line-height: 13px; diff --git a/templates/UploadField.ss b/templates/UploadField.ss index 91cef77d6..aa3450f80 100644 --- a/templates/UploadField.ss +++ b/templates/UploadField.ss @@ -34,6 +34,7 @@ <% end_if %> <% else %>
style="display: none;"<% end_if %>> + <% if canUpload %>
<% if $multiple %> <% _t('UploadField.DROPFILES', 'drop files') %> @@ -41,6 +42,7 @@ <% _t('UploadField.DROPFILE', 'drop a file') %> <% end_if %>
+ <% end_if %>
- + <% if canUpload %> + + <% end_if %> <% if not $autoUpload %> diff --git a/tests/forms/uploadfield/UploadFieldTest.php b/tests/forms/uploadfield/UploadFieldTest.php index 2ceb16b17..8831e6206 100644 --- a/tests/forms/uploadfield/UploadFieldTest.php +++ b/tests/forms/uploadfield/UploadFieldTest.php @@ -476,6 +476,42 @@ class UploadFieldTest extends FunctionalTest { } + public function testCanUpload() { + $this->loginWithPermission('ADMIN'); + $response = $this->get('UploadFieldTest_Controller'); + $this->assertFalse($response->isError()); + + $parser = new CSSContentParser($response->getBody()); + $this->assertFalse( + (bool)$parser->getBySelector('#CanUploadFalseField .ss-uploadfield-fromcomputer-fileinput'), + 'Removes input file control' + ); + $this->assertFalse((bool)$parser->getBySelector('#CanUploadFalseField .ss-uploadfield-dropzone'), + 'Removes dropzone'); + $this->assertTrue( + (bool)$parser->getBySelector('#CanUploadFalseField .ss-uploadfield-fromfiles'), + 'Keeps "From files" button' + ); + } + + public function testCanUploadWithPermissionCode() { + $field = new UploadField('MyField'); + + $field->setConfig('canUpload', true); + $this->assertTrue($field->canUpload()); + + $field->setConfig('canUpload', false); + $this->assertFalse($field->canUpload()); + + $this->loginWithPermission('ADMIN'); + + $field->setConfig('canUpload', false); + $this->assertFalse($field->canUpload()); + + $field->setConfig('canUpload', 'ADMIN'); + $this->assertTrue($field->canUpload()); + } + public function testIsSaveable() { $form = $this->getMockForm(); @@ -775,6 +811,10 @@ class UploadFieldTest_Controller extends Controller implements TestOnly { $fieldSubfolder->setFolderName('UploadFieldTest/subfolder1'); $fieldSubfolder->setRecord($record); + $fieldCanUploadFalse = new UploadField('CanUploadFalseField'); + $fieldCanUploadFalse->setConfig('canUpload', false); + $fieldCanUploadFalse->setRecord($record); + $form = new Form( $this, 'Form', @@ -789,7 +829,8 @@ class UploadFieldTest_Controller extends Controller implements TestOnly { $fieldManyMany, $fieldReadonly, $fieldDisabled, - $fieldSubfolder + $fieldSubfolder, + $fieldCanUploadFalse ), new FieldList( new FormAction('submit') @@ -805,7 +846,8 @@ class UploadFieldTest_Controller extends Controller implements TestOnly { 'ManyManyFiles', 'ReadonlyField', 'DisabledField', - 'SubfolderField' + 'SubfolderField', + 'CanUploadFalseField' ) ); return $form;