/**
  * Get the file component from the request
  *
  * @param \SS_HTTPRequest $request
  * @return string
  */
 protected function parseFilename(\SS_HTTPRequest $request)
 {
     $filename = '';
     $next = $request->param('Filename');
     while ($next) {
         $filename = $filename ? \File::join_paths($filename, $next) : $next;
         $next = $request->shift();
     }
     if ($extension = $request->getExtension()) {
         $filename = $filename . "." . $extension;
     }
     return $filename;
 }
 /**
  * Given a set of files, combine them (as necessary) and return the url
  *
  * @param string $combinedFile Filename for this combined file
  * @param array $fileList List of files to combine
  * @param string $type Either 'js' or 'css'
  * @return string|null URL to this resource, if there are files to combine
  */
 protected function getCombinedFileURL($combinedFile, $fileList, $type)
 {
     // Skip empty lists
     if (empty($fileList)) {
         return null;
     }
     // Generate path (Filename)
     $hashQuerystring = Config::inst()->get(static::class, 'combine_hash_querystring');
     if (!$hashQuerystring) {
         $combinedFile = $this->hashedCombinedFilename($combinedFile, $fileList);
     }
     $combinedFileID = File::join_paths($this->getCombinedFilesFolder(), $combinedFile);
     // Send file combination request to the backend, with an optional callback to perform regeneration
     $minify = $this->getMinifyCombinedJSFiles();
     $combinedURL = $this->getAssetHandler()->getContentURL($combinedFileID, function () use($fileList, $minify, $type) {
         // Physically combine all file content
         $combinedData = '';
         $base = Director::baseFolder() . '/';
         $minifier = Injector::inst()->get('Requirements_Minifier');
         foreach ($fileList as $file) {
             $fileContent = file_get_contents($base . $file);
             // Use configured minifier
             if ($minify) {
                 $fileContent = $minifier->minify($fileContent, $type, $file);
             }
             if ($this->writeHeaderComment) {
                 // Write a header comment for each file for easier identification and debugging.
                 $combinedData .= "/****** FILE: {$file} *****/\n";
             }
             $combinedData .= $fileContent . "\n";
         }
         return $combinedData;
     });
     // If the name isn't hashed, we will need to append the querystring m= parameter instead
     // Since url won't be automatically suffixed, add it in here
     if ($hashQuerystring && $this->getSuffixRequirements()) {
         $hash = $this->hashOfFiles($fileList);
         $q = stripos($combinedURL, '?') === false ? '?' : '&';
         $combinedURL .= "{$q}m={$hash}";
     }
     return $combinedURL;
 }
 /**
  * Given a temporary file and upload path, validate the file and determine the
  * value of the 'Filename' tuple that should be used to store this asset.
  *
  * @param array $tmpFile
  * @param string $folderPath
  * @return string|false Value of filename tuple, or false if invalid
  */
 protected function getValidFilename($tmpFile, $folderPath = null)
 {
     if (!is_array($tmpFile)) {
         throw new InvalidArgumentException("Upload::load() Not passed an array.  Most likely, the form hasn't got the right enctype");
     }
     // Validate
     $this->clearErrors();
     $valid = $this->validate($tmpFile);
     if (!$valid) {
         return false;
     }
     // Clean filename
     if (!$folderPath) {
         $folderPath = $this->config()->uploads_folder;
     }
     $nameFilter = FileNameFilter::create();
     $file = $nameFilter->filter($tmpFile['name']);
     $filename = basename($file);
     if ($folderPath) {
         $filename = File::join_paths($folderPath, $filename);
     }
     return $filename;
 }
 public function testJoinPaths()
 {
     $this->assertEquals('name/file.jpg', File::join_paths('/name', 'file.jpg'));
     $this->assertEquals('name/file.jpg', File::join_paths('name', 'file.jpg'));
     $this->assertEquals('name/file.jpg', File::join_paths('/name', '/file.jpg'));
     $this->assertEquals('name/file.jpg', File::join_paths('name/', '/', 'file.jpg'));
     $this->assertEquals('file.jpg', File::join_paths('/', '/', 'file.jpg'));
     $this->assertEquals('', File::join_paths('/', '/'));
 }
 /**
  * Returns statically cached content for a given error code
  *
  * @param int $statusCode A HTTP Statuscode, typically 404 or 500
  * @return string|null
  */
 public static function get_content_for_errorcode($statusCode)
 {
     if (!self::config()->enable_static_file) {
         return null;
     }
     // Attempt to retrieve content from generated file handler
     $filename = self::get_error_filename($statusCode);
     $storeFilename = File::join_paths(self::config()->store_filepath, $filename);
     return self::get_asset_handler()->getContent($storeFilename);
 }
 /**
  * Given a set of files, combine them (as necessary) and return the url
  *
  * @param string $combinedFile Filename for this combined file
  * @param array $fileList List of files to combine
  * @param string $type Either 'js' or 'css'
  * @return string URL to this resource
  */
 protected function getCombinedFileURL($combinedFile, $fileList, $type)
 {
     // Generate path (Filename)
     $combinedFileID = File::join_paths($this->getCombinedFilesFolder(), $combinedFile);
     // Get entropy for this combined file (last modified date of most recent file)
     $entropy = $this->getEntropyOfFiles($fileList);
     // Send file combination request to the backend, with an optional callback to perform regeneration
     $minify = $this->getMinifyCombinedJSFiles();
     $combinedURL = $this->getAssetHandler()->getGeneratedURL($combinedFileID, $entropy, function () use($fileList, $minify, $type) {
         // Physically combine all file content
         $combinedData = '';
         $base = Director::baseFolder() . '/';
         $minifier = Injector::inst()->get('Requirements_Minifier');
         foreach (array_diff($fileList, $this->getBlocked()) as $file) {
             $fileContent = file_get_contents($base . $file);
             // Use configured minifier
             if ($minify) {
                 $fileContent = $minifier->minify($fileContent, $type, $file);
             }
             if ($this->writeHeaderComment) {
                 // Write a header comment for each file for easier identification and debugging.
                 $combinedData .= "/****** FILE: {$file} *****/\n";
             }
             $combinedData .= $fileContent . "\n";
         }
         return $combinedData;
     });
     // Since url won't be automatically suffixed, add it in here
     if ($this->getSuffixRequirements()) {
         $q = stripos($combinedURL, '?') === false ? '?' : '&';
         $combinedURL .= "{$q}m={$entropy}";
     }
     return $combinedURL;
 }
 /**
  * Save an file passed from a form post into this object.
  * File names are filtered through {@link FileNameFilter}, see class documentation
  * on how to influence this behaviour.
  *
  * @param $tmpFile array Indexed array that PHP generated for every file it uploads.
  * @param $folderPath string Folder path relative to /assets
  * @return Boolean|string Either success or error-message.
  */
 public function load($tmpFile, $folderPath = false)
 {
     if (!is_array($tmpFile)) {
         throw new InvalidArgumentException("Upload::load() Not passed an array.  Most likely, the form hasn't got the right enctype");
     }
     // Validate
     $this->clearErrors();
     $valid = $this->validate($tmpFile);
     if (!$valid) {
         return false;
     }
     // Clean filename
     if (!$folderPath) {
         $folderPath = $this->config()->uploads_folder;
     }
     $nameFilter = FileNameFilter::create();
     $file = $nameFilter->filter($tmpFile['name']);
     $filename = basename($file);
     if ($folderPath) {
         $filename = File::join_paths($folderPath, $filename);
     }
     // Validate filename
     $filename = $this->resolveExistingFile($filename);
     // Save file into backend
     $conflictResolution = $this->replaceFile ? AssetStore::CONFLICT_OVERWRITE : AssetStore::CONFLICT_RENAME;
     $this->file->setFromLocalFile($tmpFile['tmp_name'], $filename, null, null, $conflictResolution);
     // Save changes to underlying record (if it's a DataObject)
     if ($this->file instanceof DataObject) {
         $this->file->write();
     }
     //to allow extensions to e.g. create a version after an upload
     $this->file->extend('onAfterUpload');
     $this->extend('onAfterLoad', $this->file);
     return true;
 }
 /**
  * Returns an absolute filesystem path to a static error file
  * which is generated through {@link publish()}.
  *
  * @param int $statusCode A HTTP Statuscode, mostly 404 or 500
  * @param string $locale A locale, e.g. 'de_DE' (Optional)
  *
  * @param int $statusCode A HTTP Statuscode, typically 404 or 500
  * @return string
  */
 public static function get_content_for_errorcode($statusCode)
 {
     // Attempt to retrieve content from generated file handler
     $filename = self::get_error_filename($statusCode);
     $storeFilename = File::join_paths(self::config()->store_filepath, $filename);
     $result = self::get_asset_handler()->getGeneratedContent($storeFilename, 0);
     if ($result) {
         return $result;
     }
     // Fallback to physical store
     if (self::config()->enable_static_file) {
         $staticPath = self::config()->static_filepath . "/" . $filename;
         if (file_exists($staticPath)) {
             return file_get_contents($staticPath);
         }
     }
 }