Skip to content

Commit

Permalink
MDL-33144 display filetype icon and mimetype based on extension
Browse files Browse the repository at this point in the history
- use finfo to determine mimetype of a file only when it is unknown from file extension
- display filetype icon and mimetype in filemanager based on file extension
- fixed a small issue with specifying extension instead of group in file_get_typegroup()
- allow only web-compartible image types when embedding into editor or using in database field
- created new groups web_video and web_audio to use in resource module
  • Loading branch information
marinaglancy committed May 23, 2012
1 parent 5a5cdaf commit ae7f35b
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 56 deletions.
75 changes: 41 additions & 34 deletions lib/filelib.php
Expand Up @@ -1367,7 +1367,7 @@ function &get_mimetypes_array() {
'asc' => array ('type'=>'text/plain', 'icon'=>'text'),
'asm' => array ('type'=>'text/plain', 'icon'=>'text'),
'au' => array ('type'=>'audio/au', 'icon'=>'audio', 'groups'=>array('audio'), 'string'=>'audio'),
'avi' => array ('type'=>'video/x-ms-wm', 'icon'=>'avi', 'groups'=>array('video'), 'string'=>'video'),
'avi' => array ('type'=>'video/x-ms-wm', 'icon'=>'avi', 'groups'=>array('video','web_video'), 'string'=>'video'),
'bmp' => array ('type'=>'image/bmp', 'icon'=>'bmp', 'groups'=>array('image'), 'string'=>'image'),
'c' => array ('type'=>'text/plain', 'icon'=>'text'),
'cct' => array ('type'=>'shockwave/director', 'icon'=>'flash'),
Expand All @@ -1390,8 +1390,8 @@ function &get_mimetypes_array() {
'dxr' => array ('type'=>'application/x-director', 'icon'=>'flash'),
'eps' => array ('type'=>'application/postscript', 'icon'=>'eps'),
'fdf' => array ('type'=>'application/pdf', 'icon'=>'pdf'),
'flv' => array ('type'=>'video/x-flv', 'icon'=>'flash', 'groups'=>array('video'), 'string'=>'video'),
'f4v' => array ('type'=>'video/mp4', 'icon'=>'flash', 'groups'=>array('video'), 'string'=>'video'),
'flv' => array ('type'=>'video/x-flv', 'icon'=>'flash', 'groups'=>array('video','web_video'), 'string'=>'video'),
'f4v' => array ('type'=>'video/mp4', 'icon'=>'flash', 'groups'=>array('video','web_video'), 'string'=>'video'),
'gif' => array ('type'=>'image/gif', 'icon'=>'gif', 'groups'=>array('image', 'web_image'), 'string'=>'image'),
'gtar' => array ('type'=>'application/x-gtar', 'icon'=>'zip', 'groups'=>array('archive'), 'string'=>'archive'),
'tgz' => array ('type'=>'application/g-zip', 'icon'=>'zip', 'groups'=>array('archive'), 'string'=>'archive'),
Expand Down Expand Up @@ -1422,16 +1422,16 @@ function &get_mimetypes_array() {
'latex'=> array ('type'=>'application/x-latex', 'icon'=>'text'),
'm' => array ('type'=>'text/plain', 'icon'=>'text'),
'mbz' => array ('type'=>'application/vnd.moodle.backup', 'icon'=>'moodle'),
'mov' => array ('type'=>'video/quicktime', 'icon'=>'mov', 'groups'=>array('video'), 'string'=>'video'),
'mov' => array ('type'=>'video/quicktime', 'icon'=>'mov', 'groups'=>array('video','web_video'), 'string'=>'video'),
'movie'=> array ('type'=>'video/x-sgi-movie', 'icon'=>'mov', 'groups'=>array('video'), 'string'=>'video'),
'm3u' => array ('type'=>'audio/x-mpegurl', 'icon'=>'mp3', 'groups'=>array('audio'), 'string'=>'audio'),
'mp3' => array ('type'=>'audio/mp3', 'icon'=>'mp3', 'groups'=>array('audio'), 'string'=>'audio'),
'mp4' => array ('type'=>'video/mp4', 'icon'=>'mpeg', 'groups'=>array('video'), 'string'=>'video'),
'm4v' => array ('type'=>'video/mp4', 'icon'=>'mpeg', 'groups'=>array('video'), 'string'=>'video'),
'mp3' => array ('type'=>'audio/mp3', 'icon'=>'mp3', 'groups'=>array('audio','web_audio'), 'string'=>'audio'),
'mp4' => array ('type'=>'video/mp4', 'icon'=>'mpeg', 'groups'=>array('video','web_video'), 'string'=>'video'),
'm4v' => array ('type'=>'video/mp4', 'icon'=>'mpeg', 'groups'=>array('video','web_video'), 'string'=>'video'),
'm4a' => array ('type'=>'audio/mp4', 'icon'=>'mp3', 'groups'=>array('audio'), 'string'=>'audio'),
'mpeg' => array ('type'=>'video/mpeg', 'icon'=>'mpeg', 'groups'=>array('video'), 'string'=>'video'),
'mpe' => array ('type'=>'video/mpeg', 'icon'=>'mpeg', 'groups'=>array('video'), 'string'=>'video'),
'mpg' => array ('type'=>'video/mpeg', 'icon'=>'mpeg', 'groups'=>array('video'), 'string'=>'video'),
'mpeg' => array ('type'=>'video/mpeg', 'icon'=>'mpeg', 'groups'=>array('video','web_video'), 'string'=>'video'),
'mpe' => array ('type'=>'video/mpeg', 'icon'=>'mpeg', 'groups'=>array('video','web_video'), 'string'=>'video'),
'mpg' => array ('type'=>'video/mpeg', 'icon'=>'mpeg', 'groups'=>array('video','web_video'), 'string'=>'video'),

'odt' => array ('type'=>'application/vnd.oasis.opendocument.text', 'icon'=>'odt', 'groups'=>array('document')),
'ott' => array ('type'=>'application/vnd.oasis.opendocument.text-template', 'icon'=>'odt', 'groups'=>array('document')),
Expand Down Expand Up @@ -1469,8 +1469,8 @@ function &get_mimetypes_array() {
'ppsm' => array ('type'=>'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', 'icon'=>'pptx'),

'ps' => array ('type'=>'application/postscript', 'icon'=>'pdf'),
'qt' => array ('type'=>'video/quicktime', 'icon'=>'mov', 'groups'=>array('video'), 'string'=>'video'),
'ra' => array ('type'=>'audio/x-realaudio-plugin', 'icon'=>'audio', 'groups'=>array('audio'), 'string'=>'audio'),
'qt' => array ('type'=>'video/quicktime', 'icon'=>'mov', 'groups'=>array('video','web_video'), 'string'=>'video'),
'ra' => array ('type'=>'audio/x-realaudio-plugin', 'icon'=>'audio', 'groups'=>array('audio','web_audio'), 'string'=>'audio'),
'ram' => array ('type'=>'audio/x-pn-realaudio-plugin', 'icon'=>'audio', 'groups'=>array('audio'), 'string'=>'audio'),
'rhb' => array ('type'=>'text/xml', 'icon'=>'xml'),
'rm' => array ('type'=>'audio/x-pn-realaudio-plugin', 'icon'=>'audio', 'groups'=>array('audio'), 'string'=>'audio'),
Expand All @@ -1483,11 +1483,11 @@ function &get_mimetypes_array() {
'smi' => array ('type'=>'application/smil', 'icon'=>'text'),
'smil' => array ('type'=>'application/smil', 'icon'=>'text'),
'sqt' => array ('type'=>'text/xml', 'icon'=>'xml'),
'svg' => array ('type'=>'image/svg+xml', 'icon'=>'image', 'groups'=>array('image'), 'string'=>'image'),
'svgz' => array ('type'=>'image/svg+xml', 'icon'=>'image', 'groups'=>array('image'), 'string'=>'image'),
'svg' => array ('type'=>'image/svg+xml', 'icon'=>'image', 'groups'=>array('image','web_image'), 'string'=>'image'),
'svgz' => array ('type'=>'image/svg+xml', 'icon'=>'image', 'groups'=>array('image','web_image'), 'string'=>'image'),
'swa' => array ('type'=>'application/x-director', 'icon'=>'flash'),
'swf' => array ('type'=>'application/x-shockwave-flash', 'icon'=>'flash'),
'swfl' => array ('type'=>'application/x-shockwave-flash', 'icon'=>'flash'),
'swf' => array ('type'=>'application/x-shockwave-flash', 'icon'=>'flash', 'groups'=>array('video','web_video')),
'swfl' => array ('type'=>'application/x-shockwave-flash', 'icon'=>'flash', 'groups'=>array('video','web_video')),

'sxw' => array ('type'=>'application/vnd.sun.xml.writer', 'icon'=>'odt'),
'stw' => array ('type'=>'application/vnd.sun.xml.writer.template', 'icon'=>'odt'),
Expand Down Expand Up @@ -1653,14 +1653,15 @@ function file_file_icon($file, $size = null) {
} else {
$mimetype = '';
}
if ($filename && pathinfo($filename, PATHINFO_EXTENSION) &&
(!$mimetype || mimeinfo('type', $filename) === $mimetype)) {
// files with different extensions sharing the same mimetype (i.e. 'text/plain') may have different icons
return file_extension_icon($filename, $size);
} else {
// if mimetype and extension do not match we assume that mimetype is more correct
return file_mimetype_icon($mimetype, $size);
$mimetypes = &get_mimetypes_array();
if ($filename) {
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if ($extension && !empty($mimetypes[$extension])) {
// if file name has known extension, return icon for this extension
return file_extension_icon($filename, $size);
}
}
return file_mimetype_icon($mimetype, $size);
}

/**
Expand All @@ -1682,13 +1683,18 @@ function file_file_icon($file, $size = null) {
function file_folder_icon($iconsize = null) {
global $CFG;
static $iconpostfixes = array(256=>'-256', 128=>'-128', 96=>'-96', 80=>'-80', 72=>'-72', 64=>'-64', 48=>'-48', 32=>'-32', 24=>'-24', 16=>'');
static $cached = array();
$iconsize = max(array(16, (int)$iconsize));
foreach ($iconpostfixes as $size => $postfix) {
$fullname = $CFG->dirroot.'/pix/f/folder'.$postfix;
if ($iconsize >= $size && (file_exists($fullname.'.png') || file_exists($fullname.'.gif'))) {
return 'f/folder'.$postfix;
if (!array_key_exists($iconsize, $cached)) {
foreach ($iconpostfixes as $size => $postfix) {
$fullname = $CFG->dirroot.'/pix/f/folder'.$postfix;
if ($iconsize >= $size && (file_exists($fullname.'.png') || file_exists($fullname.'.gif'))) {
$cached[$iconsize] = 'f/folder'.$postfix;
break;
}
}
}
return $cached[$iconsize];
}

/**
Expand Down Expand Up @@ -1749,6 +1755,7 @@ function file_extension_icon($filename, $size = NULL) {
* @return string Text description
*/
function get_mimetype_description($obj, $capitalise=false) {
$filename = $mimetype = '';
if (is_object($obj) && method_exists($obj, 'get_filename') && method_exists($obj, 'get_mimetype')) {
// this is an instance of stored_file
$mimetype = $obj->get_mimetype();
Expand All @@ -1761,22 +1768,22 @@ function get_mimetype_description($obj, $capitalise=false) {
$obj = (array)$obj;
if (!empty($obj['filename'])) {
$filename = $obj['filename'];
} else {
$filename = '';
}
if (!empty($obj['mimetype'])) {
$mimetype = $obj['mimetype'];
} else {
$mimetype = mimeinfo('type', $filename);
}
} else {
$mimetype = $obj;
$filename = '';
}
$mimetypefromext = mimeinfo('type', $filename);
if (empty($mimetype) || $mimetypefromext !== 'document/unknown') {
// if file has a known extension, overwrite the specified mimetype
$mimetype = $mimetypefromext;
}
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (empty($extension)) {
$mimetypestr = mimeinfo_from_type('string', $mimetype);
$extension = mimeinfo_from_type('extension', $mimetype);
$extension = str_replace('.', '', mimeinfo_from_type('extension', $mimetype));
} else {
$mimetypestr = mimeinfo('string', $filename);
}
Expand Down Expand Up @@ -1835,7 +1842,7 @@ function file_get_typegroup($element, $groups) {
if (empty($value[$element])) {
continue;
}
if (($group === $extension || $group === $value['type'] ||
if (($group === '.'.$extension || $group === $value['type'] ||
(!empty($value['groups']) && in_array($group, $value['groups']))) &&
!in_array($value[$element], $cached[$element][$group])) {
$cached[$element][$group][] = $value[$element];
Expand Down
12 changes: 6 additions & 6 deletions lib/filestorage/file_storage.php
Expand Up @@ -1794,19 +1794,19 @@ public function import_external_file($storedfile) {
/**
* Return mimetype by given file pathname
*
* This method uses fileinfo module to get mimetype using magic bytes if file exists.
* If not, it will get mimetype based on filename
* If file has a known extension, we return the mimetype based on extension.
* Otherwise (when possible) we try to get the mimetype from file contents.
*
* @param string $pathname
* @return string
*/
public static function mimetype($pathname) {
if (file_exists($pathname)) {
$type = mimeinfo('type', $pathname);
if ($type === 'document/unknown' && class_exists('finfo') && file_exists($pathname)) {
$finfo = new finfo(FILEINFO_MIME_TYPE);
return mimeinfo_from_type('type', $finfo->file($pathname));
} else {
return mimeinfo('type', $pathname);
$type = mimeinfo_from_type('type', $finfo->file($pathname));
}
return $type;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/form/editor.php
Expand Up @@ -302,7 +302,7 @@ function toHtml() {

$args = new stdClass();
// need these three to filter repositories list
$args->accepted_types = array('image');
$args->accepted_types = array('web_image');
$args->return_types = (FILE_INTERNAL | FILE_EXTERNAL | FILE_REFERENCE);
$args->context = $ctx;
$args->env = 'filepicker';
Expand Down
2 changes: 1 addition & 1 deletion mod/data/field/picture/field.class.php
Expand Up @@ -75,7 +75,7 @@ function display_add_field($recordid=0) {
$options = new stdClass();
$options->maxbytes = $this->field->param3;
$options->itemid = $itemid;
$options->accepted_types = array('image');
$options->accepted_types = array('web_image');
$options->return_types = FILE_INTERNAL;
$options->context = $PAGE->context;
if (!empty($file)) {
Expand Down
2 changes: 1 addition & 1 deletion mod/data/field/textarea/field.class.php
Expand Up @@ -82,7 +82,7 @@ function display_add_field($recordid=0) {
if ($options['maxfiles'] != 0 ) {
$args = new stdClass();
// need these three to filter repositories list
$args->accepted_types = array('image');
$args->accepted_types = array('web_image');
$args->return_types = (FILE_INTERNAL | FILE_EXTERNAL);
$args->context = $this->context;
$args->env = 'filepicker';
Expand Down
16 changes: 4 additions & 12 deletions mod/resource/locallib.php
Expand Up @@ -82,7 +82,7 @@ function resource_display_embed($resource, $cm, $course, $file) {
core_media::OPTION_BLOCK => true,
);

if (in_array($mimetype, array('image/gif','image/jpeg','image/png'))) { // It's an image
if (file_mimetype_in_typegroup($mimetype, 'web_image')) { // It's an image
$code = resourcelib_embed_image($fullurl, $title);

} else if ($mimetype === 'application/pdf') {
Expand Down Expand Up @@ -409,30 +409,22 @@ function resource_print_filenotfound($resource, $cm, $course) {
* @return int display type constant
*/
function resource_get_final_display_type($resource) {
global $CFG;
global $CFG, $PAGE;

if ($resource->display != RESOURCELIB_DISPLAY_AUTO) {
return $resource->display;
}

static $download = array('application/zip', 'application/x-tar', 'application/g-zip'); // binary formats
static $embed = array('image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', // images
'application/x-shockwave-flash', 'video/x-flv', 'video/x-ms-wm', // video formats
'video/quicktime', 'video/mpeg', 'video/mp4',
'audio/mp3', 'audio/x-realaudio-plugin', 'x-realaudio-plugin', // audio formats
'application/pdf', 'text/html',
);

if (empty($resource->mainfile)) {
return RESOURCELIB_DISPLAY_DOWNLOAD;
} else {
$mimetype = mimeinfo('type', $resource->mainfile);
}

if (in_array($mimetype, $download)) {
if (file_mimetype_in_typegroup($mimetype, 'archive')) {
return RESOURCELIB_DISPLAY_DOWNLOAD;
}
if (in_array($mimetype, $embed)) {
if (file_mimetype_in_typegroup($mimetype, array('web_image', '.pdf', '.htm', 'web_video', 'web_audio'))) {
return RESOURCELIB_DISPLAY_EMBED;
}

Expand Down
2 changes: 1 addition & 1 deletion repository/upload/lib.php
Expand Up @@ -171,7 +171,7 @@ public function process_upload($saveas_filename, $maxbytes, $types = '*', $savep

if ($this->mimetypes != '*') {
// check filetype
$filemimetype = mimeinfo('type', $_FILES[$elname]['name']);
$filemimetype = file_storage::mimetype($_FILES[$elname]['tmp_name']);
if (!in_array($filemimetype, $this->mimetypes)) {
throw new moodle_exception('invalidfiletype', 'repository', '', get_mimetype_description(array('filename' => $_FILES[$elname]['name'])));
}
Expand Down

0 comments on commit ae7f35b

Please sign in to comment.