split of mimetype detection code from OC_Helper, adding the option for apps to register additional mimetype mappings

This commit is contained in:
Robin Appelman 2013-08-07 16:38:57 +02:00
parent 057d7aa108
commit fc332acf8a
2 changed files with 315 additions and 236 deletions

View File

@ -0,0 +1,121 @@
<?php
/**
* Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OC\Files\Type;
/**
* Class Detection
*
* Mimetype detection
*
* @package OC\Files\Type
*/
class Detection {
protected $mimetypes = array();
/**
* add an extension -> mimetype mapping
*
* @param string $extension
* @param string $mimetype
*/
public function registerType($extension, $mimetype) {
$this->mimetypes[$extension] = $mimetype;
}
/**
* add an array of extension -> mimetype mappings
*
* @param array $types
*/
public function registerTypeArray($types) {
$this->mimetypes = array_merge($this->mimetypes, $types);
}
/**
* detect mimetype only based on filename, content of file is not used
*
* @param string $path
* @return string
*/
public function detectPath($path) {
if (strpos($path, '.')) {
//try to guess the type by the file extension
$extension = strtolower(strrchr(basename($path), "."));
$extension = substr($extension, 1); //remove leading .
return (isset($this->mimetypes[$extension])) ? $this->mimetypes[$extension] : 'application/octet-stream';
} else {
return 'application/octet-stream';
}
}
/**
* detect mimetype based on both filename and content
*
* @param string $path
* @return string
*/
public function detect($path) {
$isWrapped = (strpos($path, '://') !== false) and (substr($path, 0, 7) == 'file://');
if (@is_dir($path)) {
// directories are easy
return "httpd/unix-directory";
}
$mimeType = $this->detectPath($path);
if ($mimeType == 'application/octet-stream' and function_exists('finfo_open')
and function_exists('finfo_file') and $finfo = finfo_open(FILEINFO_MIME)
) {
$info = @strtolower(finfo_file($finfo, $path));
if ($info) {
$mimeType = substr($info, 0, strpos($info, ';'));
}
finfo_close($finfo);
}
if (!$isWrapped and $mimeType == 'application/octet-stream' && function_exists("mime_content_type")) {
// use mime magic extension if available
$mimeType = mime_content_type($path);
}
if (!$isWrapped and $mimeType == 'application/octet-stream' && \OC_Helper::canExecute("file")) {
// it looks like we have a 'file' command,
// lets see if it does have mime support
$path = escapeshellarg($path);
$fp = popen("file -b --mime-type $path 2>/dev/null", "r");
$reply = fgets($fp);
pclose($fp);
//trim the newline
$mimeType = trim($reply);
}
return $mimeType;
}
/**
* detect mimetype based on the content of a string
*
* @param string $data
* @return string
*/
public function detectString($data) {
if (function_exists('finfo_open') and function_exists('finfo_file')) {
$finfo = finfo_open(FILEINFO_MIME);
return finfo_buffer($finfo, $data);
} else {
$tmpFile = \OC_Helper::tmpFile();
$fh = fopen($tmpFile, 'wb');
fwrite($fh, $data, 8024);
fclose($fh);
$mime = $this->detect($tmpFile);
unset($tmpFile);
return $mime;
}
}
}

View File

