mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #1161 from chillu/pulls/uploadfield-replacefile
NEW Upload->replaceFile setting
This commit is contained in:
commit
af52de97e9
6
_config/config.yml
Normal file
6
_config/config.yml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
Name: coreconfig
|
||||
---
|
||||
Upload:
|
||||
# Replace an existing file rather than renaming the new one.
|
||||
replaceFile: false
|
@ -219,6 +219,13 @@ editform, or 'fileEditValidator' to determine the validator (eg RequiredFields).
|
||||
(of a method on File to provide a actions) for the EditForm (Example: 'getCMSActions')
|
||||
- `fileEditValidator`: (string) Validator (eg RequiredFields) or string $name
|
||||
(of a method on File to provide a Validator) for the EditForm (Example: 'getCMSValidator')
|
||||
|
||||
You can also configure the underlying `[api:Upload]` class, by using the YAML config system.
|
||||
|
||||
:::yaml
|
||||
Upload:
|
||||
# Globally disables automatic renaming of files
|
||||
replaceFile: true
|
||||
|
||||
## TODO: Using the UploadField in a frontend form
|
||||
|
||||
|
@ -45,6 +45,12 @@ class Upload extends Controller {
|
||||
* @var array
|
||||
*/
|
||||
protected $tmpFile;
|
||||
|
||||
/**
|
||||
* Replace an existing file rather than renaming the new one.
|
||||
* @var Boolean
|
||||
*/
|
||||
protected $replaceFile;
|
||||
|
||||
/**
|
||||
* Processing errors that can be evaluated,
|
||||
@ -61,10 +67,11 @@ class Upload extends Controller {
|
||||
* @var string
|
||||
*/
|
||||
public static $uploads_folder = "Uploads";
|
||||
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->validator = new Upload_Validator();
|
||||
$this->replaceFile = $this->config()->get('replaceFile');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,11 +107,6 @@ class Upload extends Controller {
|
||||
|
||||
if(!$folderPath) $folderPath = self::$uploads_folder;
|
||||
|
||||
if(!$this->file) {
|
||||
$fileClass = File::get_class_for_file_extension(pathinfo($tmpFile['name'], PATHINFO_EXTENSION));
|
||||
$this->file = new $fileClass();
|
||||
}
|
||||
|
||||
if(!is_array($tmpFile)) {
|
||||
user_error("Upload::load() Not passed an array. Most likely, the form hasn't got the right enctype",
|
||||
E_USER_ERROR);
|
||||
@ -137,25 +139,40 @@ class Upload extends Controller {
|
||||
$fileName = basename($file);
|
||||
|
||||
$relativeFilePath = ASSETS_DIR . "/" . $folderPath . "/$fileName";
|
||||
|
||||
// Create a new file record (or try to retrieve an existing one)
|
||||
if(!$this->file) {
|
||||
$fileClass = File::get_class_for_file_extension(pathinfo($tmpFile['name'], PATHINFO_EXTENSION));
|
||||
if($this->replaceFile) {
|
||||
$this->file = File::get()
|
||||
->filter(array(
|
||||
'Name' => $fileName,
|
||||
'ParentID' => $parentFolder ? $parentFolder->ID : 0
|
||||
))->First();
|
||||
}
|
||||
if(!$this->file) $this->file = new $fileClass();
|
||||
}
|
||||
|
||||
// if filename already exists, version the filename (e.g. test.gif to test1.gif)
|
||||
while(file_exists("$base/$relativeFilePath")) {
|
||||
$i = isset($i) ? ($i+1) : 2;
|
||||
$oldFilePath = $relativeFilePath;
|
||||
// make sure archives retain valid extensions
|
||||
if(substr($relativeFilePath, strlen($relativeFilePath) - strlen('.tar.gz')) == '.tar.gz' ||
|
||||
substr($relativeFilePath, strlen($relativeFilePath) - strlen('.tar.bz2')) == '.tar.bz2') {
|
||||
$relativeFilePath = preg_replace('/[0-9]*(\.tar\.[^.]+$)/', $i . '\\1', $relativeFilePath);
|
||||
} else if (strpos($relativeFilePath, '.') !== false) {
|
||||
$relativeFilePath = preg_replace('/[0-9]*(\.[^.]+$)/', $i . '\\1', $relativeFilePath);
|
||||
} else if (strpos($relativeFilePath, '_') !== false) {
|
||||
$relativeFilePath = preg_replace('/_([^_]+$)/', '_'.$i, $relativeFilePath);
|
||||
} else {
|
||||
$relativeFilePath .= '_'.$i;
|
||||
}
|
||||
if($oldFilePath == $relativeFilePath && $i > 2) {
|
||||
user_error("Couldn't fix $relativeFilePath with $i tries", E_USER_ERROR);
|
||||
}
|
||||
if(!$this->replaceFile) {
|
||||
while(file_exists("$base/$relativeFilePath")) {
|
||||
$i = isset($i) ? ($i+1) : 2;
|
||||
$oldFilePath = $relativeFilePath;
|
||||
// make sure archives retain valid extensions
|
||||
if(substr($relativeFilePath, strlen($relativeFilePath) - strlen('.tar.gz')) == '.tar.gz' ||
|
||||
substr($relativeFilePath, strlen($relativeFilePath) - strlen('.tar.bz2')) == '.tar.bz2') {
|
||||
$relativeFilePath = preg_replace('/[0-9]*(\.tar\.[^.]+$)/', $i . '\\1', $relativeFilePath);
|
||||
} else if (strpos($relativeFilePath, '.') !== false) {
|
||||
$relativeFilePath = preg_replace('/[0-9]*(\.[^.]+$)/', $i . '\\1', $relativeFilePath);
|
||||
} else if (strpos($relativeFilePath, '_') !== false) {
|
||||
$relativeFilePath = preg_replace('/_([^_]+$)/', '_'.$i, $relativeFilePath);
|
||||
} else {
|
||||
$relativeFilePath .= '_'.$i;
|
||||
}
|
||||
if($oldFilePath == $relativeFilePath && $i > 2) {
|
||||
user_error("Couldn't fix $relativeFilePath with $i tries", E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(file_exists($tmpFile['tmp_name']) && copy($tmpFile['tmp_name'], "$base/$relativeFilePath")) {
|
||||
@ -181,6 +198,20 @@ class Upload extends Controller {
|
||||
$this->file = $file;
|
||||
return $this->load($tmpFile, $folderPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Boolean
|
||||
*/
|
||||
public function setReplaceFile($bool) {
|
||||
$this->replaceFile = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Boolean
|
||||
*/
|
||||
public function getReplaceFile() {
|
||||
return $this->replaceFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Container for all validation on the file
|
||||
|
@ -78,7 +78,7 @@ class FileField extends FormField {
|
||||
* @param int $value The value of the field.
|
||||
*/
|
||||
public function __construct($name, $title = null, $value = null) {
|
||||
$this->upload = new Upload();
|
||||
$this->upload = Upload::create();
|
||||
|
||||
parent::__construct($name, $title, $value);
|
||||
}
|
||||
|
@ -316,6 +316,62 @@ class UploadTest extends SapphireTest {
|
||||
$file2->delete();
|
||||
}
|
||||
|
||||
public function testReplaceFile() {
|
||||
// create tmp file
|
||||
$tmpFileName = 'UploadTest-testUpload';
|
||||
$tmpFilePath = TEMP_FOLDER . '/' . $tmpFileName;
|
||||
$tmpFileContent = '';
|
||||
for($i=0; $i<10000; $i++) $tmpFileContent .= '0';
|
||||
file_put_contents($tmpFilePath, $tmpFileContent);
|
||||
|
||||
// emulates the $_FILES array
|
||||
$tmpFile = array(
|
||||
'name' => $tmpFileName,
|
||||
'type' => 'text/plaintext',
|
||||
'size' => filesize($tmpFilePath),
|
||||
'tmp_name' => $tmpFilePath,
|
||||
'extension' => 'txt',
|
||||
'error' => UPLOAD_ERR_OK,
|
||||
);
|
||||
|
||||
// Make sure there are none here, otherwise they get renamed incorrectly for the test.
|
||||
$this->deleteTestUploadFiles("/UploadTest-testUpload.*/");
|
||||
|
||||
$v = new UploadTest_Validator();
|
||||
$v->setAllowedExtensions(array(''));
|
||||
|
||||
// test upload into default folder
|
||||
$u = new Upload();
|
||||
$u->setValidator($v);
|
||||
$u->load($tmpFile);
|
||||
$file = $u->getFile();
|
||||
|
||||
$this->assertEquals(
|
||||
'UploadTest-testUpload',
|
||||
$file->Name,
|
||||
'File is uploaded without extension'
|
||||
);
|
||||
|
||||
$u = new Upload();
|
||||
$u->setValidator($v);
|
||||
$u->setReplaceFile(true);
|
||||
$u->load($tmpFile);
|
||||
$file2 = $u->getFile();
|
||||
$this->assertEquals(
|
||||
'UploadTest-testUpload',
|
||||
$file2->Name,
|
||||
'File does not receive new name'
|
||||
);
|
||||
$this->assertEquals(
|
||||
$file->ID,
|
||||
$file2->ID,
|
||||
'File database record is the same'
|
||||
);
|
||||
|
||||
$file->delete();
|
||||
$file2->delete();
|
||||
}
|
||||
|
||||
}
|
||||
class UploadTest_Validator extends Upload_Validator implements TestOnly {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user