示例#1
0
 public static function newFromFileData($data, array $params = array())
 {
     $selector_class = PhabricatorEnv::getEnvConfig('storage.engine-selector');
     $selector = newv($selector_class, array());
     $engines = $selector->selectStorageEngines($data, $params);
     if (!$engines) {
         throw new Exception("No valid storage engines are available!");
     }
     $data_handle = null;
     $engine_identifier = null;
     foreach ($engines as $engine) {
         try {
             // Perform the actual write.
             $data_handle = $engine->writeFile($data, $params);
             if (!$data_handle || strlen($data_handle) > 255) {
                 // This indicates an improperly implemented storage engine.
                 throw new Exception("Storage engine '{$engine}' executed writeFile() but did not " . "return a valid handle ('{$data_handle}') to the data: it must " . "be nonempty and no longer than 255 characters.");
             }
             $engine_identifier = $engine->getEngineIdentifier();
             if (!$engine_identifier || strlen($engine_identifier) > 32) {
                 throw new Exception("Storage engine '{$engine}' returned an improper engine " . "identifier '{$engine_identifier}': it must be nonempty " . "and no longer than 32 characters.");
             }
             // We stored the file somewhere so stop trying to write it to other
             // places.
             break;
         } catch (Exception $ex) {
             // If an engine doesn't work, keep trying all the other valid engines
             // in case something else works.
             phlog($ex);
         }
     }
     if (!$data_handle) {
         throw new Exception("All storage engines failed to write file!");
     }
     $file_name = idx($params, 'name');
     $file_name = self::normalizeFileName($file_name);
     // If for whatever reason, authorPHID isn't passed as a param
     // (always the case with newFromFileDownload()), store a ''
     $authorPHID = idx($params, 'authorPHID');
     $file = new PhabricatorFile();
     $file->setName($file_name);
     $file->setByteSize(strlen($data));
     $file->setAuthorPHID($authorPHID);
     $file->setStorageEngine($engine_identifier);
     $file->setStorageHandle($data_handle);
     // TODO: This is probably YAGNI, but allows for us to do encryption or
     // compression later if we want.
     $file->setStorageFormat(self::STORAGE_FORMAT_RAW);
     if (isset($params['mime-type'])) {
         $file->setMimeType($params['mime-type']);
     } else {
         try {
             $tmp = new TempFile();
             Filesystem::writeFile($tmp, $data);
             list($stdout) = execx('file -b --mime %s', $tmp);
             $file->setMimeType($stdout);
         } catch (Exception $ex) {
             // Be robust here since we don't really care that much about mime types.
         }
     }
     $file->save();
     return $file;
 }
示例#2
0
 public static function newFromFileData($data, array $params = array())
 {
     $selector = PhabricatorEnv::newObjectFromConfig('storage.engine-selector');
     $engines = $selector->selectStorageEngines($data, $params);
     if (!$engines) {
         throw new Exception("No valid storage engines are available!");
     }
     $data_handle = null;
     $engine_identifier = null;
     $exceptions = array();
     foreach ($engines as $engine) {
         $engine_class = get_class($engine);
         try {
             // Perform the actual write.
             $data_handle = $engine->writeFile($data, $params);
             if (!$data_handle || strlen($data_handle) > 255) {
                 // This indicates an improperly implemented storage engine.
                 throw new PhabricatorFileStorageConfigurationException("Storage engine '{$engine_class}' executed writeFile() but did " . "not return a valid handle ('{$data_handle}') to the data: it " . "must be nonempty and no longer than 255 characters.");
             }
             $engine_identifier = $engine->getEngineIdentifier();
             if (!$engine_identifier || strlen($engine_identifier) > 32) {
                 throw new PhabricatorFileStorageConfigurationException("Storage engine '{$engine_class}' returned an improper engine " . "identifier '{$engine_identifier}': it must be nonempty " . "and no longer than 32 characters.");
             }
             // We stored the file somewhere so stop trying to write it to other
             // places.
             break;
         } catch (Exception $ex) {
             if ($ex instanceof PhabricatorFileStorageConfigurationException) {
                 // If an engine is outright misconfigured (or misimplemented), raise
                 // that immediately since it probably needs attention.
                 throw $ex;
             }
             // If an engine doesn't work, keep trying all the other valid engines
             // in case something else works.
             phlog($ex);
             $exceptions[] = $ex;
         }
     }
     if (!$data_handle) {
         throw new PhutilAggregateException("All storage engines failed to write file:", $exceptions);
     }
     $file_name = idx($params, 'name');
     $file_name = self::normalizeFileName($file_name);
     // If for whatever reason, authorPHID isn't passed as a param
     // (always the case with newFromFileDownload()), store a ''
     $authorPHID = idx($params, 'authorPHID');
     $file = new PhabricatorFile();
     $file->setName($file_name);
     $file->setByteSize(strlen($data));
     $file->setAuthorPHID($authorPHID);
     $file->setContentHash(PhabricatorHash::digest($data));
     $file->setStorageEngine($engine_identifier);
     $file->setStorageHandle($data_handle);
     // TODO: This is probably YAGNI, but allows for us to do encryption or
     // compression later if we want.
     $file->setStorageFormat(self::STORAGE_FORMAT_RAW);
     if (isset($params['mime-type'])) {
         $file->setMimeType($params['mime-type']);
     } else {
         $tmp = new TempFile();
         Filesystem::writeFile($tmp, $data);
         $file->setMimeType(Filesystem::getMimeType($tmp));
     }
     $file->save();
     return $file;
 }