/** * Loads the temporary file data into a File object * * @param array $tmpFile Temporary file data * @param string $error Error message * @return AssetContainer File object, or null if error */ protected function saveTemporaryFile($tmpFile, &$error = null) { // Determine container object $error = null; $fileObject = null; if (empty($tmpFile)) { $error = _t('UploadField.FIELDNOTSET', 'File information not found'); return null; } if ($tmpFile['error']) { $error = $tmpFile['error']; return null; } // Search for relations that can hold the uploaded files, but don't fallback // to default if there is no automatic relation if ($relationClass = $this->getRelationAutosetClass(null)) { // Allow File to be subclassed if ($relationClass === 'SilverStripe\\Assets\\File' && isset($tmpFile['name'])) { $relationClass = File::get_class_for_file_extension(File::get_file_extension($tmpFile['name'])); } // Create new object explicitly. Otherwise rely on Upload::load to choose the class. $fileObject = Object::create($relationClass); if (!$fileObject instanceof DataObject || !$fileObject instanceof AssetContainer) { throw new InvalidArgumentException("Invalid asset container {$relationClass}"); } } // Get the uploaded file into a new file object. try { $this->upload->loadIntoFile($tmpFile, $fileObject, $this->getFolderName()); } catch (Exception $e) { // we shouldn't get an error here, but just in case $error = $e->getMessage(); return null; } // Check if upload field has an error if ($this->upload->isError()) { $error = implode(' ' . PHP_EOL, $this->upload->getErrors()); return null; } // return file return $this->upload->getFile(); }
/** * @param DataObject|DataObjectInterface $record */ public function saveInto(DataObjectInterface $record) { if (!isset($_FILES[$this->name])) { return; } $fileClass = File::get_class_for_file_extension(File::get_file_extension($_FILES[$this->name]['name'])); /** @var File $file */ if ($this->relationAutoSetting) { // assume that the file is connected via a has-one $objectClass = DataObject::getSchema()->hasOneComponent(get_class($record), $this->name); if ($objectClass === File::class || empty($objectClass)) { // Create object of the appropriate file class $file = Object::create($fileClass); } else { // try to create a file matching the relation $file = Object::create($objectClass); } } else { if ($record instanceof File) { $file = $record; } else { $file = Object::create($fileClass); } } $this->upload->loadIntoFile($_FILES[$this->name], $file, $this->getFolderName()); if ($this->upload->isError()) { return; } if ($this->relationAutoSetting) { if (empty($objectClass)) { return; } $file = $this->upload->getFile(); $record->{$this->name . 'ID'} = $file->ID; } }
/** * Creates a single file based on a form-urlencoded upload. * * @param HTTPRequest $request * @return HTTPRequest|HTTPResponse */ public function apiCreateFile(HTTPRequest $request) { $data = $request->postVars(); $upload = $this->getUpload(); // CSRF check $token = SecurityToken::inst(); if (empty($data[$token->getName()]) || !$token->check($data[$token->getName()])) { return new HTTPResponse(null, 400); } // Check parent record /** @var Folder $parentRecord */ $parentRecord = null; if (!empty($data['ParentID']) && is_numeric($data['ParentID'])) { $parentRecord = Folder::get()->byID($data['ParentID']); } $data['Parent'] = $parentRecord; $tmpFile = $request->postVar('Upload'); if (!$upload->validate($tmpFile)) { $result = ['message' => null]; $errors = $upload->getErrors(); if ($message = array_shift($errors)) { $result['message'] = ['type' => 'error', 'value' => $message]; } return (new HTTPResponse(json_encode($result), 400))->addHeader('Content-Type', 'application/json'); } // TODO Allow batch uploads $fileClass = File::get_class_for_file_extension(File::get_file_extension($tmpFile['name'])); /** @var File $file */ $file = Injector::inst()->create($fileClass); // check canCreate permissions if (!$file->canCreate(null, $data)) { $result = ['message' => ['type' => 'error', 'value' => _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.CreatePermissionDenied', 'You do not have permission to add files')]]; return (new HTTPResponse(json_encode($result), 403))->addHeader('Content-Type', 'application/json'); } $uploadResult = $upload->loadIntoFile($tmpFile, $file, $parentRecord ? $parentRecord->getFilename() : '/'); if (!$uploadResult) { $result = ['message' => ['type' => 'error', 'value' => _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.LoadIntoFileFailed', 'Failed to load file')]]; return (new HTTPResponse(json_encode($result), 400))->addHeader('Content-Type', 'application/json'); } $file->ParentID = $parentRecord ? $parentRecord->ID : 0; $file->write(); $result = [$this->getObjectFromData($file)]; return (new HTTPResponse(json_encode($result)))->addHeader('Content-Type', 'application/json'); }