mirror of
https://github.com/silverstripe/silverstripe-dms
synced 2024-10-22 14:05:56 +02:00
8d4b24b68d
This fix is quite ugly, but in theory, it's fine. By ugly, I mean the interface is kind of weird without it. Because 3.1 allows uploading when a DataObject doesn't exist, we need to override the new defaults to not allow such if the DO isn't saved yet.
207 lines
6.2 KiB
PHP
207 lines
6.2 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Field for uploading files into a DMSDocument. Replacing the existing file.
|
|
* Not ideally suited for the purpose, as the base implementation
|
|
* assumes to operate on a {@link File} record. We only use this as
|
|
* a temporary container, which gets deleted as soon as the actual
|
|
* {@link DMSDocument} is created.
|
|
*
|
|
* <b>NOTE: this Field will call write() on the supplied record</b>
|
|
*
|
|
* @author Julian Seidenberg
|
|
* @package dms
|
|
*/
|
|
class DMSUploadField extends UploadField {
|
|
private static $allowed_actions = array (
|
|
"upload",
|
|
);
|
|
|
|
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
|
|
* add it into the DMS storage, deleting the old/uploaded file.
|
|
* @param File
|
|
*/
|
|
protected function attachFile($file) {
|
|
$dms = DMS::inst();
|
|
$record = $this->getRecord();
|
|
|
|
if($record instanceof DMSDocument) {
|
|
// If the edited record is a document,
|
|
// assume we're replacing an existing file
|
|
$doc = $record;
|
|
$doc->ingestFile($file);
|
|
} else {
|
|
// Otherwise create it
|
|
$doc = $dms->storeDocument($file);
|
|
$file->delete();
|
|
// Relate to the underlying page being edited.
|
|
// Not applicable when editing the document itself and replacing it.
|
|
$doc->addPage($record);
|
|
}
|
|
|
|
return $doc;
|
|
}
|
|
|
|
public function validate($validator) {
|
|
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
|
|
*
|
|
* @param SS_HTTPRequest $request
|
|
* @return string json
|
|
*/
|
|
public function upload(SS_HTTPRequest $request) {
|
|
if($this->isDisabled() || $this->isReadonly()) return $this->httpError(403);
|
|
|
|
// Protect against CSRF on destructive action
|
|
$token = $this->getForm()->getSecurityToken();
|
|
if(!$token->checkRequest($request)) return $this->httpError(400);
|
|
|
|
$name = $this->getName();
|
|
$tmpfile = $request->postVar($name);
|
|
$record = $this->getRecord();
|
|
|
|
// Check if the file has been uploaded into the temporary storage.
|
|
if (!$tmpfile) {
|
|
$return = array('error' => _t('UploadField.FIELDNOTSET', 'File information not found'));
|
|
} else {
|
|
$return = array(
|
|
'name' => $tmpfile['name'],
|
|
'size' => $tmpfile['size'],
|
|
'type' => $tmpfile['type'],
|
|
'error' => $tmpfile['error']
|
|
);
|
|
}
|
|
|
|
// Check for constraints on the record to which the file will be attached.
|
|
if (!$return['error'] && $this->relationAutoSetting && $record && $record->exists()) {
|
|
$tooManyFiles = false;
|
|
// Some relationships allow many files to be attached.
|
|
if ($this->getConfig('allowedMaxFileNumber') && ($record->has_many($name) || $record->many_many($name))) {
|
|
if(!$record->isInDB()) $record->write();
|
|
$tooManyFiles = $record->{$name}()->count() >= $this->getConfig('allowedMaxFileNumber');
|
|
// has_one only allows one file at any given time.
|
|
} elseif($record->has_one($name)) {
|
|
$tooManyFiles = $record->{$name}() && $record->{$name}()->exists();
|
|
}
|
|
|
|
// Report the constraint violation.
|
|
if ($tooManyFiles) {
|
|
if(!$this->getConfig('allowedMaxFileNumber')) $this->setConfig('allowedMaxFileNumber', 1);
|
|
$return['error'] = _t(
|
|
'UploadField.MAXNUMBEROFFILES',
|
|
'Max number of {count} file(s) exceeded.',
|
|
array('count' => $this->getConfig('allowedMaxFileNumber'))
|
|
);
|
|
}
|
|
}
|
|
|
|
// Process the uploaded file
|
|
if (!$return['error']) {
|
|
$fileObject = null;
|
|
|
|
if ($this->relationAutoSetting) {
|
|
// Search for relations that can hold the uploaded files.
|
|
if ($relationClass = $this->getRelationAutosetClass()) {
|
|
// Create new object explicitly. Otherwise rely on Upload::load to choose the class.
|
|
$fileObject = Object::create($relationClass);
|
|
}
|
|
}
|
|
|
|
// Get the uploaded file into a new file object.
|
|
try {
|
|
$this->upload->loadIntoFile($tmpfile, $fileObject, $this->folderName);
|
|
} catch (Exception $e) {
|
|
// we shouldn't get an error here, but just in case
|
|
$return['error'] = $e->getMessage();
|
|
}
|
|
|
|
if (!$return['error']) {
|
|
if ($this->upload->isError()) {
|
|
$return['error'] = implode(' '.PHP_EOL, $this->upload->getErrors());
|
|
} else {
|
|
$file = $this->upload->getFile();
|
|
|
|
// CUSTOM Attach the file to the related record.
|
|
$document = $this->attachFile($file);
|
|
|
|
// Collect all output data.
|
|
$return = array_merge($return, array(
|
|
'id' => $document->ID,
|
|
'name' => $document->getTitle(),
|
|
'thumbnail_url' => $document->Icon($document->getExtension()),
|
|
'edit_url' => $this->getItemHandler($document->ID)->EditLink(),
|
|
'size' => $document->getFileSizeFormatted(),
|
|
'buttons' => $document->renderWith($this->getTemplateFileButtons()),
|
|
'showeditform' => true
|
|
));
|
|
|
|
// CUSTOM END
|
|
}
|
|
}
|
|
}
|
|
$response = new SS_HTTPResponse(Convert::raw2json(array($return)));
|
|
$response->addHeader('Content-Type', 'text/plain');
|
|
return $response;
|
|
}
|
|
|
|
|
|
/**
|
|
* Never directly display items uploaded
|
|
* @return SS_List
|
|
*/
|
|
public function getItems() {
|
|
return new ArrayList();
|
|
}
|
|
|
|
public function Field($properties = array()) {
|
|
$fields = parent::Field($properties);
|
|
|
|
// 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');
|
|
Requirements::javascript('dms/javascript/DMSUploadField_downloadtemplate.js');
|
|
|
|
// In the add dialog, add the addtemplate into the set of file that load.
|
|
Requirements::javascript('dms/javascript/DMSUploadField_addtemplate.js');
|
|
|
|
return $fields;
|
|
}
|
|
|
|
/**
|
|
* @param int $itemID
|
|
* @return UploadField_ItemHandler
|
|
*/
|
|
public function getItemHandler($itemID) {
|
|
return DMSUploadField_ItemHandler::create($this, $itemID);
|
|
}
|
|
}
|
|
|
|
class DMSUploadField_ItemHandler extends UploadField_ItemHandler {
|
|
function getItem() {
|
|
return DataObject::get_by_id('DMSDocument', $this->itemID);
|
|
}
|
|
|
|
}
|