/** * Get the MIME type based on a file's extension. If the finfo class exists in PHP, and the file * exists relative to the project root, then use that extension, otherwise fallback to a list of * commonly known MIME types. * * @param string $filename * * @return string */ public static function get_mime_type($filename) { // If the finfo module is compiled into PHP, use it. $path = BASE_PATH . DIRECTORY_SEPARATOR . $filename; if (class_exists('finfo') && file_exists($path)) { $finfo = new finfo(FILEINFO_MIME_TYPE); return $finfo->file($path); } // Fallback to use the list from the HTTP.yml configuration and rely on the file extension // to get the file mime-type $ext = File::get_file_extension($filename); // Get the mime-types $mimeTypes = HTTP::config()->get('MimeTypes'); // The mime type doesn't exist if (!isset($mimeTypes[$ext])) { return 'application/unknown'; } return $mimeTypes[$ext]; }
/** * Validate that this DBFile accepts this filename as valid * * @param string $filename * @throws ValidationException * @return bool */ protected function isValidFilename($filename) { $extension = strtolower(File::get_file_extension($filename)); // Validate true if within the list of allowed extensions $allowed = $this->getAllowedExtensions(); if ($allowed) { return in_array($extension, $allowed); } // If no extensions are configured, fallback to global list $globalList = File::config()->allowed_extensions; if (in_array($extension, $globalList)) { return true; } // Only admins can bypass global rules return !File::config()->apply_restrictions_to_admin && Permission::check('ADMIN'); }
/** * @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; } }
/** * 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(); }
/** * Guess file category from either a file or url * * @param string $url * @param File $file * @return string */ protected function getFileCategory($url, $file) { if ($file) { return $file->appCategory(); } if ($url) { return File::get_app_category(File::get_file_extension($url)); } return null; }
/** * Get file extension * * @return string */ public function getExtension() { $extension = File::get_file_extension($this->getName()); return strtolower($extension); }
/** * 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'); }
public function testGetExtension() { $this->assertEquals('', File::get_file_extension('myfile'), 'No extension'); $this->assertEquals('txt', File::get_file_extension('myfile.txt'), 'Simple extension'); $this->assertEquals('gz', File::get_file_extension('myfile.tar.gz'), 'Double-barrelled extension only returns last bit'); }