Skip to content

Commit

Permalink
Merge pull request #341 from mateusz/uploadfield-hasone
Browse files Browse the repository at this point in the history
Uploadfield doesn't save into inherited Image Classes
  • Loading branch information
Sean Harvey committed Apr 19, 2012
2 parents a1327fa + a9e7de0 commit b8faa41
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 9 deletions.
44 changes: 40 additions & 4 deletions forms/UploadField.php
Expand Up @@ -432,6 +432,7 @@ public function upload(SS_HTTPRequest $request) {
$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 {
Expand All @@ -442,14 +443,20 @@ public function upload(SS_HTTPRequest $request) {
'error' => $tmpfile['error']
);
}
if (!$return['error'] && $record && $record->exists()) {

// 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'] = sprintf(_t(
Expand All @@ -458,20 +465,49 @@ public function upload(SS_HTTPRequest $request) {
), $this->getConfig('allowedMaxFileNumber'));
}
}

// Process the uploaded file
if (!$return['error']) {
$fileObject = null;

if ($this->relationAutoSetting) {
// Search for classes that can hold the uploaded files by traversing the relationship.
if ($record->hasMethod($name)) {
$remote = $record->$name();
if ($remote instanceof DataList) {
// has_many or many_many
$desiredClass = $remote->dataClass();
}
else if (is_object($remote)) {
// has_one
$desiredClass = $remote->ClassName;
}

// If we have a specific class, create new object explicitly. Otherwise rely on Upload::load to choose the class.
if (is_string($desiredClass)) $fileObject = Object::create($desiredClass);
}
}

// Get the uploaded file into a new file object.
try {
$this->upload->loadIntoFile($tmpfile, null, $this->folderName);
$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();
$file->write();
$this->attachFile($file);

// Attach the file to the related record.
if ($this->relationAutoSetting) {
$this->attachFile($file);
}

// Collect all output data.
$file = $this->customiseFile($file);
$return = array_merge($return, array(
'id' => $file->ID,
Expand Down
49 changes: 44 additions & 5 deletions tests/forms/uploadfield/UploadFieldTest.php
Expand Up @@ -28,7 +28,7 @@ function testUploadNoRelation() {
$this->assertFalse($response->isError());
$this->assertFileExists(ASSETS_PATH . "/UploadFieldTest/$tmpFileName");
$uploadedFile = DataObject::get_one('File', sprintf('"Name" = \'%s\'', $tmpFileName));
$this->assertNotNull($uploadedFile);
$this->assertTrue(is_object($uploadedFile), 'The file object is created');
}

function testUploadHasOneRelation() {
Expand All @@ -48,13 +48,38 @@ function testUploadHasOneRelation() {
$this->assertFalse($response->isError());
$this->assertFileExists(ASSETS_PATH . "/UploadFieldTest/$tmpFileName");
$uploadedFile = DataObject::get_one('File', sprintf('"Name" = \'%s\'', $tmpFileName));
$this->assertNotNull($uploadedFile);
$this->assertTrue(is_object($uploadedFile), 'The file object is created');

$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertTrue($record->HasOneFile()->exists());
$this->assertEquals($record->HasOneFile()->Name, $tmpFileName);
}

function testUploadHasOneRelationWithExtendedFile() {
$this->loginWithPermission('ADMIN');

// Unset existing has_one relation before re-uploading
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$record->HasOneExtendedFileID = null;
$record->write();

$tmpFileName = 'testUploadHasOneRelationWithExtendedFile.txt';
$_FILES = array('HasOneExtendedFile' => $this->getUploadFile($tmpFileName));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasOneExtendedFile/upload',
array('HasOneExtendedFile' => $this->getUploadFile($tmpFileName))
);
$this->assertFalse($response->isError());

$this->assertFileExists(ASSETS_PATH . "/UploadFieldTest/$tmpFileName");
$uploadedFile = DataObject::get_one('UploadFieldTest_ExtendedFile', sprintf('"Name" = \'%s\'', $tmpFileName));
$this->assertTrue(is_object($uploadedFile), 'The file object is created');

$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertTrue($record->HasOneExtendedFile()->exists(), 'The extended file is attached to the class');
$this->assertEquals($record->HasOneExtendedFile()->Name, $tmpFileName, 'Proper file has been attached');
}

function testUploadHasManyRelation() {
$this->loginWithPermission('ADMIN');

Expand All @@ -69,7 +94,7 @@ function testUploadHasManyRelation() {
$this->assertFalse($response->isError());
$this->assertFileExists(ASSETS_PATH . "/UploadFieldTest/$tmpFileName");
$uploadedFile = DataObject::get_one('File', sprintf('"Name" = \'%s\'', $tmpFileName));
$this->assertNotNull($uploadedFile);
$this->assertTrue(is_object($uploadedFile), 'The file object is created');

$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertEquals(3, $record->HasManyFiles()->Count());
Expand All @@ -91,7 +116,7 @@ function testUploadManyManyRelation() {
$this->assertFalse($response->isError());
$this->assertFileExists(ASSETS_PATH . "/UploadFieldTest/$tmpFileName");
$uploadedFile = DataObject::get_one('File', sprintf('"Name" = \'%s\'', $tmpFileName));
$this->assertNotNull($uploadedFile);
$this->assertTrue(is_object($uploadedFile), 'The file object is created');

$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertEquals($relationCount+1, $record->ManyManyFiles()->Count());
Expand Down Expand Up @@ -605,7 +630,7 @@ function tearDown() {
}

// Remove left over folders and any files that may exist
if(file_exists('../assets/UploadFieldTest')) Filesystem::removeFolder('../assets/FileTest');
if(file_exists('../assets/UploadFieldTest')) Filesystem::removeFolder('../assets/UploadFieldTest');
}

}
Expand All @@ -620,6 +645,7 @@ class UploadFieldTest_Record extends DataObject implements TestOnly {
'HasOneFile' => 'File',
'HasOneFileMaxOne' => 'File',
'HasOneFileMaxTwo' => 'File',
'HasOneExtendedFile' => 'UploadFieldTest_ExtendedFile'
);

static $has_many = array(
Expand Down Expand Up @@ -666,6 +692,10 @@ function Form() {
$fieldHasOne = new UploadField('HasOneFile');
$fieldHasOne->setFolderName('UploadFieldTest');
$fieldHasOne->setRecord($record);

$fieldHasOneExtendedFile = new UploadField('HasOneExtendedFile');
$fieldHasOneExtendedFile->setFolderName('UploadFieldTest');
$fieldHasOneExtendedFile->setRecord($record);

$fieldHasOneMaxOne = new UploadField('HasOneFileMaxOne');
$fieldHasOneMaxOne->setFolderName('UploadFieldTest');
Expand Down Expand Up @@ -712,6 +742,7 @@ function Form() {
$fieldHasOne,
$fieldHasOneMaxOne,
$fieldHasOneMaxTwo,
$fieldHasOneExtendedFile,
$fieldHasMany,
$fieldHasManyMaxTwo,
$fieldManyMany,
Expand All @@ -727,6 +758,7 @@ function Form() {
'HasOneFile',
'HasOneFileMaxOne',
'HasOneFileMaxTwo',
'HasOneExtendedFile',
'HasManyFiles',
'HasManyFilesMaxTwo',
'ManyManyFiles',
Expand All @@ -743,3 +775,10 @@ function submit($data, $form) {
}

}

/**
* Used for testing the create-on-upload
*/
class UploadFieldTest_ExtendedFile extends File implements TestOnly {

}

0 comments on commit b8faa41

Please sign in to comment.