@ -25,9 +25,9 @@
* Collection of useful functions
*/
class OC_Helper {
private static $mimetypes=array();
private static $tmpFiles = array();
private static $mimetypeIcons = array();
private static $mimetypeDetector;
/**
* @brief Creates an url using a defined route
@ -65,16 +65,13 @@ class OC_Helper {
} else {
$urlLinkTo = OC_App::getAppWebPath($app) . '/' . $file;
}
}
else{
} else {
$urlLinkTo = OC::$WEBROOT . '/' . $app . '/' . $file;
}
}
else{
} else {
if (file_exists(OC::$SERVERROOT . '/core/' . $file)) {
$urlLinkTo = OC::$WEBROOT . '/core/' . $file;
}
else{
} else {
$urlLinkTo = OC::$WEBROOT . '/' . $file;
}
}
@ -108,8 +105,7 @@ class OC_Helper {
*
* Returns a absolute url to the given app and file.
*/
public static function makeURLAbsolute( $url )
{
public static function makeURLAbsolute($url) {
return OC_Request::serverProtocol() . '://' . OC_Request::serverHost() . $url;
}
@ -304,8 +300,7 @@ class OC_Helper {
if (is_link($fullpath))
return false;
elseif (!is_dir($fullpath) && !@chmod($fullpath, $filemode))
return false;
elseif(!self::chmodr($fullpath, $filemode))
return false; elseif (!self::chmodr($fullpath, $filemode))
return false;
}
}
@ -362,6 +357,14 @@ class OC_Helper {
}
}
static public function getMimetypeDetector() {
if (!self::$mimetypeDetector) {
self::$mimetypeDetector = new \OC\Files\Type\Detection();
self::$mimetypeDetector->registerTypeArray(include 'mimetypes.list.php');
}
return self::$mimetypeDetector;
}
/**
* Try to guess the mimetype based on filename
*
@ -369,80 +372,28 @@ class OC_Helper {
* @return string
*/
static public function getFileNameMimeType($path) {
if(strpos($path, '.')) {
//try to guess the type by the file extension
if(!self::$mimetypes || self::$mimetypes != include 'mimetypes.list.php') {
self::$mimetypes=include 'mimetypes.list.php';
}
$extension=strtolower(strrchr(basename($path), "."));
$extension=substr($extension, 1);//remove leading .
return (isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
}else{
return 'application/octet-stream';
}
return self::getMimetypeDetector()->detectPath($path);
}
/**
* get the mimetype form a local file
*
* @param string $path
* @return string
* does NOT work for ownClouds filesystem, use OC_FileSystem::getMimeType instead
*/
static function getMimeType($path) {
$isWrapped=(strpos($path, '://')!==false) and (substr($path, 0, 7)=='file://');
if (@is_dir($path)) {
// directories are easy
return "httpd/unix-directory";
}
$mimeType = self::getFileNameMimeType($path);
if($mimeType=='application/octet-stream' and function_exists('finfo_open')
and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)) {
$info = @strtolower(finfo_file($finfo, $path));
if($info) {
$mimeType=substr($info, 0, strpos($info, ';'));
}
finfo_close($finfo);
}
if (!$isWrapped and $mimeType=='application/octet-stream' && function_exists("mime_content_type")) {
// use mime magic extension if available
$mimeType = mime_content_type($path);
}
if (!$isWrapped and $mimeType=='application/octet-stream' && OC_Helper::canExecute("file")) {
// it looks like we have a 'file' command,
// lets see if it does have mime support
$path=escapeshellarg($path);
$fp = popen("file -b --mime-type $path 2>/dev/null", "r");
$reply = fgets($fp);
pclose($fp);
//trim the newline
$mimeType = trim($reply);
}
return $mimeType;
return self::getMimetypeDetector()->detect($path);
}
/**
* get the mimetype form a data string
*
* @param string $data
* @return string
*/
static function getStringMimeType($data) {
if(function_exists('finfo_open') and function_exists('finfo_file')) {
$finfo=finfo_open(FILEINFO_MIME);
return finfo_buffer($finfo, $data);
}else{
$tmpFile=OC_Helper::tmpFile();
$fh=fopen($tmpFile, 'wb');
fwrite($fh, $data, 8024);
fclose($fh);
$mime=self::getMimeType($tmpFile);
unset($tmpFile);
return $mime;
}
return self::getMimetypeDetector()->detectString($data);
}
/**
@ -466,6 +417,7 @@ class OC_Helper {
/**
* returns "checked"-attribute if request contains selected radio element
* OR if radio element is the default one -- maybe?
*
* @param string $s Name of radio-button element name
* @param string $v Value of current radio-button element
* @param string $d Value of default radio-button element
@ -522,6 +474,7 @@ class OC_Helper {
/**
* copy the contents of one stream to another
*
* @param resource $source
* @param resource $target
* @return int the number of bytes copied
@ -544,6 +497,7 @@ class OC_Helper {
/**
* create a temporary file with an unique filename
*
* @param string $postfix
* @return string
*
@ -559,6 +513,7 @@ class OC_Helper {
/**
* move a file to oc-noclean temp dir
*
* @param string $filename
* @return mixed
*
@ -584,6 +539,7 @@ class OC_Helper {
/**
* create a temporary folder with an unique filename
*
* @return string
*
* temporary files are automatically cleaned up after the script is finished
@ -792,6 +748,7 @@ class OC_Helper {
/**
* Shortens str to maxlen by replacing characters in the middle with '...', eg.
* ellipsis('a very long string with lots of useless info to make a better example', 14) becomes 'a very ...example'
*
* @param string $str the string
* @param string $maxlen the maximum length of the result
* @return string with at most maxlen characters
@ -833,6 +790,7 @@ class OC_Helper {
/**
* Checks if a function is available
*
* @param string $function_name
* @return bool
*/